示例#1
0
     * [output]
     *     The filtered JavaScript code.
     */
    if (isset($PHORUM['hooks']['javascript_filter'])) {
        $content = phorum_api_hook('javascript_filter', $content);
    }
    if (!empty($PHORUM['cache_javascript'])) {
        $cache_time = time();
        phorum_cache_put('js', $cache_key, array($cache_time, $content), 86400);
    }
    // Send the JavaScript to the browser.
    header("Content-Type: text/javascript");
    print "/* FRESH */";
    print $content;
    // Exit here explicitly for not giving back control to portable and
    // embedded Phorum setups.
    exit(0);
}
// Find the modification time for the cache file.
$last_modified = $cache_time;
// Check if a If-Modified-Since header is in the request. If yes, then
// check if the JavaScript code has changed, based on the filemtime() data from
// above. If nothing changed, then we return a 304 header, to tell the
// browser to use the cached data.
phorum_api_output_last_modify_time($last_modified);
// Send the JavaScript to the browser.
header("Content-Type: text/javascript");
echo $content;
// Exit here explicitly for not giving back control to portable and
// embedded Phorum setups.
exit(0);
示例#2
0
文件: file.php 项目: samuell/Core
/**
 * Retrieve a Phorum file.
 *
 * This function can handle Phorum file retrieval in multiple ways:
 * either return the file to the caller or send it directly to the user's
 * browser (based on the $flags parameter). Sending it directly to the
 * browser allows for the implementation of modules that don't have to buffer
 * the full file data before sending it (a.k.a. streaming, which provides the
 * advantage of using less memory for sending files).
 *
 * @param mixed $file
 *     This is either an array containing at least the fields "file_id"
 *     and "filename" or a numerical file_id value. Note that you can
 *     use the return value of the function
 *     {@link phorum_api_file_check_read_access()} as input for this function.
 *
 * @param integer $flags
 *     These are flags that influence aspects of the function call. It is
 *     a bitflag value, so you can OR multiple flags together. Available
 *     flags for this function are: {@link PHORUM_FLAG_IGNORE_PERMS},
 *     {@link PHORUM_FLAG_GET}, {@link PHORUM_FLAG_SEND} and
 *     {@link PHORUM_FLAG_FORCE_DOWNLOAD}. The SEND flag has precedence
 *     over the GET flag.
 *
 * @return mixed
 *     On error, this function will return FALSE.
 *     The functions {@link phorum_api_error_message()} and
 *     {@link phorum_api_error_code()} can be used to retrieve information
 *     about the error that occurred.
 *
 *     If the {@link PHORUM_FLAG_SEND} flag is used, then the function will
 *     return NULL.
 *
 *     If the {@link PHORUM_FLAG_GET} flag is used, then the function
 *     will return a file description array, containing the fields "file_id",
 *     "username", "file_data", "mime_type".
 *     If the {@link $file} parameter was an array, then all fields from that
 *     array will be included as well.
 */
function phorum_api_file_retrieve($file, $flags = PHORUM_FLAG_GET)
{
    global $PHORUM;
    // Reset error storage.
    $PHORUM["API"]["errno"] = NULL;
    $PHORUM["API"]["error"] = NULL;
    // If $file is not an array, we are handling a numerical file_id.
    // In that case, first retrieve the file data through the access check
    // function. All the function flags are passed on to that function,
    // so the PHORUM_FLAG_IGNORE_PERMS flag can be set for ignoring access
    // permissions.
    if (!is_array($file)) {
        $file_id = (int) $file;
        $file = phorum_api_file_check_read_access($file_id, $flags);
        // Return in case of errors.
        if ($file === FALSE) {
            return FALSE;
        }
    }
    // A small basic check to see if we have a proper $file array.
    if (!isset($file["file_id"])) {
        trigger_error("phorum_api_file_get(): \$file parameter needs a \"file_id\" field.", E_USER_ERROR);
    }
    if (!isset($file["filename"])) {
        trigger_error("phorum_api_file_get(): \$file parameter needs a \"filename\" field.", E_USER_ERROR);
    }
    settype($file["file_id"], "int");
    /*
     * [hook]
     *     file_retrieve
     *
     * [description]
     *     This hook allows modules to handle the file data retrieval.
     *     The hook can use <literal>phorum_api_error()</literal>
     *     to return an error. Hooks should be aware that their input might
     *     not be <literal>$file</literal>, but <literal>FALSE</literal>
     *     instead, in which case they should immediately return
     *     <literal>FALSE</literal> themselves.
     *
     * [category]
     *     File storage
     *
     * [when]
     *     In
     *     <filename>include/api/file.php</filename>,
     *     right before a file attachment is retrieved from the database.
     *
     * [input]
     *     Two part array where the first element is an empty file array
     *     and the second element is the flags variable.
     *
     * [output]
     *     Same as input with file_data filled in.
     *
     */
    $file["result"] = 0;
    $file["mime_type"] = NULL;
    $file["file_data"] = NULL;
    if (isset($PHORUM["hooks"]["file_retrieve"])) {
        list($file, $flags) = phorum_api_hook("file_retrieve", array($file, $flags));
        if ($file === FALSE) {
            return FALSE;
        }
        // If a module sent the file data to the browser, then we are done.
        if ($file["result"] == PHORUM_FLAG_SEND) {
            return NULL;
        }
    }
    // If no module handled file retrieval, we will retrieve the
    // file from the Phorum database.
    if ($file["file_data"] === NULL) {
        $dbfile = $PHORUM['DB']->file_get($file["file_id"], TRUE);
        if (empty($dbfile)) {
            return phorum_api_error(PHORUM_ERRNO_NOTFOUND, "Phorum file (id {$file["file_id"]}) could not be " . "retrieved from the database.");
        }
        // Phorum stores the files in base64 format in the database, to
        // prevent problems with dumping and restoring databases.
        $file["file_data"] = base64_decode($dbfile["file_data"]);
    }
    // Set the MIME type information if it was not set by a module.
    $mime_type_verified = FALSE;
    if ($file["mime_type"] === NULL) {
        // Determine the MIME type based on the file extension using
        // the MIME types as defined in the Phorum API code.
        $extension_mime_type = phorum_api_file_get_mimetype($file["filename"]);
        // The MIME magic file to use for the fileinfo extension.
        if (!empty($PHORUM['mime_magic_file'])) {
            $mime_magic_file = $PHORUM['mime_magic_file'];
        } else {
            $mime_magic_file = NULL;
        }
        // Retrieve the MIME-type using the fileinfo extension if
        // it is available and enabled.
        if (function_exists("finfo_open") && (!isset($PHORUM['file_fileinfo_ext']) || !empty($PHORUM['file_fileinfo_ext'])) && ($finfo = @finfo_open(FILEINFO_MIME, $mime_magic_file))) {
            $file["mime_type"] = finfo_buffer($finfo, $file['file_data']);
            finfo_close($finfo);
            if ($file["mime_type"] === FALSE) {
                return phorum_api_error(PHORUM_ERRNO_ERROR, "The mime-type of file {$file["file_id"]} couldn't be " . "determined through the fileinfo-extension");
            }
            // The MIME-type for the file extension doesn't fit the
            // MIME-type as determined by the file's magic signature.
            // Because it is not safe to view this file in a browser,
            // we force a download.
            if ($extension_mime_type != $file["mime_type"]) {
                $flags = $flags | PHORUM_FLAG_FORCE_DOWNLOAD;
            }
            $mime_type_verified = TRUE;
        } else {
            $file["mime_type"] = $extension_mime_type;
        }
    }
    // If the file is not requested for downloading, then check if it is
    // safe for the browser to view the file inline. If it is not, then
    // enable the force download flag to make sure that the browser will
    // download the file instead.
    $safe_to_cache = TRUE;
    $safe_to_view = TRUE;
    if (!($flags & PHORUM_FLAG_FORCE_DOWNLOAD) && !$mime_type_verified) {
        list($safe_to_view, $safe_to_cache) = phorum_api_file_safe_to_view($file);
        if (!$safe_to_view) {
            $flags = $flags | PHORUM_FLAG_FORCE_DOWNLOAD;
        }
    }
    // Allow for post processing on the retrieved file.
    /**
     * @todo document the file_after_retrieve hook.
     */
    if (!empty($PHORUM['hooks']['file_after_retrieve'])) {
        list($file, $flags) = phorum_api_hook("file_after_retrieve", array($file, $flags));
    }
    // In "send" mode, we directly send the file contents to the browser.
    if ($flags & PHORUM_FLAG_SEND) {
        // Avoid using any output compression or handling on the sent data.
        ini_set('zlib.output_compression', '0');
        ini_set('output_handler', '');
        // Get rid of any buffered output so far (there shouldn't be any).
        phorum_api_buffer_clear();
        $time = (int) $file['add_datetime'];
        // Handle client side caching.
        if ($safe_to_cache) {
            // Check if an If-Modified-Since header is in the request. If yes,
            // then check if the file has changed, based on the date from
            // the file data. If nothing changed, then we return a 304 header,
            // to tell the browser to use the cached data.
            phorum_api_output_last_modify_time($time);
            // Send caching headers, so files can be cached by the browser.
            phorum_api_output_cache_max_age(3600 * 24 * 60);
        } else {
            phorum_api_output_cache_disable();
        }
        if ($flags & PHORUM_FLAG_FORCE_DOWNLOAD) {
            $disposition = 'attachment; ';
            $type = 'application/octet-stream';
        } else {
            $disposition = '';
            $type = $file['mime_type'];
        }
        header("Content-Disposition: " . "{$disposition}filename=\"{$file['filename']}\"");
        header("Content-Type: {$type}");
        header('Content-Length: ' . strlen($file['file_data']));
        print $file['file_data'];
        return NULL;
    } elseif ($flags & PHORUM_FLAG_GET) {
        return $file;
    } else {
        trigger_error("phorum_api_file_retrieve(): no retrieve mode specified in the " . "flags (either use PHORUM_FLAG_GET or PHORUM_FLAG_SEND).", E_USER_ERROR);
    }
}