mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 04:30:15 +01:00
MDL-3030 quiz overdue handling: display message on the summary page.
This change also includes a clean-up of how we display and initialise the countdown timer.
This commit is contained in:
parent
2de9be52aa
commit
2b2b645842
@ -410,25 +410,6 @@ class quiz_access_manager {
|
||||
return $timeleft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will cause the attempt time to start counting down after the page has loaded,
|
||||
* if that is necessary.
|
||||
*
|
||||
* @param object $attempt the data from the relevant quiz_attempts row.
|
||||
* @param int $timenow the time to consider as 'now'.
|
||||
* @param mod_quiz_renderer $output the quiz renderer.
|
||||
*/
|
||||
public function show_attempt_timer_if_needed($attempt, $timenow, $output) {
|
||||
$timeleft = $this->get_time_left($attempt, $timenow);
|
||||
|
||||
if ($timeleft !== false) {
|
||||
// Make sure the timer starts just above zero. If $timeleft was <= 0, then
|
||||
// this will just have the effect of causing the quiz to be submitted immediately.
|
||||
$timerstartvalue = max($timeleft, 1);
|
||||
$output->initialise_timer($timerstartvalue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bolean if this quiz should only be shown to students in a popup window.
|
||||
*/
|
||||
|
@ -126,5 +126,4 @@ if ($attemptobj->is_last_page($page)) {
|
||||
$nextpage = $page + 1;
|
||||
}
|
||||
|
||||
$accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time(), $output);
|
||||
echo $output->attempt_page($attemptobj, $page, $accessmanager, $messages, $slots, $id, $nextpage);
|
||||
|
@ -945,6 +945,19 @@ class quiz_attempt {
|
||||
return $this->quba->get_question_action_time($slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time remaining for an in-progress attempt, if the time is short
|
||||
* enought that it would be worth showing a timer.
|
||||
* @param int $timenow the time to consider as 'now'.
|
||||
* @return int|false the number of seconds remaining for this attempt.
|
||||
* False if there is no limit.
|
||||
*/
|
||||
public function get_time_left($timenow) {
|
||||
if ($this->attempt->state != self::IN_PROGRESS) {
|
||||
return false;
|
||||
}
|
||||
return $this->get_access_manager($timenow)->get_time_left($this->attempt, $timenow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int the time when this attempt was submitted. 0 if it has not been
|
||||
@ -959,23 +972,29 @@ class quiz_attempt {
|
||||
* student should next do something.
|
||||
* @return int timestamp by which the student needs to do something.
|
||||
*/
|
||||
function get_due_date($timenow) {
|
||||
function get_due_date() {
|
||||
$deadlines = array();
|
||||
if ($this->quizobj->get_quiz()->timelimit) {
|
||||
$deadlines[] = $this->attempt->timestart + $this->quizobj->get_quiz()->timelimit;
|
||||
}
|
||||
if ($this->quizobj->get_quiz()->timeclose) {
|
||||
$deadlines[] = $this->quizobj->get_quiz()->timeclose;
|
||||
}
|
||||
if ($deadlines) {
|
||||
$duedate = min($deadlines);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($attempt->state) {
|
||||
switch ($this->attempt->state) {
|
||||
case self::IN_PROGRESS:
|
||||
$timeleft = $this->get_access_manager($timenow)->get_time_left(
|
||||
$this->attempt, $timenow);
|
||||
if ($timeleft === false) {
|
||||
return false;
|
||||
} else {
|
||||
return $timenow + $timeleft;
|
||||
}
|
||||
return $duedate;
|
||||
|
||||
case self::OVERDUE:
|
||||
return $this->attempt->timefinished + $this->quizobj->get_quiz()->graceperiod;
|
||||
return $duedate + $this->quizobj->get_quiz()->graceperiod;
|
||||
|
||||
default:
|
||||
throw new coding_exception('Unexpected state: ' . $attempt->state);
|
||||
throw new coding_exception('Unexpected state: ' . $this->attempt->state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1473,7 +1492,7 @@ class quiz_attempt_nav_panel extends quiz_nav_panel_base {
|
||||
public function render_end_bits(mod_quiz_renderer $output) {
|
||||
return html_writer::link($this->attemptobj->summary_url(),
|
||||
get_string('endtest', 'quiz'), array('class' => 'endtestlink')) .
|
||||
$output->countdown_timer() .
|
||||
$output->countdown_timer($this->attemptobj, time()) .
|
||||
$this->render_restart_preview_link($output);
|
||||
}
|
||||
}
|
||||
|
@ -418,6 +418,7 @@ $string['moveselectedonpage'] = 'Move selected questions to page: {$a}';
|
||||
$string['multichoice'] = 'Multiple choice';
|
||||
$string['multipleanswers'] = 'Choose at least one answer.';
|
||||
$string['multiplier'] = 'Multiplier';
|
||||
$string['mustbesubmittedby'] = 'This attempt must be submitted by {$a}.';
|
||||
$string['name'] = 'Name';
|
||||
$string['navmethod'] = 'Navigation method';
|
||||
$string['navmethod_free'] = 'Free';
|
||||
@ -496,6 +497,7 @@ $string['overduehandling_desc'] = 'What should happen by default if a student do
|
||||
$string['overduehandlingautosubmit'] = 'the attempt is submitted automatically';
|
||||
$string['overduehandlinggraceperiod'] = 'there is a grace period in which to submit the attempt, but not answer more questions';
|
||||
$string['overduehandlingautoabandon'] = 'that is it. The attempt must be submitted before time expires, or it is not counted';
|
||||
$string['overduemustbesubmittedby'] = 'This attempt is now overdue. It should already have been submitted. If you would like this quiz to be graded, you must submit it by {$a}. If you not submit it by then, no marks from this attempt will be counted.';
|
||||
$string['override'] = 'Override';
|
||||
$string['overridedeletegroupsure'] = 'Are you sure you want to delete the override for group {$a}?';
|
||||
$string['overridedeleteusersure'] = 'Are you sure you want to delete the override for user {$a}?';
|
||||
|
@ -96,7 +96,11 @@ M.mod_quiz.timer = {
|
||||
Y.one('#quiz-time-left').setContent(M.str.quiz.timesup);
|
||||
var input = Y.one('input[name=timeup]');
|
||||
input.set('value', 1);
|
||||
input.ancestor('form').submit();
|
||||
var form = input.ancestor('form');
|
||||
if (form.one('input[name=finishattempt]')) {
|
||||
form.one('input[name=finishattempt]').set('value', 0);
|
||||
}
|
||||
form.submit();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,16 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
* Return the HTML of the quiz timer.
|
||||
* @return string HTML content.
|
||||
*/
|
||||
public function countdown_timer() {
|
||||
public function countdown_timer(quiz_attempt $attemptobj, $timenow) {
|
||||
|
||||
$timeleft = $attemptobj->get_time_left($timenow);
|
||||
if ($timeleft !== false) {
|
||||
// Make sure the timer starts just above zero. If $timeleft was <= 0, then
|
||||
// this will just have the effect of causing the quiz to be submitted immediately.
|
||||
$timerstartvalue = max($timeleft, 1);
|
||||
$this->initialise_timer($timerstartvalue);
|
||||
}
|
||||
|
||||
return html_writer::tag('div', get_string('timeleft', 'quiz') . ' ' .
|
||||
html_writer::tag('span', '', array('id' => 'quiz-time-left')),
|
||||
array('id' => 'quiz-timer'));
|
||||
@ -604,8 +613,6 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
public function summary_page_controls($attemptobj) {
|
||||
$output = '';
|
||||
// countdown timer
|
||||
$output .= $this->countdown_timer();
|
||||
|
||||
// Return to place button
|
||||
$button = new single_button(
|
||||
@ -626,11 +633,23 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
new moodle_url($attemptobj->processattempt_url(), $options),
|
||||
get_string('submitallandfinish', 'quiz'));
|
||||
$button->id = 'responseform';
|
||||
$button->add_action(new confirm_action(get_string('confirmclose', 'quiz'), null,
|
||||
get_string('submitallandfinish', 'quiz')));
|
||||
if ($attemptobj->get_state() == quiz_attempt::IN_PROGRESS) {
|
||||
$button->add_action(new confirm_action(get_string('confirmclose', 'quiz'), null,
|
||||
get_string('submitallandfinish', 'quiz')));
|
||||
}
|
||||
|
||||
$output .= $this->container($this->container($this->render($button),
|
||||
'controls'), 'submitbtns mdl-align');
|
||||
$duedate = $attemptobj->get_due_date();
|
||||
$message = '';
|
||||
if ($attemptobj->get_state() == quiz_attempt::OVERDUE) {
|
||||
$message = get_string('overduemustbesubmittedby', 'quiz', userdate($duedate));
|
||||
|
||||
} else if ($duedate) {
|
||||
$message = get_string('mustbesubmittedby', 'quiz', userdate($duedate));
|
||||
}
|
||||
|
||||
$output .= $this->countdown_timer($attemptobj, time());
|
||||
$output .= $this->container($message . $this->container(
|
||||
$this->render($button), 'controls'), 'submitbtns mdl-align');
|
||||
|
||||
return $output;
|
||||
}
|
||||
@ -911,7 +930,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$row[] = $this->attempt_state($attemptobj, $viewobj->timenow);
|
||||
$row[] = $this->attempt_state($attemptobj);
|
||||
|
||||
if ($viewobj->markcolumn) {
|
||||
if ($attemptoptions->marks >= question_display_options::MARK_AND_MAX &&
|
||||
@ -975,7 +994,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
* @param int $timenow the time to use as 'now'.
|
||||
* @return string the appropriate lang string to describe the state.
|
||||
*/
|
||||
public function attempt_state($attemptobj, $timenow) {
|
||||
public function attempt_state($attemptobj) {
|
||||
switch ($attemptobj->get_state()) {
|
||||
case quiz_attempt::IN_PROGRESS:
|
||||
return get_string('stateinprogress', 'quiz');
|
||||
@ -983,7 +1002,7 @@ class mod_quiz_renderer extends plugin_renderer_base {
|
||||
case quiz_attempt::OVERDUE:
|
||||
return get_string('stateoverdue', 'quiz') . html_writer::tag('span',
|
||||
get_string('stateoverduedetails', 'quiz',
|
||||
userdate($attemptobj->get_due_date($timenow))),
|
||||
userdate($attemptobj->get_due_date())),
|
||||
array('class' => 'statedetails'));
|
||||
|
||||
case quiz_attempt::FINISHED:
|
||||
|
@ -89,6 +89,4 @@ $PAGE->set_heading($attemptobj->get_course()->fullname);
|
||||
$accessmanager->setup_attempt_page($PAGE);
|
||||
|
||||
// Display the page.
|
||||
|
||||
$accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time(), $output);
|
||||
echo $output->summary_page($attemptobj, $displayoptions);
|
||||
|
Loading…
x
Reference in New Issue
Block a user