moodle/question/preview.php

237 lines
8.9 KiB
PHP
Raw Normal View History

<?php // $Id$
/**
* This page displays a preview of a question
*
* The preview uses the option settings from the activity within which the question
* is previewed or the default settings if no activity is specified. The question session
* information is stored in the session as an array of subsequent states rather
* than in the database.
*
* TODO: make this work with activities other than quiz
*
* @author Alex Smith as part of the Serving Mathematics project
* {@link http://maths.york.ac.uk/serving_maths}
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package questionbank
*/
require_once("../config.php");
require_once($CFG->libdir.'/questionlib.php');
require_once($CFG->dirroot.'/mod/quiz/locallib.php'); // We really want to get rid of this
$id = required_param('id', PARAM_INT); // question id
// if no quiz id is specified then a dummy quiz with default options is used
$quizid = optional_param('quizid', 0, PARAM_INT);
// if no quiz id is specified then tell us the course
if (empty($quizid)) {
$courseid = required_param('courseid', PARAM_INT);
}
// Test if we are continuing an attempt at a question
$continue = optional_param('continue', 0, PARAM_BOOL);
// Check for any of the submit buttons
$fillcorrect = optional_param('fillcorrect', 0, PARAM_BOOL);
$markall = optional_param('markall', 0, PARAM_BOOL);
$finishattempt = optional_param('finishattempt', 0, PARAM_BOOL);
$back = optional_param('back', 0, PARAM_BOOL);
$startagain = optional_param('startagain', 0, PARAM_BOOL);
// We are always continuing an attempt if a submit button was pressed with the
// exception of the start again button
if ($fillcorrect || $markall || $finishattempt || $back) {
$continue = true;
} else if ($startagain) {
$continue = false;
}
2007-09-04 05:44:14 +00:00
$url = new moodle_url($CFG->wwwroot . '/question/preview.php');
$url->param('id', $id);
if ($quizid) {
$url->param('quizid', $quizid);
} else {
$url->param('courseid', $courseid);
}
$url->param('continue', 1);
if (!$continue) {
// Start a new attempt; delete the old session
unset($SESSION->quizpreview);
// Redirect to ourselves but with continue=1; prevents refreshing the page
// from restarting an attempt (needed so that random questions don't change)
2007-09-04 05:44:14 +00:00
redirect($url->out());
}
2007-08-09 21:51:09 +00:00
// Load the question information
if (!$questions = get_records('question', 'id', $id)) {
error('Could not load question');
}
if (empty($quizid)) {
$quiz = new cmoptions;
$quiz->id = 0;
2006-03-21 20:55:23 +00:00
$quiz->review = $CFG->quiz_review;
require_login($courseid, false);
$quiz->course = $courseid;
} else if (!$quiz = get_record('quiz', 'id', $quizid)) {
error("Quiz id $quizid does not exist");
2007-08-09 21:51:09 +00:00
} else {
require_login($quiz->course, false, get_coursemodule_from_instance('quiz', $quizid, $quiz->course));
}
2007-08-09 21:51:09 +00:00
if ($maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $id)) {
$questions[$id]->maxgrade = $maxgrade;
} else {
$questions[$id]->maxgrade = $questions[$id]->defaultgrade;
}
$quiz->id = 0; // just for safety
$quiz->questions = $id;
if (!$category = get_record("question_categories", "id", $questions[$id]->category)) {
error("This question doesn't belong to a valid category!");
}
2007-08-09 21:51:09 +00:00
if (!question_has_capability_on($questions[$id], 'use', $questions[$id]->category)){
error("You can't preview these questions!");
}
2007-08-09 21:51:09 +00:00
if (isset($COURSE)){
$quiz->course = $COURSE->id;
}
// Load the question type specific information
Towards removing reference to quiz module from the question code Renaming tables: quiz_questions -> question quiz_states -> question_states Renaming functions: quiz_delete_question -> delete_question quiz_get_question_options -> get_question_options quiz_get_states -> get_question_states quiz_restore_state -> restore_question_state quiz_save_question_session -> save_question_session quiz_state_is_graded -> question_state_is_graded quiz_extract_responses -> question_extract_responses quiz_regrade_question_in_attempt -> regrade_question_in_attempt quiz_process_responses -> question_process_responses quiz_isgradingevent -> question_isgradingevent($event) quiz_search_for_duplicate_responses -> question_search_for_duplicate_responses quiz_apply_penalty_and_timelimit -> question_apply_penalty_and_timelimit quiz_print_question_icon -> print_question_icon quiz_get_image -> get_question_image quiz_make_name_prefix -> question_make_name_prefix quiz_get_id_from_name_prefix -> question_get_id_from_name_prefix quiz_new_attempt_uniqueid -> question_new_attempt_uniqueid quiz_get_renderoptions -> question_get_renderoptions quiz_print_quiz_question -> print_question quiz_get_question_responses -> get_question_responses quiz_get_question_actual_response -> get_question_actual_response quiz_get_question_fraction_grade -> get_question_fraction_grade quiz_get_default_category -> get_default_question_category Renaming constants: QUIZ_EVENT.... -> QUESTION_EVENT.... QUIZ_MAX_NUMBER_ANSWERS -> QUESTION_NUMANS
2006-02-28 09:26:00 +00:00
if (!get_question_options($questions)) {
error(get_string('newattemptfail', 'quiz'));
}
// Create a dummy quiz attempt
// TODO: find out what of the following we really need. What is $attempt
// really used for?
$timenow = time();
$attempt->quiz = $quiz->id;
$attempt->userid = $USER->id;
$attempt->attempt = 0;
$attempt->sumgrades = 0;
$attempt->timestart = $timenow;
$attempt->timefinish = 0;
$attempt->timemodified = $timenow;
$attempt->uniqueid = 0;
$attempt->id = 0;
// Restore the history of question sessions from the moodle session or create
// new sessions. Make $states a reference to the states array in the moodle
// session.
2007-09-04 05:44:14 +00:00
if (isset($SESSION->quizpreview->states) and $SESSION->quizpreview->questionid == $id) {
// Reload the question session history from the moodle session
$states =& $SESSION->quizpreview->states;
$historylength = count($states) - 1;
if ($back && $historylength > 0) {
// Go back one step in the history
unset($states[$historylength]);
$historylength--;
}
} else {
// Record the question id in the moodle session
$SESSION->quizpreview->questionid = $id;
// Create an empty session for the question
if (!$newstates =
Towards removing reference to quiz module from the question code Renaming tables: quiz_questions -> question quiz_states -> question_states Renaming functions: quiz_delete_question -> delete_question quiz_get_question_options -> get_question_options quiz_get_states -> get_question_states quiz_restore_state -> restore_question_state quiz_save_question_session -> save_question_session quiz_state_is_graded -> question_state_is_graded quiz_extract_responses -> question_extract_responses quiz_regrade_question_in_attempt -> regrade_question_in_attempt quiz_process_responses -> question_process_responses quiz_isgradingevent -> question_isgradingevent($event) quiz_search_for_duplicate_responses -> question_search_for_duplicate_responses quiz_apply_penalty_and_timelimit -> question_apply_penalty_and_timelimit quiz_print_question_icon -> print_question_icon quiz_get_image -> get_question_image quiz_make_name_prefix -> question_make_name_prefix quiz_get_id_from_name_prefix -> question_get_id_from_name_prefix quiz_new_attempt_uniqueid -> question_new_attempt_uniqueid quiz_get_renderoptions -> question_get_renderoptions quiz_print_quiz_question -> print_question quiz_get_question_responses -> get_question_responses quiz_get_question_actual_response -> get_question_actual_response quiz_get_question_fraction_grade -> get_question_fraction_grade quiz_get_default_category -> get_default_question_category Renaming constants: QUIZ_EVENT.... -> QUESTION_EVENT.... QUIZ_MAX_NUMBER_ANSWERS -> QUESTION_NUMANS
2006-02-28 09:26:00 +00:00
get_question_states($questions, $quiz, $attempt)) {
error(get_string('newattemptfail', 'quiz'));
}
$SESSION->quizpreview->states = array($newstates);
$states =& $SESSION->quizpreview->states;
$historylength = 0;
}
if (!$fillcorrect && !$back && ($form = data_submitted())) {
$form = (array)$form;
$submitted = true;
// Create a new item in the history of question states (don't simplify!)
$states[$historylength + 1] = array();
$states[$historylength + 1][$id] = clone($states[$historylength][$id]);
$historylength++;
$curstate =& $states[$historylength][$id];
$curstate->changed = false;
// Process the responses
unset($form['id']);
unset($form['quizid']);
unset($form['continue']);
unset($form['markall']);
unset($form['finishattempt']);
unset($form['back']);
unset($form['startagain']);
$event = $finishattempt ? QUESTION_EVENTCLOSE : QUESTION_EVENTSUBMIT;
Towards removing reference to quiz module from the question code Renaming tables: quiz_questions -> question quiz_states -> question_states Renaming functions: quiz_delete_question -> delete_question quiz_get_question_options -> get_question_options quiz_get_states -> get_question_states quiz_restore_state -> restore_question_state quiz_save_question_session -> save_question_session quiz_state_is_graded -> question_state_is_graded quiz_extract_responses -> question_extract_responses quiz_regrade_question_in_attempt -> regrade_question_in_attempt quiz_process_responses -> question_process_responses quiz_isgradingevent -> question_isgradingevent($event) quiz_search_for_duplicate_responses -> question_search_for_duplicate_responses quiz_apply_penalty_and_timelimit -> question_apply_penalty_and_timelimit quiz_print_question_icon -> print_question_icon quiz_get_image -> get_question_image quiz_make_name_prefix -> question_make_name_prefix quiz_get_id_from_name_prefix -> question_get_id_from_name_prefix quiz_new_attempt_uniqueid -> question_new_attempt_uniqueid quiz_get_renderoptions -> question_get_renderoptions quiz_print_quiz_question -> print_question quiz_get_question_responses -> get_question_responses quiz_get_question_actual_response -> get_question_actual_response quiz_get_question_fraction_grade -> get_question_fraction_grade quiz_get_default_category -> get_default_question_category Renaming constants: QUIZ_EVENT.... -> QUESTION_EVENT.... QUIZ_MAX_NUMBER_ANSWERS -> QUESTION_NUMANS
2006-02-28 09:26:00 +00:00
if ($actions = question_extract_responses($questions, $form, $event)) {
$actions[$id]->timestamp = 0; // We do not care about timelimits here
question_process_responses($questions[$id], $curstate, $actions[$id], $quiz, $attempt);
if (!$curstate->changed) {
// Update the current state rather than creating a new one
$historylength--;
unset($states[$historylength]);
$states = array_values($states);
$curstate =& $states[$historylength][$id];
}
}
} else {
$submitted = false;
$curstate =& $states[$historylength][$id];
}
// TODO: should not use quiz-specific function here
$options = quiz_get_renderoptions($quiz->review, $curstate);
// Fill in the correct responses (unless the question is in readonly mode)
if ($fillcorrect && !$options->readonly) {
2006-02-24 13:48:43 +00:00
$curstate->responses = $QTYPES[$questions[$id]->qtype]
->get_correct_responses($questions[$id], $curstate);
}
$strpreview = get_string('preview', 'quiz').' '.format_string($questions[$id]->name);
$questionlist = array($id);
$headtags = get_html_head_contributions($questionlist, $questions, $states[$historylength]);
print_header($strpreview, '', '', '', $headtags);
print_heading($strpreview);
if (!empty($quizid)) {
2007-01-08 07:38:29 +00:00
echo '<p class="quemodname">'.get_string('modulename', 'quiz') . ': ';
p(format_string($quiz->name));
echo "</p>\n";
}
$number = 1;
2007-09-04 05:44:14 +00:00
echo '<form method="post" action="'.$url->out(true).'" enctype="multipart/form-data" id="responseform">', "\n";
Towards removing reference to quiz module from the question code Renaming tables: quiz_questions -> question quiz_states -> question_states Renaming functions: quiz_delete_question -> delete_question quiz_get_question_options -> get_question_options quiz_get_states -> get_question_states quiz_restore_state -> restore_question_state quiz_save_question_session -> save_question_session quiz_state_is_graded -> question_state_is_graded quiz_extract_responses -> question_extract_responses quiz_regrade_question_in_attempt -> regrade_question_in_attempt quiz_process_responses -> question_process_responses quiz_isgradingevent -> question_isgradingevent($event) quiz_search_for_duplicate_responses -> question_search_for_duplicate_responses quiz_apply_penalty_and_timelimit -> question_apply_penalty_and_timelimit quiz_print_question_icon -> print_question_icon quiz_get_image -> get_question_image quiz_make_name_prefix -> question_make_name_prefix quiz_get_id_from_name_prefix -> question_get_id_from_name_prefix quiz_new_attempt_uniqueid -> question_new_attempt_uniqueid quiz_get_renderoptions -> question_get_renderoptions quiz_print_quiz_question -> print_question quiz_get_question_responses -> get_question_responses quiz_get_question_actual_response -> get_question_actual_response quiz_get_question_fraction_grade -> get_question_fraction_grade quiz_get_default_category -> get_default_question_category Renaming constants: QUIZ_EVENT.... -> QUESTION_EVENT.... QUIZ_MAX_NUMBER_ANSWERS -> QUESTION_NUMANS
2006-02-28 09:26:00 +00:00
print_question($questions[$id], $curstate, $number, $quiz, $options);
echo '<br />';
2007-01-08 07:45:53 +00:00
2007-08-09 21:51:09 +00:00
2007-01-08 07:38:29 +00:00
echo '<div class="controls">';
2007-09-04 05:44:14 +00:00
echo $url->hidden_params_out();
// Print the mark and finish attempt buttons
echo '<input name="markall" type="submit" value="' . get_string('markall',
'quiz') . "\" />\n";
echo '<input name="finishattempt" type="submit" value="' .
get_string('finishattempt', 'quiz') . "\" />\n";
echo '<br />';
echo '<br />';
// Print the fill correct button (unless the question is in readonly mode)
if (!$options->readonly) {
echo '<input name="fillcorrect" type="submit" value="' .
get_string('fillcorrect', 'quiz') . "\" />\n";
}
// Print the navigation buttons
if ($historylength > 0) {
echo '<input name="back" type="submit" value="' . get_string('previous',
'quiz') . "\" />\n";
}
// Print the start again button
echo '<input name="startagain" type="submit" value="' .
get_string('startagain', 'quiz') . "\" />\n";
// Print the close window button
echo '<input type="button" onclick="window.close()" value="' .
get_string('closepreview', 'quiz') . "\" />";
2007-01-08 07:38:29 +00:00
echo '</div>';
echo '</form>';
print_footer();
?>