mirror of
https://github.com/moodle/moodle.git
synced 2025-02-01 05:18:06 +01:00
ccba5b8805
The sequence of questions that made up a quiz used to be stored as a comma-separated list in quiz.questions. Now the same information is stored in the rows in the quiz_slots table. This is not just 'better' in a database design sense, but it allows for the future changes we will need as we enhance the quiz in the MDL-40987 epic. Having changed the database structure, all the rest of the code needs to be changed to account for it, and that is done here. Note that there are not many unit tests for the changed bit. That is because as part of MDL-40987 we will be changing the code further, and we will add unit tests then.
203 lines
7.9 KiB
PHP
203 lines
7.9 KiB
PHP
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* This file defines the quiz responses report class.
|
|
*
|
|
* @package quiz_responses
|
|
* @copyright 2006 Jean-Michel Vedrine
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
require_once($CFG->dirroot . '/mod/quiz/report/attemptsreport.php');
|
|
require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_options.php');
|
|
require_once($CFG->dirroot . '/mod/quiz/report/responses/responses_form.php');
|
|
require_once($CFG->dirroot . '/mod/quiz/report/responses/last_responses_table.php');
|
|
require_once($CFG->dirroot . '/mod/quiz/report/responses/first_or_all_responses_table.php');
|
|
|
|
|
|
/**
|
|
* Quiz report subclass for the responses report.
|
|
*
|
|
* This report lists some combination of
|
|
* * what question each student saw (this makes sense if random questions were used).
|
|
* * the response they gave,
|
|
* * and what the right answer is.
|
|
*
|
|
* Like the overview report, there are options for showing students with/without
|
|
* attempts, and for deleting selected attempts.
|
|
*
|
|
* @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com}
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class quiz_responses_report extends quiz_attempts_report {
|
|
|
|
public function display($quiz, $cm, $course) {
|
|
global $OUTPUT;
|
|
|
|
list($currentgroup, $students, $groupstudents, $allowed) =
|
|
$this->init('responses', 'quiz_responses_settings_form', $quiz, $cm, $course);
|
|
$options = new quiz_responses_options('responses', $quiz, $cm, $course);
|
|
|
|
if ($fromform = $this->form->get_data()) {
|
|
$options->process_settings_from_form($fromform);
|
|
|
|
} else {
|
|
$options->process_settings_from_params();
|
|
}
|
|
|
|
$this->form->set_data($options->get_initial_form_data());
|
|
|
|
if ($options->attempts == self::ALL_WITH) {
|
|
// This option is only available to users who can access all groups in
|
|
// groups mode, so setting allowed to empty (which means all quiz attempts
|
|
// are accessible, is not a security porblem.
|
|
$allowed = array();
|
|
}
|
|
|
|
// Load the required questions.
|
|
$questions = quiz_report_get_significant_questions($quiz);
|
|
|
|
// Prepare for downloading, if applicable.
|
|
$courseshortname = format_string($course->shortname, true,
|
|
array('context' => context_course::instance($course->id)));
|
|
if ($options->whichtries === question_attempt::LAST_TRY) {
|
|
$tableclassname = 'quiz_last_responses_table';
|
|
} else {
|
|
$tableclassname = 'quiz_first_or_all_responses_table';
|
|
}
|
|
$table = new $tableclassname($quiz, $this->context, $this->qmsubselect,
|
|
$options, $groupstudents, $students, $questions, $options->get_url());
|
|
$filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'),
|
|
$courseshortname, $quiz->name);
|
|
$table->is_downloading($options->download, $filename,
|
|
$courseshortname . ' ' . format_string($quiz->name, true));
|
|
if ($table->is_downloading()) {
|
|
raise_memory_limit(MEMORY_EXTRA);
|
|
}
|
|
|
|
$this->process_actions($quiz, $cm, $currentgroup, $groupstudents, $allowed, $options->get_url());
|
|
|
|
// Start output.
|
|
if (!$table->is_downloading()) {
|
|
// Only print headers if not asked to download data.
|
|
$this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
|
|
}
|
|
|
|
if ($groupmode = groups_get_activity_groupmode($cm)) {
|
|
// Groups are being used, so output the group selector if we are not downloading.
|
|
if (!$table->is_downloading()) {
|
|
groups_print_activity_menu($cm, $options->get_url());
|
|
}
|
|
}
|
|
|
|
// Print information on the number of existing attempts.
|
|
if (!$table->is_downloading()) {
|
|
// Do not print notices when downloading.
|
|
if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
|
|
echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
|
|
}
|
|
}
|
|
|
|
$hasquestions = quiz_has_questions($quiz->id);
|
|
if (!$table->is_downloading()) {
|
|
if (!$hasquestions) {
|
|
echo quiz_no_questions_message($quiz, $cm, $this->context);
|
|
} else if (!$students) {
|
|
echo $OUTPUT->notification(get_string('nostudentsyet'));
|
|
} else if ($currentgroup && !$groupstudents) {
|
|
echo $OUTPUT->notification(get_string('nostudentsingroup'));
|
|
}
|
|
|
|
// Print the display options.
|
|
$this->form->display();
|
|
}
|
|
|
|
$hasstudents = $students && (!$currentgroup || $groupstudents);
|
|
if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {
|
|
|
|
list($fields, $from, $where, $params) = $table->base_sql($allowed);
|
|
|
|
$table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where", $params);
|
|
|
|
$table->set_sql($fields, $from, $where, $params);
|
|
|
|
if (!$table->is_downloading()) {
|
|
// Print information on the grading method.
|
|
if ($strattempthighlight = quiz_report_highlighting_grading_method(
|
|
$quiz, $this->qmsubselect, $options->onlygraded)) {
|
|
echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
|
|
}
|
|
}
|
|
|
|
// Define table columns.
|
|
$columns = array();
|
|
$headers = array();
|
|
|
|
if (!$table->is_downloading() && $options->checkboxcolumn) {
|
|
$columns[] = 'checkbox';
|
|
$headers[] = null;
|
|
}
|
|
|
|
$this->add_user_columns($table, $columns, $headers);
|
|
$this->add_state_column($columns, $headers);
|
|
|
|
if ($table->is_downloading()) {
|
|
$this->add_time_columns($columns, $headers);
|
|
}
|
|
|
|
$this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers);
|
|
|
|
foreach ($questions as $id => $question) {
|
|
if ($options->showqtext) {
|
|
$columns[] = 'question' . $id;
|
|
$headers[] = get_string('questionx', 'question', $question->number);
|
|
}
|
|
if ($options->showresponses) {
|
|
$columns[] = 'response' . $id;
|
|
$headers[] = get_string('responsex', 'quiz_responses', $question->number);
|
|
}
|
|
if ($options->showright) {
|
|
$columns[] = 'right' . $id;
|
|
$headers[] = get_string('rightanswerx', 'quiz_responses', $question->number);
|
|
}
|
|
}
|
|
|
|
$table->define_columns($columns);
|
|
$table->define_headers($headers);
|
|
$table->sortable(true, 'uniqueid');
|
|
|
|
// Set up the table.
|
|
$table->define_baseurl($options->get_url());
|
|
|
|
$this->configure_user_columns($table);
|
|
|
|
$table->no_sorting('feedbacktext');
|
|
$table->column_class('sumgrades', 'bold');
|
|
|
|
$table->set_attribute('id', 'responses');
|
|
|
|
$table->collapsible(true);
|
|
|
|
$table->out($options->pagesize, true);
|
|
}
|
|
return true;
|
|
}
|
|
}
|