PageRenderTime 26ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/mod/quiz/view.php

https://bitbucket.org/kudutest/moodlegit
PHP | 241 lines | 163 code | 35 blank | 43 comment | 54 complexity | 2dfa603d92d877aaa62393b7c2c2096b MD5 | raw file
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * This page is the entry page into the quiz UI. Displays information about the
  18. * quiz to students and teachers, and lets students see their previous attempts.
  19. *
  20. * @package mod
  21. * @subpackage quiz
  22. * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
  23. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24. */
  25. require_once(dirname(__FILE__) . '/../../config.php');
  26. require_once($CFG->libdir.'/gradelib.php');
  27. require_once($CFG->dirroot.'/mod/quiz/locallib.php');
  28. require_once($CFG->libdir . '/completionlib.php');
  29. $id = optional_param('id', 0, PARAM_INT); // Course Module ID, or ...
  30. $q = optional_param('q', 0, PARAM_INT); // Quiz ID.
  31. if ($id) {
  32. if (!$cm = get_coursemodule_from_id('quiz', $id)) {
  33. print_error('invalidcoursemodule');
  34. }
  35. if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
  36. print_error('coursemisconf');
  37. }
  38. } else {
  39. if (!$quiz = $DB->get_record('quiz', array('id' => $q))) {
  40. print_error('invalidquizid', 'quiz');
  41. }
  42. if (!$course = $DB->get_record('course', array('id' => $quiz->course))) {
  43. print_error('invalidcourseid');
  44. }
  45. if (!$cm = get_coursemodule_from_instance("quiz", $quiz->id, $course->id)) {
  46. print_error('invalidcoursemodule');
  47. }
  48. }
  49. // Check login and get context.
  50. require_login($course, false, $cm);
  51. $context = context_module::instance($cm->id);
  52. require_capability('mod/quiz:view', $context);
  53. // Cache some other capabilities we use several times.
  54. $canattempt = has_capability('mod/quiz:attempt', $context);
  55. $canreviewmine = has_capability('mod/quiz:reviewmyattempts', $context);
  56. $canpreview = has_capability('mod/quiz:preview', $context);
  57. // Create an object to manage all the other (non-roles) access rules.
  58. $timenow = time();
  59. $quizobj = quiz::create($cm->instance, $USER->id);
  60. $accessmanager = new quiz_access_manager($quizobj, $timenow,
  61. has_capability('mod/quiz:ignoretimelimits', $context, null, false));
  62. $quiz = $quizobj->get_quiz();
  63. // Log this request.
  64. add_to_log($course->id, 'quiz', 'view', 'view.php?id=' . $cm->id, $quiz->id, $cm->id);
  65. $completion = new completion_info($course);
  66. $completion->set_module_viewed($cm);
  67. // Initialize $PAGE, compute blocks.
  68. $PAGE->set_url('/mod/quiz/view.php', array('id' => $cm->id));
  69. // Create view object which collects all the information the renderer will need.
  70. $viewobj = new mod_quiz_view_object();
  71. $viewobj->accessmanager = $accessmanager;
  72. $viewobj->canreviewmine = $canreviewmine;
  73. // Get this user's attempts.
  74. $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true);
  75. $lastfinishedattempt = end($attempts);
  76. $unfinished = false;
  77. if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) {
  78. $attempts[] = $unfinishedattempt;
  79. // If the attempt is now overdue, deal with that - and pass isonline = false.
  80. // We want the student notified in this case.
  81. $quizobj->create_attempt_object($unfinishedattempt)->handle_if_time_expired(time(), false);
  82. $unfinished = $unfinishedattempt->state == quiz_attempt::IN_PROGRESS ||
  83. $unfinishedattempt->state == quiz_attempt::OVERDUE;
  84. if (!$unfinished) {
  85. $lastfinishedattempt = $unfinishedattempt;
  86. }
  87. $unfinishedattempt = null; // To make it clear we do not use this again.
  88. }
  89. $numattempts = count($attempts);
  90. $viewobj->attempts = $attempts;
  91. $viewobj->attemptobjs = array();
  92. foreach ($attempts as $attempt) {
  93. $viewobj->attemptobjs[] = new quiz_attempt($attempt, $quiz, $cm, $course, false);
  94. }
  95. // Work out the final grade, checking whether it was overridden in the gradebook.
  96. if (!$canpreview) {
  97. $mygrade = quiz_get_best_grade($quiz, $USER->id);
  98. } else if ($lastfinishedattempt) {
  99. // Users who can preview the quiz don't get a proper grade, so work out a
  100. // plausible value to display instead, so the page looks right.
  101. $mygrade = quiz_rescale_grade($lastfinishedattempt->sumgrades, $quiz, false);
  102. } else {
  103. $mygrade = null;
  104. }
  105. $mygradeoverridden = false;
  106. $gradebookfeedback = '';
  107. $grading_info = grade_get_grades($course->id, 'mod', 'quiz', $quiz->id, $USER->id);
  108. if (!empty($grading_info->items)) {
  109. $item = $grading_info->items[0];
  110. if (isset($item->grades[$USER->id])) {
  111. $grade = $item->grades[$USER->id];
  112. if ($grade->overridden) {
  113. $mygrade = $grade->grade + 0; // Convert to number.
  114. $mygradeoverridden = true;
  115. }
  116. if (!empty($grade->str_feedback)) {
  117. $gradebookfeedback = $grade->str_feedback;
  118. }
  119. }
  120. }
  121. $title = $course->shortname . ': ' . format_string($quiz->name);
  122. $PAGE->set_title($title);
  123. $PAGE->set_heading($course->fullname);
  124. $output = $PAGE->get_renderer('mod_quiz');
  125. // Print table with existing attempts.
  126. if ($attempts) {
  127. // Work out which columns we need, taking account what data is available in each attempt.
  128. list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);
  129. $viewobj->attemptcolumn = $quiz->attempts != 1;
  130. $viewobj->gradecolumn = $someoptions->marks >= question_display_options::MARK_AND_MAX &&
  131. quiz_has_grades($quiz);
  132. $viewobj->markcolumn = $viewobj->gradecolumn && ($quiz->grade != $quiz->sumgrades);
  133. $viewobj->overallstats = $lastfinishedattempt && $alloptions->marks >= question_display_options::MARK_AND_MAX;
  134. $viewobj->feedbackcolumn = quiz_has_feedback($quiz) && $alloptions->overallfeedback;
  135. }
  136. $viewobj->timenow = $timenow;
  137. $viewobj->numattempts = $numattempts;
  138. $viewobj->mygrade = $mygrade;
  139. $viewobj->moreattempts = $unfinished ||
  140. !$accessmanager->is_finished($numattempts, $lastfinishedattempt);
  141. $viewobj->mygradeoverridden = $mygradeoverridden;
  142. $viewobj->gradebookfeedback = $gradebookfeedback;
  143. $viewobj->lastfinishedattempt = $lastfinishedattempt;
  144. $viewobj->canedit = has_capability('mod/quiz:manage', $context);
  145. $viewobj->editurl = new moodle_url('/mod/quiz/edit.php', array('cmid' => $cm->id));
  146. $viewobj->backtocourseurl = new moodle_url('/course/view.php', array('id' => $course->id));
  147. $viewobj->startattempturl = $quizobj->start_attempt_url();
  148. $viewobj->startattemptwarning = $quizobj->confirm_start_attempt_message($unfinished);
  149. $viewobj->popuprequired = $accessmanager->attempt_must_be_in_popup();
  150. $viewobj->popupoptions = $accessmanager->get_popup_options();
  151. // Display information about this quiz.
  152. $viewobj->infomessages = $viewobj->accessmanager->describe_rules();
  153. if ($quiz->attempts != 1) {
  154. $viewobj->infomessages[] = get_string('gradingmethod', 'quiz',
  155. quiz_get_grading_option_name($quiz->grademethod));
  156. }
  157. // Determine wheter a start attempt button should be displayed.
  158. $viewobj->quizhasquestions = (bool) quiz_clean_layout($quiz->questions, true);
  159. $viewobj->preventmessages = array();
  160. if (!$viewobj->quizhasquestions) {
  161. $viewobj->buttontext = '';
  162. } else {
  163. if ($unfinished) {
  164. if ($canattempt) {
  165. $viewobj->buttontext = get_string('continueattemptquiz', 'quiz');
  166. } else if ($canpreview) {
  167. $viewobj->buttontext = get_string('continuepreview', 'quiz');
  168. }
  169. } else {
  170. if ($canattempt) {
  171. $viewobj->preventmessages = $viewobj->accessmanager->prevent_new_attempt(
  172. $viewobj->numattempts, $viewobj->lastfinishedattempt);
  173. if ($viewobj->preventmessages) {
  174. $viewobj->buttontext = '';
  175. } else if ($viewobj->numattempts == 0) {
  176. $viewobj->buttontext = get_string('attemptquiznow', 'quiz');
  177. } else {
  178. $viewobj->buttontext = get_string('reattemptquiz', 'quiz');
  179. }
  180. } else if ($canpreview) {
  181. $viewobj->buttontext = get_string('previewquiznow', 'quiz');
  182. }
  183. }
  184. // If, so far, we think a button should be printed, so check if they will be
  185. // allowed to access it.
  186. if ($viewobj->buttontext) {
  187. if (!$viewobj->moreattempts) {
  188. $viewobj->buttontext = '';
  189. } else if ($canattempt
  190. && $viewobj->preventmessages = $viewobj->accessmanager->prevent_access()) {
  191. $viewobj->buttontext = '';
  192. }
  193. }
  194. }
  195. echo $OUTPUT->header();
  196. if (isguestuser()) {
  197. // Guests can't do a quiz, so offer them a choice of logging in or going back.
  198. echo $output->view_page_guest($course, $quiz, $cm, $context, $viewobj->infomessages);
  199. } else if (!isguestuser() && !($canattempt || $canpreview
  200. || $viewobj->canreviewmine)) {
  201. // If they are not enrolled in this course in a good enough role, tell them to enrol.
  202. echo $output->view_page_notenrolled($course, $quiz, $cm, $context, $viewobj->infomessages);
  203. } else {
  204. echo $output->view_page($course, $quiz, $cm, $context, $viewobj);
  205. }
  206. echo $OUTPUT->footer();