PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/quiz/report/responses/report.php

https://github.com/cmiic/moodle
PHP | 219 lines | 131 code | 39 blank | 49 comment | 36 complexity | 1ae5e3a479e545b3ae49ae9ce3d232b3 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 file defines the quiz responses report class.
  18. *
  19. * @package quiz_responses
  20. * @copyright 2006 Jean-Michel Vedrine
  21. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22. */
  23. defined('MOODLE_INTERNAL') || die();
  24. require_once($CFG->dirroot . '/mod/quiz/report/attemptsreport.php');
  25. require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_options.php');
  26. require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_form.php');
  27. require_once($CFG->dirroot . '/mod/quiz/report/responses/last_responses_table.php');
  28. require_once($CFG->dirroot . '/mod/quiz/report/responses/first_or_all_responses_table.php');
  29. /**
  30. * Quiz report subclass for the responses report.
  31. *
  32. * This report lists some combination of
  33. * * what question each student saw (this makes sense if random questions were used).
  34. * * the response they gave,
  35. * * and what the right answer is.
  36. *
  37. * Like the overview report, there are options for showing students with/without
  38. * attempts, and for deleting selected attempts.
  39. *
  40. * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
  41. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42. */
  43. class quiz_responses_report extends quiz_attempts_report {
  44. public function display($quiz, $cm, $course) {
  45. global $OUTPUT, $DB;
  46. list($currentgroup, $studentsjoins, $groupstudentsjoins, $allowedjoins) = $this->init(
  47. 'responses', 'quiz_responses_settings_form', $quiz, $cm, $course);
  48. $options = new quiz_responses_options('responses', $quiz, $cm, $course);
  49. if ($fromform = $this->form->get_data()) {
  50. $options->process_settings_from_form($fromform);
  51. } else {
  52. $options->process_settings_from_params();
  53. }
  54. $this->form->set_data($options->get_initial_form_data());
  55. // Load the required questions.
  56. $questions = quiz_report_get_significant_questions($quiz);
  57. // Prepare for downloading, if applicable.
  58. $courseshortname = format_string($course->shortname, true,
  59. array('context' => context_course::instance($course->id)));
  60. if ($options->whichtries === question_attempt::LAST_TRY) {
  61. $tableclassname = 'quiz_last_responses_table';
  62. } else {
  63. $tableclassname = 'quiz_first_or_all_responses_table';
  64. }
  65. $table = new $tableclassname($quiz, $this->context, $this->qmsubselect,
  66. $options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url());
  67. $filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'),
  68. $courseshortname, $quiz->name);
  69. $table->is_downloading($options->download, $filename,
  70. $courseshortname . ' ' . format_string($quiz->name, true));
  71. if ($table->is_downloading()) {
  72. raise_memory_limit(MEMORY_EXTRA);
  73. }
  74. $this->hasgroupstudents = false;
  75. if (!empty($groupstudentsjoins->joins)) {
  76. $sql = "SELECT DISTINCT u.id
  77. FROM {user} u
  78. $groupstudentsjoins->joins
  79. WHERE $groupstudentsjoins->wheres";
  80. $this->hasgroupstudents = $DB->record_exists_sql($sql, $groupstudentsjoins->params);
  81. }
  82. $hasstudents = false;
  83. if (!empty($studentsjoins->joins)) {
  84. $sql = "SELECT DISTINCT u.id
  85. FROM {user} u
  86. $studentsjoins->joins
  87. WHERE $studentsjoins->wheres";
  88. $hasstudents = $DB->record_exists_sql($sql, $studentsjoins->params);
  89. }
  90. if ($options->attempts == self::ALL_WITH) {
  91. // This option is only available to users who can access all groups in
  92. // groups mode, so setting allowed to empty (which means all quiz attempts
  93. // are accessible, is not a security problem.
  94. $allowedjoins = new \core\dml\sql_join();
  95. }
  96. $this->process_actions($quiz, $cm, $currentgroup, $groupstudentsjoins, $allowedjoins, $options->get_url());
  97. // Start output.
  98. if (!$table->is_downloading()) {
  99. // Only print headers if not asked to download data.
  100. $this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
  101. }
  102. if ($groupmode = groups_get_activity_groupmode($cm)) {
  103. // Groups are being used, so output the group selector if we are not downloading.
  104. if (!$table->is_downloading()) {
  105. groups_print_activity_menu($cm, $options->get_url());
  106. }
  107. }
  108. // Print information on the number of existing attempts.
  109. if (!$table->is_downloading()) {
  110. // Do not print notices when downloading.
  111. if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
  112. echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
  113. }
  114. }
  115. $hasquestions = quiz_has_questions($quiz->id);
  116. if (!$table->is_downloading()) {
  117. if (!$hasquestions) {
  118. echo quiz_no_questions_message($quiz, $cm, $this->context);
  119. } else if (!$hasstudents) {
  120. echo $OUTPUT->notification(get_string('nostudentsyet'));
  121. } else if ($currentgroup && !$this->hasgroupstudents) {
  122. echo $OUTPUT->notification(get_string('nostudentsingroup'));
  123. }
  124. // Print the display options.
  125. $this->form->display();
  126. }
  127. $hasstudents = $hasstudents && (!$currentgroup || $this->hasgroupstudents);
  128. if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {
  129. list($fields, $from, $where, $params) = $table->base_sql($allowedjoins);
  130. $table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where", $params);
  131. $table->set_sql($fields, $from, $where, $params);
  132. if (!$table->is_downloading()) {
  133. // Print information on the grading method.
  134. if ($strattempthighlight = quiz_report_highlighting_grading_method(
  135. $quiz, $this->qmsubselect, $options->onlygraded)) {
  136. echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
  137. }
  138. }
  139. // Define table columns.
  140. $columns = array();
  141. $headers = array();
  142. if (!$table->is_downloading() && $options->checkboxcolumn) {
  143. $columns[] = 'checkbox';
  144. $headers[] = null;
  145. }
  146. $this->add_user_columns($table, $columns, $headers);
  147. $this->add_state_column($columns, $headers);
  148. if ($table->is_downloading()) {
  149. $this->add_time_columns($columns, $headers);
  150. }
  151. $this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers);
  152. foreach ($questions as $id => $question) {
  153. if ($options->showqtext) {
  154. $columns[] = 'question' . $id;
  155. $headers[] = get_string('questionx', 'question', $question->number);
  156. }
  157. if ($options->showresponses) {
  158. $columns[] = 'response' . $id;
  159. $headers[] = get_string('responsex', 'quiz_responses', $question->number);
  160. }
  161. if ($options->showright) {
  162. $columns[] = 'right' . $id;
  163. $headers[] = get_string('rightanswerx', 'quiz_responses', $question->number);
  164. }
  165. }
  166. $table->define_columns($columns);
  167. $table->define_headers($headers);
  168. $table->sortable(true, 'uniqueid');
  169. // Set up the table.
  170. $table->define_baseurl($options->get_url());
  171. $this->configure_user_columns($table);
  172. $table->no_sorting('feedbacktext');
  173. $table->column_class('sumgrades', 'bold');
  174. $table->set_attribute('id', 'responses');
  175. $table->collapsible(true);
  176. $table->out($options->pagesize, true);
  177. }
  178. return true;
  179. }
  180. }