From 6695d5947f3c85180620bf965c7f431faba5b53d Mon Sep 17 00:00:00 2001
From: Stephen Bourget <sbourget@goffstown.k12.nh.us>
Date: Wed, 25 Feb 2015 10:22:41 -0500
Subject: [PATCH] MDL-34006 Lesson: Resume lesson loads wrong page.

---
 .../backup/moodle2/backup_lesson_stepslib.php |  2 +-
 .../moodle2/restore_lesson_stepslib.php       | 11 ++++
 mod/lesson/db/install.xml                     |  7 ++-
 mod/lesson/db/upgrade.php                     | 16 ++++++
 mod/lesson/pagetypes/branchtable.php          | 24 ++++----
 mod/lesson/version.php                        |  2 +-
 mod/lesson/view.php                           | 56 +++++++++++++------
 7 files changed, 84 insertions(+), 34 deletions(-)

diff --git a/mod/lesson/backup/moodle2/backup_lesson_stepslib.php b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php
index c95f6a0b4ec..ae17a64b253 100644
--- a/mod/lesson/backup/moodle2/backup_lesson_stepslib.php
+++ b/mod/lesson/backup/moodle2/backup_lesson_stepslib.php
@@ -119,7 +119,7 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
         // and user.
         $branches = new backup_nested_element('branches');
         $branch = new backup_nested_element('branch', array('id'), array(
-            'userid','retry','flag','timeseen'
+             'userid', 'retry', 'flag', 'timeseen', 'nextpageid'
         ));
 
         // The lesson_grades table
diff --git a/mod/lesson/backup/moodle2/restore_lesson_stepslib.php b/mod/lesson/backup/moodle2/restore_lesson_stepslib.php
index 815e2550051..2c981e3cf0d 100644
--- a/mod/lesson/backup/moodle2/restore_lesson_stepslib.php
+++ b/mod/lesson/backup/moodle2/restore_lesson_stepslib.php
@@ -233,6 +233,17 @@ class restore_lesson_activity_structure_step extends restore_activity_structure_
         }
         $rs->close();
 
+        // Remap all the restored 'nextpageid' fields now that we have all the pages and their mappings.
+        $rs = $DB->get_recordset('lesson_branch', array('lessonid' => $this->task->get_activityid()),
+                                 '', 'id, nextpageid');
+        foreach ($rs as $answer) {
+            if ($answer->nextpageid > 0) {
+                $answer->nextpageid = $this->get_mappingid('lesson_page', $answer->nextpageid);
+                $DB->update_record('lesson_branch', $answer);
+            }
+        }
+        $rs->close();
+
         // Re-map the dependency and activitylink information
         // If a depency or activitylink has no mapping in the backup data then it could either be a duplication of a
         // lesson, or a backup/restore of a single lesson. We have no way to determine which and whether this is the
diff --git a/mod/lesson/db/install.xml b/mod/lesson/db/install.xml
index 29f858fe26e..802994ae4c1 100644
--- a/mod/lesson/db/install.xml
+++ b/mod/lesson/db/install.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/lesson/db" VERSION="20120122" COMMENT="XMLDB file for Moodle mod/lesson"
+<XMLDB PATH="mod/lesson/db" VERSION="20150201" COMMENT="XMLDB file for Moodle mod/lesson"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -10,7 +10,7 @@
         <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
         <FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
-        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" />
+        <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="practice" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="modattempts" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="usepassword" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -165,6 +165,7 @@
         <FIELD NAME="retry" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="flag" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="timeseen" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="nextpageid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
@@ -192,4 +193,4 @@
       </INDEXES>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
diff --git a/mod/lesson/db/upgrade.php b/mod/lesson/db/upgrade.php
index 1f91609cece..e82d424b3cd 100644
--- a/mod/lesson/db/upgrade.php
+++ b/mod/lesson/db/upgrade.php
@@ -137,5 +137,21 @@ function xmldb_lesson_upgrade($oldversion) {
         // Lesson savepoint reached.
         upgrade_mod_savepoint(true, 2014122900, 'lesson');
     }
+
+    if ($oldversion < 2015022500) {
+
+        // Define field nextpageid to be added to lesson_branch.
+        $table = new xmldb_table('lesson_branch');
+        $field = new xmldb_field('nextpageid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timeseen');
+
+        // Conditionally launch add field nextpageid.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // Lesson savepoint reached.
+        upgrade_mod_savepoint(true, 2015022500, 'lesson');
+    }
+
     return true;
 }
diff --git a/mod/lesson/pagetypes/branchtable.php b/mod/lesson/pagetypes/branchtable.php
index 095495bee0a..cb7568af942 100644
--- a/mod/lesson/pagetypes/branchtable.php
+++ b/mod/lesson/pagetypes/branchtable.php
@@ -173,15 +173,6 @@ class lesson_page_type_branchtable extends lesson_page {
         } else {
             $retries = 0;
         }
-        $branch = new stdClass;
-        $branch->lessonid = $this->lesson->id;
-        $branch->userid = $USER->id;
-        $branch->pageid = $this->properties->id;
-        $branch->retry = $retries;
-        $branch->flag = $branchflag;
-        $branch->timeseen = time();
-
-        $DB->insert_record("lesson_branch", $branch);
 
         //  this is called when jumping to random from a branch table
         $context = context_module::instance($PAGE->cm->id);
@@ -207,8 +198,19 @@ class lesson_page_type_branchtable extends lesson_page {
         } elseif ($newpageid == LESSON_RANDOMBRANCH) {
             $newpageid = lesson_unseen_branch_jump($this->lesson, $USER->id);
         }
-        // no need to record anything in lesson_attempts
-        redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id,'pageid'=>$newpageid)));
+
+        // Record this page in lesson_branch.
+        $branch = new stdClass;
+        $branch->lessonid = $this->lesson->id;
+        $branch->userid = $USER->id;
+        $branch->pageid = $this->properties->id;
+        $branch->retry = $retries;
+        $branch->flag = $branchflag;
+        $branch->timeseen = time();
+        $branch->nextpageid = $newpageid;
+        $DB->insert_record("lesson_branch", $branch);
+
+        redirect(new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id, 'pageid' => $newpageid)));
     }
 
     public function display_answers(html_table $table) {
diff --git a/mod/lesson/version.php b/mod/lesson/version.php
index 8c3f6233801..6d29f8e5256 100644
--- a/mod/lesson/version.php
+++ b/mod/lesson/version.php
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2015021800;       // The current module version (Date: YYYYMMDDXX)
+$plugin->version   = 2015022500;    // The current module version (Date: YYYYMMDDXX)
 $plugin->requires  = 2014110400;    // Requires this Moodle version
 $plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
 $plugin->cron      = 0;
diff --git a/mod/lesson/view.php b/mod/lesson/view.php
index d52fe619679..662b2ee022b 100644
--- a/mod/lesson/view.php
+++ b/mod/lesson/view.php
@@ -215,33 +215,53 @@ if (empty($pageid)) {
         // in here, user has viewed a branch table
         $lastbranchtable = current($branchtables);
         if (count($allattempts) > 0) {
-            foreach($allattempts as $attempt) {
-                if ($lastbranchtable->timeseen > $attempt->timeseen) {
-                    // branch table was viewed later than the last attempt
+            if ($lastbranchtable->timeseen > $attempt->timeseen) {
+                // This branch table was viewed more recently than the question page.
+                if (!empty($lastbranchtable->nextpageid)) {
+                    $lastpageseen = $lastbranchtable->nextpageid;
+                } else {
+                    // Next page ID did not exist prior to MDL-34006.
                     $lastpageseen = $lastbranchtable->pageid;
                 }
-                break;
             }
         } else {
-            // hasnt answered any questions but has viewed a branch table
-            $lastpageseen = $lastbranchtable->pageid;
+            // Has not answered any questions but has viewed a branch table.
+            if (!empty($lastbranchtable->nextpageid)) {
+                $lastpageseen = $lastbranchtable->nextpageid;
+            } else {
+                // Next page ID did not exist prior to MDL-34006.
+                $lastpageseen = $lastbranchtable->pageid;
+            }
         }
     }
-    if (isset($lastpageseen) && $DB->count_records('lesson_attempts', array('lessonid'=>$lesson->id, 'userid'=>$USER->id, 'retry'=>$retries)) > 0) {
-        echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('leftduringtimedsession', 'lesson'));
-        if ($lesson->timed) {
-            if ($lesson->retake) {
-                $continuelink = new single_button(new moodle_url('/mod/lesson/view.php', array('id'=>$cm->id, 'pageid'=>$lesson->firstpageid, 'startlastseen'=>'no')), get_string('continue', 'lesson'), 'get');
-                echo '<div class="center leftduring">'.$lessonoutput->message(get_string('leftduringtimed', 'lesson'), $continuelink).'</div>';
+    // Check to see if end of lesson was reached.
+    if ((isset($lastpageseen) && ($lastpageseen != LESSON_EOL))) {
+        if (($DB->count_records('lesson_attempts', array('lessonid' => $lesson->id, 'userid' => $USER->id, 'retry' => $retries)) > 0)
+                || $DB->count_records('lesson_branch', array("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $retries)) > 0) {
+
+            echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('leftduringtimedsession', 'lesson'));
+            if ($lesson->timed) {
+                if ($lesson->retake) {
+                    $continuelink = new single_button(new moodle_url('/mod/lesson/view.php',
+                            array('id' => $cm->id, 'pageid' => $lesson->firstpageid, 'startlastseen' => 'no')),
+                            get_string('continue', 'lesson'), 'get');
+
+                    echo html_writer::div($lessonoutput->message(get_string('leftduringtimed', 'lesson'), $continuelink),
+                            'center leftduring');
+
+                } else {
+                    $courselink = new single_button(new moodle_url('/course/view.php',
+                            array('id' => $PAGE->course->id)), get_string('returntocourse', 'lesson'), 'get');
+
+                    echo html_writer::div($lessonoutput->message(get_string('leftduringtimednoretake', 'lesson'), $courselink),
+                            'center leftduring');
+                }
             } else {
-                $courselink = new single_button(new moodle_url('/course/view.php', array('id'=>$PAGE->course->id)), get_string('returntocourse', 'lesson'), 'get');
-                echo '<div class="center leftduring">'.$lessonoutput->message(get_string('leftduringtimednoretake', 'lesson'), $courselink).'</div>';
+                echo $lessonoutput->continue_links($lesson, $lastpageseen);
             }
-        } else {
-            echo $lessonoutput->continue_links($lesson, $lastpageseen);
+            echo $lessonoutput->footer();
+            exit();
         }
-        echo $lessonoutput->footer();
-        exit();
     }
 
     if ($attemptflag) {