Skip to content

Commit

Permalink
MDL-20636 Images in questions now work in quiz attempts.
Browse files Browse the repository at this point in the history
  • Loading branch information
timhunt committed Feb 9, 2011
1 parent 7ee80ca commit 56e82d9
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 72 deletions.
27 changes: 4 additions & 23 deletions lib/questionlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,10 @@ function question_preload_questions($questionids, $extrafields = '', $join = '',
}
list($questionidcondition, $params) = $DB->get_in_or_equal(
$questionids, SQL_PARAMS_NAMED, 'qid0000');
$sql = 'SELECT q.*' . $extrafields . ' FROM {question} q' . $join .
' WHERE q.id ' . $questionidcondition;
$sql = 'SELECT q.*, qc.contextid' . $extrafields . ' FROM {question} q
JOIN {question_categories} qc ON q.category = qc.id' .
$join .
' WHERE q.id ' . $questionidcondition;

// Load the questions
if (!$questions = $DB->get_records_sql($sql, $extraparams + $params)) {
Expand Down Expand Up @@ -1863,27 +1865,6 @@ function question_pluginfile($course, $context, $component, $filearea, $args, $f
}
}

/**
* TODO delete this. Replaced by $quba->check_file_access.
*
* Final test for whether a studnet should be allowed to see a particular file.
* This delegates the decision to the question type plugin.
*
* @param object $question The question to be rendered.
* @param object $state The state to render the question in.
* @param object $options An object specifying the rendering options.
* @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_check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args, $forcedownload) {
global $QTYPES;
return $QTYPES[$question->qtype]->check_file_access($question, $state, $options, $contextid, $component,
$filearea, $args, $forcedownload);
}

/**
* Create url for question export
*
Expand Down
2 changes: 1 addition & 1 deletion mod/quiz/attempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@

// Some hidden fields to trach what is going on.
echo '<input type="hidden" name="attempt" value="' . $attemptobj->get_attemptid() . '" />';
echo '<input type="hidden" name="thispage" id="nextpagehiddeninput" value="' . $page . '" />';
echo '<input type="hidden" name="thispage" value="' . $page . '" />';
echo '<input type="hidden" name="nextpage" id="nextpagehiddeninput" value="' . $nextpage . '" />';
echo '<input type="hidden" name="timeup" id="timeup" value="0" />';
echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
Expand Down
52 changes: 37 additions & 15 deletions mod/quiz/attemptlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,15 +375,19 @@ function __construct($attempt, $quiz, $cm, $course) {
}

/**
* Static function to create a new quiz_attempt object given an attemptid.
*
* @param integer $attemptid the attempt id.
* @return quiz_attempt the new quiz_attempt object
* Used by {create()} and {create_from_usage_id()}.
* @param array $conditions passed to $DB->get_record('quiz_attempts', $conditions).
*/
static public function create($attemptid) {
static protected function create_helper($conditions) {
global $DB;

if (!$attempt = quiz_load_attempt($attemptid)) {
// TODO deal with the issue that makes this necessary.
// if (!$DB->record_exists('question_sessions', array('attemptid' => $attempt->uniqueid))) {
// // this attempt has not yet been upgraded to the new model
// quiz_upgrade_states($attempt);
// }

if (!$attempt = $DB->get_record('quiz_attempts', $conditions)) {
throw new moodle_exception('invalidattemptid', 'quiz');
}
if (!$quiz = $DB->get_record('quiz', array('id' => $attempt->quiz))) {
Expand All @@ -402,6 +406,26 @@ static public function create($attemptid) {
return new quiz_attempt($attempt, $quiz, $cm, $course);
}

/**
* Static function to create a new quiz_attempt object given an attemptid.
*
* @param integer $attemptid the attempt id.
* @return quiz_attempt the new quiz_attempt object
*/
static public function create($attemptid) {
return self::create_helper(array('id' => $attemptid));
}

/**
* Static function to create a new quiz_attempt object given a usage id.
*
* @param integer $usageid the attempt usage id.
* @return quiz_attempt the new quiz_attempt object
*/
static public function create_from_usage_id($usageid) {
return self::create_helper(array('uniqueid' => $usageid));
}

private function determine_layout() {
$this->pagelayout = array();

Expand Down Expand Up @@ -637,7 +661,6 @@ public function is_last_page($page) {
* @return array the reqested list of question ids.
*/
public function get_slots($page = 'all') {
// TODO rename to get_slots
if ($page === 'all') {
$numbers = array();
foreach ($this->pagelayout as $numbersonpage) {
Expand Down Expand Up @@ -757,7 +780,7 @@ public function start_attempt_url() {
* this page to be output as only a fragment.
* @return string the URL to continue this attempt.
*/
public function attempt_url($slot = 0, $page = -1, $thispage = -1) {
public function attempt_url($slot = null, $page = -1, $thispage = -1) {
return $this->page_and_question_url('attempt', $slot, $page, false, $thispage);
}

Expand Down Expand Up @@ -785,7 +808,7 @@ public function processattempt_url() {
* this page to be output as only a fragment.
* @return string the URL to review this attempt.
*/
public function review_url($slot = 0, $page = -1, $showall = false, $thispage = -1) {
public function review_url($slot = null, $page = -1, $showall = false, $thispage = -1) {
return $this->page_and_question_url('review', $slot, $page, $showall, $thispage);
}

Expand Down Expand Up @@ -889,11 +912,10 @@ public function render_question_for_commenting($slot) {
* @param string $thispageurl the URL of the page this question is being printed on.
* @return string HTML for the question in its current state.
*/
public function check_file_access($questionid, $reviewing, $contextid, $component,
public function check_file_access($slot, $reviewing, $contextid, $component,
$filearea, $args, $forcedownload) {
return question_check_file_access($this->questions[$questionid],
$this->get_question_state($questionid), $this->get_display_options($reviewing),
$contextid, $component, $filearea, $args, $forcedownload);
return $this->quba->check_file_access($slot, $this->get_display_options($reviewing),
$component, $filearea, $args, $forcedownload);
}

/**
Expand Down Expand Up @@ -1030,7 +1052,7 @@ public function question_print_comment_fields($slot, $prefix) {
protected function page_and_question_url($script, $slot, $page, $showall, $thispage) {
// Fix up $page
if ($page == -1) {
if ($slot && !$showall) {
if (!is_null($slot) && !$showall) {
$page = $this->quba->get_question($slot)->_page;
} else {
$page = 0;
Expand All @@ -1043,7 +1065,7 @@ protected function page_and_question_url($script, $slot, $page, $showall, $thisp

// Add a fragment to scroll down to the question.
$fragment = '';
if ($slot) {
if (!is_null($slot)) {
if ($slot == reset($this->pagelayout[$page])) {
// First question on page, go to top.
$fragment = '#';
Expand Down
11 changes: 4 additions & 7 deletions mod/quiz/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1608,16 +1608,13 @@ function quiz_pluginfile($course, $cm, $context, $filearea, $args, $forcedownloa
* @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 quiz_question_pluginfile($course, $context, $component,
$filearea, $attemptid, $questionid, $args, $forcedownload) {
function mod_quiz_question_pluginfile($course, $context, $component,
$filearea, $qubaid, $slot, $args, $forcedownload) {
global $USER, $CFG;
require_once($CFG->dirroot . '/mod/quiz/locallib.php');

$attemptobj = quiz_attempt::create($attemptid);
$attemptobj = quiz_attempt::create_from_usage_id($qubaid);
require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm());
$questionids = array($questionid);
$attemptobj->load_questions($questionids);
$attemptobj->load_question_states($questionids);

if ($attemptobj->is_own_attempt() && !$attemptobj->is_finished()) {
// In the middle of an attempt.
Expand All @@ -1632,7 +1629,7 @@ function quiz_question_pluginfile($course, $context, $component,
$isreviewing = true;
}

if (!$attemptobj->check_file_access($questionid, $isreviewing, $context->id,
if (!$attemptobj->check_file_access($slot, $isreviewing, $context->id,
$component, $filearea, $args, $forcedownload)) {
send_file_not_found();
}
Expand Down
23 changes: 0 additions & 23 deletions mod/quiz/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,29 +157,6 @@ function quiz_get_latest_attempt_by_user($quizid, $userid) {
}
}

/**
* Load an attempt by id. You need to use this method instead of $DB->get_record, because
* of some ancient history to do with the upgrade from Moodle 1.4 to 1.5, See the comment
* after CREATE TABLE `prefix_quiz_newest_states` in mod/quiz/db/mysql.php.
*
* @param integer $attemptid the id of the attempt to load.
*/
function quiz_load_attempt($attemptid) {
global $DB;
$attempt = $DB->get_record('quiz_attempts', array('id' => $attemptid));
if (!$attempt) {
return false;
}

// TODO deal with the issue that makes this necessary.
// if (!$DB->record_exists('question_sessions', array('attemptid' => $attempt->uniqueid))) {
// /// this attempt has not yet been upgraded to the new model
// quiz_upgrade_states($attempt);
// }

return $attempt;
}

/**
* Delete a quiz attempt.
* @param mixed $attempt an integer attempt id or an attempt object (row of the quiz_attempts table).
Expand Down
2 changes: 1 addition & 1 deletion mod/quiz/processattempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
} else {
$nexturl = $attemptobj->attempt_url(0, $page);
if ($scrollpos !== '') {
$nexturl .= '&scrollpos=' . ((int) $scrollpos);
$nexturl->param('scrollpos', $scrollpos);
}
}

Expand Down
6 changes: 5 additions & 1 deletion question/engine/bank.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ public static function load_question($questionid, $allowshuffle = true) {
return self::return_test_question_data($questionid);
}

$questiondata = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST);
$questiondata = $DB->get_record_sql('
SELECT q.*, qc.contextid
FROM {question} q
JOIN {question_categories} qc ON q.category = qc.id
WHERE q.id = :id', array('id' => $questionid), MUST_EXIST);
get_question_options($questiondata);
if (!$allowshuffle) {
$questiondata->options->shuffleanswers = false;
Expand Down
3 changes: 2 additions & 1 deletion question/engine/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,7 @@ class question_attempt {
protected $usageid;

/** @var integer the id of the context this question_attempt belongs to. */
// TODO I don't think this is actually needed.
protected $owningcontextid = null;

/** @var integer the number used to identify this question_attempt within the usage. */
Expand Down Expand Up @@ -1808,7 +1809,7 @@ public function summarise_action(question_attempt_step $step) {
*/
public function rewrite_pluginfile_urls($text, $component, $filearea, $itemid) {
return question_rewrite_question_urls($text,
'pluginfile.php', $this->owningcontextid, $component, $filearea,
'pluginfile.php', $this->question->contextid, $component, $filearea,
array($this->get_usage_id(), $this->get_slot()), $itemid);
}

Expand Down
1 change: 1 addition & 0 deletions question/type/ddwtos/simpletest/testquestiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ protected function get_test_question_data() {
$dd = new stdClass;
$dd->id = 0;
$dd->category = 0;
$dd->contextid = 0;
$dd->parent = 0;
$dd->questiontextformat = FORMAT_HTML;
$dd->generalfeedbackformat = FORMAT_HTML;
Expand Down
1 change: 1 addition & 0 deletions question/type/gapselect/simpletest/testquestiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ protected function get_test_question_data() {
$gapselect = new stdClass;
$gapselect->id = 0;
$gapselect->category = 0;
$gapselect->contextid = 0;
$gapselect->parent = 0;
$gapselect->questiontextformat = FORMAT_HTML;
$gapselect->generalfeedbackformat = FORMAT_HTML;
Expand Down
4 changes: 4 additions & 0 deletions question/type/match/simpletest/testquestiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/


require_once($CFG->dirroot . '/question/engine/simpletest/helpers.php');
require_once($CFG->dirroot . '/question/type/match/questiontype.php');


/**
* Unit tests for the matching question definition class.
*
Expand All @@ -50,6 +53,7 @@ protected function get_test_question_data() {
$q->id = 0;
$q->name = 'Matching question';
$q->category = 0;
$q->contextid = 0;
$q->parent = 0;
$q->questiontext = 'Classify the animals.';
$q->questiontextformat = FORMAT_HTML;
Expand Down
1 change: 1 addition & 0 deletions question/type/missingtype/simpletest/testmissingtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ protected function get_unknown_questiondata() {
$questiondata = new stdClass;
$questiondata->id = 0;
$questiondata->category = 0;
$questiondata->contextid = 0;
$questiondata->parent = 0;
$questiondata->name = 'Test';
$questiondata->questiontext = 'This is the question text.';
Expand Down
3 changes: 3 additions & 0 deletions question/type/questionbase.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ abstract class question_definition {
/** @var integer question category id. */
public $category;

/** @var integer question category id. */
public $contextid;

/** @var integer parent question id. */
public $parent = 0;

Expand Down
1 change: 1 addition & 0 deletions question/type/questiontype.php
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ protected function make_question_instance($questiondata) {
protected function initialise_question_instance(question_definition $question, $questiondata) {
$question->id = $questiondata->id;
$question->category = $questiondata->category;
$question->contextid = $questiondata->contextid;
$question->parent = $questiondata->parent;
$question->qtype = $this;
$question->name = $questiondata->name;
Expand Down

0 comments on commit 56e82d9

Please sign in to comment.