mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00
MDL-16263 A way for students to flag/bookmark, particular questions during a quiz attempt for later review.
This is an initial implementation that is now at a working state, but with a few things left to do. It seemed like a good idea to commit it before leaving work on Friday night.
This commit is contained in:
parent
57f43d239a
commit
62e76c6766
18 changed files with 340 additions and 29 deletions
|
@ -497,7 +497,7 @@ class quiz_attempt extends quiz {
|
|||
* @return object the render options for this user on this attempt.
|
||||
*/
|
||||
public function get_render_options($state) {
|
||||
return quiz_get_renderoptions($this->quiz->review, $state);
|
||||
return quiz_get_renderoptions($this->quiz, $this->attempt, $this->context, $state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -534,7 +534,7 @@ class quiz_attempt extends quiz {
|
|||
case QUESTION_EVENTCLOSEANDGRADE:
|
||||
case QUESTION_EVENTCLOSE:
|
||||
case QUESTION_EVENTMANUALGRADE:
|
||||
$options = quiz_get_renderoptions($this->quiz->review, $this->states[$questionid]);
|
||||
$options = $this->get_render_options($this->states[$questionid]);
|
||||
if ($options->scores) {
|
||||
return question_get_feedback_class($state->last_graded->raw_grade /
|
||||
$this->questions[$questionid]->maxgrade);
|
||||
|
@ -551,6 +551,16 @@ class quiz_attempt extends quiz {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $questionid question id of a question that belongs to this quiz.
|
||||
* @return boolean whether this question hss been flagged by the attempter.
|
||||
*/
|
||||
public function is_question_flagged($questionid) {
|
||||
$this->ensure_state_loaded($questionid);
|
||||
$state = $this->states[$questionid];
|
||||
return $state->flagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the grade obtained on a particular question, if the user is permitted to see it.
|
||||
* You must previously have called load_question_states to load the state data about this question.
|
||||
|
@ -560,7 +570,7 @@ class quiz_attempt extends quiz {
|
|||
*/
|
||||
public function get_question_score($questionid) {
|
||||
$this->ensure_state_loaded($questionid);
|
||||
$options = quiz_get_renderoptions($this->quiz->review, $this->states[$questionid]);
|
||||
$options = $this->get_render_options($this->quiz->review, $this->states[$questionid]);
|
||||
if ($options->scores) {
|
||||
return quiz_format_grade($this->quiz, $this->states[$questionid]->last_graded->grade);
|
||||
} else {
|
||||
|
@ -803,12 +813,20 @@ abstract class quiz_nav_panel_base {
|
|||
|
||||
abstract protected function get_end_bits();
|
||||
|
||||
protected function get_question_state($question) {
|
||||
$state = 'todo'; // TODO MDL-15653
|
||||
protected function get_question_state_classes($question) {
|
||||
// The current status of the question.
|
||||
$classes = $this->attemptobj->get_question_status($question->id);
|
||||
|
||||
// Plus a marker for the current page.
|
||||
if ($question->_page == $this->page) {
|
||||
$state .= ' thispage';
|
||||
$classes .= ' thispage';
|
||||
}
|
||||
return $state;
|
||||
|
||||
// Plus a marker for flagged questions.
|
||||
if ($this->attemptobj->is_question_flagged($question->id)) {
|
||||
$classes .= ' flagged';
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function display() {
|
||||
|
@ -833,7 +851,7 @@ class quiz_attempt_nav_panel extends quiz_nav_panel_base {
|
|||
}
|
||||
return '<input type="submit" name="gotopage' . $question->_page .
|
||||
'" value="' . $number . '" class="qnbutton ' .
|
||||
$this->get_question_state($question) . '"' . $onclick . '/>';
|
||||
$this->get_question_state_classes($question) . '"' . $onclick . '/>';
|
||||
}
|
||||
|
||||
protected function get_end_bits() {
|
||||
|
@ -853,7 +871,7 @@ class quiz_review_nav_panel extends quiz_nav_panel_base {
|
|||
|
||||
protected function get_question_button($number, $question) {
|
||||
return '<a href="' . $this->attemptobj->review_url($question->id) .
|
||||
'" class="qnbutton ' . $this->get_question_state($question) .
|
||||
'" class="qnbutton ' . $this->get_question_state_classes($question) .
|
||||
'">' . $number . '</a>';
|
||||
}
|
||||
|
||||
|
|
|
@ -1257,6 +1257,7 @@ function quiz_get_extra_capabilities() {
|
|||
'moodle/question:movemine',
|
||||
'moodle/question:moveall',
|
||||
'moodle/question:managecategory',
|
||||
'moodle/question:flag',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -752,15 +752,38 @@ function quiz_question_preview_button($quiz, $question) {
|
|||
0, 0, $strpreview, QUESTION_PREVIEW_POPUP_OPTIONS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $attempt the attempt.
|
||||
* @param object $context the quiz context.
|
||||
* @return integer whether flags should be shown/editable to the current user for this attempt.
|
||||
*/
|
||||
function quiz_get_flag_option($attempt, $context) {
|
||||
global $USER;
|
||||
static $flagmode = null;
|
||||
if (is_null($flagmode)) {
|
||||
if (!has_capability('moodle/question:flag', $context)) {
|
||||
$flagmode = QUESTION_FLAGSHIDDEN;
|
||||
} else if ($attempt->userid == $USER->id) {
|
||||
$flagmode = QUESTION_FLAGSEDITABLE;
|
||||
} else {
|
||||
$flagmode = QUESTION_FLAGSSHOWN;
|
||||
}
|
||||
}
|
||||
return $flagmode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine render options
|
||||
*
|
||||
* @param int $reviewoptions
|
||||
* @param object $state
|
||||
*/
|
||||
function quiz_get_renderoptions($reviewoptions, $state) {
|
||||
function quiz_get_renderoptions($quiz, $attempt, $context, $state) {
|
||||
$reviewoptions = $quiz->review;
|
||||
$options = new stdClass;
|
||||
|
||||
$options->flags = quiz_get_flag_option($attempt, $context);
|
||||
|
||||
// Show the question in readonly (review) mode if the question is in
|
||||
// the closed state
|
||||
$options->readonly = question_state_is_closed($state);
|
||||
|
@ -791,28 +814,31 @@ function quiz_get_renderoptions($reviewoptions, $state) {
|
|||
*
|
||||
* @param object $quiz the quiz instance.
|
||||
* @param object $attempt the attempt in question.
|
||||
* @param $context the roles and permissions context,
|
||||
* normally the context for the quiz module instance.
|
||||
* @param $context the quiz module context.
|
||||
*
|
||||
* @return object an object with boolean fields responses, scores, feedback,
|
||||
* correct_responses, solutions and general feedback
|
||||
*/
|
||||
function quiz_get_reviewoptions($quiz, $attempt, $context=null) {
|
||||
function quiz_get_reviewoptions($quiz, $attempt, $context) {
|
||||
global $USER;
|
||||
|
||||
$options = new stdClass;
|
||||
$options->readonly = true;
|
||||
|
||||
$options->flags = quiz_get_flag_option($attempt, $context);
|
||||
|
||||
// Provide the links to the question review and comment script
|
||||
if (!empty($attempt->id)) {
|
||||
$options->questionreviewlink = '/mod/quiz/reviewquestion.php?attempt=' . $attempt->id;
|
||||
}
|
||||
|
||||
// Show a link to the comment box only for closed attempts
|
||||
if ($attempt->timefinish && !is_null($context) && has_capability('mod/quiz:grade', $context)) {
|
||||
if ($attempt->timefinish && has_capability('mod/quiz:grade', $context)) {
|
||||
$options->questioncommentlink = '/mod/quiz/comment.php';
|
||||
}
|
||||
|
||||
// Whether to display a response history.
|
||||
$canviewreports = !is_null($context) && has_capability('mod/quiz:viewreports', $context);
|
||||
$canviewreports = has_capability('mod/quiz:viewreports', $context);
|
||||
$options->history = ($canviewreports && !$attempt->preview) ? 'all' : 'graded';
|
||||
|
||||
if ($canviewreports && has_capability('moodle/grade:viewhidden', $context) && !$attempt->preview) {
|
||||
|
@ -867,7 +893,7 @@ function quiz_get_reviewoptions($quiz, $attempt, $context=null) {
|
|||
* at least one of the attempts, the other showing which options are true
|
||||
* for all attempts.
|
||||
*/
|
||||
function quiz_get_combined_reviewoptions($quiz, $attempts, $context=null) {
|
||||
function quiz_get_combined_reviewoptions($quiz, $attempts, $context) {
|
||||
$fields = array('readonly', 'scores', 'feedback', 'correct_responses', 'solutions', 'generalfeedback', 'overallfeedback');
|
||||
$someoptions = new stdClass;
|
||||
$alloptions = new stdClass;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue