/** * Form for editing HTML block instances. * * @copyright 2010 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package block_html * @category files * @param stdClass $course course object * @param stdClass $birecord_or_cm block instance record * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool */ function block_html_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $SCRIPT; if ($context->contextlevel != CONTEXT_BLOCK) { send_file_not_found(); } require_course_login($course); if ($filearea !== 'content') { send_file_not_found(); } $fs = get_file_storage(); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'block_html', 'content', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } if ($parentcontext = get_context_instance_by_id($birecord_or_cm->parentcontextid)) { if ($parentcontext->contextlevel == CONTEXT_USER) { // force download on all personal pages including /my/ //because we do not have reliable way to find out from where this is used $forcedownload = true; } } else { // weird, there should be parent context, better force dowload then $forcedownload = true; } session_get_instance()->write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, $options); }
/** * Serves the message attachments. Implements needed access control ;-) * * @param object $course * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - justsend the file */ function block_jmail_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $SCRIPT; if ($context->contextlevel != CONTEXT_BLOCK) { //send_file_not_found(); } require_course_login($course); $coursecontext = block_jmail_get_context(CONTEXT_COURSE, $course->id, MUST_EXIST); // The mailbox constructor does the permission validation if (!($mailbox = new block_jmail_mailbox($course, $coursecontext, $context))) { return; } $messageid = (int) array_shift($args); $message = block_jmail_message::get_from_id($messageid); // We check if we are the senders or the receivers if (!$message) { send_file_not_found(); } $pendingaprobal = !$message->approved and has_capability('block/jmail:approvemessages', $context); if (!$message->is_mine() and !$pendingaprobal) { send_file_not_found(); } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/block_jmail/{$filearea}/{$messageid}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } $forcedownload = true; send_stored_file($file, 60 * 60, 0, $forcedownload); }
function workshopform_numerrors_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload) { global $DB; if ($context->contextlevel != CONTEXT_MODULE) { return false; } require_login($course, true, $cm); if ($filearea !== 'description') { return false; } $itemid = (int)array_shift($args); // the id of the assessment form dimension if (!$workshop = $DB->get_record('workshop', array('id' => $cm->instance))) { send_file_not_found(); } if (!$dimension = $DB->get_record('workshopform_numerrors', array('id' => $itemid ,'workshopid' => $workshop->id))) { send_file_not_found(); } // TODO now make sure the user is allowed to see the file // (media embedded into the dimension description) $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/$context->id/workshopform_numerrors/$filearea/$itemid/$relativepath"; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { return false; } // finally send the file send_stored_file($file); }
/** * Server teamwork files * * @category files * @param stdClass $course course object * @param stdClass $cm course module object * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool */ function teamworkform_rubric_pluginfile($course, $cm, $context, $filearea, array $args, $forcedownload, array $options = array()) { global $DB; if ($context->contextlevel != CONTEXT_MODULE) { return false; } require_login($course, true, $cm); if ($filearea !== 'description') { return false; } $itemid = (int) array_shift($args); // the id of the assessment form dimension if (!($teamwork = $DB->get_record('teamwork', array('id' => $cm->instance)))) { send_file_not_found(); } if (!($dimension = $DB->get_record('teamworkform_rubric', array('id' => $itemid, 'teamworkid' => $teamwork->id)))) { send_file_not_found(); } // TODO now make sure the user is allowed to see the file // (media embedded into the dimension description) $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/teamworkform_rubric/{$filearea}/{$itemid}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { return false; } // finally send the file send_stored_file($file, 0, 0, $forcedownload, $options); }
function theme_clean_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'logo') { $theme = theme_config::load('clean'); return $theme->setting_file_serve('logo', $args, $forcedownload, $options); } else { send_file_not_found(); } }
/** * Form for editing Information Spot block instances. * * @copyright 2014 Roberto Pinna * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package block_informationspot * @category files * @param stdClass $course course object * @param stdClass $birecord_or_cm block instance record * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool */ function block_informationspot_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $DB, $CFG, $USER; if ($context->contextlevel != CONTEXT_BLOCK) { send_file_not_found(); } // If block is in course context, then check if user has capability to access course. if ($context->get_course_context(false)) { require_course_login($course); } else { if ($CFG->forcelogin) { require_login(); } else { // Get parent context and see if user have proper permission. $parentcontext = $context->get_parent_context(); if ($parentcontext->contextlevel === CONTEXT_COURSECAT) { // Check if category is visible and user can view this category. $category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST); if (!$category->visible) { require_capability('moodle/category:viewhiddencategories', $parentcontext); } } else { if ($parentcontext->contextlevel === CONTEXT_USER && $parentcontext->instanceid != $USER->id) { // The block is in the context of a user, it is only visible to the user who it belongs to. send_file_not_found(); } } // At this point there is no way to check SYSTEM context, so ignoring it. } } if ($filearea != 'image') { send_file_not_found(); } $fs = get_file_storage(); $imageid = array_shift($args); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'block_informationspot', $filearea, $imageid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } if ($parentcontext = context::instance_by_id($birecord_or_cm->parentcontextid, IGNORE_MISSING)) { if ($parentcontext->contextlevel == CONTEXT_USER) { // force download on all personal pages including /my/ //because we do not have reliable way to find out from where this is used $forcedownload = true; } } else { // weird, there should be parent context, better force dowload then $forcedownload = true; } // NOTE: it woudl be nice to have file revisions here, for now rely on standard file lifetime, // do not lower it because the files are dispalyed very often. \core\session\manager::write_close(); send_stored_file($file, null, 0, $forcedownload, $options); }
function local_email_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { $fs = get_file_storage(); $relativepath = implode('/', $args); $filename = $args[1]; $itemid = $args[0]; if (!($file = $fs->get_file($context->id, 'local_email', $filearea, $itemid, '/', $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0); }
/** * This is method serves up files to the user. The files used in this course are just images, * but they are sent largely the same way. * */ function block_nurs_navigation_pluginfile($course, $birecord, $context, $filearea, $args, $forcedownload) { require_once 'lib/filelib.php'; $fs = get_file_storage(); $entryid = clean_param(array_shift($args), PARAM_INT); $file = array_shift($args); if (!($file = $fs->get_file($context->id, 'block_nurs_navigation', $filearea, $entryid, '/', $file))) { send_file_not_found(); return; } send_stored_file($file, 10 * 60, 0, true); }
function question_preview_question_pluginfile_joomdle($course, $context, $component, $filearea, $qubaid, $slot, $filename, $forcedownload) { global $USER, $DB, $CFG; $query = "SELECT *\n FROM {$CFG->prefix}files\n WHERE component = 'question'\n AND filearea = ?\n AND itemid = ?\n AND filename = ?\n ORDER by id\n LIMIT 1"; $params = array($filearea, $qubaid, $filename); $record = $DB->get_record_sql($query, $params); $fs = get_file_storage(); if (!($file = $fs->get_file_by_hash($record->pathnamehash))) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload); }
/** * Serve question files when they are displayed in this export format. * * @param context $previewcontext the quiz context * @param int $questionid the question id. * @param context $filecontext the file (question) context * @param string $filecomponent the component the file belongs to. * @param string $filearea the file area. * @param array $args remaining file args. * @param bool $forcedownload. * @param array $options additional options affecting the file serving. */ function qformat_xhtml_question_preview_pluginfile($previewcontext, $questionid, $filecontext, $filecomponent, $filearea, $args, $forcedownload, $options = array()) { global $CFG; list($context, $course, $cm) = get_context_info_array($previewcontext->id); require_login($course, false, $cm); question_require_capability_on($questionid, 'view'); $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$filecontext->id}/{$filecomponent}/{$filearea}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload, $options); }
/** * Serves any files associated with the theme settings. * * @param stdClass $course * @param stdClass $cm * @param context $context * @param string $filearea * @param array $args * @param bool $forcedownload * @param array $options * @return bool */ function theme_bootstrap_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { $fs = get_file_storage(); $relativepath = implode('/', $args); $filename = $args[1]; $itemid = $args[0]; if ($filearea == 'logo') { $itemid = 0; } if (!($file = $fs->get_file($context->id, 'theme_bootstrap', $filearea, $itemid, '/', $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload); }
function block_course_message_pluginfile($course, $birecord, $context, $filearea, $args, $forcedownload) { require_once 'lib/filelib.php'; $fs = get_file_storage(); $context = context_course::instance($course->id); $entryid = clean_param(array_shift($args), PARAM_INT); $file = array_shift($args); if (!($file = $fs->get_file($context->id, 'block_course_message', $filearea, $entryid, '/', $file))) { send_file_not_found(); return; } // Fourth parameter forces the user to download the file. send_stored_file($file, BLOCK_CM_LIFETIME, 0, $forcedownload); }
/** * Files support. * * Exits if the required permissions are not satisfied. * * @param stdClass $course course object * @param stdClass $cm * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return void The file is sent along with it's headers */ function tool_generator_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { // Only for admins or CLI. if (!defined('CLI_SCRIPT') && !is_siteadmin()) { die; } if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } $fs = get_file_storage(); $file = $fs->get_file($context->id, 'tool_generator', $filearea, $args[0], '/', $args[1]); // Send the file, always forcing download, we don't want options. session_get_instance()->write_close(); send_stored_file($file, 0, 0, true); }
/** * Form for editing HTML block instances. * * @copyright 2010 Petr Skoda (http://skodak.org) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @package block_html * @category files * @param stdClass $course course object * @param stdClass $birecord_or_cm block instance record * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool * @todo MDL-36050 improve capability check on stick blocks, so we can check user capability before sending images. */ function block_html_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $DB, $CFG; if ($context->contextlevel != CONTEXT_BLOCK) { send_file_not_found(); } // If block is in course context, then check if user has capability to access course. if ($context->get_course_context(false)) { require_course_login($course); } else { if ($CFG->forcelogin) { require_login(); } else { // Get parent context and see if user have proper permission. $parentcontext = $context->get_parent_context(); if ($parentcontext->contextlevel === CONTEXT_COURSECAT) { // Check if category is visible and user can view this category. $category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST); if (!$category->visible) { require_capability('moodle/category:viewhiddencategories', $parentcontext); } } // At this point there is no way to check SYSTEM or USER context, so ignoring it. } } if ($filearea !== 'content') { send_file_not_found(); } $fs = get_file_storage(); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'block_html', 'content', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } if ($parentcontext = get_context_instance_by_id($birecord_or_cm->parentcontextid)) { if ($parentcontext->contextlevel == CONTEXT_USER) { // force download on all personal pages including /my/ //because we do not have reliable way to find out from where this is used $forcedownload = true; } } else { // weird, there should be parent context, better force dowload then $forcedownload = true; } session_get_instance()->write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, $options); }
/** * Serve questiontext files in the question text when they are displayed in this report. * * @package quiz_statistics * @category files * @param context $previewcontext the quiz context * @param int $questionid the question id. * @param context $filecontext the file (question) context * @param string $filecomponent the component the file belongs to. * @param string $filearea the file area. * @param array $args remaining file args. * @param bool $forcedownload. * @param array $options additional options affecting the file serving. */ function quiz_statistics_question_preview_pluginfile($previewcontext, $questionid, $filecontext, $filecomponent, $filearea, $args, $forcedownload, $options = array()) { global $CFG; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; list($context, $course, $cm) = get_context_info_array($previewcontext->id); require_login($course, false, $cm); // Assume only trusted people can see this report. There is no real way to // validate questionid, becuase of the complexity of random quetsions. require_capability('quiz/statistics:view', $context); $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$filecontext->id}/{$filecomponent}/{$filearea}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload, $options); }
function block_navbuttons_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload) { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_course_login($course); if ($filearea !== 'icons') { send_file_not_found(); } $fs = get_file_storage(); $filename = $args[1]; $iconid = $args[0]; if (!($file = $fs->get_file($context->id, 'block_navbuttons', 'icons', $iconid, '/', $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 60 * 60, 0, $forcedownload); }
function block_course_profile_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $SCRIPT; if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } if ($filearea !== 'courseicon') { send_file_not_found(); } $fs = get_file_storage(); $file = $fs->get_file($context->id, 'block_course_profile', 'courseicon', 0, '/', $course->id); if (!$file or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); send_stored_file($file, 60 * 60, 0, false, $options); }
/** * Serves rolesexport xml files. * * @param object $course * @param object $cm * @param object $context * @param string $filearea * @param array $args * @param bool $forcedownload * @return bool false if file not found, does not return if found - just send the file */ function report_rolesmigration_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $USER; //require_capability('mod/assignment:view', $this->context); $fullpath = "/{$context->id}/report_rolesmigration/{$filearea}/" . implode('/', $args); $fs = get_file_storage(); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } if ($USER->id != $file->get_userid() && !has_capability('moodle/role:manage', $context)) { send_file_not_found(); } session_get_instance()->write_close(); // unlock session during fileserving if (!send_stored_file($file, 60 * 60, 0, true)) { send_file_not_found(); } }
function local_note_pluginfile($course, $birecord_or_cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $DB, $CFG; if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } // If block is in course context, then check if user has capability to access course. if ($context->get_course_context(false)) { //require_course_login($course); } else { if ($CFG->forcelogin) { //require_login(); } else { // Get parent context and see if user have proper permission. $parentcontext = $context->get_parent_context(); if ($parentcontext->contextlevel === CONTEXT_COURSECAT) { // Check if category is visible and user can view this category. $category = $DB->get_record('course_categories', array('id' => $parentcontext->instanceid), '*', MUST_EXIST); if (!$category->visible) { require_capability('moodle/category:viewhiddencategories', $parentcontext); } } // At this point there is no way to check SYSTEM or USER context, so ignoring it. } } if ($filearea !== 'content') { send_file_not_found(); } $fs = get_file_storage(); $filename = array_pop($args); //$filepath = $args ? '/'.implode('/', $args).'/' : '/'; $filepath = '/'; $itemid = $args['0']; //added by nihar -to get the item id if (!($file = $fs->get_file($context->id, 'local_note', 'content', $itemid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } session_get_instance()->write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, $options); }
/** * File serving. * * @param stdClass $course The course object. * @param stdClass $cm The cm object. * @param context $context The context object. * @param string $filearea The file area. * @param array $args List of arguments. * @param bool $forcedownload Whether or not to force the download of the file. * @param array $options Array of options. * @return void|false */ function core_admin_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $CFG; if (in_array($filearea, ['logo', 'logocompact'])) { $size = array_shift($args); // The path hides the size. $itemid = clean_param(array_shift($args), PARAM_INT); $filename = clean_param(array_shift($args), PARAM_FILE); $themerev = theme_get_revision(); if ($themerev <= 0) { // Normalise to 0 as -1 doesn't place well with paths. $themerev = 0; } // Extract the requested width and height. $maxwidth = 0; $maxheight = 0; if (preg_match('/^\\d+x\\d+$/', $size)) { list($maxwidth, $maxheight) = explode('x', $size); $maxwidth = clean_param($maxwidth, PARAM_INT); $maxheight = clean_param($maxheight, PARAM_INT); } $lifetime = 0; if ($itemid > 0 && $themerev == $itemid) { // The itemid is $CFG->themerev, when 0 or less no caching. Also no caching when they don't match. $lifetime = DAYSECS * 60; } // Anyone, including guests and non-logged in users, can view the logos. $options = ['cacheability' => 'public']; // Check if we've got a cached file to return. When lifetime is 0 then we don't want to cached one. $candidate = $CFG->localcachedir . "/core_admin/{$themerev}/{$filearea}/{$maxwidth}x{$maxheight}/{$filename}"; if (file_exists($candidate) && $lifetime > 0) { send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options); } // Find the original file. $fs = get_file_storage(); $filepath = "/{$context->id}/core_admin/{$filearea}/0/{$filename}"; if (!($file = $fs->get_file_by_hash(sha1($filepath)))) { send_file_not_found(); } // No need for resizing, but if the file should be cached we save it so we can serve it fast next time. if (empty($maxwidth) && empty($maxheight)) { if ($lifetime) { file_safe_save_content($file->get_content(), $candidate); } send_stored_file($file, $lifetime, 0, false, $options); } // Proceed with the resizing. $filedata = $file->resize_image($maxwidth, $maxheight); if (!$filedata) { send_file_not_found(); } // If we don't want to cached the file, serve now and quit. if (!$lifetime) { send_content_uncached($filedata, $filename); } // Save, serve and quit. file_safe_save_content($filedata, $candidate); send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options); } send_file_not_found(); }
// always at least user id print_error('invalidarguments'); } $contextid = (int) array_shift($args); $component = array_shift($args); $filearea = array_shift($args); $draftid = (int) array_shift($args); if ($component !== 'user' or $filearea !== 'draft') { send_file_not_found(); } $context = context::instance_by_id($contextid); if ($context->contextlevel != CONTEXT_USER) { send_file_not_found(); } $userid = $context->instanceid; if ($USER->id != $userid) { print_error('invaliduserid'); } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/user/draft/{$draftid}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->get_filename() == '.') { send_file_not_found(); } // ======================================== // finally send the file // ======================================== \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, false, true, array('preview' => $preview)); // force download - security first!
/** * Called via pluginfile.php -> question_pluginfile to serve files belonging to * a question in a question_attempt when that attempt is a preview. * * @param object $course course settings object * @param object $context context object * @param string $component the name of the component we are serving files for. * @param string $filearea the name of the file area. * @param int $qubaid the question_usage this image belongs to. * @param int $slot the relevant slot within the usage. * @param array $args the remaining bits of the file path. * @param bool $forcedownload whether the user must be forced to download the file. * @return bool false if file not found, does not return if found - justsend the file */ function question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload) { global $USER, $DB, $CFG; $quba = question_engine::load_questions_usage_by_activity($qubaid); if (!question_has_capability_on($quba->get_question($slot), 'use')) { send_file_not_found(); } $options = new question_display_options(); $options->feedback = question_display_options::VISIBLE; $options->numpartscorrect = question_display_options::VISIBLE; $options->generalfeedback = question_display_options::VISIBLE; $options->rightanswer = question_display_options::VISIBLE; $options->manualcomment = question_display_options::VISIBLE; $options->history = question_display_options::VISIBLE; if (!$quba->check_file_access($slot, $options, $component, $filearea, $args, $forcedownload)) { send_file_not_found(); } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/{$component}/{$filearea}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload); }
/** * Gets a file relative to this file in the repository and sends it to the browser. * Used to allow relative file linking within a repository without creating file records * for linked files * * Repositories that overwrite this must be very careful - see filesystem repository for example. * * @param stored_file $mainfile The main file we are trying to access relative files for. * @param string $relativepath the relative path to the file we are trying to access. * */ public function send_relative_file(stored_file $mainfile, $relativepath) { // This repository hasn't implemented this so send_file_not_found. send_file_not_found(); }
function format_slides_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload){ $filename = array_pop($args); // TODO: check filepath $filepath = $args ? '/'.implode('/', $args).'/' : '/'; $fs = get_file_storage(); //echo $context->id . 'format_slides ' . $filearea . " " . $args[0] . " " . $filepath . " " . $filename . "<br/>"; if (!$file = $fs->get_file($context->id, 'format_slides', $filearea, $args[0], "/", $filename)) { send_file_not_found(); } session_get_instance()->write_close(); send_stored_file($file, 60*60, 0, $forcedownload); exit; }
/** * Serves any files associated with the theme settings. * * @param stdClass $course * @param stdClass $cm * @param context $context * @param string $filearea * @param array $args * @param bool $forcedownload * @param array $options * @return bool */ function theme_clean_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { if ($context->contextlevel == CONTEXT_SYSTEM and $filearea === 'logo') { $theme = theme_config::load('clean'); // By default, theme files must be cache-able by both browsers and proxies. if (!array_key_exists('cacheability', $options)) { $options['cacheability'] = 'public'; } return $theme->setting_file_serve('logo', $args, $forcedownload, $options); } else { send_file_not_found(); } }
/** * Serve questiontext files in the question text when they are displayed in this report. * * @package core_files * @category files * @param context $previewcontext the context in which the preview is happening. * @param int $questionid the question id. * @param context $filecontext the file (question) context. * @param string $filecomponent the component the file belongs to. * @param string $filearea the file area. * @param array $args remaining file args. * @param bool $forcedownload. * @param array $options additional options affecting the file serving. */ function core_question_question_preview_pluginfile($previewcontext, $questionid, $filecontext, $filecomponent, $filearea, $args, $forcedownload, $options = array()) { global $DB; // Verify that contextid matches the question. $question = $DB->get_record_sql(' SELECT q.*, qc.contextid FROM {question} q JOIN {question_categories} qc ON qc.id = q.category WHERE q.id = :id AND qc.contextid = :contextid', array('id' => $questionid, 'contextid' => $filecontext->id), MUST_EXIST); // Check the capability. list($context, $course, $cm) = get_context_info_array($previewcontext->id); require_login($course, false, $cm); question_require_capability_on($question, 'use'); $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$filecontext->id}/{$filecomponent}/{$filearea}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 0, 0, $forcedownload, $options); }
/** * Serves any files associated with the theme settings. * * @param stdClass $course * @param stdClass $cm * @param context $context * @param string $filearea * @param array $args * @param bool $forcedownload * @param array $options * @return bool */ function theme_bcu_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { static $theme; if (empty($theme)) { $theme = theme_config::load('bcu'); } if ($context->contextlevel == CONTEXT_SYSTEM) { if ($filearea === 'logo') { return $theme->setting_file_serve('logo', $args, $forcedownload, $options); } else { if ($filearea === 'style') { theme_essential_serve_css($args[1]); } else { if ($filearea === 'pagebackground') { return $theme->setting_file_serve('pagebackground', $args, $forcedownload, $options); } else { if (preg_match("/p[1-9][0-9]/", $filearea) !== false) { return $theme->setting_file_serve($filearea, $args, $forcedownload, $options); } else { if (substr($filearea, 0, 9) === 'marketing' && substr($filearea, 10, 5) === 'image') { return $theme->setting_file_serve($filearea, $args, $forcedownload, $options); } else { if ($filearea === 'iphoneicon') { return $theme->setting_file_serve('iphoneicon', $args, $forcedownload, $options); } else { if ($filearea === 'iphoneretinaicon') { return $theme->setting_file_serve('iphoneretinaicon', $args, $forcedownload, $options); } else { if ($filearea === 'ipadicon') { return $theme->setting_file_serve('ipadicon', $args, $forcedownload, $options); } else { if ($filearea === 'ipadretinaicon') { return $theme->setting_file_serve('ipadretinaicon', $args, $forcedownload, $options); } else { if ($filearea === 'fontfilettfheading') { return $theme->setting_file_serve('fontfilettfheading', $args, $forcedownload, $options); } else { if ($filearea === 'fontfilettfbody') { return $theme->setting_file_serve('fontfilettfbody', $args, $forcedownload, $options); } else { send_file_not_found(); } } } } } } } } } } } } else { send_file_not_found(); } }
/** * This function delegates file serving to individual plugins * * @param string $relativepath * @param bool $forcedownload * @param null|string $preview the preview mode, defaults to serving the original file * @todo MDL-31088 file serving improments */ function file_pluginfile($relativepath, $forcedownload, $preview = null) { global $DB, $CFG, $USER; // relative path must start with '/' if (!$relativepath) { print_error('invalidargorconf'); } else { if ($relativepath[0] != '/') { print_error('pathdoesnotstartslash'); } } // extract relative path components $args = explode('/', ltrim($relativepath, '/')); if (count($args) < 3) { // always at least context, component and filearea print_error('invalidarguments'); } $contextid = (int) array_shift($args); $component = clean_param(array_shift($args), PARAM_COMPONENT); $filearea = clean_param(array_shift($args), PARAM_AREA); list($context, $course, $cm) = get_context_info_array($contextid); $fs = get_file_storage(); // ======================================================================================================================== if ($component === 'blog') { // Blog file serving if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } if ($filearea !== 'attachment' and $filearea !== 'post') { send_file_not_found(); } if (empty($CFG->enableblogs)) { print_error('siteblogdisable', 'blog'); } $entryid = (int) array_shift($args); if (!($entry = $DB->get_record('post', array('module' => 'blog', 'id' => $entryid)))) { send_file_not_found(); } if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) { require_login(); if (isguestuser()) { print_error('noguest'); } if ($CFG->bloglevel == BLOG_USER_LEVEL) { if ($USER->id != $entry->userid) { send_file_not_found(); } } } if ($entry->publishstate === 'public') { if ($CFG->forcelogin) { require_login(); } } else { if ($entry->publishstate === 'site') { require_login(); //ok } else { if ($entry->publishstate === 'draft') { require_login(); if ($USER->id != $entry->userid) { send_file_not_found(); } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $entryid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 10 * 60, 0, true, array('preview' => $preview)); // download MUST be forced - security! // ======================================================================================================================== } else { if ($component === 'grade') { if (($filearea === 'outcome' or $filearea === 'scale') and $context->contextlevel == CONTEXT_SYSTEM) { // Global gradebook files if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) { //TODO: nobody implemented this yet in grade edit form!! send_file_not_found(); if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } // ======================================================================================================================== } else { if ($component === 'tag') { if ($filearea === 'description' and $context->contextlevel == CONTEXT_SYSTEM) { // All tag descriptions are going to be public but we still need to respect forcelogin if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/tag/description/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'badges') { require_once $CFG->libdir . '/badgeslib.php'; $badgeid = (int) array_shift($args); $badge = new badge($badgeid); $filename = array_pop($args); if ($filearea === 'badgeimage') { if ($filename !== 'f1' && $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'badges', 'badgeimage', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) { if (!($file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } } // ======================================================================================================================== } else { if ($component === 'calendar') { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) { // All events here are public the one requirement is that we respect forcelogin if ($CFG->forcelogin) { require_login(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'eventtype' => 'site')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) { // Must be logged in, if they are not then they obviously can't be this user require_login(); // Don't want guests here, potentially saves a DB call if (isguestuser()) { send_file_not_found(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database - user id must match if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'userid' => $USER->id, 'eventtype' => 'user')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) { // Respect forcelogin and require login unless this is the site.... it probably // should NEVER be the site if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } // Must be able to at least view the course. This does not apply to the front page. if ($course->id != SITEID && !is_enrolled($context) && !is_viewing($context)) { //TODO: hmm, do we really want to block guests here? send_file_not_found(); } // Get the event id $eventid = array_shift($args); // Load the event from the database we need to check whether it is // a) valid course event // b) a group event // Group events use the course context (there is no group context) if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'courseid' => $course->id)))) { send_file_not_found(); } // If its a group event require either membership of view all groups capability if ($event->eventtype === 'group') { if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($event->groupid, $USER->id)) { send_file_not_found(); } } else { if ($event->eventtype === 'course' || $event->eventtype === 'site') { // Ok. Please note that the event type 'site' still uses a course context. } else { // Some other type. send_file_not_found(); } } // If we get this far we can serve the file $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } // ======================================================================================================================== } else { if ($component === 'user') { if ($filearea === 'icon' and $context->contextlevel == CONTEXT_USER) { if (count($args) == 1) { $themename = theme_config::DEFAULT_THEME; $filename = array_shift($args); } else { $themename = array_shift($args); $filename = array_shift($args); } // fix file name automatically if ($filename !== 'f1' and $filename !== 'f2' and $filename !== 'f3') { $filename = 'f1'; } if ((!empty($CFG->forcelogin) and !isloggedin()) || !empty($CFG->forceloginforprofileimage) && (!isloggedin() || isguestuser())) { // protect images if login required and not logged in; // also if login is required for profile images and is not logged in or guest // do not use require_login() because it is expensive and not suitable here anyway $theme = theme_config::load($themename); redirect($theme->pix_url('u/' . $filename, 'moodle')); // intentionally not cached } if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.jpg'))) { if ($filename === 'f3') { // f3 512x512px was introduced in 2.3, there might be only the smaller version. if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.png'))) { $file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.jpg'); } } } } if (!$file) { // bad reference - try to prevent future retries as hard as possible! if ($user = $DB->get_record('user', array('id' => $context->instanceid), 'id, picture')) { if ($user->picture > 0) { $DB->set_field('user', 'picture', 0, array('id' => $user->id)); } } // no redirect here because it is not cached $theme = theme_config::load($themename); $imagefile = $theme->resolve_image_location('u/' . $filename, 'moodle', null); send_file($imagefile, basename($imagefile), 60 * 60 * 24 * 14); } $options = array('preview' => $preview); if (empty($CFG->forcelogin) && empty($CFG->forceloginforprofileimage)) { // Profile images should be cache-able by both browsers and proxies according // to $CFG->forcelogin and $CFG->forceloginforprofileimage. $options['cacheability'] = 'public'; } send_stored_file($file, 60 * 60 * 24 * 365, 0, false, $options); // enable long caching, there are many images on each page } else { if ($filearea === 'private' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } if ($USER->id !== $context->instanceid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) { if ($CFG->forcelogin) { require_login(); } $userid = $context->instanceid; if ($USER->id == $userid) { // always can access own } else { if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { send_file_not_found(); } // we allow access to site profile of all course contacts (usually teachers) if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $context)) { send_file_not_found(); } $canview = false; if (has_capability('moodle/user:viewdetails', $context)) { $canview = true; } else { $courses = enrol_get_my_courses(); } while (!$canview && count($courses) > 0) { $course = array_shift($courses); if (has_capability('moodle/user:viewdetails', context_course::instance($course->id))) { $canview = true; } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) { $userid = (int) array_shift($args); $usercontext = context_user::instance($userid); if ($CFG->forcelogin) { require_login(); } if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { print_error('noguest'); } //TODO: review this logic of user profile access prevention if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('usernotavailable'); } if (!has_capability('moodle/user:viewdetails', $context) && !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('cannotviewprofile'); } if (!is_enrolled($context, $userid)) { print_error('notenrolledprofile'); } if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { print_error('groupnotamember'); } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($usercontext->id, 'user', 'profile', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } $userid = $context->instanceid; if ($USER->id != $userid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'user', 'backup', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { send_file_not_found(); } } } } } // ======================================================================================================================== } else { if ($component === 'coursecat') { if ($context->contextlevel != CONTEXT_COURSECAT) { send_file_not_found(); } if ($filearea === 'description') { if ($CFG->forcelogin) { // no login necessary - unless login forced everywhere require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'coursecat', 'description', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'course') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } if ($filearea === 'summary' || $filearea === 'overviewfiles') { if ($CFG->forcelogin) { require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section') { if ($CFG->forcelogin) { require_login($course); } else { if ($course->id != SITEID) { require_login($course); } } $sectionid = (int) array_shift($args); if (!($section = $DB->get_record('course_sections', array('id' => $sectionid, 'course' => $course->id)))) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'cohort') { $cohortid = (int) array_shift($args); $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST); $cohortcontext = context::instance_by_id($cohort->contextid); // The context in the file URL must be either cohort context or context of the course underneath the cohort's context. if ($context->id != $cohort->contextid && ($context->contextlevel != CONTEXT_COURSE || !in_array($cohort->contextid, $context->get_parent_context_ids()))) { send_file_not_found(); } // User is able to access cohort if they have view cap on cohort level or // the cohort is visible and they have view cap on course level. $canview = has_capability('moodle/cohort:view', $cohortcontext) || $cohort->visible && has_capability('moodle/cohort:view', $context); if ($filearea === 'description' && $canview) { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (($file = $fs->get_file($cohortcontext->id, 'cohort', 'description', $cohort->id, $filepath, $filename)) && !$file->is_directory()) { \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); } else { if ($component === 'group') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_course_login($course, true, null, false); $groupid = (int) array_shift($args); $group = $DB->get_record('groups', array('id' => $groupid, 'courseid' => $course->id), '*', MUST_EXIST); if ($course->groupmodeforce and $course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context) and !groups_is_member($group->id, $USER->id)) { // do not allow access to separate group info if not member or teacher send_file_not_found(); } if ($filearea === 'description') { require_login($course); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'group', 'description', $group->id, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'icon') { $filename = array_pop($args); if ($filename !== 'f1' and $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.jpg'))) { send_file_not_found(); } } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, false, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'grouping') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_login($course); $groupingid = (int) array_shift($args); // note: everybody has access to grouping desc images for now if ($filearea === 'description') { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'grouping', 'description', $groupingid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'backup') { if ($filearea === 'course' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'course', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $sectionid = (int) array_shift($args); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) { require_login($course, false, $cm); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'activity', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'automated' and $context->contextlevel == CONTEXT_COURSE) { // Backup files that were generated by the automated backup systems. require_login($course); require_capability('moodle/site:config', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'automated', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } } // ======================================================================================================================== } else { if ($component === 'question') { require_once $CFG->libdir . '/questionlib.php'; question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload); send_file_not_found(); // ======================================================================================================================== } else { if ($component === 'grading') { if ($filearea === 'description') { // files embedded into the form definition description if ($context->contextlevel == CONTEXT_SYSTEM) { require_login(); } else { if ($context->contextlevel >= CONTEXT_COURSE) { require_login($course, false, $cm); } else { send_file_not_found(); } } $formid = (int) array_shift($args); $sql = "SELECT ga.id\n FROM {grading_areas} ga\n JOIN {grading_definitions} gd ON (gd.areaid = ga.id)\n WHERE gd.id = ? AND ga.contextid = ?"; $areaid = $DB->get_field_sql($sql, array($formid, $context->id), IGNORE_MISSING); if (!$areaid) { send_file_not_found(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/{$formid}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } // ======================================================================================================================== } else { if (strpos($component, 'mod_') === 0) { $modname = substr($component, 4); if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/mod/{$modname}/lib.php"; if ($context->contextlevel == CONTEXT_MODULE) { if ($cm->modname !== $modname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } } if ($filearea === 'intro') { if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { send_file_not_found(); } require_course_login($course, true, $cm); // all users may access it $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'mod_' . $modname, 'intro', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } // finally send the file send_stored_file($file, null, 0, false, array('preview' => $preview)); } $filefunction = $component . '_pluginfile'; $filefunctionold = $modname . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } else { if (function_exists($filefunctionold)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, 'block_') === 0) { $blockname = substr($component, 6); // note: no more class methods in blocks please, that is .... if (!file_exists("{$CFG->dirroot}/blocks/{$blockname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/blocks/{$blockname}/lib.php"; if ($context->contextlevel == CONTEXT_BLOCK) { $birecord = $DB->get_record('block_instances', array('id' => $context->instanceid), '*', MUST_EXIST); if ($birecord->blockname !== $blockname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } if ($context->get_course_context(false)) { // If block is in course context, then check if user has capability to access course. require_course_login($course); } else { if ($CFG->forcelogin) { // If user is logged out, bp record will not be visible, even if the user would have access if logged in. require_login(); } } $bprecord = $DB->get_record('block_positions', array('contextid' => $context->id, 'blockinstanceid' => $context->instanceid)); // User can't access file, if block is hidden or doesn't have block:view capability if ($bprecord && !$bprecord->visible || !has_capability('moodle/block:view', $context)) { send_file_not_found(); } } else { $birecord = null; } $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, '_') === false) { // all core subsystems have to be specified above, no more guessing here! send_file_not_found(); } else { // try to serve general plugin file in arbitrary context $dir = core_component::get_component_directory($component); if (!file_exists("{$dir}/lib.php")) { send_file_not_found(); } include_once "{$dir}/lib.php"; $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); } } } } } } } } } } } } } } } } } }
/** * Repository method to serve the referenced file * * @see send_stored_file * * @param stored_file $storedfile the file that contains the reference * @param int $lifetime Number of seconds before the file should expire from caches (default 24 hours) * @param int $filter 0 (default)=no filtering, 1=all files, 2=html files only * @param bool $forcedownload If true (default false), forces download of file rather than view in browser/plugin * @param array $options additional options affecting the file serving */ public function send_file($storedfile, $lifetime = 86400, $filter = 0, $forcedownload = false, array $options = null) { if ($this->has_moodle_files()) { $fs = get_file_storage(); $params = file_storage::unpack_reference($storedfile->get_reference(), true); $srcfile = null; if (is_array($params)) { $srcfile = $fs->get_file($params['contextid'], $params['component'], $params['filearea'], $params['itemid'], $params['filepath'], $params['filename']); } if (empty($options)) { $options = array(); } if (!isset($options['filename'])) { $options['filename'] = $storedfile->get_filename(); } if (!$srcfile) { send_file_not_found(); } else { send_stored_file($srcfile, $lifetime, $filter, $forcedownload, $options); } } else { throw new coding_exception("Repository plugin must implement send_file() method."); } }
function block_clampmail_pluginfile($course, $record, $context, $filearea, $args, $forcedownload) { $fs = get_file_storage(); global $DB; list($itemid, $filename) = $args; $params = array('component' => 'block_clampmail', 'filearea' => $filearea, 'itemid' => $itemid, 'filename' => $filename); $instanceid = $DB->get_field('files', 'id', $params); if (empty($instanceid)) { send_file_not_found(); } else { $file = $fs->get_file_by_id($instanceid); send_stored_file($file); } }