Example #1
0
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @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 array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload)
{
    global $DB, $CFG;
    list($context, $course, $cm) = get_context_info_array($context->id);
    require_login($course, false, $cm);
    if ($filearea === 'export') {
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        //DEBUG
        //echo '<textarea cols=90 rows=20>';
        //echo $content;
        //echo '</textarea>';
        //die;
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    $attemptid = (int) array_shift($args);
    $questionid = (int) array_shift($args);
    if ($attemptid === 0) {
        // preview
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $attemptid, $questionid, $args, $forcedownload);
    } else {
        $module = $DB->get_field('question_attempts', 'modulename', array('id' => $attemptid));
        $dir = get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (!function_exists($filefunction)) {
            send_file_not_found();
        }
        $filefunction($course, $context, $component, $filearea, $attemptid, $questionid, $args, $forcedownload);
        send_file_not_found();
    }
}
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @package  core_question
 * @category files
 * @param stdClass $course course settings object
 * @param stdClass $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 array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 * @param array $options additional options affecting the file serving
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload, array $options = array())
{
    global $DB, $CFG;
    // Special case, sending a question bank export.
    if ($filearea === 'export') {
        list($context, $course, $cm) = get_context_info_array($context->id);
        require_login($course, false, $cm);
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    // Normal case, a file belonging to a question.
    $qubaidorpreview = array_shift($args);
    // Two sub-cases: 1. A question being previewed outside an attempt/usage.
    if ($qubaidorpreview === 'preview') {
        $previewcontextid = (int) array_shift($args);
        $previewcomponent = array_shift($args);
        $questionid = (int) array_shift($args);
        $previewcontext = context_helper::instance_by_id($previewcontextid);
        $result = component_callback($previewcomponent, 'question_preview_pluginfile', array($previewcontext, $questionid, $context, $component, $filearea, $args, $forcedownload, $options), 'newcallbackmissing');
        if ($result === 'newcallbackmissing' && ($filearea = 'questiontext')) {
            // Fall back to the legacy callback for backwards compatibility.
            debugging("Component {$previewcomponent} does not define the expected " . "{$previewcomponent}_question_preview_pluginfile callback. Falling back to the deprecated " . "{$previewcomponent}_questiontext_preview_pluginfile callback.", DEBUG_DEVELOPER);
            component_callback($previewcomponent, 'questiontext_preview_pluginfile', array($previewcontext, $questionid, $args, $forcedownload, $options));
        }
        send_file_not_found();
    }
    // 2. A question being attempted in the normal way.
    $qubaid = (int) $qubaidorpreview;
    $slot = (int) array_shift($args);
    $module = $DB->get_field('question_usages', 'component', array('id' => $qubaid));
    if ($module === 'core_question_preview') {
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
    } else {
        $dir = core_component::get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (function_exists($filefunction)) {
            $filefunction($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
        }
        // Okay, we're here so lets check for function without 'mod_'.
        if (strpos($module, 'mod_') === 0) {
            $filefunctionold = substr($module, 4) . '_question_pluginfile';
            if (function_exists($filefunctionold)) {
                $filefunctionold($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
            }
        }
        send_file_not_found();
    }
}
/**
 * Called by pluginfile.php to serve files related to the 'question' core
 * component and for files belonging to qtypes.
 *
 * For files that relate to questions in a question_attempt, then we delegate to
 * a function in the component that owns the attempt (for example in the quiz,
 * or in core question preview) to get necessary inforation.
 *
 * (Note that, at the moment, all question file areas relate to questions in
 * attempts, so the If at the start of the last paragraph is always true.)
 *
 * Does not return, either calls send_file_not_found(); or serves the file.
 *
 * @package  core_question
 * @category files
 * @param stdClass $course course settings object
 * @param stdClass $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 array $args the remaining bits of the file path.
 * @param bool $forcedownload whether the user must be forced to download the file.
 * @param array $options additional options affecting the file serving
 */
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload, array $options = array())
{
    global $DB, $CFG;
    if ($filearea === 'questiontext_preview') {
        $component = array_shift($args);
        $questionid = array_shift($args);
        component_callback($component, 'questiontext_preview_pluginfile', array($context, $questionid, $args, $forcedownload, $options));
        send_file_not_found();
    }
    if ($filearea === 'export') {
        list($context, $course, $cm) = get_context_info_array($context->id);
        require_login($course, false, $cm);
        require_once $CFG->dirroot . '/question/editlib.php';
        $contexts = new question_edit_contexts($context);
        // check export capability
        $contexts->require_one_edit_tab_cap('export');
        $category_id = (int) array_shift($args);
        $format = array_shift($args);
        $cattofile = array_shift($args);
        $contexttofile = array_shift($args);
        $filename = array_shift($args);
        // load parent class for import/export
        require_once $CFG->dirroot . '/question/format.php';
        require_once $CFG->dirroot . '/question/editlib.php';
        require_once $CFG->dirroot . '/question/format/' . $format . '/format.php';
        $classname = 'qformat_' . $format;
        if (!class_exists($classname)) {
            send_file_not_found();
        }
        $qformat = new $classname();
        if (!($category = $DB->get_record('question_categories', array('id' => $category_id)))) {
            send_file_not_found();
        }
        $qformat->setCategory($category);
        $qformat->setContexts($contexts->having_one_edit_tab_cap('export'));
        $qformat->setCourse($course);
        if ($cattofile == 'withcategories') {
            $qformat->setCattofile(true);
        } else {
            $qformat->setCattofile(false);
        }
        if ($contexttofile == 'withcontexts') {
            $qformat->setContexttofile(true);
        } else {
            $qformat->setContexttofile(false);
        }
        if (!$qformat->exportpreprocess()) {
            send_file_not_found();
            print_error('exporterror', 'question', $thispageurl->out());
        }
        // export data to moodle file pool
        if (!($content = $qformat->exportprocess(true))) {
            send_file_not_found();
        }
        send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
    }
    $qubaid = (int) array_shift($args);
    $slot = (int) array_shift($args);
    $module = $DB->get_field('question_usages', 'component', array('id' => $qubaid));
    if ($module === 'core_question_preview') {
        require_once $CFG->dirroot . '/question/previewlib.php';
        return question_preview_question_pluginfile($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
    } else {
        $dir = get_component_directory($module);
        if (!file_exists("{$dir}/lib.php")) {
            send_file_not_found();
        }
        include_once "{$dir}/lib.php";
        $filefunction = $module . '_question_pluginfile';
        if (function_exists($filefunction)) {
            $filefunction($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
        }
        // Okay, we're here so lets check for function without 'mod_'.
        if (strpos($module, 'mod_') === 0) {
            $filefunctionold = substr($module, 4) . '_question_pluginfile';
            if (function_exists($filefunctionold)) {
                $filefunctionold($course, $context, $component, $filearea, $qubaid, $slot, $args, $forcedownload, $options);
            }
        }
        send_file_not_found();
    }
}