Permalink
Browse files

MDL-35717 quiz: fix overdue attempt processing

  • Loading branch information...
mpetrowi committed Oct 9, 2012
1 parent 6109f21 commit 8e771aed93eea08cc3e9410283f5354e02311281
View
@@ -392,17 +392,35 @@ public function setup_attempt_page($page) {
}
/**
- * Compute how much time is left before this attempt must be submitted.
+ * Compute when the attempt must be submitted.
+ *
+ * @param object $attempt the data from the relevant quiz_attempts row.
+ * @return int|false the attempt close time.
+ * False if there is no limit.
+ */
+ public function get_end_time($attempt) {
+ $timeclose = false;
+ foreach ($this->rules as $rule) {
+ $ruletimeclose = $rule->end_time($attempt);
+ if ($ruletimeclose !== false && ($timeclose === false || $ruletimeclose < $timeclose)) {
+ $timeclose = $ruletimeclose;
+ }
+ }
+ return $timeclose;
+ }
+
+ /**
+ * Compute what should be displayed to the user for time remaining in this attempt.
*
* @param object $attempt the data from the relevant quiz_attempts row.
* @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.
+ * False if no limit should be displayed.
*/
- public function get_time_left($attempt, $timenow) {
+ public function get_time_left_display($attempt, $timenow) {
$timeleft = false;
foreach ($this->rules as $rule) {
- $ruletimeleft = $rule->time_left($attempt, $timenow);
+ $ruletimeleft = $rule->time_left_display($attempt, $timenow);
if ($ruletimeleft !== false && ($timeleft === false || $ruletimeleft < $timeleft)) {
$timeleft = $ruletimeleft;
}
@@ -180,14 +180,28 @@ public function is_finished($numprevattempts, $lastattempt) {
/**
* If, because of this rule, the user has to finish their attempt by a certain time,
- * you should override this method to return the amount of time left in seconds.
+ * you should override this method to return the attempt end time.
+ * @param object $attempt the current attempt
+ * @return mixed the attempt close time, or false if there is no close time.
+ */
+ public function end_time($attempt) {
+ return false;
+ }
+
+ /**
+ * If the user should be shown a different amount of time than $timenow - $this->end_time(), then
+ * override this method. This is useful if the time remaining is large enough to be omitted.
* @param object $attempt the current attempt
* @param int $timenow the time now. We don't use $this->timenow, so we can
* give the user a more accurate indication of how much time is left.
- * @return mixed false if there is no deadline, of the time left in seconds if there is one.
+ * @return mixed the time left in seconds (can be negative) or false if there is no limit.
*/
- public function time_left($attempt, $timenow) {
- return false;
+ public function time_left_display($attempt, $timenow) {
+ $endtime = $this->end_time($attempt);
+ if ($endtime === false) {
+ return false;
+ }
+ return $endtime - $timenow;
}
/**
@@ -55,7 +55,8 @@ public function test_just_first_delay() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->prevent_new_attempt(3, $attempt));
@@ -89,7 +90,8 @@ public function test_just_second_delay() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->prevent_new_attempt(5, $attempt));
@@ -128,7 +130,8 @@ public function test_just_both_delays() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->prevent_new_attempt(5, $attempt));
@@ -179,7 +182,8 @@ public function test_with_close_date() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$attempt->timefinish = 13000;
$this->assertEquals($rule->prevent_new_attempt(1, $attempt),
@@ -236,7 +240,8 @@ public function test_time_limit_and_overdue() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->prevent_new_attempt(5, $attempt));
@@ -56,7 +56,8 @@ public function test_ipaddress_access_rule() {
$this->assertFalse($rule->description());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
$quiz->subnet = '0.0.0.0';
@@ -68,6 +69,7 @@ public function test_ipaddress_access_rule() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
}
@@ -64,6 +64,7 @@ public function test_num_attempts_access_rule() {
$this->assertTrue($rule->is_finished(666, $attempt));
$this->assertFalse($rule->prevent_access());
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
}
@@ -93,20 +93,24 @@ public function is_finished($numprevattempts, $lastattempt) {
return $this->quiz->timeclose && $this->timenow > $this->quiz->timeclose;
}
- public function time_left($attempt, $timenow) {
+ public function end_time($attempt) {
+ if ($this->quiz->timeclose) {
+ return $this->quiz->timeclose;
+ }
+ return false;
+ }
+
+ public function time_left_display($attempt, $timenow) {
// If this is a teacher preview after the close date, do not show
// the time.
if ($attempt->preview && $timenow > $this->quiz->timeclose) {
return false;
}
-
- // Otherwise, return to the time left until the close date, providing
- // that is less than QUIZ_SHOW_TIME_BEFORE_DEADLINE.
- if ($this->quiz->timeclose) {
- $timeleft = $this->quiz->timeclose - $timenow;
- if ($timeleft < QUIZ_SHOW_TIME_BEFORE_DEADLINE) {
- return $timeleft;
- }
+ // Otherwise, return to the time left until the close date, providing that is
+ // less than QUIZ_SHOW_TIME_BEFORE_DEADLINE.
+ $endtime = $this->end_time($attempt);
+ if ($endtime !== false && $timenow > $endtime - QUIZ_SHOW_TIME_BEFORE_DEADLINE) {
+ return $endtime - $timenow;
}
return false;
}
@@ -55,15 +55,17 @@ public function test_no_dates() {
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 10000));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 10000));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$rule = new quizaccess_openclosedate($quizobj, 0);
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
public function test_start_date() {
@@ -85,15 +87,17 @@ public function test_start_date() {
get_string('notavailable', 'quizaccess_openclosedate'));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
$rule = new quizaccess_openclosedate($quizobj, 10000);
$this->assertEquals($rule->description(),
array(get_string('quizopenedon', 'quiz', userdate(10000))));
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 0));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
public function test_close_date() {
@@ -114,10 +118,12 @@ public function test_close_date() {
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
- $this->assertEquals($rule->time_left($attempt, 19900), 100);
- $this->assertEquals($rule->time_left($attempt, 20000), 0);
- $this->assertEquals($rule->time_left($attempt, 20100), -100);
+
+ $this->assertEquals($rule->end_time($attempt), 20000);
+ $this->assertFalse($rule->time_left_display($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
+ $this->assertEquals($rule->time_left_display($attempt, 19900), 100);
+ $this->assertEquals($rule->time_left_display($attempt, 20000), 0);
+ $this->assertEquals($rule->time_left_display($attempt, 20100), -100);
$rule = new quizaccess_openclosedate($quizobj, 20001);
$this->assertEquals($rule->description(),
@@ -126,10 +132,11 @@ public function test_close_date() {
get_string('notavailable', 'quizaccess_openclosedate'));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertTrue($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
- $this->assertEquals($rule->time_left($attempt, 19900), 100);
- $this->assertEquals($rule->time_left($attempt, 20000), 0);
- $this->assertEquals($rule->time_left($attempt, 20100), -100);
+ $this->assertEquals($rule->end_time($attempt), 20000);
+ $this->assertFalse($rule->time_left_display($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
+ $this->assertEquals($rule->time_left_display($attempt, 19900), 100);
+ $this->assertEquals($rule->time_left_display($attempt, 20000), 0);
+ $this->assertEquals($rule->time_left_display($attempt, 20100), -100);
}
public function test_both_dates() {
@@ -176,10 +183,11 @@ public function test_both_dates() {
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertTrue($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
- $this->assertEquals($rule->time_left($attempt, 19900), 100);
- $this->assertEquals($rule->time_left($attempt, 20000), 0);
- $this->assertEquals($rule->time_left($attempt, 20100), -100);
+ $this->assertEquals($rule->end_time($attempt), 20000);
+ $this->assertFalse($rule->time_left_display($attempt, 20000 - QUIZ_SHOW_TIME_BEFORE_DEADLINE));
+ $this->assertEquals($rule->time_left_display($attempt, 19900), 100);
+ $this->assertEquals($rule->time_left_display($attempt, 20000), 0);
+ $this->assertEquals($rule->time_left_display($attempt, 20100), -100);
}
public function test_close_date_with_overdue() {
@@ -53,6 +53,7 @@ public function test_password_access_rule() {
get_string('requirepasswordmessage', 'quizaccess_password'));
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
}
@@ -58,6 +58,7 @@ public function test_safebrowser_access_rule() {
$rule->description());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
}
@@ -54,6 +54,7 @@ public function test_securewindow_access_rule() {
$this->assertEmpty($rule->description());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
$this->assertFalse($rule->is_finished(0, $attempt));
- $this->assertFalse($rule->time_left($attempt, 1));
+ $this->assertFalse($rule->end_time($attempt));
+ $this->assertFalse($rule->time_left_display($attempt, 0));
}
}
@@ -52,7 +52,17 @@ public function description() {
format_time($this->quiz->timelimit));
}
- public function time_left($attempt, $timenow) {
- return $attempt->timestart + $this->quiz->timelimit - $timenow;
+ public function end_time($attempt) {
+ return $attempt->timestart + $this->quiz->timelimit;
+ }
+
+ public function time_left_display($attempt, $timenow) {
+ // If this is a teacher preview after the time limit expires, don't show the time_left
+ $endtime = $this->end_time($attempt);
+ if ($attempt->preview && $timenow > $endtime) {
+ return false;
+ }
+ return $endtime - $timenow;
+
}
}
@@ -51,9 +51,11 @@ public function test_time_limit_access_rule() {
get_string('quiztimelimit', 'quizaccess_timelimit', format_time(3600)));
$attempt->timestart = 10000;
- $this->assertEquals($rule->time_left($attempt, 10000), 3600);
- $this->assertEquals($rule->time_left($attempt, 12000), 1600);
- $this->assertEquals($rule->time_left($attempt, 14000), -400);
+ $attempt->preview = 0;
+ $this->assertEquals($rule->end_time($attempt), 13600);
+ $this->assertEquals($rule->time_left_display($attempt, 10000), 3600);
+ $this->assertEquals($rule->time_left_display($attempt, 12000), 1600);
+ $this->assertEquals($rule->time_left_display($attempt, 14000), -400);
$this->assertFalse($rule->prevent_access());
$this->assertFalse($rule->prevent_new_attempt(0, $attempt));
@@ -13,3 +13,7 @@ Overview of this plugin type at http://docs.moodle.org/dev/Quiz_access_rules
* This plugin type now supports cron in the standard way. If required, Create a
lib.php file containing
function quizaccess_mypluginname_cron() {};
+
+=== 2.4 ===
+
+* Replaced time_left() with new time_left_display() and end_time() functions.
Oops, something went wrong.

0 comments on commit 8e771ae

Please sign in to comment.