}
$count++;
- // Make sure they didn't answer it more than the max number of attmepts
- if (count($try) > $lesson->maxattempts) {
- $essay = $try[$lesson->maxattempts-1];
- } else {
- $essay = end($try);
- }
+ // Make sure they didn't answer it more than the max number of attempts.
+ $essay = $lesson->get_last_attempt($try);
// Start processing the attempt
$essayinfo = lesson_page_type_essay::extract_useranswer($essay->useranswer);
$attemptset[$useranswer->pageid][] = $useranswer;
}
- // Drop all attempts that go beyond max attempts for the lesson
- foreach ($attemptset as $key => $set) {
- $attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
+ if (!empty($lesson->maxattempts)) {
+ // Drop all attempts that go beyond max attempts for the lesson.
+ foreach ($attemptset as $key => $set) {
+ $attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
+ }
}
// get only the pages and their answers that the user answered
}
return $data;
}
+
+ /**
+ * Returns the last "legal" attempt from the list of student attempts.
+ *
+ * @param array $attempts The list of student attempts.
+ * @return stdClass The updated fom data.
+ */
+ public function get_last_attempt(array $attempts): stdClass {
+ // If there are more tries than the max that is allowed, grab the last "legal" attempt.
+ if (!empty($this->maxattempts) && (count($attempts) > $this->maxattempts)) {
+ $lastattempt = $attempts[$this->maxattempts - 1];
+ } else {
+ // Grab the last attempt since there's no limit to the max attempts or the user has made fewer attempts than the max.
+ $lastattempt = end($attempts);
+ }
+ return $lastattempt;
+ }
}
'userid' => $USER->id, 'pageid' => $this->properties->id, 'retry' => $nretakes));
// Check if they have reached (or exceeded) the maximum number of attempts allowed.
- if ($nattempts >= $this->lesson->maxattempts) {
+ if (!empty($this->lesson->maxattempts) && $nattempts >= $this->lesson->maxattempts) {
$result->maxattemptsreached = true;
$result->feedback = get_string('maximumnumberofattemptsreached', 'lesson');
$result->newpageid = $this->lesson->get_next_page($this->properties->nextpageid);
// "number of attempts remaining" message if $this->lesson->maxattempts > 1
// displaying of message(s) is at the end of page for more ergonomic display
if (!$result->correctanswer && ($result->newpageid == 0)) {
- // retreive the number of attempts left counter for displaying at bottom of feedback page
- if ($nattempts >= $this->lesson->maxattempts) {
+ // Retrieve the number of attempts left counter for displaying at bottom of feedback page.
+ if (!empty($this->lesson->maxattempts) && $nattempts >= $this->lesson->maxattempts) {
if ($this->lesson->maxattempts > 1) { // don't bother with message if only one attempt
$result->maxattemptsreached = true;
}
$mform->setDefault('review', $lessonconfig->displayreview);
$mform->setAdvanced('review', $lessonconfig->displayreview_adv);
- $numbers = array();
+ $numbers = array('0' => get_string('unlimited'));
for ($i = 10; $i > 0; $i--) {
$numbers[$i] = $i;
}
return true;
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
$essayinfo = self::extract_useranswer($temp->useranswer);
if ($essayinfo->graded) {
if (isset($pagestats[$temp->pageid])) {
return true;
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
if ($temp->correct) {
if (isset($pagestats[$temp->pageid]["correct"])) {
$pagestats[$temp->pageid]["correct"]++;
return $table;
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
if ($this->properties->qoption) {
$userresponse = explode(",", $temp->useranswer);
foreach ($userresponse as $response) {
return $table;
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
$pagestats[$temp->pageid][$temp->useranswer]++;
} else {
return $table;
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
$pagestats[$temp->pageid][$temp->useranswer]++;
} else {
}
public function stats(array &$pagestats, $tries) {
- if(count($tries) > $this->lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
- $temp = $tries[$this->lesson->maxattempts - 1];
- } else {
- // else, user attempted the question less than the max, so grab the last one
- $temp = end($tries);
- }
+ $temp = $this->lesson->get_last_attempt($tries);
if ($this->properties->qoption) {
$userresponse = explode(",", $temp->useranswer);
foreach ($userresponse as $response) {
And I should not see "Yes, I'd like to try again"
And I press "Continue"
And I should see "Congratulations - end of lesson reached"
+
+ Scenario: Student should not see remaining attempts notification if maximum number of attempts is set to unlimited
+ Given I add a "Lesson" to section "1" and I fill the form with:
+ | Name | Test lesson name |
+ | Description | Test lesson description |
+ | id_review | Yes |
+ | id_maxattempts | 0 |
+ And I follow "Test lesson name"
+ And I follow "Add a question page"
+ And I set the following fields to these values:
+ | id_qtype | True/false |
+ And I press "Add a question page"
+ And I set the following fields to these values:
+ | Page title | Test question |
+ | Page contents | Test content |
+ | id_answer_editor_0 | right |
+ | id_answer_editor_1 | wrong |
+ And I press "Save page"
+ And I log out
+ And I log in as "student1"
+ And I am on "Course 1" course homepage
+ When I follow "Test lesson name"
+ Then I should see "Test content"
+ And I set the following fields to these values:
+ | wrong | 1 |
+ And I press "Submit"
+ And I should not see "attempt(s) remaining"
+ And I press "Yes, I'd like to try again"
+ And I should see "Test content"
+ And I set the following fields to these values:
+ | right | 1 |
+ And I press "Submit"
+ And I should not see "Yes, I'd like to try again"
+ And I should see "Congratulations - end of lesson reached"
$this->assertEquals(true, $lesson->is_participant($USER->id),
'Admin is enrolled, suspended and can participate');
}
+
+ /**
+ * Data provider for test_get_last_attempt.
+ *
+ * @return array
+ */
+ public function test_get_last_attempt_dataprovider() {
+ return [
+ [0, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
+ [1, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 1]],
+ [2, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 2]],
+ [3, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
+ [4, [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]], (object)['id' => 3]],
+ ];
+ }
+
+ /**
+ * Test the get_last_attempt() method.
+ *
+ * @dataProvider test_get_last_attempt_dataprovider
+ * @param int $maxattempts Lesson setting.
+ * @param array $attempts The list of student attempts.
+ * @param object $expected Expected result.
+ */
+ public function test_get_last_attempt($maxattempts, $attempts, $expected) {
+ $this->resetAfterTest();
+ $this->setAdminUser();
+ $course = $this->getDataGenerator()->create_course();
+ $lesson = $this->getDataGenerator()->create_module('lesson', ['course' => $course, 'maxattempts' => $maxattempts]);
+ $lesson = new lesson($lesson);
+ $this->assertEquals($expected, $lesson->get_last_attempt($attempts));
+ }
}