From 56a4ae4673c7659ac99c46c99d5620831f229917 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 29 Jun 2011 14:39:16 +0100 Subject: [PATCH] MDL-28074 question preview should set context/course/cm properly. 1. We need this so that, for example, when previewing a question from the quiz editing page, the preview uses the filter settings, theme and language set for that quiz and course. --- lib/questionlib.php | 14 ++++++++++++- mod/quiz/locallib.php | 2 +- question/editlib.php | 3 ++- question/preview.php | 45 ++++++++++++++++++++++++++++------------- question/previewlib.php | 34 ++++++++++++++++++++++++------- 5 files changed, 74 insertions(+), 24 deletions(-) diff --git a/lib/questionlib.php b/lib/questionlib.php index 5c7d89f42be..3b43fc91a60 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -640,13 +640,25 @@ function question_move_category_to_context($categoryid, $oldcontextid, $newconte * @param question_display_options $displayoptions the display options to use. * @param int $variant the variant of the question to preview. If null, one will * be picked randomly. + * @param object $context context to run the preview in (affects things like + * filter settings, theme, lang, etc.) Defaults to $PAGE->context. * @return string the URL. */ function question_preview_url($questionid, $preferredbehaviour = null, - $maxmark = null, $displayoptions = null, $variant = null) { + $maxmark = null, $displayoptions = null, $variant = null, $context = null) { $params = array('id' => $questionid); + if (is_null($context)) { + global $PAGE; + $context = $PAGE->context; + } + if ($context->contextlevel == CONTEXT_MODULE) { + $params['cmid'] = $context->instanceid; + } else if ($context->contextlevel == CONTEXT_COURSE) { + $params['courseid'] = $context->instanceid; + } + if (!is_null($preferredbehaviour)) { $params['behaviour'] = $preferredbehaviour; } diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 3efca32792e..0e5718215db 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -880,7 +880,7 @@ function quiz_question_preview_url($quiz, $question) { * @return the HTML for a preview question icon. */ function quiz_question_preview_button($quiz, $question, $label = false) { - global $CFG, $COURSE, $OUTPUT; + global $CFG, $OUTPUT; if (!question_has_capability_on($question, 'use', $question->category)) { return ''; } diff --git a/question/editlib.php b/question/editlib.php index afb8891bc0d..d7c082a2776 100644 --- a/question/editlib.php +++ b/question/editlib.php @@ -1152,7 +1152,8 @@ class question_bank_view { } public function preview_question_url($question) { - return question_preview_url($question->id); + return question_preview_url($question->id, null, null, null, null, + $this->contexts->lowest()); } /** diff --git a/question/preview.php b/question/preview.php index e6085a6a8b0..ea243991753 100644 --- a/question/preview.php +++ b/question/preview.php @@ -37,19 +37,36 @@ require_once(dirname(__FILE__) . '/previewlib.php'); // Get and validate question id. $id = required_param('id', PARAM_INT); $question = question_bank::load_question($id); -require_login(); -$category = $DB->get_record('question_categories', - array('id' => $question->category), '*', MUST_EXIST); -question_require_capability_on($question, 'use'); $PAGE->set_pagelayout('popup'); -$PAGE->set_context(get_context_instance_by_id($category->contextid)); + +// Were we given a particular context to run the question in? +// This affects things like filter settings, or forced theme or language. +if ($cmid = optional_param('cmid', 0, PARAM_INT)) { + $cm = get_coursemodule_from_id(false, $cmid); + require_login($cm->course, false, $cm); + $context = get_context_instance(CONTEXT_MODULE, $cmid); + +} else if ($courseid = optional_param('courseid', 0, PARAM_INT)) { + require_login($courseid); + $context = get_context_instance(CONTEXT_COURSE, $courseid); + +} else { + require_login(); + $category = $DB->get_record('question_categories', + array('id' => $question->category), '*', MUST_EXIST); + $context = get_context_instance_by_id($category->contextid); + $PAGE->set_context($context); + // Note that in the other cases, require_login will set the correct page context. +} +question_require_capability_on($question, 'use'); // Get and validate display options. $maxvariant = $question->get_num_variants(); $options = new question_preview_options($question); $options->load_user_defaults(); $options->set_from_request(); -$PAGE->set_url(question_preview_url($id, $options->behaviour, $options->maxmark, $options)); +$PAGE->set_url(question_preview_url($id, $options->behaviour, $options->maxmark, + $options, $options->variant, $context)); // Get and validate exitsing preview, or start a new one. $previewid = optional_param('previewid', 0, PARAM_INT); @@ -63,7 +80,7 @@ if ($previewid) { } catch (Exception $e) { print_error('submissionoutofsequencefriendlymessage', 'question', question_preview_url($question->id, $options->behaviour, - $options->maxmark, $options), null, $e); + $options->maxmark, $options, $options->variant, $context), null, $e); } $slot = $quba->get_first_question_number(); $usedquestion = $quba->get_question($slot); @@ -74,8 +91,8 @@ if ($previewid) { $options->variant = $quba->get_variant($slot); } else { - $quba = question_engine::make_questions_usage_by_activity('core_question_preview', - get_context_instance_by_id($category->contextid)); + $quba = question_engine::make_questions_usage_by_activity( + 'core_question_preview', $context); $quba->set_preferred_behaviour($options->behaviour); $slot = $quba->add_question($question, $options->maxmark); @@ -97,8 +114,8 @@ $options->behaviour = $quba->get_preferred_behaviour(); $options->maxmark = $quba->get_question_max_mark($slot); // Create the settings form, and initialise the fields. -$optionsform = new preview_options_form(new moodle_url('/question/preview.php', - array('id' => $question->id)), array('quba' => $quba, 'maxvariant' => $maxvariant)); +$optionsform = new preview_options_form(question_preview_form_url($question->id, $context), + array('quba' => $quba, 'maxvariant' => $maxvariant)); $optionsform->set_data($options); // Process change of settings, if that was requested. @@ -108,16 +125,16 @@ if ($newoptions = $optionsform->get_submitted_data()) { if (!isset($newoptions->variant)) { $newoptions->variant = $options->variant; } - restart_preview($previewid, $question->id, $newoptions); + restart_preview($previewid, $question->id, $newoptions, $context); } // Prepare a URL that is used in various places. -$actionurl = question_preview_action_url($question->id, $quba->get_id(), $options); +$actionurl = question_preview_action_url($question->id, $quba->get_id(), $options, $context); // Process any actions from the buttons at the bottom of the form. if (data_submitted() && confirm_sesskey()) { if (optional_param('restart', false, PARAM_BOOL)) { - restart_preview($previewid, $question->id, $options); + restart_preview($previewid, $question->id, $options, $context); } else if (optional_param('fill', null, PARAM_BOOL)) { $correctresponse = $quba->get_correct_response($slot); diff --git a/question/previewlib.php b/question/previewlib.php index 6e34333bc64..0978e87d902 100644 --- a/question/previewlib.php +++ b/question/previewlib.php @@ -230,10 +230,6 @@ function question_preview_question_pluginfile($course, $context, $component, $quba = question_engine::load_questions_usage_by_activity($qubaid); - if ($quba->get_owning_context()->id != $context->id) { - send_file_not_found(); - } - if (!question_has_capability_on($quba->get_question($slot), 'use')) { send_file_not_found(); } @@ -267,22 +263,46 @@ function question_preview_question_pluginfile($course, $context, $component, * @param question_preview_options $options the options in use. */ function question_preview_action_url($questionid, $qubaid, - question_preview_options $options) { + question_preview_options $options, $context) { $params = array( 'id' => $questionid, 'previewid' => $qubaid, ); + if ($context->contextlevel == CONTEXT_MODULE) { + $params['cmid'] = $context->instanceid; + } else if ($context->contextlevel == CONTEXT_COURSE) { + $params['courseid'] = $context->instanceid; + } $params = array_merge($params, $options->get_url_params()); return new moodle_url('/question/preview.php', $params); } +/** + * The the URL to use for actions relating to this preview. + * @param int $questionid the question being previewed. + * @param int $qubaid the id of the question usage for this preview. + * @param question_preview_options $options the options in use. + */ +function question_preview_form_url($questionid, $context) { + $params = array( + 'id' => $questionid, + ); + if ($context->contextlevel == CONTEXT_MODULE) { + $params['cmid'] = $context->instanceid; + } else if ($context->contextlevel == CONTEXT_COURSE) { + $params['courseid'] = $context->instanceid; + } + return new moodle_url('/question/preview.php', $params); +} + /** * Delete the current preview, if any, and redirect to start a new preview. * @param int $previewid * @param int $questionid * @param object $displayoptions + * @param object $context */ -function restart_preview($previewid, $questionid, $displayoptions) { +function restart_preview($previewid, $questionid, $displayoptions, $context) { global $DB; if ($previewid) { @@ -291,5 +311,5 @@ function restart_preview($previewid, $questionid, $displayoptions) { $transaction->allow_commit(); } redirect(question_preview_url($questionid, $displayoptions->behaviour, - $displayoptions->maxmark, $displayoptions, $displayoptions->variant)); + $displayoptions->maxmark, $displayoptions, $displayoptions->variant, $context)); }