MDL-20636 Quiz index and reviewquestion pages work.

This commit is contained in:
Tim Hunt
2011-02-09 20:18:28 +00:00
parent b2607ccc19
commit 729c372b1b
4 changed files with 290 additions and 273 deletions
+162 -145
View File
@@ -1,176 +1,193 @@
<?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 page lists all the instances of quiz in a particular course
* This script lists all the instances of quiz in a particular course
*
* @package mod
* @subpackage quiz
* @author Martin Dougiamas and many others.
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package quiz
*/
require_once("../../config.php");
require_once("locallib.php");
require_once("../../config.php");
require_once("locallib.php");
$id = required_param('id', PARAM_INT);
$PAGE->set_url('/mod/quiz/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id' => $id))) {
print_error('invalidcourseid');
}
$coursecontext = get_context_instance(CONTEXT_COURSE, $id);
require_login($course->id);
$PAGE->set_pagelayout('incourse');
$id = required_param('id', PARAM_INT);
$PAGE->set_url('/mod/quiz/index.php', array('id'=>$id));
if (!$course = $DB->get_record('course', array('id' => $id))) {
print_error('invalidcourseid');
}
$coursecontext = get_context_instance(CONTEXT_COURSE, $id);
require_login($course->id);
$PAGE->set_pagelayout('incourse');
add_to_log($course->id, "quiz", "view all", "index.php?id=$course->id", "");
add_to_log($course->id, "quiz", "view all", "index.php?id=$course->id", "");
// Print the header
$strquizzes = get_string("modulenameplural", "quiz");
$streditquestions = '';
$editqcontexts = new question_edit_contexts($coursecontext);
if ($editqcontexts->have_one_edit_tab_cap('questions')) {
$streditquestions =
"<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/question/edit.php\">
<div>
<input type=\"hidden\" name=\"courseid\" value=\"$course->id\" />
<input type=\"submit\" value=\"".get_string("editquestions", "quiz")."\" />
</div>
</form>";
}
$PAGE->navbar->add($strquizzes);
$PAGE->set_title($strquizzes);
$PAGE->set_button($streditquestions);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
$strquizzes = get_string("modulenameplural", "quiz");
$streditquestions = '';
$editqcontexts = new question_edit_contexts($coursecontext);
if ($editqcontexts->have_one_edit_tab_cap('questions')) {
$streditquestions =
"<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/question/edit.php\">
<div>
<input type=\"hidden\" name=\"courseid\" value=\"$course->id\" />
<input type=\"submit\" value=\"".get_string("editquestions", "quiz")."\" />
</div>
</form>";
}
$PAGE->navbar->add($strquizzes);
$PAGE->set_title($strquizzes);
$PAGE->set_button($streditquestions);
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
// Get all the appropriate data
if (!$quizzes = get_all_instances_in_course("quiz", $course)) {
notice(get_string('thereareno', 'moodle', $strquizzes), "../../course/view.php?id=$course->id");
die;
}
$sections = get_all_sections($course->id);
if (!$quizzes = get_all_instances_in_course("quiz", $course)) {
notice(get_string('thereareno', 'moodle', $strquizzes), "../../course/view.php?id=$course->id");
die;
}
$sections = get_all_sections($course->id);
// Check if we need the closing date header
$showclosingheader = false;
$showfeedback = false;
foreach ($quizzes as $quiz) {
if ($quiz->timeclose!=0) {
$showclosingheader=true;
}
if (quiz_has_feedback($quiz)) {
$showfeedback=true;
}
if($showclosingheader && $showfeedback) {
break;
}
$showclosingheader = false;
$showfeedback = false;
foreach ($quizzes as $quiz) {
if ($quiz->timeclose!=0) {
$showclosingheader=true;
}
if (quiz_has_feedback($quiz)) {
$showfeedback=true;
}
if($showclosingheader && $showfeedback) {
break;
}
}
// Configure table for displaying the list of instances.
$headings = array(get_string('name'));
$align = array('left');
$headings = array(get_string('name'));
$align = array('left');
if ($showclosingheader) {
array_push($headings, get_string('quizcloses', 'quiz'));
if ($showclosingheader) {
array_push($headings, get_string('quizcloses', 'quiz'));
array_push($align, 'left');
}
array_unshift($headings, get_string('sectionname', 'format_'.$course->format));
array_unshift($align, 'center');
$showing = ''; // default
if (has_capability('mod/quiz:viewreports', $coursecontext)) {
array_push($headings, get_string('attempts', 'quiz'));
array_push($align, 'left');
$showing = 'stats';
} else if (has_any_capability(array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), $coursecontext)) {
array_push($headings, get_string('grade', 'quiz'));
array_push($align, 'left');
if ($showfeedback) {
array_push($headings, get_string('feedback', 'quiz'));
array_push($align, 'left');
}
$showing = 'grades'; // default
array_unshift($headings, get_string('sectionname', 'format_'.$course->format));
array_unshift($align, 'center');
$grades = $DB->get_records_sql_menu('
SELECT qg.quiz, qg.grade
FROM {quiz_grades} qg
JOIN {quiz} q ON q.id = qg.quiz
WHERE q.course = ? AND qg.userid = ?',
array($course->id, $USER->id));
}
$showing = ''; // default
$table = new html_table();
$table->head = $headings;
$table->align = $align;
if (has_capability('mod/quiz:viewreports', $coursecontext)) {
array_push($headings, get_string('attempts', 'quiz'));
array_push($align, 'left');
$showing = 'stats';
} else if (has_any_capability(array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), $coursecontext)) {
array_push($headings, get_string('grade', 'quiz'));
array_push($align, 'left');
// Populate the table with the list of instances.
$currentsection = '';
foreach ($quizzes as $quiz) {
$cm = get_coursemodule_from_instance('quiz', $quiz->id);
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
$data = array();
// Section number if necessary.
$strsection = '';
if ($quiz->section != $currentsection) {
if ($quiz->section) {
$strsection = $quiz->section;
$strsection = get_section_name($course, $sections[$quiz->section]);
}
if ($currentsection) {
$learningtable->data[] = 'hr';
}
$currentsection = $quiz->section;
}
$data[] = $strsection;
// Link to the instance.
$class = '';
if (!$quiz->visible) {
$class = ' class="dimmed"';
}
$data[] = "<a$class href=\"view.php?id=$quiz->coursemodule\">" . format_string($quiz->name, true) . '</a>';
// Close date.
if ($quiz->timeclose) {
$data[] = userdate($quiz->timeclose);
} else if ($showclosingheader) {
$data[] = '';
}
if ($showing == 'stats') {
// The $quiz objects returned by get_all_instances_in_course have the necessary $cm
// fields set to make the following call work.
$data[] = quiz_attempt_summary_link_to_reports($quiz, $cm, $context);
} else if ($showing == 'grades') {
// Grade and feedback.
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'all');
list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);
$grade = '';
$feedback = '';
if ($quiz->grade && array_key_exists($quiz->id, grades)) {
if ($alloptions->marks) {
$a = new stdClass;
$a->grade = quiz_format_grade($quiz, $grades[$quiz->id]);
$a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
$grade = get_string('outofshort', 'quiz', $a);
}
if ($alloptions->overallfeedback) {
$feedback = quiz_feedback_for_grade($grades[$quiz->id], $quiz, $context, $cm);
}
}
$data[] = $grade;
if ($showfeedback) {
array_push($headings, get_string('feedback', 'quiz'));
array_push($align, 'left');
$data[] = $feedback;
}
$showing = 'grades'; // default
$grades = $DB->get_records_sql_menu('
SELECT qg.quiz, qg.grade
FROM {quiz_grades} qg
JOIN {quiz} q ON q.id = qg.quiz
WHERE q.course = ? AND qg.userid = ?',
array($course->id, $USER->id));
}
$table = new html_table();
$table->head = $headings;
$table->align = $align;
/// Populate the table with the list of instances.
$currentsection = '';
foreach ($quizzes as $quiz) {
$cm = get_coursemodule_from_instance('quiz', $quiz->id);
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
$data = array();
// Section number if necessary.
$strsection = '';
if ($quiz->section != $currentsection) {
if ($quiz->section) {
$strsection = $quiz->section;
$strsection = get_section_name($course, $sections[$quiz->section]);
}
if ($currentsection) {
$learningtable->data[] = 'hr';
}
$currentsection = $quiz->section;
}
$data[] = $strsection;
// Link to the instance.
$class = '';
if (!$quiz->visible) {
$class = ' class="dimmed"';
}
$data[] = "<a$class href=\"view.php?id=$quiz->coursemodule\">" . format_string($quiz->name, true) . '</a>';
// Close date.
if ($quiz->timeclose) {
$data[] = userdate($quiz->timeclose);
} else if ($showclosingheader) {
$data[] = '';
}
if ($showing == 'stats') {
// The $quiz objects returned by get_all_instances_in_course have the necessary $cm
// fields set to make the following call work.
$data[] = quiz_attempt_summary_link_to_reports($quiz, $cm, $context);
} else if ($showing == 'grades') {
// Grade and feedback.
$attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'all');
list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);
$grade = '';
$feedback = '';
if ($quiz->grade && array_key_exists($quiz->id, grades)) {
if ($alloptions->marks) {
$a = new stdClass;
$a->grade = quiz_format_grade($quiz, grades[$quiz->id]);
$a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
$grade = get_string('outofshort', 'quiz', $a);
}
if ($alloptions->overallfeedback) {
$feedback = quiz_feedback_for_grade(grades[$quiz->id], $quiz, $context, $cm);
}
}
$data[] = $grade;
if ($showfeedback) {
$data[] = $feedback;
}
}
$table->data[] = $data;
} // End of loop over quiz instances.
$table->data[] = $data;
} // End of loop over quiz instances.
// Display the table.
echo '<br />';
echo html_writer::table($table);
echo html_writer::table($table);
// Finish the page
echo $OUTPUT->footer();
echo $OUTPUT->footer();
+121 -121
View File
@@ -1,144 +1,144 @@
<?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 page prints a review of a particular question attempt.
* This page is expected to only be used in a popup window.
*
* @author Martin Dougiamas, Tim Hunt and many others.
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package quiz
* @package mod
* @subpackage quiz
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(dirname(__FILE__) . '/../../config.php');
require_once('locallib.php');
require_once(dirname(__FILE__) . '/../../config.php');
require_once('locallib.php');
$attemptid = required_param('attempt', PARAM_INT); // attempt id
$questionid = required_param('question', PARAM_INT); // question id
$stateid = optional_param('state', 0, PARAM_INT); // state id
$attemptid = required_param('attempt', PARAM_INT); // attempt id
$slot = required_param('slot', PARAM_INT); // question number in usage
$seq = optional_param('step', null, PARAM_INT); // sequence number
$url = new moodle_url('/mod/quiz/reviewquestion.php', array('attempt'=>$attemptid,'question'=>$questionid));
if ($stateid !== 0) {
$url->param('state', $stateid);
$baseurl = new moodle_url('/mod/quiz/reviewquestion.php',
array('attempt' => $attemptid, 'slot' => $slot));
$currenturl = new moodle_url($baseurl);
if ($seq !== 0) {
$currenturl->param('step', $seq);
}
$PAGE->set_url($currenturl);
$PAGE->set_pagelayout('popup');
$attemptobj = quiz_attempt::create($attemptid);
// Check login.
require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm());
$attemptobj->check_review_capability();
// Permissions checks for normal users who do not have quiz:viewreports capability.
if (!$attemptobj->has_capability('mod/quiz:viewreports')) {
// Can't review during the attempt - send them back to the attempt page.
if (!$attemptobj->is_finished()) {
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('cannotreviewopen', 'quiz'));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
$PAGE->set_url($url);
$PAGE->set_pagelayout('popup');
$attemptobj = quiz_attempt::create($attemptid);
/// Check login.
require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm());
$attemptobj->check_review_capability();
/// Create an object to manage all the other (non-roles) access rules.
$accessmanager = $attemptobj->get_access_manager(time());
$options = $attemptobj->get_review_options();
/// Permissions checks for normal users who do not have quiz:viewreports capability.
if (!$attemptobj->has_capability('mod/quiz:viewreports')) {
/// Can't review during the attempt - send them back to the attempt page.
if (!$attemptobj->is_finished()) {
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('cannotreviewopen', 'quiz'));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
/// Can't review other users' attempts.
if (!$attemptobj->is_own_attempt()) {
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('notyourattempt', 'quiz'));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
/// Can't review unless Students may review -> Responses option is turned on.
if (!$options->responses) {
$accessmanager = $attemptobj->get_access_manager(time());
echo $OUTPUT->header();
echo $OUTPUT->notification($accessmanager->cannot_review_message($attemptobj->get_review_options()));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
// Can't review other users' attempts.
if (!$attemptobj->is_own_attempt()) {
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('notyourattempt', 'quiz'));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
/// Load the questions and states.
$questionids = array($questionid);
$attemptobj->load_questions($questionids);
$attemptobj->load_question_states($questionids);
/// If it was asked for, load another state, instead of the latest.
if ($stateid) {
$attemptobj->load_specific_question_state($questionid, $stateid);
// Can't review unless Students may review -> Responses option is turned on.
if (!$options->responses) {
$accessmanager = $attemptobj->get_access_manager(time());
echo $OUTPUT->header();
echo $OUTPUT->notification($accessmanager->cannot_review_message($attemptobj->get_review_options()));
echo $OUTPUT->close_window_button();
echo $OUTPUT->footer();
die;
}
}
/// Work out the base URL of this page.
$baseurl = $CFG->wwwroot . '/mod/quiz/reviewquestion.php?attempt=' .
$attemptobj->get_attemptid() . '&amp;question=' . $questionid;
// Log this review.
add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'reviewquestion.php?attempt=' .
$attemptobj->get_attemptid() . '&slot=' . $slot . ($seq ? '&step=' . $seq : ''),
$attemptobj->get_quizid(), $attemptobj->get_cmid());
/// Log this review.
add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'reviewquestion.php?attempt=' .
$attemptobj->get_attemptid() . '&question=' . $questionid .
($stateid ? '&state=' . $stateid : ''),
$attemptobj->get_quizid(), $attemptobj->get_cmid());
// Print the page header
$attemptobj->get_question_html_head_contributions($slot);
$PAGE->set_title($attemptobj->get_course()->shortname . ': '.format_string($attemptobj->get_quiz_name()));
$PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
/// Print the page header
$attemptobj->get_question_html_head_contributions($questionid);
$PAGE->set_title($attemptobj->get_course()->shortname . ': '.format_string($attemptobj->get_quiz_name()));
$PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
// Print infobox
$rows = array();
/// Print infobox
$rows = array();
// User picture and name.
if ($attemptobj->get_userid() <> $USER->id) {
// Print user picture and name
$student = $DB->get_record('user', array('id' => $attemptobj->get_userid()));
$picture = $OUTPUT->user_picture($student, array('courseid'=>$attemptobj->get_courseid()));
$rows[] = '<tr><th scope="row" class="cell">' . $picture . '</th><td class="cell"><a href="' .
$CFG->wwwroot . '/user/view.php?id=' . $student->id . '&amp;course=' . $attemptobj->get_courseid() . '">' .
fullname($student, true) . '</a></td></tr>';
}
/// User picture and name.
if ($attemptobj->get_userid() <> $USER->id) {
// Print user picture and name
$student = $DB->get_record('user', array('id' => $attemptobj->get_userid()));
$picture = $OUTPUT->user_picture($student, array('courseid'=>$attemptobj->get_courseid()));
$rows[] = '<tr><th scope="row" class="cell">' . $picture . '</th><td class="cell"><a href="' .
$CFG->wwwroot . '/user/view.php?id=' . $student->id . '&amp;course=' . $attemptobj->get_courseid() . '">' .
fullname($student, true) . '</a></td></tr>';
// Quiz name.
$rows[] = '<tr><th scope="row" class="cell">' . get_string('modulename', 'quiz') .
'</th><td class="cell">' . format_string($attemptobj->get_quiz_name()) . '</td></tr>';
// Question name.
$rows[] = '<tr><th scope="row" class="cell">' . get_string('question', 'quiz') .
'</th><td class="cell">' . format_string(
$attemptobj->get_question_name($slot)) . '</td></tr>';
// Other attempts at the quiz.
if ($attemptobj->has_capability('mod/quiz:viewreports')) {
$attemptlist = $attemptobj->links_to_other_attempts($baseurl);
if ($attemptlist) {
$rows[] = '<tr><th scope="row" class="cell">' . get_string('attempts', 'quiz') .
'</th><td class="cell">' . $attemptlist . '</td></tr>';
}
}
/// Quiz name.
$rows[] = '<tr><th scope="row" class="cell">' . get_string('modulename', 'quiz') .
'</th><td class="cell">' . format_string($attemptobj->get_quiz_name()) . '</td></tr>';
// Timestamp of this action.
$timestamp = $attemptobj->get_question_action_time($slot);
if ($timestamp) {
$rows[] = '<tr><th scope="row" class="cell">' . get_string('completedon', 'quiz') .
'</th><td class="cell">' . userdate($timestamp) . '</td></tr>';
}
/// Question name.
$rows[] = '<tr><th scope="row" class="cell">' . get_string('question', 'quiz') .
'</th><td class="cell">' . format_string(
$attemptobj->get_question($questionid)->name) . '</td></tr>';
// Now output the summary table, if there are any rows to be shown.
if (!empty($rows)) {
echo '<table class="generaltable generalbox quizreviewsummary"><tbody>', "\n";
echo implode("\n", $rows);
echo "\n</tbody></table>\n";
}
/// Other attempts at the quiz.
if ($attemptobj->has_capability('mod/quiz:viewreports')) {
$attemptlist = $attemptobj->links_to_other_attempts($baseurl);
if ($attemptlist) {
$rows[] = '<tr><th scope="row" class="cell">' . get_string('attempts', 'quiz') .
'</th><td class="cell">' . $attemptlist . '</td></tr>';
}
}
/// Timestamp of this action.
$timestamp = $attemptobj->get_question_state($questionid)->timestamp;
if ($timestamp) {
$rows[] = '<tr><th scope="row" class="cell">' . get_string('completedon', 'quiz') .
'</th><td class="cell">' . userdate($timestamp) . '</td></tr>';
}
/// Now output the summary table, if there are any rows to be shown.
if (!empty($rows)) {
echo '<table class="generaltable generalbox quizreviewsummary"><tbody>', "\n";
echo implode("\n", $rows);
echo "\n</tbody></table>\n";
}
/// Print the question in the requested state.
if ($stateid) {
$baseurl .= '&amp;state=' . $stateid;
}
$attemptobj->print_question($questionid, true, $baseurl);
/// Finish the page
echo $OUTPUT->footer();
// Print the question in the requested state.
if (!is_null($seq)) {
echo $attemptobj->render_question_at_step($slot, $seq, true, $currenturl);
} else {
echo $attemptobj->render_question($slot, true, $currenturl);
}
// Finish the page
echo $OUTPUT->footer();
+5 -5
View File
@@ -34,7 +34,7 @@
* @copyright 2009 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_question_renderer extends renderer_base {
class core_question_renderer extends plugin_renderer_base {
/**
* Generate the display of a question in a particular state, and with certain
@@ -331,10 +331,10 @@ class core_question_renderer extends renderer_base {
if ($stepno == $qa->get_num_steps()) {
$rowclass = 'current';
} else if (!empty($options->questionreviewlink)) {
$stepno = link_to_popup_window($options->questionreviewlink .
'&amp;slot=' . $qa->get_slot() .
'&step=' . $i, 'reviewquestion', $stepno, 450, 650,
get_string('reviewresponse', 'quiz'), 'none', true);
$url = new moodle_url($options->questionreviewlink, array('slot' => $qa->get_slot(), 'step' => $i));
$stepno = $this->output->action_link($url, $stepno,
new popup_action('click', $url, 'reviewquestion', array('width' => 450, 'height' => 650)),
array('title' => get_string('reviewresponse', 'quiz')));
}
$user = new stdClass;
$user->id = $step->get_user_id();
+2 -2
View File
@@ -81,7 +81,7 @@ DONE mod/quiz/defaults.php | 12 +-
mod/quiz/edit.js | 131 +
mod/quiz/edit.php | 118 +-
mod/quiz/editlib.php | 79 +-
mod/quiz/index.php | 6 +-
DONE mod/quiz/index.php | 6 +-
DONE mod/quiz/jstimer.php | 58 -
DONE mod/quiz/lib.php | 454 ++--
DONE mod/quiz/locallib.php | 848 +++++--
@@ -102,7 +102,7 @@ DONE mod/quiz/protect_js.php | 56 -
mod/quiz/restorelibpre15.php | 41 +-
DONE mod/quiz/review.php | 520 ++--
DONE mod/quiz/reviewoptions.html | 124 +-
mod/quiz/reviewquestion.php | 267 +-
DONE mod/quiz/reviewquestion.php | 267 +-
mod/quiz/settingslib.php
DONE mod/quiz/simpletest/testaccessrules.php | 518 ++++
DONE mod/quiz/simpletest/testlib.php | 58 +