a8c95959277a88db67bd30a47a2718af5f131f81
[moodle.git] / mod / quiz / attempt.php
1 <?php
2 /**
3  * This page prints a particular instance of quiz
4  *
5  * @author Martin Dougiamas and many others. This has recently been completely
6  *         rewritten by Alex Smith, Julian Sedding and Gustav Delius as part of
7  *         the Serving Mathematics project
8  *         {@link http://maths.york.ac.uk/serving_maths}
9  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
10  * @package quiz
11  */
13     require_once(dirname(__FILE__) . '/../../config.php');
14     require_once($CFG->dirroot . '/mod/quiz/locallib.php');
16 /// Look for old-style URLs, such as may be in the logs, and redirect them to startattemtp.php
17     if ($id = optional_param('id', 0, PARAM_INTEGER)) {
18         redirect($CFG->wwwroot . '/mod/quiz/startattempt.php?cmid=' . $id . '&sesskey=' . sesskey());
19     } else if ($qid = optional_param('q', 0, PARAM_INTEGER)) {
20         if (!$cm = get_coursemodule_from_instance('quiz', $qid)) {
21             print_error('invalidquizid', 'quiz');
22         }
23         redirect($CFG->wwwroot . '/mod/quiz/startattempt.php?cmid=' . $cm->id . '&sesskey=' . sesskey());
24     }
26 /// Get submitted parameters.
27     $attemptid = required_param('attempt', PARAM_INT);
28     $page = optional_param('page', 0, PARAM_INT);
30     $url = new moodle_url('/mod/quiz/attempt.php', array('attempt' => $attemptid));
31     if ($page !== 0) {
32         $url->param('page', $page);
33     }
34     $PAGE->set_url($url);
36     $attemptobj = quiz_attempt::create($attemptid);
38 /// Check login.
39     require_login($attemptobj->get_course(), false, $attemptobj->get_cm());
41 /// Check that this attempt belongs to this user.
42     if ($attemptobj->get_userid() != $USER->id) {
43         if ($attemptobj->has_capability('mod/quiz:viewreports')) {
44             redirect($attemptobj->review_url(0, $page));
45         } else {
46             quiz_error($attemptobj->get_quiz(), 'notyourattempt');
47         }
48     }
50 /// Check capabilities and block settings
51     if (!$attemptobj->is_preview_user()) {
52         $attemptobj->require_capability('mod/quiz:attempt');
53         if (empty($attemptobj->get_quiz()->showblocks)) {
54             $PAGE->blocks->show_only_fake_blocks();
55         }
57     } else {
58         navigation_node::override_active_url($attemptobj->start_attempt_url());
59     }
61 /// If the attempt is already closed, send them to the review page.
62     if ($attemptobj->is_finished()) {
63         redirect($attemptobj->review_url(0, $page));
64     }
66 /// Check the access rules.
67     $accessmanager = $attemptobj->get_access_manager(time());
68     $messages = $accessmanager->prevent_access();
69     if (!$attemptobj->is_preview_user() && $messages) {
70         print_error('attempterror', 'quiz', $quizobj->view_url(),
71                 $accessmanager->print_messages($messages, true));
72     }
73     $accessmanager->do_password_check($attemptobj->is_preview_user());
75     add_to_log($attemptobj->get_courseid(), 'quiz', 'continue attempt',
76             'review.php?attempt=' . $attemptobj->get_attemptid(),
77             $attemptobj->get_quizid(), $attemptobj->get_cmid());
79 /// Get the list of questions needed by this page.
80     $questionids = $attemptobj->get_question_ids($page);
82 /// Check.
83     if (empty($questionids)) {
84         quiz_error($quiz, 'noquestionsfound');
85     }
87 /// Load those questions and the associated states.
88     $attemptobj->load_questions($questionids);
89     $attemptobj->load_question_states($questionids);
91 /// Print the quiz page ////////////////////////////////////////////////////////
93     // Initialise the JavaScript.
94     $headtags = $attemptobj->get_html_head_contributions($page);
95     $PAGE->requires->js_init_call('M.mod_quiz.init_attempt_form', null, false, quiz_get_js_module());
97     // Arrange for the navigation to be displayed.
98     $navbc = $attemptobj->get_navigation_panel('quiz_attempt_nav_panel', $page);
99     $firstregion = reset($PAGE->blocks->get_regions());
100     $PAGE->blocks->add_pretend_block($navbc, $firstregion);
102     // Print the page header
103     $title = get_string('attempt', 'quiz', $attemptobj->get_attempt_number());
104     $PAGE->set_heading($attemptobj->get_course()->fullname);
105     if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
106         $accessmanager->setup_secure_page($attemptobj->get_course()->shortname . ': ' .
107                 format_string($attemptobj->get_quiz_name()));
108     } else if ($accessmanager->safebrowser_required($attemptobj->is_preview_user())) {
109         $PAGE->set_title($attemptobj->get_course()->shortname . ': '.format_string($attemptobj->get_quiz_name()));
110         $PAGE->set_cacheable(false);
111         echo $OUTPUT->header();
112     } else {
113         $PAGE->set_title(format_string($attemptobj->get_quiz_name()));
114         echo $OUTPUT->header();
115     }
117     if ($attemptobj->is_preview_user()) {
119         $quiz = $attemptobj->get_quiz();
121     /// Heading and tab bar.
122         echo $OUTPUT->heading(get_string('previewquiz', 'quiz', format_string($quiz->name)));
123         $attemptobj->print_restart_preview_button();
125     /// Inform teachers of any restrictions that would apply to students at this point.
126         if ($messages) {
127             echo $OUTPUT->box_start('quizaccessnotices');
128             echo $OUTPUT->heading(get_string('accessnoticesheader', 'quiz'), 3);
129             $accessmanager->print_messages($messages);
130             echo $OUTPUT->box_end();
131         }
132     }
134     // Start the form
135     echo '<form id="responseform" method="post" action="', s($attemptobj->processattempt_url()),
136             '" enctype="multipart/form-data" accept-charset="utf-8">', "\n";
137     echo '<div>';
139 /// Print all the questions
140     foreach ($attemptobj->get_question_ids($page) as $id) {
141         $attemptobj->print_question($id, false, $attemptobj->attempt_url($id, $page));
142     }
144 /// Print a link to the next page.
145     echo '<div class="submitbtns">';
146     if ($attemptobj->is_last_page($page)) {
147         $nextpage = -1;
148     } else {
149         $nextpage = $page + 1;
150     }
151     echo '<input type="submit" value="' . get_string('next') . '" />';
152     echo "</div>";
154     // Some hidden fields to trach what is going on.
155     echo '<input type="hidden" name="attempt" value="' . $attemptobj->get_attemptid() . '" />';
156     echo '<input type="hidden" name="nextpage" id="nextpagehiddeninput" value="' . $nextpage . '" />';
157     echo '<input type="hidden" name="timeup" id="timeup" value="0" />';
158     echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
160     // Add a hidden field with questionids. Do this at the end of the form, so
161     // if you navigate before the form has finished loading, it does not wipe all
162     // the student's answers.
163     echo '<input type="hidden" name="questionids" value="' .
164             implode(',', $attemptobj->get_question_ids($page)) . "\" />\n";
166     // Finish the form
167     echo '</div>';
168     echo "</form>\n";
170     // Finish the page
171     $accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time());
172     echo $OUTPUT->footer();