diff --git a/mod/lesson/lang/en/deprecated.txt b/mod/lesson/lang/en/deprecated.txt
index 948ccc10d8a..cd791367dd3 100644
--- a/mod/lesson/lang/en/deprecated.txt
+++ b/mod/lesson/lang/en/deprecated.txt
@@ -1 +1,2 @@
essayemailmessage,mod_lesson
+lessonattempted,mod_lesson
diff --git a/mod/lesson/lang/en/lesson.php b/mod/lesson/lang/en/lesson.php
index de04c568fe6..91e48c959e3 100644
--- a/mod/lesson/lang/en/lesson.php
+++ b/mod/lesson/lang/en/lesson.php
@@ -50,6 +50,7 @@ $string['addedendofcluster'] = 'Added an end of cluster';
$string['addendofcluster'] = 'Add an end of cluster';
$string['addnewgroupoverride'] = 'Add group override';
$string['addnewuseroverride'] = 'Add user override';
+$string['additionalattemptsremaining'] = 'Completed, You can re-attempt this lesson';
$string['addpage'] = 'Add a page';
$string['and'] = 'AND';
$string['anchortitle'] = 'Start of main content';
@@ -250,7 +251,6 @@ $string['leftduringtimed'] = 'You have left during a timed lesson.
Please c
$string['leftduringtimednoretake'] = 'You have left during a timed lesson and you are
not allowed to retake or continue the lesson.';
$string['lesson:addinstance'] = 'Add a new lesson';
$string['lesson:grade'] = 'Grade lesson essay questions';
-$string['lessonattempted'] = 'Lesson attempted';
$string['lessonclosed'] = 'This lesson closed on {$a}.';
$string['lessoncloses'] = 'Lesson closes';
$string['lessoncloseson'] = 'Lesson closes on {$a}';
@@ -259,6 +259,7 @@ $string['lessonformating'] = 'Lesson formatting';
$string['lesson:manage'] = 'Manage a lesson activity';
$string['lesson:manageoverrides'] = 'Manage lesson overrides';
$string['lesson:viewreports'] = 'View lesson reports';
+$string['lessonname'] = 'Lesson: {$a}';
$string['lessonmenu'] = 'Lesson menu';
$string['lessonnotready'] = 'This lesson is not ready to be taken. Please contact your {$a}.';
$string['lessonnotready2'] = 'This lesson is not ready to be taken.';
@@ -346,6 +347,7 @@ $string['nooverridedata'] = 'You must override at least one of the lesson settin
$string['noretake'] = 'You are not allowed to retake this lesson.';
$string['normal'] = 'Normal - follow lesson path';
$string['notcompleted'] = 'Not completed';
+$string['notyetcompleted'] = 'Lesson has been started, but not yet completed';
$string['notdefined'] = 'Not defined';
$string['notenoughsubquestions'] = 'Not enough sub-questions have been defined!';
$string['notenoughtimespent'] = 'You completed this lesson in {$a->timespent}, which is less than the required time of {$a->timerequired}. You might need to attempt the lesson again.';
@@ -520,3 +522,4 @@ $string['youshouldview'] = 'You should answer at least: {$a}';
// Deprecated since Moodle 2.9.
$string['essayemailmessage'] = '
Essay prompt:
{$a->question}
Your response:
{$a->response}
{$a->teacher}\'s comments:
{$a->comment}
You have received {$a->earned} out of {$a->outof} for this essay question.
Your grade for the lesson has been changed to {$a->newgrade}%.
'; +$string['lessonattempted'] = 'Lesson attempted'; diff --git a/mod/lesson/lib.php b/mod/lesson/lib.php index f7d068d16a4..e73170bc5a1 100644 --- a/mod/lesson/lib.php +++ b/mod/lesson/lib.php @@ -418,10 +418,52 @@ function lesson_print_overview($courses, &$htmlarray) { return; } -/// Get Necessary Strings - $strlesson = get_string('modulename', 'lesson'); - $strnotattempted = get_string('nolessonattempts', 'lesson'); - $strattempted = get_string('lessonattempted', 'lesson'); + // Get all of the current users attempts on all lessons. + $params = array($USER->id); + $sql = 'SELECT lessonid, userid, count(userid) as attempts + FROM {lesson_grades} + WHERE userid = ? + GROUP BY lessonid, userid'; + $allattempts = $DB->get_records_sql($sql, $params); + $completedattempts = array(); + foreach ($allattempts as $myattempt) { + $completedattempts[$myattempt->lessonid] = $myattempt->attempts; + } + + // Get the current course ID. + $listoflessons = array(); + foreach ($lessons as $lesson) { + $listoflessons[] = $lesson->id; + } + // Get the last page viewed by the current user for every lesson in this course. + list($insql, $inparams) = $DB->get_in_or_equal($listoflessons, SQL_PARAMS_NAMED); + $dbparams = array_merge($inparams, array('userid1' => $USER->id, 'userid2' => $USER->id)); + + $lastattempts = $DB->get_records_sql("SELECT l.id, l.timeseen,l.lessonid, l.userid, + l.retry, l.pageid, l.nextpageid, p.qtype FROM ( + SELECT lessonid, userid, pageid, timeseen, retry, id, answerid AS nextpageid + FROM {lesson_attempts} + WHERE userid = :userid1 + UNION + SELECT lessonid, userid, pageid, timeseen, retry, id, nextpageid + FROM {lesson_branch} + WHERE userid = :userid2) l + JOIN {lesson_pages} p + ON l.pageid = p.id + WHERE l.lessonid $insql + ORDER BY l.lessonid asc, l.timeseen desc", $dbparams); + + $lastviewed = array(); + foreach ($lastattempts as $lastattempt) { + if (!isset($lastviewed[$lastattempt->lessonid])) { + $lastviewed[$lastattempt->lessonid] = $lastattempt; + } else if ($lastviewed[$lastattempt->lessonid]->timeseen < $lastattempt->timeseen) { + $lastviewed[$lastattempt->lessonid] = $lastattempt; + } + } + + // Since we have lessons in this course, now include the constants we need. + require_once($CFG->dirroot . '/mod/lesson/locallib.php'); $now = time(); foreach ($lessons as $lesson) { @@ -429,37 +471,84 @@ function lesson_print_overview($courses, &$htmlarray) { and $lesson->deadline >= $now // And it is before the deadline has been met and ($lesson->available == 0 or $lesson->available <= $now)) { // And the lesson is available - // Lesson name - if (!$lesson->visible) { - $class = ' class="dimmed"'; - } else { - $class = ''; - } - $str = $OUTPUT->box("$strlesson: wwwroot/mod/lesson/view.php?id=$lesson->coursemodule\">". - format_string($lesson->name).'', 'name'); + // Visibility. + $class = (!$lesson->visible) ? 'dimmed' : ''; - // Deadline + // Context. + $context = context_module::instance($lesson->coursemodule); + + // Link to activity. + $url = new moodle_url('/mod/lesson/view.php', array('id' => $lesson->coursemodule)); + $url = html_writer::link($url, format_string($lesson->name, true, array('context' => $context)), array('class' => $class)); + $str = $OUTPUT->box(get_string('lessonname', 'lesson', $url), 'name'); + + // Deadline. $str .= $OUTPUT->box(get_string('lessoncloseson', 'lesson', userdate($lesson->deadline)), 'info'); - // Attempt information - if (has_capability('mod/lesson:manage', context_module::instance($lesson->coursemodule))) { - // Number of user attempts + // Attempt information. + if (has_capability('mod/lesson:manage', $context)) { + // This is a teacher, Get the Number of user attempts. $attempts = $DB->count_records('lesson_grades', array('lessonid' => $lesson->id)); $str .= $OUTPUT->box(get_string('xattempts', 'lesson', $attempts), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); } else { - // Determine if the user has attempted the lesson or not - if ($DB->count_records('lesson_attempts', array('lessonid'=>$lesson->id, 'userid'=>$USER->id))) { - $str .= $OUTPUT->box($strattempted, 'info'); + // This is a student, See if the user has at least started the lesson. + if (isset($lastviewed[$lesson->id]->timeseen)) { + // See if the user has finished this attempt. + if (isset($completedattempts[$lesson->id]) && + ($completedattempts[$lesson->id] == ($lastviewed[$lesson->id]->retry + 1))) { + // Are additional attempts allowed? + if ($lesson->retake) { + // User can retake the lesson. + $str .= $OUTPUT->box(get_string('additionalattemptsremaining', 'lesson'), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); + } else { + // User has completed the lesson and no retakes are allowed. + $str = ''; + } + + } else { + // The last attempt was not finished or the lesson does not contain questions. + // See if the last page viewed was a branchtable. + require_once($CFG->dirroot . '/mod/lesson/pagetypes/branchtable.php'); + if ($lastviewed[$lesson->id]->qtype == LESSON_PAGE_BRANCHTABLE) { + // See if the next pageid is the end of lesson. + if ($lastviewed[$lesson->id]->nextpageid == LESSON_EOL) { + // The last page viewed was the End of Lesson. + if ($lesson->retake) { + // User can retake the lesson. + $str .= $OUTPUT->box(get_string('additionalattemptsremaining', 'lesson'), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); + } else { + // User has completed the lesson and no retakes are allowed. + $str = ''; + } + + } else { + // The last page viewed was NOT the end of lesson. + $str .= $OUTPUT->box(get_string('notyetcompleted', 'lesson'), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); + } + + } else { + // Last page was a question page, so the attempt is not completed yet. + $str .= $OUTPUT->box(get_string('notyetcompleted', 'lesson'), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); + } + } + } else { - $str .= $OUTPUT->box($strnotattempted, 'info'); + // User has not yet started this lesson. + $str .= $OUTPUT->box(get_string('nolessonattempts', 'lesson'), 'info'); + $str = $OUTPUT->box($str, 'lesson overview'); } } - $str = $OUTPUT->box($str, 'lesson overview'); - - if (empty($htmlarray[$lesson->course]['lesson'])) { - $htmlarray[$lesson->course]['lesson'] = $str; - } else { - $htmlarray[$lesson->course]['lesson'] .= $str; + if (!empty($str)) { + if (empty($htmlarray[$lesson->course]['lesson'])) { + $htmlarray[$lesson->course]['lesson'] = $str; + } else { + $htmlarray[$lesson->course]['lesson'] .= $str; + } } } } diff --git a/mod/lesson/tests/behat/lesson_student_my_home.feature b/mod/lesson/tests/behat/lesson_student_my_home.feature new file mode 100644 index 00000000000..c11206c083f --- /dev/null +++ b/mod/lesson/tests/behat/lesson_student_my_home.feature @@ -0,0 +1,326 @@ +@mod @mod_lesson +Feature: In My home, a student can see their current status on all lessons with an upcoming due date + In order to know my status on a lesson + As a student + I need to see it in My home + + Background: + Given the following "users" exist: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@asd.com | + | student1 | Student | 1 | student1@asd.com | + And the following "courses" exist: + | fullname | shortname | category | + | Course 1 | C1 | 0 | + And the following "course enrolments" exist: + | user | course | role | + | teacher1 | C1 | editingteacher | + | student1 | C1 | student | + And the following "activities" exist: + | activity | name | intro | deadline | retake | course | idnumber | + | lesson | Test lesson name | Test lesson description | 1893481200 | 1 | C1 | lesson1 | + And I log in as "teacher1" + And I follow "Course 1" + And I turn editing mode on + + @javascript + Scenario: A completed lesson with only questions that allows multiple attempts + Given I follow "Test lesson name" + And I follow "Add a question page" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 1 | + | Page contents | Cat is an amphibian | + | id_answer_editor_0 | False | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | True | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I set the field "qtype" to "Question" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 2 | + | Page contents | Paper is made from trees. | + | id_answer_editor_0 | True | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | False | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "Cat is an amphibian" + And I set the following fields to these values: + | False | 1 | + And I press "Submit" + And I press "Continue" + And I should see "Paper is made from trees." + And I set the following fields to these values: + | False | 1 | + And I press "Submit" + And I press "Continue" + And I should see "Congratulations - end of lesson reached" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "Completed, You can re-attempt this lesson" + + @javascript + Scenario: A completed lesson with only questions that does not allow multiple attempts + Given I follow "Test lesson name" + And I navigate to "Edit settings" node in "Lesson administration" + And I set the following fields to these values: + | Re-takes allowed | 0 | + And I press "Save and display" + And I follow "Add a question page" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 1 | + | Page contents | Cat is an amphibian | + | id_answer_editor_0 | False | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | True | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I set the field "qtype" to "Question" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 2 | + | Page contents | Paper is made from trees. | + | id_answer_editor_0 | True | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | False | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "Cat is an amphibian" + And I set the following fields to these values: + | False | 1 | + And I press "Submit" + And I press "Continue" + And I should see "Paper is made from trees." + And I set the following fields to these values: + | False | 1 | + And I press "Submit" + And I press "Continue" + And I should see "Congratulations - end of lesson reached" + When I click on "My home" "link" in the "Navigation" "block" + Then I should not see "You have lessons that are due" + + @javascript + Scenario: A completed lesson with only content pages that allows multiple attempts + Given I follow "Test lesson name" + And I follow "Add a content page" + And I set the following fields to these values: + | Page title | First page name | + | Page contents | First page contents | + | id_answer_editor_0 | Next page | + | id_jumpto_0 | Next page | + And I press "Save page" + And I set the field "qtype" to "Add a content page" + And I set the following fields to these values: + | Page title | Second page name | + | Page contents | Second page contents | + | id_answer_editor_0 | Previous page | + | id_jumpto_0 | Previous page | + | id_answer_editor_1 | End of lesson | + | id_jumpto_1 | End of lesson | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "First page contents" + And I press "Next page" + And I should see "Second page contents" + And I press "End of lesson" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "Completed, You can re-attempt this lesson" + + @javascript + Scenario: A completed lesson with only content pages that does not allow multiple attempts + Given I follow "Test lesson name" + And I navigate to "Edit settings" node in "Lesson administration" + And I set the following fields to these values: + | Re-takes allowed | 0 | + And I press "Save and display" + And I follow "Add a content page" + And I set the following fields to these values: + | Page title | First page name | + | Page contents | First page contents | + | id_answer_editor_0 | Next page | + | id_jumpto_0 | Next page | + And I press "Save page" + And I set the field "qtype" to "Add a content page" + And I set the following fields to these values: + | Page title | Second page name | + | Page contents | Second page contents | + | id_answer_editor_0 | Previous page | + | id_jumpto_0 | Previous page | + | id_answer_editor_1 | End of lesson | + | id_jumpto_1 | End of lesson | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "First page contents" + And I press "Next page" + And I should see "Second page contents" + And I press "End of lesson" + When I click on "My home" "link" in the "Navigation" "block" + Then I should not see "You have lessons that are due" + + @javascript + Scenario: An incomplete lesson with only questions. + Given I follow "Test lesson name" + And I follow "Add a question page" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 1 | + | Page contents | Cat is an amphibian | + | id_answer_editor_0 | False | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | True | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I set the field "qtype" to "Question" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 2 | + | Page contents | Paper is made from trees. | + | id_answer_editor_0 | True | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | False | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "Cat is an amphibian" + And I set the following fields to these values: + | False | 1 | + And I press "Submit" + And I press "Continue" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "Lesson has been started, but not yet completed" + + @javascript + Scenario: An incomplete lesson with only content pages. + Given I follow "Test lesson name" + And I follow "Add a content page" + And I set the following fields to these values: + | Page title | First page name | + | Page contents | First page contents | + | id_answer_editor_0 | Next page | + | id_jumpto_0 | Next page | + And I press "Save page" + And I set the field "qtype" to "Add a content page" + And I set the following fields to these values: + | Page title | Second page name | + | Page contents | Second page contents | + | id_answer_editor_0 | Previous page | + | id_jumpto_0 | Previous page | + | id_answer_editor_1 | End of lesson | + | id_jumpto_1 | End of lesson | + And I press "Save page" + And I log out + And I log in as "student1" + And I follow "Course 1" + And I follow "Test lesson name" + And I should see "First page contents" + And I press "Next page" + And I should see "Second page contents" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "Lesson has been started, but not yet completed" + + @javascript + Scenario: A lesson with only questions that has not been started. + Given I follow "Test lesson name" + And I follow "Add a question page" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 1 | + | Page contents | Cat is an amphibian | + | id_answer_editor_0 | False | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | True | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I set the field "qtype" to "Question" + And I set the field "Select a question type" to "True/false" + And I press "Add a question page" + And I set the following fields to these values: + | Page title | True/false question 2 | + | Page contents | Paper is made from trees. | + | id_answer_editor_0 | True | + | id_response_editor_0 | Correct | + | id_jumpto_0 | Next page | + | id_answer_editor_1 | False | + | id_response_editor_1 | Wrong | + | id_jumpto_1 | This page | + And I press "Save page" + And I log out + And I log in as "student1" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "No attempts have been made on this lesson" + + @javascript + Scenario: A lesson with only content pages that has not been started. + Given I follow "Test lesson name" + And I follow "Add a content page" + And I set the following fields to these values: + | Page title | First page name | + | Page contents | First page contents | + | id_answer_editor_0 | Next page | + | id_jumpto_0 | Next page | + And I press "Save page" + And I set the field "qtype" to "Add a content page" + And I set the following fields to these values: + | Page title | Second page name | + | Page contents | Second page contents | + | id_answer_editor_0 | Previous page | + | id_jumpto_0 | Previous page | + | id_answer_editor_1 | End of lesson | + | id_jumpto_1 | End of lesson | + And I press "Save page" + And I log out + And I log in as "student1" + When I click on "My home" "link" in the "Navigation" "block" + Then I should see "You have lessons that are due" + And I click on ".collapsibleregioncaption" "css_element" + And I should see "No attempts have been made on this lesson" \ No newline at end of file