]> git.mjollnir.org Git - moodle.git/commitdiff
mod-lesson MDL-21006 Huge refactoring of the lesson code
authorSam Hemelryk <sam@moodle.com>
Wed, 16 Dec 2009 02:00:48 +0000 (02:00 +0000)
committerSam Hemelryk <sam@moodle.com>
Wed, 16 Dec 2009 02:00:48 +0000 (02:00 +0000)
The following are notable changes made in this commit
* Lesson page type are now class based and extend an abstract class. This includes a class for the page type and a class for the creating/editing a instance of this page.
* Converted all forms to mforms
* Action script located in mod/action/* were worked into the above so far less switch statements and the action directory will be removed.
* Implements a custom renderer
* Converted everything to use page, output, and custom renderer methods
* Replaced all deprecated methods incl. print_textarea conversions
* Tried to cut down on excessive DB calls.
Things worth noting:
* The focus of this patch was on cleaning up the module not rewriting it, as such I have organized NOT rewritten. There are still many areas in the module where the code could be greatly improved however to do so would require a rethink/rewrite

61 files changed:
lang/en_utf8/help/lesson/displayleftif.html [new file with mode: 0644]
lang/en_utf8/lesson.php
mod/lesson/action/addbranchtable.php [deleted file]
mod/lesson/action/addcluster.php [deleted file]
mod/lesson/action/addendofbranch.php [deleted file]
mod/lesson/action/addendofcluster.php [deleted file]
mod/lesson/action/addpage.php [deleted file]
mod/lesson/action/confirmdelete.php [deleted file]
mod/lesson/action/continue.html [deleted file]
mod/lesson/action/continue.php [deleted file]
mod/lesson/action/delete.php [deleted file]
mod/lesson/action/editpage.php [deleted file]
mod/lesson/action/insertpage.php [deleted file]
mod/lesson/action/move.php [deleted file]
mod/lesson/action/moveit.php [deleted file]
mod/lesson/action/updatepage.php [deleted file]
mod/lesson/backuplib.php
mod/lesson/continue.php [new file with mode: 0644]
mod/lesson/db/access.php
mod/lesson/db/install.php
mod/lesson/db/install.xml
mod/lesson/db/upgrade.php
mod/lesson/edit.php
mod/lesson/editpage.php [new file with mode: 0644]
mod/lesson/editpage_form.php [new file with mode: 0644]
mod/lesson/essay.php
mod/lesson/essay_form.php [new file with mode: 0644]
mod/lesson/format.php
mod/lesson/grade.php
mod/lesson/highscores.php
mod/lesson/import.php
mod/lesson/import_form.php [new file with mode: 0644]
mod/lesson/importppt.php
mod/lesson/importpptlib.php [new file with mode: 0644]
mod/lesson/index.php
mod/lesson/lesson.css [moved from mod/lesson/styles.php with 88% similarity]
mod/lesson/lesson.php
mod/lesson/lib.php
mod/lesson/locallib.php
mod/lesson/mediafile.php
mod/lesson/mod_form.php
mod/lesson/pagetypes/branchtable.php [new file with mode: 0644]
mod/lesson/pagetypes/cluster.php [new file with mode: 0644]
mod/lesson/pagetypes/endofbranch.php [new file with mode: 0644]
mod/lesson/pagetypes/endofcluster.php [new file with mode: 0644]
mod/lesson/pagetypes/essay.php [new file with mode: 0644]
mod/lesson/pagetypes/matching.php [new file with mode: 0644]
mod/lesson/pagetypes/multichoice.php [new file with mode: 0644]
mod/lesson/pagetypes/numerical.php [new file with mode: 0644]
mod/lesson/pagetypes/shortanswer.php [new file with mode: 0644]
mod/lesson/pagetypes/truefalse.php [new file with mode: 0644]
mod/lesson/reformat.php
mod/lesson/renderer.php [new file with mode: 0644]
mod/lesson/report.php
mod/lesson/restorelib.php
mod/lesson/settings.php [new file with mode: 0644]
mod/lesson/tabs.php
mod/lesson/timer.js
mod/lesson/version.php
mod/lesson/view.php
mod/lesson/view_form.php [new file with mode: 0644]

diff --git a/lang/en_utf8/help/lesson/displayleftif.html b/lang/en_utf8/help/lesson/displayleftif.html
new file mode 100644 (file)
index 0000000..9f71767
--- /dev/null
@@ -0,0 +1,6 @@
+<h1>Display left menu: grade condition</h1>
+
+<p>By specifying a grade greater than 0, the user taking the lesson must have a grade equal to
+or greater than the grade set in order to view the Left Menu.</p>
+<p>This allows Lesson designers to force users to go through the entire lesson during the user's first attempt.
+Then, if a user retakes the Lesson after meeting the required grade they can see the left menu to help with review.</p>
\ No newline at end of file
index 51bc5534c0099c97385628183f06a689d9cce8cb..a4da9a47aa270aa184b643d373a72b829ab166b0 100644 (file)
@@ -9,6 +9,7 @@ $string['activitylinkname'] = 'Go to: $a';
 $string['addabranchtable'] = 'Add a Branch Table';
 $string['addbranchtable'] = 'Add a Branch Table';
 $string['addanendofbranch'] = 'Add an End of Branch';
+$string['addanewpage'] = 'Add a new page';
 $string['addaquestionpage'] = 'Add a Question Page';
 $string['addaquestionpagehere'] = 'Add a question page here';
 $string['addcluster'] = 'Add a Cluster';
@@ -33,6 +34,7 @@ $string['available'] = 'Available from';
 $string['averagescore'] = 'Average score';
 $string['averagetime'] = 'Average time';
 $string['branchtable'] = 'Branch Table';
+$string['branch'] = 'Branch';
 $string['cannotfindanswer'] = 'Cannot find answer';
 $string['cannotfindattempt'] = 'Error: could not find attempt';
 $string['cannotfindessay'] = 'Error: could not find essay';
@@ -61,6 +63,7 @@ $string['checkquestion'] = 'Check question';
 $string['classstats'] = 'Class statistics';
 $string['clicktodownload'] = 'Click on the following link to download the file.';
 $string['clicktopost'] = 'Click here to post your grade on the High Scores list.';
+$string['cluster'] = 'Cluster';
 $string['clusterjump'] = 'Unseen question within a cluster';
 $string['clustertitle'] = 'Cluster';
 $string['collapsed'] = 'Collapsed';
@@ -69,6 +72,15 @@ $string['completed'] = 'Completed';
 $string['completederror'] = 'Complete the lesson';
 $string['completethefollowingconditions'] = 'You must complete the following condition(s) in <b>$a</b> lesson before you can proceed.';
 $string['conditionsfordependency'] = 'Condition(s) for the dependency';
+$string['configactionaftercorrectanswer']= 'The default action to take after a correct answer';
+$string['configmaxanswers']= 'Default maximum number of answers/branches per page';
+$string['configmaxhighscores']= 'Number of high scores displayed';
+$string['configmediaclose']= 'Displays a close button as part of the popup generated for a linked media file';
+$string['configmediaheight']= 'Sets the height of the popup displayed for a linked media file';
+$string['configmediawidth']= 'Sets the width of the popup displayed for a linked media file';
+$string['configslideshowbgcolor']= 'Background color to for the slideshow if it is enabled';
+$string['configslideshowheight']= 'Sets the height of the slideshow if it is enabled';
+$string['configslideshowwidth']= 'Sets the width of the slideshow if it is enabled';
 $string['confirmdelete']= 'Delete page';
 $string['confirmdeletionofthispage'] = 'Confirm deletion of this page';
 $string['congratulations'] = 'Congratulations - end of lesson reached';
@@ -95,19 +107,22 @@ $string['displayhighscores'] = 'Display high scores';
 $string['displayinleftmenu'] = 'Display in left menu?';
 $string['displayleftif'] = 'Display left menu only if grade greater than:';
 $string['displayleftmenu'] = 'Display left menu';
+$string['displayleftmenuif'] = 'Display left menu: grade condition';
 $string['displayofgrade'] = 'Display of grade (for students only)';
 $string['displayreview'] = 'Display review button';
 $string['displayscorewithessays'] = 'You earned $a->score out of $a->tempmaxgrade for the automatically graded questions.<br />Your $a->essayquestions essay question(s) will be graded and added<br />into your final score at a later date.<br /><br />Your current grade without the essay question(s) is $a->score out of $a->grade';
 $string['displayscorewithoutessays'] = 'Your score is $a->score (out of $a->grade).';
 $string['edit'] = 'Edit';
+$string['editingquestionpage'] = 'Editing $a question page';
 $string['editpage'] = 'Edit page contents';
 $string['editlessonsettings'] = 'Edit lesson settings';
 $string['editpagecontent'] = 'Edit page contents';
 $string['email'] = 'Email';
-$string['emailallgradedessays'] = 'Email ALL<br />graded essays';
+$string['emailallgradedessays'] = 'Email ALL graded essays';
 $string['emailgradedessays'] = 'Email graded essays';
 $string['emailsuccess'] = 'Emails sent successfully';
 $string['endofbranch'] = 'End of branch';
+$string['endofcluster'] = 'End of cluster';
 $string['endofclustertitle'] = 'End of cluster';
 $string['endoflesson'] = 'End of lesson';
 $string['enteredthis'] = 'entered this.';
@@ -144,6 +159,7 @@ $string['importppt'] = 'Import PowerPoint';
 $string['importquestions'] = 'Import questions';
 $string['insertedpage'] = 'Inserted page';
 $string['invalidpageid'] = 'Invalid lesson page ID';
+$string['invalidfile'] = 'Invalid file';
 $string['invalidid'] = 'No course module ID or lesson ID were passed';
 $string['invalidlessonid'] = 'lesson ID was incorrect';
 $string['invalidpageid'] = 'Invalid Page ID';
@@ -174,6 +190,8 @@ $string['lowscore'] = 'Low score';
 $string['lowtime'] = 'Low time';
 $string['manualgrading'] = 'Grade Essays';
 $string['matchesanswer'] = 'Matches with answer';
+$string['matching'] = 'Matching';
+$string['matchingpair'] = 'Matching pair $a';
 $string['maxhighscores'] = 'Number of high scores displayed';
 $string['maximumnumberofanswersbranches'] = 'Maximum number of answers/branches';
 $string['maximumnumberofattempts'] = 'Maximum number of attempts';
@@ -183,8 +201,8 @@ $string['maxtimewarning'] = 'You have $a minute(s) to finish the lesson.';
 $string['mediaclose'] = 'Show close button:';
 $string['mediafile'] = 'Pop-up to file or web page';
 $string['mediafilepopup'] = 'Click here to view';
-$string['mediaheight'] = 'Window height:';
-$string['mediawidth'] = 'width:';
+$string['mediaheight'] = 'Popup window height:';
+$string['mediawidth'] = 'Popup window width:';
 $string['minimumnumberofquestions'] = 'Minimum number of questions';
 $string['missingname'] = 'Please enter a nickname';
 $string['modattempts'] = 'Allow student review';
@@ -196,9 +214,11 @@ $string['movedpage'] = 'Moved page';
 $string['movepagehere'] = 'Move page to here';
 $string['moving'] = 'Moving page: $a';
 $string['multianswer'] = 'Multianswer';
+$string['multichoice'] = 'Multichoice';
 $string['multipleanswer'] = 'Multiple Answer';
 $string['nameapproved'] = 'Name approved';
 $string['namereject'] = 'Sorry, your name has been rejected by the filter.<br />Please try another name.';
+$string['new'] = 'new';
 $string['nextpage'] = 'Next page';
 $string['noanswer'] = 'No answer given.  Please go back and submit an answer.';
 $string['noattemptrecordsfound'] = 'No attempt records found: no grade given';
@@ -226,10 +246,12 @@ $string['numberofcorrectmatches'] = 'Number of correct matches: $a';
 $string['numberofpagestoshow'] = 'Number of pages (cards) to show';
 $string['numberofpagesviewed'] = 'Number of questions answered: $a';
 $string['numberofpagesviewednotice'] = 'Number of questions answered: $a->nquestions; (You should answer at least: $a->minquestions)';
+$string['numerical'] = 'Numerical';
 $string['onpostperpage'] = 'Only one posting per grade';
 $string['ongoing'] = 'Display ongoing score';
 $string['ongoingcustom'] = 'You have earned $a->score point(s) out of $a->currenthigh point(s) thus far.';
 $string['ongoingnormal'] = 'You have answered $a->correct correctly out of $a->viewed attempts.';
+$string['options'] = 'Options';
 $string['or'] = 'OR';
 $string['ordered'] = 'Ordered';
 $string['other'] = 'Other';
@@ -247,6 +269,7 @@ $string['pleaseenteryouranswerinthebox'] = 'Please enter your answer in the box'
 $string['pleasematchtheabovepairs'] = 'Please match the above pairs';
 $string['pointsearned'] = 'Points earned';
 $string['postsuccess'] = 'Post successful';
+$string['pptsuccessfullimport'] = 'Successfully imported pages from the uploaded PowerPoint Presentation';
 $string['practice'] = 'Practice lesson';
 $string['preprocesserror'] = 'Error occurred during pre-processing!';
 $string['processerror'] = 'Error occurred during processing!';
@@ -285,8 +308,10 @@ $string['savepage'] = 'Save page';
 $string['score'] = 'Score';
 $string['scores'] = 'Scores';
 $string['secondpluswrong'] = 'Not quite.  Would you like to try again?';
+$string['selectaqtype'] = 'Select a question type';
 $string['showanunansweredpage'] = 'Show an unanswered Page';
 $string['showanunseenpage'] = 'Show an Unseen Page';
+$string['shortanswer'] = 'Short answer';
 $string['singleanswer'] = 'Single Answer';
 $string['skip'] = 'Skip navigation';
 $string['slideshow'] = 'Slide Show';
@@ -312,6 +337,9 @@ $string['timespenterror'] = 'Spend at least $a minutes in the lesson';
 $string['timespentminutes'] = 'Time Spent (minutes)';
 $string['timetaken'] = 'Time taken';
 $string['topscorestitle'] = 'Top $a High Scores';
+$string['truefalse'] = 'True/False';
+$string['unabledtosavefile'] = 'The file you uploaded could not be saved';
+$string['unknownqtypesnotimported'] = '$a questions with unsupported question types were not imported';
 $string['unseenpageinbranch'] = 'Unseen question within a branch';
 $string['unsupportedqtype'] = 'Unsupported question type ($a)!';
 $string['updatedpage'] = 'Updated page';
diff --git a/mod/lesson/action/addbranchtable.php b/mod/lesson/action/addbranchtable.php
deleted file mode 100644 (file)
index 92ebafc..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- *  Action for adding a branch table.  Prints an HTML form.
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-
-    // first get the preceeding page
-    $pageid = required_param('pageid', PARAM_INT);
-
-    // set of jump array
-    $jump = array();
-    $jump[0] = get_string("thispage", "lesson");
-    $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
-    $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
-    $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
-    if (!optional_param('firstpage', 0, PARAM_INT)) {
-        if (!$apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
-            print_error('cannotfindfirstpage', 'lesson');
-        }
-        while (true) {
-            if ($apageid) {
-                $title = $DB->get_field("lesson_pages", "title", array("id" => $apageid));
-                $jump[$apageid] = $title;
-                $apageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $apageid));
-            } else {
-                // last page reached
-                break;
-            }
-        }
-     }
-    // give teacher a blank proforma
-    $helpicon = new moodle_help_icon();
-    $helpicon->text = get_string("addabranchtable", "lesson");
-    $helpicon->page = "overview";
-    $helpicon->module = "lesson";
-    echo $OUTPUT->heading_with_help($helpicon);
-
-    ?>
-    <form id="form" method="post" action="lesson.php" class="addform">
-    <fieldset class="invisiblefieldset fieldsetfix">
-    <input type="hidden" name="id" value="<?PHP echo $cm->id ?>" />
-    <input type="hidden" name="action" value="insertpage" />
-    <input type="hidden" name="pageid" value="<?PHP echo $pageid ?>" />
-    <input type="hidden" name="qtype" value="<?PHP echo LESSON_BRANCHTABLE ?>" />
-    <input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
-    <table class="generalbox boxaligncenter" cellpadding="5" border="1">
-    <tr valign="top">
-    <td><strong><label for="title"><?php print_string("pagetitle", "lesson"); ?>:</label></strong><br />
-    <input type="text" id="title" name="title" size="80" value="" /></td></tr>
-    <?php
-    echo "<tr><td><strong>";
-    echo get_string("pagecontents", "lesson").":</strong><br />\n";
-    print_textarea($usehtmleditor, 25,70, 0, 0, "contents");
-    echo "</td></tr>\n";
-    echo "<tr><td>\n";
-    echo "<div class=\"boxaligncenter addform\"><input name=\"layout\" type=\"checkbox\" value=\"1\" checked=\"checked\" />";
-    echo get_string("arrangebuttonshorizontally", "lesson")."\n";
-    echo "<br /><input name=\"display\" type=\"checkbox\" value=\"1\" checked=\"checked\" />";
-    echo get_string("displayinleftmenu", "lesson");
-    echo "</div>\n";
-    echo "</td></tr>\n";
-    for ($i = 0; $i < $lesson->maxanswers; $i++) {
-        $iplus1 = $i + 1;
-        echo "<tr><td><strong>".get_string("description", "lesson")." $iplus1:</strong><br />\n";
-        print_textarea(false, 10, 70, 630, 300, "answer[$i]");
-        echo "</td></tr>\n";
-        echo "<tr><td><strong>".get_string("jump", "lesson")." $iplus1:</strong> \n";
-        if ($i) {
-            // answers 2, 3, 4... jumpto this page
-            echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-        } else {
-            // answer 1 jumpto next page
-            echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", LESSON_NEXTPAGE, false));
-        }
-        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-        echo "</td></tr>\n";
-    }
-    // close table and form
-    ?>
-    </table><br />
-    <input type="submit" value="<?php  print_string("addabranchtable", "lesson") ?>" />
-    <input type="submit" name="cancel" value="<?php  print_string("cancel") ?>" />
-    </fieldset>
-    </form>
diff --git a/mod/lesson/action/addcluster.php b/mod/lesson/action/addcluster.php
deleted file mode 100644 (file)
index 8a3a709..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/**
- * Action for adding a cluster page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    // first get the preceeding page
-    // if $pageid = 0, then we are inserting a new page at the beginning of the lesson
-    $pageid = required_param('pageid', PARAM_INT);
-
-    $timenow = time();
-
-    if ($pageid == 0) {
-        if (!$page = $DB->get_record("lesson_pages", array("prevpageid" => 0, "lessonid" => $lesson->id))) {
-            print_error('cannotfindpagerecord', 'lesson');
-        }
-    } else {
-        if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-            print_error('cannotfindpagerecord', 'lesson');
-        }
-    }
-    $newpage = new stdClass;
-    $newpage->lessonid = $lesson->id;
-    $newpage->prevpageid = $pageid;
-    if ($pageid != 0) {
-        $newpage->nextpageid = $page->nextpageid;
-    } else {
-        $newpage->nextpageid = $page->id;
-    }
-    $newpage->qtype = LESSON_CLUSTER;
-    $newpage->timecreated = $timenow;
-    $newpage->title = get_string("clustertitle", "lesson");
-    $newpage->contents = get_string("clustertitle", "lesson");
-    $newpageid = $DB->insert_record("lesson_pages", $newpage);
-    // update the linked list...
-    if ($pageid != 0) {
-        $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
-    }
-
-    if ($pageid == 0) {
-        $page->nextpageid = $page->id;
-    }
-    if ($page->nextpageid) {
-        // the new page is not the last page
-        $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
-    }
-    // ..and the single "answer"
-    $newanswer = new stdClass;
-    $newanswer->lessonid = $lesson->id;
-    $newanswer->pageid = $newpageid;
-    $newanswer->timecreated = $timenow;
-    $newanswer->jumpto = LESSON_CLUSTERJUMP;
-    $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-    lesson_set_message(get_string('addedcluster', 'lesson'), 'notifysuccess');
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-
diff --git a/mod/lesson/action/addendofbranch.php b/mod/lesson/action/addendofbranch.php
deleted file mode 100644 (file)
index b6bb3be..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * Action for adding an end of branch page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    // first get the preceeding page
-    $pageid = required_param('pageid', PARAM_INT);
-
-    $timenow = time();
-
-    // the new page is not the first page (end of branch always comes after an existing page)
-    if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error('cannotfindpagerecord', 'lesson');
-    }
-    // chain back up to find the (nearest branch table)
-    $btpageid = $pageid;
-    if (!$btpage = $DB->get_record("lesson_pages", array("id" => $btpageid))) {
-        print_error('cannotfindpagerecord', 'lesson');
-    }
-    while (($btpage->qtype != LESSON_BRANCHTABLE) AND ($btpage->prevpageid > 0)) {
-        $btpageid = $btpage->prevpageid;
-        if (!$btpage = $DB->get_record("lesson_pages", array("id" => $btpageid))) {
-            print_error('cannotfindpagerecord', 'lesson');
-        }
-    }
-    if ($btpage->qtype == LESSON_BRANCHTABLE) {
-        $newpage = new stdClass;
-        $newpage->lessonid = $lesson->id;
-        $newpage->prevpageid = $pageid;
-        $newpage->nextpageid = $page->nextpageid;
-        $newpage->qtype = LESSON_ENDOFBRANCH;
-        $newpage->timecreated = $timenow;
-        $newpage->title = get_string("endofbranch", "lesson");
-        $newpage->contents = get_string("endofbranch", "lesson");
-        $newpageid = $DB->insert_record("lesson_pages", $newpage);
-        // update the linked list...
-        $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
-        if ($page->nextpageid) {
-            // the new page is not the last page
-            $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
-        }
-        // ..and the single "answer"
-        $newanswer = new stdClass;
-        $newanswer->lessonid = $lesson->id;
-        $newanswer->pageid = $newpageid;
-        $newanswer->timecreated = $timenow;
-        $newanswer->jumpto = $btpageid;
-        $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-
-        lesson_set_message(get_string('addedanendofbranch', 'lesson'), 'notifysuccess');
-    } else {
-        lesson_set_message(get_string('nobranchtablefound', 'lesson'));
-    }
-
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-
diff --git a/mod/lesson/action/addendofcluster.php b/mod/lesson/action/addendofcluster.php
deleted file mode 100644 (file)
index 4150950..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-/**
- * Action for adding an end of cluster page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    // first get the preceeding page
-    $pageid = required_param('pageid', PARAM_INT);
-
-    $timenow = time();
-
-    // the new page is not the first page (end of cluster always comes after an existing page)
-    if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error('cannotfindpages', 'lesson');
-    }
-
-    // could put code in here to check if the user really can insert an end of cluster
-
-    $newpage = new stdClass;
-    $newpage->lessonid = $lesson->id;
-    $newpage->prevpageid = $pageid;
-    $newpage->nextpageid = $page->nextpageid;
-    $newpage->qtype = LESSON_ENDOFCLUSTER;
-    $newpage->timecreated = $timenow;
-    $newpage->title = get_string("endofclustertitle", "lesson");
-    $newpage->contents = get_string("endofclustertitle", "lesson");
-    $newpageid = $DB->insert_record("lesson_pages", $newpage);
-    // update the linked list...
-    $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
-    if ($page->nextpageid) {
-        // the new page is not the last page
-        $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
-    }
-    // ..and the single "answer"
-    $newanswer = new stdClass;
-    $newanswer->lessonid = $lesson->id;
-    $newanswer->pageid = $newpageid;
-    $newanswer->timecreated = $timenow;
-    $newanswer->jumpto = LESSON_NEXTPAGE;
-    $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-    lesson_set_message(get_string('addedendofcluster', 'lesson'), 'notifysuccess');
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
diff --git a/mod/lesson/action/addpage.php b/mod/lesson/action/addpage.php
deleted file mode 100644 (file)
index 4ba7ca6..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-<?php
-/**
- *  Action for adding a question page.  Prints an HTML form.
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    // first get the preceeding page
-    $pageid = required_param('pageid', PARAM_INT);
-    $qtype = optional_param('qtype', LESSON_MULTICHOICE, PARAM_INT);
-
-    // set of jump array
-    $jump = array();
-    $jump[0] = get_string("thispage", "lesson");
-    $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
-    $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
-    $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
-    if(lesson_display_branch_jumps($lesson->id, $pageid)) {
-        $jump[LESSON_UNSEENBRANCHPAGE] = get_string("unseenpageinbranch", "lesson");
-        $jump[LESSON_RANDOMPAGE] = get_string("randompageinbranch", "lesson");
-    }
-    if(lesson_display_cluster_jump($lesson->id, $pageid)) {
-        $jump[LESSON_CLUSTERJUMP] = get_string("clusterjump", "lesson");
-    }
-    if (!optional_param('firstpage', 0, PARAM_INT)) {
-        $linkadd = "";
-        $apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0));
-
-        while (true) {
-            if ($apageid) {
-                $title = $DB->get_field("lesson_pages", "title", array("id" => $apageid));
-                $jump[$apageid] = strip_tags(format_string($title,true));
-                $apageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $apageid));
-            } else {
-                // last page reached
-                break;
-            }
-        }
-    } else {
-        $linkadd = "&amp;firstpage=1";
-    }
-
-    // give teacher a blank proforma
-    $helpicon = new moodle_help_icon();
-    $helpicon->text = get_string("addaquestionpage", "lesson");
-    $helpicon->page = "overview";
-    $helpicon->module = "lesson";
-    echo $OUTPUT->heading_with_help($helpicon);
-
-    ?>
-    <form id="form" method="post" action="lesson.php" class="addform">
-    <fieldset class="invisiblefieldset fieldsetfix">
-    <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
-    <input type="hidden" name="action" value="insertpage" />
-    <input type="hidden" name="pageid" value="<?php echo $pageid ?>" />
-    <input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
-      <?php
-        echo '<b>'.get_string("questiontype", "lesson").":</b> \n";
-        echo $OUTPUT->help_icon(moodle_help_icon::make("questiontypes", get_string("questiontype", "lesson"), "lesson"))."<br />";
-        lesson_qtype_menu($LESSON_QUESTION_TYPE, $qtype,
-                          "lesson.php?id=$cm->id&amp;action=addpage&amp;pageid=".$pageid.$linkadd);
-
-        if ( $qtype == LESSON_SHORTANSWER || $qtype == LESSON_MULTICHOICE ) {  // only display this option for Multichoice and shortanswer
-            echo '<p>';
-            if ($qtype == LESSON_SHORTANSWER) {
-                $qoptionstr = get_string('casesensitive', 'lesson');
-            } else {
-                $qoptionstr = get_string('multianswer', 'lesson');
-            }
-            echo "<label for=\"qoption\"><strong>$qoptionstr</strong></label><input type=\"checkbox\" id=\"qoption\" name=\"qoption\" value=\"1\"/>";
-            echo $OUTPUT->help_icon(moodle_help_icon::make("questionoption", get_string("questionoption", "lesson"), "lesson"));
-            echo '</p>';
-        }
-    ?>
-    <table cellpadding="5" class="generalbox boxaligncenter" border="1">
-    <tr valign="top">
-    <td><b><label for="title"><?php print_string("pagetitle", "lesson"); ?>:</label></b><br />
-    <input type="text" id="title" name="title" size="80" value="" /></td></tr>
-    <?php
-    echo "<tr><td><b>";
-    echo get_string("pagecontents", "lesson").":</b><br />\n";
-    print_textarea($usehtmleditor, 25,70, 630, 400, "contents");
-    echo "</td></tr>\n";
-    switch ($qtype) {
-        case LESSON_TRUEFALSE :
-            for ($i = 0; $i < 2; $i++) {
-                $iplus1 = $i + 1;
-                echo "<tr><td><b>".get_string("answer", "lesson")." $iplus1:</b><br />\n";
-                print_textarea(false, 6, 70, 630, 300, "answer[$i]");
-                echo "</td></tr>\n";
-                echo "<tr><td><b>".get_string("response", "lesson")." $iplus1:</b><br />\n";
-                print_textarea(false, 6, 70, 630, 300, "response[$i]");
-                echo "</td></tr>\n";
-                echo "<tr><td><b>".get_string("jump", "lesson")." $iplus1:</b> \n";
-                if ($i) {
-                    // answers 2, 3, 4... jumpto this page
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                } else {
-                    // answer 1 jumpto next page
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", LESSON_NEXTPAGE, false));
-                }
-                echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                if($lesson->custom) {
-                    if ($i) {
-                        echo get_string("score", "lesson")." $iplus1: <input type=\"text\" name=\"score[$i]\" value=\"0\" size=\"5\" />";
-                    } else {
-                        echo get_string("score", "lesson")." $iplus1: <input type=\"text\" name=\"score[$i]\" value=\"1\" size=\"5\" />";
-                    }
-                }
-                echo "</td></tr>\n";
-            }
-            break;
-        case LESSON_ESSAY :
-                echo "<tr><td><b>".get_string("jump", "lesson").":</b> \n";
-                echo $OUTPUT->select(html_select::make($jump, "jumpto[0]", LESSON_NEXTPAGE, false));
-                echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                if ($lesson->custom) {
-                    echo get_string("score", "lesson").": <input type=\"text\" name=\"score[0]\" value=\"1\" size=\"5\" />";
-                }
-                echo "</td></tr>\n";
-            break;
-        case LESSON_MATCHING :
-            for ($i = 0; $i < $lesson->maxanswers+2; $i++) {
-                $icorrected = $i - 1;
-                if ($i == 0) {
-                    echo "<tr><td><b>".get_string("correctresponse", "lesson").":</b><br />\n";
-                    print_textarea(false, 6, 70, 630, 300, "answer[$i]");
-                    echo "</td></tr>\n";
-                } elseif ($i == 1) {
-                    echo "<tr><td><b>".get_string("wrongresponse", "lesson").":</b><br />\n";
-                    print_textarea(false, 6, 70, 630, 300, "answer[$i]");
-                    echo "</td></tr>\n";
-                } else {
-                    echo "<tr><td><b>".get_string("answer", "lesson")." $icorrected:</b><br />\n";
-                    print_textarea(false, 6, 70, 630, 300, "answer[$i]");
-                    echo "</td></tr>\n";
-                    echo "<tr><td><b>".get_string("matchesanswer", "lesson")." $icorrected:</b><br />\n";
-                    print_textarea(false, 6, 70, 630, 300, "response[$i]");
-                    echo "</td></tr>\n";
-                }
-                if ($i == 2) {
-                    echo "<tr><td><b>".get_string("correctanswerjump", "lesson").":</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", LESSON_NEXTPAGE, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    if($lesson->custom) {
-                        echo get_string("correctanswerscore", "lesson").": <input type=\"text\" name=\"score[$i]\" value=\"1\" size=\"5\" />";
-                    }
-                    echo "</td></tr>\n";
-                } elseif ($i == 3) {
-                    echo "<tr><td><b>".get_string("wronganswerjump", "lesson").":</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    if($lesson->custom) {
-                        echo get_string("wronganswerscore", "lesson").": <input type=\"text\" name=\"score[$i]\" value=\"0\" size=\"5\" />";
-                    }
-                    echo "</td></tr>\n";
-                }
-            }
-            break;
-        case LESSON_SHORTANSWER :
-        case LESSON_NUMERICAL :
-        case LESSON_MULTICHOICE :
-            // default code
-            for ($i = 0; $i < $lesson->maxanswers; $i++) {
-                $iplus1 = $i + 1;
-                echo "<tr><td><b>".get_string("answer", "lesson")." $iplus1:</b><br />\n";
-                print_textarea(false, 6, 70, 630, 300, "answer[$i]");
-                echo "</td></tr>\n";
-                echo "<tr><td><b>".get_string("response", "lesson")." $iplus1:</b><br />\n";
-                print_textarea(false, 6, 70, 630, 300, "response[$i]");
-                echo "</td></tr>\n";
-                echo "<tr><td><b>".get_string("jump", "lesson")." $iplus1:</b> \n";
-                if ($i) {
-                    // answers 2, 3, 4... jumpto this page
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                } else {
-                    // answer 1 jumpto next page
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", LESSON_NEXTPAGE, false));
-                }
-                echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                if($lesson->custom) {
-                    if ($i) {
-                        echo get_string("score", "lesson")." $iplus1: <input type=\"text\" name=\"score[$i]\" value=\"0\" size=\"5\" />";
-                    } else {
-                        echo get_string("score", "lesson")." $iplus1: <input type=\"text\" name=\"score[$i]\" value=\"1\" size=\"5\" />";
-                    }
-                }
-                echo "</td></tr>\n";
-            }
-            break;
-    }
-    // close table and form
-    ?>
-    </table><br />
-    <input type="submit" value="<?php  print_string("addaquestionpage", "lesson") ?>" />
-    <input type="submit" name="cancel" value="<?php  print_string("cancel") ?>" />
-    </fieldset>
-    </form>
diff --git a/mod/lesson/action/confirmdelete.php b/mod/lesson/action/confirmdelete.php
deleted file mode 100644 (file)
index 8daa9fe..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Action for confirming the deletion of a page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    $pageid = required_param('pageid', PARAM_INT);
-    if (!$thispage = $DB->get_record("lesson_pages", array ("id" => $pageid))) {
-        print_error('cannotfindpages', 'lesson');
-    }
-    echo $OUTPUT->heading(get_string("deletingpage", "lesson", format_string($thispage->title)));
-    // print the jumps to this page
-    $params = array("lessonid" => $lesson->id, "pageid" => $pageid);
-    if ($answers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid AND jumpto = :pageid + 1", $params)) {
-        echo $OUTPUT->heading(get_string("thefollowingpagesjumptothispage", "lesson"));
-        echo "<p align=\"center\">\n";
-        foreach ($answers as $answer) {
-            if (!$title = $DB->get_field("lesson_pages", "title", array("id" => $answer->pageid))) {
-                print_error('cannotfindpagetitle', 'lesson');
-            }
-            echo $title."<br />\n";
-        }
-    }
-    echo $OUTPUT->confirm(get_string("confirmdeletionofthispage","lesson"),
-         "lesson.php?action=delete&id=$cm->id&pageid=$pageid",
-         "view.php?id=$cm->id");
-
diff --git a/mod/lesson/action/continue.html b/mod/lesson/action/continue.html
deleted file mode 100644 (file)
index c2f612d..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-/**
- * HTML template for continue.php
- *
- * @package lesson
- **/
-?>
-
-<?php if ($lesson->displayleft) { // Skip navigation anchor ?>
-
-        <a name="maincontent" id="maincontent" title="<?php print_string('anchortitle', 'lesson') ?>"></a>
-
-<?php } ?>
-
-<?php
-    // This calculates and prints the ongoing score message
-    if ($lesson->ongoing) {
-        lesson_print_ongoing_score($lesson);
-    }
-?>
-
-            <?php echo $feedback ?>
-
-<?php if (isset($USER->modattempts[$lesson->id])) { // User is modifying attempts - save button and some instructions ?>
-
-            <form id="endoflesson" method ="post" action="<?php echo $CFG->wwwroot ?>/mod/lesson/view.php">
-            <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
-            <input type="hidden" name="pageid" value="<?php echo LESSON_EOL; ?>" />
-
-            <p align="center">
-                <?php print_string("savechangesandeol", "lesson") ?>
-            </p>
-            <p align="center">
-                <?php lesson_print_submit_link(get_string('savechanges', 'lesson'), 'endoflesson'); ?>
-            </p>
-            <p align="center">
-                <?php print_string("or", "lesson") ?>
-            </p>
-            <p align="center">
-                <?php print_string("continuetoanswer", "lesson") ?>
-            </p>
-
-            </form>
-<?php } ?>
-
-<?php if ($lesson->review && !$correctanswer && !$noanswer && !$isessayquestion) { // Review button back ?>
-
-            <form id="reviewback" method ="post" action="<?php echo $CFG->wwwroot ?>/mod/lesson/view.php">
-            <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
-            <input type="hidden" name="pageid" value="<?php echo $pageid; ?>" />
-
-            <p>
-                <?php lesson_print_submit_link(get_string('reviewquestionback', 'lesson'), 'reviewback'); ?>
-            </p>
-
-            </form>
-
-<?php } ?>
-
-            <form id="pageform" method ="post" action="<?php echo $CFG->wwwroot ?>/mod/lesson/view.php">
-            <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
-            <input type="hidden" name="pageid" value="<?php echo $newpageid ?>" />
-
-<?php if ($lesson->review && !$correctanswer && !$noanswer && !$isessayquestion) { // Review button continue ?>
-
-            <p>
-                <?php lesson_print_submit_link(get_string('reviewquestioncontinue', 'lesson'), 'pageform'); ?>
-            </p>
-
-<?php } else { // Normal continue button ?>
-
-            <p>
-                <?php lesson_print_submit_link(get_string('continue', 'lesson'), 'pageform'); ?>
-            </p>
-
-<?php } ?>
-
-            </form>
diff --git a/mod/lesson/action/continue.php b/mod/lesson/action/continue.php
deleted file mode 100644 (file)
index f14f267..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-<?php
-/**
- * Action for processing page answers by users
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    // left menu code
-    // check to see if the user can see the left menu
-    if (!has_capability('mod/lesson:manage', $context)) {
-        $lesson->displayleft = lesson_displayleftif($lesson);
-    }
-
-    // This is the code updates the lesson time for a timed test
-    // get time information for this user
-    $timer = new stdClass;
-    if (!has_capability('mod/lesson:manage', $context)) {
-        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-        if (!$timer = $DB->get_records_select('lesson_timer', "lessonid = :lessonid AND userid = :userid", $params, 'starttime')) {
-            print_error('Error: could not find records');
-        } else {
-            $timer = array_pop($timer); // this will get the latest start time record
-        }
-
-        if ($lesson->timed) {
-            $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
-
-            if ($timeleft <= 0) {
-                // Out of time
-                lesson_set_message(get_string('eolstudentoutoftime', 'lesson'));
-                redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=".LESSON_EOL."&outoftime=normal");
-                die; // Shouldn't be reached, but make sure
-            } else if ($timeleft < 60) {
-                // One minute warning
-                lesson_set_message(get_string("studentoneminwarning", "lesson"));
-            }
-        }
-
-        $timer->lessontime = time();
-        $DB->update_record("lesson_timer", $timer);
-    }
-
-    // record answer (if necessary) and show response (if none say if answer is correct or not)
-    $pageid = required_param('pageid', PARAM_INT);
-    if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error("Continue: Page record not found");
-    }
-    // set up some defaults
-    $answerid        = 0;
-    $noanswer        = false;
-    $correctanswer   = false;
-    $isessayquestion = false;   // use this to turn off review button on essay questions
-    $newpageid       = 0;       // stay on the page
-    $studentanswer   = '';      // use this to store student's answer(s) in order to display it on feedback page
-    switch ($page->qtype) {
-         case LESSON_ESSAY :
-            $isessayquestion = true;
-            if (!$useranswer = $_POST['answer']) {
-                $noanswer = true;
-                break;
-            }
-            $useranswer = clean_param($useranswer, PARAM_RAW);
-
-            if (!$answers = $DB->get_records("lesson_answers", array("pageid" => $pageid), "id")) {
-                print_error("Continue: No answers found");
-            }
-            $correctanswer = false;
-            foreach ($answers as $answer) {
-                $answerid = $answer->id;
-                $newpageid = $answer->jumpto;
-            }
-            /// 6/29/04 //
-            $userresponse->sent=0;
-            $userresponse->graded = 0;
-            $userresponse->score = 0;
-            $userresponse->answer = $useranswer;
-            $userresponse->response = "";
-            $userresponse = serialize($userresponse);
-
-            $studentanswer = s($useranswer);
-            break;
-         case LESSON_SHORTANSWER :
-            if (isset($_POST['answer'])) {
-                $useranswer = $_POST['answer'];
-            } else {
-                $noanswer = true;
-                break;
-            }
-            $useranswer = s(clean_param($useranswer, PARAM_RAW));
-            if (!$answers = $DB->get_records("lesson_answers", array("pageid" => $pageid), "id")) {
-                print_error("Continue: No answers found");
-            }
-            $i=0;
-            foreach ($answers as $answer) {
-                $i += 1;
-                $expectedanswer  = $answer->answer; // for easier handling of $answer->answer
-                $ismatch         = false;
-                $markit          = false;
-                $useregexp       = false;
-
-                if ($page->qoption) {
-                    $useregexp = true;
-                }
-
-                if ($useregexp) { //we are using 'normal analysis', which ignores case
-                    $ignorecase = '';
-                    if ( substr($expectedanswer,strlen($expectedanswer) - 2, 2) == '/i') {
-                        $expectedanswer = substr($expectedanswer,0,strlen($expectedanswer) - 2);
-                        $ignorecase = 'i';
-                    }
-                } else {
-                    $expectedanswer = str_replace('*', '#####', $expectedanswer);
-                    $expectedanswer = preg_quote($expectedanswer, '/');
-                    $expectedanswer = str_replace('#####', '.*', $expectedanswer);
-                }
-                // see if user typed in any of the correct answers
-                if ((!$lesson->custom && lesson_iscorrect($pageid, $answer->jumpto)) or ($lesson->custom && $answer->score > 0) ) {
-                    if (!$useregexp) { // we are using 'normal analysis', which ignores case
-                        if (preg_match('/^'.$expectedanswer.'$/i',$useranswer)) {
-                            $ismatch = true;
-                        }
-                    } else {
-                        if (preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$useranswer)) {
-                            $ismatch = true;
-                        }
-                    }
-                    if ($ismatch == true) {
-                        $correctanswer = true;
-                    }
-                } else {
-                   if (!$useregexp) { //we are using 'normal analysis'
-                        // see if user typed in any of the wrong answers; don't worry about case
-                        if (preg_match('/^'.$expectedanswer.'$/i',$useranswer)) {
-                            $ismatch = true;
-                        }
-                    } else { // we are using regular expressions analysis
-                        $startcode = substr($expectedanswer,0,2);
-                        switch ($startcode){
-                            //1- check for absence of required string in $useranswer (coded by initial '--')
-                            case "--":
-                                $expectedanswer = substr($expectedanswer,2);
-                                if (!preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$useranswer)) {
-                                    $ismatch = true;
-                                }
-                                break;
-                            //2- check for code for marking wrong strings (coded by initial '++')
-                            case "++":
-                                $expectedanswer=substr($expectedanswer,2);
-                                $markit = true;
-                                //check for one or several matches
-                                if (preg_match_all('/'.$expectedanswer.'/'.$ignorecase,$useranswer, $matches)) {
-                                    $ismatch   = true;
-                                    $nb        = count($matches[0]);
-                                    $original  = array();
-                                    $marked    = array();
-                                    $fontStart = '<span class="incorrect matches">';
-                                    $fontEnd   = '</span>';
-                                    for ($i = 0; $i < $nb; $i++) {
-                                        array_push($original,$matches[0][$i]);
-                                        array_push($marked,$fontStart.$matches[0][$i].$fontEnd);
-                                    }
-                                    $useranswer = str_replace($original, $marked, $useranswer);
-                                }
-                                break;
-                            //3- check for wrong answers belonging neither to -- nor to ++ categories
-                            default:
-                                if (preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$useranswer, $matches)) {
-                                    $ismatch = true;
-                                }
-                                break;
-                        }
-                        $correctanswer = false;
-                    }
-                }
-                if ($ismatch) {
-                    $newpageid = $answer->jumpto;
-                    if (trim(strip_tags($answer->response))) {
-                        $response = $answer->response;
-                    }
-                    $answerid = $answer->id;
-                    break; // quit answer analysis immediately after a match has been found
-                }
-            }
-            $studentanswer = $useranswer;
-            break;
-
-        case LESSON_TRUEFALSE :
-            if (empty($_POST['answerid'])) {
-                $noanswer = true;
-                break;
-            }
-            $answerid = required_param('answerid', PARAM_INT);
-            if (!$answer = $DB->get_record("lesson_answers", array("id" => $answerid))) {
-                print_error("Continue: answer record not found");
-            }
-            if (lesson_iscorrect($pageid, $answer->jumpto)) {
-                $correctanswer = true;
-            }
-            if ($lesson->custom) {
-                if ($answer->score > 0) {
-                    $correctanswer = true;
-                } else {
-                    $correctanswer = false;
-                }
-            }
-            $newpageid = $answer->jumpto;
-            $response  = trim($answer->response);
-            $studentanswer = $answer->answer;
-            break;
-
-        case LESSON_MULTICHOICE :
-            if ($page->qoption) {
-                // MULTIANSWER allowed, user's answer is an array
-                if (isset($_POST['answer'])) {
-                    $useranswers = $_POST['answer'];
-                    foreach ($useranswers as $key => $useranswer) {
-                        $useranswers[$key] = clean_param($useranswer, PARAM_INT);
-                    }
-                } else {
-                    $noanswer = true;
-                    break;
-                }
-                // get what the user answered
-                $userresponse = implode(",", $useranswers);
-                // get the answers in a set order, the id order
-                if (!$answers = $DB->get_records("lesson_answers", array("pageid" => $pageid), "id")) {
-                    print_error("Continue: No answers found");
-                }
-                $ncorrect = 0;
-                $nhits = 0;
-                $correctresponse = '';
-                $wrongresponse = '';
-                $correctanswerid = 0;
-                $wronganswerid = 0;
-                // store student's answers for displaying on feedback page
-                foreach ($answers as $answer) {
-                    foreach ($useranswers as $key => $answerid) {
-                        if ($answerid == $answer->id) {
-                            $studentanswer .= '<br />'.$answer->answer;
-                        }
-                    }
-                }
-                // this is for custom scores.  If score on answer is positive, it is correct
-                if ($lesson->custom) {
-                    $ncorrect = 0;
-                    $nhits = 0;
-                    foreach ($answers as $answer) {
-                        if ($answer->score > 0) {
-                            $ncorrect++;
-
-                            foreach ($useranswers as $key => $answerid) {
-                                if ($answerid == $answer->id) {
-                                   $nhits++;
-                                }
-                            }
-                            // save the first jumpto page id, may be needed!...
-                            if (!isset($correctpageid)) {
-                                // leave in its "raw" state - will converted into a proper page id later
-                                $correctpageid = $answer->jumpto;
-                            }
-                            // save the answer id for scoring
-                            if ($correctanswerid == 0) {
-                                $correctanswerid = $answer->id;
-                            }
-                            // ...also save any response from the correct answers...
-                            if (trim(strip_tags($answer->response))) {
-                                $correctresponse = $answer->response;
-                            }
-                        } else {
-                            // save the first jumpto page id, may be needed!...
-                            if (!isset($wrongpageid)) {
-                                // leave in its "raw" state - will converted into a proper page id later
-                                $wrongpageid = $answer->jumpto;
-                            }
-                            // save the answer id for scoring
-                            if ($wronganswerid == 0) {
-                                $wronganswerid = $answer->id;
-                            }
-                            // ...and from the incorrect ones, don't know which to use at this stage
-                            if (trim(strip_tags($answer->response))) {
-                                $wrongresponse = $answer->response;
-                            }
-                        }
-                    }
-                } else {
-                    foreach ($answers as $answer) {
-                        if (lesson_iscorrect($pageid, $answer->jumpto)) {
-                            $ncorrect++;
-                            foreach ($useranswers as $key => $answerid) {
-                                if ($answerid == $answer->id) {
-                                    $nhits++;
-                                }
-                            }
-                            // save the first jumpto page id, may be needed!...
-                            if (!isset($correctpageid)) {
-                                // leave in its "raw" state - will converted into a proper page id later
-                                $correctpageid = $answer->jumpto;
-                            }
-                            // save the answer id for scoring
-                            if ($correctanswerid == 0) {
-                                $correctanswerid = $answer->id;
-                            }
-                            // ...also save any response from the correct answers...
-                            if (trim(strip_tags($answer->response))) {
-                                $correctresponse = $answer->response;
-                            }
-                        } else {
-                            // save the first jumpto page id, may be needed!...
-                            if (!isset($wrongpageid)) {
-                                // leave in its "raw" state - will converted into a proper page id later
-                                $wrongpageid = $answer->jumpto;
-                            }
-                            // save the answer id for scoring
-                            if ($wronganswerid == 0) {
-                                $wronganswerid = $answer->id;
-                            }
-                            // ...and from the incorrect ones, don't know which to use at this stage
-                            if (trim(strip_tags($answer->response))) {
-                                $wrongresponse = $answer->response;
-                            }
-                        }
-                    }
-                }
-                if ((count($useranswers) == $ncorrect) and ($nhits == $ncorrect)) {
-                    $correctanswer = true;
-                    $response  = $correctresponse;
-                    $newpageid = $correctpageid;
-                    $answerid  = $correctanswerid;
-                } else {
-                    $response  = $wrongresponse;
-                    $newpageid = $wrongpageid;
-                    $answerid  = $wronganswerid;
-                }
-            } else {
-                // only one answer allowed
-                if (empty($_POST['answerid'])) {
-                    $noanswer = true;
-                    break;
-                }
-                $answerid = required_param('answerid', PARAM_INT);
-                if (!$answer = $DB->get_record("lesson_answers", array("id" => $answerid))) {
-                    print_error("Continue: answer record not found");
-                }
-                if (lesson_iscorrect($pageid, $answer->jumpto)) {
-                    $correctanswer = true;
-                }
-                if ($lesson->custom) {
-                    if ($answer->score > 0) {
-                        $correctanswer = true;
-                    } else {
-                        $correctanswer = false;
-                    }
-                }
-                $newpageid = $answer->jumpto;
-                $response  = trim($answer->response);
-                $studentanswer = $answer->answer;
-            }
-            break;
-        case LESSON_MATCHING :
-            if (isset($_POST['response']) && is_array($_POST['response'])) { // only arrays should be submitted
-                $response = array();
-                foreach ($_POST['response'] as $key => $value) {
-                    $response[$key] = $value;
-                }
-            } else {
-                $noanswer = true;
-                break;
-            }
-
-            if (!$answers = $DB->get_records("lesson_answers", array("pageid" => $pageid), "id")) {
-                print_error("Continue: No answers found");
-            }
-
-            $ncorrect = 0;
-            $i = 0;
-            foreach ($answers as $answer) {
-                if ($i == 0 || $i == 1) {
-                    // ignore first two answers, they are correct response
-                    // and wrong response
-                    $i++;
-                    continue;
-                }
-                if ($answer->response == $response[$answer->id]) {
-                    $ncorrect++;
-                }
-                if ($i == 2) {
-                    $correctpageid = $answer->jumpto;
-                    $correctanswerid = $answer->id;
-                }
-                if ($i == 3) {
-                    $wrongpageid = $answer->jumpto;
-                    $wronganswerid = $answer->id;
-                }
-                $i++;
-            }
-            // get he users exact responses for record keeping
-            $userresponse = array();
-            foreach ($response as $key => $value) {
-                foreach($answers as $answer) {
-                    if ($value == $answer->response) {
-                        $userresponse[] = $answer->id;
-                    }
-                }
-                $studentanswer .= '<br />'.$answers[$key]->answer.' = '.$value;
-            }
-            $userresponse = implode(",", $userresponse);
-
-            $response = '';
-            if ($ncorrect == count($answers)-2) {  // dont count correct/wrong responses in the total.
-                foreach ($answers as $answer) {
-                    if ($answer->response == NULL && $answer->answer != NULL) {
-                        $response = $answer->answer;
-                        break;
-                    }
-                }
-                if (isset($correctpageid)) {
-                    $newpageid = $correctpageid;
-                }
-                if (isset($correctanswerid)) {
-                    $answerid = $correctanswerid;
-                }
-                $correctanswer = true;
-            } else {
-                $t = 0;
-                foreach ($answers as $answer) {
-                    if ($answer->response == NULL && $answer->answer != NULL) {
-                        if ($t == 1) {
-                            $response = $answer->answer;
-                            break;
-                        }
-                        $t++;
-                    }
-                }
-                $newpageid = $wrongpageid;
-                $answerid = $wronganswerid;
-            }
-            break;
-
-        case LESSON_NUMERICAL :
-            // set defaults
-            $response = '';
-            $newpageid = 0;
-
-            if (isset($_POST['answer'])) {
-                $useranswer = (float) optional_param('answer', 0, PARAM_RAW);  // just doing default PARAM_RAW, not doing PARAM_INT because it could be a float
-            } else {
-                $noanswer = true;
-                break;
-            }
-            $studentanswer = $userresponse = $useranswer;
-            if (!$answers = $DB->get_records("lesson_answers", array("pageid" => $pageid), "id")) {
-                print_error("Continue: No answers found");
-            }
-            foreach ($answers as $answer) {
-                if (strpos($answer->answer, ':')) {
-                    // there's a pairs of values
-                    list($min, $max) = explode(':', $answer->answer);
-                    $minimum = (float) $min;
-                    $maximum = (float) $max;
-                } else {
-                    // there's only one value
-                    $minimum = (float) $answer->answer;
-                    $maximum = $minimum;
-                }
-                if (($useranswer >= $minimum) and ($useranswer <= $maximum)) {
-                    $newpageid = $answer->jumpto;
-                    $response = trim($answer->response);
-                    if (lesson_iscorrect($pageid, $newpageid)) {
-                        $correctanswer = true;
-                    }
-                    if ($lesson->custom) {
-                        if ($answer->score > 0) {
-                            $correctanswer = true;
-                        } else {
-                            $correctanswer = false;
-                        }
-                    }
-                    $answerid = $answer->id;
-                    break;
-                }
-            }
-            break;
-
-        case LESSON_BRANCHTABLE:
-            $noanswer = false;
-            $newpageid = optional_param('jumpto', NULL, PARAM_INT);
-            // going to insert into lesson_branch
-            if ($newpageid == LESSON_RANDOMBRANCH) {
-                $branchflag = 1;
-            } else {
-                $branchflag = 0;
-            }
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-            if ($grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid AND userid = :userid",
-                         $params, "grade DESC")) {
-                $retries = count($grades);
-            } else {
-                $retries = 0;
-            }
-            $branch = new stdClass;
-            $branch->lessonid = $lesson->id;
-            $branch->userid = $USER->id;
-            $branch->pageid = $pageid;
-            $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
-            if($newpageid == LESSON_UNSEENBRANCHPAGE) {
-                if (has_capability('mod/lesson:manage', $context)) {
-                     $newpageid = LESSON_NEXTPAGE;
-                } else {
-                     $newpageid = lesson_unseen_question_jump($lesson->id, $USER->id, $pageid);  // this may return 0
-                }
-            }
-            // convert jumpto page into a proper page id
-            if ($newpageid == 0) {
-                $newpageid = $pageid;
-            } elseif ($newpageid == LESSON_NEXTPAGE) {
-                if (!$newpageid = $page->nextpageid) {
-                    // no nextpage go to end of lesson
-                    $newpageid = LESSON_EOL;
-                }
-            } elseif ($newpageid == LESSON_PREVIOUSPAGE) {
-                $newpageid = $page->prevpageid;
-            } elseif ($newpageid == LESSON_RANDOMPAGE) {
-                $newpageid = lesson_random_question_jump($lesson->id, $pageid);
-            } elseif ($newpageid == LESSON_RANDOMBRANCH) {
-                $newpageid = lesson_unseen_branch_jump($lesson->id, $USER->id);
-            }
-            // no need to record anything in lesson_attempts
-            redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$newpageid");
-            break;
-
-    }
-
-    $attemptsremaining  = 0;
-    $maxattemptsreached = 0;
-    $nodefaultresponse  = false; // Flag for redirecting when default feedback is turned off
-
-    if ($noanswer) {
-        $newpageid = $pageid; // display same page again
-        $feedback  = get_string('noanswer', 'lesson');
-    } else {
-        $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-        if (!has_capability('mod/lesson:manage', $context)) {
-            // record student's attempt
-            $attempt = new stdClass;
-            $attempt->lessonid = $lesson->id;
-            $attempt->pageid = $pageid;
-            $attempt->userid = $USER->id;
-            $attempt->answerid = $answerid;
-            $attempt->retry = $nretakes;
-            $attempt->correct = $correctanswer;
-            if(isset($userresponse)) {
-                $attempt->useranswer = $userresponse;
-            }
-
-            $attempt->timeseen = time();
-            // if allow modattempts, then update the old attempt record, otherwise, insert new answer record
-            if (isset($USER->modattempts[$lesson->id])) {
-                $attempt->retry = $nretakes - 1; // they are going through on review, $nretakes will be too high
-            }
-            $newattemptid = $DB->insert_record("lesson_attempts", $attempt);
-            // "number of attempts remaining" message if $lesson->maxattempts > 1
-            // displaying of message(s) is at the end of page for more ergonomic display
-            if (!$correctanswer and ($newpageid == 0)) {
-                // wrong answer and student is stuck on this page - check how many attempts
-                // the student has had at this page/question
-                $nattempts = $DB->count_records("lesson_attempts", array("pageid"=>$pageid, "userid"=>$USER->id),
-                    "retry", $nretakes);
-
-                // retreive the number of attempts left counter for displaying at bottom of feedback page
-                if ($nattempts >= $lesson->maxattempts) {
-                    if ($lesson->maxattempts > 1) { // don't bother with message if only one attempt
-                        $maxattemptsreached = 1;
-                    }
-                    $newpageid = LESSON_NEXTPAGE;
-                } else if ($lesson->maxattempts > 1) { // don't bother with message if only one attempt
-                    $attemptsremaining = $lesson->maxattempts - $nattempts;
-                }
-            }
-        }
-        // TODO: merge this code with the jump code below.  Convert jumpto page into a proper page id
-        if ($newpageid == 0) {
-            $newpageid = $pageid;
-        } elseif ($newpageid == LESSON_NEXTPAGE) {
-            if ($lesson->nextpagedefault) {
-                // in Flash Card mode...
-                // ... first get the page ids (lessonid the 5th param is needed to make $DB->get_records play)
-                $allpages = $DB->get_records("lesson_pages", array("lessonid" => $lesson->id), "id", "id,lessonid,qtype");
-                shuffle ($allpages);
-                $found = false;
-                if ($lesson->nextpagedefault == LESSON_UNSEENPAGE) {
-                    foreach ($allpages as $thispage) {
-                        if (!$DB->count_records("lesson_attempts", array("pageid"=>$thispage->id, "userid"=>$USER->id, "retry"=>$nretakes))) {
-                            $found = true;
-                            break;
-                        }
-                    }
-                } elseif ($lesson->nextpagedefault == LESSON_UNANSWEREDPAGE) {
-                    foreach ($allpages as $thispage) {
-                        if ($thispage->qtype == LESSON_ESSAY) {
-                            if (!$DB->count_records("lesson_attempts", array('pageid'=>$thispage->id, 'userid'=>$USER->id, 'retry'=>$nretakes))) {
-                                $found = true;
-                                break;
-                            }
-                        } else {
-                            if (!$DB->count_records("lesson_attempts", array('pageid'=>$thispage->id, 'userid'=>$USER->id, 'correct'=>1, 'retry'=>$nretakes))) {
-                                $found = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-                if ($found) {
-                    $newpageid = $thispage->id;
-                    if ($lesson->maxpages) {
-                        // check number of pages viewed (in the lesson)
-                        if ($DB->count_records("lesson_attempts", array("lessonid"=>$lesson->id, "userid"=>$USER->id,
-                                "retry"=>$nretakes)) >= $lesson->maxpages) {
-                            $newpageid = LESSON_EOL;
-                        }
-                    }
-                } else {
-                    $newpageid = LESSON_EOL;
-                }
-            } elseif (!$newpageid = $page->nextpageid) {
-                // no nextpage go to end of lesson
-                $newpageid = LESSON_EOL;
-            }
-        }
-
-        // Determine default feedback if necessary
-        if (empty($response)) {
-            if (!$lesson->feedback and !$noanswer and !($lesson->review and !$correctanswer and !$isessayquestion)) {
-                // These conditions have been met:
-                //  1. The lesson manager has not supplied feedback to the student
-                //  2. Not displaying default feedback
-                //  3. The user did provide an answer
-                //  4. We are not reviewing with an incorrect answer (and not reviewing an essay question)
-
-                $nodefaultresponse = true;  // This will cause a redirect below
-            } else if ($isessayquestion) {
-                $response = get_string('defaultessayresponse', 'lesson');
-            } else if ($correctanswer) {
-                $response = get_string('thatsthecorrectanswer', 'lesson');
-            } else {
-                $response = get_string('thatsthewronganswer', 'lesson');
-            }
-        }
-
-        // display response (if there is one - there should be!)
-        // display: lesson title, page title, question text, student's answer(s) before feedback message
-
-        if ($response) {
-            //optionally display question page title
-            //if ($title = $DB->get_field("lesson_pages", "title", array("id" => $pageid))) {
-            //    print_heading($title);
-            //}
-            if ($lesson->review and !$correctanswer and !$isessayquestion) {
-                $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-                $qattempts = $DB->count_records("lesson_attempts", array("userid"=>$USER->id, "retry"=>$nretakes, "pageid"=>$pageid));
-                if ($qattempts == 1) {
-                    $feedback = get_string("firstwrong", "lesson");
-                } else {
-                    $feedback = get_string("secondpluswrong", "lesson");
-                }
-            } else {
-                if ($correctanswer) {
-                    $class = 'response correct'; //CSS over-ride this if they exist (!important)
-                } else if ($isessayquestion) {
-                    $class = 'response';
-                } else {
-                    $class = 'response incorrect';
-                }
-                $options = new stdClass;
-                $options->noclean = true;
-                $options->para = true;
-                $feedback = $OUTPUT->box(format_text($page->contents, FORMAT_MOODLE, $options), 'generalbox boxaligncenter');
-                $feedback .= '<em>'.get_string("youranswer", "lesson").'</em> : '.format_text($studentanswer, FORMAT_MOODLE, $options).
-                                 "<div class=\"$class\">".format_text($response, FORMAT_MOODLE, $options).'</div>';
-            }
-        }
-    }
-
-    // TODO: merge with the jump code above.  This is where some jump numbers are interpreted
-    if (isset($USER->modattempts[$lesson->id])) {
-        // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
-        if ($USER->modattempts[$lesson->id] == $pageid) {  // remember, this session variable holds the pageid of the last page that the user saw
-            $newpageid = LESSON_EOL;
-        } else {
-            $nretakes--; // make sure we are looking at the right try.
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $nretakes);
-            $attempts = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, "timeseen", "id, pageid");
-            $found = false;
-            $temppageid = 0;
-            foreach($attempts as $attempt) {
-                if ($found && $temppageid != $attempt->pageid) { // now try to find the next page, make sure next few attempts do no belong to current page
-                    $newpageid = $attempt->pageid;
-                    break;
-                }
-                if ($attempt->pageid == $pageid) {
-                    $found = true; // if found current page
-                    $temppageid = $attempt->pageid;
-                }
-            }
-        }
-    } elseif ($newpageid != LESSON_CLUSTERJUMP && $pageid != 0 && $newpageid > 0) {  // going to check to see if the page that the user is going to view next, is a cluster page.  If so, dont display, go into the cluster.  The $newpageid > 0 is used to filter out all of the negative code jumps.
-        if (!$page = $DB->get_record("lesson_pages", array("id" => $newpageid))) {
-            print_error("Error: could not find page");
-        }
-        if ($page->qtype == LESSON_CLUSTER) {
-            $newpageid = lesson_cluster_jump($lesson->id, $USER->id, $page->id);
-        } elseif ($page->qtype == LESSON_ENDOFCLUSTER) {
-            $jump = $DB->get_field("lesson_answers", "jumpto", array("pageid" => $page->id, "lessonid" => $lesson->id));
-            if ($jump == LESSON_NEXTPAGE) {
-                if ($page->nextpageid == 0) {
-                    $newpageid = LESSON_EOL;
-                } else {
-                    $newpageid = $page->nextpageid;
-                }
-            } else {
-                $newpageid = $jump;
-            }
-        }
-    } elseif ($newpageid == LESSON_UNSEENBRANCHPAGE) {
-        if (has_capability('mod/lesson:manage', $context)) {
-            if ($page->nextpageid == 0) {
-                $newpageid = LESSON_EOL;
-            } else {
-                $newpageid = $page->nextpageid;
-            }
-        } else {
-            $newpageid = lesson_unseen_question_jump($lesson->id, $USER->id, $pageid);
-        }
-    } elseif ($newpageid == LESSON_PREVIOUSPAGE) {
-        $newpageid = $page->prevpageid;
-    } elseif ($newpageid == LESSON_RANDOMPAGE) {
-        $newpageid = lesson_random_question_jump($lesson->id, $pageid);
-    } elseif ($newpageid == LESSON_CLUSTERJUMP) {
-        if (has_capability('mod/lesson:manage', $context)) {
-            if ($page->nextpageid == 0) {  // if teacher, go to next page
-                $newpageid = LESSON_EOL;
-            } else {
-                $newpageid = $page->nextpageid;
-            }
-        } else {
-            $newpageid = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
-        }
-    }
-
-    if ($nodefaultresponse) {
-        // Don't display feedback
-        redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$newpageid");
-    }
-
-/// Set Messages
-
-    // This is the warning msg for teachers to inform them that cluster and unseen does not work while logged in as a teacher
-    if(has_capability('mod/lesson:manage', $context) and lesson_display_teacher_warning($lesson->id)) {
-        $warningvars->cluster = get_string("clusterjump", "lesson");
-        $warningvars->unseen = get_string("unseenpageinbranch", "lesson");
-        lesson_set_message(get_string("teacherjumpwarning", "lesson", $warningvars));
-    }
-    // Inform teacher that s/he will not see the timer
-    if ($lesson->timed and has_capability('mod/lesson:manage', $context)) {
-        lesson_set_message(get_string("teachertimerwarning", "lesson"));
-    }
-    // Report attempts remaining
-    if ($attemptsremaining != 0) {
-        lesson_set_message(get_string('attemptsremaining', 'lesson', $attemptsremaining));
-    }
-    // Report if max attempts reached
-    if ($maxattemptsreached != 0) {
-        lesson_set_message('('.get_string("maximumnumberofattemptsreached", "lesson").')');
-    }
-
-    $PAGE->set_url('mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id));
-    $PAGE->set_subpage($page->id);
-
-/// Print the header, heading and tabs
-    lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
-    lesson_print_header($cm, $course, $lesson, 'view', true, $page->id);
-
-    include(dirname(__FILE__).'/continue.html');
-
diff --git a/mod/lesson/action/delete.php b/mod/lesson/action/delete.php
deleted file mode 100644 (file)
index 2ba5c4d..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/**
- * Action for deleting a page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    $pageid = required_param('pageid', PARAM_INT);
-    if (!$thispage = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error("Delete: page record not found");
-    }
-
-    // first delete all the associated records...
-    $DB->delete_records("lesson_attempts", array("pageid" => $pageid));
-    // ...now delete the answers...
-    $DB->delete_records("lesson_answers", array("pageid" => $pageid));
-    // ..and the page itself
-    $DB->delete_records("lesson_pages", array("id" => $pageid));
-
-    // repair the hole in the linkage
-    if (!$thispage->prevpageid AND !$thispage->nextpageid) {
-        //This is the only page, no repair needed
-    } elseif (!$thispage->prevpageid) {
-        // this is the first page...
-        if (!$page = $DB->get_record("lesson_pages", array("id" => $thispage->nextpageid))) {
-            print_error("Delete: next page not found");
-        }
-        if (!$DB->set_field("lesson_pages", "prevpageid", 0, array("id" => $page->id))) {
-            print_error("Delete: unable to set prevpage link");
-        }
-    } elseif (!$thispage->nextpageid) {
-        // this is the last page...
-        if (!$page = $DB->get_record("lesson_pages", array("id" => $thispage->prevpageid))) {
-            print_error("Delete: prev page not found");
-        }
-        if (!$DB->set_field("lesson_pages", "nextpageid", 0, array("id" => $page->id))) {
-            print_error("Delete: unable to set nextpage link");
-        }
-    } else {
-        // page is in the middle...
-        if (!$prevpage = $DB->get_record("lesson_pages", array("id" => $thispage->prevpageid))) {
-            print_error("Delete: prev page not found");
-        }
-        if (!$nextpage = $DB->get_record("lesson_pages", array("id" => $thispage->nextpageid))) {
-            print_error("Delete: next page not found");
-        }
-        if (!$DB->set_field("lesson_pages", "nextpageid", $nextpage->id, array("id" => $prevpage->id))) {
-            print_error("Delete: unable to set next link");
-        }
-        if (!$DB->set_field("lesson_pages", "prevpageid", $prevpage->id, array("id" => $nextpage->id))) {
-            print_error("Delete: unable to set prev link");
-        }
-    }
-    lesson_set_message(get_string('deletedpage', 'lesson').': '.format_string($thispage->title, true), 'notifysuccess');
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-
diff --git a/mod/lesson/action/editpage.php b/mod/lesson/action/editpage.php
deleted file mode 100644 (file)
index 36379e3..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-<?php
-/**
- *  Action for editing a page.  Prints an HTML form.
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-
-    // get the page
-    $pageid = required_param('pageid', PARAM_INT);
-    $redirect = optional_param('redirect', '', PARAM_ALPHA);
-
-    if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error('cannotfindpages', 'lesson');
-    }
-
-    $page->qtype = optional_param('qtype', $page->qtype, PARAM_INT);
-
-    // set of jump array
-    $jump = array();
-    $jump[0] = get_string("thispage", "lesson");
-    $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
-    $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
-    if(lesson_display_branch_jumps($lesson->id, $page->id)) {
-        $jump[LESSON_UNSEENBRANCHPAGE] = get_string("unseenpageinbranch", "lesson");
-        $jump[LESSON_RANDOMPAGE] = get_string("randompageinbranch", "lesson");
-    }
-    if ($page->qtype == LESSON_ENDOFBRANCH || $page->qtype == LESSON_BRANCHTABLE) {
-        $jump[LESSON_RANDOMBRANCH] = get_string("randombranch", "lesson");
-    }
-    if(lesson_display_cluster_jump($lesson->id, $page->id) && $page->qtype != LESSON_BRANCHTABLE && $page->qtype != LESSON_ENDOFCLUSTER) {
-        $jump[LESSON_CLUSTERJUMP] = get_string("clusterjump", "lesson");
-    }
-    $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
-    if (!$apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
-        print_error('cannotfindfirstpage', 'lesson');
-    }
-    while (true) {
-        if ($apageid) {
-            if (!$apage = $DB->get_record("lesson_pages", array("id" => $apageid))) {
-                print_error('cannotfindpages', 'lesson');
-            }
-            // removed != LESSON_ENDOFBRANCH...
-            if (trim($page->title)) { // ...nor nuffin pages
-                $jump[$apageid] = strip_tags(format_string($apage->title,true));
-            }
-            $apageid = $apage->nextpageid;
-        } else {
-            // last page reached
-            break;
-        }
-    }
-    // give teacher a proforma
-    ?>
-    <form id="editpage" method="post" action="lesson.php">
-    <fieldset class="invisiblefieldset fieldsetfix">
-    <input type="hidden" name="id" value="<?php echo $cm->id ?>" />
-    <input type="hidden" name="action" value="updatepage" />
-    <input type="hidden" name="pageid" value="<?php echo $pageid ?>" />
-    <input type="hidden" name="sesskey" value="<?php echo sesskey() ?>" />
-    <input type="hidden" name="redirect" value="<?php echo $redirect ?>" />
-    <input type="hidden" name="redisplay" value="0" />
-    <center>
-       <?php
-        switch ($page->qtype) {
-            case LESSON_MULTICHOICE :
-                echo '<b>'.get_string("questiontype", "lesson").":</b> \n";
-                echo $OUTPUT->help_icon(moodle_help_icon::make("questiontypes", get_string("questiontype", "lesson"), "lesson"))."<br />";
-                lesson_qtype_menu($LESSON_QUESTION_TYPE, $page->qtype,
-                                  "lesson.php?id=$cm->id&amp;action=editpage&amp;pageid=$page->id",
-                                  "getElementById('editpage').redisplay.value=1;getElementById('editpage').submit();");
-                echo "<p><b><label for=\"qoption\">".get_string('multianswer', 'lesson').":</label></b> \n";
-                if ($page->qoption) {
-                    echo "<input type=\"checkbox\" id=\"qoption\" name=\"qoption\" value=\"1\" checked=\"checked\" />";
-                } else {
-                    echo "<input type=\"checkbox\" id=\"qoption\" name=\"qoption\" value=\"1\" />";
-                }
-                echo $OUTPUT->help_icon(moodle_help_icon::make("questionoption", get_string("questionoption", "lesson"), "lesson"));
-                echo "</p>\n";
-                break;
-            case LESSON_SHORTANSWER :
-                echo '<b>'.get_string("questiontype", "lesson").":</b> \n";
-                echo $OUTPUT->help_icon(moodle_help_icon::make("questiontypes", get_string("questiontype", "lesson"), "lesson"))."<br />";
-                lesson_qtype_menu($LESSON_QUESTION_TYPE, $page->qtype,
-                                  "lesson.php?id=$cm->id&amp;action=editpage&amp;pageid=$page->id",
-                                  "getElementById('editpage').redisplay.value=1;getElementById('editpage').submit();");
-                echo "<p><b><label for=\"qoption\">".get_string('casesensitive', 'lesson').":</label></b> \n";
-                if ($page->qoption) {
-                    echo "<input type=\"checkbox\" id=\"qoption\" name=\"qoption\" value=\"1\" checked=\"checked\" />";
-                } else {
-                    echo "<input type=\"checkbox\" id=\"qoption\" name=\"qoption\" value=\"1\" />";
-                }
-                echo $OUTPUT->help_icon(moodle_help_icon::make("questionoption", get_string("questionoption", "lesson"), "lesson"));
-                echo "</p>\n";
-                break;
-            case LESSON_TRUEFALSE :
-            case LESSON_ESSAY :
-            case LESSON_MATCHING :
-            case LESSON_NUMERICAL :
-                echo '<b>'.get_string("questiontype", "lesson").":</b> \n";
-                echo $OUTPUT->help_icon(moodle_help_icon::make("questiontypes", get_string("questiontype", "lesson"), "lesson"))."<br />";
-                lesson_qtype_menu($LESSON_QUESTION_TYPE, $page->qtype,
-                                  "lesson.php?id=$cm->id&amp;action=editpage&amp;pageid=$page->id",
-                                  "getElementById('editpage').redisplay.value=1;getElementById('editpage').submit();");
-                break;
-        }
-    ?>
-    <table cellpadding="5" class="generalbox" border="1">
-    <tr valign="top">
-    <td><b><label for="title"><?php print_string('pagetitle', 'lesson'); ?>:</label></b><br />
-    <input type="text" id="title" name="title" size="80" maxsize="255" value="<?php p($page->title) ?>" /></td>
-    </tr>
-    <?PHP
-    echo "<tr><td><b>";
-    echo get_string("pagecontents", "lesson").":</b><br />\n";
-    print_textarea($usehtmleditor, 25, 70, 630, 400, "contents", $page->contents);
-    echo "</td></tr>\n";
-    $n = 0;
-    switch ($page->qtype) {
-        case LESSON_BRANCHTABLE :
-            echo "<input type=\"hidden\" name=\"qtype\" value=\"$page->qtype\" />\n";
-            echo "<tr><td>\n";
-            echo "<center>";
-            if ($page->layout) {
-                echo "<input checked=\"checked\" name=\"layout\" type=\"checkbox\" value=\"1\" />";
-            } else {
-                echo "<input name=\"layout\" type=\"checkbox\" value=\"1\" />";
-            }
-            echo get_string("arrangebuttonshorizontally", "lesson")."\n";
-            echo "<br />";
-            if ($page->display) {
-                echo "<input name=\"display\" type=\"checkbox\" value=\"1\" checked=\"checked\" />";
-            } else {
-                echo "<input name=\"display\" type=\"checkbox\" value=\"1\" />";
-            }
-            echo get_string("displayinleftmenu", "lesson")."\n";
-            echo "</center></td></tr>\n";
-            echo "<tr><td><b>".get_string("branchtable", "lesson")."</b> \n";
-            break;
-        case LESSON_CLUSTER :
-            echo "<input type=\"hidden\" name=\"qtype\" value=\"$page->qtype\" />\n";
-            echo "<tr><td><b>".get_string("clustertitle", "lesson")."</b> \n";
-            break;
-        case LESSON_ENDOFCLUSTER :
-            echo "<input type=\"hidden\" name=\"qtype\" value=\"$page->qtype\" />\n";
-            echo "<tr><td><b>".get_string("endofclustertitle", "lesson")."</b> \n";
-            break;
-        case LESSON_ENDOFBRANCH :
-            echo "<input type=\"hidden\" name=\"qtype\" value=\"$page->qtype\" />\n";
-            echo "<tr><td><b>".get_string("endofbranch", "lesson")."</b> \n";
-            break;
-        default :
-            echo "<tr><td>";
-        break;
-    }
-
-    echo "</td></tr>\n";
-    // get the answers in a set order, the id order
-
-    if ($answers = $DB->get_records("lesson_answers", array("pageid" => $page->id), "id")) {
-        foreach ($answers as $answer) {
-            $flags = intval($answer->flags); // force into an integer
-            $nplus1 = $n + 1;
-            echo "<input type=\"hidden\" name=\"answerid[$n]\" value=\"$answer->id\" />\n";
-            switch ($page->qtype) {
-                case LESSON_MATCHING:
-                    if ($n == 0) {
-                        echo "<tr><td><b><label for=\"edit-answer[$n]\">".get_string('correctresponse', 'lesson').":</label></b>\n";
-                        if ($flags & LESSON_ANSWER_EDITOR) {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" checked=\"checked\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer);
-                        } else {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea(false, 6, 70, 630, 300, "answer[$n]", $answer->answer);
-                        }
-                    } elseif ($n == 1) {
-                        echo "<tr><td><b><label for=\"edit-answer[$n]\">".get_string('wrongresponse', 'lesson').":</label></b>\n";
-                        if ($flags & LESSON_ANSWER_EDITOR) {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" checked=\"checked\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer);
-                        } else {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea(false, 6, 70, 630, 300, "answer[$n]", $answer->answer);
-                        }
-                    } else {
-                        $ncorrected = $n - 1;
-                        echo "<tr><td><b><label for=\"edit-answer[$n]\">".get_string('answer', 'lesson')." $ncorrected:</label></b>\n";
-                        if ($flags & LESSON_ANSWER_EDITOR) {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" checked=\"checked\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer);
-                        } else {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea(false, 6, 70, 630, 300, "answer[$n]", $answer->answer);
-                        }
-                        echo "</td></tr>\n";
-                        echo "<tr><td><b><label for=\"edit-response[$n]\">".get_string('matchesanswer', 'lesson')." $ncorrected:</label></b>\n";
-                        if ($flags & LESSON_RESPONSE_EDITOR) {
-                            echo " [<label for=\"responseeditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"responseeditor[$n]\" name=\"responseeditor[$n]\" value=\"1\" checked=\"checked\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea($usehtmleditor, 20, 70, 630, 300, "response[$n]", $answer->response);
-                        } else {
-                            echo " [<label for=\"responseeditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"responseeditor[$n]\" name=\"responseeditor[$n]\" value=\"1\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea(false, 6, 70, 630, 300, "response[$n]", $answer->response);
-                        }
-                    }
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_TRUEFALSE:
-                case LESSON_MULTICHOICE:
-                case LESSON_SHORTANSWER:
-                case LESSON_NUMERICAL:
-                    echo "<tr><td><b><label for=\"edit-answer[$n]\">".get_string('answer', 'lesson')." $nplus1:</label></b>\n";
-                    if ($flags & LESSON_ANSWER_EDITOR and $page->qtype != LESSON_SHORTANSWER and $page->qtype != LESSON_NUMERICAL) {
-                        echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                            "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" checked=\"checked\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer);
-                    } else {
-                        if ($page->qtype != LESSON_SHORTANSWER and $page->qtype != LESSON_NUMERICAL) {
-                            echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                                "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" />";
-                            echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                            echo "]<br />\n";
-                            print_textarea(false, 6, 70, 630, 300, "answer[$n]", $answer->answer);
-                        } else {
-                            echo "<br />\n";
-                            print_textarea(false, 1, 70, 630, 300, "answer[$n]", $answer->answer);
-                        }
-                    }
-                    echo "</td></tr>\n";
-                    echo "<tr><td><b><label for=\"edit-response[$n]\">".get_string('response', 'lesson')." $nplus1:</label></b>\n";
-                    if ($flags & LESSON_RESPONSE_EDITOR) {
-                        echo " [<label for=\"responseeditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                            "<input type=\"checkbox\" id=\"responseeditor[$n]\" name=\"responseeditor[$n]\" value=\"1\" checked=\"checked\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea($usehtmleditor, 20, 70, 630, 300, "response[$n]", $answer->response);
-                    } else {
-                        echo " [<label for=\"responseeditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                            "<input type=\"checkbox\" id=\"responseeditor[$n]\" name=\"responseeditor[$n]\" value=\"1\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea(false, 6, 70, 630, 300, "response[$n]", $answer->response);
-                    }
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_BRANCHTABLE:
-                    echo "<tr><td><b><label for=\"edit-answer[$n]\">".get_string("description", "lesson")." $nplus1:</label></b>\n";
-                    if ($flags & LESSON_ANSWER_EDITOR) {
-                        echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                            "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" checked=\"checked\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea($usehtmleditor, 20, 70, 630, 300, "answer[$n]", $answer->answer);
-                    } else {
-                        echo " [<label for=\"answereditor[$n]\">".get_string("useeditor", "lesson")."</label>: ".
-                            "<input type=\"checkbox\" id=\"answereditor[$n]\" name=\"answereditor[$n]\" value=\"1\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea(false, 10, 70, 630, 300, "answer[$n]", $answer->answer);
-                    }
-                    echo "</td></tr>\n";
-                    break;
-            }
-            switch ($page->qtype) {
-                case LESSON_MATCHING :
-                    if ($n == 2) {
-                        echo "<tr><td><b>".get_string("correctanswerjump", "lesson").":</b> \n";
-                        echo $OUTPUT->select(html_select::make($jump, "jumpto[$n]", $answer->jumpto, false));
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                        if($lesson->custom)
-                            echo get_string("correctanswerscore", "lesson").": <input type=\"text\" name=\"score[$n]\" value=\"$answer->score\" size=\"5\" />";
-                        echo "</td></tr>\n";
-                    }
-                    if ($n == 3) {
-                        echo "<tr><td><b>".get_string("wronganswerjump", "lesson").":</b> \n";
-                        echo $OUTPUT->select(html_select::make($jump, "jumpto[$n]", $answer->jumpto, false));
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                        if($lesson->custom)
-                            echo get_string("wronganswerscore", "lesson").": <input type=\"text\" name=\"score[$n]\" value=\"$answer->score\" size=\"5\" />";
-                        echo "</td></tr>\n";
-                    }
-                    //echo "</td></tr>\n";
-                    break;
-                case LESSON_ESSAY :
-                    echo "<tr><td><b>".get_string("jump", "lesson").":</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$n]", $answer->jumpto, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    if($lesson->custom) {
-                        echo get_string("score", "lesson").": <input type=\"text\" name=\"score[$n]\" value=\"$answer->score\" size=\"5\" />";
-                    }
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_TRUEFALSE:
-                case LESSON_MULTICHOICE:
-                case LESSON_SHORTANSWER:
-                case LESSON_NUMERICAL:
-                    echo "<tr><td><b>".get_string("jump", "lesson")." $nplus1:</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$n]", $answer->jumpto, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    if($lesson->custom) {
-                        echo get_string("score", "lesson")." $nplus1: <input type=\"text\" name=\"score[$n]\" value=\"$answer->score\" size=\"5\" />";
-                    }
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_BRANCHTABLE:
-                case LESSON_CLUSTER:
-                case LESSON_ENDOFCLUSTER:
-                case LESSON_ENDOFBRANCH:
-                    echo "<tr><td><b>".get_string("jump", "lesson")." $nplus1:</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$n]", $answer->jumpto, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    echo "</td></tr>\n";
-                    break;
-            }
-            $n++;
-            if ($page->qtype == LESSON_ESSAY) {
-                break; // only one answer for essays
-            }
-        }
-    }
-    if ($page->qtype != LESSON_ENDOFBRANCH && $page->qtype != LESSON_CLUSTER && $page->qtype != LESSON_ENDOFCLUSTER) {
-        if ($page->qtype == LESSON_MATCHING) {
-            $maxanswers = $lesson->maxanswers + 2;
-        } else {
-            $maxanswers = $lesson->maxanswers;
-        }
-        for ($i = $n; $i < $maxanswers; $i++) {
-            if ($page->qtype == LESSON_TRUEFALSE && $i > 1) {
-                break; // stop printing answers... only need two for true/false
-            }
-            $iplus1 = $i + 1;
-            echo "<input type=\"hidden\" name=\"answerid[$i]\" value=\"0\" />\n";
-            switch ($page->qtype) {
-                case LESSON_MATCHING:
-                    $icorrected = $i - 1;
-                    echo "<tr><td><b>".get_string("answer", "lesson")." $icorrected:</b>\n";
-                    echo " [".get_string("useeditor", "lesson").": ".
-                        "<input type=\"checkbox\" name=\"answereditor[$i]\" value=\"1\" />";
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                    echo "]<br />\n";
-                    print_textarea(false, 10, 70, 630, 300, "answer[$i]");
-                    echo "</td></tr>\n";
-                    echo "<tr><td><b>".get_string("matchesanswer", "lesson")." $icorrected:</b>\n";
-                    echo " [".get_string("useeditor", "lesson").": ".
-                        "<input type=\"checkbox\" name=\"responseeditor[$i]\" value=\"1\" />";
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                    echo "]<br />\n";
-                    print_textarea(false, 10, 70, 630, 300, "response[$i]");
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_TRUEFALSE:
-                case LESSON_MULTICHOICE:
-                case LESSON_SHORTANSWER:
-                case LESSON_NUMERICAL:
-                    echo "<tr><td><b>".get_string("answer", "lesson")." $iplus1:</b>\n";
-                    if ($page->qtype != LESSON_SHORTANSWER and $page->qtype != LESSON_NUMERICAL) {
-                        echo " [".get_string("useeditor", "lesson").": ".
-                            "<input type=\"checkbox\" name=\"answereditor[$i]\" value=\"1\" />";
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                        echo "]<br />\n";
-                        print_textarea(false, 10, 70, 630, 300, "answer[$i]");
-                    } else {
-                        echo "<br />\n";
-                        print_textarea(false, 1, 70, 630, 300, "answer[$i]");
-                    }
-                    echo "</td></tr>\n";
-                    echo "<tr><td><b>".get_string("response", "lesson")." $iplus1:</b>\n";
-                    echo " [".get_string("useeditor", "lesson").": ".
-                        "<input type=\"checkbox\" name=\"responseeditor[$i]\" value=\"1\" />";
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                    echo "]<br />\n";
-                    print_textarea(false, 10, 70, 630, 300, "response[$i]");
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_BRANCHTABLE:
-                    echo "<tr><td><b>".get_string("description", "lesson")." $iplus1:</b>\n";
-                    echo " [".get_string("useeditor", "lesson").": ".
-                        "<input type=\"checkbox\" name=\"answereditor[$i]\" value=\"1\" />";
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("useeditor", get_string("useeditor", "lesson"), "lesson"));
-                    echo "]<br />\n";
-                    print_textarea(false, 10, 70, 630, 300, "answer[$i]");
-                    echo "</td></tr>\n";
-                    break;
-            }
-            switch ($page->qtype) {
-                case LESSON_ESSAY :
-                    if ($i < 1) {
-                        echo "<tr><td><b>".get_string("jump", "lesson").":</b> \n";
-                        echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                        if($lesson->custom) {
-                            echo get_string("score", "lesson").": <input type=\"text\" name=\"score[$i]\" value=\"1\" size=\"5\" />";
-                        }
-                        echo "</td></tr>\n";
-                    }
-                    break;
-                case LESSON_MATCHING :
-                    if ($i == 2) {
-                        echo "<tr><td><b>".get_string("correctanswerjump", "lesson").":</b> \n";
-                        echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", $answer->jumpto, false));
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                        if ($lesson->custom) {
-                            echo get_string("correctanswerscore", "lesson").": <input type=\"text\" name=\"score[$i]\" value=\"$answer->score\" size=\"5\" />";
-                        }
-                        echo "</td></tr>\n";
-                    }
-                    if ($i == 3) {
-                        echo "<tr><td><b>".get_string("wronganswerjump", "lesson").":</b> \n";
-                        echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", $answer->jumpto, false));
-                        echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                        if ($lesson->custom) {
-                            echo get_string("wronganswerscore", "lesson").": <input type=\"text\" name=\"score[$i]\" value=\"$answer->score\" size=\"5\" />";
-                        }
-                        echo "</td></tr>\n";
-                    }
-
-                    break;
-                case LESSON_TRUEFALSE:
-                case LESSON_MULTICHOICE:
-                case LESSON_SHORTANSWER:
-                case LESSON_NUMERICAL:
-                    echo "<tr><td><b>".get_string("jump", "lesson")." $iplus1:</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    if($lesson->custom) {
-                        echo get_string("score", "lesson")." $iplus1: <input type=\"text\" name=\"score[$i]\" value=\"0\" size=\"5\" />";
-                    }
-                    echo "</td></tr>\n";
-                    break;
-                case LESSON_BRANCHTABLE :
-                    echo "<tr><td><b>".get_string("jump", "lesson")." $iplus1:</b> \n";
-                    echo $OUTPUT->select(html_select::make($jump, "jumpto[$i]", 0, false));
-                    echo $OUTPUT->help_icon(moodle_help_icon::make("jumpto", get_string("jump", "lesson"), "lesson"));
-                    echo "</td></tr>\n";
-                    break;
-            }
-        }
-    }
-    // close table and form
-    ?>
-    </table><br />
-    <input type="button" value="<?php print_string("redisplaypage", "lesson") ?>"
-        onclick="getElementById('editpage').redisplay.value=1;getElementById('editpage').submit();" />
-    <input type="submit" value="<?php  print_string("savepage", "lesson") ?>" />
-    <input type="submit" name="cancel" value="<?php  print_string("cancel") ?>" />
-    </center>
-    </fieldset>
-    </form>
diff --git a/mod/lesson/action/insertpage.php b/mod/lesson/action/insertpage.php
deleted file mode 100644 (file)
index 6fa694e..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-/**
- * Action for processing the form from addpage action and inserts the page.
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    // check to see if the cancel button was pushed
-    if (optional_param('cancel', '', PARAM_ALPHA)) {
-        redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-    }
-
-    $timenow = time();
-
-    $form = data_submitted();
-    $newpage = new stdClass;
-    $newanswer = new stdClass;
-    if ($form->pageid) {
-        // the new page is not the first page
-        if (!$page = $DB->get_record("lesson_pages", array("id" => $form->pageid))) {
-            print_error('cannotfindpages', 'lesson');
-        }
-        $newpage->lessonid = clean_param($lesson->id, PARAM_INT);
-        $newpage->prevpageid = clean_param($form->pageid, PARAM_INT);
-        $newpage->nextpageid = clean_param($page->nextpageid, PARAM_INT);
-        $newpage->timecreated = $timenow;
-        $newpage->qtype = $form->qtype;
-        if (isset($form->qoption)) {
-            $newpage->qoption = clean_param($form->qoption, PARAM_INT);
-        } else {
-            $newpage->qoption = 0;
-        }
-        if (isset($form->layout)) {
-            $newpage->layout = clean_param($form->layout, PARAM_INT);
-        } else {
-            $newpage->layout = 0;
-        }
-        if (isset($form->display)) {
-            $newpage->display = clean_param($form->display, PARAM_INT);
-        } else {
-            $newpage->display = 0;
-        }
-        $newpage->title = clean_param($form->title, PARAM_CLEANHTML);
-        $newpage->contents = trim($form->contents);
-        $newpage->title = $newpage->title;
-        $newpageid = $DB->insert_record("lesson_pages", $newpage);
-        // update the linked list (point the previous page to this new one)
-        $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $newpage->prevpageid));
-        if ($page->nextpageid) {
-            // new page is not the last page
-            $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
-        }
-    } else {
-        // new page is the first page
-        // get the existing (first) page (if any)
-        $params = array ("lessonid" => $lesson->id, "prevpageid" => 0);
-        if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
-            // there are no existing pages
-            $newpage->lessonid = $lesson->id;
-            $newpage->prevpageid = 0; // this is a first page
-            $newpage->nextpageid = 0; // this is the only page
-            $newpage->timecreated = $timenow;
-            $newpage->qtype = clean_param($form->qtype, PARAM_INT);
-            if (isset($form->qoption)) {
-                $newpage->qoption = clean_param($form->qoption, PARAM_INT);
-            } else {
-                $newpage->qoption = 0;
-            }
-            if (isset($form->layout)) {
-                $newpage->layout = clean_param($form->layout, PARAM_INT);
-            } else {
-                $newpage->layout = 0;
-            }
-            if (isset($form->display)) {
-                $newpage->display = clean_param($form->display, PARAM_INT);
-            } else {
-                $newpage->display = 0;
-            }
-            $newpage->title = clean_param($form->title, PARAM_CLEANHTML);
-            $newpage->contents = trim($form->contents);
-            $newpage->title = $newpage->title;
-            $newpageid = $DB->insert_record("lesson_pages", $newpage);
-        } else {
-            // there are existing pages put this at the start
-            $newpage->lessonid = $lesson->id;
-            $newpage->prevpageid = 0; // this is a first page
-            $newpage->nextpageid = $page->id;
-            $newpage->timecreated = $timenow;
-            $newpage->qtype = clean_param($form->qtype, PARAM_INT);
-            if (isset($form->qoption)) {
-                $newpage->qoption = clean_param($form->qoption, PARAM_INT);
-            } else {
-                $newpage->qoption = 0;
-            }
-            if (isset($form->layout)) {
-                $newpage->layout = clean_param($form->layout, PARAM_INT);
-            } else {
-                $newpage->layout = 0;
-            }
-            if (isset($form->display)) {
-                $newpage->display = clean_param($form->display, PARAM_INT);
-            } else {
-                $newpage->display = 0;
-            }
-            $newpage->title = clean_param($form->title, PARAM_CLEANHTML);
-            $newpage->contents = trim($form->contents);
-            $newpage->title = $newpage->title;
-            $newpageid = $DB->insert_record("lesson_pages", $newpage);
-            // update the linked list
-            $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $newpage->nextpageid));
-        }
-    }
-    // now add the answers
-    if ($form->qtype == LESSON_ESSAY) {
-        $newanswer->lessonid = $lesson->id;
-        $newanswer->pageid = $newpageid;
-        $newanswer->timecreated = $timenow;
-        if (isset($form->jumpto[0])) {
-            $newanswer->jumpto = clean_param($form->jumpto[0], PARAM_INT);
-        }
-        if (isset($form->score[0])) {
-            $newanswer->score = clean_param($form->score[0], PARAM_INT);
-        }
-        $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-    } else {
-        if ($form->qtype == LESSON_MATCHING) {
-            // need to add two to offset correct response and wrong response
-            $lesson->maxanswers = $lesson->maxanswers + 2;
-        }
-        for ($i = 0; $i < $lesson->maxanswers; $i++) {
-            if (!empty($form->answer[$i]) and trim(strip_tags($form->answer[$i]))) { // strip_tags because the HTML editor adds <p><br />...
-                $newanswer->lessonid = $lesson->id;
-                $newanswer->pageid = $newpageid;
-                $newanswer->timecreated = $timenow;
-                $newanswer->answer = trim($form->answer[$i]);
-                if (isset($form->response[$i])) {
-                    $newanswer->response = trim($form->response[$i]);
-                }
-                if (isset($form->jumpto[$i])) {
-                    $newanswer->jumpto = clean_param($form->jumpto[$i], PARAM_INT);
-                }
-                if ($lesson->custom) {
-                    if (isset($form->score[$i])) {
-                        $newanswer->score = clean_param($form->score[$i], PARAM_INT);
-                    }
-                }
-                $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-            } else {
-                if ($form->qtype == LESSON_MATCHING) {
-                    if ($i < 2) {
-                        $newanswer->lessonid = $lesson->id;
-                        $newanswer->pageid = $newpageid;
-                        $newanswer->timecreated = $timenow;
-                        $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-                    }
-                } else {
-                    break;
-                }
-            }
-        }
-    }
-
-    lesson_set_message(get_string('insertedpage', 'lesson').': '.format_string($newpage->title, true), 'notifysuccess');
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-
diff --git a/mod/lesson/action/move.php b/mod/lesson/action/move.php
deleted file mode 100644 (file)
index d90100e..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-/**
- * Action that displays an interface for moving a page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-
-    $pageid = required_param('pageid', PARAM_INT);
-    $title = $DB->get_field("lesson_pages", "title", array("id" => $pageid));
-    echo $OUTPUT->heading(get_string("moving", "lesson", format_string($title)));
-
-    $params = array ("lessonid" => $lesson->id, "prevpageid" => 0);
-    if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
-        print_error('cannotfindfirstpage', 'lesson');
-    }
-
-    echo "<center><table cellpadding=\"5\" border=\"1\">\n";
-    echo "<tr><td><a href=\"lesson.php?id=$cm->id&amp;sesskey=".sesskey()."&amp;action=moveit&amp;pageid=$pageid&amp;after=0\"><small>".
-        get_string("movepagehere", "lesson")."</small></a></td></tr>\n";
-    while (true) {
-        if ($page->id != $pageid) {
-            if (!$title = trim(format_string($page->title))) {
-                $title = "<< ".get_string("notitle", "lesson")."  >>";
-            }
-            echo "<tr><td><b>$title</b></td></tr>\n";
-            echo "<tr><td><a href=\"lesson.php?id=$cm->id&amp;sesskey=".sesskey()."&amp;action=moveit&amp;pageid=$pageid&amp;after={$page->id}\"><small>".
-                get_string("movepagehere", "lesson")."</small></a></td></tr>\n";
-        }
-        if ($page->nextpageid) {
-            if (!$page = $DB->get_record("lesson_pages", array("id" => $page->nextpageid))) {
-                print_error('cannotfindnextpage', 'lesson');
-            }
-        } else {
-            // last page reached
-            break;
-        }
-    }
-    echo "</table>\n";
-
diff --git a/mod/lesson/action/moveit.php b/mod/lesson/action/moveit.php
deleted file mode 100644 (file)
index 1c81fe7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/**
- * Action for actually moving the page (database changes)
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    $pageid = required_param('pageid', PARAM_INT); //  page to move
-    if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
-        print_error("Moveit: page not found");
-    }
-    $after = required_param('after', PARAM_INT); // target page
-
-    // first step. determine the new first page
-    // (this is done first as the current first page will be lost in the next step)
-    if (!$after) {
-        // the moved page is the new first page
-        $newfirstpageid = $pageid;
-        // reset $after so that is points to the last page
-        // (when the pages are in a ring this will in effect be the first page)
-        if ($page->nextpageid) {
-            if (!$after = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "nextpageid" => 0))) {
-                print_error("Moveit: last page id not found");
-            }
-        } else {
-            // the page being moved is the last page, so the new last page will be
-            $after = $page->prevpageid;
-        }
-    } elseif (!$page->prevpageid) {
-        // the page to be moved was the first page, so the following page must be the new first page
-        $newfirstpageid = $page->nextpageid;
-    } else {
-        // the current first page remains the first page
-        if (!$newfirstpageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
-            print_error("Moveit: current first page id not found");
-        }
-    }
-    // the rest is all unconditional...
-
-    // second step. join pages into a ring
-    if (!$firstpageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
-        print_error("Moveit: firstpageid not found");
-    }
-    if (!$lastpageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "nextpageid" => 0))) {
-        print_error("Moveit: lastpage not found");
-    }
-    if (!$DB->set_field("lesson_pages", "prevpageid", $lastpageid, array("id" => $firstpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-    if (!$DB->set_field("lesson_pages", "nextpageid", $firstpageid, array("id" => $lastpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-
-    // third step. remove the page to be moved
-    if (!$prevpageid = $DB->get_field("lesson_pages", "prevpageid", array("id" => $pageid))) {
-        print_error("Moveit: prevpageid not found");
-    }
-    if (!$nextpageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $pageid))) {
-        print_error("Moveit: nextpageid not found");
-    }
-    if (!$DB->set_field("lesson_pages", "nextpageid", $nextpageid, array("id" => $prevpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-    if (!$DB->set_field("lesson_pages", "prevpageid", $prevpageid, array("id" => $nextpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-
-    // fourth step. insert page to be moved in new place...
-    if (!$nextpageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $after))) {
-        print_error("Movit: nextpageid not found");
-    }
-    if (!$DB->set_field("lesson_pages", "nextpageid", $pageid, array("id" => $after))) {
-        print_error("Moveit: unable to update link");
-    }
-    if (!$DB->set_field("lesson_pages", "prevpageid", $pageid, array("id" => $nextpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-    // ...and set the links in the moved page
-    if (!$DB->set_field("lesson_pages", "prevpageid", $after, array("id" => $pageid))) {
-        print_error("Moveit: unable to update link");
-    }
-    if (!$DB->set_field("lesson_pages", "nextpageid", $nextpageid, array("id" => $pageid))) {
-        print_error("Moveit: unable to update link");
-    }
-
-    // fifth step. break the ring
-    if (!$newlastpageid = $DB->get_field("lesson_pages", "prevpageid", array("id" => $newfirstpageid))) {
-        print_error("Moveit: newlastpageid not found");
-    }
-    if (!$DB->set_field("lesson_pages", "prevpageid", 0, array("id" => $newfirstpageid))) {
-        print_error("Moveit: unable to update link");
-    }
-    if (!$DB->set_field("lesson_pages", "nextpageid", 0, array("id" => $newlastpageid))) {
-            print_error("Moveit: unable to update link");
-    }
-    lesson_set_message(get_string('movedpage', 'lesson'), 'notifysuccess');
-    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-
diff --git a/mod/lesson/action/updatepage.php b/mod/lesson/action/updatepage.php
deleted file mode 100644 (file)
index 55780bb..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-/**
- * Action for processing the form in editpage action and saves the page
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
- **/
-    require_sesskey();
-
-    $redirect = optional_param('redirect', '', PARAM_ALPHA);
-
-    $timenow = time();
-    $form = data_submitted();
-
-    $page = new stdClass;
-    $page->id = clean_param($form->pageid, PARAM_INT);
-
-    // check to see if the cancel button was pushed
-    if (optional_param('cancel', '', PARAM_ALPHA)) {
-        if ($redirect == 'navigation') {
-            // redirect to viewing the page
-            redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$page->id");
-        } else {
-            redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-        }
-    }
-
-    $page->timemodified = $timenow;
-    $page->qtype = clean_param($form->qtype, PARAM_INT);
-    if (isset($form->qoption)) {
-        $page->qoption = clean_param($form->qoption, PARAM_INT);
-    } else {
-        $page->qoption = 0;
-    }
-    if (isset($form->layout)) {
-        $page->layout = clean_param($form->layout, PARAM_INT);
-    } else {
-        $page->layout = 0;
-    }
-    if (isset($form->display)) {
-        $page->display = clean_param($form->display, PARAM_INT);
-    } else {
-        $page->display = 0;
-    }
-    $page->title = clean_param($form->title, PARAM_CLEANHTML);
-    $page->contents = trim($form->contents);
-    $page->title = $page->title;
-
-    $DB->update_record("lesson_pages", $page);
-    if ($page->qtype == LESSON_ENDOFBRANCH || $page->qtype == LESSON_ESSAY || $page->qtype == LESSON_CLUSTER || $page->qtype == LESSON_ENDOFCLUSTER) {
-        // there's just a single answer with a jump
-        $oldanswer = new stdClass;
-        $oldanswer->id = $form->answerid[0];
-        $oldanswer->timemodified = $timenow;
-        $oldanswer->jumpto = clean_param($form->jumpto[0], PARAM_INT);
-        if (isset($form->score[0])) {
-            $oldanswer->score = clean_param($form->score[0], PARAM_INT);
-        }
-        // delete other answers  this if mainly for essay questions.  If one switches from using a qtype like Multichoice,
-        // then switches to essay, the old answers need to be removed because essay is
-        // supposed to only have one answer record
-        $params = array ("pageid" => $page->id);
-        if ($answers = $DB->get_records_select("lesson_answers", "pageid = :pageid", $params)) {
-            foreach ($answers as $answer) {
-                if ($answer->id != clean_param($form->answerid[0], PARAM_INT)) {
-                    $DB->delete_records("lesson_answers", array("id" => $answer->id));
-                }
-            }
-        }
-        $DB->update_record("lesson_answers", $oldanswer);
-    } else {
-        // it's an "ordinary" page
-        if ($page->qtype == LESSON_MATCHING) {
-            // need to add two to offset correct response and wrong response
-            $lesson->maxanswers = $lesson->maxanswers + 2;
-        }
-        for ($i = 0; $i < $lesson->maxanswers; $i++) {
-            // strip tags because the editor gives <p><br />...
-            // also save any answers where the editor is (going to be) used
-            if ((isset($form->answer[$i]) and (trim(strip_tags($form->answer[$i]))) != '') or isset($form->answereditor[$i]) or isset($form->responseeditor[$i])) {
-                if ($form->answerid[$i]) {
-                    $oldanswer = new stdClass;
-                    $oldanswer->id = clean_param($form->answerid[$i], PARAM_INT);
-                    if (!isset($form->answereditor[$i])) {
-                        $form->answereditor[$i] = 0;
-                    }
-                    if (!isset($form->responseeditor[$i])) {
-                        $form->responseeditor[$i] = 0;
-                    }
-                    $oldanswer->flags = $form->answereditor[$i] * LESSON_ANSWER_EDITOR +
-                                        $form->responseeditor[$i] * LESSON_RESPONSE_EDITOR;
-                    $oldanswer->timemodified = $timenow;
-                    $oldanswer->answer = trim($form->answer[$i]);
-                    if (isset($form->response[$i])) {
-                        $oldanswer->response = trim($form->response[$i]);
-                    } else {
-                        $oldanswer->response = '';
-                    }
-                    $oldanswer->jumpto = clean_param($form->jumpto[$i], PARAM_INT);
-                    if (isset($form->score[$i])) {
-                        $oldanswer->score = clean_param($form->score[$i], PARAM_INT);
-                    }
-                    $DB->update_record("lesson_answers", $oldanswer);
-                } else {
-                    // it's a new answer
-                    $newanswer = new stdClass; // need to clear id if more than one new answer is ben added
-                    $newanswer->lessonid = $lesson->id;
-                    $newanswer->pageid = $page->id;
-                    if (!isset($form->answereditor[$i])) {
-                        $form->answereditor[$i] = 0;
-                    }
-                    if (!isset($form->responseeditor[$i])) {
-                        $form->responseeditor[$i] = 0;
-                    }
-                    $newanswer->flags = $form->answereditor[$i] * LESSON_ANSWER_EDITOR +
-                                        $form->responseeditor[$i] * LESSON_RESPONSE_EDITOR;
-                    $newanswer->timecreated = $timenow;
-                    $newanswer->answer = trim($form->answer[$i]);
-                    if (isset($form->response[$i])) {
-                        $newanswer->response = trim($form->response[$i]);
-                    }
-                    $newanswer->jumpto = clean_param($form->jumpto[$i], PARAM_INT);
-                    if (isset($form->score[$i])) {
-                        $newanswer->score = clean_param($form->score[$i], PARAM_INT);
-                    }
-                    $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
-                }
-            } else {
-                 if ($form->qtype == LESSON_MATCHING) {
-                    if ($i >= 2) {
-                        if ($form->answerid[$i]) {
-                            // need to delete blanked out answer
-                            $DB->delete_records("lesson_answers", array("id" => clean_param($form->answerid[$i], PARAM_INT)));
-                        }
-                    } else {
-                        $oldanswer = new stdClass;
-                        $oldanswer->id = clean_param($form->answerid[$i], PARAM_INT);
-                        if (!isset($form->answereditor[$i])) {
-                            $form->answereditor[$i] = 0;
-                        }
-                        if (!isset($form->responseeditor[$i])) {
-                            $form->responseeditor[$i] = 0;
-                        }
-                        $oldanswer->flags = $form->answereditor[$i] * LESSON_ANSWER_EDITOR +
-                                            $form->responseeditor[$i] * LESSON_RESPONSE_EDITOR;
-                        $oldanswer->timemodified = $timenow;
-                        $oldanswer->answer = NULL;
-                        $DB->update_record("lesson_answers", $oldanswer);
-                    }
-                } elseif (!empty($form->answerid[$i])) {
-                    // need to delete blanked out answer
-                    $DB->delete_records("lesson_answers", array("id" => clean_param($form->answerid[$i], PARAM_INT)));
-                }
-            }
-        }
-    }
-
-    if ($form->redisplay) {
-        redirect("$CFG->wwwroot/mod/lesson/lesson.php?id=$cm->id&amp;action=editpage&amp;pageid=$page->id&amp;redirect=$redirect");
-    }
-
-    lesson_set_message(get_string('updatedpage', 'lesson').': '.format_string($page->title, true), 'notifysuccess');
-    if ($redirect == 'navigation') {
-        // takes us back to viewing the page
-        redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$page->id");
-    } else {
-        redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
-    }
-
index de2b0feb1f7ea43202d4642efaa6b7f33af0cf07..b9fc75c365099397762a014ced189bcb0a46cc29 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Lesson's backup routine
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
-    //This is the "graphical" structure of the lesson mod:
-    //
-    //          lesson_default                  lesson ----------------------------|--------------------------|--------------------------|
-    //     (UL, pk->id,fk->courseid)         (CL,pk->id)                           |                          |                          |
-    //                                             |                               |                          |                          |
-    //                                             |                         lesson_grades              lesson_high_scores         lesson_timer
-    //                                             |                  (UL, pk->id,fk->lessonid)    (UL, pk->id,fk->lessonid)   (UL, pk->id,fk->lessonid)
-    //                                             |
-    //                                             |
-    //                                      lesson_pages---------------------------|
-    //                                  (CL,pk->id,fk->lessonid)                   |
-    //                                             |                               |
-    //                                             |                         lesson_branch
-    //                                             |                   (UL, pk->id,fk->pageid)
-    //                                       lesson_answers
-    //                                    (CL,pk->id,fk->pageid)
-    //                                             |
-    //                                             |
-    //                                             |
-    //                                       lesson_attempts
-    //                                  (UL,pk->id,fk->answerid)
-    //
-    // Meaning: pk->primary key field of the table
-    //          fk->foreign key to link with parent
-    //          nt->nested field (recursive data)
-    //          CL->course level info
-    //          UL->user level info
-    //          files->table may have files)
-    //
-    //-----------------------------------------------------------
-
-    //This function executes all the backup procedure about this mod
-    function lesson_backup_mods($bf, $preferences) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        //Iterate over lesson table
-        $lessons = $DB->get_records("lesson", array ("course" => $preferences->backup_course), "id");
-        if ($lessons) {
-            foreach ($lessons as $lesson) {
-                if (backup_mod_selected($preferences,'lesson',$lesson->id)) {
-                    $status = lesson_backup_one_mod($bf,$preferences,$lesson);
-                }
+
+// This is the "graphical" structure of the lesson mod:
+//
+//                  lesson ----------------------------|--------------------------|--------------------------|
+//               (CL,pk->id)                           |                          |                          |
+//                     |                               |                          |                          |
+//                     |                         lesson_grades              lesson_high_scores         lesson_timer
+//                     |                  (UL, pk->id,fk->lessonid)    (UL, pk->id,fk->lessonid)   (UL, pk->id,fk->lessonid)
+//                     |
+//                     |
+//              lesson_pages---------------------------|
+//          (CL,pk->id,fk->lessonid)                   |
+//                     |                               |
+//                     |                         lesson_branch
+//                     |                   (UL, pk->id,fk->pageid)
+//               lesson_answers
+//            (CL,pk->id,fk->pageid)
+//                     |
+//                     |
+//                     |
+//               lesson_attempts
+//          (UL,pk->id,fk->answerid)
+//
+// Meaning: pk->primary key field of the table
+//          fk->foreign key to link with parent
+//          nt->nested field (recursive data)
+//          CL->course level info
+//          UL->user level info
+//          files->table may have files)
+//
+//-----------------------------------------------------------
+
+/**
+ * This function executes all the backup procedure about this mod
+ */
+function lesson_backup_mods($bf, $preferences) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    //Iterate over lesson table
+    $lessons = $DB->get_records("lesson", array ("course" => $preferences->backup_course), "id");
+    if ($lessons) {
+        foreach ($lessons as $lesson) {
+            if (backup_mod_selected($preferences,'lesson',$lesson->id)) {
+                $status = lesson_backup_one_mod($bf,$preferences,$lesson);
             }
         }
-        return $status;
     }
+    return $status;
+}
 
-    function lesson_backup_one_mod($bf,$preferences,$lesson) {
+function lesson_backup_one_mod($bf,$preferences,$lesson) {
 
-        global $CFG, $DB;
+    global $CFG, $DB;
 
-        if (is_numeric($lesson)) {
-            $lesson = $DB->get_record('lesson',array ('id' => $lesson));
-        }
+    if (is_numeric($lesson)) {
+        $lesson = $DB->get_record('lesson',array ('id' => $lesson));
+    }
 
-        $status = true;
-
-        //Start mod
-        fwrite ($bf,start_tag("MOD",3,true));
-        //Print lesson data
-        fwrite ($bf,full_tag("ID",4,false,$lesson->id));
-        fwrite ($bf,full_tag("MODTYPE",4,false,"lesson"));
-        fwrite ($bf,full_tag("NAME",4,false,$lesson->name));
-        fwrite ($bf,full_tag("PRACTICE",4,false,$lesson->practice));
-        fwrite ($bf,full_tag("MODATTEMPTS",4,false,$lesson->modattempts));
-        fwrite ($bf,full_tag("USEPASSWORD",4,false,$lesson->usepassword));
-        fwrite ($bf,full_tag("PASSWORD",4,false,$lesson->password));
-        fwrite ($bf,full_tag("DEPENDENCY",4,false,$lesson->dependency));
-        fwrite ($bf,full_tag("CONDITIONS",4,false,$lesson->conditions));
-        fwrite ($bf,full_tag("GRADE",4,false,$lesson->grade));
-        fwrite ($bf,full_tag("CUSTOM",4,false,$lesson->custom));
-        fwrite ($bf,full_tag("ONGOING",4,false,$lesson->ongoing));
-        fwrite ($bf,full_tag("USEMAXGRADE",4,false,$lesson->usemaxgrade));
-        fwrite ($bf,full_tag("MAXANSWERS",4,false,$lesson->maxanswers));
-        fwrite ($bf,full_tag("MAXATTEMPTS",4,false,$lesson->maxattempts));
-        fwrite ($bf,full_tag("REVIEW",4,false,$lesson->review));
-        fwrite ($bf,full_tag("NEXTPAGEDEFAULT",4,false,$lesson->nextpagedefault));
-        fwrite ($bf,full_tag("FEEDBACK",4,false,$lesson->feedback));
-        fwrite ($bf,full_tag("MINQUESTIONS",4,false,$lesson->minquestions));
-        fwrite ($bf,full_tag("MAXPAGES",4,false,$lesson->maxpages));
-        fwrite ($bf,full_tag("TIMED",4,false,$lesson->timed));
-        fwrite ($bf,full_tag("MAXTIME",4,false,$lesson->maxtime));
-        fwrite ($bf,full_tag("RETAKE",4,false,$lesson->retake));
-        fwrite ($bf,full_tag("ACTIVITYLINK",4,false,$lesson->activitylink));
-        fwrite ($bf,full_tag("MEDIAFILE",4,false,$lesson->mediafile));
-        fwrite ($bf,full_tag("MEDIAHEIGHT",4,false,$lesson->mediaheight));
-        fwrite ($bf,full_tag("MEDIAWIDTH",4,false,$lesson->mediawidth));
-        fwrite ($bf,full_tag("MEDIACLOSE",4,false,$lesson->mediaclose));
-        fwrite ($bf,full_tag("SLIDESHOW",4,false,$lesson->slideshow));
-        fwrite ($bf,full_tag("WIDTH",4,false,$lesson->width));
-        fwrite ($bf,full_tag("HEIGHT",4,false,$lesson->height));
-        fwrite ($bf,full_tag("BGCOLOR",4,false,$lesson->bgcolor));
-        fwrite ($bf,full_tag("DISPLAYLEFT",4,false,$lesson->displayleft));
-        fwrite ($bf,full_tag("DISPLAYLEFTIF",4,false,$lesson->displayleftif));
-        fwrite ($bf,full_tag("PROGRESSBAR",4,false,$lesson->progressbar));
-        fwrite ($bf,full_tag("SHOWHIGHSCORES",4,false,$lesson->highscores));
-        fwrite ($bf,full_tag("MAXHIGHSCORES",4,false,$lesson->maxhighscores));
-        fwrite ($bf,full_tag("AVAILABLE",4,false,$lesson->available));
-        fwrite ($bf,full_tag("DEADLINE",4,false,$lesson->deadline));
-        fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$lesson->timemodified));
-
-        //Now we backup lesson pages
-        $status = backup_lesson_pages($bf,$preferences,$lesson->id);
-        //if we've selected to backup users info, then backup grades, high scores, and timer info
-        if ($status) {
-            if (backup_userdata_selected($preferences,'lesson',$lesson->id)) {
-                if(!backup_lesson_grades($bf, $preferences, $lesson->id)) {
-                    return false;
-                }
-                if (!backup_lesson_high_scores($bf, $preferences, $lesson->id)) {
-                    return false;
-                }
-                if (!backup_lesson_timer($bf, $preferences, $lesson->id)) {
-                    return false;
-                }
+    $status = true;
+
+    //Start mod
+    fwrite ($bf,start_tag("MOD",3,true));
+    //Print lesson data
+    fwrite ($bf,full_tag("ID",4,false,$lesson->id));
+    fwrite ($bf,full_tag("MODTYPE",4,false,"lesson"));
+    fwrite ($bf,full_tag("NAME",4,false,$lesson->name));
+    fwrite ($bf,full_tag("PRACTICE",4,false,$lesson->practice));
+    fwrite ($bf,full_tag("MODATTEMPTS",4,false,$lesson->modattempts));
+    fwrite ($bf,full_tag("USEPASSWORD",4,false,$lesson->usepassword));
+    fwrite ($bf,full_tag("PASSWORD",4,false,$lesson->password));
+    fwrite ($bf,full_tag("DEPENDENCY",4,false,$lesson->dependency));
+    fwrite ($bf,full_tag("CONDITIONS",4,false,$lesson->conditions));
+    fwrite ($bf,full_tag("GRADE",4,false,$lesson->grade));
+    fwrite ($bf,full_tag("CUSTOM",4,false,$lesson->custom));
+    fwrite ($bf,full_tag("ONGOING",4,false,$lesson->ongoing));
+    fwrite ($bf,full_tag("USEMAXGRADE",4,false,$lesson->usemaxgrade));
+    fwrite ($bf,full_tag("MAXANSWERS",4,false,$lesson->maxanswers));
+    fwrite ($bf,full_tag("MAXATTEMPTS",4,false,$lesson->maxattempts));
+    fwrite ($bf,full_tag("REVIEW",4,false,$lesson->review));
+    fwrite ($bf,full_tag("NEXTPAGEDEFAULT",4,false,$lesson->nextpagedefault));
+    fwrite ($bf,full_tag("FEEDBACK",4,false,$lesson->feedback));
+    fwrite ($bf,full_tag("MINQUESTIONS",4,false,$lesson->minquestions));
+    fwrite ($bf,full_tag("MAXPAGES",4,false,$lesson->maxpages));
+    fwrite ($bf,full_tag("TIMED",4,false,$lesson->timed));
+    fwrite ($bf,full_tag("MAXTIME",4,false,$lesson->maxtime));
+    fwrite ($bf,full_tag("RETAKE",4,false,$lesson->retake));
+    fwrite ($bf,full_tag("ACTIVITYLINK",4,false,$lesson->activitylink));
+    fwrite ($bf,full_tag("MEDIAFILE",4,false,$lesson->mediafile));
+    fwrite ($bf,full_tag("MEDIAHEIGHT",4,false,$lesson->mediaheight));
+    fwrite ($bf,full_tag("MEDIAWIDTH",4,false,$lesson->mediawidth));
+    fwrite ($bf,full_tag("MEDIACLOSE",4,false,$lesson->mediaclose));
+    fwrite ($bf,full_tag("SLIDESHOW",4,false,$lesson->slideshow));
+    fwrite ($bf,full_tag("WIDTH",4,false,$lesson->width));
+    fwrite ($bf,full_tag("HEIGHT",4,false,$lesson->height));
+    fwrite ($bf,full_tag("BGCOLOR",4,false,$lesson->bgcolor));
+    fwrite ($bf,full_tag("DISPLAYLEFT",4,false,$lesson->displayleft));
+    fwrite ($bf,full_tag("DISPLAYLEFTIF",4,false,$lesson->displayleftif));
+    fwrite ($bf,full_tag("PROGRESSBAR",4,false,$lesson->progressbar));
+    fwrite ($bf,full_tag("SHOWHIGHSCORES",4,false,$lesson->highscores));
+    fwrite ($bf,full_tag("MAXHIGHSCORES",4,false,$lesson->maxhighscores));
+    fwrite ($bf,full_tag("AVAILABLE",4,false,$lesson->available));
+    fwrite ($bf,full_tag("DEADLINE",4,false,$lesson->deadline));
+    fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$lesson->timemodified));
+
+    //Now we backup lesson pages
+    $status = backup_lesson_pages($bf,$preferences,$lesson->id);
+    //if we've selected to backup users info, then backup grades, high scores, and timer info
+    if ($status) {
+        if (backup_userdata_selected($preferences,'lesson',$lesson->id)) {
+            if(!backup_lesson_grades($bf, $preferences, $lesson->id)) {
+                return false;
+            }
+            if (!backup_lesson_high_scores($bf, $preferences, $lesson->id)) {
+                return false;
             }
-            // back up the default for the course.  There might not be one, but if there
-            //  is, there will only be one.
-            $status = backup_lesson_default($bf,$preferences);
-            //End mod
-            if ($status) {
-                $status =fwrite ($bf,end_tag("MOD",3,true));
+            if (!backup_lesson_timer($bf, $preferences, $lesson->id)) {
+                return false;
             }
         }
-
-        return $status;
+        //End mod
+        $status =fwrite ($bf,end_tag("MOD",3,true));
     }
 
-    //Backup lesson_pages contents (executed from lesson_backup_mods)
-    function backup_lesson_pages ($bf, $preferences, $lessonid) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        // run through the pages in their logical order, get the first page
-        $params = array ("lessonid" => $lessonid, "prevpageid" => 0);
-        if ($page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("PAGES",4,true));
-            //Iterate over each page
-            while (true) {
-                //Start of page
-                $status =fwrite ($bf,start_tag("PAGE",5,true));
-                //Print page contents (prevpageid and nextpageid not needed)
-                fwrite ($bf,full_tag("PAGEID",6,false,$page->id)); // needed to fix (absolute) jumps
-                fwrite ($bf,full_tag("QTYPE",6,false,$page->qtype));
-                fwrite ($bf,full_tag("QOPTION",6,false,$page->qoption));
-                fwrite ($bf,full_tag("LAYOUT",6,false,$page->layout));
-                fwrite ($bf,full_tag("DISPLAY",6,false,$page->display));
-                fwrite ($bf,full_tag("TIMECREATED",6,false,$page->timecreated));
-                fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$page->timemodified));
-                fwrite ($bf,full_tag("TITLE",6,false,$page->title));
-                fwrite ($bf,full_tag("CONTENTS",6,false,$page->contents));
-                //Now we backup lesson answers for this page
-                $status = backup_lesson_answers($bf, $preferences, $page->id);
-                // backup branch table info for branch tables.
-                if ($status && backup_userdata_selected($preferences,'lesson',$lessonid)) {
-                    if (!backup_lesson_branch($bf, $preferences, $page->id)) {
-                        return false;
-                    }
+    return $status;
+}
+
+//Backup lesson_pages contents (executed from lesson_backup_mods)
+function backup_lesson_pages ($bf, $preferences, $lessonid) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    // run through the pages in their logical order, get the first page
+    $params = array ("lessonid" => $lessonid, "prevpageid" => 0);
+    if ($page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("PAGES",4,true));
+        //Iterate over each page
+        while (true) {
+            //Start of page
+            $status =fwrite ($bf,start_tag("PAGE",5,true));
+            //Print page contents (prevpageid and nextpageid not needed)
+            fwrite ($bf,full_tag("PAGEID",6,false,$page->id)); // needed to fix (absolute) jumps
+            fwrite ($bf,full_tag("QTYPE",6,false,$page->qtype));
+            fwrite ($bf,full_tag("QOPTION",6,false,$page->qoption));
+            fwrite ($bf,full_tag("LAYOUT",6,false,$page->layout));
+            fwrite ($bf,full_tag("DISPLAY",6,false,$page->display));
+            fwrite ($bf,full_tag("TIMECREATED",6,false,$page->timecreated));
+            fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$page->timemodified));
+            fwrite ($bf,full_tag("TITLE",6,false,$page->title));
+            fwrite ($bf,full_tag("CONTENTS",6,false,$page->contents));
+            //Now we backup lesson answers for this page
+            $status = backup_lesson_answers($bf, $preferences, $page->id);
+            // backup branch table info for branch tables.
+            if ($status && backup_userdata_selected($preferences,'lesson',$lessonid)) {
+                if (!backup_lesson_branch($bf, $preferences, $page->id)) {
+                    return false;
                 }
-                //End of page
-                $status =fwrite ($bf,end_tag("PAGE",5,true));
-                // move to the next (logical) page
-                if ($page->nextpageid) {
-                    if (!$page = $DB->get_record("lesson_pages", array ("id" => $page->nextpageid))) {
-                        print_error('cannotfindnextpage', 'lesson');
-                    }
-                } else {
-                    // last page reached
-                    break;
+            }
+            //End of page
+            $status =fwrite ($bf,end_tag("PAGE",5,true));
+            // move to the next (logical) page
+            if ($page->nextpageid) {
+                if (!$page = $DB->get_record("lesson_pages", array ("id" => $page->nextpageid))) {
+                    print_error('cannotfindnextpage', 'lesson');
                 }
-
+            } else {
+                // last page reached
+                break;
             }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("PAGES",4,true));
+
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("PAGES",4,true));
     }
-
-    //Backup lesson_answers contents (executed from backup_lesson_pages)
-    function backup_lesson_answers($bf,$preferences,$pageno) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        // get the answers in a set order, the id order
-        $lesson_answers = $DB->get_records("lesson_answers", array("pageid" => $pageno), "id");
-
-        //If there is lesson_answers
-        if ($lesson_answers) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("ANSWERS",6,true));
-            //Iterate over each element
-            foreach ($lesson_answers as $answer) {
-                //Start answer
-                $status =fwrite ($bf,start_tag("ANSWER",7,true));
-                //Print answer contents
-                fwrite ($bf,full_tag("ID",8,false,$answer->id));
-                fwrite ($bf,full_tag("JUMPTO",8,false,$answer->jumpto));
-                fwrite ($bf,full_tag("GRADE",8,false,$answer->grade));
-                fwrite ($bf,full_tag("SCORE",8,false,$answer->score));
-                fwrite ($bf,full_tag("FLAGS",8,false,$answer->flags));
-                fwrite ($bf,full_tag("TIMECREATED",8,false,$answer->timecreated));
-                fwrite ($bf,full_tag("TIMEMODIFIED",8,false,$answer->timemodified));
-                fwrite ($bf,full_tag("ANSWERTEXT",8,false,$answer->answer));
-                fwrite ($bf,full_tag("RESPONSE",8,false,$answer->response));
-                //Now we backup any lesson attempts (if student data required)
-                if (backup_userdata_selected($preferences,'lesson',$answer->lessonid)) {
-                    $status = backup_lesson_attempts($bf,$preferences,$answer->id);
-                }
-                //End rubric
-                $status =fwrite ($bf,end_tag("ANSWER",7,true));
+    return $status;
+}
+
+//Backup lesson_answers contents (executed from backup_lesson_pages)
+function backup_lesson_answers($bf,$preferences,$pageno) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    // get the answers in a set order, the id order
+    $lesson_answers = $DB->get_records("lesson_answers", array("pageid" => $pageno), "id");
+
+    //If there is lesson_answers
+    if ($lesson_answers) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("ANSWERS",6,true));
+        //Iterate over each element
+        foreach ($lesson_answers as $answer) {
+            //Start answer
+            $status =fwrite ($bf,start_tag("ANSWER",7,true));
+            //Print answer contents
+            fwrite ($bf,full_tag("ID",8,false,$answer->id));
+            fwrite ($bf,full_tag("JUMPTO",8,false,$answer->jumpto));
+            fwrite ($bf,full_tag("GRADE",8,false,$answer->grade));
+            fwrite ($bf,full_tag("SCORE",8,false,$answer->score));
+            fwrite ($bf,full_tag("FLAGS",8,false,$answer->flags));
+            fwrite ($bf,full_tag("TIMECREATED",8,false,$answer->timecreated));
+            fwrite ($bf,full_tag("TIMEMODIFIED",8,false,$answer->timemodified));
+            fwrite ($bf,full_tag("ANSWERTEXT",8,false,$answer->answer));
+            fwrite ($bf,full_tag("RESPONSE",8,false,$answer->response));
+            //Now we backup any lesson attempts (if student data required)
+            if (backup_userdata_selected($preferences,'lesson',$answer->lessonid)) {
+                $status = backup_lesson_attempts($bf,$preferences,$answer->id);
             }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("ANSWERS",6,true));
+            //End rubric
+            $status =fwrite ($bf,end_tag("ANSWER",7,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("ANSWERS",6,true));
     }
-
-    //Backup lesson_attempts contents (executed from lesson_backup_answers)
-    function backup_lesson_attempts ($bf,$preferences,$answerid) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        $lesson_attempts = $DB->get_records("lesson_attempts", array("answerid" => $answerid));
-        //If there are attempts
-        if ($lesson_attempts) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("ATTEMPTS",8,true));
-            //Iterate over each attempt
-            foreach ($lesson_attempts as $attempt) {
-                //Start Attempt
-                $status =fwrite ($bf,start_tag("ATTEMPT",9,true));
-                //Print attempt contents
-                fwrite ($bf,full_tag("USERID",10,false,$attempt->userid));
-                fwrite ($bf,full_tag("RETRY",10,false,$attempt->retry));
-                fwrite ($bf,full_tag("CORRECT",10,false,$attempt->correct));
-                fwrite ($bf,full_tag("USERANSWER",10,false,$attempt->useranswer));
-                fwrite ($bf,full_tag("TIMESEEN",10,false,$attempt->timeseen));
-                //End attempt
-                $status =fwrite ($bf,end_tag("ATTEMPT",9,true));
-            }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("ATTEMPTS",8,true));
+    return $status;
+}
+
+//Backup lesson_attempts contents (executed from lesson_backup_answers)
+function backup_lesson_attempts ($bf,$preferences,$answerid) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    $lesson_attempts = $DB->get_records("lesson_attempts", array("answerid" => $answerid));
+    //If there are attempts
+    if ($lesson_attempts) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("ATTEMPTS",8,true));
+        //Iterate over each attempt
+        foreach ($lesson_attempts as $attempt) {
+            //Start Attempt
+            $status =fwrite ($bf,start_tag("ATTEMPT",9,true));
+            //Print attempt contents
+            fwrite ($bf,full_tag("USERID",10,false,$attempt->userid));
+            fwrite ($bf,full_tag("RETRY",10,false,$attempt->retry));
+            fwrite ($bf,full_tag("CORRECT",10,false,$attempt->correct));
+            fwrite ($bf,full_tag("USERANSWER",10,false,$attempt->useranswer));
+            fwrite ($bf,full_tag("TIMESEEN",10,false,$attempt->timeseen));
+            //End attempt
+            $status =fwrite ($bf,end_tag("ATTEMPT",9,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("ATTEMPTS",8,true));
     }
-
-
-   //Backup lesson_grades contents (executed from backup_lesson_mods)
-    function backup_lesson_grades ($bf,$preferences,$lessonid) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        $grades = $DB->get_records("lesson_grades", array("lessonid" => $lessonid));
-
-        //If there is grades
-        if ($grades) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("GRADES",4,true));
-            //Iterate over each grade
-            foreach ($grades as $grade) {
-                //Start grade
-                $status =fwrite ($bf,start_tag("GRADE",5,true));
-                //Print grade contents
-                fwrite ($bf,full_tag("USERID",6,false,$grade->userid));
-                fwrite ($bf,full_tag("GRADE_VALUE",6,false,$grade->grade));
-                fwrite ($bf,full_tag("LATE",6,false,$grade->late));
-                fwrite ($bf,full_tag("COMPLETED",6,false,$grade->completed));
-                //End grade
-                $status =fwrite ($bf,end_tag("GRADE",5,true));
-            }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("GRADES",4,true));
+    return $status;
+}
+
+
+//Backup lesson_grades contents (executed from backup_lesson_mods)
+function backup_lesson_grades ($bf,$preferences,$lessonid) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    $grades = $DB->get_records("lesson_grades", array("lessonid" => $lessonid));
+
+    //If there is grades
+    if ($grades) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("GRADES",4,true));
+        //Iterate over each grade
+        foreach ($grades as $grade) {
+            //Start grade
+            $status =fwrite ($bf,start_tag("GRADE",5,true));
+            //Print grade contents
+            fwrite ($bf,full_tag("USERID",6,false,$grade->userid));
+            fwrite ($bf,full_tag("GRADE_VALUE",6,false,$grade->grade));
+            fwrite ($bf,full_tag("LATE",6,false,$grade->late));
+            fwrite ($bf,full_tag("COMPLETED",6,false,$grade->completed));
+            //End grade
+            $status =fwrite ($bf,end_tag("GRADE",5,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("GRADES",4,true));
     }
-
-    //Backup lesson_branch contents (executed from backup_lesson_pages)
-    function backup_lesson_branch($bf,$preferences,$pageno) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        // get the branches in a set order, the id order
-        $lesson_branch = $DB->get_records("lesson_branch", array("pageid" => $pageno), "id");
-
-        //If there is lesson_branch
-        if ($lesson_branch) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("BRANCHES",6,true));
-            //Iterate over each element
-            foreach ($lesson_branch as $branch) {
-                //Start branch
-                $status =fwrite ($bf,start_tag("BRANCH",7,true));
-                //Print branch contents
-                fwrite ($bf,full_tag("USERID",8,false,$branch->userid));
-                fwrite ($bf,full_tag("RETRY",8,false,$branch->retry));
-                fwrite ($bf,full_tag("FLAG",8,false,$branch->flag));
-                fwrite ($bf,full_tag("TIMESEEN",8,false,$branch->timeseen));
-                // END BRANCH
-                $status =fwrite ($bf,end_tag("BRANCH",7,true));
-            }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("BRANCHES",6,true));
+    return $status;
+}
+
+//Backup lesson_branch contents (executed from backup_lesson_pages)
+function backup_lesson_branch($bf,$preferences,$pageno) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    // get the branches in a set order, the id order
+    $lesson_branch = $DB->get_records("lesson_branch", array("pageid" => $pageno), "id");
+
+    //If there is lesson_branch
+    if ($lesson_branch) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("BRANCHES",6,true));
+        //Iterate over each element
+        foreach ($lesson_branch as $branch) {
+            //Start branch
+            $status =fwrite ($bf,start_tag("BRANCH",7,true));
+            //Print branch contents
+            fwrite ($bf,full_tag("USERID",8,false,$branch->userid));
+            fwrite ($bf,full_tag("RETRY",8,false,$branch->retry));
+            fwrite ($bf,full_tag("FLAG",8,false,$branch->flag));
+            fwrite ($bf,full_tag("TIMESEEN",8,false,$branch->timeseen));
+            // END BRANCH
+            $status =fwrite ($bf,end_tag("BRANCH",7,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("BRANCHES",6,true));
     }
-
-   //Backup lesson_timer contents (executed from backup_lesson_mods)
-    function backup_lesson_timer ($bf,$preferences,$lessonid) {
-
-        global $CFG, $DB;
-
-        $status = true;
-
-        $times = $DB->get_records("lesson_timer", array("lessonid" => $lessonid));
-
-        //If there is times
-        if ($times) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("TIMES",4,true));
-            //Iterate over each time
-            foreach ($times as $time) {
-                //Start time
-                $status =fwrite ($bf,start_tag("TIME",5,true));
-                //Print time contents
-                fwrite ($bf,full_tag("USERID",6,false,$time->userid));
-                fwrite ($bf,full_tag("STARTTIME",6,false,$time->starttime));
-                fwrite ($bf,full_tag("LESSONTIME",6,false,$time->lessontime));
-                //End time
-                $status =fwrite ($bf,end_tag("TIME",5,true));
-            }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("TIMES",4,true));
+    return $status;
+}
+
+//Backup lesson_timer contents (executed from backup_lesson_mods)
+function backup_lesson_timer ($bf,$preferences,$lessonid) {
+
+    global $CFG, $DB;
+
+    $status = true;
+
+    $times = $DB->get_records("lesson_timer", array("lessonid" => $lessonid));
+
+    //If there is times
+    if ($times) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("TIMES",4,true));
+        //Iterate over each time
+        foreach ($times as $time) {
+            //Start time
+            $status =fwrite ($bf,start_tag("TIME",5,true));
+            //Print time contents
+            fwrite ($bf,full_tag("USERID",6,false,$time->userid));
+            fwrite ($bf,full_tag("STARTTIME",6,false,$time->starttime));
+            fwrite ($bf,full_tag("LESSONTIME",6,false,$time->lessontime));
+            //End time
+            $status =fwrite ($bf,end_tag("TIME",5,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("TIMES",4,true));
     }
-
-    // backup lesson_high_score contents (executed from backup_lesson_mods)
-    function backup_lesson_high_scores($bf, $preferences, $lessonid) {
-        global $CFG, $DB;
-
-        $status = true;
-
-        $highscores = $DB->get_records("lesson_high_scores", array("lessonid" => $lessonid));
-
-        //If there is highscores
-        if ($highscores) {
-            //Write start tag
-            $status =fwrite ($bf,start_tag("HIGHSCORES",4,true));
-            //Iterate over each highscore
-            foreach ($highscores as $highscore) {
-                //Start highscore
-                $status =fwrite ($bf,start_tag("HIGHSCORE",5,true));
-                //Print highscore contents
-                fwrite ($bf,full_tag("USERID",6,false,$highscore->userid));
-                fwrite ($bf,full_tag("GRADEID",6,false,$highscore->gradeid));
-                fwrite ($bf,full_tag("NICKNAME",6,false,$highscore->nickname));
-                //End highscore
-                $status =fwrite ($bf,end_tag("HIGHSCORE",5,true));
-            }
-            //Write end tag
-            $status =fwrite ($bf,end_tag("HIGHSCORES",4,true));
+    return $status;
+}
+
+// backup lesson_high_score contents (executed from backup_lesson_mods)
+function backup_lesson_high_scores($bf, $preferences, $lessonid) {
+    global $CFG, $DB;
+
+    $status = true;
+
+    $highscores = $DB->get_records("lesson_high_scores", array("lessonid" => $lessonid));
+
+    //If there is highscores
+    if ($highscores) {
+        //Write start tag
+        $status =fwrite ($bf,start_tag("HIGHSCORES",4,true));
+        //Iterate over each highscore
+        foreach ($highscores as $highscore) {
+            //Start highscore
+            $status =fwrite ($bf,start_tag("HIGHSCORE",5,true));
+            //Print highscore contents
+            fwrite ($bf,full_tag("USERID",6,false,$highscore->userid));
+            fwrite ($bf,full_tag("GRADEID",6,false,$highscore->gradeid));
+            fwrite ($bf,full_tag("NICKNAME",6,false,$highscore->nickname));
+            //End highscore
+            $status =fwrite ($bf,end_tag("HIGHSCORE",5,true));
         }
-        return $status;
+        //Write end tag
+        $status =fwrite ($bf,end_tag("HIGHSCORES",4,true));
     }
-
-    // backup lesson_default contents (executed from backup_lesson_mods)
-    function backup_lesson_default ($bf,$preferences) {
-        global $CFG, $DB;
-
-        $status = true;
-
-        //only one default record per course
-        $default = $DB->get_record("lesson_default", array("course" => $preferences->backup_course));
-        if ($default) {
-            //Start mod
-            $status =fwrite ($bf,start_tag("DEFAULTS",4,true));
-            //Print default data
-            fwrite ($bf,full_tag("PRACTICE",5,false,$default->practice));
-            fwrite ($bf,full_tag("MODATTEMPTS",5,false,$default->modattempts));
-            fwrite ($bf,full_tag("USEPASSWORD",5,false,$default->usepassword));
-            fwrite ($bf,full_tag("PASSWORD",5,false,$default->password));
-            fwrite ($bf,full_tag("CONDITIONS",5,false,$default->conditions));
-            fwrite ($bf,full_tag("GRADE",5,false,$default->grade));
-            fwrite ($bf,full_tag("CUSTOM",5,false,$default->custom));
-            fwrite ($bf,full_tag("ONGOING",5,false,$default->ongoing));
-            fwrite ($bf,full_tag("USEMAXGRADE",5,false,$default->usemaxgrade));
-            fwrite ($bf,full_tag("MAXANSWERS",5,false,$default->maxanswers));
-            fwrite ($bf,full_tag("MAXATTEMPTS",5,false,$default->maxattempts));
-            fwrite ($bf,full_tag("REVIEW",5,false,$default->review));
-            fwrite ($bf,full_tag("NEXTPAGEDEFAULT",5,false,$default->nextpagedefault));
-            fwrite ($bf,full_tag("FEEDBACK",5,false,$default->feedback));
-            fwrite ($bf,full_tag("MINQUESTIONS",5,false,$default->minquestions));
-            fwrite ($bf,full_tag("MAXPAGES",5,false,$default->maxpages));
-            fwrite ($bf,full_tag("TIMED",5,false,$default->timed));
-            fwrite ($bf,full_tag("MAXTIME",5,false,$default->maxtime));
-            fwrite ($bf,full_tag("RETAKE",5,false,$default->retake));
-            fwrite ($bf,full_tag("MEDIAHEIGHT",5,false,$default->mediaheight));
-            fwrite ($bf,full_tag("MEDIAWIDTH",5,false,$default->mediawidth));
-            fwrite ($bf,full_tag("MEDIACLOSE",5,false,$default->mediaclose));
-            fwrite ($bf,full_tag("SLIDESHOW",5,false,$default->slideshow));
-            fwrite ($bf,full_tag("WIDTH",5,false,$default->width));
-            fwrite ($bf,full_tag("HEIGHT",5,false,$default->height));
-            fwrite ($bf,full_tag("BGCOLOR",5,false,$default->bgcolor));
-            fwrite ($bf,full_tag("DISPLAYLEFT",5,false,$default->displayleft));
-            fwrite ($bf,full_tag("DISPLAYLEFTIF",5,false,$default->displayleftif));
-            fwrite ($bf,full_tag("PROGRESSBAR",5,false,$default->progressbar));
-            fwrite ($bf,full_tag("HIGHSCORES",5,false,$default->highscores));
-            fwrite ($bf,full_tag("MAXHIGHSCORES",5,false,$default->maxhighscores));
-            $status =fwrite ($bf,end_tag("DEFAULTS",4,true));
+    return $status;
+}
+
+//Return an array of info (name,value)
+function lesson_check_backup_mods($course,$user_data=false,$backup_unique_code,$instances=null) {
+    if (!empty($instances) && is_array($instances) && count($instances)) {
+        $info = array();
+        foreach ($instances as $id => $instance) {
+            $info += lesson_check_backup_mods_instances($instance,$backup_unique_code);
         }
-        return $status;
+        return $info;
+    }
+    //First the course data
+    $info[0][0] = get_string("modulenameplural","lesson");
+    if ($ids = lesson_ids($course)) {
+        $info[0][1] = count($ids);
+    } else {
+        $info[0][1] = 0;
     }
 
-    //Return an array of info (name,value)
-    function lesson_check_backup_mods($course,$user_data=false,$backup_unique_code,$instances=null) {
-        if (!empty($instances) && is_array($instances) && count($instances)) {
-            $info = array();
-            foreach ($instances as $id => $instance) {
-                $info += lesson_check_backup_mods_instances($instance,$backup_unique_code);
-            }
-            return $info;
-        }
-        //First the course data
-        $info[0][0] = get_string("modulenameplural","lesson");
-        if ($ids = lesson_ids($course)) {
-            $info[0][1] = count($ids);
+    //Now, if requested, the user_data
+    if ($user_data) {
+        $info[1][0] = get_string("attempts","lesson");
+        if ($ids = lesson_attempts_ids_by_course ($course)) {
+            $info[1][1] = count($ids);
         } else {
-            $info[0][1] = 0;
+            $info[1][1] = 0;
         }
-
-        //Now, if requested, the user_data
-        if ($user_data) {
-            $info[1][0] = get_string("attempts","lesson");
-            if ($ids = lesson_attempts_ids_by_course ($course)) {
-                $info[1][1] = count($ids);
-            } else {
-                $info[1][1] = 0;
-            }
-        }
-        return $info;
     }
-
-    //Return an array of info (name,value)
-    function lesson_check_backup_mods_instances($instance,$backup_unique_code) {
-        //First the course data
-        $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
-        $info[$instance->id.'0'][1] = '';
-
-        //Now, if requested, the user_data
-        if (!empty($instance->userdata)) {
-            $info[$instance->id.'1'][0] = get_string("attempts","lesson");
-            if ($ids = lesson_attempts_ids_by_instance ($instance->id)) {
-                $info[$instance->id.'1'][1] = count($ids);
-            } else {
-                $info[$instance->id.'1'][1] = 0;
-            }
+    return $info;
+}
+
+//Return an array of info (name,value)
+function lesson_check_backup_mods_instances($instance,$backup_unique_code) {
+    //First the course data
+    $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
+    $info[$instance->id.'0'][1] = '';
+
+    //Now, if requested, the user_data
+    if (!empty($instance->userdata)) {
+        $info[$instance->id.'1'][0] = get_string("attempts","lesson");
+        if ($ids = lesson_attempts_ids_by_instance ($instance->id)) {
+            $info[$instance->id.'1'][1] = count($ids);
+        } else {
+            $info[$instance->id.'1'][1] = 0;
         }
-        return $info;
     }
+    return $info;
+}
 
-    //Return a content encoded to support interactivities linking. Every module
-    //should have its own. They are called automatically from the backup procedure.
-    function lesson_encode_content_links ($content,$preferences) {
+//Return a content encoded to support interactivities linking. Every module
+//should have its own. They are called automatically from the backup procedure.
+function lesson_encode_content_links ($content,$preferences) {
 
-        global $CFG;
+    global $CFG;
 
-        $base = preg_quote($CFG->wwwroot,"/");
+    $base = preg_quote($CFG->wwwroot,"/");
 
-        //Link to the list of lessons
-        $buscar="/(".$base."\/mod\/lesson\/index.php\?id\=)([0-9]+)/";
-        $result= preg_replace($buscar,'$@LESSONINDEX*$2@$',$content);
+    //Link to the list of lessons
+    $buscar="/(".$base."\/mod\/lesson\/index.php\?id\=)([0-9]+)/";
+    $result= preg_replace($buscar,'$@LESSONINDEX*$2@$',$content);
 
-        //Link to lesson view by moduleid
-        $buscar="/(".$base."\/mod\/lesson\/view.php\?id\=)([0-9]+)/";
-        $result= preg_replace($buscar,'$@LESSONVIEWBYID*$2@$',$result);
+    //Link to lesson view by moduleid
+    $buscar="/(".$base."\/mod\/lesson\/view.php\?id\=)([0-9]+)/";
+    $result= preg_replace($buscar,'$@LESSONVIEWBYID*$2@$',$result);
 
-        return $result;
-    }
+    return $result;
+}
 
-    // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+// INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
 
-    //Returns an array of lesson id
-    function lesson_ids ($course) {
+//Returns an array of lesson id
+function lesson_ids ($course) {
 
-        global $CFG, $DB;
+    global $CFG, $DB;
 
-        $params = array ("course" => $course);
-        return $DB->get_records_sql ("SELECT l.id, l.course
-                                 FROM {lesson} l
-                                 WHERE l.course = :course", $params);
-    }
+    $params = array ("course" => $course);
+    return $DB->get_records_sql ("SELECT l.id, l.course
+                             FROM {lesson} l
+                             WHERE l.course = :course", $params);
+}
 
-    //Returns an array of lesson_submissions id
-    function lesson_attempts_ids_by_course ($course) {
+//Returns an array of lesson_submissions id
+function lesson_attempts_ids_by_course ($course) {
 
-        global $CFG, $DB;
+    global $CFG, $DB;
 
-        $params = array ("course" => $course);
-        return $DB->get_records_sql ("SELECT a.id , a.lessonid
-                                 FROM {lesson_attempts} a,
-                                      {lesson} l
-                                 WHERE l.course = :course AND
-                                       a.lessonid = l.id", $params);
-    }
-
-    //Returns an array of lesson_submissions id
-    function lesson_attempts_ids_by_instance ($instanceid) {
+    $params = array ("course" => $course);
+    return $DB->get_records_sql ("SELECT a.id , a.lessonid
+                             FROM {lesson_attempts} a,
+                                  {lesson} l
+                             WHERE l.course = :course AND
+                                   a.lessonid = l.id", $params);
+}
 
-        global $CFG, $DB;
+//Returns an array of lesson_submissions id
+function lesson_attempts_ids_by_instance ($instanceid) {
 
-        $params = array ("lessonid" => $instanceid);
-        return $DB->get_records_sql ("SELECT a.id , a.lessonid
-                                 FROM {lesson_attempts} a
-                                 WHERE a.lessonid = :lessonid", $params);
-    }
+    global $CFG, $DB;
 
+    $params = array ("lessonid" => $instanceid);
+    return $DB->get_records_sql ("SELECT a.id , a.lessonid
+                             FROM {lesson_attempts} a
+                             WHERE a.lessonid = :lessonid", $params);
+}
\ No newline at end of file
diff --git a/mod/lesson/continue.php b/mod/lesson/continue.php
new file mode 100644 (file)
index 0000000..a943f0d
--- /dev/null
@@ -0,0 +1,199 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Action for processing page answers by users
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/** Require the specific libraries */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+try {
+    $cm = get_coursemodule_from_id('lesson', required_param('id', PARAM_INT), 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+
+require_login($course, false, $cm);
+require_sesskey();
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+$canmanage = has_capability('mod/lesson:manage', $context);
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
+
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/continue.php', array('id'=>$cm->id));
+$PAGE->set_url($url);
+$PAGE->navbar->add(get_string('continue', 'lesson'));
+
+// This is the code updates the lesson time for a timed test
+// get time information for this user
+if (!$canmanage) {
+    $lesson->displayleft = lesson_displayleftif($lesson);
+    $timer = $lesson->update_timer();
+    if ($lesson->timed) {
+        $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
+        if ($timeleft <= 0) {
+            // Out of time
+            $lesson->add_message(get_string('eolstudentoutoftime', 'lesson'));
+            redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$cm->id,'pageid'=>LESSON_EOL, 'outoftime'=>'normal')));
+        } else if ($timeleft < 60) {
+            // One minute warning
+            $lesson->add_message(get_string("studentoneminwarning", "lesson"));
+        }
+    }
+} else {
+    $timer = new stdClass;
+}
+
+// record answer (if necessary) and show response (if none say if answer is correct or not)
+$page = $lesson->load_page(required_param('pageid', PARAM_INT));
+$result = $page->record_attempt($context);
+
+if (isset($USER->modattempts[$lesson->id])) {
+    // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
+    if ($USER->modattempts[$lesson->id] == $page->id) {  // remember, this session variable holds the pageid of the last page that the user saw
+        $result->newpageid = LESSON_EOL;
+    } else {
+        $nretakes--; // make sure we are looking at the right try.
+        $attempts = $DB->get_records("lesson_attempts", array("lessonid"=>$lesson->id, "userid"=>$USER->id, "retry"=>$nretakes), "timeseen", "id, pageid");
+        $found = false;
+        $temppageid = 0;
+        foreach($attempts as $attempt) {
+            if ($found && $temppageid != $attempt->pageid) { // now try to find the next page, make sure next few attempts do no belong to current page
+                $result->newpageid = $attempt->pageid;
+                break;
+            }
+            if ($attempt->pageid == $page->id) {
+                $found = true; // if found current page
+                $temppageid = $attempt->pageid;
+            }
+        }
+    }
+} elseif ($result->newpageid != LESSON_CLUSTERJUMP && $page->id != 0 && $result->newpageid > 0) {
+    // going to check to see if the page that the user is going to view next, is a cluster page.
+    // If so, dont display, go into the cluster.  The $result->newpageid > 0 is used to filter out all of the negative code jumps.
+    $newpage = $lesson->load_page($result->newpageid);
+    if ($newpageid = $newpage->override_next_page($result->newpageid)) {
+        $result->newpageid = $newpageid;
+    }
+} elseif ($result->newpageid == LESSON_UNSEENBRANCHPAGE) {
+    if ($canmanage) {
+        if ($page->nextpageid == 0) {
+            $result->newpageid = LESSON_EOL;
+        } else {
+            $result->newpageid = $page->nextpageid;
+        }
+    } else {
+        $result->newpageid = lesson_unseen_question_jump($lesson, $USER->id, $page->id);
+    }
+} elseif ($result->newpageid == LESSON_PREVIOUSPAGE) {
+    $result->newpageid = $page->prevpageid;
+} elseif ($result->newpageid == LESSON_RANDOMPAGE) {
+    $result->newpageid = lesson_random_question_jump($lesson, $page->id);
+} elseif ($result->newpageid == LESSON_CLUSTERJUMP) {
+    if ($canmanage) {
+        if ($page->nextpageid == 0) {  // if teacher, go to next page
+            $result->newpageid = LESSON_EOL;
+        } else {
+            $result->newpageid = $page->nextpageid;
+        }
+    } else {
+        $result->newpageid = $lesson->cluster_jump($page->id);
+    }
+}
+
+if ($result->nodefaultresponse) {
+    // Don't display feedback
+    redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$cm->id,'pageid'=>$result->newpageid)));
+}
+
+/// Set Messages
+
+if ($canmanage) {
+    // This is the warning msg for teachers to inform them that cluster and unseen does not work while logged in as a teacher
+    if(lesson_display_teacher_warning($lesson)) {
+        $warningvars->cluster = get_string("clusterjump", "lesson");
+        $warningvars->unseen = get_string("unseenpageinbranch", "lesson");
+        $lesson->add_message(get_string("teacherjumpwarning", "lesson", $warningvars));
+    }
+    // Inform teacher that s/he will not see the timer
+    if ($lesson->timed) {
+        $lesson->add_message(get_string("teachertimerwarning", "lesson"));
+    }
+}
+// Report attempts remaining
+if ($result->attemptsremaining != 0) {
+    $lesson->add_message(get_string('attemptsremaining', 'lesson', $result->attemptsremaining));
+}
+// Report if max attempts reached
+if ($result->maxattemptsreached != 0) {
+    $lesson->add_message('('.get_string("maximumnumberofattemptsreached", "lesson").')');
+}
+
+$PAGE->set_url('mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id));
+$PAGE->set_subpage($page->id);
+
+/// Print the header, heading and tabs
+lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
+echo $lessonoutput->header($lesson, 'view', true, $page->id);
+
+if ($lesson->displayleft) {
+    echo '<a name="maincontent" id="maincontent" title="'.get_string('anchortitle', 'lesson').'"></a>';
+}
+// This calculates and prints the ongoing score message
+if ($lesson->ongoing) {
+    echo $lessonoutput->ongoing_score($lesson);
+}
+echo $result->feedback;
+
+// User is modifying attempts - save button and some instructions
+if (isset($USER->modattempts[$lesson->id])) {
+    $url = $CFG->wwwroot.'/mod/lesson/view.php';
+    $options = array('id'=>$cm->id, 'pageid'=>LESSON_EOL);
+    $form = html_form::make($url, $options, get_string('savechanges', 'lesson'));
+    $content = $OUTPUT->box(get_string("savechangesandeol", "lesson"), 'center');
+    $content .= $OUTPUT->box(get_string("or", "lesson"), 'center');
+    $content .= $OUTPUT->box(get_string("continuetoanswer", "lesson"), 'center');
+    echo $OUTPUT->form($form, $content);
+}
+
+// Review button back
+if ($lesson->review && !$result->correctanswer && !$result->noanswer && !$result->isessayquestion) {
+    $url = $CFG->wwwroot.'/mod/lesson/view.php';
+    $options = array('id'=>$cm->id, 'pageid'=>$page->id);
+    $form = html_form::make($url, $options, get_string('reviewquestionback', 'lesson'));
+    echo $OUTPUT->form($form);
+}
+
+$url = $CFG->wwwroot.'/mod/lesson/view.php';
+$options = array('id'=>$cm->id, 'pageid'=>$result->newpageid);
+if ($lesson->review && !$result->correctanswer && !$result->noanswer && !$result->isessayquestion) {
+    // Review button continue
+    $form = html_form::make_button($url, $options, get_string('reviewquestioncontinue', 'lesson'));
+} else {
+    // Normal continue button
+    $form = html_form::make_button($url, $options, get_string('continue', 'lesson'));
+}
+echo $OUTPUT->button($form);
+echo $lessonoutput->footer();
\ No newline at end of file
index 60adf6ae3b9a1c1d448f162f0c6c8f64d9c51929..96707c07a87b24953fe5340261dcb53135cc82e6 100644 (file)
@@ -1,9 +1,30 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Capability definitions for the lesson module.
  *
  * For naming conventions, see lib/db/access.php.
+ *
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  */
 $capabilities = array(
 
     'mod/lesson:edit' => array(
index 37ae270d34d7965a3563dd56b1e2a1b6c1ab8169..5501b7650c43352139a727ee6a22db69d96402d7 100644 (file)
@@ -1,9 +1,30 @@
 <?php
 
-// This file replaces:
-//   * STATEMENTS section in db/install.xml
-//   * lib.php/modulename_install() post installation hook
-//   * partially defaults.php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file replaces:
+ *   * STATEMENTS section in db/install.xml
+ *   * lib.php/modulename_install() post installation hook
+ *   * partially defaults.php
+ *
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 o
+ */
 
 function xmldb_lesson_install() {
     global $DB;
index 4b18fc038c9f16d8a10ba2cba479f4d5aac2eac2..e8fe598380141d1f5eb3835ac7ab34e6191df337 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/lesson/db" VERSION="20070223" COMMENT="XMLDB file for Moodle mod/lesson"
+<XMLDB PATH="mod/lesson/db" VERSION="20091208" COMMENT="XMLDB file for Moodle mod/lesson"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -48,7 +48,7 @@
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="deadline"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" />
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
       </KEYS>
       <INDEXES>
         <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
@@ -80,7 +80,7 @@
         <FIELD NAME="lessonid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="pageid"/>
         <FIELD NAME="pageid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="lessonid" NEXT="jumpto"/>
         <FIELD NAME="jumpto" TYPE="int" LENGTH="11" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="pageid" NEXT="grade"/>
-        <FIELD NAME="grade" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="jumpto" NEXT="score"/>
+        <FIELD NAME="grade" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="jumpto" NEXT="score"/>
         <FIELD NAME="score" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="grade" NEXT="flags"/>
         <FIELD NAME="flags" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="score" NEXT="timecreated"/>
         <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="flags" NEXT="timemodified"/>
         <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="lesson_grades" COMMENT="Defines lesson_grades" PREVIOUS="lesson_attempts" NEXT="lesson_default">
+    <TABLE NAME="lesson_grades" COMMENT="Defines lesson_grades" PREVIOUS="lesson_attempts" NEXT="lesson_timer">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="lessonid"/>
         <FIELD NAME="lessonid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="userid"/>
         <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
       </INDEXES>
     </TABLE>
-    <TABLE NAME="lesson_default" COMMENT="Defines lesson_default" PREVIOUS="lesson_grades" NEXT="lesson_timer">
-      <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="course"/>
-        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="practice"/>
-        <FIELD NAME="practice" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="course" NEXT="modattempts"/>
-        <FIELD NAME="modattempts" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="practice" NEXT="usepassword"/>
-        <FIELD NAME="usepassword" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="modattempts" NEXT="password"/>
-        <FIELD NAME="password" TYPE="char" LENGTH="32" NOTNULL="true" SEQUENCE="false" PREVIOUS="usepassword" NEXT="conditions"/>
-        <FIELD NAME="conditions" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" PREVIOUS="password" NEXT="grade"/>
-        <FIELD NAME="grade" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="conditions" NEXT="custom"/>
-        <FIELD NAME="custom" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="grade" NEXT="ongoing"/>
-        <FIELD NAME="ongoing" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="custom" NEXT="usemaxgrade"/>
-        <FIELD NAME="usemaxgrade" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="ongoing" NEXT="maxanswers"/>
-        <FIELD NAME="maxanswers" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="4" SEQUENCE="false" PREVIOUS="usemaxgrade" NEXT="maxattempts"/>
-        <FIELD NAME="maxattempts" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="5" SEQUENCE="false" PREVIOUS="maxanswers" NEXT="review"/>
-        <FIELD NAME="review" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="maxattempts" NEXT="nextpagedefault"/>
-        <FIELD NAME="nextpagedefault" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="review" NEXT="feedback"/>
-        <FIELD NAME="feedback" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="nextpagedefault" NEXT="minquestions"/>
-        <FIELD NAME="minquestions" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="feedback" NEXT="maxpages"/>
-        <FIELD NAME="maxpages" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="minquestions" NEXT="timed"/>
-        <FIELD NAME="timed" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="maxpages" NEXT="maxtime"/>
-        <FIELD NAME="maxtime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="timed" NEXT="retake"/>
-        <FIELD NAME="retake" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" PREVIOUS="maxtime" NEXT="mediaheight"/>
-        <FIELD NAME="mediaheight" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="100" SEQUENCE="false" PREVIOUS="retake" NEXT="mediawidth"/>
-        <FIELD NAME="mediawidth" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="650" SEQUENCE="false" PREVIOUS="mediaheight" NEXT="mediaclose"/>
-        <FIELD NAME="mediaclose" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="mediawidth" NEXT="slideshow"/>
-        <FIELD NAME="slideshow" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="mediaclose" NEXT="width"/>
-        <FIELD NAME="width" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="640" SEQUENCE="false" PREVIOUS="slideshow" NEXT="height"/>
-        <FIELD NAME="height" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="480" SEQUENCE="false" PREVIOUS="width" NEXT="bgcolor"/>
-        <FIELD NAME="bgcolor" TYPE="char" LENGTH="7" NOTNULL="false" DEFAULT="#FFFFFF" SEQUENCE="false" PREVIOUS="height" NEXT="displayleft"/>
-        <FIELD NAME="displayleft" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="bgcolor" NEXT="displayleftif"/>
-        <FIELD NAME="displayleftif" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="displayleft" NEXT="progressbar"/>
-        <FIELD NAME="progressbar" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="displayleftif" NEXT="highscores"/>
-        <FIELD NAME="highscores" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="progressbar" NEXT="maxhighscores"/>
-        <FIELD NAME="maxhighscores" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" PREVIOUS="highscores"/>
-      </FIELDS>
-      <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" />
-      </KEYS>
-    </TABLE>
-    <TABLE NAME="lesson_timer" COMMENT="lesson timer for each lesson" PREVIOUS="lesson_default" NEXT="lesson_branch">
+    <TABLE NAME="lesson_timer" COMMENT="lesson timer for each lesson" PREVIOUS="lesson_grades" NEXT="lesson_branch">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="lessonid"/>
         <FIELD NAME="lessonid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="userid"/>
       </INDEXES>
     </TABLE>
   </TABLES>
-</XMLDB>
+</XMLDB>
\ No newline at end of file
index 30941931f8988eb97d5508ecd5e338b080694e18..6649022d99aa3fc4bc85403c179ced0626713e3c 100644 (file)
@@ -1,24 +1,45 @@
 <?php
 
-// This file keeps track of upgrades to
-// the lesson module
+// This file is part of Moodle - http://moodle.org/
 //
-// Sometimes, changes between versions involve
-// alterations to database structures and other
-// major things that may break installations.
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
 //
-// The upgrade function in this file will attempt
-// to perform all the necessary actions to upgrade
-// your older installtion to the current version.
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
 //
-// If there's something it cannot do itself, it
-// will tell you what you need to do.
-//
-// The commands in here will all be database-neutral,
-// using the methods of database_manager class
-//
-// Please do not forget to use upgrade_set_timeout()
-// before any action that may take longer time to finish.
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to
+ * the lesson module
+ *
+ * Sometimes, changes between versions involve
+ * alterations to database structures and other
+ * major things that may break installations.
+ *
+ * The upgrade function in this file will attempt
+ * to perform all the necessary actions to upgrade
+ * your older installtion to the current version.
+ *
+ * If there's something it cannot do itself, it
+ * will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral,
+ * using the methods of database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ * 
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 o
+ */
 
 function xmldb_lesson_upgrade($oldversion) {
     global $CFG, $DB;
@@ -53,6 +74,89 @@ function xmldb_lesson_upgrade($oldversion) {
         upgrade_mod_savepoint($result, 2008112601, 'lesson');
     }
 
+    if ($result && $oldversion < 2009111600) {
+        /**
+         * Change the grade field within lesson_answers to an unsigned int and increment
+         * the length by one to ensure that no values are changed (reduced)
+         */
+        $table = new xmldb_table('lesson_answers');
+        $field = new xmldb_field('grade');
+        $field->set_attributes(XMLDB_TYPE_INTEGER, '4', false, XMLDB_NOTNULL, null, '0', 'jumpto');
+        $dbman->change_field_type($table, $field);
+        upgrade_mod_savepoint($result, 2009111600, 'lesson');
+    }
+
+    if ($result && $oldversion < 2009120400) {
+        
+        /**
+         * Move any media files associated with the lesson to use the new file
+         * API methods and structures.
+         */
+        $lessons = $DB->get_records_select('lesson', 'mediafile != \'\'');
+
+        $empty = $DB->sql_empty(); // silly oracle empty string handling workaround
+        $sqlfrom = "FROM {lesson} l
+                    JOIN {modules} m ON m.name = 'lesson'
+                    JOIN {course_modules} cm ON (cm.module = m.id AND cm.instance = l.id)
+                   WHERE l.mediafile <> '$empty'";
+
+        $count = $DB->count_records_sql("SELECT COUNT('x') $sqlfrom");
+
+        if ($count > 0 && $rs = $DB->get_recordset_sql("SELECT l.id, l.mediafile, l.course, cm.id AS cmid $sqlfrom ORDER BY l.course, l.id")) {
+
+            $pbar = new progress_bar('migratelessonfiles', 500, true);
+            $fs = get_file_storage();
+
+            $i = 0;
+            foreach ($rs as $lesson) {
+                $i++;
+                upgrade_set_timeout(60); // set up timeout, may also abort execution
+                $pbar->update($i, $count, "Migrating lesson mediafiles - $i/$count.");
+                
+                $filepath = $CFG->dataroot.'/'.$lesson->course.'/'.$CFG->moddata.'/lesson/'.$lesson->mediafile;
+                if (!is_readable($filepath)) {
+                    //file missing??
+                    echo $OUTPUT->notification("File not readable, skipping: ".$filepath);
+                    $DB->set_field('lesson', 'mediafile', '', array('id'=>$lesson->id));
+                    continue;
+                }
+
+                $filearea = 'lesson_media_file';
+                $filename = clean_param($lesson->mediafile, PARAM_FILE);
+                if ($filename === '') {
+                    echo $OUTPUT->notification("Unsupported lesson filename, skipping: ".$filepath);
+                    $DB->set_field('lesson', 'mediafile', '', array('id'=>$lesson->id));
+                    continue;
+                }
+
+                $context = get_context_instance(CONTEXT_MODULE, $lesson->cmid);
+                if (!$fs->file_exists($context->id, $filearea, $lesson->id, '/', $filename)) {
+                    $file_record = array('contextid'=>$context->id, 'filearea'=>$filearea, 'itemid'=>$lesson->id, 'filepath'=>'/', 'filename'=>$filename);
+                    if ($fs->create_file_from_pathname($file_record, $filepath)) {
+                        if ($DB->set_field('lesson', 'mediafile', $filename, array('id'=>$lesson->id))) {
+                            unlink($filepath);
+                        }
+                    }
+                }
+
+                // remove dir if empty
+                @rmdir("$CFG->dataroot/$post->course/$CFG->moddata/lesson");
+            }
+        }
+
+        upgrade_mod_savepoint($result, 2009120400, 'lesson');
+    }
+
+    if ($result && $oldversion < 2009120800) {
+        /**
+         * Drop the lesson_default table, as of Moodle 2.0 it is no longer used
+         * the module now has a settings.php instead
+         */
+        $table = new xmldb_table('lesson_default');
+        $dbman->drop_table($table);
+        upgrade_mod_savepoint($result, 2009120800, 'lesson');
+    }
+
     return $result;
 }
 
index 83843aa41e9292b97614ea351b1849381abedd25..25de1d3ac48765399f8f23696425fb36c3560957 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Provides the interface for overall authoring of lessons
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once('../../config.php');
-    require_once('locallib.php');
-    require_once('lib.php');
-
-    $id      = required_param('id', PARAM_INT);             // Course Module ID
-    $display = optional_param('display', 0, PARAM_INT);
-    $mode    = optional_param('mode', get_user_preferences('lesson_view', 'collapsed'), PARAM_ALPHA);
-    $pageid = optional_param('pageid', 0, PARAM_INT);
-
-    if ($mode != 'single') {
-        set_user_preference('lesson_view', $mode);
-    }
-
-    list($cm, $course, $lesson) = lesson_get_basics($id);
-
-    if ($firstpage = $DB->get_record('lesson_pages', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
-        if (!$pages = $DB->get_records('lesson_pages', array('lessonid' => $lesson->id))) {
-            print_error('cannotfindrecords', 'lesson');
-        }
-    }
-
-    if ($pageid) {
-        if (!$singlepage = $DB->get_record('lesson_pages', array('id' => $pageid))) {
-            print_error('invalidpageid', 'lesson');
-        }
-    }
-
-    require_login($course->id, false, $cm);
-
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$id,'mode'=>$mode));
-    if ($display !== 0) {
-        $url->param('display', $display);
-    }
-    if ($pageid !== 0) {
-        $url->param('pageid', $pageid);
-    }
-    $PAGE->set_url($url);
-    $PAGE->navbar->add(get_string('edit'));
-
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    require_capability('mod/lesson:manage', $context);
-
-    lesson_print_header($cm, $course, $lesson, $mode);
-
-    if (empty($firstpage)) {
-        // There are no pages; give teacher some options
-        if (has_capability('mod/lesson:edit', $context)) {
-            echo $OUTPUT->box( "<table cellpadding=\"5\" border=\"0\">\n<tr><th scope=\"col\">".get_string("whatdofirst", "lesson")."</th></tr><tr><td>".
-                "<a href=\"import.php?id=$cm->id&amp;pageid=0\">".
-                get_string("importquestions", "lesson")."</a></td></tr><tr><td>".
-                "<a href=\"importppt.php?id=$cm->id&amp;pageid=0\">".
-                get_string("importppt", "lesson")."</a></td></tr><tr><td>".
-                "<a href=\"lesson.php?id=$cm->id&amp;action=addbranchtable&amp;pageid=0&amp;firstpage=1\">".
-                get_string("addabranchtable", "lesson")."</a></td></tr><tr><td>".
-                "<a href=\"lesson.php?id=$cm->id&amp;action=addpage&amp;pageid=0&amp;firstpage=1\">".
-                get_string("addaquestionpage", "lesson").
-                "</a></td></tr></table>\n", 'center', '20%');
-        }
-    } else {
-        // Set some standard variables
-        $pageid = $firstpage->id;
-        $prevpageid = 0;
-        $npages = count($pages);
-
-        switch ($mode) {
-            case 'collapsed':
-                $table = new html_table();
-                $table->head = array(get_string('pagetitle', 'lesson'), get_string('qtype', 'lesson'), get_string('jumps', 'lesson'), get_string('actions', 'lesson'));
-                $table->align = array('left', 'left', 'left', 'center');
-                $table->wrap = array('', 'nowrap', '', 'nowrap');
-                $table->tablealign = 'center';
-                $table->cellspacing = 0;
-                $table->cellpadding = '2px';
-                $table->data = array();
-
-                while ($pageid != 0) {
-                    $page = $pages[$pageid];
-
-                    if ($page->qtype == LESSON_MATCHING) {
-                        // The jumps for matching question type is stored
-                        // in the 3rd and 4rth answer record.
-                        $limitfrom = $limitnum = 2;
-                    } else {
-                        $limitfrom = $limitnum = '';
-                    }
-
-                    $jumps = array();
-                    $params = array ("lessonid" => $lesson->id, "pageid" => $pageid);
-                    if($answers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid and pageid = :pageid", $params, 'id', '*', $limitfrom, $limitnum)) {
-                        foreach ($answers as $answer) {
-                            $jumps[] = lesson_get_jump_name($answer->jumpto);
-                        }
-                    }
-
-                    $table->data[] = array("<a href=\"$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id&amp;mode=single&amp;pageid=".$page->id."\">".format_string($pages[$pageid]->title,true).'</a>',
-                                           lesson_get_qtype_name($page->qtype),
-                                           implode("<br />\n", $jumps),
-                                           lesson_print_page_actions($cm->id, $page, $npages, true, true)
-                                          );
-                    $pageid = $page->nextpageid;
-                }
-
-                echo $OUTPUT->table($table);
-                break;
-
-            case 'single':
-                // Only viewing a single page in full - change some variables to display just one
-                $prevpageid = $singlepage->prevpageid;
-                $pageid     = $singlepage->id;
-
-                $pages = array();
-                $pages[$singlepage->id] = $singlepage;
-
-            case 'full':
-                echo '<table class="boxaligncenter" cellpadding="5" border="0" style="width:80%;">
-                         <tr>
-                             <td align="left">';
-                lesson_print_add_links($cm->id, $prevpageid);
-                echo '       </td>
-                         </tr>';
-
-                while ($pageid != 0) {
-                    $page = $pages[$pageid];
-
-                    echo "<tr><td>\n";
-                    echo "<table style=\"width:100%;\" border=\"1\" class=\"generalbox\"><tr><th colspan=\"2\" scope=\"col\">".format_string($page->title)."&nbsp;&nbsp;\n";
-                    lesson_print_page_actions($cm->id, $page, $npages);
-                    echo "</th></tr>\n";
-                    echo "<tr><td colspan=\"2\">\n";
-                    $options = new stdClass;
-                    $options->noclean = true;
-                    echo format_text($page->contents, FORMAT_MOODLE, $options);
-                    echo "</td></tr>\n";
-                    // get the answers in a set order, the id order
-                    if ($answers = $DB->get_records("lesson_answers", array("pageid" => $page->id), "id")) {
-                        echo "<tr><td colspan=\"2\" align=\"center\"><strong>\n";
-                        echo lesson_get_qtype_name($page->qtype);
-                        switch ($page->qtype) {
-                            case LESSON_SHORTANSWER :
-                                if ($page->qoption) {
-                                    echo " - ".get_string("casesensitive", "lesson");
-                                }
-                                break;
-                            case LESSON_MULTICHOICE :
-                                if ($page->qoption) {
-                                    echo " - ".get_string("multianswer", "lesson");
-                                }
-                                break;
-                            case LESSON_MATCHING :
-                                echo get_string("firstanswershould", "lesson");
-                                break;
-                        }
-                        echo "</strong></td></tr>\n";
-                        $i = 1;
-                        $n = 0;
-                        $options = new stdClass;
-                        $options->noclean = true;
-                        $options->para = false;
-                        foreach ($answers as $answer) {
-                            switch ($page->qtype) {
-                                case LESSON_MULTICHOICE:
-                                case LESSON_TRUEFALSE:
-                                case LESSON_SHORTANSWER:
-                                case LESSON_NUMERICAL:
-                                    echo "<tr><td align=\"right\" valign=\"top\" style=\"width:20%;\">\n";
-                                    if ($lesson->custom) {
-                                        // if the score is > 0, then it is correct
-                                        if ($answer->score > 0) {
-                                            echo '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
-                                        } else {
-                                            echo '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
-                                        }
-                                    } else {
-                                        if (lesson_iscorrect($page->id, $answer->jumpto)) {
-                                            // underline correct answers
-                                            echo '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
-                                        } else {
-                                            echo '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
-                                        }
-                                    }
-                                    echo "</td><td style=\"width:80%;\">\n";
-                                    echo format_text($answer->answer, FORMAT_MOODLE, $options);
-                                    echo "</td></tr>\n";
-                                    echo "<tr><td align=\"right\" valign=\"top\"><span class=\"label\">".get_string("response", "lesson")." $i</span>: \n";
-                                    echo "</td><td>\n";
-                                    echo format_text($answer->response, FORMAT_MOODLE, $options);
-                                    echo "</td></tr>\n";
-                                    break;
-                                case LESSON_MATCHING:
-                                    if ($n < 2) {
-                                        if ($answer->answer != NULL) {
-                                            if ($n == 0) {
-                                                echo "<tr><td align=\"right\" valign=\"top\"><span class=\"label\">".get_string("correctresponse", "lesson")."</span>: \n";
-                                                echo "</td><td>\n";
-                                                echo format_text($answer->answer, FORMAT_MOODLE, $options);
-                                                echo "</td></tr>\n";
-                                            } else {
-                                                echo "<tr><td align=\"right\" valign=\"top\"><span class=\"label\">".get_string("wrongresponse", "lesson")."</span>: \n";
-                                                echo "</td><td>\n";
-                                                echo format_text($answer->answer, FORMAT_MOODLE, $options);
-                                                echo "</td></tr>\n";
-                                            }
-                                        }
-                                        $n++;
-                                        $i--;
-                                    } else {
-                                        echo "<tr><td align=\"right\" valign=\"top\" style=\"width:20%;\">\n";
-                                        if ($lesson->custom) {
-                                            // if the score is > 0, then it is correct
-                                            if ($answer->score > 0) {
-                                                echo '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
-                                            } else {
-                                                echo '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
-                                            }
-                                        } else {
-                                            if (lesson_iscorrect($page->id, $answer->jumpto)) {
-                                                // underline correct answers
-                                                echo '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
-                                            } else {
-                                                echo '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
-                                            }
-                                        }
-                                        echo "</td><td style=\"width:80%;\">\n";
-                                        echo format_text($answer->answer, FORMAT_MOODLE, $options);
-                                        echo "</td></tr>\n";
-                                        echo "<tr><td align=\"right\" valign=\"top\"><span class=\"label\">".get_string("matchesanswer", "lesson")." $i</span>: \n";
-                                        echo "</td><td>\n";
-                                        echo format_text($answer->response, FORMAT_MOODLE, $options);
-                                        echo "</td></tr>\n";
-                                    }
-                                    break;
-                                case LESSON_BRANCHTABLE:
-                                    echo "<tr><td align=\"right\" valign=\"top\" style=\"width:20%;\">\n";
-                                    echo '<span class="label">'.get_string("description", "lesson")." $i</span>: \n";
-                                    echo "</td><td style=\"width:80%;\">\n";
-                                    echo format_text($answer->answer, FORMAT_MOODLE, $options);
-                                    echo "</td></tr>\n";
-                                    break;
-                            }
-
-                            $jumptitle = lesson_get_jump_name($answer->jumpto);
-                            if ($page->qtype == LESSON_MATCHING) {
-                                if ($i == 1) {
-                                    echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("correctanswerscore", "lesson");
-                                    echo "</span>: </td><td style=\"width:80%;\">\n";
-                                    echo "$answer->score</td></tr>\n";
-                                    echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("correctanswerjump", "lesson");
-                                    echo "</span>:</td><td style=\"width:80%;\">\n";
-                                    echo "$jumptitle</td></tr>\n";
-                                } elseif ($i == 2) {
-                                    echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("wronganswerscore", "lesson");
-                                    echo "</span>: </td><td style=\"width:80%;\">\n";
-                                    echo "$answer->score</td></tr>\n";
-                                    echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("wronganswerjump", "lesson");
-                                    echo "</span>: </td><td style=\"width:80%;\">\n";
-                                    echo "$jumptitle</td></tr>\n";
-                                }
-                            } else {
-                                if ($lesson->custom and
-                                    $page->qtype != LESSON_BRANCHTABLE and
-                                    $page->qtype != LESSON_ENDOFBRANCH and
-                                    $page->qtype != LESSON_CLUSTER and
-                                    $page->qtype != LESSON_ENDOFCLUSTER) {
-                                    echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("score", "lesson")." $i";
-                                    echo "</span>: </td><td style=\"width:80%;\">\n";
-                                    echo "$answer->score</td></tr>\n";
-                                }
-                                echo "<tr><td align=\"right\" style=\"width:20%;\"><span class=\"label\">".get_string("jump", "lesson")." $i";
-                                echo "</span>: </td><td style=\"width:80%;\">\n";
-                                echo "$jumptitle</td></tr>\n";
-                            }
-                            $i++;
-                        }
-                    }
-                    echo "</table></td></tr>\n<tr><td align=\"left\">";
-                    lesson_print_add_links($cm->id, $page->id);
-                    echo "</td></tr><tr><td>\n";
-                    // check the prev links - fix (silently) if necessary - there was a bug in
-                    // versions 1 and 2 when add new pages. Not serious then as the backwards
-                    // links were not used in those versions
-                    if ($page->prevpageid != $prevpageid) {
-                        // fix it
-                        $DB->set_field("lesson_pages", "prevpageid", $prevpageid, array("id" => $page->id));
-                        debugging("<p>***prevpageid of page $page->id set to $prevpageid***");
-                    }
-
-                    if (count($pages) == 1) {
-                        echo "</td></tr>";
-                        break;
-                    }
-
-                    $prevpageid = $page->id;
-                    $pageid = $page->nextpageid;
-                    echo "</td></tr>";
-                }
-                echo "</table>";
-                break;
-        }
+require_once('../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+try {
+    $cm = get_coursemodule_from_id('lesson', required_param('id', PARAM_INT), 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:manage', $context);
+
+$mode    = optional_param('mode', get_user_preferences('lesson_view', 'collapsed'), PARAM_ALPHA);
+$PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$cm->id,'mode'=>$mode)));
+
+if ($mode != get_user_preferences('lesson_view', 'collapsed') && $mode !== 'single') {
+    set_user_preference('lesson_view', $mode);
+}
+
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
+$PAGE->navbar->add(get_string('edit'));
+echo $lessonoutput->header($lesson, $mode);
+if (!$lesson->has_pages()) {
+    // There are no pages; give teacher some options
+    require_capability('mod/lesson:edit', $context);
+    echo $lessonoutput->add_first_page_links($lesson);
+} else {
+    switch ($mode) {
+        case 'collapsed':
+            echo $lessonoutput->display_edit_collapsed($lesson, $lesson->firstpageid);
+            break;
+        case 'single':
+            $pageid =  required_param('pageid', PARAM_INT);
+            $PAGE->url->param('pageid', $pageid);
+            $singlepage = $lesson->load_page($pageid);
+            echo $lessonoutput->display_edit_full($lesson, $singlepage->id, $singlepage->prevpageid, true);
+            break;
+        case 'full':
+            echo $lessonoutput->display_edit_full($lesson, $lesson->firstpageid, 0);
+            break;
     }
+}
 
-    echo $OUTPUT->footer();
-
+echo $lessonoutput->footer();
\ No newline at end of file
diff --git a/mod/lesson/editpage.php b/mod/lesson/editpage.php
new file mode 100644 (file)
index 0000000..b79b2aa
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Action for adding a question page.  Prints an HTML form.
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once('editpage_form.php');
+
+// first get the preceeding page
+$pageid = required_param('pageid', PARAM_INT);
+$id     = required_param('id', PARAM_INT);         // Course Module ID
+$qtype  = optional_param('qtype', 0, PARAM_INT);
+$edit   = optional_param('edit', false, PARAM_BOOL);
+
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:edit', $context);
+
+$PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('pageid'=>$pageid, 'id'=>$id, 'qtype'=>$qtype)));
+
+if ($edit) {
+    $editpage = lesson_page::load($pageid, $lesson);
+    $qtype = $editpage->qtype;
+    $edit = true;
+} else {
+    $edit = false;    
+}
+
+$jumpto = lesson_page::get_jumptooptions($pageid, $lesson);
+$manager = lesson_page_type_manager::get($lesson);
+$mform = $manager->get_page_form($qtype, array('editoroptions'=>null, 'jumpto'=>$jumpto, 'lesson'=>$lesson, 'edit'=>$edit, 'maxbytes'=>$PAGE->course->maxbytes));
+
+if ($edit) {
+    $properties = $editpage->properties();
+    $properties->pageid = $editpage->id;
+    $properties->id = $cm->id;
+    $mform->set_data($properties, $context, $editpage->id);
+    $PAGE->navbar->add(get_string('edit'), new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$id)));
+    $PAGE->navbar->add(get_string('editingquestionpage', 'lesson', get_string($mform->qtypestring, 'lesson')));
+} else {
+    // Give the page type being created a chance to override the creation process
+    // this is used by endofbranch, cluster, and endofcluster to skip the creation form.
+    // IT SHOULD ALWAYS CALL require_sesskey();
+    $mform->construction_override($pageid, $lesson);
+    
+    $defaultpage = new stdClass;
+    $defaultpage->id = $cm->id;
+    $defaultpage->pageid = $pageid;
+    $defaultpage->qtype = $qtype;
+    $defaultpage->contentsformat = FORMAT_HTML;
+    $mform->set_data($defaultpage);
+    $PAGE->navbar->add(get_string('addanewpage', 'lesson'), $PAGE->url);
+    if ($qtype !== 'unknown') {
+        $PAGE->navbar->add(get_string($mform->qtypestring, 'lesson'));
+    }
+}
+
+if ($data = $mform->get_data()) {
+    require_sesskey();
+    if ($edit) {
+        $data->lessonid = $data->id;
+        $data->id = $data->pageid;
+        unset($data->pageid);
+        unset($data->edit);
+        $editpage->update($data, $context, $PAGE->course->maxbytes);
+    } else {
+        $editpage = lesson_page::create($data, $lesson, $context, $PAGE->course->maxbytes);
+    }
+    redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$cm->id)));
+}
+
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
+echo $lessonoutput->header($lesson);
+$mform->display();
+echo $lessonoutput->footer();
\ No newline at end of file
diff --git a/mod/lesson/editpage_form.php b/mod/lesson/editpage_form.php
new file mode 100644 (file)
index 0000000..7777447
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Generic forms used for page selection
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Question selection form
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+class lesson_add_page_form_selection extends lesson_add_page_form_base {
+
+    public $qtype = 'questiontype';
+    public $qtypestring = 'selectaqtype';
+    protected $standard = false;
+    protected $manager = null;
+
+    public function __construct($arg1, $arg2) {
+        $this->manager = lesson_page_type_manager::get($arg2['lesson']);
+        parent::__construct($arg1, $arg2);
+    }
+
+    public function custom_definition() {
+        $mform = $this->_form;
+        $types = $this->manager->get_page_type_strings(lesson_page::TYPE_QUESTION);
+        asort($types);
+        $mform->addElement('select', 'qtype', get_string('selectaqtype', 'lesson'), $types);
+        $mform->setHelpButton('qtype', array('questiontypes', get_string("questiontype", "lesson"), "lesson"));
+    }
+}
+
+/**
+ * Dummy class to represent an unknown question type and direct to the selection
+ * form.
+ */
+final class lesson_add_page_form_unknown extends lesson_add_page_form_base {}
\ No newline at end of file
index 9bff13759adbc5d4dc97b82211da51d020c16b2d..45aed8c6aef9c9dcdf43bd0a313e4a6aa036c273 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Provides the interface for grading essay questions
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once('../../config.php');
-    require_once('locallib.php');
-    require_once('lib.php');
-    require_once($CFG->libdir.'/eventslib.php');
-
-    $id   = required_param('id', PARAM_INT);             // Course Module ID
-    $mode = optional_param('mode', 'display', PARAM_ALPHA);
-
-    list($cm, $course, $lesson) = lesson_get_basics($id);
-
-    require_login($course->id, false, $cm);
-
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$id));
-    if ($mode !== 'display') {
-        $url->param('mode', $mode);
-    }
-    $PAGE->set_url($url);
-    $PAGE->navbar->add(get_string('manualgrading','lesson'));
-
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-    require_capability('mod/lesson:edit', $context);
+require_once('../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once($CFG->dirroot.'/mod/lesson/essay_form.php');
+require_once($CFG->libdir.'/eventslib.php');
+
+$id   = required_param('id', PARAM_INT);             // Course Module ID
+$mode = optional_param('mode', 'display', PARAM_ALPHA);
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:edit', $context);
+
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$id));
+if ($mode !== 'display') {
+    $url->param('mode', $mode);
+}
+$PAGE->set_url($url);
+$PAGE->navbar->add(get_string('manualgrading','lesson'));
 
 /// Handle any preprocessing before header is printed - based on $mode
-    switch ($mode) {
-        case 'display':  // Default view - get the necessary data
-            // Get lesson pages that are essay
-            $params = array ("lessonid" => $lesson->id, "qtype" => LESSON_ESSAY);
-            if ($pages = $DB->get_records_select('lesson_pages', "lessonid = :lessonid AND qtype = :qtype", $params)) {
-                // Get only the attempts that are in response to essay questions
-                list($usql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
-                if ($essayattempts = $DB->get_records_select('lesson_attempts', 'pageid $usql', $parameters)) {
-                    // Get all the users who have taken this lesson, order by their last name
-                    if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
-                        $params["groupinid"] = $cm->groupingid;
-                        $sql = "SELECT DISTINCT u.*
-                                FROM {lesson_attempts} a
-                                    INNER JOIN {user} u ON u.id = a.userid
-                                    INNER JOIN {groups_members} gm ON gm.userid = u.id
-                                    INNER JOIN {groupings_groups} gg ON gm.groupid = :groupinid
-                                WHERE a.lessonid = :lessonid
-                                ORDER BY u.lastname";
-                    } else {
-                        $sql = "SELECT u.*
-                                FROM {user} u,
-                                     {lesson_attempts} a
-                                WHERE a.lessonid = :lessonid and
-                                      u.id = a.userid
-                                ORDER BY u.lastname";
-                    }
-                    if (!$users = $DB->get_records_sql($sql, $params)) {
-                        $mode = 'none'; // not displaying anything
-                        lesson_set_message(get_string('noonehasanswered', 'lesson'));
-                    }
-                } else {
-                    $mode = 'none'; // not displaying anything
-                    lesson_set_message(get_string('noonehasanswered', 'lesson'));
-                }
-            } else {
-                $mode = 'none'; // not displaying anything
-                lesson_set_message(get_string('noessayquestionsfound', 'lesson'));
+switch ($mode) {
+    case 'grade':
+        // Grading form - get the necessary data
+        require_sesskey();
+
+        $attemptid = required_param('attemptid', PARAM_INT);
+
+        if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
+            print_error('cannotfindattempt', 'lesson');
+        }
+        $page = $lesson->load_page($attempt->pageid);
+        if (!$user = $DB->get_record('user', array('id' => $attempt->userid))) {
+            print_error('cannotfinduser', 'lesson');
+        }
+        if (!$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $page->id))) {
+            print_error('cannotfindanswer', 'lesson');
+        }
+        break;
+
+    case 'update':
+        require_sesskey();
+        $mform = new essay_grading_form();
+        if ($form = $mform->get_data()) {
+
+            if (optional_param('cancel', false, PARAM_RAW)) {
+                redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
             }
-            break;
-        case 'grade':  // Grading form - get the necessary data
-            require_sesskey();
 
             $attemptid = required_param('attemptid', PARAM_INT);
-
             if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
                 print_error('cannotfindattempt', 'lesson');
             }
-            if (!$page = $DB->get_record('lesson_pages', array('id' => $attempt->pageid))) {
-                print_error('cannotfindpages', 'lesson');
+            if (!$grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1)) {
+                print_error('cannotfindgrade', 'lesson');
             }
-            if (!$user = $DB->get_record('user', array('id' => $attempt->userid))) {
-                print_error('cannotfinduser', 'lesson');
-            }
-            if (!$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $page->id))) {
-                print_error('cannotfindanswer', 'lesson');
-            }
-            break;
-        case 'update':
-            if (confirm_sesskey() and $form = data_submitted()) {
-                if (optional_param('cancel', 0, PARAM_RAW)) {
-                    redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
-                }
-
-                $attemptid = required_param('attemptid', PARAM_INT);
 
-                if (!$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid))) {
-                    print_error('cannotfindattempt', 'lesson');
-                }
-                $params = array ("lessonid" => $lesson->id, "userid" => $attempt->userid);
-                if (!$grades = $DB->get_records_select('lesson_grades', "lessonid = :lessonid and userid = :userid", $params, 'completed', '*', $attempt->retry, 1)) {
-                    print_error('cannotfindgrade', 'lesson');
-                }
+            $essayinfo = new stdClass;
+            $essayinfo = unserialize($attempt->useranswer);
 
-                $essayinfo = new stdClass;
-                $essayinfo = unserialize($attempt->useranswer);
+            $essayinfo->graded = 1;
+            $essayinfo->score = clean_param($form->score, PARAM_INT);
+            $essayinfo->response = clean_param($form->response, PARAM_RAW);
+            $essayinfo->sent = 0;
+            if (!$lesson->custom && $essayinfo->score == 1) {
+                $attempt->correct = 1;
+            } else {
+                $attempt->correct = 0;
+            }
 
-                $essayinfo->graded = 1;
-                $essayinfo->score = clean_param($form->score, PARAM_INT);
-                $essayinfo->response = clean_param($form->response, PARAM_RAW);
-                $essayinfo->sent = 0;
-                if (!$lesson->custom && $essayinfo->score == 1) {
-                    $attempt->correct = 1;
-                } else {
-                    $attempt->correct = 0;
-                }
+            $attempt->useranswer = serialize($essayinfo);
 
-                $attempt->useranswer = serialize($essayinfo);
+            $DB->update_record('lesson_attempts', $attempt);
 
-                $DB->update_record('lesson_attempts', $attempt);
+            // Get grade information
+            $grade = current($grades);
+            $gradeinfo = lesson_grade($lesson, $attempt->retry, $attempt->userid);
 
-                // Get grade information
-                $grade = current($grades);
-                $gradeinfo = lesson_grade($lesson, $attempt->retry, $attempt->userid);
+            // Set and update
+            $updategrade->id = $grade->id;
+            $updategrade->grade = $gradeinfo->grade;
+            $DB->update_record('lesson_grades', $updategrade);
+            // Log it
+            add_to_log($course->id, 'lesson', 'update grade', "essay.php?id=$cm->id", $lesson->name, $cm->id);
 
-                // Set and update
-                $updategrade->id = $grade->id;
-                $updategrade->grade = $gradeinfo->grade;
-                $DB->update_record('lesson_grades', $updategrade);
-                // Log it
-                add_to_log($course->id, 'lesson', 'update grade', "essay.php?id=$cm->id", $lesson->name, $cm->id);
+            $lesson->add_message(get_string('changessaved'), 'notifysuccess');
 
-                lesson_set_message(get_string('changessaved'), 'notifysuccess');
+            // update central gradebook
+            lesson_update_grades($lesson, $grade->userid);
 
-                // update central gradebook
-                lesson_update_grades($lesson, $grade->userid);
+            redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$cm->id)));
+        } else {
+            print_error('invalidformdata');
+        }
+        break;
+    case 'email':
+        // Sending an email(s) to a single user or all
+        require_sesskey();
 
-                redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
-            } else {
-                print_error('invalidformdata');
+        // Get our users (could be singular)
+        if ($userid = optional_param('userid', 0, PARAM_INT)) {
+            $queryadd = " AND userid = ?";
+            if (! $users = $DB->get_records('user', array('id' => $userid))) {
+                print_error('cannotfinduser', 'lesson');
             }
-            break;
-        case 'email': // Sending an email(s) to a single user or all
-            require_sesskey();
-
-            // Get our users (could be singular)
-            if ($userid = optional_param('userid', 0, PARAM_INT)) {
-                $queryadd = " AND userid = :userid";
-                if (! $users = $DB->get_records('user', array('id' => $userid))) {
-                    print_error('cannotfinduser', 'lesson');
-                }
-            } else {
-                $queryadd = '';
-                $params = array ("lessonid" => $lesson->id);
-                if (!$users = $DB->get_records_sql("SELECT u.*
-                                         FROM {user} u,
-                                              {lesson_attempts} a
-                                         WHERE a.lessonid = :lessonid and
-                                               u.id = a.userid
-                                         ORDER BY u.lastname", $params)) {
-                    print_error('cannotfinduser', 'lesson');
-                }
+        } else {
+            $queryadd = '';
+            $params = array ("lessonid" => $lesson->id);
+            if (!$users = $DB->get_records_sql("SELECT DISTINCT u.id, u.*
+                                     FROM {user} u,
+                                          {lesson_attempts} a
+                                     WHERE a.lessonid = :lessonid and
+                                           u.id = a.userid
+                                     ORDER BY u.lastname", $params)) {
+                print_error('cannotfinduser', 'lesson');
             }
+        }
 
-            // Get lesson pages that are essay
-            $params = array ("lessonid" => $lesson->id, "qtype" => LESSON_ESSAY);
-            if (!$pages = $DB->get_records_select('lesson_pages', "lessonid = :lessonid AND qtype = :qtype", $params)) {
-                print_error('cannotfindpages', 'lesson');
+        $pages = $lesson->load_all_pages();
+        foreach ($pages as $key=>$page) {
+            if ($page->qtype !== LESSON_PAGE_ESSAY) {
+                unset($pages[$key]);
             }
+        }
+
+        // Get only the attempts that are in response to essay questions
+        list($usql, $params) = $DB->get_in_or_equal(array_keys($pages));
+        if (!empty($queryadd)) {
+            $params[] = $userid;
+        }
+        if (!$attempts = $DB->get_records_select('lesson_attempts', "pageid $usql".$queryadd, $params)) {
+            print_error('nooneansweredthisquestion', 'lesson');
+        }
+        // Get the answers
+        list($answerUsql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
+        array_unshift($parameters, $lesson->id);
+        if (!$answers = $DB->get_records_select('lesson_answers', "lessonid = ? AND pageid $answerUsql", $parameters, '', 'pageid, score')) {
+            print_error('cannotfindanswer', 'lesson');
+        }
+        $options = new stdClass;
+        $options->noclean = true;
+
+        foreach ($attempts as $attempt) {
+            $essayinfo = unserialize($attempt->useranswer);
+            if ($essayinfo->graded && !$essayinfo->sent) {
+                // Holds values for the essayemailsubject string for the email message
+                $a = new stdClass;
+
+                // Set the grade
+                $grades = $DB->get_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$attempt->userid), 'completed', '*', $attempt->retry, 1);
+                $grade  = current($grades);
+                $a->newgrade = $grade->grade;
+
+                // Set the points
+                if ($lesson->custom) {
+                    $a->earned = $essayinfo->score;
+                    $a->outof  = $answers[$attempt->pageid]->score;
+                } else {
+                    $a->earned = $essayinfo->score;
+                    $a->outof  = 1;
+                }
 
-            // Get only the attempts that are in response to essay questions
-            list($usql, $params) = $DB->get_in_or_equal(array_keys($pages));
-            if (isset($queryadd) && $queryadd!='') {
-                $params["userid"] = $userid;
+                // Set rest of the message values
+                $currentpage = $lesson->load_page($attempt->pageid);
+                $a->question = format_text($currentpage->contents, FORMAT_MOODLE, $options);
+                $a->response = s($essayinfo->answer);
+                $a->comment  = s($essayinfo->response);
+
+                // Fetch message HTML and plain text formats
+                $message  = get_string('essayemailmessage2', 'lesson', $a);
+                $plaintext = format_text_email($message, FORMAT_HTML);
+
+                // Subject
+                $subject = get_string('essayemailsubject', 'lesson', format_string($pages[$attempt->pageid]->title,true));
+
+                $eventdata = new object();
+                $eventdata->modulename       = 'lesson';
+                $eventdata->userfrom         = $USER;
+                $eventdata->userto           = $users[$attempt->userid];
+                $eventdata->subject          = $subject;
+                $eventdata->fullmessage      = $plaintext;
+                $eventdata->fullmessageformat = FORMAT_PLAIN;
+                $eventdata->fullmessagehtml  = $message;
+                $eventdata->smallmessage     = '';
+
+                // Required for messaging framework
+                $eventdata->component = 'mod_lesson';
+                $eventdata->name = 'graded_essay';
+                
+                message_send($eventdata);
+                $essayinfo->sent = 1;
+                $attempt->useranswer = serialize($essayinfo);
+                $DB->update_record('lesson_attempts', $attempt);
+                // Log it
+                add_to_log($course->id, 'lesson', 'update email essay grade', "essay.php?id=$cm->id", format_string($pages[$attempt->pageid]->title,true).': '.fullname($users[$attempt->userid]), $cm->id);
             }
-            if (!$attempts = $DB->get_records_select('lesson_attempts', "pageid $usql".$queryadd, $params)) {
-                print_error('nooneansweredthisquestion', 'lesson');
+        }
+        $lesson->add_message(get_string('emailsuccess', 'lesson'), 'notifysuccess');
+        redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$cm->id)));
+        break;
+    case 'display':  // Default view - get the necessary data
+    default:
+        // Get lesson pages that are essay
+        $pages = $lesson->load_all_pages();
+        foreach ($pages as $key=>$page) {
+            if ($page->qtype !== LESSON_PAGE_ESSAY) {
+                unset($pages[$key]);
             }
-            // Get the answers
-            list($answerUsql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
-            $parameters["lessonid"] = $lesson->id;
-            if (!$answers = $DB->get_records_select('lesson_answers', "lessonid = :lessonid AND pageid $answerUsql", $parameters, '', 'pageid, score')) {
-                print_error('cannotfindanswer', 'lesson');
+        }
+        if (count($pages) > 0) {
+            $params = array ("lessonid" => $lesson->id, "qtype" => LESSON_PAGE_ESSAY);
+            // Get only the attempts that are in response to essay questions
+            list($usql, $parameters) = $DB->get_in_or_equal(array_keys($pages));
+            if ($essayattempts = $DB->get_records_select('lesson_attempts', 'pageid '.$usql, $parameters)) {
+                // Get all the users who have taken this lesson, order by their last name
+                if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
+                    $params["groupinid"] = $cm->groupingid;
+                    $sql = "SELECT DISTINCT u.*
+                            FROM {lesson_attempts} a
+                                INNER JOIN {user} u ON u.id = a.userid
+                                INNER JOIN {groups_members} gm ON gm.userid = u.id
+                                INNER JOIN {groupings_groups} gg ON gm.groupid = :groupinid
+                            WHERE a.lessonid = :lessonid
+                            ORDER BY u.lastname";
+                } else {
+                    $sql = "SELECT DISTINCT u.*
+                            FROM {user} u,
+                                 {lesson_attempts} a
+                            WHERE a.lessonid = :lessonid and
+                                  u.id = a.userid
+                            ORDER BY u.lastname";
+                }
+                if (!$users = $DB->get_records_sql($sql, $params)) {
+                    $mode = 'none'; // not displaying anything
+                    $lesson->add_message(get_string('noonehasanswered', 'lesson'));
+                }
+            } else {
+                $mode = 'none'; // not displaying anything
+                $lesson->add_message(get_string('noonehasanswered', 'lesson'));
             }
-            $options = new stdClass;
-            $options->noclean = true;
-
-            foreach ($attempts as $attempt) {
-                $essayinfo = unserialize($attempt->useranswer);
-                if ($essayinfo->graded and !$essayinfo->sent) {
-                    // Holds values for the essayemailsubject string for the email message
-                    $a = new stdClass;
-
-                    // Set the grade
-                    $params = array ("lessonid" => $lesson->id, "userid" => $attempt->userid);
-                    $grades = $DB->get_records_select('lesson_grades', "lessonid = :lessonid and userid = :userid", $params, 'completed', '*', $attempt->retry, 1);
-                    $grade  = current($grades);
-                    $a->newgrade = $grade->grade;
-
-                    // Set the points
-                    if ($lesson->custom) {
-                        $a->earned = $essayinfo->score;
-                        $a->outof  = $answers[$attempt->pageid]->score;
+        } else {
+            $mode = 'none'; // not displaying anything
+            $lesson->add_message(get_string('noessayquestionsfound', 'lesson'));
+        }
+        break;
+}
+// Log it
+add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id);
+
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
+echo $lessonoutput->header($lesson, 'essay');
+
+switch ($mode) {
+    case 'display':
+        // Expects $user, $essayattempts and $pages to be set already
+
+        // Group all the essays by userid
+        $studentessays = array();
+        foreach ($essayattempts as $essay) {
+            // Not very nice :) but basically
+            //   this organizes the essays so we know how many
+            //   times a student answered an essay per try and per page
+            $studentessays[$essay->userid][$essay->pageid][$essay->retry][] = $essay;
+        }
+
+        // Setup table
+        $table = new html_table();
+        $table->head = array(get_string('name'), get_string('essays', 'lesson'), get_string('email', 'lesson'));
+        $table->set_classes(array('standardtable', 'generaltable'));
+        $table->align = array('left', 'left', 'left');
+        $table->wrap = array('nowrap', 'nowrap', '');
+
+        // Cycle through all the students
+        foreach (array_keys($studentessays) as $userid) {
+            $studentname = fullname($users[$userid], true);
+            $essaylinks = array();
+
+            // Number of attempts on the lesson
+            $attempts = $DB->count_records('lesson_grades', array('userid'=>$userid, 'lessonid'=>$lesson->id));
+
+            // Go through each essay page
+            foreach ($studentessays[$userid] as $page => $tries) {
+                $count = 0;
+
+                // Go through each attempt per page
+                foreach($tries as $try) {
+                    if ($count == $attempts) {
+                        break;  // Stop displaying essays (attempt not completed)
+                    }
+                    $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 {
-                        $a->earned = $essayinfo->score;
-                        $a->outof  = 1;
+                        $essay = end($try);
                     }
 
-                    // Set rest of the message values
-                    $a->question = format_text($pages[$attempt->pageid]->contents, FORMAT_MOODLE, $options);
-                    $a->response = s($essayinfo->answer);
-                    $a->comment  = s($essayinfo->response);
-
-                    // Fetch message HTML and plain text formats
-                    $message  = get_string('essayemailmessage2', 'lesson', $a);
-                    $plaintxt = format_text_email($message, FORMAT_HTML);
-
-                    // Subject
-                    $subject = get_string('essayemailsubject', 'lesson', format_string($pages[$attempt->pageid]->title,true));
-
-                    $eventdata = new object();
-                    $eventdata->modulename       = 'lesson';
-                    $eventdata->userfrom         = $USER;
-                    $eventdata->userto           = $users[$attempt->userid];
-                    $eventdata->subject          = $subject;
-                    $eventdata->fullmessage      = $plaintext;
-                    $eventdata->fullmessageformat = FORMAT_PLAIN;
-                    $eventdata->fullmessagehtml  = $message;
-                    $eventdata->smallmessage     = '';
-                    message_send($eventdata);
-                    $essayinfo->sent = 1;
-                    $attempt->useranswer = serialize($essayinfo);
-                    $DB->update_record('lesson_attempts', $attempt);
-                    // Log it
-                    add_to_log($course->id, 'lesson', 'update email essay grade', "essay.php?id=$cm->id", format_string($pages[$attempt->pageid]->title,true).': '.fullname($users[$attempt->userid]), $cm->id);
+                    // Start processing the attempt
+                    $essayinfo = unserialize($essay->useranswer);
+
+                    // link for each essay
+                    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'grade','attemptid'=>$essay->id,'sesskey'=>sesskey()));
+                    $link = html_link::make($url, userdate($essay->timeseen, get_string('strftimedatetime')).' '.format_string($pages[$essay->pageid]->title,true));
+                    // Different colors for all the states of an essay (graded, if sent, not graded)
+                    if (!$essayinfo->graded) {
+                        $link->set_classes("graded");
+                    } elseif (!$essayinfo->sent) {
+                        $link->set_classes("sent");
+                    } else {
+                        $link->set_classes("ungraded");
+                    }
+                    $essaylinks[] = $OUTPUT->link($link);
                 }
             }
-            lesson_set_message(get_string('emailsuccess', 'lesson'), 'notifysuccess');
-            redirect("$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id");
-            break;
-    }
-
-    // Log it
-    add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id);
-
-    lesson_print_header($cm, $course, $lesson, 'essay');
-
-    switch ($mode) {
-        case 'display':
-            // Expects $user, $essayattempts and $pages to be set already
-
-            // Group all the essays by userid
-            $studentessays = array();
-            foreach ($essayattempts as $essay) {
-                // Not very nice :) but basically
-                //   this organizes the essays so we know how many
-                //   times a student answered an essay per try and per page
-                $studentessays[$essay->userid][$essay->pageid][$essay->retry][] = $essay;
-            }
+            // email link for this user
+            $url = new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','userid'=>$userid,'sesskey'=>sesskey()));
+            $emaillink = $OUTPUT->link(html_link::make($url, get_string('emailgradedessays', 'lesson')));
 
-            // Setup table
-            $table = new html_table();
-            $table->head = array(get_string('name'), get_string('essays', 'lesson'), get_string('email', 'lesson'));
-            $table->align = array('left', 'left', 'left');
-            $table->wrap = array('nowrap', 'nowrap', 'nowrap');
-
-            // Get the student ids of the users who have answered the essay question
-            $userids = array_keys($studentessays);
-
-            // Cycle through all the students
-            foreach ($userids as $userid) {
-                $studentname = fullname($users[$userid], true);
-                $essaylinks = array();
-
-                // Number of attempts on the lesson
-                $attempts = $DB->count_records('lesson_grades', array('userid'=>$userid, 'lessonid'=>$lesson->id));
-
-                // Go through each essay page
-                foreach ($studentessays[$userid] as $page => $tries) {
-                    $count = 0;
-
-                    // Go through each attempt per page
-                    foreach($tries as $try) {
-                        if ($count == $attempts) {
-                            break;  // Stop displaying essays (attempt not completed)
-                        }
-                        $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);
-                        }
-
-                        // Start processing the attempt
-                        $essayinfo = unserialize($essay->useranswer);
-
-                        // Different colors for all the states of an essay (graded, if sent, not graded)
-                        if (!$essayinfo->graded) {
-                            $class = ' class="graded"';
-                        } elseif (!$essayinfo->sent) {
-                            $class = ' class="sent"';
-                        } else {
-                            $class = ' class="ungraded"';
-                        }
-                        // link for each essay
-                        $essaylinks[] = "<a$class href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=grade&amp;attemptid=$essay->id&amp;sesskey=".sesskey().'">'.userdate($essay->timeseen, get_string('strftimedatetime')).' '.format_string($pages[$essay->pageid]->title,true).'</a>';
-                    }
-                }
-                // email link for this user
-                $emaillink = "<a href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=email&amp;userid=$userid&amp;sesskey=".sesskey().'">'.get_string('emailgradedessays', 'lesson').'</a>';
+            $table->data[] = array($OUTPUT->user_picture(moodle_user_picture::make($users[$userid], $course->id)).$studentname, implode("<br />", $essaylinks), $emaillink);
+        }
 
-                $table->data[] = array($OUTPUT->user_picture(moodle_user_picture::make($users[$userid], $course->id)).$studentname, implode("<br />\n", $essaylinks), $emaillink);
-            }
-            // email link for all users
-            $emailalllink = "<a href=\"$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id&amp;mode=email&amp;sesskey=".sesskey().'">'.get_string('emailallgradedessays', 'lesson').'</a>';
-
-            $table->data[] = array(' ', ' ', $emailalllink);
-
-            echo $OUTPUT->table($table);
-            break;
-        case 'grade':
-            // Grading form
-            // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
-
-            echo '<div class="grade">
-                  <form id="essaygrade" method="post" action="'.$CFG->wwwroot.'/mod/lesson/essay.php">
-                  <input type="hidden" name="id" value="'.$cm->id.'" />
-                  <input type="hidden" name="mode" value="update" />
-                  <input type="hidden" name="attemptid" value="'.$attemptid.'" />
-                  <input type="hidden" name="sesskey" value="'.sesskey().'" />';
-
-            // All tables will have these settings
-            $originaltable = new html_table();
-            $originaltable->align = array('left');
-            $originaltable->wrap = array();
-            $originaltable->width = '50%';
-            $originaltable->size = array('100%');
-            $originaltable->add_class('generaltable gradetable');
-
-            // Print the question
-            $table = clone($originaltable);
-            $table->head = array(get_string('question', 'lesson'));
-            $options = new stdClass;
-            $options->noclean = true;
-            $table->data[] = array(format_text($page->contents, FORMAT_MOODLE, $options));
-
-            echo $OUTPUT->table($table);
-
-            // Now the user's answer
-            $essayinfo = unserialize($attempt->useranswer);
+        // email link for all users
+        $url = new moodle_url($CFG->wwwroot.'/mod/lesson/essay.php', array('id'=>$cm->id,'mode'=>'email','sesskey'=>sesskey()));
+        $emailalllink = $OUTPUT->link(html_link::make($url, get_string('emailallgradedessays', 'lesson')));
 
-            $table = clone($originaltable);
-            $table = new html_table();
-            $table->head = array(get_string('studentresponse', 'lesson', fullname($user, true)));
-            $table->data[] = array(s($essayinfo->answer));
-
-            echo $OUTPUT->table($table);
-
-            // Now a response box and grade drop-down for grader
-            $table = clone($originaltable);
-            $table->head = array(get_string('comments', 'lesson'));
-            $table->data[] = array(print_textarea(false, 15, 60, 0, 0, 'response', $essayinfo->response, $course->id, true));
-            $options = array();
-            if ($lesson->custom) {
-                for ($i=$answer->score; $i>=0; $i--) {
-                    $options[$i] = $i;
-                }
-            } else {
-                $options[0] = get_string('nocredit', 'lesson');
-                $options[1] = get_string('credit', 'lesson');
-            }
-            $select = html_select::make($options, 'score', $essayinfo->score, false);
-            $select->nothingvalue = '';
-            $table->data[] = array(get_string('essayscore', 'lesson').': '.$OUTPUT->select($select));
-
-            echo $OUTPUT->table($table);
-            echo '<div class="buttons">
-                  <input type="submit" name="cancel" value="'.get_string('cancel').'" />
-                  <input type="submit" value="'.get_string('savechanges').'" />
-                  </div>
-                  </form>
-                  </div>';
-            break;
-    }
-
-    echo $OUTPUT->footer();
+        $table->data[] = array(' ', ' ', $emailalllink);
+
+        echo $OUTPUT->table($table);
+        break;
+    case 'grade':
+        // Grading form
+        // Expects the following to be set: $attemptid, $answer, $user, $page, $attempt
 
+
+        $essayinfo = unserialize($attempt->useranswer);
+        $options = array();
+        if ($lesson->custom) {
+            $i = $answer->score;
+            while ($i >= 0) {
+                $options[$i] = (string)$i;
+                $i--;
+            }
+        } else {
+            $options[0] = get_string('nocredit', 'lesson');
+            $options[1] = get_string('credit', 'lesson');
+        }
+        $mform = new essay_grading_form(null, array('scoreoptions'=>$options, 'user'=>$user));
+
+        $data = new stdClass;
+        $data->id = $cm->id;
+        $data->attemptid = $attemptid;
+        $data->score = $essayinfo->score;
+        $data->studentanswer = format_string($essayinfo->answer, FORMAT_MOODLE);
+        $data->response = $essayinfo->response;
+        $mform->set_data($data);
+
+        $mform->display();
+        break;
+}
+
+echo $OUTPUT->footer();
diff --git a/mod/lesson/essay_form.php b/mod/lesson/essay_form.php
new file mode 100644 (file)
index 0000000..93c4b9c
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Essay grading form
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Include formslib if it has not already been included
+ */
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Essay grading form
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+class essay_grading_form extends moodleform {
+
+    public function definition() {
+        $mform = $this->_form;
+
+        $mform->addElement('header', 'formheader', get_string('question', 'lesson'));
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'attemptid');
+        $mform->setType('attemptid', PARAM_INT);
+
+        $mform->addElement('hidden', 'mode', 'update');
+        $mform->setType('mode', PARAM_ALPHA);
+
+        $mform->addElement('static', 'studentanswer', get_string('studentresponse', 'lesson', fullname($this->_customdata['user'], true)));
+
+        $mform->addElement('textarea', 'response', get_string('comments', 'lesson'), array('rows'=>'15', 'cols'=>'60'));
+        $mform->setType('response', PARAM_TEXT);
+
+        $mform->addElement('select', 'score', get_string('essayscore', 'lesson'), $this->_customdata['scoreoptions']);
+        $mform->setType('score', PARAM_INT);
+
+        $this->add_action_buttons(get_string('cancel'), get_string('savechanges'));
+
+    }
+}
\ No newline at end of file
index f6647ceeeda20b22cb46c71f521e33a00031638d..35773ed69c1c0b4376c399a2f6ded087f49071cd 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * format.php  - Default format class for file imports/exports. Doesn't do
  * everything on it's own -- it needs to be extended.
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * Included by import.ph
+ *
  * @package lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Given some question info and some data about the the answers
+ * this function parses, organises and saves the question
+ *
+ * This is only used when IMPORTING questions and is only called
+ * from format.php
+ * Lifted from mod/quiz/lib.php -
+ *    1. all reference to oldanswers removed
+ *    2. all reference to quiz_multichoice table removed
+ *    3. In SHORTANSWER questions usecase is store in the qoption field
+ *    4. In NUMERIC questions store the range as two answers
+ *    5. TRUEFALSE options are ignored
+ *    6. For MULTICHOICE questions with more than one answer the qoption field is true
+ *
+ * @param opject $question Contains question data like question, type and answers.
+ * @return object Returns $result->error or $result->notice.
  **/
+function lesson_save_question_options($question, $lesson) {
+    global $DB;
+
+    // These lines are required to ensure that all page types have
+    // been loaded for the following switch
+    if (!($lesson instanceof lesson)) {
+        $lesson = new lesson($lesson);
+    }
+    $manager = lesson_page_type_manager::get($lesson);
+    
+    $timenow = time();
+    switch ($question->qtype) {
+        case LESSON_PAGE_SHORTANSWER:
+
+            $answers = array();
+            $maxfraction = -1;
+
+            // Insert all the new answers
+            foreach ($question->answer as $key => $dataanswer) {
+                if ($dataanswer != "") {
+                    $answer = new stdClass;
+                    $answer->lessonid   = $question->lessonid;
+                    $answer->pageid   = $question->id;
+                    if ($question->fraction[$key] >=0.5) {
+                        $answer->jumpto = LESSON_NEXTPAGE;
+                    }
+                    $answer->timecreated   = $timenow;
+                    $answer->grade = $question->fraction[$key] * 100;
+                    $answer->answer   = $dataanswer;
+                    $answer->response = $question->feedback[$key];
+                    $answer->id = $DB->insert_record("lesson_answers", $answer);
+                    $answers[] = $answer->id;
+                    if ($question->fraction[$key] > $maxfraction) {
+                        $maxfraction = $question->fraction[$key];
+                    }
+                }
+            }
+
+
+            /// Perform sanity checks on fractional grades
+            if ($maxfraction != 1) {
+                $maxfraction = $maxfraction * 100;
+                $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
+                return $result;
+            }
+            break;
+
+        case LESSON_PAGE_NUMERICAL:   // Note similarities to SHORTANSWER
+
+            $answers = array();
+            $maxfraction = -1;
+
+
+            // for each answer store the pair of min and max values even if they are the same
+            foreach ($question->answer as $key => $dataanswer) {
+                if ($dataanswer != "") {
+                    $answer = new stdClass;
+                    $answer->lessonid   = $question->lessonid;
+                    $answer->pageid   = $question->id;
+                    $answer->jumpto = LESSON_NEXTPAGE;
+                    $answer->timecreated   = $timenow;
+                    $answer->grade = $question->fraction[$key] * 100;
+                    $min = $question->answer[$key] - $question->tolerance[$key];
+                    $max = $question->answer[$key] + $question->tolerance[$key];
+                    $answer->answer   = $min.":".$max;
+                    // $answer->answer   = $question->min[$key].":".$question->max[$key]; original line for min/max
+                    $answer->response = $question->feedback[$key];
+                    $answer->id = $DB->insert_record("lesson_answers", $answer);
+
+                    $answers[] = $answer->id;
+                    if ($question->fraction[$key] > $maxfraction) {
+                        $maxfraction = $question->fraction[$key];
+                    }
+                }
+            }
+
+            /// Perform sanity checks on fractional grades
+            if ($maxfraction != 1) {
+                $maxfraction = $maxfraction * 100;
+                $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
+                return $result;
+            }
+        break;
+
+
+        case LESSON_PAGE_TRUEFALSE:
+
+            // the truth
+            $answer->lessonid   = $question->lessonid;
+            $answer->pageid = $question->id;
+            $answer->timecreated   = $timenow;
+            $answer->answer = get_string("true", "quiz");
+            $answer->grade = $question->answer * 100;
+            if ($answer->grade > 50 ) {
+                $answer->jumpto = LESSON_NEXTPAGE;
+            }
+            if (isset($question->feedbacktrue)) {
+                $answer->response = $question->feedbacktrue;
+            }
+            $true->id = $DB->insert_record("lesson_answers", $answer);
+
+            // the lie
+            $answer = new stdClass;
+            $answer->lessonid   = $question->lessonid;
+            $answer->pageid = $question->id;
+            $answer->timecreated   = $timenow;
+            $answer->answer = get_string("false", "quiz");
+            $answer->grade = (1 - (int)$question->answer) * 100;
+            if ($answer->grade > 50 ) {
+                $answer->jumpto = LESSON_NEXTPAGE;
+            }
+            if (isset($question->feedbackfalse)) {
+                $answer->response = $question->feedbackfalse;
+            }
+            $false->id = $DB->insert_record("lesson_answers", $answer);
+
+          break;
+
+        case LESSON_PAGE_MULTICHOICE:
+
+            $totalfraction = 0;
+            $maxfraction = -1;
+
+            $answers = array();
+
+            // Insert all the new answers
+            foreach ($question->answer as $key => $dataanswer) {
+                if ($dataanswer != "") {
+                    $answer = new stdClass;
+                    $answer->lessonid   = $question->lessonid;
+                    $answer->pageid   = $question->id;
+                    $answer->timecreated   = $timenow;
+                    $answer->grade = $question->fraction[$key] * 100;
+                    // changed some defaults
+                    /* Original Code
+                    if ($answer->grade > 50 ) {
+                        $answer->jumpto = LESSON_NEXTPAGE;
+                    }
+                    Replaced with:                    */
+                    if ($answer->grade > 50 ) {
+                        $answer->jumpto = LESSON_NEXTPAGE;
+                        $answer->score = 1;
+                    }
+                    // end Replace
+                    $answer->answer   = $dataanswer;
+                    $answer->response = $question->feedback[$key];
+                    $answer->id = $DB->insert_record("lesson_answers", $answer);
+                    // for Sanity checks
+                    if ($question->fraction[$key] > 0) {
+                        $totalfraction += $question->fraction[$key];
+                    }
+                    if ($question->fraction[$key] > $maxfraction) {
+                        $maxfraction = $question->fraction[$key];
+                    }
+                }
+            }
+
+            /// Perform sanity checks on fractional grades
+            if ($question->single) {
+                if ($maxfraction != 1) {
+                    $maxfraction = $maxfraction * 100;
+                    $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
+                    return $result;
+                }
+            } else {
+                $totalfraction = round($totalfraction,2);
+                if ($totalfraction != 1) {
+                    $totalfraction = $totalfraction * 100;
+                    $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
+                    return $result;
+                }
+            }
+        break;
+
+        case LESSON_PAGE_MATCHING:
+
+            $subquestions = array();
+
+            $defaultanswer = new stdClass;
+            $defaultanswer->lessonid   = $question->lessonid;
+            $defaultanswer->pageid   = $question->id;
+            $defaultanswer->timecreated   = $timenow;
+            $defaultanswer->grade = 0;
+
+            // The first answer should always be the correct answer
+            $correctanswer = clone($defaultanswer);
+            $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson');
+            $DB->insert_record("lesson_answers", $correctanswer);
+
+            // The second answer should always be the wrong answer
+            $wronganswer = clone($defaultanswer);
+            $wronganswer->answer = get_string('thatsthewronganswer', 'lesson');
+            $DB->insert_record("lesson_answers", $wronganswer);
+
+            $i = 0;
+            // Insert all the new question+answer pairs
+            foreach ($question->subquestions as $key => $questiontext) {
+                $answertext = $question->subanswers[$key];
+                if (!empty($questiontext) and !empty($answertext)) {
+                    $answer = clone($defaultanswer);
+                    $answer->answer = $questiontext;
+                    $answer->response   = $answertext;
+                    if ($i == 0) {
+                        // first answer contains the correct answer jump
+                        $answer->jumpto = LESSON_NEXTPAGE;
+                    }
+                    $subquestion->id = $DB->insert_record("lesson_answers", $answer);
+                    $subquestions[] = $subquestion->id;
+                    $i++;
+                }
+            }
+
+            if (count($subquestions) < 3) {
+                $result->notice = get_string("notenoughsubquestions", "quiz");
+                return $result;
+            }
+            break;
+        default:
+            $result->error = "Unsupported question type ($question->qtype)!";
+            return $result;
+    }
+    return true;
+}
 
-// Included by import.php
 
 class qformat_default {
 
     var $displayerrors = true;
     var $category = NULL;
     var $questionids = array();
-    var $qtypeconvert = array(NUMERICAL   => LESSON_NUMERICAL,
-                              MULTICHOICE => LESSON_MULTICHOICE,
-                              TRUEFALSE   => LESSON_TRUEFALSE,
-                              SHORTANSWER => LESSON_SHORTANSWER,
-                              MATCH       => LESSON_MATCHING
+    var $qtypeconvert = array(NUMERICAL   => LESSON_PAGE_NUMERICAL,
+                              MULTICHOICE => LESSON_PAGE_MULTICHOICE,
+                              TRUEFALSE   => LESSON_PAGE_TRUEFALSE,
+                              SHORTANSWER => LESSON_PAGE_SHORTANSWER,
+                              MATCH       => LESSON_PAGE_MATCHING
                               );
 
-/// Importing functions
+    // Importing functions
+    function provide_import() {
+        return false;
+    }
 
     function importpreprocess() {
-    /// Does any pre-processing that may be desired
-
+        // Does any pre-processing that may be desired
         return true;
     }
 
@@ -49,6 +310,8 @@ class qformat_default {
 
         $count = 0;
 
+        $unsupportedquestions = 0;
+
         foreach ($questions as $question) {   // Process and store each question
             switch ($question->qtype) {
                 // the good ones
@@ -124,7 +387,7 @@ class qformat_default {
 
                     $question->lessonid = $lesson->id; // needed for foreign key
                     $question->qtype = $this->qtypeconvert[$question->qtype];
-                    $result = lesson_save_question_options($question);
+                    $result = lesson_save_question_options($question, $lesson);
 
                     if (!empty($result->error)) {
                         echo $OUTPUT->notification($result->error);
@@ -138,10 +401,14 @@ class qformat_default {
                     break;
             // the Bad ones
                 default :
-                    echo $OUTPUT->notification(get_string('unsupportedqtype', 'lesson', $question->qtype));
+                    $unsupportedquestions++;
+                    break;
             }
 
         }
+        if ($unsupportedquestions) {
+            echo $OUTPUT->notification(get_string('unknownqtypesnotimported', 'lesson', $unsupportedquestions));
+        }
         return true;
     }
 
@@ -213,7 +480,7 @@ class qformat_default {
         global $CFG;
 
         $question = new stdClass();
-        $question->shuffleanswers = $CFG->quiz_shuffleanswers;
+        $question->shuffleanswers = get_config('quiz', 'shuffleanswers');
         $question->defaultgrade = 1;
         $question->image = "";
         $question->usecase = 0;
@@ -232,10 +499,9 @@ class qformat_default {
     }
 
     function importpostprocess() {
-    /// Does any post-processing that may be desired
-    /// Argument is a simple array of question ids that
-    /// have just been added.
-
+        /// Does any post-processing that may be desired
+        /// Argument is a simple array of question ids that
+        /// have just been added.
         return true;
     }
 
index 52732c93bcfc12faa9748348976b73d6b5b845a0..a100d9ccacc3f8e67fb4f6747c83fcb138f572f8 100644 (file)
@@ -1,29 +1,47 @@
 <?php
 
-    require_once("../../config.php");
-
-    $id   = required_param('id', PARAM_INT);          // Course module ID
-
-    $PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/grade.php', array('id'=>$id)));
-
-    if (! $cm = get_coursemodule_from_id('lesson', $id)) {
-        print_error('invalidcoursemodule');
-    }
-
-    if (! $lesson = $DB->get_record("lesson", array("id" => $cm->instance))) {
-        print_error('invalidlessonid', 'lesson');
-    }
-
-    if (! $course = $DB->get_record("course", array("id" => $lesson->course))) {
-        print_error('coursemisconf');
-    }
-
-    require_login($course->id, false, $cm);
-
-    if (has_capability('mod/lesson:edit', get_context_instance(CONTEXT_MODULE, $cm->id))) {
-        redirect('report.php?id='.$cm->id);
-    } else {
-        redirect('view.php?id='.$cm->id);
-    }
-
-
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Grade.php
+ *
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Require config.php
+ */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+try {
+    $cm = get_coursemodule_from_id('lesson', required_param('id', PARAM_INT), 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+
+$PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/grade.php', array('id'=>$cm->id)));
+
+if (has_capability('mod/lesson:edit', get_context_instance(CONTEXT_MODULE, $cm->id))) {
+    redirect('report.php?id='.$cm->id);
+} else {
+    redirect('view.php?id='.$cm->id);
+}
\ No newline at end of file
index 8fc2ecbe9b0191da0ef794240e0f5bc2580bed8e..31d2976f877db8b179ae0606087124eae8e73c76 100644 (file)
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Provides the interface for viewing and adding high scores
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once('../../config.php');
-    require_once('locallib.php');
-    require_once('lib.php');
-
-    $id      = required_param('id', PARAM_INT);             // Course Module ID
-    $mode    = optional_param('mode', '', PARAM_ALPHA);
-    $link = optional_param('link', 0, PARAM_INT);
-
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/highscores.php', array('id'=>$id));
-    if ($mode !== '') {
-        $url->param('mode', $mode);
-    }
-    if ($link !== 0) {
-        $url->param('link', $link);
-    }
-    $PAGE->set_url($url);
-
-    list($cm, $course, $lesson) = lesson_get_basics($id);
-
-    require_login($course->id, false, $cm);
-
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-
-    switch ($mode) {
-        case 'add':
-            // Ensure that we came from view.php
-            if (!confirm_sesskey() or !data_submitted()) {
-                print_error('invalidformdata');
+/** include required files */
+require_once('../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+$id      = required_param('id', PARAM_INT);             // Course Module ID
+$mode    = optional_param('mode', '', PARAM_ALPHA);
+$link = optional_param('link', 0, PARAM_INT);
+
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/highscores.php', array('id'=>$id));
+if ($mode !== '') {
+    $url->param('mode', $mode);
+}
+if ($link !== 0) {
+    $url->param('link', $link);
+}
+$PAGE->set_url($url);
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+switch ($mode) {
+    case 'add':
+        // Ensure that we came from view.php
+        if (!confirm_sesskey() or !data_submitted()) {
+            print_error('invalidformdata');
+        }
+        break;
+
+    case 'save':
+        if (confirm_sesskey() and $form = data_submitted($CFG->wwwroot.'/mod/lesson/view.php')) {
+            $name = trim(optional_param('name', '', PARAM_CLEAN));
+
+            // Make sure it is not empty
+            if (empty($name)) {
+                $lesson->add_message(get_string('missingname', 'lesson'));
+                $mode = 'add';
+                break;
             }
-            break;
-
-        case 'save':
-            if (confirm_sesskey() and $form = data_submitted($CFG->wwwroot.'/mod/lesson/view.php')) {
-                $name = trim(optional_param('name', '', PARAM_CLEAN));
-
-                // Make sure it is not empty
-                if (empty($name)) {
-                    lesson_set_message(get_string('missingname', 'lesson'));
+            // Check for censored words
+            $filterwords = explode(',', get_string('censorbadwords'));
+            foreach ($filterwords as $filterword) {
+                if (strstr($name, $filterword)) {
+                    $lesson->add_message(get_string('namereject', 'lesson'));
                     $mode = 'add';
                     break;
                 }
-                // Check for censored words
-                $filterwords = explode(',', get_string('censorbadwords'));
-                foreach ($filterwords as $filterword) {
-                    if (strstr($name, $filterword)) {
-                        lesson_set_message(get_string('namereject', 'lesson'));
-                        $mode = 'add';
-                        break;
-                    }
-                }
-                // Bad word was found
-                if ($mode == 'add') {
-                    break;
-                }
-                $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-                if (!$grades = $DB->get_records_select('lesson_grades', "lessonid = :lessonid", $params, 'completed')) {
-                    print_error('cannotfindfirstgrade', 'lesson');
-                }
+            }
+            // Bad word was found
+            if ($mode == 'add') {
+                break;
+            }
+            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
+            if (!$grades = $DB->get_records_select('lesson_grades', "lessonid = :lessonid", $params, 'completed')) {
+                print_error('cannotfindfirstgrade', 'lesson');
+            }
 
-                if (!$newgrade = $DB->get_record_sql("SELECT *
-                                                   FROM {lesson_grades}
-                                                  WHERE lessonid = :lessonid
-                                                    AND userid = :userid
-                                               ORDER BY completed DESC", $params, true)) {
-                    print_error('cannotfindnewestgrade', 'lesson');
-                }
+            if (!$newgrade = $DB->get_record_sql("SELECT *
+                                               FROM {lesson_grades}
+                                              WHERE lessonid = :lessonid
+                                                AND userid = :userid
+                                           ORDER BY completed DESC", $params, true)) {
+                print_error('cannotfindnewestgrade', 'lesson');
+            }
 
-                // Check for multiple submissions
-                if ($DB->record_exists('lesson_high_scores', array('gradeid' => $newgrade->id))) {
-                    print_error('onpostperpage', 'lesson');
-                }
+            // Check for multiple submissions
+            if ($DB->record_exists('lesson_high_scores', array('gradeid' => $newgrade->id))) {
+                print_error('onpostperpage', 'lesson');
+            }
 
-                // Find out if we need to delete any records
-                if ($highscores = $DB->get_records_sql("SELECT h.*, g.grade
-                                                     FROM {lesson_grades} g, {lesson_high_scores} h
-                                                    WHERE h.gradeid = g.id
-                                                    AND h.lessonid = :lessonid
-                                                    ORDER BY g.grade DESC", $params)) {
-                    // Only count unique scores in our total for max high scores
-                    $uniquescores = array();
+            // Find out if we need to delete any records
+            if ($highscores = $DB->get_records_sql("SELECT h.*, g.grade
+                                                 FROM {lesson_grades} g, {lesson_high_scores} h
+                                                WHERE h.gradeid = g.id
+                                                AND h.lessonid = :lessonid
+                                                ORDER BY g.grade DESC", $params)) {
+                // Only count unique scores in our total for max high scores
+                $uniquescores = array();
+                foreach ($highscores as $highscore) {
+                    $uniquescores[$highscore->grade] = 1;
+                }
+                if (count($uniquescores) >= $lesson->maxhighscores) {
+                    // Top scores list is full, might need to delete a score
+                    $flag = true;
+                    // See if the new score is already listed in the top scores list
+                    // if it is listed, then dont need to delete any records
                     foreach ($highscores as $highscore) {
-                        $uniquescores[$highscore->grade] = 1;
+                        if ($newgrade->grade == $highscore->grade) {
+                            $flag = false;
+                        }
                     }
-                    if (count($uniquescores) >= $lesson->maxhighscores) {
-                        // Top scores list is full, might need to delete a score
-                        $flag = true;
-                        // See if the new score is already listed in the top scores list
-                        // if it is listed, then dont need to delete any records
+                    if ($flag) {
+                        // Pushing out the lowest score (could be multiple records)
+                        $lowscore = 0;
                         foreach ($highscores as $highscore) {
-                            if ($newgrade->grade == $highscore->grade) {
-                                $flag = false;
+                            if (empty($lowscore) or $lowscore > $highscore->grade) {
+                                $lowscore = $highscore->grade;
                             }
                         }
-                        if ($flag) {
-                            // Pushing out the lowest score (could be multiple records)
-                            $lowscore = 0;
-                            foreach ($highscores as $highscore) {
-                                if (empty($lowscore) or $lowscore > $highscore->grade) {
-                                    $lowscore = $highscore->grade;
-                                }
-                            }
-                            // Now, delete all high scores with the low score
-                            foreach ($highscores as $highscore) {
-                                if ($highscore->grade == $lowscore) {
-                                    $DB->delete_records('lesson_high_scores', array('id' => $highscore->id));
-                                }
+                        // Now, delete all high scores with the low score
+                        foreach ($highscores as $highscore) {
+                            if ($highscore->grade == $lowscore) {
+                                $DB->delete_records('lesson_high_scores', array('id' => $highscore->id));
                             }
                         }
                     }
                 }
-
-                $newhighscore = new stdClass;
-                $newhighscore->lessonid = $lesson->id;
-                $newhighscore->userid = $USER->id;
-                $newhighscore->gradeid = $newgrade->id;
-                $newhighscore->nickname = $name;
-
-                $DB->insert_record('lesson_high_scores', $newhighscore);
-
-                // Log it
-                add_to_log($course->id, 'lesson', 'update highscores', "highscores.php?id=$cm->id", $name, $cm->id);
-
-                lesson_set_message(get_string('postsuccess', 'lesson'), 'notifysuccess');
-                redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id&amp;link=1");
-            } else {
-                print_error('invalidformdata');
-            }
-            break;
-    }
-
-    // Log it
-    add_to_log($course->id, 'lesson', 'view highscores', "highscores.php?id=$cm->id", $lesson->name, $cm->id);
-
-    lesson_print_header($cm, $course, $lesson, 'highscores');
-
-    switch ($mode) {
-        case 'add':
-            echo $OUTPUT->box_start('generalbox boxaligncenter');
-            echo '<div class="mdl-align">
-                 <form id="nickname" method ="post" action="'.$CFG->wwwroot.'/mod/lesson/highscores.php" autocomplete="off">
-                 <input type="hidden" name="id" value="'.$cm->id.'" />
-                 <input type="hidden" name="mode" value="save" />
-                 <input type="hidden" name="sesskey" value="'.sesskey().'" />';
-
-            echo get_string("entername", "lesson").": <input type=\"text\" name=\"name\" size=\"7\" maxlength=\"5\" />\n<p>\n";
-            lesson_print_submit_link(get_string("submitname", "lesson"), 'nickname');
-            echo "</p>\n</form>\n</div>\n";
-            echo $OUTPUT->box_end();
-            break;
-        default:
-            $params = array ("lessonid" => $lesson->id);
-            if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid", $params, "completed")) {
-                $grades = array();
             }
 
-            echo $OUTPUT->heading(get_string("topscorestitle", "lesson", $lesson->maxhighscores), 4);
-
-            if (!$highscores = $DB->get_records_select("lesson_high_scores", "lessonid = :lessonid", $params)) {
-                echo $OUTPUT->heading(get_string("nohighscores", "lesson"), 3);
-            } else {
-                foreach ($highscores as $highscore) {
-                    $grade = $grades[$highscore->gradeid]->grade;
-                    $topscores[$grade][] = $highscore->nickname;
+            $newhighscore = new stdClass;
+            $newhighscore->lessonid = $lesson->id;
+            $newhighscore->userid = $USER->id;
+            $newhighscore->gradeid = $newgrade->id;
+            $newhighscore->nickname = $name;
+
+            $DB->insert_record('lesson_high_scores', $newhighscore);
+
+            // Log it
+            add_to_log($course->id, 'lesson', 'update highscores', "highscores.php?id=$cm->id", $name, $cm->id);
+
+            $lesson->add_message(get_string('postsuccess', 'lesson'), 'notifysuccess');
+            redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id&amp;link=1");
+        } else {
+            print_error('invalidformdata');
+        }
+        break;
+}
+
+// Log it
+add_to_log($course->id, 'lesson', 'view highscores', "highscores.php?id=$cm->id", $lesson->name, $cm->id);
+
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
+echo $lessonoutput->header($lesson, 'highscores');
+
+switch ($mode) {
+    case 'add':
+        echo $lessonoutput->add_highscores_form($lesson);
+        break;
+    default:
+        $params = array ("lessonid" => $lesson->id);
+        if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid", $params, "completed")) {
+            $grades = array();
+        }
+
+        echo $OUTPUT->heading(get_string("topscorestitle", "lesson", $lesson->maxhighscores), 4);
+
+        if (!$highscores = $DB->get_records_select("lesson_high_scores", "lessonid = :lessonid", $params)) {
+            echo $OUTPUT->heading(get_string("nohighscores", "lesson"), 3);
+        } else {
+            foreach ($highscores as $highscore) {
+                $grade = $grades[$highscore->gradeid]->grade;
+                $topscores[$grade][] = $highscore->nickname;
+            }
+            krsort($topscores);
+
+            $table = new html_table();
+            $table->align = array('center', 'left', 'right');
+            $table->wrap = array();
+            $table->width = "30%";
+            $table->cellspacing = '10px';
+            $table->size = array('*', '*', '*');
+
+            $table->head = array(get_string("rank", "lesson"), get_string('name'), get_string("scores", "lesson"));
+
+            $printed = 0;
+            while (true) {
+                $temp = current($topscores);
+                $score = key($topscores);
+                $rank = $printed + 1;
+                sort($temp);
+                foreach ($temp as $student) {
+                    $table->data[] = array($rank, $student, $score.'%');
                 }
-                krsort($topscores);
-
-                $table = new html_table();
-                $table->align = array('center', 'left', 'right');
-                $table->wrap = array();
-                $table->width = "30%";
-                $table->cellspacing = '10px';
-                $table->size = array('*', '*', '*');
-
-                $table->head = array(get_string("rank", "lesson"), get_string('name'), get_string("scores", "lesson"));
-
-                $printed = 0;
-                while (true) {
-                    $temp = current($topscores);
-                    $score = key($topscores);
-                    $rank = $printed + 1;
-                    sort($temp);
-                    foreach ($temp as $student) {
-                        $table->data[] = array($rank, $student, $score.'%');
-                    }
-                    $printed++;
-                    if (!next($topscores) || !($printed < $lesson->maxhighscores)) {
-                        break;
-                    }
+                $printed++;
+                if (!next($topscores) || !($printed < $lesson->maxhighscores)) {
+                    break;
                 }
-                echo $OUTPUT->table($table);
             }
-
-            if (!has_capability('mod/lesson:manage', $context)) {  // teachers don't need the links
-                echo '<div class="mdl-align">';
-                if ($link) {
-                    echo "<br /><div class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">".get_string("returntocourse", "lesson")."</a></div>";
-                } else {
-                    echo "<br /><span class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">".get_string("cancel", "lesson").'</a></span> '.
-                        " <span class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;viewed=1\">".get_string("startlesson", "lesson").'</a></span>';
-                }
-                echo "</div>";
+            echo $OUTPUT->table($table);
+        }
+
+        if (!has_capability('mod/lesson:manage', $context)) {  // teachers don't need the links
+            echo $OUTPUT->box_start('mdl-align');
+            echo $OUTPUT->box_start('lessonbutton standardbutton');
+            if ($link) {
+                echo $OUTPUT->link(html_link::make(new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id)), get_string("returntocourse", "lesson")));
+            } else {
+                echo $OUTPUT->link(html_link::make(new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id)), get_string("cancel", "lesson"))). ' ';
+                echo $OUTPUT->link(html_link::make(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$cm->id, 'viewed'=>'1')), get_string("startlesson", "lesson")));
             }
-            break;
-    }
-
-    echo $OUTPUT->footer();
-
+            echo $OUTPUT->box_end();
+            echo $OUTPUT->box_end();
+        }
+        break;
+}
 
+echo $lessonoutput->footer();
\ No newline at end of file
index 48a3b503bf098e2f1b44044f636e81b651175855..3811f22563239e2a4682355ab758c7cbb98a506f 100644 (file)
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Imports lesson pages
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once("../../config.php");
-    require_once("lib.php");
-    require_once("locallib.php");
-    require_once($CFG->libdir.'/questionlib.php');
-
-    $id     = required_param('id', PARAM_INT);         // Course Module ID
-    $pageid = optional_param('pageid', '', PARAM_INT); // Page ID
+require_once("../../config.php");
+require_once($CFG->libdir.'/questionlib.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once($CFG->dirroot.'/mod/lesson/import_form.php');
+require_once($CFG->dirroot.'/mod/lesson/format.php');  // Parent class
 
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/import.php', array('id'=>$id));
-    if ($pageid !== '') {
-        $url->param('pageid', $pageid);
-    }
-    $PAGE->set_url($url);
+$id     = required_param('id', PARAM_INT);         // Course Module ID
+$pageid = optional_param('pageid', '', PARAM_INT); // Page ID
 
-    if (! $cm = get_coursemodule_from_id('lesson', $id)) {
-        print_error('invalidcoursemodule');
-    }
+$PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/import.php', array('id'=>$id, 'pageid'=>$pageid)));
 
-    if (! $course = $DB->get_record("course", array("id" => $cm->course))) {
-        print_error('coursemisconf');
-    }
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:edit', $context);
 
-    if (! $lesson = $DB->get_record("lesson", array("id" => $cm->instance))) {
-        print_error('invalidcoursemodule');
-    }
+$strimportquestions = get_string("importquestions", "lesson");
+$strlessons = get_string("modulenameplural", "lesson");
 
+$manager = lesson_page_type_manager::get($lesson);
 
-    require_login($course->id, false, $cm);
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    require_capability('mod/lesson:edit', $context);
+$data = new stdClass;
+$data->id = $PAGE->cm->id;
+$data->pageid = $pageid;
 
-    $strimportquestions = get_string("importquestions", "lesson");
-    $strlessons = get_string("modulenameplural", "lesson");
+$mform = new lesson_import_form(null, array('formats'=>lesson_get_import_export_formats('import')));
+$mform->set_data($data);
 
     $PAGE->navbar->add($strimportquestions);
     $PAGE->set_title($strimportquestions);
     $PAGE->set_heading($strimportquestions);
     echo $OUTPUT->header();
 
-    if ($form = data_submitted()) {   /// Filename
+$helpicon = new moodle_help_icon();
+$helpicon->text = $strimportquestions;
+$helpicon->page = "import";
+$helpicon->module = "lesson";
+echo $OUTPUT->heading_with_help($helpicon);
 
-        $form->format = clean_param($form->format, PARAM_SAFEDIR); // For safety
-
-        if (empty($_FILES['newfile'])) {      // file was just uploaded
-            echo $OUTPUT->notification(get_string("uploadproblem") );
-        }
+if ($data = $mform->get_data()) {
 
-        if ((!is_uploaded_file($_FILES['newfile']['tmp_name']) or $_FILES['newfile']['size'] == 0)) {
-            echo $OUTPUT->notification(get_string("uploadnofilefound") );
+    require_sesskey();
 
-        } else {  // Valid file is found
+    if (!$importfile = $mform->get_importfile_name()) {
+        print_error('uploadproblem', 'moodle');
+        }
 
-            if (! is_readable("$CFG->dirroot/question/format/$form->format/format.php")) {
-                print_error('unknowformat','', '', $form->format);
+    $formatclass = 'qformat_'.$data->format;
+    $formatclassfile = $CFG->dirroot.'/question/format/'.$data->format.'/format.php';
+    if (!is_readable($formatclassfile)) {
+        print_error('unknowformat','', '', $data->format);
             }
+    require_once($formatclassfile);
+    $format = new $formatclass();
 
-            require("format.php");  // Parent class
-            require("$CFG->dirroot/question/format/$form->format/format.php");
-
-            $classname = "qformat_$form->format";
-            $format = new $classname();
-
-            if (! $format->importpreprocess()) {             // Do anything before that we need to
+    // Do anything before that we need to
+    if (! $format->importpreprocess()) {
                 print_error('preprocesserror', 'lesson');
             }
 
-            if (! $format->importprocess($_FILES['newfile']['tmp_name'], $lesson, $pageid)) {    // Process the uploaded file
+    // Process the uploaded file
+    if (! $format->importprocess($importfile, $lesson, $pageid)) {
                 print_error('processerror', 'lesson');
             }
 
-            if (! $format->importpostprocess()) {                     // In case anything needs to be done after
+    // In case anything needs to be done after
+    if (! $format->importpostprocess()) {
                 print_error('postprocesserror', 'lesson');
             }
 
             echo "<hr>";
-            echo $OUTPUT->continue_button("view.php?id=$cm->id");
-            echo $OUTPUT->footer();
-            exit;
-        }
-    }
-
-    /// Print upload form
-
-    $fileformatnames = get_import_export_formats('import');
-
-    $helpicon = new moodle_help_icon();
-    $helpicon->text = $strimportquestions;
-    $helpicon->page = "import";
-    $helpicon->module = "lesson";
-
-    echo $OUTPUT->heading_with_help($helpicon);
-
-    echo $OUTPUT->box_start('generalbox boxaligncenter');
-    echo "<form enctype=\"multipart/form-data\" method=\"post\" action=\"import.php\">";
-    echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
-    echo "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />\n";
-    echo "<table cellpadding=\"5\">";
-
-    echo "<tr><td align=\"right\">";
-    print_string("fileformat", "lesson");
-    echo ":</td><td>";
-    echo $OUTPUT->select(html_select::make($fileformatnames, "format", "gift", false));
-    echo "</td></tr>";
-
-    echo "<tr><td align=\"right\">";
-    print_string("upload");
-    echo ":</td><td>";
-    echo "<input name=\"newfile\" type=\"file\" size=\"50\" />";
-    echo "</td></tr><tr><td>&nbsp;</td><td>";
-    echo "<input type=\"submit\" name=\"save\" value=\"".get_string("uploadthisfile")."\" />";
-    echo "</td></tr>";
-
-    echo "</table>";
-    echo "</form>";
-    echo $OUTPUT->box_end();
+    echo $OUTPUT->continue_button('view.php?id='.$PAGE->cm->id);
 
-    echo $OUTPUT->footer();
+} else {
 
+    // Print upload form
+    $mform->display();
+}
 
+echo $OUTPUT->footer();
\ No newline at end of file
diff --git a/mod/lesson/import_form.php b/mod/lesson/import_form.php
new file mode 100644 (file)
index 0000000..201185e
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Form used to select a file and file format for the import
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Form used to select a file and file format for the import
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class lesson_import_form extends moodleform {
+
+    public function definition() {
+
+        $mform = $this->_form;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $mform->addElement('select', 'format', get_string('fileformat', 'lesson'), $this->_customdata['formats']);
+        $mform->setDefault('format', 'gift');
+        $mform->setType('format', 'text');
+        $mform->addRule('format', null, 'required');
+
+        $mform->addElement('file', 'newfile', get_string('upload'), array('size'=>'50'));
+        $mform->addRule('newfile', null, 'required');
+
+        $this->add_action_buttons(null, get_string("uploadthisfile"));
+
+    }
+
+    public function get_importfile_name(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $_FILES['newfile']['tmp_name'];
+        }else{
+            return  NULL;
+        }
+    }
+
+    public function get_importfile_realname(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            // TODO change this to use the files API properly.
+            return $_FILES['newfile']['name'];
+        }else{
+            return  NULL;
+        }
+    }
+
+}
\ No newline at end of file
index 8e7310a2129435b699403579456350abb19b3ad4..804089cb127cf5966e93056b840c277ecfa59a13 100644 (file)
@@ -1,5 +1,20 @@
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * This is a very rough importer for powerpoint slides
  * Export a powerpoint presentation with powerpoint as html pages
  *
  * The script supports book and lesson.
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once("../../config.php");
-    require_once("locallib.php");
-
-    $id     = required_param('id', PARAM_INT);         // Course Module ID
-    $pageid = optional_param('pageid', '', PARAM_INT); // Page ID
-    global $matches;
-
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/importppt.php', array('id'=>$id));
-    if ($pageid !== '') {
-        $url->param('pageid', $pageid);
-    }
-    $PAGE->set_url($url);
-
-    if (! $cm = get_coursemodule_from_id('lesson', $id)) {
-        print_error('invalidcoursemodule');
-    }
-
-    if (! $course = $DB->get_record("course", array("id" => $cm->course))) {
-        print_error('coursemisconf');
-    }
-
-    // allows for adaption for multiple modules
-    if(! $modname = $DB->get_field('modules', 'name', array('id' => $cm->module))) {
-        print_error('invalidmoduleid', '', '', $cm->module);
-    }
-
-    if (! $mod = $DB->get_record($modname, array("id" => $cm->instance))) {
-        print_error('invalidcoursemodule');
-    }
-
-    require_login($course->id, false, $cm);
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    require_capability('mod/lesson:edit', $context);
-
-    $strimportppt = get_string("importppt", "lesson");
-    $strlessons = get_string("modulenameplural", "lesson");
-
-    $PAGE->navbar->add($strimportppt);
-    $PAGE->set_title($strimportppt);
-    $PAGE->set_heading($strimportppt);
-    echo $OUTPUT->header();
-
-    if ($form = data_submitted()) {   /// Filename
-
-        if (empty($_FILES['newfile'])) {      // file was just uploaded
-            echo $OUTPUT->notification(get_string("uploadproblem") );
-        }
-
-        if ((!is_uploaded_file($_FILES['newfile']['tmp_name']) or $_FILES['newfile']['size'] == 0)) {
-            echo $OUTPUT->notification(get_string("uploadnofilefound") );
-
-        } else {  // Valid file is found
-
-            if ($rawpages = readdata($_FILES, $course->id, $modname)) {  // first try to reall all of the data in
-                $pageobjects = extract_data($rawpages, $course->id, $mod->name, $modname); // parse all the html files into objects
-                clean_temp(); // all done with files so dump em
-
-                $mod_create_objects = $modname.'_create_objects';
-                $mod_save_objects = $modname.'_save_objects';
-
-                $objects = $mod_create_objects($pageobjects, $mod->id);  // function to preps the data to be sent to DB
-
-                if(! $mod_save_objects($objects, $mod->id, $pageid)) {  // sends it to DB
-                    print_error('cannotsavedata');
-                }
-            } else {
-                print_error('cannotgetdata');
-            }
-
-            echo "<hr>";
-            echo $OUTPUT->continue_button("$CFG->wwwroot/mod/$modname/view.php?id=$cm->id");
-            echo $OUTPUT->footer();
-            exit;
-        }
-    }
-
-    /// Print upload form
-    $helpicon = new moodle_help_icon();
-    $helpicon->text = $strimportppt;
-    $helpicon->page = "importppt";
-    $helpicon->module = "lesson";
-
-    echo $OUTPUT->heading_with_help($helpicon);
-
-    echo $OUTPUT->box_start('generalbox boxaligncenter');
-    echo "<form id=\"theform\" enctype=\"multipart/form-data\" method=\"post\">";
-    echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
-    echo "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />\n";
-    echo "<table cellpadding=\"5\">";
-
-    echo "<tr><td align=\"right\">";
-    print_string("upload");
-    echo ":</td><td>";
-    echo "<input name=\"newfile\" type=\"file\" size=\"50\" />";
-    echo "</td></tr><tr><td>&nbsp;</td><td>";
-    echo "<input type=\"submit\" name=\"save\" value=\"".get_string("uploadthisfile")."\" />";
-    echo "</td></tr>";
-
-    echo "</table>";
-    echo "</form>";
-    echo $OUTPUT->box_end();
-
-    echo $OUTPUT->footer();
-
-// START OF FUNCTIONS
-
-function readdata($file, $courseid, $modname) {
-// this function expects a zip file to be uploaded.  Then it parses
-// outline.htm to determine the slide path.  Then parses each
-// slide to get data for the content
-
-    global $CFG;
-
-    // create an upload directory in temp
-    make_upload_directory('temp/'.$modname);
-
-    $base = $CFG->dataroot."/temp/$modname/";
+/** include required files */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once($CFG->dirroot.'/mod/lesson/importpptlib.php');
 
-    $zipfile = $_FILES["newfile"]["name"];
-    $tempzipfile = $_FILES["newfile"]["tmp_name"];
+$id     = required_param('id', PARAM_INT);         // Course Module ID
+$pageid = optional_param('pageid', '', PARAM_INT); // Page ID
 
-    // create our directory
-    $path_parts = pathinfo($zipfile);
-    $dirname = substr($zipfile, 0, strpos($zipfile, '.'.$path_parts['extension'])); // take off the extension
-    if (!file_exists($base.$dirname)) {
-        mkdir($base.$dirname, $CFG->directorypermissions);
-    }
-
-    // move our uploaded file to temp/lesson
-    move_uploaded_file($tempzipfile, $base.$zipfile);
-
-    // unzip it!
-    unzip_file($base.$zipfile, $base, false);
-
-    $base = $base.$dirname;  // update the base
-
-    // this is the file where we get the names of the files for the slides (in the correct order too)
-    $outline = $base.'/outline.htm';
-
-    $pages = array();
-
-    if (file_exists($outline) and is_readable($outline)) {
-        $outlinecontents = file_get_contents($outline);
-        $filenames = array();
-        preg_match_all("/javascript:GoToSld\('(.*)'\)/", $outlinecontents, $filenames);  // this gets all of our files names
-
-        // file $pages with the contents of all of the slides
-        foreach ($filenames[1] as $file) {
-            $path = $base.'/'.$file;
-            if (is_readable($path)) {
-                $pages[$path] = file_get_contents($path);
-            } else {
-                return false;
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/importppt.php', array('id'=>$id));
+if ($pageid !== '') {
+    $url->param('pageid', $pageid);
+}
+$PAGE->set_url($url);
+
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+$modname = 'lesson';
+$mod = $cm;
+require_login($course, false, $cm);
+
+require_login($course->id, false, $cm);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:edit', $context);
+
+$strimportppt = get_string("importppt", "lesson");
+$strlessons = get_string("modulenameplural", "lesson");
+
+$data = new stdClass;
+$data->id = $cm->id;
+$data->pageid = $pageid;
+$mform = new lesson_importppt_form();
+$mform->set_data($data);
+
+if ($data = $mform->get_data()) {
+    $manager = lesson_page_type_manager::get($lesson);
+    if (!$filename = $mform->get_new_filename('pptzip')) {
+        print_error('invalidfile', 'lesson');
+    }
+    if (!$package = $mform->save_stored_file('pptzip', $context->id, 'lesson_ppt_imports', $lesson->id, '/', $filename, true)) {
+        print_error('unabletosavefile', 'lesson');
+    }
+    // extract package content
+    $packer = get_file_packer('application/zip');
+    $package->extract_to_storage($packer, $context->id, 'lesson_imported_files', $lesson->id, '/');
+    
+    $fs = get_file_storage();
+    if ($files = $fs->get_area_files($context->id, 'lesson_imported_files', $lesson->id)) {
+
+        $pages = array();
+        foreach ($files as $key=>$file) {
+            if ($file->get_mimetype() != 'text/html') {
+                continue;
             }
-        }
-    } else {
-        // cannot find the outline, so grab all files that start with slide
-        $dh  = opendir($base);
-        while (false !== ($file = readdir($dh))) {  // read throug the directory
-           if ('slide' == substr($file, 0, 5)) {  // check for name (may want to check extension later)
-                $path = $base.'/'.$file;
-                if (is_readable($path)) {
-                    $pages[$path] = file_get_contents($path);
-                } else {
-                    return false;
+            $filenameinfo = pathinfo($file->get_filepath().$file->get_filename());
+
+            $page = new stdClass;
+            $page->title = '';
+            $page->contents = array();
+            $page->images = array();
+            $page->source = $filenameinfo['basename'];
+
+            $string = strip_tags($file->get_content(),'<div><img>');
+            $imgs = array();
+            preg_match_all("/<img[^>]*(src\=\"(".$filenameinfo['filename']."\_image[^>^\"]*)\"[^>]*)>/i", $string, $imgs);
+            foreach ($imgs[2] as $img) {
+                $imagename = basename($img);
+                foreach ($files as $file) {
+                    if ($imagename === $file->get_filename()) {
+                        $page->images[] = clone($file);
+                    }
                 }
             }
-        }
-
-        ksort($pages);  // order them by file name
-    }
-
-    if (empty($pages)) {
-        return false;
-    }
-
-    return $pages;
-}
 
-function extract_data($pages, $courseid, $lessonname, $modname) {
-    // this function attempts to extract the content out of the slides
-    // the slides are ugly broken xml.  and the xml is broken... yeah...
-
-    global $CFG;
-    global $matches;
-
-    $extratedpages = array();
-
-    // directory for images
-    make_upload_directory($courseid.'/moddata/'.$modname, false);  // we store our images in a subfolder in here
-
-    $imagedir = $CFG->dataroot.'/'.$courseid.'/moddata/'.$modname;
-
-    require_once($CFG->libdir .'/filelib.php');
-    $imagelink = get_file_url($courseid.'/moddata/'.$modname);
-
-    // try to make a unique subfolder to store the images
-    $lessonname = str_replace(' ', '_', $lessonname); // get rid of spaces
-    $i = 0;
-    while(true) {
-        if (!file_exists($imagedir.'/'.$lessonname.$i)) {
-            // ok doesnt exist so make the directory and update our paths
-            mkdir($imagedir.'/'.$lessonname.$i, $CFG->directorypermissions);
-            $imagedir = $imagedir.'/'.$lessonname.$i;
-            $imagelink = $imagelink.'/'.$lessonname.$i;
-            break;
-        }
-        $i++;
-    }
-
-    foreach ($pages as $file => $content) {
-        // to make life easier on our preg_match_alls, we strip out all tags except
-        // for div and img (where our content is).  We want div because sometimes we
-        // can identify the content in the div based on the div's class
-
-        $tags = '<div><img>'; // should also allow <b><i>
-        $string = strip_tags($content,$tags);
-        //echo s($string);
-
-        $matches = array();
-        // this will look for a non nested tag that is closed
-        // want to allow <b><i>(maybe more) tags but when we do that
-        // the preg_match messes up.
-        preg_match_all("/(<([\w]+)[^>]*>)([^<\\2>]*)(<\/\\2>)/", $string, $matches);
-        //(<([\w]+)[^>]*>)([^<\\2>]*)(<\/\\2>)  original pattern
-        //(<(div+)[^>]*>)[^(<div*)](<\/div>) work in progress
-
-        $path_parts = pathinfo($file);
-        $file = substr($path_parts['basename'], 0, strpos($path_parts['basename'], '.')); // get rid of the extension
-
-        $imgs = array();
-        // this preg matches all images
-        preg_match_all("/<img[^>]*(src\=\"(".$file."\_image[^>^\"]*)\"[^>]*)>/i", $string, $imgs);
-
-        // start building our page
-        $page = new stdClass;
-        $page->title = '';
-        $page->contents = array();
-        $page->images = array();
-        $page->source = $path_parts['basename']; // need for book only
-
-        // this foreach keeps the style intact.  Found it doesn't help much.  But if you want back uncomment
-        // this foreach and uncomment the line with the comment imgstyle in it.  Also need to comment out
-        // the $page->images[]... line in the next foreach
-        /*foreach ($imgs[1] as $img) {
-            $page->images[] = '<img '.str_replace('src="', "src=\"$imagelink/", $img).' />';
-        }*/
-        foreach ($imgs[2] as $img) {
-            copy($path_parts['dirname'].'/'.$img, $imagedir.'/'.$img);
-            $page->images[] = "<img src=\"$imagelink/$img\" title=\"$img\" />";  // comment out this line if you are using the above foreach loop
-        }
-        for($i = 0; $i < count($matches[1]); $i++) { // go through all of our div matches
-
-            $class = isolate_class($matches[1][$i]); // first step in isolating the class
-
-            // check for any static classes
-            switch ($class) {
-                case 'T':  // class T is used for Titles
-                    $page->title = $matches[3][$i];
-                    break;
-                case 'B':  // I would guess that all bullet lists would start with B then go to B1, B2, etc
-                case 'B1': // B1-B4 are just insurance, should just hit B and all be taken care of
-                case 'B2':
-                case 'B3':
-                case 'B4':
-                    $page->contents[] = build_list('<ul>', $i, 0);  // this is a recursive function that will grab all the bullets and rebuild the list in html
-                    break;
-                default:
-                    if ($matches[3][$i] != '&#13;') {  // odd crap generated... sigh
-                        if (substr($matches[3][$i], 0, 1) == ':') {  // check for leading :    ... hate MS ...
-                            $page->contents[] = substr($matches[3][$i], 1);  // get rid of :
-                        } else {
-                            $page->contents[] = $matches[3][$i];
-                        }
-                    }
-                    break;
-            }
-        }
-        /*if (count($page->contents) == 0) {  // didnt find anything, grab everything
-                                            // potential to pull in a lot of crap
-            for($i = 0; $i < count($matches[1]); $i++) {
-                //if($class = isolate_class($matches[1][$i])) {
-                    //if ($class == 'O') {
+            $matches = array();
+            // this will look for a non nested tag that is closed
+            // want to allow <b><i>(maybe more) tags but when we do that
+            // the preg_match messes up.
+            preg_match_all("/(<([\w]+)[^>]*>)([^<\\2>]*)(<\/\\2>)/", $string, $matches);
+            for($i = 0; $i < count($matches[1]); $i++) { // go through all of our div matches
+
+                $class = lesson_importppt_isolate_class($matches[1][$i]); // first step in isolating the class
+
+                // check for any static classes
+                switch ($class) {
+                    case 'T':  // class T is used for Titles
+                        $page->title = $matches[3][$i];
+                        break;
+                    case 'B':  // I would guess that all bullet lists would start with B then go to B1, B2, etc
+                    case 'B1': // B1-B4 are just insurance, should just hit B and all be taken care of
+                    case 'B2':
+                    case 'B3':
+                    case 'B4':
+                        $page->contents[] = lesson_importppt_build_list($matches, '<ul>', $i, 0);  // this is a recursive function that will grab all the bullets and rebuild the list in html
+                        break;
+                    default:
                         if ($matches[3][$i] != '&#13;') {  // odd crap generated... sigh
                             if (substr($matches[3][$i], 0, 1) == ':') {  // check for leading :    ... hate MS ...
                                 $page->contents[] = substr($matches[3][$i], 1);  // get rid of :
@@ -303,292 +136,82 @@ function extract_data($pages, $courseid, $lessonname, $modname) {
                                 $page->contents[] = $matches[3][$i];
                             }
                         }
-                    //}
-                //}
-            }
-        }*/
-        // add the page to the array;
-        $extratedpages[] = $page;
-
-    } // end $pages foreach loop
-
-    return $extratedpages;
-}
-
-/**
-A recursive function to build a html list
-*/
-function build_list($list, &$i, $depth) {
-    global $matches; // not sure why I global this...
-
-    while($i < count($matches[1])) {
-
-        $class = isolate_class($matches[1][$i]);
-
-        if (strstr($class, 'B')) {  // make sure we are still working with bullet classes
-            if ($class == 'B') {
-                $this_depth = 0;  // calling class B depth 0
-            } else {
-                // set the depth number.  So B1 is depth 1 and B2 is depth 2 and so on
-                $this_depth = substr($class, 1);
-                if (!is_numeric($this_depth)) {
-                    print_error('invalidnum');
+                        break;
                 }
             }
-            if ($this_depth < $depth) {
-                // we are moving back a level in the nesting
-                break;
-            }
-            if ($this_depth > $depth) {
-                // we are moving in a lvl in nesting
-                $list .= '<ul>';
-                $list = build_list($list, $i, $this_depth);
-                // once we return back, should go to the start of the while
-                continue;
-            }
-            // no depth changes, so add the match to our list
-            if ($cleanstring = ppt_clean_text($matches[3][$i])) {
-                $list .= '<li>'.ppt_clean_text($matches[3][$i]).'</li>';
-            }
-            $i++;
-        } else {
-            // not a B class, so get out of here...
-            break;
+            $pages[] = $page;
         }
-    }
-    // end the list and return it
-    $list .= '</ul>';
-    return $list;
 
-}
+        $branchtables = lesson_create_objects($pages, $lesson->id);
 
-/**
-Given an html tag, this function will
-*/
-function isolate_class($string) {
-    if($class = strstr($string, 'class=')) { // first step in isolating the class
-        $class = substr($class, strpos($class, '=')+1);  // this gets rid of <div blawblaw class=  there are no "" or '' around the class name   ...sigh...
-        if (strstr($class, ' ')) {
-            // spaces found, so cut off everything off after the first space
-            return substr($class, 0, strpos($class, ' '));
+        // first set up the prevpageid and nextpageid
+        if (empty($pageid)) { // adding it to the top of the lesson
+            $prevpageid = 0;
+            // get the id of the first page.  If not found, then no pages in the lesson
+            if (!$nextpageid = $DB->get_field('lesson_pages', 'id', array('prevpageid' => 0, 'lessonid' => $lesson->id))) {
+                $nextpageid = 0;
+            }
         } else {
-            // no spaces so nothing else in the div tag, cut off the >
-            return substr($class, 0, strpos($class, '>'));
+            // going after an actual page
+            $prevpageid = $pageid;
+            $nextpageid = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $pageid));
         }
-    } else {
-        // no class defined in the tag
-        return '';
-    }
-}
-
-/**
-This function strips off the random chars that ppt puts infront of bullet lists
-*/
-function ppt_clean_text($string) {
-    $chop = 1; // default: just a single char infront of the content
-
-    // look for any other crazy things that may be infront of the content
-    if (strstr($string, '&lt;') and strpos($string, '&lt;') == 0) {  // look for the &lt; in the sting and make sure it is in the front
-        $chop = 4;  // increase the $chop
-    }
-    // may need to add more later....
-
-    $string = substr($string, $chop);
-
-    if ($string != '&#13;') {
-        return $string;
-    } else {
-        return false;
-    }
-}
-
-/**
-    Clean up the temp directory
-*/
-function clean_temp() {
-    global $CFG;
-    // this function is broken, use it to clean up later
-    // should only clean up what we made as well because someone else could be importing ppt as well
-    //delDirContents($CFG->dataroot.'/temp/lesson');
-}
-
-/**
-    Creates objects an object with the page and answers that are to be inserted into the database
-*/
-function lesson_create_objects($pageobjects, $lessonid) {
-
-    $branchtables = array();
-    $branchtable = new stdClass;
-
-    // all pages have this info
-    $page->lessonid = $lessonid;
-    $page->prevpageid = 0;
-    $page->nextpageid = 0;
-    $page->qtype = LESSON_BRANCHTABLE;
-    $page->qoption = 0;
-    $page->layout = 1;
-    $page->display = 1;
-    $page->timecreated = time();
-    $page->timemodified = 0;
-
-    // all answers are the same
-    $answer->lessonid = $lessonid;
-    $answer->jumpto = LESSON_NEXTPAGE;
-    $answer->grade = 0;
-    $answer->score = 0;
-    $answer->flags = 0;
-    $answer->timecreated = time();
-    $answer->timemodified = 0;
-    $answer->answer = "Next";
-    $answer->response = "";
-
-    $answers[] = clone($answer);
-
-    $answer->jumpto = LESSON_PREVIOUSPAGE;
-    $answer->answer = "Previous";
 
-    $answers[] = clone($answer);
+        foreach ($branchtables as $branchtable) {
 
-    $branchtable->answers = $answers;
+            // set the doubly linked list
+            $branchtable->page->nextpageid = $nextpageid;
+            $branchtable->page->prevpageid = $prevpageid;
 
-    $i = 1;
+            // insert the page
+            $id = $DB->insert_record('lesson_pages', $branchtable->page);
 
-    foreach ($pageobjects as $pageobject) {
-        $temp = prep_page($pageobject, $i);  // makes our title and contents
-        $page->title = $temp->title;
-        $page->contents = $temp->contents;
-        $branchtable->page = clone($page);  // add the page
-        $branchtables[] = clone($branchtable);  // add it all to our array
-        $i++;
-    }
-
-    return $branchtables;
-}
-
-/**
-    Creates objects an chapter object that is to be inserted into the database
-*/
-function book_create_objects($pageobjects, $bookid) {
-    global $DB;
-
-    $chapters = array();
-    $chapter = new stdClass;
-
-    // same for all chapters
-    $chapter->bookid = $bookid;
-    $chapter->pagenum = $DB->count_records('book_chapters', array('bookid'=>$bookid))+1;
-    $chapter->timecreated = time();
-    $chapter->timemodified = time();
-    $chapter->subchapter = 0;
-
-    $i = 1;
-    foreach ($pageobjects as $pageobject) {
-        $page = prep_page($pageobject, $i);  // get title and contents
-        $chapter->importsrc = $pageobject->source; // add the source
-        $chapter->title = $page->title;
-        $chapter->content = $page->contents;
-        $chapters[] = $chapter;
-
-        // increment our page number and our counter
-        $chapter->pagenum = $chapter->pagenum + 1;
-        $i++;
-    }
-
-    return $chapters;
-}
-
-/**
-    Builds the title and content strings from an object
-*/
-function prep_page($pageobject, $count) {
-    if ($pageobject->title == '') {
-        $page->title = "Page $count";  // no title set so make a generic one
-    } else {
-        $page->title = $pageobject->title;
-    }
-
-    $page->contents = '';
-
-    // nab all the images first
-    foreach ($pageobject->images as $image) {
-        $image = str_replace("\n", '', $image);
-        $image = str_replace("\r", '', $image);
-        $image = str_replace("'", '"', $image);  // imgstyle
-
-        $page->contents .= $image;
-    }
-    // go through the contents array and put <p> tags around each element and strip out \n which I have found to be uneccessary
-    foreach ($pageobject->contents as $content) {
-        $content = str_replace("\n", '', $content);
-        $content = str_replace("\r", '', $content);
-        $content = str_replace('&#13;', '', $content);  // puts in returns?
-        $content = '<p>'.$content.'</p>';
-        $page->contents .= $content;
-    }
-    return $page;
-}
-
-/**
-    Saves the branchtable objects to the DB
-*/
-function lesson_save_objects($branchtables, $lessonid, $after) {
-    global $DB;
-
-    // first set up the prevpageid and nextpageid
-    if ($after == 0) { // adding it to the top of the lesson
-        $prevpageid = 0;
-        // get the id of the first page.  If not found, then no pages in the lesson
-        if (!$nextpageid = $DB->get_field('lesson_pages', 'id', array('prevpageid' => 0, 'lessonid' => $lessonid))) {
-            $nextpageid = 0;
-        }
-    } else {
-        // going after an actual page
-        $prevpageid = $after;
-        $nextpageid = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $after));
-    }
-
-    foreach ($branchtables as $branchtable) {
+            if (!empty($branchtable->page->images)) {
+                $changes = array('contextid'=>$context->id, 'filearea'=>'lesson_page_contents', 'itemid'=>$id, 'timemodified'=>time());
+                foreach ($branchtable->page->images as $image) {
+                    $fs->create_file_from_storedfile($changes, $image);
+                }
+            }
 
-        // set the doubly linked list
-        $branchtable->page->nextpageid = $nextpageid;
-        $branchtable->page->prevpageid = $prevpageid;
+            // update the link of the page previous to the one we just updated
+            if ($prevpageid != 0) {  // if not the first page
+                $DB->set_field("lesson_pages", "nextpageid", $id, array("id" => $prevpageid));
+            }
 
-        // insert the page
-        $id = $DB->insert_record('lesson_pages', $branchtable->page);
+            // insert the answers
+            foreach ($branchtable->answers as $answer) {
+                $answer->pageid = $id;
+                $DB->insert_record('lesson_answers', $answer);
+            }
 
-        // update the link of the page previous to the one we just updated
-        if ($prevpageid != 0) {  // if not the first page
-            $DB->set_field("lesson_pages", "nextpageid", $id, array("id" => $prevpageid));
+            $prevpageid = $id;
         }
 
-        // insert the answers
-        foreach ($branchtable->answers as $answer) {
-            $answer->pageid = $id;
-            $DB->insert_record('lesson_answers', $answer);
+        // all done with inserts.  Now check to update our last page (this is when we import between two lesson pages)
+        if ($nextpageid != 0) {  // if the next page is not the end of lesson
+            $DB->set_field("lesson_pages", "prevpageid", $id, array("id" => $nextpageid));
         }
-
-        $prevpageid = $id;
     }
 
-    // all done with inserts.  Now check to update our last page (this is when we import between two lesson pages)
-    if ($nextpageid != 0) {  // if the next page is not the end of lesson
-        $DB->set_field("lesson_pages", "prevpageid", $id, array("id" => $nextpageid));
-    }
+    // Remove all unzipped files!
+    $fs->delete_area_files($context->id, 'lesson_imported_files', $lesson->id);
 
-    return true;
+    redirect("$CFG->wwwroot/mod/$modname/view.php?id=$cm->id", get_string('pptsuccessfullimport', 'lesson'), 5);
 }
 
-/**
-    Save the chapter objects to the database
-*/
-function book_save_objects($chapters, $bookid, $pageid='0') {
-    global $DB;
-
-    // nothing fancy, just save them all in order
-    foreach ($chapters as $chapter) {
-        $chapter->id = $DB->insert_record('book_chapters', $chapter);
-    }
-    return true;
-}
-
-
+$PAGE->navbar->add($strimportppt);
+$PAGE->set_title($strimportppt);
+$PAGE->set_heading($strimportppt);
+echo $OUTPUT->header();
+
+/// Print upload form
+$helpicon = new moodle_help_icon();
+$helpicon->text = $strimportppt;
+$helpicon->page = "importppt";
+$helpicon->module = "lesson";
+
+echo $OUTPUT->heading_with_help($helpicon);
+echo $OUTPUT->box_start('generalbox boxaligncenter');
+$mform->display();
+echo $OUTPUT->box_end();
+echo $OUTPUT->footer();
\ No newline at end of file
diff --git a/mod/lesson/importpptlib.php b/mod/lesson/importpptlib.php
new file mode 100644 (file)
index 0000000..2161dae
--- /dev/null
@@ -0,0 +1,231 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Contains functions used by importppt.php that naturally pertain to importing
+ * powerpoint presentations into the lesson module
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * A recursive function to build a html list
+ *
+ * @param array $matches
+ * @param string $list
+ * @param int $i
+ * @param int $depth
+ * @return string
+ */
+function lesson_importppt_build_list(array &$matches, $list, &$i, $depth) {
+    while($i < count($matches[1])) {
+
+        $class = lesson_importppt_isolate_class($matches[1][$i]);
+
+        if (strstr($class, 'B')) {  // make sure we are still working with bullet classes
+            if ($class == 'B') {
+                $this_depth = 0;  // calling class B depth 0
+            } else {
+                // set the depth number.  So B1 is depth 1 and B2 is depth 2 and so on
+                $this_depth = substr($class, 1);
+                if (!is_numeric($this_depth)) {
+                    print_error('invalidnum');
+                }
+            }
+            if ($this_depth < $depth) {
+                // we are moving back a level in the nesting
+                break;
+            }
+            if ($this_depth > $depth) {
+                // we are moving in a lvl in nesting
+                $list .= '<ul>';
+                $list = lesson_importppt_build_list($matches, $list, $i, $this_depth);
+                // once we return back, should go to the start of the while
+                continue;
+            }
+            // no depth changes, so add the match to our list
+            if ($cleanstring = lesson_importppt_clean_text($matches[3][$i])) {
+                $list .= '<li>'.lesson_importppt_clean_text($matches[3][$i]).'</li>';
+            }
+            $i++;
+        } else {
+            // not a B class, so get out of here...
+            break;
+        }
+    }
+    // end the list and return it
+    $list .= '</ul>';
+    return $list;
+
+}
+
+/**
+ * Given an html tag, this function will
+ *
+ * @param string $string
+ * @return string
+ */
+function lesson_importppt_isolate_class($string) {
+    if($class = strstr($string, 'class=')) { // first step in isolating the class
+        $class = substr($class, strpos($class, '=')+1);  // this gets rid of <div blawblaw class=  there are no "" or '' around the class name   ...sigh...
+        if (strstr($class, ' ')) {
+            // spaces found, so cut off everything off after the first space
+            return substr($class, 0, strpos($class, ' '));
+        } else {
+            // no spaces so nothing else in the div tag, cut off the >
+            return substr($class, 0, strpos($class, '>'));
+        }
+    } else {
+        // no class defined in the tag
+        return '';
+    }
+}
+
+/**
+ * This function strips off the random chars that ppt puts infront of bullet lists
+ *
+ * @param string $string
+ * @return string
+ */
+function lesson_importppt_clean_text($string) {
+    $chop = 1; // default: just a single char infront of the content
+
+    // look for any other crazy things that may be infront of the content
+    if (strstr($string, '&lt;') and strpos($string, '&lt;') == 0) {  // look for the &lt; in the sting and make sure it is in the front
+        $chop = 4;  // increase the $chop
+    }
+    // may need to add more later....
+
+    $string = substr($string, $chop);
+
+    if ($string != '&#13;') {
+        return $string;
+    } else {
+        return false;
+    }
+}
+
+/**
+ *  Creates objects an object with the page and answers that are to be inserted into the database
+ *
+ * @param array $pageobjects
+ * @param int $lessonid
+ * @return array
+ */
+function lesson_create_objects($pageobjects, $lessonid) {
+
+    $branchtables = array();
+    $branchtable = new stdClass;
+
+    // all pages have this info
+    $page->lessonid = $lessonid;
+    $page->prevpageid = 0;
+    $page->nextpageid = 0;
+    $page->qtype = LESSON_PAGE_BRANCHTABLE;
+    $page->qoption = 0;
+    $page->layout = 1;
+    $page->display = 1;
+    $page->timecreated = time();
+    $page->timemodified = 0;
+
+    // all answers are the same
+    $answer->lessonid = $lessonid;
+    $answer->jumpto = LESSON_NEXTPAGE;
+    $answer->grade = 0;
+    $answer->score = 0;
+    $answer->flags = 0;
+    $answer->timecreated = time();
+    $answer->timemodified = 0;
+    $answer->answer = "Next";
+    $answer->response = "";
+
+    $answers[] = clone($answer);
+
+    $answer->jumpto = LESSON_PREVIOUSPAGE;
+    $answer->answer = "Previous";
+
+    $answers[] = clone($answer);
+
+    $branchtable->answers = $answers;
+
+    $i = 1;
+
+    foreach ($pageobjects as $pageobject) {
+        if ($pageobject->title == '') {
+            $page->title = "Page $i";  // no title set so make a generic one
+        } else {
+            $page->title = $pageobject->title;
+        }
+        $page->contents = '';
+
+        // nab all the images first
+        $page->images = $pageobject->images;
+        foreach ($page->images as $image) {
+            $imagetag = '<img src="@@PLUGINFILE@@'.$image->get_filepath().$image->get_filename().'" title="'.$image->get_filename().'" />';
+            $imagetag = str_replace("\n", '', $imagetag);
+            $imagetag = str_replace("\r", '', $imagetag);
+            $imagetag = str_replace("'", '"', $imagetag);  // imgstyle
+            $page->contents .= $imagetag;
+        }
+        // go through the contents array and put <p> tags around each element and strip out \n which I have found to be uneccessary
+        foreach ($pageobject->contents as $content) {
+            $content = str_replace("\n", '', $content);
+            $content = str_replace("\r", '', $content);
+            $content = str_replace('&#13;', '', $content);  // puts in returns?
+            $content = '<p>'.$content.'</p>';
+            $page->contents .= $content;
+        }
+
+        $branchtable->page = clone($page);  // add the page
+        $branchtables[] = clone($branchtable);  // add it all to our array
+        $i++;
+    }
+
+    return $branchtables;
+}
+
+/**
+ * Form displayed to the user asking them to select a file to upload
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class lesson_importppt_form extends moodleform {
+
+    public function definition() {
+        global $COURSE;
+
+        $mform = $this->_form;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $filepickeroptions = array();
+        $filepickeroptions['filetypes'] = array('*.zip');
+        $filepickeroptions['maxbytes'] = $COURSE->maxbytes;
+        $mform->addElement('filepicker', 'pptzip', get_string('upload'), null, $filepickeroptions);
+        $mform->addRule('pptzip', null, 'required', null, 'client');
+
+        $this->add_action_buttons(null, get_string("uploadthisfile"));
+    }
+
+}
\ No newline at end of file
index d803c3b73f9517bb8be26410da32fbe00c1c79b0..86ac45f844bf6aa71c1122852fcd684f22588db3 100644 (file)
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * This page lists all the instances of lesson in a particular course
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once("../../config.php");
-    require_once($CFG->dirroot.'/mod/lesson/lib.php');
-    require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+/** Include required files */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
 
-    $id = required_param('id', PARAM_INT);   // course
+$id = required_param('id', PARAM_INT);   // course
 
-    $PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/index.php', array('id'=>$id)));
+$PAGE->set_url(new moodle_url($CFG->wwwroot.'/mod/lesson/index.php', array('id'=>$id)));
 
-    if (!$course = $DB->get_record("course", array("id" => $id))) {
-        print_error('invalidcourseid');
-    }
+if (!$course = $DB->get_record("course", array("id" => $id))) {
+    print_error('invalidcourseid');
+}
 
-    require_login($course->id);
+require_login($course);
 
-    add_to_log($course->id, "lesson", "view all", "index.php?id=$course->id", "");
+add_to_log($course->id, "lesson", "view all", "index.php?id=$course->id", "");
 
 
 /// Get all required strings
 
-    $strlessons = get_string("modulenameplural", "lesson");
-    $strlesson  = get_string("modulename", "lesson");
+$strlessons = get_string("modulenameplural", "lesson");
+$strlesson  = get_string("modulename", "lesson");
 
 
 /// Print the header
-    $PAGE->navbar->add($strlessons);
-    $PAGE->set_title("$course->shortname: $strlessons");
-    $PAGE->set_heading($course->fullname);
-    echo $OUTPUT->header();
+$PAGE->navbar->add($strlessons);
+$PAGE->set_title("$course->shortname: $strlessons");
+$PAGE->set_heading($course->fullname);
+echo $OUTPUT->header();
 
 /// Get all the appropriate data
 
-    if (! $lessons = get_all_instances_in_course("lesson", $course)) {
-        notice(get_string('thereareno', 'moodle', $strlessons), "../../course/view.php?id=$course->id");
-        die;
-    }
+if (! $lessons = get_all_instances_in_course("lesson", $course)) {
+    notice(get_string('thereareno', 'moodle', $strlessons), "../../course/view.php?id=$course->id");
+    die;
+}
 
 /// Print the list of instances (your module will probably extend this)
 
-    $timenow = time();
-    $strname  = get_string("name");
-    $strgrade  = get_string("grade");
-    $strdeadline  = get_string("deadline", "lesson");
-    $strweek  = get_string("week");
-    $strtopic  = get_string("topic");
-    $strnodeadline = get_string("nodeadline", "lesson");
-    $table = new html_table();
-
-    if ($course->format == "weeks") {
-        $table->head  = array ($strweek, $strname, $strgrade, $strdeadline);
-        $table->align = array ("center", "left", "center", "center");
-    } else if ($course->format == "topics") {
-        $table->head  = array ($strtopic, $strname, $strgrade, $strdeadline);
-        $table->align = array ("center", "left", "center", "center");
+$timenow = time();
+$strname  = get_string("name");
+$strgrade  = get_string("grade");
+$strdeadline  = get_string("deadline", "lesson");
+$strweek  = get_string("week");
+$strtopic  = get_string("topic");
+$strnodeadline = get_string("nodeadline", "lesson");
+$table = new html_table();
+
+if ($course->format == "weeks") {
+    $table->head  = array ($strweek, $strname, $strgrade, $strdeadline);
+    $table->align = array ("center", "left", "center", "center");
+} else if ($course->format == "topics") {
+    $table->head  = array ($strtopic, $strname, $strgrade, $strdeadline);
+    $table->align = array ("center", "left", "center", "center");
+} else {
+    $table->head  = array ($strname, $strgrade, $strdeadline);
+    $table->align = array ("left", "center", "center");
+}
+
+foreach ($lessons as $lesson) {
+    if (!$lesson->visible) {
+        //Show dimmed if the mod is hidden
+        $link = "<a class=\"dimmed\" href=\"view.php?id=$lesson->coursemodule\">".format_string($lesson->name,true)."</a>";
     } else {
-        $table->head  = array ($strname, $strgrade, $strdeadline);
-        $table->align = array ("left", "center", "center");
+        //Show normal if the mod is visible
+        $link = "<a href=\"view.php?id=$lesson->coursemodule\">".format_string($lesson->name,true)."</a>";
     }
+    $cm = get_coursemodule_from_instance('lesson', $lesson->id);
+    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
 
-    foreach ($lessons as $lesson) {
-        if (!$lesson->visible) {
-            //Show dimmed if the mod is hidden
-            $link = "<a class=\"dimmed\" href=\"view.php?id=$lesson->coursemodule\">".format_string($lesson->name,true)."</a>";
-        } else {
-            //Show normal if the mod is visible
-            $link = "<a href=\"view.php?id=$lesson->coursemodule\">".format_string($lesson->name,true)."</a>";
-        }
-        $cm = get_coursemodule_from_instance('lesson', $lesson->id);
-        $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+    if ($lesson->deadline == 0) {
+        $due = $strnodeadline;
+    } else if ($lesson->deadline > $timenow) {
+        $due = userdate($lesson->deadline);
+    } else {
+        $due = "<font color=\"red\">".userdate($lesson->deadline)."</font>";
+    }
 
-        if ($lesson->deadline == 0) {
-            $due = $strnodeadline;
-        } else if ($lesson->deadline > $timenow) {
-            $due = userdate($lesson->deadline);
+    if ($course->format == "weeks" or $course->format == "topics") {
+        if (has_capability('mod/lesson:manage', $context)) {
+            $grade_value = $lesson->grade;
         } else {
-            $due = "<font color=\"red\">".userdate($lesson->deadline)."</font>";
-        }
-
-        if ($course->format == "weeks" or $course->format == "topics") {
-            if (has_capability('mod/lesson:manage', $context)) {
-                $grade_value = $lesson->grade;
-            } else {
-                // it's a student, show their grade
-                $grade_value = 0;
-                if ($return = lesson_get_user_grades($lesson, $USER->id)) {
-                    $grade_value = $return[$USER->id]->rawgrade;
-                }
+            // it's a student, show their grade
+            $grade_value = 0;
+            if ($return = lesson_get_user_grades($lesson, $USER->id)) {
+                $grade_value = $return[$USER->id]->rawgrade;
             }
-            $table->data[] = array ($lesson->section, $link, $grade_value, $due);
-        } else {
-            $table->data[] = array ($link, $lesson->grade, $due);
         }
+        $table->data[] = array ($lesson->section, $link, $grade_value, $due);
+    } else {
+        $table->data[] = array ($link, $lesson->grade, $due);
     }
-
-    echo "<br />";
-
-    echo $OUTPUT->table($table);
-
-/// Finish the page
-
-    echo $OUTPUT->footer();
-
-
+}
+echo $OUTPUT->table($table);
+echo $OUTPUT->footer();
\ No newline at end of file
similarity index 88%
rename from mod/lesson/styles.php
rename to mod/lesson/lesson.css
index d175799066872b619b6d4cf402bd056b6ad2eb91..d2739a27e58ebe964b84738ba5ffc9d6ccfa6b0b 100644 (file)
@@ -6,6 +6,18 @@
     text-align: left;
 }
 
+.mod-lesson .standardtable,
+.mod-lesson .mform .box.contents {
+    text-align: left;
+    margin:1em auto;
+    width:80%;
+}
+
+.mod-lesson .compacttable {
+    margin:0px auto;
+    width:80%;
+}
+
 .mod-lesson #layout-table {
     width: 100%;
 }
@@ -21,6 +33,7 @@
 
 .mod-lesson .addlinks {
     font-size: .8em;
+    margin:5px auto;
 }
 
 .mod-lesson .userinfotable .cell,
     width: 20em;
 }
 
+.mod-lesson .edit_pages_box {
+    width:80%;
+    margin-left:10%;
+}
 
 /***
  *** Lesson Buttons
 }
 
 .mod-lesson .progress_bar_completed {
-    /*  Example Use of Image
-    background-image: url(<?php echo $CFG->wwwroot ?>/mod/lesson/completed.gif);
-    background-position: center;
-    background-repeat: repeat-x;
-    */
     background-color: green;
     padding: 0px;
     margin: 0px;
 }
 
 .mod-lesson .progress_bar_todo {
-    /*  Example Use of Image
-    background-image: url(<?php echo $CFG->wwwroot ?>/mod/lesson/todo.gif);
-    background-repeat: repeat-x;
-    background-position: center;
-    */
     background-color: red;
     text-align: left;
     padding: 0px;
 }
 
 .mod-lesson .progress_bar_token {
-    /*  Example Use of Image
-    background-image: url(<?php echo $CFG->wwwroot ?>/mod/lesson/token.gif);
-    background-repeat: repeat-none;
-    */
     background-color: #000000;
     height: 20px;
     width: 5px;
     padding: 0px;
     margin: 0px;
 }
+
+.mod-lesson .center {
+    text-align:center;
+}
+
+.mod-lesson .centerpadded {
+    text-align:center;
+    padding:5px;
+}
+
+.mod-lesson .firstpageoptions {
+    width:30%;
+    margin-left:35%;
+    margin-top:1em;
+    text-align:center;
+}
\ No newline at end of file
index 78ecdbc55d29f33f6864ee1a06bc00c86d85f2ad..bab873387737c32b256fe984614ede155e2320ba 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Handles lesson actions
  *
  * ACTIONS handled are:
- *    addbranchtable
- *    addendofbranch
- *    addcluster
- *    addendofcluster
- *    addpage
  *    confirmdelete
- *    continue
  *    delete
- *    editpage
- *    insertpage
  *    move
  *    moveit
- *    updatepage
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require("../../config.php");
-    require("locallib.php");
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
 
-    $id     = required_param('id', PARAM_INT);         // Course Module ID
-    $action = required_param('action', PARAM_ALPHA);   // Action
+$id     = required_param('id', PARAM_INT);         // Course Module ID
+$action = required_param('action', PARAM_ALPHA);   // Action
+$pageid = required_param('pageid', PARAM_INT);
 
-    list($cm, $course, $lesson) = lesson_get_basics($id);
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
 
-    require_login($course, false, $cm);
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/lesson.php', array('id'=>$id,'action'=>$action));
+$PAGE->set_url($url);
+$PAGE->navbar->add(get_string($action, 'lesson'));
 
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$id,'action'=>$action));
-    $PAGE->set_url($url);
-    $PAGE->navbar->add(get_string($action, 'lesson'));
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:edit', $context);
+require_sesskey();
 
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-/// Set up some general variables
-    $usehtmleditor = can_use_html_editor();
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
 
 /// Process the action
-    switch ($action) {
-        case 'addbranchtable':
-        case 'addpage':
-        case 'confirmdelete':
-        case 'editpage':
-        case 'move':
-            lesson_print_header($cm, $course, $lesson);
-        case 'addcluster':
-        case 'addendofbranch':
-        case 'addendofcluster':
-        case 'delete':
-        case 'insertpage':
-        case 'updatepage':
-        case 'moveit':
-            require_capability('mod/lesson:edit', $context);
-        case 'continue':
-            include($CFG->dirroot.'/mod/lesson/action/'.$action.'.php');
-            break;
-        default:
-            print_error('unknowaction');
-    }
-
-    echo $OUTPUT->footer();
+switch ($action) {
+    case 'confirmdelete':
+        $thispage = $lesson->load_page($pageid);
+
+        echo $lessonoutput->header($lesson);
+        echo $OUTPUT->heading(get_string("deletingpage", "lesson", format_string($thispage->title)));
+        // print the jumps to this page
+        $params = array("lessonid" => $lesson->id, "pageid" => $pageid);
+        if ($answers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid AND jumpto = :pageid + 1", $params)) {
+            echo $OUTPUT->heading(get_string("thefollowingpagesjumptothispage", "lesson"));
+            echo "<p align=\"center\">\n";
+            foreach ($answers as $answer) {
+                if (!$title = $DB->get_field("lesson_pages", "title", array("id" => $answer->pageid))) {
+                    print_error('cannotfindpagetitle', 'lesson');
+                }
+                echo $title."<br />\n";
+            }
+        }
+        echo $OUTPUT->confirm(get_string("confirmdeletionofthispage","lesson"),"lesson.php?action=delete&id=$cm->id&pageid=$pageid","view.php?id=$cm->id");
+
+        break;
+    case 'move':
+
+        $title = $DB->get_field("lesson_pages", "title", array("id" => $pageid));
+
+        echo $lessonoutput->header($lesson);
+        echo $OUTPUT->heading(get_string("moving", "lesson", format_string($title)));
+
+        $params = array ("lessonid" => $lesson->id, "prevpageid" => 0);
+        if (!$page = $DB->get_record_select("lesson_pages", "lessonid = :lessonid AND prevpageid = :prevpageid", $params)) {
+            print_error('cannotfindfirstpage', 'lesson');
+        }
+
+        echo "<center><table cellpadding=\"5\" border=\"1\">\n";
+        echo "<tr><td><a href=\"lesson.php?id=$cm->id&amp;sesskey=".sesskey()."&amp;action=moveit&amp;pageid=$pageid&amp;after=0\"><small>".
+            get_string("movepagehere", "lesson")."</small></a></td></tr>\n";
+        while (true) {
+            if ($page->id != $pageid) {
+                if (!$title = trim(format_string($page->title))) {
+                    $title = "<< ".get_string("notitle", "lesson")."  >>";
+                }
+                echo "<tr><td><b>$title</b></td></tr>\n";
+                echo "<tr><td><a href=\"lesson.php?id=$cm->id&amp;sesskey=".sesskey()."&amp;action=moveit&amp;pageid=$pageid&amp;after={$page->id}\"><small>".
+                    get_string("movepagehere", "lesson")."</small></a></td></tr>\n";
+            }
+            if ($page->nextpageid) {
+                if (!$page = $DB->get_record("lesson_pages", array("id" => $page->nextpageid))) {
+                    print_error('cannotfindnextpage', 'lesson');
+                }
+            } else {
+                // last page reached
+                break;
+            }
+        }
+        echo "</table>\n";
+
+        break;
+    case 'delete':
+        $thispage = $lesson->load_page($pageid);
+        $thispage->delete();
+        $lesson->add_message(get_string('deletedpage', 'lesson').': '.format_string($thispage->title, true), 'notifysuccess');
+        redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
+        break;
+    case 'moveit':
+        $after = (int)required_param('after', PARAM_INT); // target page
+
+        $pages = $lesson->load_all_pages();
+
+        if (!array_key_exists($pageid, $pages) || ($after!=0 && !array_key_exists($after, $pages))) {
+            print_error('Unable to find the page to move');
+        }
+        $pagetomove = clone($pages[$pageid]);
+        unset($pages[$pageid]);
+
+        $pageids = array();
+        if ($after === 0) {
+            $pageids['p0'] = $pageid;
+        }
+        foreach ($pages as $page) {
+            $pageids[] = $page->id;
+            if ($page->id == $after) {
+                $pageids[] = $pageid;
+            }
+        }
+
+        $pageidsref = $pageids;
+        reset($pageidsref);
+        $prev = 0;
+        $next = next($pageidsref);
+        foreach ($pageids as $pid) {
+            if ($pid === $pageid) {
+                $page = $pagetomove;
+            } else {
+                $page = $pages[$pid];
+            }
+            if ($page->prevpageid != $prev || $page->nextpageid != $next) {
+                $page->move($next, $prev);
+            }
+            $prev = $page->id;
+            $next = next($pageidsref);
+            if (!$next) {
+                $next = 0;
+            }
+        }
 
+        $lesson->add_message(get_string('movedpage', 'lesson'), 'notifysuccess');
+        redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id");
+        break;
+    default:
+        print_error('unknowaction');
+        break;
+}
 
+echo $lessonoutput->footer();
\ No newline at end of file
index 3d181f3e848565a8da4afa744e93df3eca01cf4f..29320d6d45538c05e5092ee53cdd2d770e378e54 100644 (file)
 /**
  * Standard library of functions and constants for lesson
  *
- * @package   mod-lesson
+ * @package   lesson
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-/** Include {@link eventslib.php} */
+/** Include required libraries */
 require_once($CFG->libdir.'/eventslib.php');
+require_once($CFG->libdir.'/filelib.php');
+require_once($CFG->dirroot.'/calendar/lib.php');
+require_once($CFG->dirroot.'/course/moodleform_mod.php');
 
 /** LESSON_MAX_EVENT_LENGTH = 432000 ; 5 days maximum */
 define("LESSON_MAX_EVENT_LENGTH", "432000");
@@ -40,16 +43,29 @@ define("LESSON_MAX_EVENT_LENGTH", "432000");
  * @param object $lesson Lesson post data from the form
  * @return int
  **/
-function lesson_add_instance($lesson) {
+function lesson_add_instance($data, $mform) {
     global $SESSION, $DB;
 
-    lesson_process_pre_save($lesson);
+    $cmid = $data->coursemodule;
 
-    $lesson->id = $DB->insert_record("lesson", $lesson);
+    lesson_process_pre_save($data);
 
-    lesson_process_post_save($lesson);
+    unset($data->mediafile);
+    $lessonid = $DB->insert_record("lesson", $data);
+    $data->id = $lessonid;
 
-    lesson_grade_item_update($lesson);
+    $context = get_context_instance(CONTEXT_MODULE, $cmid);
+    $lesson = $DB->get_record('lesson', array('id'=>$lessonid), '*', MUST_EXIST);
+
+    if ($filename = $mform->get_new_filename('mediafile')) {
+        if ($file = $mform->save_stored_file('mediafile', $context->id, 'lesson_media_file', $lesson->id, '/', $filename)) {
+            $DB->set_field('lesson', 'mediafile', $file->get_filename(), array('id'=>$lesson->id));
+        }
+    }
+
+    lesson_process_post_save($data);
+
+    lesson_grade_item_update($data);
 
     return $lesson->id;
 }
@@ -63,24 +79,33 @@ function lesson_add_instance($lesson) {
  * @param object $lesson Lesson post data from the form
  * @return boolean
  **/
-function lesson_update_instance($lesson) {
+function lesson_update_instance($data, $mform) {
     global $DB;
 
-    $lesson->id = $lesson->instance;
+    $data->id = $data->instance;
+    $cmid = $data->coursemodule;
 
-    lesson_process_pre_save($lesson);
+    lesson_process_pre_save($data);
 
-    if (!$result = $DB->update_record("lesson", $lesson)) {
+    unset($data->mediafile);
+    if (!$result = $DB->update_record("lesson", $data)) {
         return false; // Awe man!
     }
 
-    lesson_process_post_save($lesson);
+    $context = get_context_instance(CONTEXT_MODULE, $cmid);
+    if ($filename = $mform->get_new_filename('mediafile')) {
+        if ($file = $mform->save_stored_file('mediafile', $context->id, 'lesson_media_file', $data->id, '/', $filename, true)) {
+            $DB->set_field('lesson', 'mediafile', $file->get_filename(), array('id'=>$data->id));
+        }
+    }
+
+    lesson_process_post_save($data);
 
     // update grade item definition
-    lesson_grade_item_update($lesson);
+    lesson_grade_item_update($data);
 
     // update grades - TODO: do it only when grading style changes
-    lesson_update_grades($lesson, 0, false);
+    lesson_update_grades($data, 0, false);
 
     return $result;
 }
@@ -97,53 +122,14 @@ function lesson_update_instance($lesson) {
  */
 function lesson_delete_instance($id) {
     global $DB;
-
-    if (! $lesson = $DB->get_record("lesson", array("id"=>$id))) {
-        return false;
-    }
-
-    $result = true;
-
-    if (! $DB->delete_records("lesson", array("id"=>$lesson->id))) {
-        $result = false;
-    }
-    if (! $DB->delete_records("lesson_pages", array("lessonid"=>$lesson->id))) {
-        $result = false;
-    }
-    if (! $DB->delete_records("lesson_answers", array("lessonid"=>$lesson->id))) {
-        $result = false;
-    }
-    if (! $DB->delete_records("lesson_attempts", array("lessonid"=>$lesson->id))) {
-        $result = false;
-    }
-    if (! $DB->delete_records("lesson_grades", array("lessonid"=>$lesson->id))) {
-        $result = false;
-    }
-    if (! $DB->delete_records("lesson_timer", array("lessonid"=>$lesson->id))) {
-            $result = false;
-    }
-    if (! $DB->delete_records("lesson_branch", array("lessonid"=>$lesson->id))) {
-            $result = false;
-    }
-    if (! $DB->delete_records("lesson_high_scores", array("lessonid"=>$lesson->id))) {
-            $result = false;
-    }
-    if ($events = $DB->get_records('event', array("modulename"=>'lesson', "instance"=>$lesson->id))) {
-        foreach($events as $event) {
-            delete_event($event->id);
-        }
-    }
-
-    lesson_grade_item_delete($lesson);
-
-    return $result;
+    $lesson = $DB->get_record("lesson", array("id"=>$id), '*', MUST_EXIST);
+    $lesson = new lesson($lesson);
+    return $lesson->delete();
 }
 
 /**
  * Given a course object, this function will clean up anything that
- * would be leftover after all the instances were deleted.
- *
- * As of now, this function just cleans the lesson_default table
+ * would be leftover after all the instances were deleted
  *
  * @global object
  * @param object $course an object representing the course that is being deleted
@@ -151,16 +137,6 @@ function lesson_delete_instance($id) {
  * @return boolean
  */
 function lesson_delete_course($course, $feedback=true) {
-    global $DB, $OUTPUT;
-
-    $count = $DB->count_records('lesson_default', array('course'=>$course->id));
-    $DB->delete_records('lesson_default', array('course' => $course->id));
-
-    //Inform about changes performed if feedback is enabled
-    if ($feedback) {
-        echo $OUTPUT->notification(get_string('deletedefaults', 'lesson', $count));
-    }
-
     return true;
 }
 
@@ -527,9 +503,7 @@ function lesson_grade_item_update($lesson, $grades=NULL) {
  */
 function lesson_grade_item_delete($lesson) {
     global $CFG;
-    require_once($CFG->libdir.'/gradelib.php');
-
-    return grade_update('mod/lesson', $lesson->course, 'mod', 'lesson', $lesson->id, 0, NULL, array('deleted'=>1));
+    
 }
 
 
@@ -569,7 +543,7 @@ function lesson_get_view_actions() {
  * @return array
  */
 function lesson_get_post_actions() {
-    return array('end','start', 'update grade attempt');
+    return array('end','start');
 }
 
 /**
@@ -600,6 +574,16 @@ function lesson_process_pre_save(&$lesson) {
         $lesson->gradebetterthan = 100;
     }
 
+    if (empty($lesson->width)) {
+        $lesson->width = 640;
+    }
+    if (empty($lesson->height)) {
+        $lesson->height = 480;
+    }
+    if (empty($lesson->bgcolor)) {
+        $lesson->bgcolor = '#FFFFFF';
+    }
+
     // Conditions for dependency
     $conditions = new stdClass;
     $conditions->timespent = $lesson->timespent;
@@ -613,21 +597,6 @@ function lesson_process_pre_save(&$lesson) {
     if (empty($lesson->password)) {
         unset($lesson->password);
     }
-
-    if ($lesson->lessondefault) {
-        $default = new stdClass;
-        $default = clone($lesson);
-        unset($default->name);
-        unset($default->timemodified);
-        unset($default->available);
-        unset($default->deadline);
-        if ($default->id = $DB->get_field('lesson_default', 'id', array('course' => $default->course))) {
-            $DB->update_record('lesson_default', $default);
-        } else {
-            $DB->insert_record('lesson_default', $default);
-        }
-    }
-    unset($lesson->lessondefault);
 }
 
 /**
@@ -643,7 +612,8 @@ function lesson_process_post_save(&$lesson) {
 
     if ($events = $DB->get_records('event', array('modulename'=>'lesson', 'instance'=>$lesson->id))) {
         foreach($events as $event) {
-            delete_event($event->id);
+            $event = calendar_event::load($event->id);
+            $event->delete();
         }
     }
 
@@ -664,20 +634,18 @@ function lesson_process_post_save(&$lesson) {
     if ($lesson->deadline and $lesson->available and $event->timeduration <= LESSON_MAX_EVENT_LENGTH) {
         // Single event for the whole lesson.
         $event->name = $lesson->name;
-        add_event($event);
+        calendar_event::create(clone($event));
     } else {
         // Separate start and end events.
         $event->timeduration  = 0;
         if ($lesson->available) {
             $event->name = $lesson->name.' ('.get_string('lessonopens', 'lesson').')';
-            add_event($event);
-            unset($event->id); // So we can use the same object for the close event.
-        }
-        if ($lesson->deadline) {
+            calendar_event::create(clone($event));
+        } else if ($lesson->deadline) {
             $event->name      = $lesson->name.' ('.get_string('lessoncloses', 'lesson').')';
             $event->timestart = $lesson->deadline;
             $event->eventtype = 'close';
-            add_event($event);
+            calendar_event::create(clone($event));
         }
     }
 }
@@ -802,7 +770,7 @@ function lesson_supports($feature) {
 }
 
 /**
- * This fucntion extends the global navigaiton for the site.
+ * This function extends the global navigaiton for the site.
  * It is important to note that you should not rely on PAGE objects within this
  * body of code as there is no guarantee that during an AJAX request they are
  * available
@@ -838,6 +806,10 @@ function lesson_extend_settings_navigation($settings, $module) {
     $lessonnav = $settings->get($lessonnavkey);
     $lessonnav->forceopen = true;
 
+    if (empty($PAGE->cm->context)) {
+        $PAGE->cm->context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->instance);
+    }
+
     $canedit = has_capability('mod/lesson:edit', $PAGE->cm->context);
 
     $url = new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id));
@@ -875,3 +847,2274 @@ function lesson_extend_settings_navigation($settings, $module) {
         $settings->remove_child($lessonnavkey);
     }
 }
+
+/**
+ * Get list of available import or export formats
+ *
+ * Copied and modified from lib/questionlib.php
+ *
+ * @param string $type 'import' if import list, otherwise export list assumed
+ * @return array sorted list of import/export formats available
+ */
+function lesson_get_import_export_formats($type) {
+    global $CFG;
+    $fileformats = get_plugin_list("qformat");
+
+    $fileformatname=array();
+    foreach ($fileformats as $fileformat=>$fdir) {
+        $format_file = "$fdir/format.php";
+        if (file_exists($format_file) ) {
+            require_once($format_file);
+        } else {
+            continue;
+        }
+        $classname = "qformat_$fileformat";
+        $format_class = new $classname();
+        if ($type=='import') {
+            $provided = $format_class->provide_import();
+        } else {
+            $provided = $format_class->provide_export();
+        }
+        if ($provided) {
+            $formatname = get_string($fileformat, 'quiz');
+            if ($formatname == "[[$fileformat]]") {
+                $formatname = get_string($fileformat, 'qformat_'.$fileformat);
+                if ($formatname == "[[$fileformat]]") {
+                    $formatname = $fileformat;  // Just use the raw folder name
+                }
+            }
+            $fileformatnames[$fileformat] = $formatname;
+        }
+    }
+    natcasesort($fileformatnames);
+
+    return $fileformatnames;
+}
+
+/**
+ * Serves the lesson attachments. Implements needed access control ;-)
+ *
+ * @param object $course
+ * @param object $cminfo
+ * @param object $context
+ * @param string $filearea
+ * @param array $args
+ * @param bool $forcedownload
+ * @return bool false if file not found, does not return if found - justsend the file
+ */
+function lesson_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
+    global $CFG, $DB;
+
+    if (!$cminfo->uservisible) {
+        return false;
+    }
+    
+    $fileareas = lesson_get_file_areas();
+    if (!array_key_exists($filearea, $fileareas)) {
+        return false;
+    }
+
+    if (!$cm = get_coursemodule_from_instance('lesson', $cminfo->instance, $course->id)) {
+        return false;
+    }
+
+    if (!$lesson = $DB->get_record('lesson', array('id'=>$cminfo->instance))) {
+        return false;
+    }
+
+    require_course_login($course, true, $cm);
+
+    if ($filearea === 'lesson_page_content') {
+        $pageid = (int)array_shift($args);
+        if (!$page = $DB->get_record('lesson_pages', array('id'=>$pageid))) {
+            return false;
+        }
+        $fullpath = $context->id.$filearea.$pageid.'/'.implode('/', $args);
+        $forcedownload = true;
+    } else {
+        $fullpath = $context->id.$filearea.implode('/', $args);
+    }
+
+    $fs = get_file_storage();
+    if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
+        return false;
+    }
+
+    // finally send the file
+    send_stored_file($file, 0, 0, $forcedownload); // download MUST be forced - security!
+}
+
+/**
+ * Returns an array of file areas
+ * @return array
+ */
+function lesson_get_file_areas() {
+    return array('lesson_page_contents'=>'lesson_page_contents', 'lesson_media_file'=>'lesson_media_file');
+}
+
+/**
+ * Returns a file_info_stored object for the file being requested here
+ *
+ * @global <type> $CFG
+ * @param file_browse $browser
+ * @param array $areas
+ * @param object $course
+ * @param object $cm
+ * @param object $context
+ * @param string $filearea
+ * @param int $itemid
+ * @param string $filepath
+ * @param string $filename
+ * @return file_info_stored
+ */
+function lesson_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
+    global $CFG;
+    $fs = get_file_storage();
+    $filepath = is_null($filepath) ? '/' : $filepath;
+    $filename = is_null($filename) ? '.' : $filename;
+    $urlbase = $CFG->wwwroot.'/pluginfile.php';
+    if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) {
+        return null;
+    }
+    return new file_info_stored($browser, $context, $storedfile, $urlbase, $filearea, $itemid, true, true, false);
+}
+
+/**
+ * This is a function used to detect media types and generate html code.
+ *
+ * @global object $CFG
+ * @global object $PAGE
+ * @param object $lesson
+ * @param object $context
+ * @return string $code the html code of media
+ */
+function lesson_get_media_html($lesson, $context) {
+    global $CFG, $PAGE, $OUTPUT;
+
+    // get the media file from file pool
+    $browser = get_file_browser();
+    $file_info  = $browser->get_file_info($context, 'lesson_media_file', $lesson->id, '/', $lesson->mediafile);
+    $url = $file_info->get_url();
+    $title = $lesson->mediafile;
+
+    $clicktoopen = $OUTPUT->link(new moodle_url($url), get_string('download'));
+
+    $mimetype = resourcelib_guess_url_mimetype($url);
+
+    // find the correct type and print it out
+    if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) {  // It's an image
+        $code = resourcelib_embed_image($url, $title);
+
+    } else if ($mimetype == 'audio/mp3') {
+        // MP3 audio file
+        $code = resourcelib_embed_mp3($url, $title, $clicktoopen);
+
+    } else if ($mimetype == 'video/x-flv') {
+        // Flash video file
+        $code = resourcelib_embed_flashvideo($url, $title, $clicktoopen);
+
+    } else if ($mimetype == 'application/x-shockwave-flash') {
+        // Flash file
+        $code = resourcelib_embed_flash($url, $title, $clicktoopen);
+
+    } else if (substr($mimetype, 0, 10) == 'video/x-ms') {
+        // Windows Media Player file
+        $code = resourcelib_embed_mediaplayer($url, $title, $clicktoopen);
+
+    } else if ($mimetype == 'video/quicktime') {
+        // Quicktime file
+        $code = resourcelib_embed_quicktime($url, $title, $clicktoopen);
+
+    } else if ($mimetype == 'video/mpeg') {
+        // Mpeg file
+        $code = resourcelib_embed_mpeg($url, $title, $clicktoopen);
+
+    } else if ($mimetype == 'audio/x-pn-realaudio-plugin') {
+        // RealMedia file
+        $code = resourcelib_embed_real($url, $title, $clicktoopen);
+
+    } else {
+        // anything else - just try object tag enlarged as much as possible
+        $code = resourcelib_embed_general($url, $title, $clicktoopen, $mimetype);
+        $PAGE->requires->yui_lib('dom');
+        $PAGE->requires->js('mod/url/functions.js');
+        $PAGE->requires->js_function_call('imscp_setup_object')->on_dom_ready();
+    }
+
+    return $code;
+}
+
+/**
+ * Abstract class to provide a core functions to the all lesson classes
+ *
+ * This class should be abstracted by ALL classes with the lesson module to ensure
+ * that all classes within this module can be interacted with in the same way.
+ *
+ * This class provides the user with a basic properties array that can be fetched
+ * or set via magic methods, or alternativily by defining methods get_blah() or
+ * set_blah() within the extending object.
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class lesson_base {
+
+    /**
+     * An object containing properties
+     * @var stdClass
+     */
+    protected $properties;
+
+    /**
+     * The constructor
+     * @param stdClass $properties
+     */
+    public function __construct($properties) {
+        $this->properties = (object)$properties;
+    }
+
+    /**
+     * Magic property method
+     *
+     * Attempts to call a set_$key method if one exists otherwise falls back
+     * to simply set the property
+     *
+     * @param string $key
+     * @param mixed $value
+     */
+    public function __set($key, $value) {
+        if (method_exists($this, 'set_'.$key)) {
+            $this->{'set_'.$key}($value);
+        }
+        $this->properties->{$key} = $value;
+    }
+
+    /**
+     * Magic get method
+     *
+     * Attempts to call a get_$key method to return the property and ralls over
+     * to return the raw property
+     *
+     * @param str $key
+     * @return mixed
+     */
+    public function __get($key) {
+        if (method_exists($this, 'get_'.$key)) {
+            return $this->{'get_'.$key}();
+        }
+        return $this->properties->{$key};
+    }
+
+    /**
+     * Stupid PHP needs an isset magic method if you use the get magic method and
+     * still want empty calls to work.... blah ~!
+     *
+     * @param string $key
+     * @return bool
+     */
+    public function __isset($key) {
+        if (method_exists($this, 'get_'.$key)) {
+            $val = $this->{'get_'.$key}();
+            return !empty($val);
+        }
+        return !empty($this->properties->{$key});
+    }
+
+    /**
+     * If overriden should create a new instance, save it in the DB and return it
+     */
+    public static function create() {}
+    /**
+     * If overriden should load an instance from the DB and return it
+     */
+    public static function load() {}
+    /**
+     * Fetches all of the properties of the object
+     * @return stdClass
+     */
+    public function properties() {
+        return $this->properties;
+    }
+}
+
+/**
+ * Class representation of a lesson
+ *
+ * This class is used the interact with, and manage a lesson once instantiated.
+ * If you need to fetch a lesson object you can do so by calling
+ *
+ * <code>
+ * lesson::load($lessonid);
+ * // or
+ * $lessonrecord = $DB->get_record('lesson', $lessonid);
+ * $lesson = new lesson($lessonrecord);
+ * </code>
+ *
+ * The class itself extends lesson_base as all classes within the lesson module should
+ *
+ * These properties are from the database
+ * @property int $id The id of this lesson
+ * @property int $course The ID of the course this lesson belongs to
+ * @property string $name The name of this lesson
+ * @property int $practice Flag to toggle this as a practice lesson
+ * @property int $modattempts Toggle to allow the user to go back and review answers
+ * @property int $usepassword Toggle the use of a password for entry
+ * @property string $password The password to require users to enter
+ * @property int $dependency ID of another lesson this lesson is dependant on
+ * @property string $conditions Conditions of the lesson dependency
+ * @property int $grade The maximum grade a user can achieve (%)
+ * @property int $custom Toggle custom scoring on or off
+ * @property int $ongoing Toggle display of an ongoing score
+ * @property int $usemaxgrade How retakes are handled (max=1, mean=0)
+ * @property int $maxanswers The max number of answers or branches
+ * @property int $maxattempts The maximum number of attempts a user can record
+ * @property int $review Toggle use or wrong answer review button
+ * @property int $nextpagedefault Override the default next page
+ * @property int $feedback Toggles display of default feedback
+ * @property int $minquestions Sets a minimum value of pages seen when calculating grades
+ * @property int $maxpages Maximum number of pages this lesson can contain
+ * @property int $retake Flag to allow users to retake a lesson
+ * @property int $activitylink Relate this lesson to another lesson
+ * @property string $mediafile File to pop up to or webpage to display
+ * @property int $mediaheight Sets the height of the media file popup
+ * @property int $mediawidth Sets the width of the media file popup
+ * @property int $mediaclose Toggle display of a media close button
+ * @property int $slideshow Flag for whether branch pages should be shown as slideshows
+ * @property int $width Width of slideshow
+ * @property int $height Height of slideshow
+ * @property string $bgcolor Background colour of slideshow
+ * @property int $displayleft Display a left meun
+ * @property int $displayleftif Sets the condition on which the left menu is displayed
+ * @property int $progressbar Flag to toggle display of a lesson progress bar
+ * @property int $highscores Flag to toggle collection of high scores
+ * @property int $maxhighscores Number of high scores to limit to
+ * @property int $available Timestamp of when this lesson becomes available
+ * @property int $deadline Timestamp of when this lesson is no longer available
+ * @property int $timemodified Timestamp when lesson was last modified
+ *
+ * These properties are calculated
+ * @property int $firstpageid Id of the first page of this lesson (prevpageid=0)
+ * @property int $lastpageid Id of the last page of this lesson (nextpageid=0)
+ * 
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class lesson extends lesson_base {
+
+    /**
+     * The id of the first page (where prevpageid = 0) gets set and retrieved by
+     * {@see get_firstpageid()} by directly calling <code>$lesson->firstpageid;</code>
+     * @var int
+     */
+    protected $firstpageid = null;
+    /**
+     * The id of the last page (where nextpageid = 0) gets set and retrieved by
+     * {@see get_lastpageid()} by directly calling <code>$lesson->lastpageid;</code>
+     * @var int
+     */
+    protected $lastpageid = null;
+    /**
+     * An array used to cache the pages associated with this lesson after the first
+     * time they have been loaded.
+     * A note to developers: If you are going to be working with MORE than one or
+     * two pages from a lesson you should probably call {@see $lesson->load_all_pages()}
+     * in order to save excess database queries.
+     * @var array An array of lesson_page objects
+     */
+    protected $pages = array();
+    /**
+     * Flag that gets set to true once all of the pages associated with the lesson
+     * have been loaded.
+     * @var bool
+     */
+    protected $loadedallpages = false;
+
+    /**
+     * Simply generates a lesson object given an array/object of properties
+     * Overrides {@see lesson_base->create()}
+     * @static
+     * @param object|array $properties
+     * @return lesson
+     */
+    public static function create($properties) {
+        return new lesson($properties);
+    }
+
+    /**
+     * Generates a lesson object from the database given its id
+     * @static
+     * @param int $lessonid
+     * @return lesson
+     */
+    public static function load($lessonid) {
+        if (!$lesson = $DB->get_record('lesson', array('id' => $lessonid))) {
+            print_error('invalidcoursemodule');
+        }
+        return new lesson($lesson);
+    }
+
+    /**
+     * Deletes this lesson from the database
+     */
+    public function delete() {
+        global $CFG, $DB;
+        require_once($CFG->libdir.'/gradelib.php');
+
+        $DB->delete_records("lesson", array("id"=>$this->properties->id));;
+        $DB->delete_records("lesson_pages", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_answers", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_attempts", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_grades", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_timer", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_branch", array("lessonid"=>$this->properties->id));
+        $DB->delete_records("lesson_high_scores", array("lessonid"=>$this->properties->id));
+        if ($events = $DB->get_records('event', array("modulename"=>'lesson', "instance"=>$this->properties->id))) {
+            foreach($events as $event) {
+                $event = calendar_event::load($event);
+                $event->delete();
+            }
+        }
+
+        grade_update('mod/lesson', $this->properties->course, 'mod', 'lesson', $this->properties->id, 0, NULL, array('deleted'=>1));
+        return true;
+    }
+
+    /**
+     * Fetches messages from the session that may have been set in previous page
+     * actions.
+     *
+     * <code>
+     * // Do not call this method directly instead use
+     * $lesson->messages;
+     * </code>
+     *
+     * @return array
+     */
+    protected function get_messages() {
+        global $SESSION;
+
+        $messages = array();
+        if (!empty($SESSION->lesson_messages) && is_array($SESSION->lesson_messages) && array_key_exists($this->properties->id, $SESSION->lesson_messages)) {
+            $messages = $SESSION->lesson_messages[$this->properties->id];
+            unset($SESSION->lesson_messages[$this->properties->id]);
+        }
+        
+        return $messages;
+    }
+
+    /**
+     * Get all of the attempts for the current user.
+     *
+     * @param int $retries
+     * @param bool $correct Optional: only fetch correct attempts
+     * @param int $pageid Optional: only fetch attempts at the given page
+     * @param int $userid Optional: defaults to the current user if not set
+     * @return array|false
+     */
+    public function get_attempts($retries, $correct=false, $pageid=null, $userid=null) {
+        global $USER, $DB;
+        $params = array("lessonid"=>$this->properties->id, "userid"=>$userid, "retry"=>$retries);
+        if ($correct) {
+            $params['correct'] = 1;
+        }
+        if ($pageid !== null) {
+            $params['pageid'] = $pageid;
+        }
+        if ($userid === null) {
+            $params['userid'] = $USER->id;
+        }
+        return $DB->get_records('lesson_attempts', $params, 'timeseen DESC');
+    }
+
+    /**
+     * Returns the first page for the lesson or false if there isn't one.
+     *
+     * This method should be called via the magic method __get();
+     * <code>
+     * $firstpage = $lesson->firstpage;
+     * </code>
+     *
+     * @return lesson_page|bool Returns the lesson_page specialised object or false
+     */
+    protected function get_firstpage() {
+        $pages = $this->load_all_pages();
+        if (count($pages) > 0) {
+            foreach ($pages as $page) {
+                if ((int)$page->prevpageid === 0) {
+                    return $page;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the last page for the lesson or false if there isn't one.
+     *
+     * This method should be called via the magic method __get();
+     * <code>
+     * $lastpage = $lesson->lastpage;
+     * </code>
+     *
+     * @return lesson_page|bool Returns the lesson_page specialised object or false
+     */
+    protected function get_lastpage() {
+        $pages = $this->load_all_pages();
+        if (count($pages) > 0) {
+            foreach ($pages as $page) {
+                if ((int)$page->nextpageid === 0) {
+                    return $page;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the id of the first page of this lesson. (prevpageid = 0)
+     * @return int
+     */
+    protected function get_firstpageid() {
+        global $DB;
+        if ($this->firstpageid == null) {
+            if (!$this->loadedallpages) {
+                $firstpageid = $DB->get_field('lesson_pages', 'id', array('lessonid'=>$this->properties->id, 'prevpageid'=>0));
+                if (!$firstpageid) {
+                    print_error('cannotfindfirstpage', 'lesson');
+                }
+                $this->firstpageid = $firstpageid;
+            } else {
+                $firstpage = $this->get_firstpage();
+                $this->firstpageid = $firstpage->id;
+            }
+        }
+        return $this->firstpageid;
+    }
+    
+    /**
+     * Returns the id of the last page of this lesson. (nextpageid = 0)
+     * @return int
+     */
+    public function get_lastpageid() {
+        global $DB;
+        if ($this->lastpageid == null) {
+            if (!$this->loadedallpages) {
+                $lastpageid = $DB->get_field('lesson_pages', 'id', array('lessonid'=>$this->properties->id, 'nextpageid'=>0));
+                if (!$lastpageid) {
+                    print_error('cannotfindlastpage', 'lesson');
+                }
+                $this->lastpageid = $lastpageid;
+            } else {
+                $lastpageid = $this->get_lastpage();
+                $this->lastpageid = $lastpageid->id;
+            }
+        }
+
+        return $this->lastpageid;
+    }
+
+     /**
+     * Gets the next page to display after the one that is provided.
+     * @param int $nextpageid
+     * @return bool
+     */
+    public function get_next_page($nextpageid) {
+        global $USER;
+        $allpages = $this->load_all_pages();
+        if ($this->properties->nextpagedefault) {
+            // in Flash Card mode...first get number of retakes
+            shuffle($allpages);
+            $found = false;
+            if ($this->properties->nextpagedefault == LESSON_UNSEENPAGE) {
+                foreach ($allpages as $nextpage) {
+                    if (!$DB->count_records("lesson_attempts", array("pageid"=>$nextpage->id, "userid"=>$USER->id, "retry"=>$nretakes))) {
+                        $found = true;
+                        break;
+                    }
+                }
+            } elseif ($this->properties->nextpagedefault == LESSON_UNANSWEREDPAGE) {
+                foreach ($allpages as $nextpage) {
+                    if (!$DB->count_records("lesson_attempts", array('pageid'=>$nextpage->id, 'userid'=>$USER->id, 'correct'=>1, 'retry'=>$nretakes))) {
+                        $found = true;
+                        break;
+                    }
+                }
+            }
+            if ($found) {
+                if ($this->properties->maxpages) {
+                    // check number of pages viewed (in the lesson)
+                    $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$this->properties->id, "userid"=>$USER->id));
+                    if ($DB->count_records("lesson_attempts", array("lessonid"=>$this->properties->id, "userid"=>$USER->id, "retry"=>$nretakes)) >= $this->properties->maxpages) {
+                        return false;
+                    }
+                }
+                return $nextpage;
+            }
+        }
+        // In a normal lesson mode
+        foreach ($allpages as $nextpage) {
+            if ((int)$nextpage->id===(int)$nextpageid) {
+                return $nextpage;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Sets a message against the session for this lesson that will displayed next
+     * time the lesson processes messages
+     *
+     * @param string $message
+     * @param string $class
+     * @param string $align
+     * @return bool
+     */
+    public function add_message($message, $class="notifyproblem", $align='center') {
+        global $SESSION;
+
+        if (empty($SESSION->lesson_messages) || !is_array($SESSION->lesson_messages)) {
+            $SESSION->lesson_messages = array();
+            $SESSION->lesson_messages[$this->properties->id] = array();
+        } else if (!array_key_exists($this->properties->id, $SESSION->lesson_messages)) {
+            $SESSION->lesson_messages[$this->properties->id] = array();
+        }
+
+        $SESSION->lesson_messages[$this->properties->id][] = array($message, $class, $align);
+
+        return true;
+    }
+
+    /**
+     * Check if the lesson is accessible at the present time
+     * @return bool True if the lesson is accessible, false otherwise
+     */
+    public function is_accessible() {
+        $available = $this->properties->available;
+        $deadline = $this->properties->deadline;
+        return (($available == 0 || time() >= $available) && ($deadline == 0 || time() < $deadline));
+    }
+
+    /**
+     * Starts the lesson time for the current user
+     * @return bool Returns true
+     */
+    public function start_timer() {
+        global $USER, $DB;
+        $USER->startlesson[$this->properties->id] = true;
+        $startlesson = new stdClass;
+        $startlesson->lessonid = $this->properties->id;
+        $startlesson->userid = $USER->id;
+        $startlesson->starttime = time();
+        $startlesson->lessontime = time();
+        $DB->insert_record('lesson_timer', $startlesson);
+        if ($this->properties->timed) {
+            $this->add_message(get_string('maxtimewarning', 'lesson', $this->properties->maxtime), 'center');
+        }
+        return true;
+    }
+
+    /**
+     * Updates the timer to the current time and returns the new timer object
+     * @param bool $restart If set to true the timer is restarted
+     * @param bool $continue If set to true AND $restart=true then the timer
+     *                        will continue from a previous attempt
+     * @return stdClass The new timer
+     */
+    public function update_timer($restart=false, $continue=false) {
+        global $USER, $DB;
+        // clock code
+        // get time information for this user
+        if (!$timer = $DB->get_records('lesson_timer', array ("lessonid" => $this->properties->id, "userid" => $USER->id), 'starttime DESC', '*', 0, 1)) {
+            print_error('cannotfindtimer', 'lesson');
+        } else {
+            $timer = current($timer); // this will get the latest start time record
+        }
+
+        if ($restart) {
+            if ($continue) {
+                // continue a previous test, need to update the clock  (think this option is disabled atm)
+                $timer->starttime = time() - ($timer->lessontime - $timer->starttime);
+            } else {
+                // starting over, so reset the clock
+                $timer->starttime = time();
+            }
+        }
+
+        $timer->lessontime = time();
+        $DB->update_record('lesson_timer', $timer);
+        return $timer;
+    }
+
+    /**
+     * Updates the timer to the current time then stops it by unsetting the user var
+     * @return bool Returns true
+     */
+    public function stop_timer() {
+        global $USER, $DB;
+        unset($USER->startlesson[$this->properties->id]);
+        return $this->update_timer(false, false);
+    }
+
+    /**
+     * Checks to see if the lesson has pages
+     */
+    public function has_pages() {
+        global $DB;
+        $pagecount = $DB->count_records('lesson_pages', array('lessonid'=>$this->properties->id));
+        return ($pagecount>0);
+    }
+
+    /**
+     * Returns the link for the related activity
+     * @return html_link|false
+     */
+    public function link_for_activitylink() {
+        global $DB;
+        $module = $DB->get_record('course_modules', array('id' => $this->properties->activitylink));
+        if ($module) {
+            $modname = $DB->get_field('modules', 'name', array('id' => $module->module));
+            if ($modname) {
+                $instancename = $DB->get_field($modname, 'name', array('id' => $module->instance));
+                if ($instancename) {
+                    $link = html_link::make(new moodle_url($CFG->wwwroot.'/mod/'.$modname.'/view.php', array('id'=>$this->properties->activitylink)), get_string('returnto', 'lesson', get_string('activitylinkname', 'lesson', $instancename)));
+                    $link->set_classes(array('centerpadded','lessonbutton','standardbutton'));
+                    return $link;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Loads the requested page.
+     *
+     * This function will return the requested page id as either a specialised
+     * lesson_page object OR as a generic lesson_page.
+     * If the page has been loaded previously it will be returned from the pages
+     * array, otherwise it will be loaded from the database first
+     *
+     * @param int $pageid
+     * @return lesson_page A lesson_page object or an object that extends it
+     */
+    public function load_page($pageid) {
+        if (!array_key_exists($pageid, $this->pages)) {
+            $manager = lesson_page_type_manager::get($this);
+            $this->pages[$pageid] = $manager->load_page($pageid, $this);
+        }
+        return $this->pages[$pageid];
+    }
+
+    /**
+     * Loads ALL of the pages for this lesson
+     *
+     * @return array An array containing all pages from this lesson
+     */
+    public function load_all_pages() {
+        if (!$this->loadedallpages) {
+            $manager = lesson_page_type_manager::get($this);
+            $this->pages = $manager->load_all_pages($this);
+            $this->loadedallpages = true;
+        }
+        return $this->pages;
+    }
+
+    /**
+     * Determins if a jumpto value is correct or not.
+     *
+     * returns true if jumpto page is (logically) after the pageid page or
+     * if the jumpto value is a special value.  Returns false in all other cases.
+     *
+     * @param int $pageid Id of the page from which you are jumping from.
+     * @param int $jumpto The jumpto number.
+     * @return boolean True or false after a series of tests.
+     **/
+    public function jumpto_is_correct($pageid, $jumpto) {
+        global $DB;
+
+        // first test the special values
+        if (!$jumpto) {
+            // same page
+            return false;
+        } elseif ($jumpto == LESSON_NEXTPAGE) {
+            return true;
+        } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
+            return true;
+        } elseif ($jumpto == LESSON_RANDOMPAGE) {
+            return true;
+        } elseif ($jumpto == LESSON_CLUSTERJUMP) {
+            return true;
+        } elseif ($jumpto == LESSON_EOL) {
+            return true;
+        }
+
+        $pages = $this->load_all_pages();
+        $apageid = $pages[$pageid]->nextpageid;
+        while ($apageid != 0) {
+            if ($jumpto == $apageid) {
+                return true;
+            }
+            $apageid = $pages[$apageid]->nextpageid;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the time a user has remaining on this lesson
+     * @param int $starttime Starttime timestamp
+     * @return string
+     */
+    public function time_remaining($starttime) {
+        $timeleft = $starttime + $this->maxtime * 60 - time();
+        $hours = floor($timeleft/3600);
+        $timeleft = $timeleft - ($hours * 3600);
+        $minutes = floor($timeleft/60);
+        $secs = $timeleft - ($minutes * 60);
+
+        if ($minutes < 10) {
+            $minutes = "0$minutes";
+        }
+        if ($secs < 10) {
+            $secs = "0$secs";
+        }
+        $output   = array();
+        $output[] = $hours;
+        $output[] = $minutes;
+        $output[] = $secs;
+        $output = implode(':', $output);
+        return $output;
+    }
+
+    /**
+     * Interprets LESSON_CLUSTERJUMP jumpto value.
+     *
+     * This will select a page randomly
+     * and the page selected will be inbetween a cluster page and end of cluter or end of lesson
+     * and the page selected will be a page that has not been viewed already
+     * and if any pages are within a branch table or end of branch then only 1 page within
+     * the branch table or end of branch will be randomly selected (sub clustering).
+     *
+     * @param int $pageid Id of the current page from which we are jumping from.
+     * @param int $userid Id of the user.
+     * @return int The id of the next page.
+     **/
+    public function cluster_jump($pageid, $userid=null) {
+        global $DB, $USER;
+
+        if ($userid===null) {
+            $userid = $USER->id;
+        }
+        // get the number of retakes
+        if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$this->properties->id, "userid"=>$userid))) {
+            $retakes = 0;
+        }
+        // get all the lesson_attempts aka what the user has seen
+        $seenpages = array();
+        if ($attempts = $this->get_attempts($retakes)) {
+            foreach ($attempts as $attempt) {
+                $seenpages[$attempt->pageid] = $attempt->pageid;
+            }
+            
+        }
+
+        // get the lesson pages
+        $lessonpages = $this->load_all_pages();
+        // find the start of the cluster
+        while ($pageid != 0) { // this condition should not be satisfied... should be a cluster page
+            if ($lessonpages[$pageid]->qtype == LESSON_PAGE_CLUSTER) {
+                break;
+            }
+            $pageid = $lessonpages[$pageid]->prevpageid;
+        }
+
+        $clusterpages = array();
+        $clusterpages = $this->get_sub_pages_of($pageid, array(LESSON_PAGE_ENDOFCLUSTER));
+        $unseen = array();
+        foreach ($clusterpages as $key=>$cluster) {
+            if ($cluster->type !== lesson_page::TYPE_QUESTION) {
+                unset($clusterpages[$key]);
+            } elseif ($cluster->is_unseen($seenpages)) {
+                $unseen[] = $cluster;
+            }
+        }
+
+        if (count($unseen) > 0) {
+            // it does not contain elements, then use exitjump, otherwise find out next page/branch
+            $nextpage = $unseen[rand(0, count($unseen)-1)];
+            if ($nextpage->qtype == LESSON_PAGE_BRANCHTABLE) {
+                // if branch table, then pick a random page inside of it
+                $branchpages = $this->get_sub_pages_of($nextpage->id, array(LESSON_PAGE_BRANCHTABLE, LESSON_PAGE_ENDOFBRANCH));
+                return $branchpages[rand(0, count($branchpages)-1)]->id;
+            } else { // otherwise, return the page's id
+                return $nextpage->id;
+            }
+        } else {
+            // seen all there is to see, leave the cluster
+            if (end($clusterpages)->nextpageid == 0) {
+                return LESSON_EOL;
+            } else {
+                $clusterendid = $pageid;
+                while ($clusterendid != 0) { // this condition should not be satisfied... should be a cluster page
+                    if ($lessonpages[$clusterendid]->qtype == LESSON_PAGE_CLUSTER) {
+                        break;
+                    }
+                    $clusterendid = $lessonpages[$clusterendid]->prevpageid;
+                }
+                $exitjump = $DB->get_field("lesson_answers", "jumpto", array("pageid" => $clusterendid, "lessonid" => $this->properties->id));
+                if ($exitjump == LESSON_NEXTPAGE) {
+                    $exitjump = $lessonpages[$pageid]->nextpageid;
+                }
+                if ($exitjump == 0) {
+                    return LESSON_EOL;
+                } else if (in_array($exitjump, array(LESSON_EOL, LESSON_PREVIOUSPAGE))) {
+                    return $exitjump;
+                } else {
+                    if (!array_key_exists($exitjump, $lessonpages)) {
+                        $found = false;
+                        foreach ($lessonpages as $page) {
+                            if ($page->id === $clusterendid) {
+                                $found = true;
+                            } else if ($page->qtype == LESSON_PAGE_ENDOFCLUSTER) {
+                                $exitjump = $DB->get_field("lesson_answers", "jumpto", array("pageid" => $page->id, "lessonid" => $this->properties->id));
+                                break;
+                            }
+                        }
+                    }
+                    if (!array_key_exists($exitjump, $lessonpages)) {
+                        return LESSON_EOL;
+                    }
+                    return $exitjump;
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds all pages that appear to be a subtype of the provided pageid until
+     * an end point specified within $ends is encountered or no more pages exist
+     *
+     * @param int $pageid
+     * @param array $ends An array of LESSON_PAGE_* types that signify an end of
+     *               the subtype
+     * @return array An array of specialised lesson_page objects
+     */
+    public function get_sub_pages_of($pageid, array $ends) {
+        $lessonpages = $this->load_all_pages();
+        $pageid = $lessonpages[$pageid]->nextpageid;  // move to the first page after the branch table
+        $pages = array();
+
+        while (true) {
+            if ($pageid == 0 || in_array($lessonpages[$pageid]->qtype, $ends)) {
+                break;
+            }
+            $pages[] = $lessonpages[$pageid];
+            $pageid = $lessonpages[$pageid]->nextpageid;
+        }
+
+        return $pages;
+    }
+
+    /**
+     * Checks to see if the specified page[id] is a subpage of a type specified in
+     * the $types array, until either there are no more pages of we find a type
+     * corrosponding to that of a type specified in $ends
+     *
+     * @param int $pageid The id of the page to check
+     * @param array $types An array of types that would signify this page was a subpage
+     * @param array $ends An array of types that mean this is not a subpage
+     * @return bool
+     */
+    public function is_sub_page_of_type($pageid, array $types, array $ends) {
+        $pages = $this->load_all_pages();
+        $pageid = $pages[$pageid]->prevpageid; // move up one
+
+        array_unshift($ends, 0);
+        // go up the pages till branch table
+        while (true) {
+            if ($pageid==0 || in_array($pages[$pageid]->qtype, $ends)) {
+                return false;
+            } else if (in_array($pages[$pageid]->qtype, $types)) {
+                return true;
+            }
+            $pageid = $pages[$pageid]->prevpageid;
+        }
+    }
+}
+
+/**
+ * Abstract class representation of a page associated with a lesson.
+ *
+ * This class should MUST be extended by all specialised page types defined in
+ * mod/lesson/pagetypes/.
+ * There are a handful of abstract methods that need to be defined as well as
+ * severl methods that can optionally be defined in order to make the page type
+ * operate in the desired way
+ *
+ * Database properties
+ * @property int $id The id of this lesson page
+ * @property int $lessonid The id of the lesson this page belongs to
+ * @property int $prevpageid The id of the page before this one
+ * @property int $nextpageid The id of the next page in the page sequence
+ * @property int $qtype Identifies the page type of this page
+ * @property int $qoption Used to record page type specific options
+ * @property int $layout Used to record page specific layout selections
+ * @property int $display Used to record page specific display selections
+ * @property int $timecreated Timestamp for when the page was created
+ * @property int $timemodified Timestamp for when the page was last modified
+ * @property string $title The title of this page
+ * @property string $contents The rich content shown to describe the page
+ * @property int $contentsformat The format of the contents field
+ *
+ * Calculated properties
+ * @property-read array $answers An array of answers for this page
+ * @property-read bool $displayinmenublock Toggles display in the left menu block
+ * @property-read array $jumps An array containing all the jumps this page uses
+ * @property-read lesson $lesson The lesson this page belongs to
+ * @property-read int $type The type of the page [question | structure]
+ * @property-read typeid The unique identifier for the page type
+ * @property-read typestring The string that describes this page type
+ *
+ * @abstract
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class lesson_page extends lesson_base {
+
+    /**
+     * A reference to the lesson this page belongs to
+     * @var lesson
+     */
+    protected $lesson = null;
+    /**
+     * Contains the answers to this lesson_page once loaded
+     * @var null|array
+     */
+    protected $answers = null;
+    /**
+     * This sets the type of the page, can be one of the constants defined below
+     * @var int
+     */
+    protected $type = 0;
+
+    /**
+     * Constants used to identify the type of the page
+     */
+    const TYPE_QUESTION = 0;
+    const TYPE_STRUCTURE = 1;
+
+    /**
+     * This method should return the integer used to identify the page type within
+     * the database and thoughout code. This maps back to the defines used in 1.x
+     * @abstract
+     * @return int
+     */
+    abstract protected function get_typeid();
+    /**
+     * This method should return the string that describes the pagetype
+     * @abstract
+     * @return string
+     */
+    abstract protected function get_typestring();
+
+    /**
+     * This method gets called to display the page to the user taking the lesson
+     * @abstract
+     * @param object $renderer
+     * @param object $attempt
+     * @return string
+     */
+    abstract public function display($renderer, $attempt);
+
+    /**
+     * Creates a new lesson_page within the database and returns the correct pagetype
+     * object to use to interact with the new lesson
+     * 
+     * @final
+     * @static
+     * @param object $properties
+     * @param lesson $lesson
+     * @return lesson_page Specialised object that extends lesson_page
+     */
+    final public static function create($properties, lesson $lesson, $context, $maxbytes) {
+        global $DB;
+        $newpage = new stdClass;
+        $newpage->title = $properties->title;
+        $newpage->contents = $properties->contents_editor['text'];
+        $newpage->contentsformat = $properties->contents_editor['format'];
+        $newpage->lessonid = $lesson->id;
+        $newpage->timecreated = time();
+        $newpage->qtype = $properties->qtype;
+        $newpage->qoption = (isset($properties->qoption))?1:0;
+        $newpage->layout = (isset($properties->layout))?1:0;
+        $newpage->display = (isset($properties->display))?1:0;
+        $newpage->prevpageid = 0; // this is a first page
+        $newpage->nextpageid = 0; // this is the only page
+
+        if ($properties->pageid) {
+            $prevpage = $DB->get_record("lesson_pages", array("id" => $properties->pageid), 'id, nextpageid');
+            if (!$prevpage) {
+                print_error('cannotfindpages', 'lesson');
+            }
+            $newpage->prevpageid = $prevpage->id;
+            $newpage->nextpageid = $prevpage->nextpageid;
+        } else {
+            $nextpage = $DB->get_record('lesson_pages', array('lessonid'=>$lesson->id, 'prevpageid'=>0), 'id');
+            if ($nextpage) {
+                // This is the first page, there are existing pages put this at the start
+                $newpage->nextpageid = $nextpage->id;
+            }
+        }
+
+        $newpage->id = $DB->insert_record("lesson_pages", $newpage);
+
+        $editor = new stdClass;
+        $editor->id = $newpage->id;
+        $editor->contents_editor = $properties->contents_editor;
+        $editor = file_postupdate_standard_editor($editor, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'lesson_page_contents', $editor->id);
+        $DB->update_record("lesson_pages", $editor);
+
+        if ($newpage->prevpageid > 0) {
+            $DB->set_field("lesson_pages", "nextpageid", $newpage->id, array("id" => $newpage->prevpageid));
+        }
+        if ($newpage->nextpageid > 0) {
+            $DB->set_field("lesson_pages", "prevpageid", $newpage->id, array("id" => $newpage->nextpageid));
+        }
+
+        $page = lesson_page::load($newpage, $lesson);
+        $page->create_answers($properties);
+
+        $lesson->add_message(get_string('insertedpage', 'lesson').': '.format_string($newpage->title, true), 'notifysuccess');
+
+        return $page;
+    }
+
+    /**
+     * This method loads a page object from the database and returns it as a
+     * specialised object that extends lesson_page
+     *
+     * @final
+     * @static
+     * @param int $id
+     * @param lesson $lesson
+     * @return lesson_page Specialised lesson_page object
+     */
+    final public static function load($id, lesson $lesson) {
+        global $DB;
+
+        if (is_object($id) && !empty($id->qtype)) {
+            $page = $id;
+        } else {
+            $page = $DB->get_record("lesson_pages", array("id" => $id));
+            if (!$page) {
+                print_error('cannotfindpages', 'lesson');
+            }
+        }
+        $manager = lesson_page_type_manager::get($lesson);
+
+        $class = 'lesson_page_type_'.$manager->get_page_type_idstring($page->qtype);
+        if (!class_exists($class)) {
+            $class = 'lesson_page';
+        }
+
+        return new $class($page, $lesson);
+    }
+
+    /**
+     * Deletes a lesson_page from the database as well as any associated records.
+     * @final
+     * @return bool
+     */
+    final public function delete() {
+        global $DB;
+        // first delete all the associated records...
+        $DB->delete_records("lesson_attempts", array("pageid" => $this->properties->id));
+        // ...now delete the answers...
+        $DB->delete_records("lesson_answers", array("pageid" => $this->properties->id));
+        // ..and the page itself
+        $DB->delete_records("lesson_pages", array("id" => $this->properties->id));
+
+        // repair the hole in the linkage
+        if (!$this->properties->prevpageid && !$this->properties->nextpageid) {
+            //This is the only page, no repair needed
+        } elseif (!$this->properties->prevpageid) {
+            // this is the first page...
+            $page = $this->lesson->load_page($this->properties->nextpageid);
+            $page->move(null, 0);
+        } elseif (!$this->properties->nextpageid) {
+            // this is the last page...
+            $page = $this->lesson->load_page($this->properties->prevpageid);
+            $page->move(0);
+        } else {
+            // page is in the middle...
+            $prevpage = $this->lesson->load_page($this->properties->prevpageid);
+            $nextpage = $this->lesson->load_page($this->properties->nextpageid);
+
+            $prevpage->move($nextpage->id);
+            $nextpage->move(null, $prevpage->id);
+        }
+        return true;
+    }
+
+    /**
+     * Moves a page by updating its nextpageid and prevpageid values within
+     * the database
+     *
+     * @final
+     * @param int $nextpageid
+     * @param int $prevpageid
+     */
+    final public function move($nextpageid=null, $prevpageid=null) {
+        global $DB;
+        if ($nextpageid === null) {
+            $nextpageid = $this->properties->nextpageid;
+        }
+        if ($prevpageid === null) {
+            $prevpageid = $this->properties->prevpageid;
+        }
+        $obj = new stdClass;
+        $obj->id = $this->properties->id;
+        $obj->prevpageid = $prevpageid;
+        $obj->nextpageid = $nextpageid;
+        $DB->update_record('lesson_pages', $obj);
+    }
+
+    /**
+     * Returns the answers that are associated with this page in the database
+     *
+     * @final
+     * @return array
+     */
+    final public function get_answers() {
+        global $DB;
+        if ($this->answers === null) {
+            $this->answers = array();
+            $answers = $DB->get_records('lesson_answers', array('pageid'=>$this->properties->id, 'lessonid'=>$this->lesson->id), 'id');
+            if (!$answers) {
+                print_error('cannotfindanswer', 'lesson');
+            }
+            foreach ($answers as $answer) {
+                $this->answers[count($this->answers)] = new lesson_page_answer($answer);
+            }
+        }
+        return $this->answers;
+    }
+
+    /**
+     * Returns the lesson this page is associated with
+     * @final
+     * @return lesson
+     */
+    final protected function get_lesson() {
+        return $this->lesson;
+    }
+
+    /**
+     * Returns the type of page this is. Not to be confused with page type
+     * @final
+     * @return int
+     */
+    final protected function get_type() {
+        return $this->type;
+    }
+
+    /**
+     * Records an attempt at this page
+     *
+     * @final
+     * @param stdClass $context
+     * @return stdClass Returns the result of the attempt
+     */
+    final public function record_attempt($context) {
+        global $DB, $USER, $OUTPUT;
+
+        /**
+         * This should be overriden by each page type to actually check the response
+         * against what ever custom criteria they have defined
+         */
+        $result = $this->check_answer();
+
+        $result->attemptsremaining  = 0;
+        $result->maxattemptsreached = false;
+
+        if ($result->noanswer) {
+            $result->newpageid = $this->properties->id; // display same page again
+            $result->feedback  = get_string('noanswer', 'lesson');
+        } else {
+            if (!has_capability('mod/lesson:manage', $context)) {
+                $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$this->lesson->id, "userid"=>$USER->id));
+                // record student's attempt
+                $attempt = new stdClass;
+                $attempt->lessonid = $this->lesson->id;
+                $attempt->pageid = $this->properties->id;
+                $attempt->userid = $USER->id;
+                $attempt->answerid = $result->answerid;
+                $attempt->retry = $nretakes;
+                $attempt->correct = $result->correctanswer;
+                if($result->userresponse !== null) {
+                    $attempt->useranswer = $result->userresponse;
+                }
+
+                $attempt->timeseen = time();
+                // if allow modattempts, then update the old attempt record, otherwise, insert new answer record
+                if (isset($USER->modattempts[$this->lesson->id])) {
+                    $attempt->retry = $nretakes - 1; // they are going through on review, $nretakes will be too high
+                }
+
+                $DB->insert_record("lesson_attempts", $attempt);
+                // "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)) {
+                    // wrong answer and student is stuck on this page - check how many attempts
+                    // the student has had at this page/question
+                    $nattempts = $DB->count_records("lesson_attempts", array("pageid"=>$this->properties->id, "userid"=>$USER->id),"retry", $nretakes);
+                    // retreive the number of attempts left counter for displaying at bottom of feedback page
+                    if ($nattempts >= $this->lesson->maxattempts) {
+                        if ($this->lesson->maxattempts > 1) { // don't bother with message if only one attempt
+                            $result->maxattemptsreached = true;
+                        }
+                        $result->newpageid = LESSON_NEXTPAGE;
+                    } else if ($this->lesson->maxattempts > 1) { // don't bother with message if only one attempt
+                        $result->attemptsremaining = $this->lesson->maxattempts - $nattempts;
+                    }
+                }
+            }
+            // TODO: merge this code with the jump code below.  Convert jumpto page into a proper page id
+            if ($result->newpageid == 0) {
+                $result->newpageid = $this->properties->id;
+            } elseif ($result->newpageid == LESSON_NEXTPAGE) {
+                $nextpage = $this->lesson->get_next_page($this->properties->nextpageid);
+                if ($nextpage === false) {
+                    $result->newpageid = LESSON_EOL;
+                } else {
+                    $result->newpageid = $nextpage->id;
+                }
+            }
+
+            // Determine default feedback if necessary
+            if (empty($result->response)) {
+                if (!$this->lesson->feedback && !$result->noanswer && !($this->lesson->review & !$result->correctanswer && !$result->isessayquestion)) {
+                    // These conditions have been met:
+                    //  1. The lesson manager has not supplied feedback to the student
+                    //  2. Not displaying default feedback
+                    //  3. The user did provide an answer
+                    //  4. We are not reviewing with an incorrect answer (and not reviewing an essay question)
+
+                    $result->nodefaultresponse = true;  // This will cause a redirect below
+                } else if ($result->isessayquestion) {
+                    $result->response = get_string('defaultessayresponse', 'lesson');
+                } else if ($result->correctanswer) {
+                    $result->response = get_string('thatsthecorrectanswer', 'lesson');
+                } else {
+                    $result->response = get_string('thatsthewronganswer', 'lesson');
+                }
+            }
+
+            if ($result->response) {
+                if ($this->lesson->review && !$result->correctanswer && !$result->isessayquestion) {
+                    $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$this->lesson->id, "userid"=>$USER->id));
+                    $qattempts = $DB->count_records("lesson_attempts", array("userid"=>$USER->id, "retry"=>$nretakes, "pageid"=>$this->properties->id));
+                    if ($qattempts == 1) {
+                        $result->feedback = get_string("firstwrong", "lesson");
+                    } else {
+                        $result->feedback = get_string("secondpluswrong", "lesson");
+                    }
+                } else {
+                    $class = 'response';
+                    if ($result->correctanswer) {
+                        $class .= ' correct'; //CSS over-ride this if they exist (!important)
+                    } else if (!$result->isessayquestion) {
+                        $class .= ' incorrect'; //CSS over-ride this if they exist (!important)
+                    }
+                    $options = new stdClass;
+                    $options->noclean = true;
+                    $options->para = true;
+                    $result->feedback = $OUTPUT->box(format_text($this->properties->contents, FORMAT_MOODLE, $options), 'generalbox boxaligncenter');
+                    $result->feedback .= '<em>'.get_string("youranswer", "lesson").'</em> : '.format_text($result->studentanswer, FORMAT_MOODLE, $options);
+                    $result->feedback .= $OUTPUT->box(format_text($result->response, FORMAT_MOODLE, $options), $class);
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns the string for a jump name
+     *
+     * @final
+     * @param int $jumpto Jump code or page ID
+     * @return string
+     **/
+    final protected function get_jump_name($jumpto) {
+        global $DB;
+        static $jumpnames = array();
+
+        if (!array_key_exists($jumpto, $jumpnames)) {
+            if ($jumpto == 0) {
+                $jumptitle = get_string('thispage', 'lesson');
+            } elseif ($jumpto == LESSON_NEXTPAGE) {
+                $jumptitle = get_string('nextpage', 'lesson');
+            } elseif ($jumpto == LESSON_EOL) {
+                $jumptitle = get_string('endoflesson', 'lesson');
+            } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
+                $jumptitle = get_string('unseenpageinbranch', 'lesson');
+            } elseif ($jumpto == LESSON_PREVIOUSPAGE) {
+                $jumptitle = get_string('previouspage', 'lesson');
+            } elseif ($jumpto == LESSON_RANDOMPAGE) {
+                $jumptitle = get_string('randompageinbranch', 'lesson');
+            } elseif ($jumpto == LESSON_RANDOMBRANCH) {
+                $jumptitle = get_string('randombranch', 'lesson');
+            } elseif ($jumpto == LESSON_CLUSTERJUMP) {
+                $jumptitle = get_string('clusterjump', 'lesson');
+            } else {
+                if (!$jumptitle = $DB->get_field('lesson_pages', 'title', array('id' => $jumpto))) {
+                    $jumptitle = '<strong>'.get_string('notdefined', 'lesson').'</strong>';
+                }
+            }
+            $jumpnames[$jumpto] = format_string($jumptitle,true);
+        }
+
+        return $jumpnames[$jumpto];
+    }
+
+    /**
+     * Construstor method
+     * @param object $properties
+     * @param lesson $lesson
+     */
+    public function __construct($properties, lesson $lesson) {
+        parent::__construct($properties);
+        $this->lesson = $lesson;
+    }
+
+    /**
+     * Returns the score for the attempt
+     * This may be overriden by page types that require manual grading
+     * @param array $answers
+     * @param object $attempt
+     * @return int
+     */
+    public function earned_score($answers, $attempt) {
+        return $answers[$attempt->answerid]->score;
+    }
+
+    /**
+     * This is a callback method that can be override and gets called when ever a page
+     * is viewed
+     *
+     * @param bool $canmanage True if the user has the manage cap
+     * @return mixed
+     */
+    public function callback_on_view($canmanage) {
+        return true;
+    }
+
+    /**
+     * Updates a lesson page and its answers within the database
+     *
+     * @param object $properties
+     * @return bool
+     */
+    public function update($properties,$context, $maxbytes) {
+        global $DB;
+        $answers  = $this->get_answers();
+        $properties->id = $this->properties->id;
+        $properties->lessonid = $this->lesson->id;
+        if (empty($properties->qoption)) {
+            $properties->qoption = '0';
+        }
+        $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$maxbytes), $context, 'lesson_page_contents', $properties->id);
+        $DB->update_record("lesson_pages", $properties);
+
+        for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
+            if (!array_key_exists($i, $this->answers)) {
+                $this->answers[$i] = new stdClass;
+                $this->answers[$i]->lessonid = $this->lesson->id;
+                $this->answers[$i]->pageid = $this->id;
+                $this->answers[$i]->timecreated = $this->timecreated;
+            }
+            if (!empty($properties->answer[$i])) {
+                $this->answers[$i]->answer = format_text($properties->answer[$i], FORMAT_PLAIN);
+                if (isset($properties->response[$i])) {
+                    $this->answers[$i]->response = format_text($properties->response[$i], FORMAT_PLAIN);
+                }
+                if (isset($properties->jumpto[$i])) {
+                    $this->answers[$i]->jumpto = $properties->jumpto[$i];
+                }
+                if ($this->lesson->custom && isset($properties->score[$i])) {
+                    $this->answers[$i]->score = $properties->score[$i];
+                }
+                if (!isset($this->answers[$i]->id)) {
+                    $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
+                } else {
+                    $DB->update_record("lesson_answers", $this->answers[$i]->properties());
+                }
+
+            } else {
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Can be set to true if the page requires a static link to create a new instance
+     * instead of simply being included in the dropdown
+     * @param int $previd
+     * @return bool
+     */
+    public function add_page_link($previd) {
+        return false;
+    }
+
+    /**
+     * Returns true if a page has been viewed before
+     *
+     * @param array|int $param Either an array of pages that have been seen or the
+     *                   number of retakes a user has had
+     * @return bool
+     */
+    public function is_unseen($param) {
+        global $USER, $DB;
+        if (is_array($param)) {
+            $seenpages = $param;
+            return (!array_key_exists($this->properties->id, $seenpages));
+        } else {
+            $nretakes = $param;
+            if (!$DB->count_records("lesson_attempts", array("pageid"=>$this->properties->id, "userid"=>$USER->id, "retry"=>$nretakes))) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Checks to see if a page has been answered previously
+     * @param int $nretakes
+     * @return bool
+     */
+    public function is_unanswered($nretakes) {
+        global $DB, $USER;
+        if (!$DB->count_records("lesson_attempts", array('pageid'=>$this->properties->id, 'userid'=>$USER->id, 'correct'=>1, 'retry'=>$nretakes))) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Creates answers within the database for this lesson_page. Usually only ever
+     * called when creating a new page instance
+     * @param object $properties
+     * @return array
+     */
+    public function create_answers($properties) {
+        global $DB;
+        // now add the answers
+        $newanswer = new stdClass;
+        $newanswer->lessonid = $this->lesson->id;
+        $newanswer->pageid = $this->properties->id;
+        $newanswer->timecreated = $this->properties->timecreated;
+
+        $answers = array();
+
+        for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
+            $answer = clone($newanswer);
+            if (!empty($properties->answer[$i])) {
+                $answer->answer = format_text($properties->answer[$i], FORMAT_PLAIN);
+                if (isset($properties->response[$i])) {
+                    $answer->response = format_text($properties->response[$i], FORMAT_PLAIN);
+                }
+                if (isset($properties->jumpto[$i])) {
+                    $answer->jumpto = $properties->jumpto[$i];
+                }
+                if ($this->lesson->custom && isset($properties->score[$i])) {
+                    $answer->score = $properties->score[$i];
+                }
+                $answer->id = $DB->insert_record("lesson_answers", $answer);
+                $answers[$answer->id] = new lesson_page_answer($answer);
+            } else {
+                break;
+            }
+        }
+
+        $this->answers = $answers;
+        return $answers;
+    }
+    
+    /**
+     * This method MUST be overriden by all question page types, or page types that
+     * wish to score a page.
+     *
+     * The structure of result should always be the same so it is a good idea when
+     * overriding this method on a page type to call
+     * <code>
+     * $result = parent::check_answer();
+     * </code>
+     * before modifiying it as required.
+     * 
+     * @return stdClass
+     */
+    public function check_answer() {
+        $result = new stdClass;
+        $result->answerid        = 0;
+        $result->noanswer        = false;
+        $result->correctanswer   = false;
+        $result->isessayquestion = false;   // use this to turn off review button on essay questions
+        $result->response        = '';
+        $result->newpageid       = 0;       // stay on the page
+        $result->studentanswer   = '';      // use this to store student's answer(s) in order to display it on feedback page
+        $result->userresponse    = null;
+        $result->feedback        = '';
+        $result->nodefaultresponse  = false; // Flag for redirecting when default feedback is turned off
+        return $result;
+    }
+
+    /**
+     * True if the page uses a custom option
+     * 
+     * Should be override and set to true if the page uses a custom option.
+     * 
+     * @return bool
+     */
+    public function has_option() {
+        return false;
+    }
+    
+    /**
+     * Returns the maximum number of answers for this page given the maximum number
+     * of answers permitted by the lesson.
+     *
+     * @param int $default
+     * @return int
+     */
+    public function max_answers($default) {
+        return $default;
+    }
+
+    /**
+     * Returns the properties of this lesson page as an object
+     * @return stdClass;
+     */
+    public function properties() {
+        $properties = clone($this->properties);
+        if ($this->answers === null) {
+            $this->get_answers();
+        }
+        if (count($this->answers)>0) {
+            $count = 0;
+            foreach ($this->answers as $answer) {
+                $properties->{'answer['.$count.']'} = $answer->answer;
+                $properties->{'response['.$count.']'} = $answer->response;
+                $properties->{'jumpto['.$count.']'} = $answer->jumpto;
+                $properties->{'score['.$count.']'} = $answer->score;
+                $count++;
+            }
+        }
+        return $properties;
+    }
+    
+    /**
+     * Returns an array of options to display whn choosing the jumpto for a page/answer
+     * @static
+     * @param int $pageid
+     * @param lesson $lesson
+     * @return array
+     */
+    public static function get_jumptooptions($pageid, lesson $lesson) {
+        global $DB;
+        $jump = array();
+        $jump[0] = get_string("thispage", "lesson");
+        $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
+        $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
+        $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
+
+        if ($pageid == 0) {
+            return $jump;
+        }
+        
+        $pages = $lesson->load_all_pages();
+        if ($pages[$pageid]->qtype == LESSON_PAGE_BRANCHTABLE || $lesson->is_sub_page_of_type($pageid, array(LESSON_PAGE_BRANCHTABLE), array(LESSON_PAGE_ENDOFBRANCH, LESSON_PAGE_CLUSTER))) {
+            $jump[LESSON_UNSEENBRANCHPAGE] = get_string("unseenpageinbranch", "lesson");
+            $jump[LESSON_RANDOMPAGE] = get_string("randompageinbranch", "lesson");
+        }
+        if($pages[$pageid]->qtype == LESSON_PAGE_CLUSTER || $lesson->is_sub_page_of_type($pageid, array(LESSON_PAGE_CLUSTER), array(LESSON_PAGE_ENDOFCLUSTER))) {
+            $jump[LESSON_CLUSTERJUMP] = get_string("clusterjump", "lesson");
+        }
+        if (!optional_param('firstpage', 0, PARAM_INT)) {
+            $apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0));
+            while (true) {
+                if ($apageid) {
+                    $title = $DB->get_field("lesson_pages", "title", array("id" => $apageid));
+                    $jump[$apageid] = strip_tags(format_string($title,true));
+                    $apageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $apageid));
+                } else {
+                    // last page reached
+                    break;
+                }
+            }
+        }
+        return $jump;
+    }
+    /**
+     * Returns the contents field for the page properly formatted and with plugin
+     * file url's converted
+     * @return string
+     */
+    public function get_contents() {
+        global $PAGE;
+        if (!empty($this->properties->contents)) {
+            if (!isset($this->properties->contentsformat)) {
+                $this->properties->contentsformat = FORMAT_HTML;
+            }
+            $context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id);
+            return file_rewrite_pluginfile_urls($this->properties->contents, 'pluginfile.php', $context->id, 'lesson_page_contents', $this->properties->id);
+        } else {
+            return '';
+        }
+    }
+
+    /**
+     * Set to true if this page should display in the menu block
+     * @return bool
+     */
+    protected function get_displayinmenublock() {
+        return false;
+    }
+
+    /**
+     * Get the string that describes the options of this page type
+     * @return string
+     */
+    public function option_description_string() {
+        return '';
+    }
+
+    /**
+     * Updates a table with the answers for this page
+     * @param html_table $table
+     * @return html_table
+     */
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson")." $i<span>: ";
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+            $i++;
+        }
+        return $table;
+    }
+
+    /**
+     * Determines if this page should be grayed out on the management/report screens
+     * @return int 0 or 1
+     */
+    protected function get_grayout() {
+        return 0;
+    }
+
+    /**
+     * Adds stats for this page to the &pagestats object. This should be defined
+     * for all page types that grade
+     * @param array $pagestats
+     * @param int $tries
+     * @return bool
+     */
+    public function stats(array &$pagestats, $tries) {
+        return true;
+    }
+
+    /**
+     * Formats the answers of this page for a report
+     *
+     * @param object $answerpage
+     * @param object $answerdata
+     * @param object $useranswer
+     * @param array $pagestats
+     * @param int $i Count of first level answers
+     * @param int $n Count of second level answers
+     * @return object The answer page for this
+     */
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            $data = get_string('jumpsto', 'lesson', $this->get_jump_name($answer->jumpto));
+            $answerdata->answers[] = array($data, "");
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+
+    /**
+     * Gets an array of the jumps used by the answers of this page
+     *
+     * @return array
+     */
+    public function get_jumps() {
+        global $DB;
+        $jumps = array();
+        $params = array ("lessonid" => $this->lesson->id, "pageid" => $this->properties->id);
+        if ($answers = $this->get_answers()) {
+            foreach ($answers as $answer) {
+                $jumps[] = $this->get_jump_name($answer->jumpto);
+            }
+        }
+        return $jumps;
+    }
+    /**
+     * Informs whether this page type require manual grading or not
+     * @return bool
+     */
+    public function requires_manual_grading() {
+        return false;
+    }
+
+    /**
+     * A callback method that allows a page to override the next page a user will
+     * see during when this page is being completed.
+     * @return false|int
+     */
+    public function override_next_page() {
+        return false;
+    }
+
+    /**
+     * This method is used to determine if this page is a valid page
+     *
+     * @param array $validpages
+     * @param array $pageviews
+     * @return int The next page id to check
+     */
+    public function valid_page_and_view(&$validpages, &$pageviews) {
+        $validpages[$this->properties->id] = 1;
+        return $this->properties->nextpageid;
+    }
+}
+
+/**
+ * Class used to represent an answer to a page
+ *
+ * @property int $id The ID of this answer in the database
+ * @property int $lessonid The ID of the lesson this answer belongs to
+ * @property int $pageid The ID of the page this answer belongs to
+ * @property int $jumpto Identifies where the user goes upon completing a page with this answer
+ * @property int $grade The grade this answer is worth
+ * @property int $score The score this answer will give
+ * @property int $flags Used to store options for the answer
+ * @property int $timecreated A timestamp of when the answer was created
+ * @property int $timemodified A timestamp of when the answer was modified
+ * @property string $answer The answer itself
+ * @property string $response The response the user sees if selecting this answer
+ * 
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class lesson_page_answer extends lesson_base {
+
+    /**
+     * Loads an page answer from the DB
+     *
+     * @param int $id
+     * @return lesson_page_answer
+     */
+    public static function load($id) {
+        global $DB;
+        $answer = $DB->get_record("lesson_answers", array("id" => $id));
+        return new lesson_page_answer($answer);
+    }
+
+    /**
+     * Given an object of properties and a page created answer(s) and saves them
+     * in the database.
+     *
+     * @param stdClass $properties
+     * @param lesson_page $page
+     * @return array
+     */
+    public static function create($properties, lesson_page $page) {
+        return $page->create_answers($properties);
+    }
+
+}
+
+/**
+ * A management class for page types
+ *
+ * This class is responsible for managing the different pages. A manager object can
+ * be retrieved by calling the following line of code:
+ * <code>
+ * $manager  = lesson_page_type_manager::get($lesson);
+ * </code>
+ * The first time the page type manager is retrieved the it includes all of the
+ * different page types located in mod/lesson/pagetypes.
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class lesson_page_type_manager {
+
+    /**
+     * An array of different page type classes
+     * @var array
+     */
+    protected $types = array();
+
+    /**
+     * Retrieves the lesson page type manager object
+     *
+     * If the object hasn't yet been created it is created here.
+     *
+     * @staticvar lesson_page_type_manager $pagetypemanager
+     * @param lesson $lesson
+     * @return lesson_page_type_manager
+     */
+    public static function get(lesson $lesson) {
+        static $pagetypemanager;
+        if (!($pagetypemanager instanceof lesson_page_type_manager)) {
+            $pagetypemanager = new lesson_page_type_manager();
+            $pagetypemanager->load_lesson_types($lesson);
+        }
+        return $pagetypemanager;
+    }
+
+    /**
+     * Finds and loads all lesson page types in mod/lesson/pagetypes
+     * 
+     * @param lesson $lesson
+     */
+    public function load_lesson_types(lesson $lesson) {
+        global $CFG;
+        $basedir = $CFG->dirroot.'/mod/lesson/pagetypes/';
+        $dir = dir($basedir);
+        while (false !== ($entry = $dir->read())) {
+            if (strpos($entry, '.')===0 || !preg_match('#^[a-zA-Z]+\.php#i', $entry)) {
+                continue;
+            }
+            require_once($basedir.$entry);
+            $class = 'lesson_page_type_'.strtok($entry,'.');
+            if (class_exists($class)) {
+                $pagetype = new $class(new stdClass, $lesson);
+                $this->types[$pagetype->typeid] = $pagetype;
+            }
+        }
+        
+    }
+
+    /**
+     * Returns an array of strings to describe the loaded page types
+     *
+     * @param int $type Can be used to return JUST the string for the requested type
+     * @return array
+     */
+    public function get_page_type_strings($type=null, $special=true) {
+        $types = array();
+        foreach ($this->types as $pagetype) {
+            if (($type===null || $pagetype->type===$type) && ($special===true || $pagetype->is_standard())) {
+                $types[$pagetype->typeid] = $pagetype->typestring;
+            }
+        }
+        return $types;
+    }
+
+    /**
+     * Returns the basic string used to identify a page type provided with an id
+     *
+     * This string can be used to instantiate or identify the page type class.
+     * If the page type id is unknown then 'unknown' is returned
+     *
+     * @param int $id
+     * @return string
+     */
+    public function get_page_type_idstring($id) {
+        foreach ($this->types as $pagetype) {
+            if ((int)$pagetype->typeid === (int)$id) {
+                return $pagetype->idstring;
+            }
+        }
+        return 'unknown';
+    }
+
+    /**
+     * Loads a page for the provided lesson given it's id
+     *
+     * This function loads a page from the lesson when given both the lesson it belongs
+     * to as well as the page's id.
+     * If the page doesn't exist an error is thrown
+     *
+     * @param int $pageid The id of the page to load
+     * @param lesson $lesson The lesson the page belongs to
+     * @return lesson_page A class that extends lesson_page
+     */
+    public function load_page($pageid, lesson $lesson) {
+        global $DB;
+        if (!($page =$DB->get_record('lesson_pages', array('id'=>$pageid, 'lessonid'=>$lesson->id)))) {
+            print_error('cannotfindpages', 'lesson');
+        }
+        $pagetype = get_class($this->types[$page->qtype]);
+        $page = new $pagetype($page, $lesson);
+        return $page;
+    }
+
+    /**
+     * This function loads ALL pages that belong to the lesson.
+     *
+     * @param lesson $lesson
+     * @return array An array of lesson_page_type_*
+     */
+    public function load_all_pages(lesson $lesson) {
+        global $DB;
+        if (!($pages =$DB->get_records('lesson_pages', array('lessonid'=>$lesson->id)))) {
+            print_error('cannotfindpages', 'lesson');
+        }
+        foreach ($pages as $key=>$page) {
+            $pagetype = get_class($this->types[$page->qtype]);
+            $pages[$key] = new $pagetype($page, $lesson);
+        }
+
+        $orderedpages = array();
+        $lastpageid = 0;
+
+        while (true) {
+            foreach ($pages as $page) {
+                if ((int)$page->prevpageid === (int)$lastpageid) {
+                    $orderedpages[$page->id] = $page;
+                    unset($pages[$page->id]);
+                    $lastpageid = $page->id;
+                    if ((int)$page->nextpageid===0) {
+                        break 2;
+                    } else {
+                        break 1;
+                    }
+                }
+            }
+        }
+
+        return $orderedpages;
+    }
+
+    /**
+     * Fetchs an mform that can be used to create/edit an page
+     *
+     * @param int $type The id for the page type
+     * @param array $arguments Any arguments to pass to the mform
+     * @return lesson_add_page_form_base
+     */
+    public function get_page_form($type, $arguments) {
+        $class = 'lesson_add_page_form_'.$this->get_page_type_idstring($type);
+        if (!class_exists($class) || get_parent_class($class)!=='lesson_add_page_form_base') {
+            debugging('Lesson page type unknown class requested '.$class, DEBUG_DEVELOPER);
+            $class = 'lesson_add_page_form_selection';
+        } else if ($class === 'lesson_add_page_form_unknown') {
+            $class = 'lesson_add_page_form_selection';
+        }
+        return new $class(null, $arguments);
+    }
+
+    /**
+     * Returns an array of links to use as add page links
+     * @param int $previd The id of the previous page
+     * @return array
+     */
+    public function get_add_page_type_links($previd) {
+        $links = array();
+
+        foreach ($this->types as $type) {
+            if (($link = $type->add_page_link($previd)) instanceof html_link) {
+                $links[] = $link;
+            }
+        }
+
+        return $links;
+    }
+}
+
+/**
+ * Abstract class that page type's MUST inherit from.
+ *
+ * This is the abstract class that ALL add page type forms must extend.
+ * You will notice that all but two of the methods this class contains are final.
+ * Essentially the only thing that extending classes can do is extend custom_definition.
+ * OR if it has a special requirement on creation it can extend construction_override
+ *
+ * @abstract
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+abstract class lesson_add_page_form_base extends moodleform {
+
+    /**
+     * This is the classic define that is used to identify this pagetype.
+     * Will be one of LESSON_*
+     * @var int
+     */
+    public $qtype;
+
+    /**
+     * The simple string that describes the page type e.g. truefalse, multichoice
+     * @var string
+     */
+    public $qtypestring;
+
+    /**
+     * An array of options used in the htmleditor
+     * @var array
+     */
+    protected $editoroptions = array();
+
+    /**
+     * True if this is a standard page of false if it does something special.
+     * Questions are standard pages, branch tables are not
+     * @var bool
+     */
+    protected $standard = true;
+
+    /**
+     * Each page type can and should override this to add any custom elements to
+     * the basic form that they want
+     */
+    public function custom_definition() {}
+
+    /**
+     * Sets the data for the form... but modifies if first for the editor then
+     * calls the parent method
+     *
+     * @param stdClass $data An object containing properties to set
+     * @param int $pageid
+     */
+    public final function set_data($data, $context=null, $pageid=null) {
+        $data = file_prepare_standard_editor($data, 'contents', $this->editoroptions, $context, 'lesson_page_contents', $pageid);
+        parent::set_data($data);
+    }
+
+    /**
+     * Used to determine if this is a standard page or a special page
+     * @return bool
+     */
+    public final function is_standard() {
+        return (bool)$this->standard;
+    }
+
+    /**
+     * Add the required basic elements to the form.
+     *
+     * This method adds the basic elements to the form including title and contents
+     * and then calls custom_definition();
+     */
+    public final function definition() {
+        $mform = $this->_form;
+        $editoroptions = $this->_customdata['editoroptions'];
+
+        $mform->addElement('header', 'qtypeheading', get_string('addaquestionpage', 'lesson', get_string($this->qtypestring, 'lesson')));
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        if ($this->standard === true) {
+            $mform->addElement('hidden', 'qtype');
+            $mform->setType('qtype', PARAM_TEXT);
+
+            $mform->addElement('text', 'title', get_string("pagetitle", "lesson"), array('size'=>70));
+            $mform->setType('title', PARAM_TEXT);
+            $this->editoroptions = array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$this->_customdata['maxbytes']);
+            $mform->addElement('editor', 'contents_editor', get_string("pagecontents", "lesson"), null, $this->editoroptions);
+            $mform->setType('contents_editor', PARAM_CLEANHTML);
+        }
+
+        $this->custom_definition();
+
+        if ($this->_customdata['edit'] === true) {
+            $mform->addElement('hidden', 'edit', 1);
+            $this->add_action_buttons(get_string('cancel'), get_string("savepage", "lesson"));
+        } else {
+            $this->add_action_buttons(get_string('cancel'), get_string("addaquestionpage", "lesson"));
+        }
+    }
+
+    /**
+     * Convenience function: Adds a jumpto select element
+     *
+     * @param string $name
+     * @param string|null $label
+     * @param int $selected The page to select by default
+     */
+    protected final function add_jumpto($name, $label=null, $selected=LESSON_NEXTPAGE) {
+        $title = get_string("jump", "lesson");
+        if ($label === null) {
+            $label = $title;
+        }
+        if (is_int($name)) {
+            $name = "jumpto[$name]";
+        }
+        $this->_form->addElement('select', $name, $label, $this->_customdata['jumpto']);
+        $this->_form->setDefault($name, $selected);
+        $this->_form->setHelpButton($name, array("jumpto", $title, "lesson"));
+    }
+
+    /**
+     * Convenience function: Adds a score input element
+     *
+     * @param string $name
+     * @param string|null $label
+     * @param mixed $value The default value
+     */
+    protected final function add_score($name, $label=null, $value=null) {
+        if ($label === null) {
+            $label = get_string("score", "lesson");
+        }
+        if (is_int($name)) {
+            $name = "score[$name]";
+        }
+        $this->_form->addElement('text', $name, $label, array('size'=>5));
+        if ($value !== null) {
+            $this->_form->setDefault($name, $value);
+        }
+    }
+
+    /**
+     * Convenience function: Adds a textarea element
+     *
+     * @param string $name
+     * @param int $count The count of the element to add
+     * @param string|null $label
+     */
+    protected final function add_textarea($name, $count, $label) {
+        $this->_form->addElement('textarea', $name.'['.$count.']', $label, array('rows'=>5, 'cols'=>70, 'width'=>630, 'height'=>300));
+    }
+    /**
+     * Convenience function: Adds an answer textarea
+     *
+     * @param int $count The count of the element to add
+     */
+    protected final function add_answer($count) {
+        $this->add_textarea('answer', $count, get_string('answer', 'lesson'));
+    }
+    /**
+     * Convenience function: Adds an response textarea
+     *
+     * @param int $count The count of the element to add
+     */
+    protected final function add_response($count) {
+        $this->add_textarea('response', $count, get_string('response', 'lesson'));
+    }
+
+    /**
+     * A function that gets called upon init of this object by the calling script.
+     *
+     * This can be used to process an immediate action if required. Currently it
+     * is only used in special cases by non-standard page types.
+     *
+     * @return bool
+     */
+    public function construction_override() {
+        return true;
+    }
+}
\ No newline at end of file
index 0ef98ef4188098ad71c13101dc3ddffadfd8604f..e544254b1e349626ca847f994b7f65586bcfc745 100644 (file)
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Local library file for Lesson.  These are non-standard functions that are used
  * only by Lesson.
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
-/**
-* Next page -> any page not seen before
-*/
-if (!defined("LESSON_UNSEENPAGE")) {
-    define("LESSON_UNSEENPAGE", 1); // Next page -> any page not seen before
-}
-/**
-* Next page -> any page not answered correctly
-*/
-if (!defined("LESSON_UNANSWEREDPAGE")) {
-    define("LESSON_UNANSWEREDPAGE", 2); // Next page -> any page not answered correctly
-}
-
-/**
-* Define different lesson flows for next page
-*/
-$LESSON_NEXTPAGE_ACTION = array (0 => get_string("normal", "lesson"),
-                          LESSON_UNSEENPAGE => get_string("showanunseenpage", "lesson"),
-                          LESSON_UNANSWEREDPAGE => get_string("showanunansweredpage", "lesson") );
-
-// Lesson jump types defined
-//  TODO: instead of using define statements, create an array with all the jump values
-
-/**
- * Jump to Next Page
- */
-if (!defined("LESSON_NEXTPAGE")) {
-    define("LESSON_NEXTPAGE", -1);
-}
-/**
- * End of Lesson
- */
-if (!defined("LESSON_EOL")) {
-    define("LESSON_EOL", -9);
-}
-/**
- * Jump to an unseen page within a branch and end of branch or end of lesson
- */
-if (!defined("LESSON_UNSEENBRANCHPAGE")) {
-    define("LESSON_UNSEENBRANCHPAGE", -50);
-}
-/**
- * Jump to Previous Page
- */
-if (!defined("LESSON_PREVIOUSPAGE")) {
-    define("LESSON_PREVIOUSPAGE", -40);
-}
-/**
- * Jump to a random page within a branch and end of branch or end of lesson
- */
-if (!defined("LESSON_RANDOMPAGE")) {
-    define("LESSON_RANDOMPAGE", -60);
-}
-/**
- * Jump to a random Branch
- */
-if (!defined("LESSON_RANDOMBRANCH")) {
-    define("LESSON_RANDOMBRANCH", -70);
-}
-/**
- * Cluster Jump
- */
-if (!defined("LESSON_CLUSTERJUMP")) {
-    define("LESSON_CLUSTERJUMP", -80);
-}
-/**
- * Undefined
- */
-if (!defined("LESSON_UNDEFINED")) {
-    define("LESSON_UNDEFINED", -99);
-}
-
-// Lesson question types defined
-
-/**
- * Short answer question type
- */
-if (!defined("LESSON_SHORTANSWER")) {
-    define("LESSON_SHORTANSWER",   "1");
-}
-/**
- * True/False question type
- */
-if (!defined("LESSON_TRUEFALSE")) {
-    define("LESSON_TRUEFALSE",     "2");
-}
-/**
- * Multichoice question type
- *
- * If you change the value of this then you need
- * to change it in restorelib.php as well.
- */
-if (!defined("LESSON_MULTICHOICE")) {
-    define("LESSON_MULTICHOICE",   "3");
-}
-/**
- * Random question type - not used
- */
-if (!defined("LESSON_RANDOM")) {
-    define("LESSON_RANDOM",        "4");
-}
-/**
- * Matching question type
- *
- * If you change the value of this then you need
- * to change it in restorelib.php, in mysql.php
- * and postgres7.php as well.
- */
-if (!defined("LESSON_MATCHING")) {
-    define("LESSON_MATCHING",      "5");
-}
-/**
- * Not sure - not used
- */
-if (!defined("LESSON_RANDOMSAMATCH")) {
-    define("LESSON_RANDOMSAMATCH", "6");
-}
-/**
- * Not sure - not used
- */
-if (!defined("LESSON_DESCRIPTION")) {
-    define("LESSON_DESCRIPTION",   "7");
-}
-/**
- * Numerical question type
- */
-if (!defined("LESSON_NUMERICAL")) {
-    define("LESSON_NUMERICAL",     "8");
-}
-/**
- * Multichoice with multianswer question type
- */
-if (!defined("LESSON_MULTIANSWER")) {
-    define("LESSON_MULTIANSWER",   "9");
-}
-/**
- * Essay question type
- */
-if (!defined("LESSON_ESSAY")) {
-    define("LESSON_ESSAY", "10");
-}
-
-/**
- * Lesson question type array.
- * Contains all question types used
- */
-$LESSON_QUESTION_TYPE = array ( LESSON_MULTICHOICE => get_string("multichoice", "quiz"),
-                              LESSON_TRUEFALSE     => get_string("truefalse", "quiz"),
-                              LESSON_SHORTANSWER   => get_string("shortanswer", "quiz"),
-                              LESSON_NUMERICAL     => get_string("numerical", "quiz"),
-                              LESSON_MATCHING      => get_string("match", "quiz"),
-                              LESSON_ESSAY           => get_string("essay", "lesson")
-//                            LESSON_DESCRIPTION   => get_string("description", "quiz"),
-//                            LESSON_RANDOM        => get_string("random", "quiz"),
-//                            LESSON_RANDOMSAMATCH => get_string("randomsamatch", "quiz"),
-//                            LESSON_MULTIANSWER   => get_string("multianswer", "quiz"),
-                              );
-
-// Non-question page types
-
-/**
- * Branch Table page
- */
-if (!defined("LESSON_BRANCHTABLE")) {
-    define("LESSON_BRANCHTABLE",   "20");
-}
-/**
- * End of Branch page
- */
-if (!defined("LESSON_ENDOFBRANCH")) {
-    define("LESSON_ENDOFBRANCH",   "21");
-}
-/**
- * Start of Cluster page
- */
-if (!defined("LESSON_CLUSTER")) {
-    define("LESSON_CLUSTER",   "30");
-}
-/**
- * End of Cluster page
- */
-if (!defined("LESSON_ENDOFCLUSTER")) {
-    define("LESSON_ENDOFCLUSTER",   "31");
-}
-
-// other variables...
-
-/**
- * Flag for the editor for the answer textarea.
- */
-if (!defined("LESSON_ANSWER_EDITOR")) {
-    define("LESSON_ANSWER_EDITOR",   "1");
-}
-/**
- * Flag for the editor for the response textarea.
- */
-if (!defined("LESSON_RESPONSE_EDITOR")) {
-    define("LESSON_RESPONSE_EDITOR",   "2");
-}
+/** Make sure this isn't being directly accessed */
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page.
+}
+
+/** Include the files that are required by this module */
+require_once($CFG->dirroot . '/mod/lesson/lib.php');
+
+/** Next page -> any page not seen before */
+define("LESSON_UNSEENPAGE", 1);
+/** Next page -> any page not answered correctly */
+define("LESSON_UNANSWEREDPAGE", 2);
+/** Jump to Next Page */
+define("LESSON_NEXTPAGE", -1);
+/** End of Lesson */
+define("LESSON_EOL", -9);
+/** Jump to an unseen page within a branch and end of branch or end of lesson */
+define("LESSON_UNSEENBRANCHPAGE", -50);
+/** Jump to Previous Page */
+define("LESSON_PREVIOUSPAGE", -40);
+/** Jump to a random page within a branch and end of branch or end of lesson */
+define("LESSON_RANDOMPAGE", -60);
+/** Jump to a random Branch */
+define("LESSON_RANDOMBRANCH", -70);
+/** Cluster Jump */
+define("LESSON_CLUSTERJUMP", -80);
+/** Undefined */
+define("LESSON_UNDEFINED", -99);
 
 //////////////////////////////////////////////////////////////////////////////////////
 /// Any other lesson functions go here.  Each of them must have a name that
 /// starts with lesson_
 
-/**
- * Print the standard header for lesson module
- *
- * This will also print up to three
- * buttons in the breadcrumb, lesson heading
- * lesson tabs, lesson notifications and perhaps
- * a popup with a media file.
- *
- * @param object $cm Course module record object
- * @param object $course Course record object
- * @param object $lesson Lesson record object
- * @param string $currenttab Current tab for the lesson tabs
- * @param boolean $extraeditbuttons Show the extra edit buttons next to the 'Update this lesson' button.
- * @param integer $lessonpageid if $extraeditbuttons is true then you must pass the page id here.
- **/
-function lesson_print_header($cm, $course, $lesson, $currenttab = '', $extraeditbuttons = false, $lessonpageid = NULL) {
-    global $CFG, $PAGE, $OUTPUT;
-
-    $activityname = format_string($lesson->name, true, $course->id);
-
-    if (empty($title)) {
-        $title = "{$course->shortname}: $activityname";
-    }
-
-/// Build the buttons
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    if (has_capability('mod/lesson:edit', $context)) {
-        $buttons = $OUTPUT->update_module_button($cm->id, 'lesson');
-        if ($extraeditbuttons) {
-            if ($lessonpageid === NULL) {
-                print_error('invalidpageid', 'lesson');
-            }
-            if (!empty($lessonpageid) and $lessonpageid != LESSON_EOL) {
-                $buttons .= '<form '.$CFG->frametarget.' method="get" action="'.$CFG->wwwroot.'/mod/lesson/lesson.php">'.
-                            '<input type="hidden" name="id" value="'.$cm->id.'" />'.
-                            '<input type="hidden" name="action" value="editpage" />'.
-                            '<input type="hidden" name="redirect" value="navigation" />'.
-                            '<input type="hidden" name="pageid" value="'.$lessonpageid.'" />'.
-                            '<input type="submit" value="'.get_string('editpagecontent', 'lesson').'" />'.
-                            '</form>';
-            }
-            $buttons = '<span class="edit_buttons">' . $buttons  .'</span>';
-        }
-    } else {
-        $buttons = '&nbsp;';
-    }
-
-/// Header setup
-    $PAGE->set_title($title);
-    $PAGE->set_heading($course->fullname);
-    $PAGE->set_button($buttons);
-    echo $OUTPUT->header();
-
-    if (has_capability('mod/lesson:manage', $context)) {
-
-        $helpicon = new moodle_help_icon();
-        $helpicon->text = $activityname;
-        $helpicon->page = "overview";
-        $helpicon->module = "lesson";
-
-        echo $OUTPUT->heading_with_help($helpicon);
-
-        if (!empty($currenttab)) {
-            include($CFG->dirroot.'/mod/lesson/tabs.php');
-        }
-    } else {
-        echo $OUTPUT->heading($activityname);
-    }
-
-    lesson_print_messages();
-}
-
-/**
- * Returns course module, course and module instance given
- * either the course module ID or a lesson module ID.
- *
- * @param int $cmid Course Module ID
- * @param int $lessonid Lesson module instance ID
- * @return array array($cm, $course, $lesson)
- **/
-function lesson_get_basics($cmid = 0, $lessonid = 0) {
-    global $DB;
-
-    if ($cmid) {
-        if (!$cm = get_coursemodule_from_id('lesson', $cmid)) {
-            print_error('invalidcoursemodule');
-        }
-        if (!$course = $DB->get_record('course', array('id' => $cm->course))) {
-            print_error('coursemisconf');
-        }
-        if (!$lesson = $DB->get_record('lesson', array('id' => $cm->instance))) {
-            print_error('invalidcoursemodule');
-        }
-    } else if ($lessonid) {
-        if (!$lesson = $DB->get_record('lesson', array('id' => $lessonid))) {
-            print_error('invalidcoursemodule');
-        }
-        if (!$course = $DB->get_record('course', array('id' => $lesson->course))) {
-            print_error('coursemisconf');
-        }
-        if (!$cm = get_coursemodule_from_instance('lesson', $lesson->id, $course->id)) {
-            print_error('invalidcoursemodule');
-        }
-    } else {
-        print_error('invalidid', 'lesson');
-    }
-
-    return array($cm, $course, $lesson);
-}
-
-/**
- * Sets a message to be printed.  Messages are printed
- * by calling {@link lesson_print_messages()}.
- *
- * @uses $SESSION
- * @param string $message The message to be printed
- * @param string $class Class to be passed to {@link notify()}.  Usually notifyproblem or notifysuccess.
- * @param string $align Alignment of the message
- * @return boolean
- **/
-function lesson_set_message($message, $class="notifyproblem", $align='center') {
-    global $SESSION;
-
-    if (empty($SESSION->lesson_messages) or !is_array($SESSION->lesson_messages)) {
-        $SESSION->lesson_messages = array();
-    }
-
-    $SESSION->lesson_messages[] = array($message, $class, $align);
-
-    return true;
-}
-
-/**
- * Print all set messages.
- *
- * See {@link lesson_set_message()} for setting messages.
- *
- * Uses {@link notify()} to print the messages.
- *
- * @uses $SESSION
- * @return boolean
- **/
-function lesson_print_messages() {
-    global $SESSION, $OUTPUT;
-
-    if (empty($SESSION->lesson_messages)) {
-        // No messages to print
-        return true;
-    }
-
-    foreach($SESSION->lesson_messages as $message) {
-        echo $OUTPUT->notification($message[0], $message[1], $message[2]);
-    }
-
-    // Reset
-    unset($SESSION->lesson_messages);
-
-    return true;
-}
-
-/**
- * Prints a lesson link that submits a form.
- *
- * If Javascript is disabled, then a regular submit button is printed
- *
- * @param string $name Name of the link or button
- * @param string $form The name of the form to be submitted
- * @param string $align Alignment of the button
- * @param string $class Class names to add to the div wrapper
- * @param string $title Title for the link (Not used if javascript is disabled)
- * @param string $id ID tag
- * @param boolean $return Return flag
- * @return mixed boolean/html
- **/
-function lesson_print_submit_link($name, $form, $align = 'center', $class='standardbutton', $title = '', $id = '', $return = false) {
-    if (!empty($align)) {
-        $align = " style=\"text-align:$align\"";
-    }
-    if (!empty($id)) {
-        $id = " id=\"$id\"";
-    }
-    if (empty($title)) {
-        $title = $name;
-    }
-
-    $output = "<div class=\"lessonbutton $class\" $align>\n";
-    $output .= "<input type=\"submit\" value=\"$name\" $align $id />";
-    $output .= "</div>\n";
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-        return true;
-    }
-}
-
-/**
- * Prints a time remaining in the following format: H:MM:SS
- *
- * @param int $starttime Time when the lesson started
- * @param int $maxtime Length of the lesson
- * @param boolean $return Return output switch
- * @return mixed boolean/string
- **/
-function lesson_print_time_remaining($starttime, $maxtime, $return = false) {
-    // Calculate hours, minutes and seconds
-    $timeleft = $starttime + $maxtime * 60 - time();
-    $hours = floor($timeleft/3600);
-    $timeleft = $timeleft - ($hours * 3600);
-    $minutes = floor($timeleft/60);
-    $secs = $timeleft - ($minutes * 60);
-
-    if ($minutes < 10) {
-        $minutes = "0$minutes";
-    }
-    if ($secs < 10) {
-        $secs = "0$secs";
-    }
-    $output   = array();
-    $output[] = $hours;
-    $output[] = $minutes;
-    $output[] = $secs;
-
-    $output = implode(':', $output);
-
-    if ($return) {
-        return $output;
-    } else {
-        echo $output;
-        return true;
-    }
-}
-
-/**
- * Prints the page action buttons
- *
- * Move/Edit/Preview/Delete
- *
- * @uses $CFG
- * @param int $cmid Course Module ID
- * @param object $page Page record
- * @param boolean $printmove Flag to print the move button or not
- * @param boolean $printaddpage Flag to print the add page drop-down or not
- * @param boolean $return Return flag
- * @return mixed boolean/string
- **/
-function lesson_print_page_actions($cmid, $page, $printmove, $printaddpage = false, $return = false) {
-    global $CFG, $OUTPUT;
-
-    $context = get_context_instance(CONTEXT_MODULE, $cmid);
-    $actions = array();
-
-    if (has_capability('mod/lesson:edit', $context)) {
-        if ($printmove) {
-            $actions[] = "<a title=\"".get_string('move')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=move&amp;pageid=$page->id\">
-                          <img src=\"" . $OUTPUT->old_icon_url('t/move') . "\" class=\"iconsmall\" alt=\"".get_string('move')."\" /></a>\n";
-        }
-        $actions[] = "<a title=\"".get_string('update')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=editpage&amp;pageid=$page->id\">
-                      <img src=\"" . $OUTPUT->old_icon_url('t/edit') . "\" class=\"iconsmall\" alt=\"".get_string('update')."\" /></a>\n";
-
-        $actions[] = "<a title=\"".get_string('preview')."\" href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cmid&amp;pageid=$page->id\">
-                      <img src=\"" . $OUTPUT->old_icon_url('t/preview') . "\" class=\"iconsmall\" alt=\"".get_string('preview')."\" /></a>\n";
-
-        $actions[] = "<a title=\"".get_string('delete')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=confirmdelete&amp;pageid=$page->id\">
-                      <img src=\"" . $OUTPUT->old_icon_url('t/delete') . "\" class=\"iconsmall\" alt=\"".get_string('delete')."\" /></a>\n";
-
-        if ($printaddpage) {
-            // Add page drop-down
-            $options = array();
-            $options['addcluster&amp;sesskey='.sesskey()]      = get_string('clustertitle', 'lesson');
-            $options['addendofcluster&amp;sesskey='.sesskey()] = get_string('endofclustertitle', 'lesson');
-            $options['addbranchtable']                         = get_string('branchtable', 'lesson');
-            $options['addendofbranch&amp;sesskey='.sesskey()]  = get_string('endofbranch', 'lesson');
-            $options['addpage']                                = get_string('question', 'lesson');
-            // Base url
-            $common = "$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&pageid=$page->id";
-            $select = html_select::make_popup_form($common, 'action', $options, "addpage_$page->id");
-            $select->nothinglabel = get_string('addpage', 'lesson').'...';
-
-            $actions[] = $OUTPUT->select($select);
-        }
-    }
-
-    $actions = implode(' ', $actions);
-
-    if ($return) {
-        return $actions;
-    } else {
-        echo $actions;
-        return false;
-    }
-}
-
-/**
- * Prints the add links in expanded view or single view when editing
- *
- * @uses $CFG
- * @param int $cmid Course Module ID
- * @param int $prevpageid Previous page id
- * @param boolean $return Return flag
- * @return mixed boolean/string
- * @todo &amp;pageid does not make sense, it is prevpageid
- **/
-function lesson_print_add_links($cmid, $prevpageid, $return = false) {
-    global $CFG;
-
-    $context = get_context_instance(CONTEXT_MODULE, $cmid);
-
-    $links = '';
-    if (has_capability('mod/lesson:edit', $context)) {
-        $links = array();
-        $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/import.php?id=$cmid&amp;pageid=$prevpageid\">".
-                    get_string('importquestions', 'lesson').'</a>';
-
-        $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addcluster&amp;pageid=$prevpageid\">".
-                    get_string('addcluster', 'lesson').'</a>';
-
-        if ($prevpageid != 0) {
-            $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addendofcluster&amp;pageid=$prevpageid\">".
-                        get_string('addendofcluster', 'lesson').'</a>';
-        }
-        $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=addbranchtable&amp;pageid=$prevpageid\">".
-                    get_string('addabranchtable', 'lesson').'</a>';
-
-        if ($prevpageid != 0) {
-            $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addendofbranch&amp;pageid=$prevpageid\">".
-                        get_string('addanendofbranch', 'lesson').'</a>';
-        }
-
-        $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=addpage&amp;pageid=$prevpageid\">".
-                    get_string('addaquestionpagehere', 'lesson').'</a>';
-
-        $links = implode(" | \n", $links);
-        $links = "\n<div class=\"addlinks\">\n$links\n</div>\n";
-    }
-
-    if ($return) {
-        return $links;
-    } else {
-        echo $links;
-        return true;
-    }
-}
-
-/**
- * Returns the string for a page type
- *
- * @uses $LESSON_QUESTION_TYPE
- * @param int $qtype Page type
- * @return string
- **/
-function lesson_get_qtype_name($qtype) {
-    global $LESSON_QUESTION_TYPE;
-    switch ($qtype) {
-        case LESSON_ESSAY :
-        case LESSON_SHORTANSWER :
-        case LESSON_MULTICHOICE :
-        case LESSON_MATCHING :
-        case LESSON_TRUEFALSE :
-        case LESSON_NUMERICAL :
-            return $LESSON_QUESTION_TYPE[$qtype];
-            break;
-        case LESSON_BRANCHTABLE :
-            return get_string("branchtable", "lesson");
-            break;
-        case LESSON_ENDOFBRANCH :
-            return get_string("endofbranch", "lesson");
-            break;
-        case LESSON_CLUSTER :
-            return get_string("clustertitle", "lesson");
-            break;
-        case LESSON_ENDOFCLUSTER :
-            return get_string("endofclustertitle", "lesson");
-            break;
-        default:
-            return '';
-            break;
-    }
-}
-
-/**
- * Returns the string for a jump name
- *
- * @param int $jumpto Jump code or page ID
- * @return string
- **/
-function lesson_get_jump_name($jumpto) {
-    global $DB;
-
-    if ($jumpto == 0) {
-        $jumptitle = get_string('thispage', 'lesson');
-    } elseif ($jumpto == LESSON_NEXTPAGE) {
-        $jumptitle = get_string('nextpage', 'lesson');
-    } elseif ($jumpto == LESSON_EOL) {
-        $jumptitle = get_string('endoflesson', 'lesson');
-    } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
-        $jumptitle = get_string('unseenpageinbranch', 'lesson');
-    } elseif ($jumpto == LESSON_PREVIOUSPAGE) {
-        $jumptitle = get_string('previouspage', 'lesson');
-    } elseif ($jumpto == LESSON_RANDOMPAGE) {
-        $jumptitle = get_string('randompageinbranch', 'lesson');
-    } elseif ($jumpto == LESSON_RANDOMBRANCH) {
-        $jumptitle = get_string('randombranch', 'lesson');
-    } elseif ($jumpto == LESSON_CLUSTERJUMP) {
-        $jumptitle = get_string('clusterjump', 'lesson');
-    } else {
-        if (!$jumptitle = $DB->get_field('lesson_pages', 'title', array('id' => $jumpto))) {
-            $jumptitle = '<strong>'.get_string('notdefined', 'lesson').'</strong>';
-        }
-    }
-
-    return format_string($jumptitle,true);
-}
-
-/**
- * Given some question info and some data about the the answers
- * this function parses, organises and saves the question
- *
- * This is only used when IMPORTING questions and is only called
- * from format.php
- * Lifted from mod/quiz/lib.php -
- *    1. all reference to oldanswers removed
- *    2. all reference to quiz_multichoice table removed
- *    3. In SHORTANSWER questions usecase is store in the qoption field
- *    4. In NUMERIC questions store the range as two answers
- *    5. TRUEFALSE options are ignored
- *    6. For MULTICHOICE questions with more than one answer the qoption field is true
- *
- * @param opject $question Contains question data like question, type and answers.
- * @return object Returns $result->error or $result->notice.
- **/
-function lesson_save_question_options($question) {
-    global $DB;
-
-    $timenow = time();
-    switch ($question->qtype) {
-        case LESSON_SHORTANSWER:
-
-            $answers = array();
-            $maxfraction = -1;
-
-            // Insert all the new answers
-            foreach ($question->answer as $key => $dataanswer) {
-                if ($dataanswer != "") {
-                    $answer = new stdClass;
-                    $answer->lessonid   = $question->lessonid;
-                    $answer->pageid   = $question->id;
-                    if ($question->fraction[$key] >=0.5) {
-                        $answer->jumpto = LESSON_NEXTPAGE;
-                    }
-                    $answer->timecreated   = $timenow;
-                    $answer->grade = $question->fraction[$key] * 100;
-                    $answer->answer   = $dataanswer;
-                    $answer->response = $question->feedback[$key];
-                    $answer->id = $DB->insert_record("lesson_answers", $answer);
-                    $answers[] = $answer->id;
-                    if ($question->fraction[$key] > $maxfraction) {
-                        $maxfraction = $question->fraction[$key];
-                    }
-                }
-            }
-
-
-            /// Perform sanity checks on fractional grades
-            if ($maxfraction != 1) {
-                $maxfraction = $maxfraction * 100;
-                $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
-                return $result;
-            }
-            break;
-
-        case LESSON_NUMERICAL:   // Note similarities to SHORTANSWER
-
-            $answers = array();
-            $maxfraction = -1;
-
-
-            // for each answer store the pair of min and max values even if they are the same
-            foreach ($question->answer as $key => $dataanswer) {
-                if ($dataanswer != "") {
-                    $answer = new stdClass;
-                    $answer->lessonid   = $question->lessonid;
-                    $answer->pageid   = $question->id;
-                    $answer->jumpto = LESSON_NEXTPAGE;
-                    $answer->timecreated   = $timenow;
-                    $answer->grade = $question->fraction[$key] * 100;
-                    $min = $question->answer[$key] - $question->tolerance[$key];
-                    $max = $question->answer[$key] + $question->tolerance[$key];
-                    $answer->answer   = $min.":".$max;
-                    // $answer->answer   = $question->min[$key].":".$question->max[$key]; original line for min/max
-                    $answer->response = $question->feedback[$key];
-                    $answer->id = $DB->insert_record("lesson_answers", $answer);
-
-                    $answers[] = $answer->id;
-                    if ($question->fraction[$key] > $maxfraction) {
-                        $maxfraction = $question->fraction[$key];
-                    }
-                }
-            }
-
-            /// Perform sanity checks on fractional grades
-            if ($maxfraction != 1) {
-                $maxfraction = $maxfraction * 100;
-                $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
-                return $result;
-            }
-        break;
-
-
-        case LESSON_TRUEFALSE:
-
-            // the truth
-            $answer->lessonid   = $question->lessonid;
-            $answer->pageid = $question->id;
-            $answer->timecreated   = $timenow;
-            $answer->answer = get_string("true", "quiz");
-            $answer->grade = $question->answer * 100;
-            if ($answer->grade > 50 ) {
-                $answer->jumpto = LESSON_NEXTPAGE;
-            }
-            if (isset($question->feedbacktrue)) {
-                $answer->response = $question->feedbacktrue;
-            }
-            $true->id = $DB->insert_record("lesson_answers", $answer);
-
-            // the lie
-            $answer = new stdClass;
-            $answer->lessonid   = $question->lessonid;
-            $answer->pageid = $question->id;
-            $answer->timecreated   = $timenow;
-            $answer->answer = get_string("false", "quiz");
-            $answer->grade = (1 - (int)$question->answer) * 100;
-            if ($answer->grade > 50 ) {
-                $answer->jumpto = LESSON_NEXTPAGE;
-            }
-            if (isset($question->feedbackfalse)) {
-                $answer->response = $question->feedbackfalse;
-            }
-            $false->id = $DB->insert_record("lesson_answers", $answer);
-
-          break;
-
-
-        case LESSON_MULTICHOICE:
-
-            $totalfraction = 0;
-            $maxfraction = -1;
-
-            $answers = array();
-
-            // Insert all the new answers
-            foreach ($question->answer as $key => $dataanswer) {
-                if ($dataanswer != "") {
-                    $answer = new stdClass;
-                    $answer->lessonid   = $question->lessonid;
-                    $answer->pageid   = $question->id;
-                    $answer->timecreated   = $timenow;
-                    $answer->grade = $question->fraction[$key] * 100;
-                    // changed some defaults
-                    /* Original Code
-                    if ($answer->grade > 50 ) {
-                        $answer->jumpto = LESSON_NEXTPAGE;
-                    }
-                    Replaced with:                    */
-                    if ($answer->grade > 50 ) {
-                        $answer->jumpto = LESSON_NEXTPAGE;
-                        $answer->score = 1;
-                    }
-                    // end Replace
-                    $answer->answer   = $dataanswer;
-                    $answer->response = $question->feedback[$key];
-                    $answer->id = $DB->insert_record("lesson_answers", $answer);
-                    // for Sanity checks
-                    if ($question->fraction[$key] > 0) {
-                        $totalfraction += $question->fraction[$key];
-                    }
-                    if ($question->fraction[$key] > $maxfraction) {
-                        $maxfraction = $question->fraction[$key];
-                    }
-                }
-            }
-
-            /// Perform sanity checks on fractional grades
-            if ($question->single) {
-                if ($maxfraction != 1) {
-                    $maxfraction = $maxfraction * 100;
-                    $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
-                    return $result;
-                }
-            } else {
-                $totalfraction = round($totalfraction,2);
-                if ($totalfraction != 1) {
-                    $totalfraction = $totalfraction * 100;
-                    $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
-                    return $result;
-                }
-            }
-        break;
-
-        case LESSON_MATCHING:
-
-            $subquestions = array();
-
-            $i = 0;
-            // Insert all the new question+answer pairs
-            foreach ($question->subquestions as $key => $questiontext) {
-                $answertext = $question->subanswers[$key];
-                if (!empty($questiontext) and !empty($answertext)) {
-                    $answer = new stdClass;
-                    $answer->lessonid   = $question->lessonid;
-                    $answer->pageid   = $question->id;
-                    $answer->timecreated   = $timenow;
-                    $answer->answer = $questiontext;
-                    $answer->response   = $answertext;
-                    if ($i == 0) {
-                        // first answer contains the correct answer jump
-                        $answer->jumpto = LESSON_NEXTPAGE;
-                    }
-                    $subquestion->id = $DB->insert_record("lesson_answers", $answer);
-                    $subquestions[] = $subquestion->id;
-                    $i++;
-                }
-            }
-
-            if (count($subquestions) < 3) {
-                $result->notice = get_string("notenoughsubquestions", "quiz");
-                return $result;
-            }
-
-            break;
-
-
-        case LESSON_RANDOMSAMATCH:
-            $options->question = $question->id;
-            $options->choose = $question->choose;
-            if ($existing = $DB->get_record("quiz_randomsamatch", array("question" => $options->question))) {
-                $options->id = $existing->id;
-                $DB->update_record("quiz_randomsamatch", $options);
-            } else {
-                $DB->insert_record("quiz_randomsamatch", $options);
-            }
-        break;
-
-        case LESSON_MULTIANSWER:
-            if (!$oldmultianswers = $DB->get_records("quiz_multianswers", array("question" => $question->id), "id ASC")) {
-                $oldmultianswers = array();
-            }
-
-            // Insert all the new multi answers
-            foreach ($question->answers as $dataanswer) {
-                if ($oldmultianswer = array_shift($oldmultianswers)) {  // Existing answer, so reuse it
-                    $multianswer = $oldmultianswer;
-                    $multianswer->positionkey = $dataanswer->positionkey;
-                    $multianswer->norm = $dataanswer->norm;
-                    $multianswer->answertype = $dataanswer->answertype;
-
-                    if (! $multianswer->answers = quiz_save_multianswer_alternatives
-                            ($question->id, $dataanswer->answertype,
-                             $dataanswer->alternatives, $oldmultianswer->answers))
-                    {
-                        $result->error = "Could not update multianswer alternatives! (id=$multianswer->id)";
-                        return $result;
-                    }
-                    $DB->update_record("quiz_multianswers", $multianswer);
-                } else {    // This is a completely new answer
-                    $multianswer = new stdClass;
-                    $multianswer->question = $question->id;
-                    $multianswer->positionkey = $dataanswer->positionkey;
-                    $multianswer->norm = $dataanswer->norm;
-                    $multianswer->answertype = $dataanswer->answertype;
-
-                    if (! $multianswer->answers = quiz_save_multianswer_alternatives
-                            ($question->id, $dataanswer->answertype,
-                             $dataanswer->alternatives))
-                    {
-                        $result->error = "Could not insert multianswer alternatives! (questionid=$question->id)";
-                        return $result;
-                    }
-                    $DB->insert_record("quiz_multianswers", $multianswer);
-                }
-            }
-        break;
-
-        case LESSON_RANDOM:
-        break;
-
-        case LESSON_DESCRIPTION:
-        break;
-
-        default:
-            $result->error = "Unsupported question type ($question->qtype)!";
-            return $result;
-        break;
-    }
-    return true;
-}
-
-/**
- * Determins if a jumpto value is correct or not.
- *
- * returns true if jumpto page is (logically) after the pageid page or
- * if the jumpto value is a special value.  Returns false in all other cases.
- *
- * @param int $pageid Id of the page from which you are jumping from.
- * @param int $jumpto The jumpto number.
- * @return boolean True or false after a series of tests.
- **/
-function lesson_iscorrect($pageid, $jumpto) {
-    global $DB;
-
-    // first test the special values
-    if (!$jumpto) {
-        // same page
-        return false;
-    } elseif ($jumpto == LESSON_NEXTPAGE) {
-        return true;
-    } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
-        return true;
-    } elseif ($jumpto == LESSON_RANDOMPAGE) {
-        return true;
-    } elseif ($jumpto == LESSON_CLUSTERJUMP) {
-        return true;
-    } elseif ($jumpto == LESSON_EOL) {
-        return true;
-    }
-    // we have to run through the pages from pageid looking for jumpid
-    if ($lessonid = $DB->get_field('lesson_pages', 'lessonid', array('id' => $pageid))) {
-        if ($pages = $DB->get_records('lesson_pages', array('lessonid' => $lessonid), '', 'id, nextpageid')) {
-            $apageid = $pages[$pageid]->nextpageid;
-            while ($apageid != 0) {
-                if ($jumpto == $apageid) {
-                    return true;
-                }
-                $apageid = $pages[$apageid]->nextpageid;
-            }
-        }
-    }
-    return false;
-}
-
-/**
- * Checks to see if a page is a branch table or is
- * a page that is enclosed by a branch table and an end of branch or end of lesson.
- * May call this function: {@link lesson_is_page_in_branch()}
- *
- * @param int $lesson Id of the lesson to which the page belongs.
- * @param int $pageid Id of the page.
- * @return boolean True or false.
- **/
-function lesson_display_branch_jumps($lessonid, $pageid) {
-    global $DB;
-
-    if($pageid == 0) {
-        // first page
-        return false;
-    }
-    // get all of the lesson pages
-    $params = array ("lessonid" => $lessonid);
-    if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
-        // adding first page
-        return false;
-    }
-
-    if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
-        return true;
-    }
-
-    return lesson_is_page_in_branch($lessonpages, $pageid);
-}
-
-/**
- * Checks to see if a page is a cluster page or is
- * a page that is enclosed by a cluster page and an end of cluster or end of lesson
- * May call this function: {@link lesson_is_page_in_cluster()}
- *
- * @param int $lesson Id of the lesson to which the page belongs.
- * @param int $pageid Id of the page.
- * @return boolean True or false.
- **/
-function lesson_display_cluster_jump($lesson, $pageid) {
-    global $DB;
-
-    if($pageid == 0) {
-        // first page
-        return false;
-    }
-    // get all of the lesson pages
-    $params = array ("lessonid" => $lesson);
-    if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
-        // adding first page
-        return false;
-    }
-
-    if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
-        return true;
-    }
-
-    return lesson_is_page_in_cluster($lessonpages, $pageid);
-
-}
-
 /**
  * Checks to see if a LESSON_CLUSTERJUMP or
  * a LESSON_UNSEENBRANCHPAGE is used in a lesson.
@@ -1028,7 +71,7 @@ function lesson_display_teacher_warning($lesson) {
     global $DB;
 
     // get all of the lesson answers
-    $params = array ("lessonid" => $lesson);
+    $params = array ("lessonid" => $lesson->id);
     if (!$lessonanswers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid", $params)) {
         // no answers, then not useing cluster or unseen
         return false;
@@ -1044,148 +87,12 @@ function lesson_display_teacher_warning($lesson) {
     return false;
 }
 
-
-/**
- * Interprets LESSON_CLUSTERJUMP jumpto value.
- *
- * This will select a page randomly
- * and the page selected will be inbetween a cluster page and end of cluter or end of lesson
- * and the page selected will be a page that has not been viewed already
- * and if any pages are within a branch table or end of branch then only 1 page within
- * the branch table or end of branch will be randomly selected (sub clustering).
- *
- * @param int $lessonid Id of the lesson.
- * @param int $userid Id of the user.
- * @param int $pageid Id of the current page from which we are jumping from.
- * @return int The id of the next page.
- **/
-function lesson_cluster_jump($lessonid, $userid, $pageid) {
-    global $DB;
-
-    // get the number of retakes
-    if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$lessonid, "userid"=>$userid))) {
-        $retakes = 0;
-    }
-
-    // get all the lesson_attempts aka what the user has seen
-    $params = array ("lessonid" => $lessonid, "userid" => $userid, "retry" => $retakes);
-    if ($seen = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, "timeseen DESC")) {
-        foreach ($seen as $value) { // load it into an array that I can more easily use
-            $seenpages[$value->pageid] = $value->pageid;
-        }
-    } else {
-        $seenpages = array();
-    }
-
-    // get the lesson pages
-    if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
-        print_error('cannotfindrecords', 'lesson');
-    }
-    // find the start of the cluster
-    while ($pageid != 0) { // this condition should not be satisfied... should be a cluster page
-        if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
-            break;
-        }
-        $pageid = $lessonpages[$pageid]->prevpageid;
-    }
-
-    $pageid = $lessonpages[$pageid]->nextpageid; // move down from the cluster page
-
-    $clusterpages = array();
-    while (true) {  // now load all the pages into the cluster that are not already inside of a branch table.
-        if ($lessonpages[$pageid]->qtype == LESSON_ENDOFCLUSTER) {
-            // store the endofcluster page's jump
-            $exitjump = $DB->get_field("lesson_answers", "jumpto", array("pageid" => $pageid, "lessonid" => $lessonid));
-            if ($exitjump == LESSON_NEXTPAGE) {
-                $exitjump = $lessonpages[$pageid]->nextpageid;
-            }
-            if ($exitjump == 0) {
-                $exitjump = LESSON_EOL;
-            }
-            break;
-        } elseif (!lesson_is_page_in_branch($lessonpages, $pageid) && $lessonpages[$pageid]->qtype != LESSON_ENDOFBRANCH) {
-            // load page into array when it is not in a branch table and when it is not an endofbranch
-            $clusterpages[] = $lessonpages[$pageid];
-        }
-        if ($lessonpages[$pageid]->nextpageid == 0) {
-            // shouldn't ever get here... should be using endofcluster
-            $exitjump = LESSON_EOL;
-            break;
-        } else {
-            $pageid = $lessonpages[$pageid]->nextpageid;
-        }
-    }
-
-    // filter out the ones we have seen
-    $unseen = array();
-    foreach ($clusterpages as $clusterpage) {
-        if ($clusterpage->qtype == LESSON_BRANCHTABLE) {            // if branchtable, check to see if any pages inside have been viewed
-            $branchpages = lesson_pages_in_branch($lessonpages, $clusterpage->id); // get the pages in the branchtable
-            $flag = true;
-            foreach ($branchpages as $branchpage) {
-                if (array_key_exists($branchpage->id, $seenpages)) {  // check if any of the pages have been viewed
-                    $flag = false;
-                }
-            }
-            if ($flag && count($branchpages) > 0) {
-                // add branch table
-                $unseen[] = $clusterpage;
-            }
-        } else {
-            // add any other type of page that has not already been viewed
-            if (!array_key_exists($clusterpage->id, $seenpages)) {
-                $unseen[] = $clusterpage;
-            }
-        }
-    }
-
-    if (count($unseen) > 0) { // it does not contain elements, then use exitjump, otherwise find out next page/branch
-        $nextpage = $unseen[rand(0, count($unseen)-1)];
-    } else {
-        return $exitjump; // seen all there is to see, leave the cluster
-    }
-
-    if ($nextpage->qtype == LESSON_BRANCHTABLE) { // if branch table, then pick a random page inside of it
-        $branchpages = lesson_pages_in_branch($lessonpages, $nextpage->id);
-        return $branchpages[rand(0, count($branchpages)-1)]->id;
-    } else { // otherwise, return the page's id
-        return $nextpage->id;
-    }
-}
-
-/**
- * Returns pages that are within a branch table and another branch table, end of branch or end of lesson
- *
- * @param array $lessonpages An array of lesson page objects.
- * @param int $branchid The id of the branch table that we would like the containing pages for.
- * @return array An array of lesson page objects.
- **/
-function lesson_pages_in_branch($lessonpages, $branchid) {
-    $pageid = $lessonpages[$branchid]->nextpageid;  // move to the first page after the branch table
-    $pagesinbranch = array();
-
-    while (true) {
-        if ($pageid == 0) { // EOL
-            break;
-        } elseif ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
-            break;
-        } elseif ($lessonpages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
-            break;
-        }
-        $pagesinbranch[] = $lessonpages[$pageid];
-        $pageid = $lessonpages[$pageid]->nextpageid;
-    }
-
-    return $pagesinbranch;
-}
-
 /**
  * Interprets the LESSON_UNSEENBRANCHPAGE jump.
  *
  * will return the pageid of a random unseen page that is within a branch
  *
- * @see lesson_pages_in_branch()
- * @param int $lesson Id of the lesson.
+ * @param lesson $lesson
  * @param int $userid Id of the user.
  * @param int $pageid Id of the page from which we are jumping.
  * @return int Id of the next page.
@@ -1194,13 +101,12 @@ function lesson_unseen_question_jump($lesson, $user, $pageid) {
     global $DB;
 
     // get the number of retakes
-    if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson, "userid"=>$user))) {
+    if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$user))) {
         $retakes = 0;
     }
 
     // get all the lesson_attempts aka what the user has seen
-    $params = array ("lessonid" => $lesson, "userid" => $user, "retry" => $retakes);
-    if ($viewedpages = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, "timeseen DESC")) {
+    if ($viewedpages = $DB->get_records("lesson_attempts", array("lessonid"=>$lesson->id, "userid"=>$user, "retry"=>$retakes), "timeseen DESC")) {
         foreach($viewedpages as $viewed) {
             $seenpages[] = $viewed->pageid;
         }
@@ -1209,9 +115,7 @@ function lesson_unseen_question_jump($lesson, $user, $pageid) {
     }
 
     // get the lesson pages
-    if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
-        print_error('cannotfindpages', 'lesson');
-    }
+    $lessonpages = $lesson->load_all_pages();
 
     if ($pageid == LESSON_UNSEENBRANCHPAGE) {  // this only happens when a student leaves in the middle of an unseen question within a branch series
         $pageid = $seenpages[0];  // just change the pageid to the last page viewed inside the branch table
@@ -1219,13 +123,13 @@ function lesson_unseen_question_jump($lesson, $user, $pageid) {
 
     // go up the pages till branch table
     while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
-        if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
+        if ($lessonpages[$pageid]->qtype == LESSON_PAGE_BRANCHTABLE) {
             break;
         }
         $pageid = $lessonpages[$pageid]->prevpageid;
     }
 
-    $pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
+    $pagesinbranch = $this->get_sub_pages_of($pageid, array(LESSON_PAGE_BRANCHTABLE, LESSON_PAGE_ENDOFBRANCH));
 
     // this foreach loop stores all the pages that are within the branch table but are not in the $seenpages array
     $unseen = array();
@@ -1256,27 +160,25 @@ function lesson_unseen_question_jump($lesson, $user, $pageid) {
 /**
  * Handles the unseen branch table jump.
  *
- * @param int $lessonid Lesson id.
+ * @param lesson $lesson
  * @param int $userid User id.
  * @return int Will return the page id of a branch table or end of lesson
  **/
-function lesson_unseen_branch_jump($lessonid, $userid) {
+function lesson_unseen_branch_jump($lesson, $userid) {
     global $DB;
 
-    if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$lessonid, "userid"=>$userid))) {
+    if (!$retakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$userid))) {
         $retakes = 0;
     }
 
-    $params = array ("lessonid" => $lessonid, "userid" => $userid, "retry" => $retakes);
+    $params = array ("lessonid" => $lesson->id, "userid" => $userid, "retry" => $retakes);
     if (!$seenbranches = $DB->get_records_select("lesson_branch", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params,
                 "timeseen DESC")) {
         print_error('cannotfindrecords', 'lesson');
     }
 
     // get the lesson pages
-    if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
-        print_error('cannotfindpages', 'lesson');
-    }
+    $lessonpages = $lesson->load_all_pages();
 
     // this loads all the viewed branch tables into $seen untill it finds the branch table with the flag
     // which is the branch table that starts the unseenbranch function
@@ -1293,7 +195,7 @@ function lesson_unseen_branch_jump($lessonid, $userid) {
     // that follow the flagged branch table
     $pageid = $lessonpages[$start]->nextpageid; // move down from the flagged branch table
     while ($pageid != 0) {  // grab all of the branch table till eol
-        if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
+        if ($lessonpages[$pageid]->qtype == LESSON_PAGE_BRANCHTABLE) {
             $branchtables[] = $lessonpages[$pageid]->id;
         }
         $pageid = $lessonpages[$pageid]->nextpageid;
@@ -1315,15 +217,15 @@ function lesson_unseen_branch_jump($lessonid, $userid) {
 /**
  * Handles the random jump between a branch table and end of branch or end of lesson (LESSON_RANDOMPAGE).
  *
- * @param int $lessonid Lesson id.
+ * @param lesson $lesson
  * @param int $pageid The id of the page that we are jumping from (?)
  * @return int The pageid of a random page that is within a branch table
  **/
-function lesson_random_question_jump($lessonid, $pageid) {
+function lesson_random_question_jump($lesson, $pageid) {
     global $DB;
 
     // get the lesson pages
-    $params = array ("lessonid" => $lessonid);
+    $params = array ("lessonid" => $lesson->id);
     if (!$lessonpages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid", $params)) {
         print_error('cannotfindpages', 'lesson');
     }
@@ -1331,14 +233,14 @@ function lesson_random_question_jump($lessonid, $pageid) {
     // go up the pages till branch table
     while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
 
-        if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
+        if ($lessonpages[$pageid]->qtype == LESSON_PAGE_BRANCHTABLE) {
             break;
         }
         $pageid = $lessonpages[$pageid]->prevpageid;
     }
 
     // get the pages within the branch
-    $pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
+    $pagesinbranch = $this->get_sub_pages_of($pageid, array(LESSON_PAGE_BRANCHTABLE, LESSON_PAGE_ENDOFBRANCH));
 
     if(count($pagesinbranch) == 0) {
         // there are no pages inside the branch, so return the next page
@@ -1348,63 +250,6 @@ function lesson_random_question_jump($lessonid, $pageid) {
     }
 }
 
-/**
- * Check to see if a page is below a branch table (logically).
- *
- * Will return true if a branch table is found logically above the page.
- * Will return false if an end of branch, cluster or the beginning
- * of the lesson is found before a branch table.
- *
- * @param array $pages An array of lesson page objects.
- * @param int $pageid Id of the page for testing.
- * @return boolean
- */
-function lesson_is_page_in_branch($pages, $pageid) {
-    $pageid = $pages[$pageid]->prevpageid; // move up one
-
-    // go up the pages till branch table
-    while (true) {
-        if ($pageid == 0) {  // ran into the beginning of the lesson
-            return false;
-        } elseif ($pages[$pageid]->qtype == LESSON_ENDOFBRANCH) { // ran into the end of another branch table
-            return false;
-        } elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // do not look beyond a cluster
-            return false;
-        } elseif ($pages[$pageid]->qtype == LESSON_BRANCHTABLE) { // hit a branch table
-            return true;
-        }
-        $pageid = $pages[$pageid]->prevpageid;
-    }
-
-}
-
-/**
- * Check to see if a page is below a cluster page (logically).
- *
- * Will return true if a cluster is found logically above the page.
- * Will return false if an end of cluster or the beginning
- * of the lesson is found before a cluster page.
- *
- * @param array $pages An array of lesson page objects.
- * @param int $pageid Id of the page for testing.
- * @return boolean
- */
-function lesson_is_page_in_cluster($pages, $pageid) {
-    $pageid = $pages[$pageid]->prevpageid; // move up one
-
-    // go up the pages till branch table
-    while (true) {
-        if ($pageid == 0) {  // ran into the beginning of the lesson
-            return false;
-        } elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER) { // ran into the end of another branch table
-            return false;
-        } elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // hit a branch table
-            return true;
-        }
-        $pageid = $pages[$pageid]->prevpageid;
-    }
-}
-
 /**
  * Calculates a user's grade for a lesson.
  *
@@ -1453,24 +298,24 @@ function lesson_grade($lesson, $ntries, $userid = 0) {
 
         // get only the pages and their answers that the user answered
         list($usql, $parameters) = $DB->get_in_or_equal(array_keys($attemptset));
-        $parameters["lessonid"] = $lesson->id;
-        $pages = $DB->get_records_select("lesson_pages", "lessonid = :lessonid AND id $usql", $parameters);
-        $answers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid AND pageid $usql", $parameters);
+        array_unshift($parameters, $lesson->id);
+        $pages = $DB->get_records_select("lesson_pages", "lessonid = ? AND id $usql", $parameters);
+        $answers = $DB->get_records_select("lesson_answers", "lessonid = ? AND pageid $usql", $parameters);
 
         // Number of pages answered
         $nquestions = count($pages);
 
         foreach ($attemptset as $attempts) {
+            $page = lesson_page::load($pages[end($attempts)->pageid], $lesson);
             if ($lesson->custom) {
                 $attempt = end($attempts);
                 // If essay question, handle it, otherwise add to score
-                if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
-                    $essayinfo = unserialize($attempt->useranswer);
-                    $earned += $essayinfo->score;
+                if ($page->requires_manual_grading()) {
+                    $earned += $page->earned_score($answers, $attempt);
                     $nmanual++;
                     $manualpoints += $answers[$attempt->answerid]->score;
                 } else if (!empty($attempt->answerid)) {
-                    $earned += $answers[$attempt->answerid]->score;
+                    $earned += $page->earned_score($answers, $attempt);
                 }
             } else {
                 foreach ($attempts as $attempt) {
@@ -1478,7 +323,7 @@ function lesson_grade($lesson, $ntries, $userid = 0) {
                 }
                 $attempt = end($attempts); // doesn't matter which one
                 // If essay question, increase numbers
-                if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
+                if ($page->requires_manual_grading()) {
                     $nmanual++;
                     $manualpoints++;
                 }
@@ -1526,180 +371,6 @@ function lesson_grade($lesson, $ntries, $userid = 0) {
     return $gradeinfo;
 }
 
-/**
- * Prints the on going message to the user.
- *
- * With custom grading On, displays points
- * earned out of total points possible thus far.
- * With custom grading Off, displays number of correct
- * answers out of total attempted.
- *
- * @param object $lesson The lesson that the user is taking.
- * @return void
- **/
-function lesson_print_ongoing_score($lesson) {
-    global $USER, $DB, $OUTPUT;
-
-    $cm = get_coursemodule_from_instance('lesson', $lesson->id);
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-    if (has_capability('mod/lesson:manage', $context)) {
-        echo "<p align=\"center\">".get_string('teacherongoingwarning', 'lesson').'</p>';
-    } else {
-        $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-        if (isset($USER->modattempts[$lesson->id])) {
-            $ntries--;
-        }
-        $gradeinfo = lesson_grade($lesson, $ntries);
-
-        $a = new stdClass;
-        if ($lesson->custom) {
-            $a->score = $gradeinfo->earned;
-            $a->currenthigh = $gradeinfo->total;
-            echo $OUTPUT->box(get_string("ongoingcustom", "lesson", $a), "generalbox boxaligncenter");
-        } else {
-            $a->correct = $gradeinfo->earned;
-            $a->viewed = $gradeinfo->attempts;
-            echo $OUTPUT->box(get_string("ongoingnormal", "lesson", $a), "generalbox boxaligncenter");
-        }
-    }
-}
-
-/**
- * Prints tabs for the editing and adding pages.  Each tab is a question type.
- *
- * @param array $qtypes The question types array (may not need to pass this because it is defined in this file)
- * @param string $selected Current selected tab
- * @param string $link The base href value of the link for the tab
- * @param string $onclick Javascript for the tab link
- * @return void
- */
-function lesson_qtype_menu($qtypes, $selected="", $link="", $onclick="") {
-    $tabs = array();
-    $tabrows = array();
-
-    foreach ($qtypes as $qtype => $qtypename) {
-        $tabrows[] = new tabobject($qtype, "$link&amp;qtype=$qtype\" onclick=\"$onclick", $qtypename);
-    }
-    $tabs[] = $tabrows;
-    print_tabs($tabs, $selected);
-    echo "<input type=\"hidden\" name=\"qtype\" value=\"$selected\" /> \n";
-
-}
-
-/**
- * Prints out a Progress Bar which depicts a user's progress within a lesson.
- *
- * Currently works best with a linear lesson.  Clusters are counted as a single page.
- * Also, only viewed branch tables and questions that have been answered correctly count
- * toward lesson completion (or progress).  Only Students can see the Progress bar as well.
- *
- * @param object $lesson The lesson that the user is currently taking.
- * @param object $course The course that the to which the lesson belongs.
- * @return boolean The return is not significant as of yet.  Will return true/false.
- **/
-function lesson_print_progress_bar($lesson, $course) {
-    global $CFG, $USER, $DB, $OUTPUT;
-
-    $cm = get_coursemodule_from_instance('lesson', $lesson->id);
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-
-    // lesson setting to turn progress bar on or off
-    if (!$lesson->progressbar) {
-        return false;
-    }
-
-    // catch teachers
-    if (has_capability('mod/lesson:manage', $context)) {
-        echo $OUTPUT->notification(get_string('progressbarteacherwarning2', 'lesson'));
-        return false;
-    }
-    if (!isset($USER->modattempts[$lesson->id])) {
-        // all of the lesson pages
-        if (!$pages = $DB->get_records('lesson_pages', array('lessonid' => $lesson->id))) {
-            return false;
-        } else {
-            foreach ($pages as $page) {
-                if ($page->prevpageid == 0) {
-                    $pageid = $page->id;  // find the first page id
-                    break;
-                }
-            }
-        }
-
-        // current attempt number
-        if (!$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id))) {
-            $ntries = 0;  // may not be necessary
-        }
-
-        $viewedpageids = array();
-
-        // collect all of the correctly answered questions
-        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $ntries);
-        if ($viewedpages = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND retry = :retry AND correct = 1", $params, 'timeseen DESC', 'pageid, id')) {
-            $viewedpageids = array_keys($viewedpages);
-        }
-        // collect all of the branch tables viewed
-        if ($viewedbranches = $DB->get_records_select("lesson_branch", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, 'timeseen DESC', 'pageid, id')) {
-            $viewedpageids = array_merge($viewedpageids, array_keys($viewedbranches));
-        }
-
-        // Filter out the following pages:
-        //      End of Cluster
-        //      End of Branch
-        //      Pages found inside of Clusters
-        // Do not filter out Cluster Page(s) because we count a cluster as one.
-        // By keeping the cluster page, we get our 1
-        $validpages = array();
-        while ($pageid != 0) {
-            if ($pages[$pageid]->qtype == LESSON_CLUSTER) {
-                $clusterpageid = $pageid; // copy it
-                $validpages[$clusterpageid] = 1;  // add the cluster page as a valid page
-                $pageid = $pages[$pageid]->nextpageid;  // get next page
-
-                // now, remove all necessary viewed paged ids from the viewedpageids array.
-                while ($pages[$pageid]->qtype != LESSON_ENDOFCLUSTER and $pageid != 0) {
-                    if (in_array($pageid, $viewedpageids)) {
-                        unset($viewedpageids[array_search($pageid, $viewedpageids)]);  // remove it
-                        // since the user did see one page in the cluster, add the cluster pageid to the viewedpageids
-                        if (!in_array($clusterpageid, $viewedpageids)) {
-                            $viewedpageids[] = $clusterpageid;
-                        }
-                    }
-                    $pageid = $pages[$pageid]->nextpageid;
-                }
-            } elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER or $pages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
-                // dont count these, just go to next
-                $pageid = $pages[$pageid]->nextpageid;
-            } else {
-                // a counted page
-                $validpages[$pageid] = 1;
-                $pageid = $pages[$pageid]->nextpageid;
-            }
-        }
-
-        // progress calculation as a percent
-        $progress = round(count($viewedpageids)/count($validpages), 2) * 100;
-    } else {
-        $progress = 100;
-    }
-
-    // print out the Progress Bar.  Attempted to put as much as possible in the style sheets.
-    echo '<div class="progress_bar" align="center">';
-    echo '<table class="progress_bar_table"><tr>';
-    if ($progress != 0) {  // some browsers do not repsect the 0 width.
-        echo '<td style="width:'.$progress.'%;" class="progress_bar_completed">';
-        echo '</td>';
-    }
-    echo '<td class="progress_bar_todo">';
-    echo '<div class="progress_bar_token"></div>';
-    echo '</td>';
-    echo '</tr></table>';
-    echo '</div>';
-
-    return true;
-}
-
 /**
  * Determines if a user can view the left menu.  The determining factor
  * is whether a user has a grade greater than or equal to the lesson setting
@@ -1765,18 +436,24 @@ function lesson_add_pretend_blocks($page, $cm, $lesson, $timer = null) {
  **/
 function lesson_mediafile_block_contents($cmid, $lesson) {
     global $OUTPUT;
-    if (empty($lesson->mediafile)) {
+    if (empty($lesson->mediafile) && empty($lesson->mediafileid)) {
         return null;
     }
 
-    $url      = '/mod/lesson/mediafile.php?id='.$cmid;
-    $options  = 'menubar=0,location=0,left=5,top=5,scrollbars,resizable,width='. $lesson->mediawidth .',height='. $lesson->mediaheight;
-    $name     = 'lessonmediafile';
+    $options = array();
+    $options['menubar'] = 0;
+    $options['location'] = 0;
+    $options['left'] = 5;
+    $options['top'] = 5;
+    $options['scrollbars'] = 1;
+    $options['resizable'] = 1;
+    $options['width'] = $lesson->mediawidth;
+    $options['height'] = $lesson->mediaheight;
 
-    $link = html_link::make($url, get_string('mediafilepopup', 'lesson'));
-    $link->add_action(new popup_action('click', $link->url, $name, $options));
+    $link = html_link::make('/mod/lesson/mediafile.php?id='.$cmid, get_string('mediafilepopup', 'lesson'));
+    $link->add_action(new popup_action('click', $link->url, 'lessonmediafile', $options));
     $link->title = get_string('mediafilepopup', 'lesson');
-    $content .= $OUTPUT->link($link);
+    $content = $OUTPUT->link($link);
 
     $content .= $OUTPUT->help_icon(moodle_help_icon::make("mediafilestudent", get_string("mediafile", "lesson"), "lesson"));
 
@@ -1805,7 +482,7 @@ function lesson_clock_block_contents($cmid, $lesson, $timer, $page) {
     }
 
     $content = '<div class="jshidewhenenabled">';
-    $content .= lesson_print_time_remaining($timer->starttime, $lesson->maxtime, true)."\n";
+    $content .=  $lesson->time_remaining($timer->starttime);
     $content .= '</div>';
 
     $clocksettings = array('starttime'=>$timer->starttime, 'servertime'=>time(),'testlength'=>($lesson->maxtime * 60));
@@ -1826,7 +503,7 @@ function lesson_clock_block_contents($cmid, $lesson, $timer, $page) {
  * print the menu in a block
  *
  * @param int $cmid Course Module ID for this lesson
- * @param object $lesson Full lesson record object
+ * @param lesson $lesson Full lesson record object
  * @return void
  **/
 function lesson_menu_block_contents($cmid, $lesson) {
@@ -1836,9 +513,13 @@ function lesson_menu_block_contents($cmid, $lesson) {
         return null;
     }
 
-    $pageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0));
-    $params = array ("lessonid" => $lesson->id);
-    $pages  = $DB->get_records_select('lesson_pages', "lessonid = :lessonid", $params);
+    $pages = $lesson->load_all_pages();
+    foreach ($pages as $page) {
+        if ((int)$page->prevpageid === 0) {
+            $pageid = $page->id;
+            break;
+        }
+    }
     $currentpageid = optional_param('pageid', $pageid, PARAM_INT);
 
     if (!$pageid || !$pages) {
@@ -1851,7 +532,7 @@ function lesson_menu_block_contents($cmid, $lesson) {
         $page = $pages[$pageid];
 
         // Only process branch tables with display turned on
-        if ($page->qtype == LESSON_BRANCHTABLE and $page->display) {
+        if ($page->displayinmenublock && $page->display) {
             if ($page->id == $currentpageid) {
                 $content .= '<li class="selected">'.format_string($page->title,true)."</li>\n";
             } else {
@@ -1869,4 +550,4 @@ function lesson_menu_block_contents($cmid, $lesson) {
     $bc->content = $content;
 
     return $bc;
-}
+}
\ No newline at end of file
index f1ba37855104f7371f5fb8b6ec81d97b71b21484..8a1fb17ae2e406f3c591d42b74393af99c598d2c 100644 (file)
@@ -1,5 +1,20 @@
 <?php
 
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * This file plays the mediafile set in lesson settings.
  *
  *  If there is a way to use the resource class instead of this code, please change to do so
  *
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  **/
 
-    require_once('../../config.php');
-    require_once($CFG->libdir.'/filelib.php');
+require_once('../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once($CFG->libdir.'/filelib.php');
+require_once($CFG->libdir.'/resourcelib.php');
 
-    $id = required_param('id', PARAM_INT);    // Course Module ID
-    $printclose = optional_param('printclose', 0, PARAM_INT);
+$id = required_param('id', PARAM_INT);    // Course Module ID
+$printclose = optional_param('printclose', 0, PARAM_INT);
 
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/mediafile.php', array('id'=>$id));
-    if ($printclose !== '') {
-        $url->param('printclose', $printclose);
-    }
-    $PAGE->set_url($url);
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/mediafile.php', array('id'=>$id));
+if ($printclose !== '') {
+    $url->param('printclose', $printclose);
+}
+$PAGE->set_url($url);
 
-    if (! $cm = get_coursemodule_from_id('lesson', $id)) {
-        print_error('invalidcoursemodule');
-    }
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
 
-    if (! $course = $DB->get_record('course', array('id' => $cm->course))) {
-        print_error('coursemisconf');
-    }
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
 
-    if (! $lesson = $DB->get_record('lesson', array('id' => $cm->instance))) {
-        print_error('invalidcoursemodule');
-    }
+// Get the mimetype
+$mimetype = mimeinfo("type", $lesson->mediafile);
 
-    require_login($course->id, false, $cm);
-
-    // Get the mimetype
-    $mimetype = mimeinfo("type", $lesson->mediafile);
-
-    if (!is_url($lesson->mediafile) and !in_array($mimetype, array('text/plain', 'text/html'))) {
+if ($printclose) {  // this is for framesets
+    if ($lesson->mediaclose) {
         $PAGE->set_title($course->shortname);
-        echo $OUTPUT->header();
+        echo $lessonoutput->header($lesson);
+        echo $OUTPUT->box('<form><div><input type="button" onclick="top.close();" value="'.get_string("closewindow").'" /></div></form>', 'lessonmediafilecontrol');
+        echo $lessonoutput->footer();
     }
+    exit();
+}
 
-    if ($printclose) {  // this is for framesets
-        if ($lesson->mediaclose) {
-            $PAGE->set_title($course->shortname);
-            echo $OUTPUT->header();
-            echo '<div class="lessonmediafilecontrol">
-                <form>
-                <div>
-                <input type="button" onclick="top.close();" value="'.get_string("closewindow").'" />
-                </div>
-                </form>
-                </div>';
-            echo $OUTPUT->footer();
-        }
-        exit();
-    }
-
-    if (is_url($lesson->mediafile)) {
-        $fullurl = $lesson->mediafile;
-    } else {
-        $fullurl = get_file_url($course->id .'/'. $lesson->mediafile);
-    }
-
-    // find the correct type and print it out
-    if ($mimetype == "audio/mp3") {    // It's an MP3 audio file
-
-        if (!empty($THEME->resource_mp3player_colors)) {
-            $c = $THEME->resource_mp3player_colors;   // You can set this up in your theme/xxx/config.php
-        } else {
-            $c = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&'.
-                 'iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&'.
-                 'font=Arial&fontColour=3333FF&buffer=10&waitForPlay=no&autoPlay=yes';
-        }
-        $c .= '&volText='.get_string('vol', 'resource').'&panText='.get_string('pan','resource');
-        $c = htmlentities($c);
-        echo '<div class="mp3player" class="lessonmediafilecontrol">';
-        echo '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
-        echo '        codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ';
-        echo '        width="600" height="70" id="mp3player" align="">';
-        echo '<param name="movie" value="'.$CFG->wwwroot.'/lib/mp3player/mp3player.swf?src='.$fullurl.'">';
-        echo '<param name="quality" value="high">';
-        echo '<param name="bgcolor" value="#333333">';
-        echo '<param name="flashvars" value="'.$c.'&amp;" />';
-        echo '<embed src="'.$CFG->wwwroot.'/lib/mp3player/mp3player.swf?src='.$fullurl.'" ';
-        echo ' quality="high" bgcolor="#333333" width="600" height="70" name="mp3player" ';
-        echo ' type="application/x-shockwave-flash" ';
-        echo ' flashvars="'.$c.'&amp;" ';
-        echo ' pluginspage="http://www.macromedia.com/go/getflashplayer">';
-        echo '</embed>';
-        echo '</object>';
-        echo '</div>';
-
-    } else if (substr($mimetype, 0, 10) == "video/x-ms") {   // It's a Media Player file
-
-        echo "<div class=\"lessonmediafilecontrol\"><p>";
-        echo '<object classid="CLSID:22D6f312-B0F6-11D0-94AB-0080C74C7E95"';
-        echo '        codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701" ';
-        echo '        standby="Loading Microsoft(R) Windows(R) Media Player components..." ';
-        echo '        id="msplayer" align="" type="application/x-oleobject">';
-        echo "<param name=\"Filename\" value=\"$fullurl\">";
-        echo '<param name="ShowControls" value="true" />';
-        echo '<param name="AutoRewind" value="true" />';
-        echo '<param name="AutoStart" value="true" />';
-        echo '<param name="Autosize" value="true" />';
-        echo '<param name="EnableContextMenu" value="true" />';
-        echo '<param name="TransparentAtStart" value="false" />';
-        echo '<param name="AnimationAtStart" value="false" />';
-        echo '<param name="ShowGotoBar" value="false" />';
-        echo '<param name="EnableFullScreenControls" value="true" />';
-        echo "\n<embed src=\"$fullurl\" name=\"msplayer\" type=\"$mimetype\" ";
-        echo ' ShowControls="1" AutoRewind="1" AutoStart="1" Autosize="0" EnableContextMenu="1"';
-        echo ' TransparentAtStart="0" AnimationAtStart="0" ShowGotoBar="0" EnableFullScreenControls="1"';
-        echo ' pluginspage="http://www.microsoft.com/Windows/Downloads/Contents/Products/MediaPlayer/">';
-        echo '</embed>';
-        echo '</object>';
-        echo "</p></div>";
-
-    } else if ($mimetype == "video/quicktime") {   // It's a Quicktime file
-
-        echo "<div class=\"lessonmediafilecontrol\"><p>";
-        echo '<object classid="CLSID:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"';
-        echo '        codebase="http://www.apple.com/qtactivex/qtplugin.cab" ';
-        echo '        height="450" width="600"';
-        echo '        id="quicktime" align="" type="application/x-oleobject">';
-        echo "<param name=\"src\" value=\"$fullurl\" />";
-        echo '<param name="autoplay" value="true" />';
-        echo '<param name="loop" value="true" />';
-        echo '<param name="controller" value="true" />';
-        echo '<param name="scale" value="aspect" />';
-        echo "\n<embed src=\"$fullurl\" name=\"quicktime\" type=\"$mimetype\" ";
-        echo ' height="450" width="600" scale="aspect"';
-        echo ' autoplay="true" controller="true" loop="true" ';
-        echo ' pluginspage="http://quicktime.apple.com/">';
-        echo '</embed>';
-        echo '</object>';
-        echo "</p></div>";
+$mediafilehtml = lesson_get_media_html($lesson, $context);
 
-    //} else if ($mimetype == "application/x-shockwave-flash") {   // It's a flash file
-
-    //    print_error('noflash');
-
-    } else if ($mimetype == "audio/x-pn-realaudio") {   // It's a realmedia file
-
-        echo '<object id="rvocx" classid="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA" width="600" height="50">';
-        echo "<param name=\"src\" value=\"$fullurl\">";
-        echo '<param name="console" value="video">';  // not sure what the console param should equal
-        echo '<param name="controls" value="ControlPanel">';
-        echo '<param name="autostart" value="true">';
-        echo '<param name="loop" value="true">';
-        echo '<embed name="rvocx" src="'.$fullurl.'" height="50" width="600" autostart="true" loop="true" nojava="true" console="video" controls="ControlPanel"></embed>';
-        echo '<noembed></noembed>';
-        echo '</object>';
-
-    } else if (is_url($lesson->mediafile) or $mimetype == 'text/html' or $mimetype == 'text/plain') {
-        // might be dangerous to handle all of these in the same fasion.  It is being set by a teacher though.
-        echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
-        echo "<html dir=\"ltr\">\n";
-        echo '<head>';
-        echo '<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />';
-        echo "<title>{$course->shortname}</title></head>\n";
-        if ($lesson->mediaclose) {
-            echo "<frameset rows=\"90%,*\">";
-            echo "<frame src=\"$fullurl\" />";
-            echo "<frame src=\"mediafile.php?id=$cm->id&amp;printclose=1\" />";
-            echo "</frameset>";
-        } else {
-            echo "<frameset rows=\"100%\">";
-            echo "<frame src=\"$fullurl\" />";
-            echo "</frameset>";
-        }
-        echo '</html>';
-        exit();
-
-    } else if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) {  // Image
-
-        echo "<div class=\"lessonmediafilecontrol\"><p>";
-        echo '<img class="lessonimage" src="'.s($fullurl).'" alt="" />';
-        echo "</p></div>";
-
-    } else {  // Default
-
-        // Get the file name
-        $file = pathinfo($lesson->mediafile);
-        $filename = basename($file['basename'], '.'.$file['extension']);
-
-        echo "<div class=\"lessonmediafilecontrol\"><p>";
-        echo $OUTPUT->notification(get_string('clicktodownload', 'lesson'));
-        echo "<a href=\"$fullurl\">".format_string($filename).'</a>';
-        echo "</p></div>";
-
-    }
-
-    function is_url($test_url) {
-        // the following is barrowed from resource code.  Thanks!
-        if (strpos($test_url, '://')) {     // eg http:// https:// ftp://  etc
-            return true;
-        }
-        if (strpos($test_url, '/') === 0) { // Starts with slash
-            return true;
-        }
-        return false;
-    }
-
-    if ($lesson->mediaclose) {
-       echo '<div class="lessonmediafilecontrol">';
-       echo $OUTPUT->close_window_button();
-       echo '</div>';
-    }
+$PAGE->set_title($course->shortname);
+echo $lessonoutput->header($lesson);
+// print the embedded media html code
+echo $OUTPUT->box($mediafilehtml);
 
-    echo $OUTPUT->footer();
+if ($lesson->mediaclose) {
+   echo '<div class="lessonmediafilecontrol">';
+   echo $OUTPUT->close_window_button();
+   echo '</div>';
+}
 
+echo $lessonoutput->footer();
\ No newline at end of file
index e61dccde13e1412ac8dfe0648fde16107e39bfab..af7212911a7c960e81d77452857ce5ea44000abd 100644 (file)
@@ -1,25 +1,84 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Form to define a new instance of lesson or edit an instance.
  * It is used from /course/modedit.php.
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
 require_once($CFG->dirroot.'/course/moodleform_mod.php');
-require_once('locallib.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
 
 class mod_lesson_mod_form extends moodleform_mod {
 
+    protected $course = null;
+
+    public function mod_lesson_mod_form($current, $section, $cm, $course) {
+        $this->course = $course;
+        parent::moodleform_mod($current, $section, $cm, $course);
+    }
+    
     function definition() {
-        global $CFG, $LESSON_NEXTPAGE_ACTION, $COURSE, $DB;
+        global $CFG, $COURSE, $DB;
 
-        $mform    =& $this->_form;
+        $mform    = $this->_form;
 
 //-------------------------------------------------------------------------------
         $mform->addElement('header', 'general', get_string('general', 'form'));
 
+        /** Legacy slideshow width element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'width');
+        $mform->setType('width', PARAM_INT);
+        $mform->setDefault('width', $CFG->lesson_slideshowwidth);
+
+        /** Legacy slideshow height element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'height');
+        $mform->setType('height', PARAM_INT);
+        $mform->setDefault('height', $CFG->lesson_slideshowheight);
+
+        /** Legacy slideshow background color element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'bgcolor');
+        $mform->setType('bgcolor', PARAM_TEXT);
+        $mform->setDefault('bgcolor', $CFG->lesson_slideshowbgcolor);
+
+        /** Legacy media popup width element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'mediawidth');
+        $mform->setType('mediawidth', PARAM_INT);
+        $mform->setDefault('mediawidth', $CFG->lesson_mediawidth);
+
+        /** Legacy media popup height element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'mediaheight');
+        $mform->setType('mediaheight', PARAM_INT);
+        $mform->setDefault('mediaheight', $CFG->lesson_mediaheight);
+
+        /** Legacy media popup close button element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'mediaclose');
+        $mform->setType('mediaclose', PARAM_BOOL);
+        $mform->setDefault('mediaclose', $CFG->lesson_mediaclose);
+
+        /** Legacy maximum highscores element to maintain backwards compatibility */
+        $mform->addElement('hidden', 'maxhighscores');
+        $mform->setType('maxhighscores', PARAM_INT);
+        $mform->setDefault('maxhighscores', $CFG->lesson_maxhighscores);
+
         $mform->addElement('text', 'name', get_string('name'), array('size'=>'64'));
         if (!empty($CFG->formatstringstriptags)) {
             $mform->setType('name', PARAM_TEXT);
@@ -50,12 +109,32 @@ class mod_lesson_mod_form extends moodleform_mod {
         for ($i=20; $i>1; $i--) {
             $numbers[$i] = $i;
         }
+
+        $mform->addElement('date_time_selector', 'available', get_string('available', 'lesson'), array('optional'=>true));
+        $mform->setDefault('available', 0);
+
+        $mform->addElement('date_time_selector', 'deadline', get_string('deadline', 'lesson'), array('optional'=>true));
+        $mform->setDefault('deadline', 0);
+
         $mform->addElement('select', 'maxanswers', get_string('maximumnumberofanswersbranches', 'lesson'), $numbers);
-        $mform->setDefault('maxanswers', 4);
+        $mform->setDefault('maxanswers', $CFG->lesson_maxanswers);
+        $mform->setType('maxanswers', PARAM_INT);
         $mform->setHelpButton('maxanswers', array('maxanswers', get_string('maximumnumberofanswersbranches', 'lesson'), 'lesson'));
 
+        $mform->addElement('selectyesno', 'usepassword', get_string('usepassword', 'lesson'));
+        $mform->setHelpButton('usepassword', array('usepassword', get_string('usepassword', 'lesson'), 'lesson'));
+        $mform->setDefault('usepassword', 0);
+        $mform->setAdvanced('usepassword');
+
+        $mform->addElement('passwordunmask', 'password', get_string('password', 'lesson'));
+        $mform->setHelpButton('password', array('password', get_string('password', 'lesson'), 'lesson'));
+        $mform->setDefault('password', '');
+        $mform->setType('password', PARAM_RAW);
+        $mform->setAdvanced('password');
+        $mform->disabledIf('password', 'usepassword', 'eq', 0);
+
 //-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('gradeoptions', 'lesson'));
+        $mform->addElement('header', 'gradeoptions', get_string('gradeoptions', 'lesson'));
 
         $mform->addElement('selectyesno', 'practice', get_string('practice', 'lesson'));
         $mform->setHelpButton('practice', array('practice', get_string('practice', 'lesson'), 'lesson'));
@@ -72,6 +151,7 @@ class mod_lesson_mod_form extends moodleform_mod {
         $mform->addElement('select', 'grade', get_string('maximumgrade'), $grades);
         $mform->setDefault('grade', 0);
         $mform->setHelpButton('grade', array('grade', get_string('maximumgrade'), 'lesson'));
+        $mform->disabledIf('grade', 'practice', 'eq', '1');
 
         $mform->addElement('selectyesno', 'retake', get_string('retakesallowed', 'lesson'));
         $mform->setHelpButton('retake', array('retake', get_string('retakesallowed', 'lesson'), 'lesson'));
@@ -83,13 +163,14 @@ class mod_lesson_mod_form extends moodleform_mod {
         $mform->addElement('select', 'usemaxgrade', get_string('handlingofretakes', 'lesson'), $options);
         $mform->setHelpButton('usemaxgrade', array('handlingofretakes', get_string('handlingofretakes', 'lesson'), 'lesson'));
         $mform->setDefault('usemaxgrade', 0);
+        $mform->disabledIf('usemaxgrade', 'retake', 'eq', '0');
 
         $mform->addElement('selectyesno', 'ongoing', get_string('ongoing', 'lesson'));
         $mform->setHelpButton('ongoing', array('ongoing', get_string('ongoing', 'lesson'), 'lesson'));
         $mform->setDefault('ongoing', 0);
 
 //-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('flowcontrol', 'lesson'));
+        $mform->addElement('header', 'flowcontrol', get_string('flowcontrol', 'lesson'));
 
         $mform->addElement('selectyesno', 'modattempts', get_string('modattempts', 'lesson'));
         $mform->setHelpButton('modattempts', array('modattempts', get_string('modattempts', 'lesson'), 'lesson'));
@@ -107,14 +188,36 @@ class mod_lesson_mod_form extends moodleform_mod {
         $mform->setHelpButton('maxattempts', array('maxattempts', get_string('maximumnumberofattempts', 'lesson'), 'lesson'));
         $mform->setDefault('maxattempts', 1);
 
-        $mform->addElement('select', 'nextpagedefault', get_string('actionaftercorrectanswer', 'lesson'), $LESSON_NEXTPAGE_ACTION);
+        $defaultnextpages = array();
+        $defaultnextpages[0] = get_string("normal", "lesson");
+        $defaultnextpages[LESSON_UNSEENPAGE] = get_string("showanunseenpage", "lesson");
+        $defaultnextpages[LESSON_UNANSWEREDPAGE] = get_string("showanunansweredpage", "lesson");
+        $mform->addElement('select', 'nextpagedefault', get_string('actionaftercorrectanswer', 'lesson'), $defaultnextpages);
         $mform->setHelpButton('nextpagedefault', array('nextpageaction', get_string('actionaftercorrectanswer', 'lesson'), 'lesson'));
-        $mform->setDefault('nextpagedefault', 0);
+        $mform->setDefault('nextpagedefault', $CFG->lesson_defaultnextpage);
+        $mform->setAdvanced('nextpagedefault');
 
         $mform->addElement('selectyesno', 'feedback', get_string('displaydefaultfeedback', 'lesson'));
         $mform->setHelpButton('feedback', array('feedback', get_string('displaydefaultfeedback', 'lesson'), 'lesson'));
         $mform->setDefault('feedback', 0);
 
+        $mform->addElement('selectyesno', 'progressbar', get_string('progressbar', 'lesson'));
+        $mform->setHelpButton('progressbar', array('progressbar', get_string('progressbar', 'lesson'), 'lesson'));
+        $mform->setDefault('progressbar', 0);
+
+        $mform->addElement('selectyesno', 'displayleft', get_string('displayleftmenu', 'lesson'));
+        $mform->setHelpButton('displayleft', array('displayleft', get_string('displayleftmenu', 'lesson'), 'lesson'));
+        $mform->setDefault('displayleft', 0);
+
+        $options = array();
+        for($i = 100; $i >= 0; $i--) {
+            $options[$i] = $i.'%';
+        }
+        $mform->addElement('select', 'displayleftif', get_string('displayleftif', 'lesson'), $options);
+        $mform->setHelpButton('displayleftif', array('displayleftif', get_string('displayleftmenuif', 'lesson'), 'lesson'));
+        $mform->setDefault('displayleftif', 0);
+        $mform->setAdvanced('displayleftif');
+
         $numbers = array();
         for ($i = 100; $i >= 0; $i--) {
             $numbers[$i] = $i;
@@ -122,6 +225,7 @@ class mod_lesson_mod_form extends moodleform_mod {
         $mform->addElement('select', 'minquestions', get_string('minimumnumberofquestions', 'lesson'), $numbers);
         $mform->setHelpButton('minquestions', array('minquestions', get_string('minimumnumberofquestions', 'lesson'), 'lesson'));
         $mform->setDefault('minquestions', 0);
+        $mform->setAdvanced('minquestions');
 
         $numbers = array();
         for ($i = 100; $i >= 0; $i--) {
@@ -129,71 +233,47 @@ class mod_lesson_mod_form extends moodleform_mod {
         }
         $mform->addElement('select', 'maxpages', get_string('numberofpagestoshow', 'lesson'), $numbers);
         $mform->setHelpButton('maxpages', array('maxpages', get_string('numberofpagestoshow', 'lesson'), 'lesson'));
+        $mform->setAdvanced('maxpages');
         $mform->setDefault('maxpages', 0);
 
-//-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('lessonformating', 'lesson'));
-
         $mform->addElement('selectyesno', 'slideshow', get_string('slideshow', 'lesson'));
         $mform->setHelpButton('slideshow', array('slideshow', get_string('slideshow', 'lesson'), 'lesson'));
         $mform->setDefault('slideshow', 0);
+        $mform->setAdvanced('slideshow');
 
-        $mform->addElement('text', 'width', get_string('slideshowwidth', 'lesson'));
-        $mform->setDefault('width', 640);
-        $mform->addRule('width', null, 'required', null, 'client');
-        $mform->addRule('width', null, 'numeric', null, 'client');
-        $mform->setHelpButton('width', array('width', get_string('slideshowwidth', 'lesson'), 'lesson'));
-        $mform->setType('width', PARAM_INT);
-
-        $mform->addElement('text', 'height', get_string('slideshowheight', 'lesson'));
-        $mform->setDefault('height', 480);
-        $mform->addRule('height', null, 'required', null, 'client');
-        $mform->addRule('height', null, 'numeric', null, 'client');
-        $mform->setHelpButton('height', array('height', get_string('slideshowheight', 'lesson'), 'lesson'));
-        $mform->setType('height', PARAM_INT);
-
-        $mform->addElement('text', 'bgcolor', get_string('slideshowbgcolor', 'lesson'));
-        $mform->setDefault('bgcolor', '#FFFFFF');
-        $mform->addRule('bgcolor', null, 'required', null, 'client');
-        $mform->setHelpButton('bgcolor', array('bgcolor', get_string('slideshowbgcolor', 'lesson'), 'lesson'));
-        $mform->setType('bgcolor', PARAM_TEXT);
+        // get the modules
+        if ($mods = get_course_mods($COURSE->id)) {
+            $modinstances = array();
+            foreach ($mods as $mod) {
 
-        $mform->addElement('selectyesno', 'displayleft', get_string('displayleftmenu', 'lesson'));
-        $mform->setHelpButton('displayleft', array('displayleft', get_string('displayleftmenu', 'lesson'), 'lesson'));
-        $mform->setDefault('displayleft', 0);
+                // get the module name and then store it in a new array
+                if ($module = get_coursemodule_from_instance($mod->modname, $mod->instance, $COURSE->id)) {
+                    if (isset($this->_cm->id) and $this->_cm->id != $mod->id){
+                        $modinstances[$mod->id] = $mod->modname.' - '.$module->name;
+                    }
+                }
+            }
+            asort($modinstances); // sort by module name
+            $modinstances=array(0=>get_string('none'))+$modinstances;
 
-        $options = array();
-        for($i = 100; $i >= 0; $i--) {
-            $options[$i] = $i.'%';
+            $mform->addElement('select', 'activitylink', get_string('activitylink', 'lesson'), $modinstances);
+            $mform->setHelpButton('activitylink', array('activitylink', get_string('activitylink', 'lesson'), 'lesson'));
+            $mform->setDefault('activitylink', 0);
+            $mform->setAdvanced('activitylink');
         }
-        $mform->addElement('select', 'displayleftif', get_string('displayleftif', 'lesson'), $options);
-        $mform->setDefault('displayleftif', 0);
-
-        $mform->addElement('selectyesno', 'progressbar', get_string('progressbar', 'lesson'));
-        $mform->setHelpButton('progressbar', array('progressbar', get_string('progressbar', 'lesson'), 'lesson'));
-        $mform->setDefault('progressbar', 0);
-
 
 //-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('accesscontrol', 'lesson'));
+        $mform->addElement('header', 'mediafileheader', get_string('mediafile', 'lesson'));
 
-        $mform->addElement('selectyesno', 'usepassword', get_string('usepassword', 'lesson'));
-        $mform->setHelpButton('usepassword', array('usepassword', get_string('usepassword', 'lesson'), 'lesson'));
-        $mform->setDefault('usepassword', 0);
-
-        $mform->addElement('passwordunmask', 'password', get_string('password', 'lesson'));
-        $mform->setHelpButton('password', array('password', get_string('password', 'lesson'), 'lesson'));
-        $mform->setDefault('password', '');
-        $mform->setType('password', PARAM_RAW);
-
-        $mform->addElement('date_time_selector', 'available', get_string('available', 'lesson'), array('optional'=>true));
-        $mform->setDefault('available', 0);
-
-        $mform->addElement('date_time_selector', 'deadline', get_string('deadline', 'lesson'), array('optional'=>true));
-        $mform->setDefault('deadline', 0);
+        $filepickeroptions = array();
+        $filepickeroptions['filetypes'] = '*';
+        $filepickeroptions['maxbytes'] = $this->course->maxbytes;
+        $mform->addElement('filepicker', 'mediafile', get_string('mediafile', 'lesson'), null, $filepickeroptions);
+        $mform->setHelpButton('mediafile', array('mediafile', get_string('mediafile', 'lesson'), 'lesson'));
+        $mform->setDefault('mediafile', '');
 
 //-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('dependencyon', 'lesson'));
+        $mform->addElement('header', 'dependencyon', get_string('dependencyon', 'lesson'));
 
         $options = array(0=>get_string('none'));
         if ($lessons = get_all_instances_in_course('lesson', $COURSE)) {
@@ -219,66 +299,6 @@ class mod_lesson_mod_form extends moodleform_mod {
         $mform->setDefault('gradebetterthan', 0);
         $mform->setType('gradebetterthan', PARAM_INT);
 
-//-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('mediafile', 'lesson'));
-
-        $mform->addElement('choosecoursefile', 'mediafile', get_string('mediafile', 'lesson'), array('courseid'=>$COURSE->id));
-        $mform->setHelpButton('mediafile', array('mediafile', get_string('mediafile', 'lesson'), 'lesson'));
-        $mform->setDefault('mediafile', '');
-        $mform->setType('mediafile', PARAM_RAW);
-
-        $mform->addElement('selectyesno', 'mediaclose', get_string('mediaclose', 'lesson'));
-        $mform->setDefault('mediaclose', 0);
-
-        $mform->addElement('text', 'mediaheight', get_string('mediaheight', 'lesson'));
-        $mform->setHelpButton('mediaheight', array('mediaheight', get_string('mediaheight', 'lesson'), 'lesson'));
-        $mform->setDefault('mediaheight', 100);
-        $mform->addRule('mediaheight', null, 'required', null, 'client');
-        $mform->addRule('mediaheight', null, 'numeric', null, 'client');
-        $mform->setType('mediaheight', PARAM_INT);
-
-        $mform->addElement('text', 'mediawidth', get_string('mediawidth', 'lesson'));
-        $mform->setHelpButton('mediawidth', array('mediawidth', get_string('mediawidth', 'lesson'), 'lesson'));
-        $mform->setDefault('mediawidth', 650);
-        $mform->addRule('mediawidth', null, 'required', null, 'client');
-        $mform->addRule('mediawidth', null, 'numeric', null, 'client');
-        $mform->setType('mediawidth', PARAM_INT);
-
-//-------------------------------------------------------------------------------
-        $mform->addElement('header', '', get_string('other', 'lesson'));
-
-        // get the modules
-        if ($mods = get_course_mods($COURSE->id)) {
-            $modinstances = array();
-            foreach ($mods as $mod) {
-
-                // get the module name and then store it in a new array
-                if ($module = get_coursemodule_from_instance($mod->modname, $mod->instance, $COURSE->id)) {
-                    if (isset($this->_cm->id) and $this->_cm->id != $mod->id){
-                        $modinstances[$mod->id] = $mod->modname.' - '.$module->name;
-                    }
-                }
-            }
-            asort($modinstances); // sort by module name
-            $modinstances=array(0=>get_string('none'))+$modinstances;
-
-            $mform->addElement('select', 'activitylink', get_string('activitylink', 'lesson'), $modinstances);
-            $mform->setHelpButton('activitylink', array('activitylink', get_string('activitylink', 'lesson'), 'lesson'));
-            $mform->setDefault('activitylink', 0);
-
-        }
-
-        $mform->addElement('text', 'maxhighscores', get_string('maxhighscores', 'lesson'));
-        $mform->setHelpButton('maxhighscores', array('maxhighscores', get_string('maxhighscores', 'lesson'), 'lesson'));
-        $mform->setDefault('maxhighscores', 10);
-        $mform->addRule('maxhighscores', null, 'required', null, 'client');
-        $mform->addRule('maxhighscores', null, 'numeric', null, 'client');
-        $mform->setType('maxhighscores', PARAM_INT);
-
-        $mform->addElement('selectyesno', 'lessondefault', get_string('lessondefault', 'lesson'));
-        $mform->setHelpButton('lessondefault', array('lessondefault', get_string('lessondefault', 'lesson'), 'lesson'));
-        $mform->setDefault('lessondefault', 0);
-
 //-------------------------------------------------------------------------------
         $this->standard_coursemodule_elements();
 //-------------------------------------------------------------------------------
@@ -305,20 +325,11 @@ class mod_lesson_mod_form extends moodleform_mod {
         if (isset($default_values['password']) and ($module->version<2008112600)) {
             unset($default_values['password']);
         }
-        if (isset($default_values['add']) and $defaults = $DB->get_record('lesson_default', array('course' => $default_values['course']))) {
-            foreach ($defaults as $fieldname => $default) {
-                switch ($fieldname) {
-                    case 'conditions':
-                        $conditions = unserialize($default);
-                        $default_values['timespent'] = $conditions->timespent;
-                        $default_values['completed'] = $conditions->completed;
-                        $default_values['gradebetterthan'] = $conditions->gradebetterthan;
-                        break;
-                    default:
-                        $default_values[$fieldname] = $default;
-                        break;
-                }
-            }
+        if (!empty($this->_cm) && !empty($default_values['mediafile'])) {
+            $context = get_context_instance(CONTEXT_MODULE, $this->_cm->id);
+            $draftitemid = file_get_submitted_draft_itemid('mediafile');
+            file_prepare_draft_area($draftitemid, $context->id, 'lesson_media_file', $this->_cm->instance, array('subdirs' => 0, 'maxbytes' => $this->course->maxbytes, 'maxfiles' => 1));
+            $default_values['mediafile'] = $draftitemid;
         }
     }
 
diff --git a/mod/lesson/pagetypes/branchtable.php b/mod/lesson/pagetypes/branchtable.php
new file mode 100644 (file)
index 0000000..9c59b15
--- /dev/null
@@ -0,0 +1,296 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Branch Table
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** Branch Table page */
+define("LESSON_PAGE_BRANCHTABLE",   "20");
+
+class lesson_page_type_branchtable extends lesson_page {
+
+    protected $type = lesson_page::TYPE_STRUCTURE;
+    protected $typeid = LESSON_PAGE_BRANCHTABLE;
+    protected $typeidstring = 'branchtable';
+    protected $string = null;
+    protected $jumpto = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public static function get_jumptooptions($firstpage, $lesson) {
+        global $DB, $PAGE;
+        $jump = array();
+        $jump[0] = get_string("thispage", "lesson");
+        $jump[LESSON_NEXTPAGE] = get_string("nextpage", "lesson");
+        $jump[LESSON_PREVIOUSPAGE] = get_string("previouspage", "lesson");
+        $jump[LESSON_EOL] = get_string("endoflesson", "lesson");
+        if (!$firstpage) {
+            if (!$apageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
+                print_error('cannotfindfirstpage', 'lesson');
+            }
+            while (true) {
+                if ($apageid) {
+                    $title = $DB->get_field("lesson_pages", "title", array("id" => $apageid));
+                    $jump[$apageid] = $title;
+                    $apageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $apageid));
+                } else {
+                    // last page reached
+                    break;
+                }
+            }
+         }
+        return $jump;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $PAGE, $CFG;
+
+        $output = '';
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        if ($this->lesson->slideshow) {
+            $output .= $renderer->slideshow_start($this->lesson);
+        }
+        $output .= $renderer->heading(format_string($this->properties->title));
+        $output .= $renderer->box($this->get_contents(), 'contents');
+
+        $buttons = array();
+        $i = 0;
+        foreach ($this->get_answers() as $answer) {
+            $params = array();
+            $params['id'] = $PAGE->cm->id;
+            $params['pageid'] = $this->properties->id;
+            $params['sesskey'] = sesskey();
+            $params['jumpto'] = $answer->jumpto;
+            $buttons[] = $renderer->button(html_form::make_button($CFG->wwwroot.'/mod/lesson/continue.php', $params, strip_tags(format_text($answer->answer, FORMAT_MOODLE, $options))));
+            $i++;
+        }
+        // Set the orientation
+        if ($this->properties->layout) {
+            $buttonshtml = $renderer->box(implode("\n", $buttons), 'branchbuttoncontainer horizontal');
+        } else {
+            $buttonshtml = $renderer->box(implode("\n", $buttons), 'branchbuttoncontainer vertical');
+        }
+        $output .= $buttonshtml;
+
+        if ($this->lesson->slideshow) {
+            $output .= $renderer->slideshow_end();
+        }
+        
+        return $output;
+    }
+
+    public function check_answer() {
+        global $USER, $DB, $PAGE, $CFG;
+
+        require_sesskey();
+        $newpageid = optional_param('jumpto', NULL, PARAM_INT);
+        // going to insert into lesson_branch
+        if ($newpageid == LESSON_RANDOMBRANCH) {
+            $branchflag = 1;
+        } else {
+            $branchflag = 0;
+        }
+        if ($grades = $DB->get_records("lesson_grades", array("lessonid" => $this->lesson->id, "userid" => $USER->id), "grade DESC")) {
+            $retries = count($grades);
+        } 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 = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id);
+        if($newpageid == LESSON_UNSEENBRANCHPAGE) {
+            if (has_capability('mod/lesson:manage', $context)) {
+                 $newpageid = LESSON_NEXTPAGE;
+            } else {
+                 $newpageid = lesson_unseen_question_jump($this->lesson, $USER->id, $this->properties->id);  // this may return 0
+            }
+        }
+        // convert jumpto page into a proper page id
+        if ($newpageid == 0) {
+            $newpageid = $this->properties->id;
+        } elseif ($newpageid == LESSON_NEXTPAGE) {
+            if (!$newpageid = $this->nextpageid) {
+                // no nextpage go to end of lesson
+                $newpageid = LESSON_EOL;
+            }
+        } elseif ($newpageid == LESSON_PREVIOUSPAGE) {
+            $newpageid = $page->prevpageid;
+        } elseif ($newpageid == LESSON_RANDOMPAGE) {
+            $newpageid = lesson_random_question_jump($this->lesson, $this->properties->id);
+        } 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($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id,'pageid'=>$newpageid)));
+    }
+
+    public function display_answers($table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("branch", "lesson")." $i<span>: ";
+            $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson")." $i<span>: ";
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+            $i++;
+        }
+        return $table;
+    }
+    public function get_grayout() {
+        return 1;
+    }
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            $data = "<input type=\"button\" name=\"$answer->id\" value=\"".strip_tags(format_text($answer->answer, FORMAT_MOODLE,$formattextdefoptions))."\" disabled=\"disabled\"> ";
+            $data .= get_string('jumpsto', 'lesson', $this->get_jump_name($answer->jumpto));
+            $answerdata->answers[] = array($data, "");
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+
+    public function update($properties) {
+        if (empty($properties->display)) {
+            $properties->display = '0';
+        }
+        if (empty($properties->layout)) {
+            $properties->layout = '0';
+        }
+        return parent::update($properties);
+    }
+    public function add_page_link($previd) {
+        global $PAGE, $CFG;
+        $addbranchurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$PAGE->cm->id, 'pageid'=>$previd, 'qtype'=>LESSON_PAGE_BRANCHTABLE));
+        return html_link::make($addbranchurl, get_string('addabranchtable', 'lesson'));
+    }
+    protected function get_displayinmenublock() {
+        return true;
+    }
+    public function is_unseen($param) {
+        global $USER, $DB;
+        if (is_array($param)) {
+            $seenpages = $param;
+            $branchpages = $this->lesson->get_sub_pages_of($this->properties->id, array(LESSON_PAGE_BRANCHTABLE, LESSON_PAGE_ENDOFBRANCH));
+            foreach ($branchpages as $branchpage) {
+                if (array_key_exists($branchpage->id, $seenpages)) {  // check if any of the pages have been viewed
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            $nretakes = $param;
+            if (!$DB->count_records("lesson_attempts", array("pageid"=>$this->properties->id, "userid"=>$USER->id, "retry"=>$nretakes))) {
+                return true;
+            }
+            return false;
+        }
+    }
+}
+
+class lesson_add_page_form_branchtable extends lesson_add_page_form_base {
+
+    public $qtype = LESSON_PAGE_BRANCHTABLE;
+    public $qtypestring = 'branchtable';
+    protected $standard = false;
+
+    public function custom_definition() {
+        global $PAGE;
+
+        $mform = $this->_form;
+        $lesson = $this->_customdata['lesson'];
+
+        $firstpage = optional_param('firstpage', false, PARAM_BOOL);
+
+        $jumptooptions = lesson_page_type_branchtable::get_jumptooptions($firstpage, $lesson);
+
+        $mform->setDefault('qtypeheading', get_string('addabranchtable', 'lesson'));
+
+        $mform->addElement('hidden', 'firstpage');
+        $mform->setType('firstpage', PARAM_BOOL);
+        $mform->setDefault('firstpage', $firstpage);
+
+        $mform->addElement('hidden', 'qtype');
+        $mform->setType('qtype', PARAM_INT);
+
+        $mform->addElement('text', 'title', get_string("pagetitle", "lesson"), array('size'=>70));
+        $mform->setType('title', PARAM_TEXT);
+
+        $this->editoroptions = array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes);
+        $mform->addElement('editor', 'contents_editor', get_string("pagecontents", "lesson"), null, $this->editoroptions);
+        $mform->setType('contents_editor', PARAM_CLEANHTML);
+
+        $mform->addElement('checkbox', 'layout', null, get_string("arrangebuttonshorizontally", "lesson"));
+        $mform->setDefault('layout', true);
+
+        $mform->addElement('checkbox', 'display', null, get_string("displayinleftmenu", "lesson"));
+        $mform->setDefault('display', true);
+
+        for ($i = 0; $i < $lesson->maxanswers; $i++) {
+            $mform->addElement('header', 'headeranswer'.$i, get_string('branch', 'lesson').' '.($i+1));
+            $mform->addElement('textarea', 'answer['.$i.']', get_string("description", "lesson"), array('rows'=>10, 'cols'=>70, 'width'=>630, 'height'=>300));
+            $mform->setType('answer['.$i.']', PARAM_CLEANHTML);
+
+            $mform->addElement('select', 'jumpto['.$i.']', get_string("jump", "lesson"), $jumptooptions);
+            if ($i === 0) {
+                $mform->setDefault('jumpto['.$i.']', 0);
+            } else {
+                $mform->setDefault('jumpto['.$i.']', LESSON_NEXTPAGE);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/cluster.php b/mod/lesson/pagetypes/cluster.php
new file mode 100644 (file)
index 0000000..89af665
--- /dev/null
@@ -0,0 +1,176 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Cluster
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** Start of Cluster page */
+define("LESSON_PAGE_CLUSTER",   "30");
+
+class lesson_page_type_cluster extends lesson_page {
+
+    protected $type = lesson_page::TYPE_STRUCTURE;
+    protected $typeidstring = 'cluster';
+    protected $typeid = LESSON_PAGE_CLUSTER;
+    protected $string = null;
+    protected $jumpto = null;
+
+    public function display($renderer, $attempt) {
+        return '';
+    }
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function get_grayout() {
+        return 1;
+    }
+    public function callback_on_view($canmanage) {
+        global $USER;
+        if (!$canmanage) {
+            // Get the next page in the lesson cluster jump
+            return $this->lesson->cluster_jump($this->properties->id);
+        } else {
+            // get the next page
+            return $this->properties->nextpageid;
+        }
+    }
+    public function override_next_page() {
+        global $USER;
+        return $this->lesson->cluster_jump($this->properties->id);
+    }
+    public function add_page_link($previd) {
+        global $PAGE, $CFG;
+        $addclusterurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$PAGE->cm->id, 'pageid'=>$previd, 'sesskey'=>sesskey(), 'qtype'=>LESSON_PAGE_CLUSTER));
+        return html_link::make($addclusterurl, get_string('addcluster', 'lesson'));
+    }
+    public function valid_page_and_view(&$validpages, &$pageviews) {
+        $validpages[$this->properties->id] = 1;  // add the cluster page as a valid page
+        foreach ($this->lesson->get_sub_pages_of($this->properties->id, array(LESSON_PAGE_ENDOFCLUSTER)) as $subpage) {
+            if (in_array($subpage->id, $pageviews)) {
+                unset($pageviews[array_search($subpage->id, $pageviews)]);  // remove it
+                // since the user did see one page in the cluster, add the cluster pageid to the viewedpageids
+                if (!in_array($this->properties->id, $pageviews)) {
+                    $pageviews[] = $this->properties->id;
+                }
+            }
+        }
+        return $this->properties->nextpageid;
+    }
+}
+
+class lesson_add_page_form_cluster extends lesson_add_page_form_base {
+
+    public $qtype = LESSON_PAGE_CLUSTER;
+    public $qtypestring = 'cluster';
+    protected $standard = false;
+
+    public function custom_definition() {
+        global $PAGE;
+
+        $mform = $this->_form;
+        $lesson = $this->_customdata['lesson'];
+        $jumptooptions = lesson_page_type_branchtable::get_jumptooptions(optional_param('firstpage', false, PARAM_BOOL), $lesson);
+
+        $mform->addElement('hidden', 'firstpage');
+        $mform->setType('firstpage', PARAM_BOOL);
+
+        $mform->addElement('hidden', 'qtype');
+        $mform->setType('qtype', PARAM_TEXT);
+
+        $mform->addElement('text', 'title', get_string("pagetitle", "lesson"), array('size'=>70));
+        $mform->setType('title', PARAM_TEXT);
+
+        $this->editoroptions = array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes);
+        $mform->addElement('editor', 'contents_editor', get_string("pagecontents", "lesson"), null, $this->editoroptions);
+        $mform->setType('contents_editor', PARAM_CLEANHTML);
+
+        $this->add_jumpto(0);
+    }
+
+
+    public function construction_override($pageid, lesson $lesson) {
+        global $PAGE, $CFG, $DB;
+        require_sesskey();
+
+        $timenow = time();
+
+        if ($pageid == 0) {
+            if ($lesson->has_pages()) {
+                if (!$page = $DB->get_record("lesson_pages", array("prevpageid" => 0, "lessonid" => $lesson->id))) {
+                    print_error('cannotfindpagerecord', 'lesson');
+                }
+            } else {
+                // This is the ONLY page
+                $page = new stdClass;
+                $page->id = 0;
+            }
+        } else {
+            if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
+                print_error('cannotfindpagerecord', 'lesson');
+            }
+        }
+        $newpage = new stdClass;
+        $newpage->lessonid = $lesson->id;
+        $newpage->prevpageid = $pageid;
+        if ($pageid != 0) {
+            $newpage->nextpageid = $page->nextpageid;
+        } else {
+            $newpage->nextpageid = $page->id;
+        }
+        $newpage->qtype = $this->qtype;
+        $newpage->timecreated = $timenow;
+        $newpage->title = get_string("clustertitle", "lesson");
+        $newpage->contents = get_string("clustertitle", "lesson");
+        $newpageid = $DB->insert_record("lesson_pages", $newpage);
+        // update the linked list...
+        if ($pageid != 0) {
+            $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
+        }
+
+        if ($pageid == 0) {
+            $page->nextpageid = $page->id;
+        }
+        if ($page->nextpageid) {
+            // the new page is not the last page
+            $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
+        }
+        // ..and the single "answer"
+        $newanswer = new stdClass;
+        $newanswer->lessonid = $lesson->id;
+        $newanswer->pageid = $newpageid;
+        $newanswer->timecreated = $timenow;
+        $newanswer->jumpto = LESSON_CLUSTERJUMP;
+        $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
+        $lesson->add_message(get_string('addedcluster', 'lesson'), 'notifysuccess');
+        redirect($CFG->wwwroot.'/mod/lesson/edit.php?id='.$PAGE->cm->id);
+    }
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/endofbranch.php b/mod/lesson/pagetypes/endofbranch.php
new file mode 100644 (file)
index 0000000..4dd7c23
--- /dev/null
@@ -0,0 +1,230 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * End of branch table
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+ /** End of Branch page */
+define("LESSON_PAGE_ENDOFBRANCH",   "21");
+
+class lesson_page_type_endofbranch extends lesson_page {
+
+    protected $type = lesson_page::TYPE_STRUCTURE;
+    protected $typeidstring = 'endofbranch';
+    protected $typeid = LESSON_PAGE_ENDOFBRANCH;
+    protected $string = null;
+    protected $jumpto = null;
+
+    public function display($renderer, $attempt) {
+        return '';
+    }
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function callback_on_view($canmanage) {
+        $this->redirect_to_first_answer();
+        exit;
+    }
+
+    public function redirect_to_first_answer($canmanager) {
+        global $USER, $PAGE;
+        $answer = array_shift($this->get_answers());
+        $jumpto = $answer->jumpto;
+        if ($jumpto == LESSON_RANDOMBRANCH) {
+
+            $jumpto = lesson_unseen_branch_jump($this->lesson, $USER->id);
+
+        } elseif ($jumpto == LESSON_CLUSTERJUMP) {
+            
+            if (!$canmanage) {
+                $jumpto = $this->lesson->cluster_jump($pageid);
+            } else {
+                if ($this->properties->nextpageid == 0) {
+                    $jumpto = LESSON_EOL;
+                } else {
+                    $jumpto = $this->properties->nextpageid;
+                }
+            }
+            
+        } else if ($answer->jumpto == LESSON_NEXTPAGE) {
+
+            if ($this->properties->nextpageid == 0) {
+                $jumpto = LESSON_EOL;
+            } else {
+                $jumpto = $this->properties->nextpageid;
+            }
+
+        } else if ($jumpto == 0) {
+
+            $jumpto = $this->properties->id;
+
+        } else if ($jumpto == LESSON_PREVIOUSPAGE) {
+
+            $jumpto = $this->properties->prevpageid;
+            
+        }
+        redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id,'pageid'=>$jumpto)));
+    }
+    public function get_grayout() {
+        return 1;
+    }
+    public function update($properties) {
+        global $DB, $PAGE;
+        
+        $properties->id = $this->properties->id;
+        $properties->lessonid = $this->lesson->id;
+        if (empty($properties->qoption)) {
+            $properties->qoption = '0';
+        }
+        $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id);
+        $DB->update_record("lesson_pages", $properties);
+
+        $answers  = $this->get_answers();
+        if (count($answers)>1) {
+            $answer = array_shift($answers);
+            foreach ($answers as $a) {
+                $DB->delete_record('lesson_answers', array('id'=>$a->id));
+            }
+        } else if (count($answers)==1) {
+            $answer = array_shift($answers);
+        } else {
+            $answer = new stdClass;
+        }
+
+        $answer->timemodified = time();;
+        if (isset($properties->jumpto[0])) {
+            $answer->jumpto = $properties->jumpto[0];
+        }
+        if (isset($form->score[0])) {
+            $answer->score = $properties->score[0];
+        }
+        if (!empty($answer->id)) {
+            $DB->update_record("lesson_answers", $answer->properties());
+        } else {
+            $DB->insert_record("lesson_answers", $answer);
+        }
+        return true;
+    }
+    public function add_page_link($previd) {
+        global $PAGE, $CFG;
+        if ($previd != 0) {
+            $addendofbranchurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$PAGE->cm->id, 'pageid'=>$previd, 'sesskey'=>sesskey(), 'qtype'=>LESSON_PAGE_ENDOFBRANCH));
+            return html_link::make($addendofbranchurl, get_string('addanendofbranch', 'lesson'));
+        }
+        return false;
+    }
+    public function valid_page_and_view(&$validpages, &$pageviews) {
+        return $this->properties->nextpageid;
+    }
+}
+
+class lesson_add_page_form_endofbranch extends lesson_add_page_form_base {
+
+    public $qtype = LESSON_PAGE_ENDOFBRANCH;
+    public $qtypestring = 'endofbranch';
+    protected $standard = false;
+
+    public function custom_definition() {
+        global $PAGE;
+
+        $mform = $this->_form;
+        $lesson = $this->_customdata['lesson'];
+        $jumptooptions = lesson_page_type_branchtable::get_jumptooptions(optional_param('firstpage', false, PARAM_BOOL), $lesson);
+
+        $mform->addElement('hidden', 'firstpage');
+        $mform->setType('firstpage', PARAM_BOOL);
+
+        $mform->addElement('hidden', 'qtype');
+        $mform->setType('qtype', PARAM_TEXT);
+
+        $mform->addElement('text', 'title', get_string("pagetitle", "lesson"), array('size'=>70));
+        $mform->setType('title', PARAM_TEXT);
+
+        $this->editoroptions = array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes);
+        $mform->addElement('editor', 'contents_editor', get_string("pagecontents", "lesson"), null, $this->editoroptions);
+        $mform->setType('contents_editor', PARAM_CLEANHTML);
+
+        $this->add_jumpto(0);
+    }
+
+    public function construction_override($pageid, $lesson) {
+        global $DB, $CFG, $PAGE;
+        require_sesskey();
+
+        // first get the preceeding page
+
+        $timenow = time();
+
+        // the new page is not the first page (end of branch always comes after an existing page)
+        if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
+            print_error('cannotfindpagerecord', 'lesson');
+        }
+        // chain back up to find the (nearest branch table)
+        $btpage = clone($page);
+        $btpageid = $btpage->id;
+        while (($btpage->qtype != LESSON_PAGE_BRANCHTABLE) && ($btpage->prevpageid > 0)) {
+            $btpageid = $btpage->prevpageid;
+            if (!$btpage = $DB->get_record("lesson_pages", array("id" => $btpageid))) {
+                print_error('cannotfindpagerecord', 'lesson');
+            }
+        }
+        
+        if ($btpage->qtype == LESSON_PAGE_BRANCHTABLE) {
+            $newpage = new stdClass;
+            $newpage->lessonid = $lesson->id;
+            $newpage->prevpageid = $pageid;
+            $newpage->nextpageid = $page->nextpageid;
+            $newpage->qtype = $this->qtype;
+            $newpage->timecreated = $timenow;
+            $newpage->title = get_string("endofbranch", "lesson");
+            $newpage->contents = get_string("endofbranch", "lesson");
+            $newpageid = $DB->insert_record("lesson_pages", $newpage);
+            // update the linked list...
+            $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
+            if ($page->nextpageid) {
+                // the new page is not the last page
+                $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
+            }
+            // ..and the single "answer"
+            $newanswer = new stdClass;
+            $newanswer->lessonid = $lesson->id;
+            $newanswer->pageid = $newpageid;
+            $newanswer->timecreated = $timenow;
+            $newanswer->jumpto = $btpageid;
+            $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
+            $lesson->add_message(get_string('addedanendofbranch', 'lesson'), 'notifysuccess');
+        } else {
+            $lesson->add_message(get_string('nobranchtablefound', 'lesson'));
+        }
+
+        redirect($CFG->wwwroot."/mod/lesson/edit.php?id=".$PAGE->cm->id);
+    }
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/endofcluster.php b/mod/lesson/pagetypes/endofcluster.php
new file mode 100644 (file)
index 0000000..4913383
--- /dev/null
@@ -0,0 +1,197 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * End of cluster
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** End of Cluster page */
+define("LESSON_PAGE_ENDOFCLUSTER",   "31");
+
+class lesson_page_type_endofcluster extends lesson_page {
+
+    protected $type = lesson_page::TYPE_STRUCTURE;
+    protected $typeidstring = 'endofcluster';
+    protected $typeid = LESSON_PAGE_ENDOFCLUSTER;
+    protected $string = null;
+    protected $jumpto = null;
+
+    public function display($renderer, $attempt) {
+        return '';
+    }
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function callback_on_view($canmanage) {
+        $this->redirect_to_next_page($canmanage);
+        exit;
+    }
+    public function redirect_to_next_page() {
+        global $PAGE;
+        if ($this->properties->nextpageid == 0) {
+            $nextpageid = LESSON_EOL;
+        } else {
+            $nextpageid = $this->properties->nextpageid;
+        }
+        redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id,'pageid'=>$nextpageid)));
+    }
+    public function get_grayout() {
+        return 1;
+    }
+    public function update($properties) {
+        global $DB, $PAGE;
+
+        $properties->id = $this->properties->id;
+        $properties->lessonid = $this->lesson->id;
+        if (empty($properties->qoption)) {
+            $properties->qoption = '0';
+        }
+        $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id);
+        $DB->update_record("lesson_pages", $properties);
+
+        $answers  = $this->get_answers();
+        if (count($answers)>1) {
+            $answer = array_shift($answers);
+            foreach ($answers as $a) {
+                $DB->delete_record('lesson_answers', array('id'=>$a->id));
+            }
+        } else if (count($answers)==1) {
+            $answer = array_shift($answers);
+        } else {
+            $answer = new stdClass;
+        }
+
+        $answer->timemodified = time();;
+        if (isset($properties->jumpto[0])) {
+            $answer->jumpto = $properties->jumpto[0];
+        }
+        if (isset($form->score[0])) {
+            $answer->score = $properties->score[0];
+        }
+        if (!empty($answer->id)) {
+            $DB->update_record("lesson_answers", $answer->properties());
+        } else {
+            $DB->insert_record("lesson_answers", $answer);
+        }
+        return true;
+    }
+    public function override_next_page() {
+        $jump = $DB->get_field("lesson_answers", "jumpto", array("pageid" => $this->properties->id, "lessonid" => $this->lesson->id));
+        if ($jump == LESSON_NEXTPAGE) {
+            if ($this->properties->nextpageid == 0) {
+                return LESSON_EOL;
+            } else {
+                return $this->properties->nextpageid;
+            }
+        } else {
+            return $jump;
+        }
+    }
+    public function add_page_link($previd) {
+        global $PAGE, $CFG;
+        if ($previd != 0) {
+            $endofclusterurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$PAGE->cm->id, 'pageid'=>$previd, 'sesskey'=>sesskey(), 'qtype'=>LESSON_PAGE_ENDOFCLUSTER));
+            return html_link::make($endofclusterurl, get_string('addendofcluster', 'lesson'));
+        }
+        return false;
+    }
+    public function valid_page_and_view(&$validpages, &$pageviews) {
+        return $this->properties->nextpageid;
+    }
+}
+
+class lesson_add_page_form_endofcluster extends lesson_add_page_form_base {
+
+    public $qtype = LESSON_PAGE_ENDOFCLUSTER;
+    public $qtypestring = 'endofcluster';
+    protected $standard = false;
+
+    public function custom_definition() {
+        global $PAGE;
+
+        $mform = $this->_form;
+        $lesson = $this->_customdata['lesson'];
+        $jumptooptions = lesson_page_type_branchtable::get_jumptooptions(optional_param('firstpage', false, PARAM_BOOL), $lesson);
+
+        $mform->addElement('hidden', 'firstpage');
+        $mform->setType('firstpage', PARAM_BOOL);
+
+        $mform->addElement('hidden', 'qtype');
+        $mform->setType('qtype', PARAM_TEXT);
+
+        $mform->addElement('text', 'title', get_string("pagetitle", "lesson"), array('size'=>70));
+        $mform->setType('title', PARAM_TEXT);
+
+        $this->editoroptions = array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes);
+        $mform->addElement('editor', 'contents_editor', get_string("pagecontents", "lesson"), null, $this->editoroptions);
+        $mform->setType('contents_editor', PARAM_CLEANHTML);
+
+        $this->add_jumpto(0);
+    }
+
+    public function construction_override($pageid, $lesson) {
+        global $CFG, $PAGE, $DB;
+        require_sesskey();
+
+        $timenow = time();
+
+        // the new page is not the first page (end of cluster always comes after an existing page)
+        if (!$page = $DB->get_record("lesson_pages", array("id" => $pageid))) {
+            print_error('cannotfindpages', 'lesson');
+        }
+
+        // could put code in here to check if the user really can insert an end of cluster
+
+        $newpage = new stdClass;
+        $newpage->lessonid = $lesson->id;
+        $newpage->prevpageid = $pageid;
+        $newpage->nextpageid = $page->nextpageid;
+        $newpage->qtype = $this->qtype;
+        $newpage->timecreated = $timenow;
+        $newpage->title = get_string("endofclustertitle", "lesson");
+        $newpage->contents = get_string("endofclustertitle", "lesson");
+        $newpageid = $DB->insert_record("lesson_pages", $newpage);
+        // update the linked list...
+        $DB->set_field("lesson_pages", "nextpageid", $newpageid, array("id" => $pageid));
+        if ($page->nextpageid) {
+            // the new page is not the last page
+            $DB->set_field("lesson_pages", "prevpageid", $newpageid, array("id" => $page->nextpageid));
+        }
+        // ..and the single "answer"
+        $newanswer = new stdClass;
+        $newanswer->lessonid = $lesson->id;
+        $newanswer->pageid = $newpageid;
+        $newanswer->timecreated = $timenow;
+        $newanswer->jumpto = LESSON_NEXTPAGE;
+        $newanswerid = $DB->insert_record("lesson_answers", $newanswer);
+        $lesson->add_message(get_string('addedendofcluster', 'lesson'), 'notifysuccess');
+        redirect($CFG->wwwroot.'/mod/lesson/edit.php?id='.$PAGE->cm->id);
+    }
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/essay.php b/mod/lesson/pagetypes/essay.php
new file mode 100644 (file)
index 0000000..4a0f07c
--- /dev/null
@@ -0,0 +1,270 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Essay
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** Essay question type */
+define("LESSON_PAGE_ESSAY", "10");
+
+class lesson_page_type_essay extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeidstring = 'essay';
+    protected $typeid = LESSON_PAGE_ESSAY;
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $PAGE, $CFG;
+
+        $mform = new lesson_display_answer_form_essay($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        if (isset($USER->modattempts[$this->lesson->id])) {
+            $essayinfo = unserialize($attempt->useranswer);
+            $data->answer = array('text'=>$essayinfo->answer, 'format'=>FORMAT_HTML);
+        }
+        $mform->set_data($data);
+        return $mform->display();
+    }
+    public function create_answers($properties) {
+        global $DB;
+        // now add the answers
+        $newanswer = new stdClass;
+        $newanswer->lessonid = $this->lesson->id;
+        $newanswer->pageid = $this->properties->id;
+        $newanswer->timecreated = $this->properties->timecreated;
+
+        if (isset($properties->jumpto[0])) {
+            $newanswer->jumpto = $properties->jumpto[0];
+        }
+        if (isset($properties->score[0])) {
+            $newanswer->score = $properties->score[0];
+        }
+        $newanswer->id = $DB->insert_record("lesson_answers", $newanswer);
+        $answers = array($newanswer->id => new lesson_page_answer($newanswer));
+        $this->answers = $answers;
+        return $answers;
+    }
+    public function check_answer() {
+        global $PAGE, $CFG;
+        $result = parent::check_answer();
+        $result->isessayquestion = true;
+
+        $mform = new lesson_display_answer_form_essay($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+        $data = $mform->get_data();
+        require_sesskey();
+
+        if (!$data) {
+            redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$this->properties->id)));
+        }
+
+        $studentanswer = $data->answer['text'];
+        if (trim($studentanswer) === '') {
+            $result->noanswer = true;
+            return $result;
+        }
+        
+        $answers = $this->get_answers();
+        foreach ($answers as $answer) {
+            $result->answerid = $answer->id;
+            $result->newpageid = $answer->jumpto;
+        }
+
+        $userresponse = new stdClass;
+        $userresponse->sent=0;
+        $userresponse->graded = 0;
+        $userresponse->score = 0;
+        $userresponse->answer = $studentanswer;
+        $userresponse->response = "";
+        $result->userresponse = serialize($userresponse);
+
+        $result->studentanswer = s($studentanswer);
+        return $result;
+    }
+    public function update($properties) {
+        global $DB, $PAGE;
+        $answers  = $this->get_answers();
+        $properties->id = $this->properties->id;
+        $properties->lessonid = $this->lesson->id;
+        $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id);
+        $DB->update_record("lesson_pages", $properties);
+
+        if (!array_key_exists(0, $this->answers)) {
+            $this->answers[0] = new stdClass;
+            $this->answers[0]->lessonid = $this->lesson->id;
+            $this->answers[0]->pageid = $this->id;
+            $this->answers[0]->timecreated = $this->timecreated;
+        }
+        if (isset($properties->jumpto[0])) {
+            $this->answers[0]->jumpto = $properties->jumpto[0];
+        }
+        if (isset($properties->score[0])) {
+            $this->answers[0]->score = $properties->score[0];
+        }
+        if (!isset($this->answers[0]->id)) {
+            $this->answers[0]->id =  $DB->insert_record("lesson_answers", $this->answers[0]);
+        } else {
+            $DB->update_record("lesson_answers", $this->answers[0]->properties());
+        }
+
+        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);
+        }
+        $essayinfo = unserialize($temp->useranswer);
+        if ($essayinfo->graded) {
+            if (isset($pagestats[$temp->pageid])) {
+                $essaystats = $pagestats[$temp->pageid];
+                $essaystats->totalscore += $essayinfo->score;
+                $essaystats->total++;
+                $pagestats[$temp->pageid] = $essaystats;
+            } else {
+                $essaystats->totalscore = $essayinfo->score;
+                $essaystats->total = 1;
+                $pagestats[$temp->pageid] = $essaystats;
+            }
+        }
+        return true;
+    }
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($useranswer != NULL) {
+                $essayinfo = unserialize($useranswer->useranswer);
+                if ($essayinfo->response == NULL) {
+                    $answerdata->response = get_string("nocommentyet", "lesson");
+                } else {
+                    $answerdata->response = s($essayinfo->response);
+                }
+                if (isset($pagestats[$this->properties->id])) {
+                    $percent = $pagestats[$this->properties->id]->totalscore / $pagestats[$this->properties->id]->total * 100;
+                    $percent = round($percent, 2);
+                    $percent = get_string("averagescore", "lesson").": ". $percent ."%";
+                } else {
+                    // dont think this should ever be reached....
+                    $percent = get_string("nooneansweredthisquestion", "lesson");
+                }
+                if ($essayinfo->graded) {
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$essayinfo->score;
+                    } elseif ($essayinfo->score) {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                } else {
+                    $answerdata->score = get_string("havenotgradedyet", "lesson");
+                }
+            } else {
+                $essayinfo->answer = get_string("didnotanswerquestion", "lesson");
+            }
+
+            if (isset($pagestats[$this->properties->id])) {
+                $avescore = $pagestats[$this->properties->id]->totalscore / $pagestats[$this->properties->id]->total;
+                $avescore = round($avescore, 2);
+                $avescore = get_string("averagescore", "lesson").": ". $avescore ;
+            } else {
+                // dont think this should ever be reached....
+                $avescore = get_string("nooneansweredthisquestion", "lesson");
+            }
+            $answerdata->answers[] = array(s($essayinfo->answer), $avescore);
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+    public function is_unanswered($nretakes) {
+        global $DB, $USER;
+        if (!$DB->count_records("lesson_attempts", array('pageid'=>$thispage->id, 'userid'=>$USER->id, 'retry'=>$nretakes))) {
+            return true;
+        }
+        return false;
+    }
+    public function requires_manual_grading() {
+        return true;
+    }
+    public function get_earnedscore($answers, $attempt) {
+        $essayinfo = unserialize($attempt->useranswer);
+        return $essayinfo->score;
+    }
+}
+
+class lesson_add_page_form_essay extends lesson_add_page_form_base {
+
+    public $qtype = 'essay';
+    public $qtypestring = 'essay';
+
+    public function custom_definition() {
+
+        $this->add_jumpto(0);
+        $this->add_score(0, null, 1);
+
+    }
+}
+
+class lesson_display_answer_form_essay extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $mform->addElement('editor', 'answer', get_string('youranswer', 'lesson'), null, null);
+        $mform->setType('answer', PARAM_CLEANHTML);
+
+        $this->add_action_buttons(null, get_string("pleaseenteryouranswerinthebox", "lesson"));
+    }
+
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/matching.php b/mod/lesson/pagetypes/matching.php
new file mode 100644 (file)
index 0000000..032114c
--- /dev/null
@@ -0,0 +1,513 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Matching
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/** Matching question type */
+define("LESSON_PAGE_MATCHING",      "5");
+
+class lesson_page_type_matching extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeid = LESSON_PAGE_MATCHING;
+    protected $typeidstring = 'matching';
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $USER, $CFG, $PAGE;
+        $mform = $this->make_answer_form($attempt);
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        $mform->set_data($data);
+        return $mform->display();
+    }
+
+    protected function make_answer_form($attempt=null) {
+        global $USER, $CFG;
+        // don't suffle answers (could be an option??)
+        $answers = array_slice($this->get_answers(), 2);
+        $responses = array();
+        foreach ($answers as $answer) {
+            // get all the response
+            if ($answer->response != NULL) {
+                $responses[] = trim($answer->response);
+            }
+        }
+
+        $responseoptions = array();
+        if (!empty($responses)) {
+            shuffle($responses);
+            $responses = array_unique($responses);
+            foreach ($responses as $response) {
+                $responseoptions[htmlspecialchars(trim($response))] = $response;
+            }
+        }
+        if (isset($USER->modattempts[$this->lesson->id]) && !empty($attempt->useranswer)) {
+            $useranswers = explode(',', $attempt->useranswer);
+            $t = 0;
+        } else {
+            $useranswers = array();
+        }
+
+        $action = $CFG->wwwroot.'/mod/lesson/continue.php';
+        $params = array('answers'=>$answers, 'useranswers'=>$useranswers, 'responseoptions'=>$responseoptions, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
+        $mform = new lesson_display_answer_form_matching($action, $params);
+        return $mform;
+    }
+
+    public function create_answers($properties) {
+        global $DB;
+        // now add the answers
+        $newanswer = new stdClass;
+        $newanswer->lessonid = $this->lesson->id;
+        $newanswer->pageid = $this->properties->id;
+        $newanswer->timecreated = $this->properties->timecreated;
+
+        $answers = array();
+
+        // need to add two to offset correct response and wrong response
+        $this->lesson->maxanswers = $this->lesson->maxanswers + 2;
+        for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
+            $answer = clone($newanswer);
+            if (!empty($properties->answer[$i])) {
+                $answer->answer = format_text($properties->answer[$i], FORMAT_PLAIN);
+                if (isset($properties->response[$i])) {
+                    $answer->response = format_text($properties->response[$i], FORMAT_PLAIN);
+                }
+                if (isset($properties->jumpto[$i])) {
+                    $answer->jumpto = $properties->jumpto[$i];
+                }
+                if ($this->lesson->custom && isset($properties->score[$i])) {
+                    $answer->score = $properties->score[$i];
+                }
+                $answer->id = $DB->insert_record("lesson_answers", $answer);
+                $answers[$answer->id] = new lesson_page_answer($answer);
+            } else if ($i < 2) {
+                $answer->id = $DB->insert_record("lesson_answers", $answer);
+                $answers[$answer->id] = new lesson_page_answer($answer);
+            } else {
+                break;
+            }
+        }
+        $this->answers = $answers;
+        return $answers;
+    }
+
+    public function check_answer() {
+        global $CFG;
+        $result = parent::check_answer();
+
+        $mform = $this->make_answer_form();
+
+        $data = $mform->get_data();
+        require_sesskey();
+
+        if (!$data) {
+            redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$this->properties->id)));
+        }
+        
+        $response = $data->response;
+        if (!is_array($response)) {
+            $result->noanswer = true;
+            return $result;
+        }
+        $answers = $this->get_answers();
+
+        $ncorrect = 0;
+        $i = 0;
+        foreach ($answers as $answer) {
+            if ($i < 2) {
+                // ignore first two answers, they are correct response
+                // and wrong response
+                $i++;
+                continue;
+            }
+            if ($answer->response == $response[$answer->id]) {
+                $ncorrect++;
+            }
+            if ($i == 2) {
+                $correctpageid = $answer->jumpto;
+                $correctanswerid = $answer->id;
+            }
+            if ($i == 3) {
+                $wrongpageid = $answer->jumpto;
+                $wronganswerid = $answer->id;
+            }
+            $i++;
+        }
+        // get he users exact responses for record keeping
+        $userresponse = array();
+        foreach ($response as $key => $value) {
+            foreach($answers as $answer) {
+                if ($value == $answer->response) {
+                    $userresponse[] = $answer->id;
+                }
+                if ((int)$answer->id === (int)$key) {
+                    $result->studentanswer .= '<br />'.$answer->answer.' = '.$value;
+                }
+            }
+        }
+        $result->userresponse = implode(",", $userresponse);
+
+        if ($ncorrect == count($answers)-2) {  // dont count correct/wrong responses in the total.
+            foreach ($answers as $answer) {
+                if ($answer->response == NULL && $answer->answer != NULL) {
+                    $result->response = $answer->answer;
+                    break;
+                }
+            }
+            if (isset($correctpageid)) {
+                $result->newpageid = $correctpageid;
+            }
+            if (isset($correctanswerid)) {
+                $result->answerid = $correctanswerid;
+            }
+            $result->correctanswer = true;
+        } else {
+            $t = 0;
+            foreach ($answers as $answer) {
+                if ($answer->response == NULL && $answer->answer != NULL) {
+                    if ($t == 1) {
+                        $result->response = $answer->answer;
+                        break;
+                    }
+                    $t++;
+                }
+            }
+            if (isset($wrongpageid)) {
+                $result->newpageid = $wrongpageid;
+            }
+            if (isset($wronganswerid)) {
+                $result->answerid = $wronganswerid;
+            }
+        }
+        return $result;
+    }
+
+    public function option_description_string() {
+        return get_string("firstanswershould", "lesson");
+    }
+
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        $n = 0;
+        
+        foreach ($answers as $answer) {
+            if ($n < 2) {
+                if ($answer->answer != NULL) {
+                    $cells = array();
+                    if ($n == 0) {
+                        $cells[] = "<span class=\"label\">".get_string("correctresponse", "lesson").'</span>';
+                    } else {
+                        $cells[] = "<span class=\"label\">".get_string("wrongresponse", "lesson").'</span>';
+                    }
+                    $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+                    $table->data[] = html_table_row::make($cells);
+                }
+                $n++;
+                $i--;
+            } else {
+                $cells = array();
+                if ($this->lesson->custom && $answer->score > 0) {
+                    // if the score is > 0, then it is correct
+                    $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+                } else if ($this->lesson->custom) {
+                    $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+                } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                    $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+                } else {
+                    $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+                }
+                $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+                $table->data[] = html_table_row::make($cells);
+
+                $cells = array();
+                $cells[] = '<span class="label">'.get_string("matchesanswer", "lesson")." $i</span>: ";
+                $cells[] = format_text($answer->response, FORMAT_MOODLE, $options);
+                $table->data[] = html_table_row::make($cells);
+            }
+
+            if ($i == 1) {
+                $cells = array();
+                $cells[] = '<span class="label">'.get_string("correctanswerscore", "lesson")." $i</span>: ";
+                $cells[] = $answer->score;
+                $table->data[] = html_table_row::make($cells);
+
+                $cells = array();
+                $cells[] = '<span class="label">'.get_string("correctanswerjump", "lesson")." $i</span>: ";
+                $cells[] = $this->get_jump_name($answer->jumpto);
+                $table->data[] = html_table_row::make($cells);
+            } elseif ($i == 2) {
+                $cells = array();
+                $cells[] = '<span class="label">'.get_string("wronganswerscore", "lesson")." $i</span>: ";
+                $cells[] = $answer->score;
+                $table->data[] = html_table_row::make($cells);
+
+                $cells = array();
+                $cells[] = '<span class="label">'.get_string("wronganswerjump", "lesson")." $i</span>: ";
+                $cells[] = $this->get_jump_name($answer->jumpto);
+                $table->data[] = html_table_row::make($cells);
+            }
+
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+
+            $i++;
+        }
+        return $table;
+    }
+    public function update($properties) {
+        global $DB, $PAGE;
+        $answers  = $this->get_answers();
+        $properties->id = $this->properties->id;
+        $properties->lessonid = $this->lesson->id;
+        $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), get_context_instance(CONTEXT_MODULE, $PAGE->cm->id), 'lesson_page_contents', $properties->id);
+        $DB->update_record("lesson_pages", $properties);
+
+        // need to add two to offset correct response and wrong response
+        $this->lesson->maxanswers += 2;
+        for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
+            if (!array_key_exists($i, $this->answers)) {
+                $this->answers[$i] = new stdClass;
+                $this->answers[$i]->lessonid = $this->lesson->id;
+                $this->answers[$i]->pageid = $this->id;
+                $this->answers[$i]->timecreated = $this->timecreated;
+            }
+            if (!empty($properties->answer[$i])) {
+                $this->answers[$i]->answer = format_text($properties->answer[$i], FORMAT_PLAIN);
+                if (isset($properties->response[$i])) {
+                    $this->answers[$i]->response = format_text($properties->response[$i], FORMAT_PLAIN);
+                }
+                if (isset($properties->jumpto[$i])) {
+                    $this->answers[$i]->jumpto = $properties->jumpto[$i];
+                }
+                if ($this->lesson->custom && isset($properties->score[$i])) {
+                    $this->answers[$i]->score = $properties->score[$i];
+                }
+                if (!isset($this->answers[$i]->id)) {
+                    $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
+                } else {
+                    $DB->update_record("lesson_answers", $this->answers[$i]->properties());
+                }
+
+            } else if ($i < 2) {
+                if (!isset($this->answers[$i]->id)) {
+                    $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
+                } else {
+                    $DB->update_record("lesson_answers", $this->answers[$i]->properties());
+                }
+
+            } else {
+                break;
+            }
+        }
+        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);
+        }
+        if ($temp->correct) {
+            if (isset($pagestats[$temp->pageid]["correct"])) {
+                $pagestats[$temp->pageid]["correct"]++;
+            } else {
+                $pagestats[$temp->pageid]["correct"] = 1;
+            }
+        }
+        if (isset($pagestats[$temp->pageid]["total"])) {
+            $pagestats[$temp->pageid]["total"]++;
+        } else {
+            $pagestats[$temp->pageid]["total"] = 1;
+        }
+        return true;
+    }
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = array();
+        foreach ($this->get_answers() as $answer) {
+            $answers[$answer->id] = $answer;
+        }
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($n == 0 && $useranswer != NULL && $useranswer->correct) {
+                if ($answer->response == NULL && $useranswer != NULL) {
+                    $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                } else {
+                    $answerdata->response = $answer->response;
+                }
+            } elseif ($n == 1 && $useranswer != NULL && !$useranswer->correct) {
+                if ($answer->response == NULL && $useranswer != NULL) {
+                    $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                } else {
+                    $answerdata->response = $answer->response;
+                }
+            } elseif ($n > 1) {
+                if ($n == 2 && $useranswer != NULL && $useranswer->correct) {
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } else {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    }
+                } elseif ($n == 3 && $useranswer != NULL && !$useranswer->correct) {
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                }
+                $data = "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->answer))."</option></select>";
+                if ($useranswer != NULL) {
+                    $userresponse = explode(",", $useranswer->useranswer);
+                    $data .= "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answers[$userresponse[$i]]->response))."</option></select>";
+                } else {
+                    $data .= "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->response))."</option></select>";
+                }
+
+                if ($n == 2) {
+                    if (isset($pagestats[$this->properties->id])) {
+                        if (!array_key_exists('correct', $pagestats[$this->properties->id])) {
+                            $pagestats[$this->properties->id]["correct"] = 0;
+                        }
+                        $percent = $pagestats[$this->properties->id]["correct"] / $pagestats[$this->properties->id]["total"] * 100;
+                        $percent = round($percent, 2);
+                        $percent .= "% ".get_string("answeredcorrectly", "lesson");
+                    } else {
+                        $percent = get_string("nooneansweredthisquestion", "lesson");
+                    }
+                } else {
+                    $percent = "";
+                }
+
+                $answerdata->answers[] = array($data, $percent);
+                $i++;
+            }
+            $n++;
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+    public function get_jumps() {
+        global $DB;
+        // The jumps for matching question type is stored
+        // in the 3rd and 4rth answer record.
+        $jumps = array();
+        $params = array ("lessonid" => $this->lesson->id, "pageid" => $this->properties->id);
+        if ($answers = $DB->get_records_select("lesson_answers", "lessonid = :lessonid and pageid = :pageid", $params, 'id', '*', '2', '2')) {
+            foreach ($answers as $answer) {
+                $jumps[] = $this->get_jump_name($answer->jumpto);
+            }
+        }
+        return $jumps;
+    }
+}
+
+class lesson_add_page_form_matching extends lesson_add_page_form_base {
+
+    public $qtype = 'matching';
+    public $qtypestring = 'matching';
+
+    public function custom_definition() {
+
+        $this->_form->addElement('header', 'correctresponse', get_string('correctresponse', 'lesson'));
+        $this->add_textarea('answer', 0, get_string('correctresponse', 'lesson'));
+        $this->add_jumpto(2, get_string('correctanswerjump','lesson'));
+        $this->add_score(2, get_string("correctanswerscore", "lesson"));
+
+        $this->_form->addElement('header', 'wrongresponse', get_string('wrongresponse', 'lesson'));
+        $this->add_textarea('answer', 1, get_string('wrongresponse', 'lesson'));
+        $this->add_jumpto(3, get_string('wronganswerjump','lesson'));
+        $this->add_score(3, get_string("wronganswerscore", "lesson"));
+
+        for ($i = 2; $i < $this->_customdata['lesson']->maxanswers+2; $i++) {
+            $this->_form->addElement('header', 'matchingpair'.($i-1), get_string('matchingpair', 'lesson', $i-1));
+            $this->add_answer($i);
+            $this->add_response($i, get_string('matchesanswer','lesson'));
+        }
+    }
+}
+
+
+class lesson_display_answer_form_matching extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $answers = $this->_customdata['answers'];
+        $useranswers = $this->_customdata['useranswers'];
+        $responseoptions = $this->_customdata['responseoptions'];
+        $lessonid = $this->_customdata['lessonid'];
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $i = 0;
+        foreach ($answers as $answer) {
+            $mform->addElement('html', '<div class="answeroption">');
+            if ($answer->response != NULL) {
+                $mform->addElement('select', 'response['.$answer->id.']', format_text($answer->answer,FORMAT_MOODLE,$options), $responseoptions);
+                $mform->setType('response['.$answer->id.']', PARAM_TEXT);
+                if (isset($USER->modattempts[$lessonid])) {
+                    $mform->setDefault('response['.$answer->id.']', htmlspecialchars(trim($answers[$useranswers[$t]]->response)));
+                } else {
+                    $mform->setDefault('response['.$answer->id.']', 'answeroption');
+                }
+            }
+            $mform->addElement('html', '</div>');
+            $i++;
+        }
+
+        $this->add_action_buttons(null, get_string("pleasematchtheabovepairs", "lesson"));
+    }
+
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/multichoice.php b/mod/lesson/pagetypes/multichoice.php
new file mode 100644 (file)
index 0000000..76499e0
--- /dev/null
@@ -0,0 +1,503 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Multichoice
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/** Multichoice question type */
+define("LESSON_PAGE_MULTICHOICE",   "3");
+
+class lesson_page_type_multichoice extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeidstring = 'multichoice';
+    protected $typeid = LESSON_PAGE_MULTICHOICE;
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+
+    public function display($renderer, $attempt) {
+        global $CFG, $PAGE;
+        $answers = $this->get_answers();
+        shuffle($answers);
+        $action = $CFG->wwwroot.'/mod/lesson/continue.php';
+        $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
+        if ($this->properties->qoption) {
+            $mform = new lesson_display_answer_form_multichoice_multianswer($action, $params);
+        } else {
+            $mform = new lesson_display_answer_form_multichoice_singleanswer($action, $params);
+        }
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        $mform->set_data($data);
+        return $mform->display();
+    }
+
+    public function check_answer() {
+        global $DB, $CFG;
+        $result = parent::check_answer();
+
+        $answers = $this->get_answers();
+        shuffle($answers);
+        $action = $CFG->wwwroot.'/mod/lesson/continue.php';
+        $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
+        if ($this->properties->qoption) {
+            $mform = new lesson_display_answer_form_multichoice_multianswer($action, $params);
+        } else {
+            $mform = new lesson_display_answer_form_multichoice_singleanswer($action, $params);
+        }
+        $data = $mform->get_data();
+        require_sesskey();
+
+        if (!$data) {
+            redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$this->properties->id)));
+        }
+        
+        if ($this->properties->qoption) {
+            // MULTIANSWER allowed, user's answer is an array
+
+            if (empty($data->answer) || !is_array($data->answer)) {
+                $result->noanswer = true;
+                return $result;
+            }
+
+            $studentanswers = $data->answer;
+            foreach ($studentanswers as $key => $useranswer) {
+                $studentanswers[$key] = clean_param($useranswer, PARAM_INT);
+            }
+            
+            // get what the user answered
+            $result->userresponse = implode(",", $studentanswers);
+
+            // get the answers in a set order, the id order
+            $answers = $this->get_answers();
+            $ncorrect = 0;
+            $nhits = 0;
+            $correctresponse = '';
+            $wrongresponse = '';
+            $correctanswerid = 0;
+            $wronganswerid = 0;
+            // store student's answers for displaying on feedback page
+            foreach ($answers as $answer) {
+                foreach ($studentanswers as $key => $answerid) {
+                    if ($answerid == $answer->id) {
+                        $result->studentanswer .= '<br />'.$answer->answer;
+                    }
+                }
+            }
+            // this is for custom scores.  If score on answer is positive, it is correct
+            if ($this->lesson->custom) {
+                $ncorrect = 0;
+                $nhits = 0;
+                foreach ($answers as $answer) {
+                    if ($answer->score > 0) {
+                        $ncorrect++;
+
+                        foreach ($studentanswers as $key => $answerid) {
+                            if ($answerid == $answer->id) {
+                               $nhits++;
+                            }
+                        }
+                        // save the first jumpto page id, may be needed!...
+                        if (!isset($correctpageid)) {
+                            // leave in its "raw" state - will converted into a proper page id later
+                            $correctpageid = $answer->jumpto;
+                        }
+                        // save the answer id for scoring
+                        if ($correctanswerid == 0) {
+                            $correctanswerid = $answer->id;
+                        }
+                        // ...also save any response from the correct answers...
+                        if (trim(strip_tags($answer->response))) {
+                            $correctresponse = $answer->response;
+                        }
+                    } else {
+                        // save the first jumpto page id, may be needed!...
+                        if (!isset($wrongpageid)) {
+                            // leave in its "raw" state - will converted into a proper page id later
+                            $wrongpageid = $answer->jumpto;
+                        }
+                        // save the answer id for scoring
+                        if ($wronganswerid == 0) {
+                            $wronganswerid = $answer->id;
+                        }
+                        // ...and from the incorrect ones, don't know which to use at this stage
+                        if (trim(strip_tags($answer->response))) {
+                            $wrongresponse = $answer->response;
+                        }
+                    }
+                }
+            } else {
+                foreach ($answers as $answer) {
+                    if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                        $ncorrect++;
+                        foreach ($studentanswers as $key => $answerid) {
+                            if ($answerid == $answer->id) {
+                                $nhits++;
+                            }
+                        }
+                        // save the first jumpto page id, may be needed!...
+                        if (!isset($correctpageid)) {
+                            // leave in its "raw" state - will converted into a proper page id later
+                            $correctpageid = $answer->jumpto;
+                        }
+                        // save the answer id for scoring
+                        if ($correctanswerid == 0) {
+                            $correctanswerid = $answer->id;
+                        }
+                        // ...also save any response from the correct answers...
+                        if (trim(strip_tags($answer->response))) {
+                            $correctresponse = $answer->response;
+                        }
+                    } else {
+                        // save the first jumpto page id, may be needed!...
+                        if (!isset($wrongpageid)) {
+                            // leave in its "raw" state - will converted into a proper page id later
+                            $wrongpageid = $answer->jumpto;
+                        }
+                        // save the answer id for scoring
+                        if ($wronganswerid == 0) {
+                            $wronganswerid = $answer->id;
+                        }
+                        // ...and from the incorrect ones, don't know which to use at this stage
+                        if (trim(strip_tags($answer->response))) {
+                            $wrongresponse = $answer->response;
+                        }
+                    }
+                }
+            }
+            if ((count($studentanswers) == $ncorrect) and ($nhits == $ncorrect)) {
+                $result->correctanswer = true;
+                $result->response  = $correctresponse;
+                $result->newpageid = $correctpageid;
+                $result->answerid  = $correctanswerid;
+            } else {
+                $result->response  = $wrongresponse;
+                $result->newpageid = $wrongpageid;
+                $result->answerid  = $wronganswerid;
+            }
+        } else {
+            // only one answer allowed
+            
+            if (empty($data->answerid) && !is_int($data->answerid)) {
+                $result->noanswer = true;
+                return $result;
+            }
+            $result->answerid = $data->answerid;
+            if (!$answer = $DB->get_record("lesson_answers", array("id" => $result->answerid))) {
+                print_error("Continue: answer record not found");
+            }
+            if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                $result->correctanswer = true;
+            }
+            if ($this->lesson->custom) {
+                if ($answer->score > 0) {
+                    $result->correctanswer = true;
+                } else {
+                    $result->correctanswer = false;
+                }
+            }
+            $result->newpageid = $answer->jumpto;
+            $result->response  = trim($answer->response);
+            $result->userresponse = $answer->answer;
+        }
+        return $result;
+    }
+
+    public function option_description_string() {
+        if ($this->properties->qoption) {
+            return " - ".get_string("multianswer", "lesson");
+        }
+        return parent::option_description_string();
+    }
+
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            if ($this->lesson->custom && $answer->score > 0) {
+                // if the score is > 0, then it is correct
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->custom) {
+                $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                // underline correct answers
+                $cells[] = '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else {
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            }
+            $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("response", "lesson")." $i</span>";
+            $cells[] = format_text($answer->response, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+            
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("score", "lesson").'</span>';
+            $cells[] = $answer->score;
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson").'</span>';
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+            $i++;
+        }
+        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);
+        }
+        if ($this->properties->qoption) {
+            $userresponse = explode(",", $temp->useranswer);
+            foreach ($userresponse as $response) {
+                if (isset($pagestats[$temp->pageid][$response])) {
+                    $pagestats[$temp->pageid][$response]++;
+                } else {
+                    $pagestats[$temp->pageid][$response] = 1;
+                }
+            }
+        } else {
+            if (isset($pagestats[$temp->pageid][$temp->answerid])) {
+                $pagestats[$temp->pageid][$temp->answerid]++;
+            } else {
+                $pagestats[$temp->pageid][$temp->answerid] = 1;
+            }
+        }
+        if (isset($pagestats[$temp->pageid]["total"])) {
+            $pagestats[$temp->pageid]["total"]++;
+        } else {
+            $pagestats[$temp->pageid]["total"] = 1;
+        }
+        return true;
+    }
+
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($this->properties->qoption) {
+                if ($useranswer == NULL) {
+                    $userresponse = array();
+                } else {
+                    $userresponse = explode(",", $useranswer->useranswer);
+                }
+                if (in_array($answer->id, $userresponse)) {
+                    // make checked
+                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
+                    if (!isset($answerdata->response)) {
+                        if ($answer->response == NULL) {
+                            if ($useranswer->correct) {
+                                $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                            } else {
+                                $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                            }
+                        } else {
+                            $answerdata->response = $answer->response;
+                        }
+                    }
+                    if (!isset($answerdata->score)) {
+                        if ($this->lesson->custom) {
+                            $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                        } elseif ($useranswer->correct) {
+                            $answerdata->score = get_string("receivedcredit", "lesson");
+                        } else {
+                            $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                        }
+                    }
+                } else {
+                    // unchecked
+                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
+                }
+                if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
+                    $data = "<div class=highlight>".$data.' '.format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</div>";
+                } else {
+                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
+                }
+            } else {
+                if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
+                    // make checked
+                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
+                    if ($answer->response == NULL) {
+                        if ($useranswer->correct) {
+                            $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                        } else {
+                            $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                        }
+                    } else {
+                        $answerdata->response = $answer->response;
+                    }
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } elseif ($useranswer->correct) {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                } else {
+                    // unchecked
+                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
+                }
+                if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
+                    $data = "<div class=\"highlight\">".$data.' '.format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</div>";
+                } else {
+                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
+                }
+            }
+            if (isset($pagestats[$this->properties->id][$answer->id])) {
+                $percent = $pagestats[$this->properties->id][$answer->id] / $pagestats[$this->properties->id]["total"] * 100;
+                $percent = round($percent, 2);
+                $percent .= "% ".get_string("checkedthisone", "lesson");
+            } else {
+                $percent = get_string("noonecheckedthis", "lesson");
+            }
+
+            $answerdata->answers[] = array($data, $percent);
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+}
+
+
+class lesson_add_page_form_multichoice extends lesson_add_page_form_base {
+
+    public $qtype = 'multichoice';
+    public $qtypestring = 'multichoice';
+
+    public function custom_definition() {
+
+        $this->_form->addElement('checkbox', 'qoption', get_string('options', 'lesson'), get_string('multianswer', 'lesson'));
+        $this->_form->setDefault('qoption', true);
+        $this->_form->setHelpButton('qoption', array("questionoption", get_string("questionoption", "lesson"), "lesson"));
+
+        for ($i = 0; $i < $this->_customdata['lesson']->maxanswers; $i++) {
+            $this->_form->addElement('header', 'answertitle'.$i, get_string('answer').' '.($i+1));
+            $this->add_answer($i);
+            $this->add_response($i);
+            $this->add_jumpto($i);
+            $this->add_score($i, null, ($i===0)?1:0);
+        }
+    }
+}
+
+class lesson_display_answer_form_multichoice_singleanswer extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $answers = $this->_customdata['answers'];
+        $lessonid = $this->_customdata['lessonid'];
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $i = 0;
+        foreach ($answers as $answer) {
+            $mform->addElement('html', '<div class="answeroption">');
+            $mform->addElement('radio','answerid',null,format_text(trim($answer->answer), FORMAT_MOODLE, $options),$answer->id);
+            $mform->setType('answer'.$i, PARAM_INT);
+            if (isset($USER->modattempts[$lessonid]) && $answer->id == $attempt->answerid) {
+                $mform->setDefault('answerid', true);
+            }
+            $mform->addElement('html', '</div>');
+            $i++;
+        }
+
+        $this->add_action_buttons(null, get_string("pleasecheckoneanswer", "lesson"));
+    }
+
+}
+
+class lesson_display_answer_form_multichoice_multianswer extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $answers = $this->_customdata['answers'];
+        $lessonid = $this->_customdata['lessonid'];
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $i = 0;
+        foreach ($answers as $answer) {
+            $mform->addElement('html', '<div class="answeroption">');
+            $mform->addElement('checkbox','answer['.$i.']',null,format_text(trim($answer->answer), FORMAT_MOODLE, $options),$answer->id);
+            $mform->setType('answer'.$i, PARAM_INT);
+            if (isset($USER->modattempts[$lessonid]) && $answer->id == $attempt->answerid) {
+                $mform->setDefault('answer['.$i.']', true);
+            }
+            $mform->addElement('html', '</div>');
+            $i++;
+        }
+
+        $this->add_action_buttons(null, get_string("pleasecheckoneormoreanswers", "lesson"));
+    }
+
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/numerical.php b/mod/lesson/pagetypes/numerical.php
new file mode 100644 (file)
index 0000000..43c1aee
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Numerical
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/** Numerical question type */
+define("LESSON_PAGE_NUMERICAL",     "8");
+
+class lesson_page_type_numerical extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeidstring = 'numerical';
+    protected $typeid = LESSON_PAGE_NUMERICAL;
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $USER, $CFG, $PAGE;
+        $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        if (isset($USER->modattempts[$this->lesson->id])) {
+            $data->answer = s($attempt->useranswer);
+        }
+        $mform->set_data($data);
+        return $mform->display();
+    }
+    public function check_answer() {
+        global $CFG;
+        $result = parent::check_answer();
+
+        $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+        $data = $mform->get_data();
+        require_sesskey();
+
+        // set defaults
+        $result->response = '';
+        $result->newpageid = 0;
+
+        if (isset($data->answer)) {
+            // just doing default PARAM_RAW, not doing PARAM_INT because it could be a float
+            $result->useranswer = (float)$data->answer;
+        } else {
+            $result->noanswer = true;
+            return $result;
+        }
+        $result->studentanswer = $result->userresponse = $result->useranswer;
+        $answers = $this->get_answers();
+        foreach ($answers as $answer) {
+            if (strpos($answer->answer, ':')) {
+                // there's a pairs of values
+                list($min, $max) = explode(':', $answer->answer);
+                $minimum = (float) $min;
+                $maximum = (float) $max;
+            } else {
+                // there's only one value
+                $minimum = (float) $answer->answer;
+                $maximum = $minimum;
+            }
+            if (($result->useranswer >= $minimum) && ($result->useranswer <= $maximum)) {
+                $result->newpageid = $answer->jumpto;
+                $result->response = trim($answer->response);
+                if ($this->lesson->jumpto_is_correct($this->properties->id, $result->newpageid)) {
+                    $result->correctanswer = true;
+                }
+                if ($this->lesson->custom) {
+                    if ($answer->score > 0) {
+                        $result->correctanswer = true;
+                    } else {
+                        $result->correctanswer = false;
+                    }
+                }
+                $result->answerid = $answer->id;
+                return $result;
+            }
+        }
+        return $result;
+    }
+
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            if ($this->lesson->custom && $answer->score > 0) {
+                // if the score is > 0, then it is correct
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->custom) {
+                $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                // underline correct answers
+                $cells[] = '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else {
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            }
+            $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("response", "lesson")." $i</span>";
+            $cells[] = format_text($answer->response, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("score", "lesson").'</span>';
+            $cells[] = $answer->score;
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson").'</span>';
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+            $i++;
+        }
+        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);
+        }
+        if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
+            $pagestats[$temp->pageid][$temp->useranswer]++;
+        } else {
+            $pagestats[$temp->pageid][$temp->useranswer] = 1;
+        }
+        if (isset($pagestats[$temp->pageid]["total"])) {
+            $pagestats[$temp->pageid]["total"]++;
+        } else {
+            $pagestats[$temp->pageid]["total"] = 1;
+        }
+        return true;
+    }
+
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($useranswer == null && $i == 0) {
+                // I have the $i == 0 because it is easier to blast through it all at once.
+                if (isset($pagestats[$this->properties->id])) {
+                    $stats = $pagestats[$this->properties->id];
+                    $total = $stats["total"];
+                    unset($stats["total"]);
+                    foreach ($stats as $valentered => $ntimes) {
+                        $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($valentered).'" />';
+                        $percent = $ntimes / $total * 100;
+                        $percent = round($percent, 2);
+                        $percent .= "% ".get_string("enteredthis", "lesson");
+                        $answerdata->answers[] = array($data, $percent);
+                    }
+                } else {
+                    $answerdata->answers[] = array(get_string("nooneansweredthisquestion", "lesson"), " ");
+                }
+                $i++;
+            } else if ($useranswer != null && ($answer->id == $useranswer->answerid || ($answer == end($answers) && empty($answerdata)))) {
+                 // get in here when what the user entered is not one of the answers
+                $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
+                if (isset($pagestats[$this->properties->id][$useranswer->useranswer])) {
+                    $percent = $pagestats[$this->properties->id][$useranswer->useranswer] / $pagestats[$this->properties->id]["total"] * 100;
+                    $percent = round($percent, 2);
+                    $percent .= "% ".get_string("enteredthis", "lesson");
+                } else {
+                    $percent = get_string("nooneenteredthis", "lesson");
+                }
+                $answerdata->answers[] = array($data, $percent);
+
+                if ($answer->id == $useranswer->answerid) {
+                    if ($answer->response == NULL) {
+                        if ($useranswer->correct) {
+                            $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                        } else {
+                            $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                        }
+                    } else {
+                        $answerdata->response = $answer->response;
+                    }
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } elseif ($useranswer->correct) {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                } else {
+                    $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": 0";
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                }
+            }
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+}
+
+class lesson_add_page_form_numerical extends lesson_add_page_form_base {
+
+    public $qtype = 'numerical';
+    public $qtypestring = 'numerical';
+
+    public function custom_definition() {
+        for ($i = 0; $i < $this->_customdata['lesson']->maxanswers; $i++) {
+            $this->_form->addElement('header', 'answertitle'.$i, get_string('answer').' '.($i+1));
+            $this->add_answer($i);
+            $this->add_response($i);
+            $this->add_jumpto($i);
+            $this->add_score($i, null, ($i===0)?1:0);
+        }
+    }
+}
+
+class lesson_display_answer_form_numerical extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $mform->addElement('text', 'answer', get_string('youranswer', 'lesson'), array('size'=>'50', 'maxlength'=>'200'));
+        $mform->setType('answer', PARAM_FLOAT);
+
+        $this->add_action_buttons(null, get_string("pleaseenteryouranswerinthebox", "lesson"));
+    }
+
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/shortanswer.php b/mod/lesson/pagetypes/shortanswer.php
new file mode 100644 (file)
index 0000000..79f8a64
--- /dev/null
@@ -0,0 +1,349 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Short answer
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** Short answer question type */
+define("LESSON_PAGE_SHORTANSWER",   "1");
+
+class lesson_page_type_shortanswer extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeidstring = 'shortanswer';
+    protected $typeid = LESSON_PAGE_SHORTANSWER;
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $USER, $CFG, $PAGE;
+        $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        if (isset($USER->modattempts[$this->lesson->id])) {
+            $data->answer = s($attempt->useranswer);
+        }
+        $mform->set_data($data);
+        return $mform->display();
+    }
+    public function check_answer() {
+        global $CFG;
+        $result = parent::check_answer();
+
+        $mform = new lesson_display_answer_form_shortanswer($CFG->wwwroot.'/mod/lesson/continue.php', array('contents'=>$this->get_contents()));
+        $data = $mform->get_data();
+        require_sesskey();
+
+        $studentanswer = trim($data->answer);
+        if ($studentanswer === '') {
+            $result->noanswer = true;
+            return $result;
+        }
+        $studentanswer = s($studentanswer);
+
+        $i=0;
+        $answers = $this->get_answers();
+        foreach ($answers as $answer) {
+            $i++;
+            $expectedanswer  = $answer->answer; // for easier handling of $answer->answer
+            $ismatch         = false;
+            $markit          = false;
+            $useregexp       = ($this->qoption);
+
+            if ($useregexp) { //we are using 'normal analysis', which ignores case
+                $ignorecase = '';
+                if (substr($expectedanswer,0,-2) == '/i') {
+                    $expectedanswer = substr($expectedanswer,0,-2);
+                    $ignorecase = 'i';
+                }
+            } else {
+                $expectedanswer = str_replace('*', '#####', $expectedanswer);
+                $expectedanswer = preg_quote($expectedanswer, '/');
+                $expectedanswer = str_replace('#####', '.*', $expectedanswer);
+            }
+            // see if user typed in any of the correct answers
+            if ((!$this->lesson->custom && $this->lesson->jumpto_is_correct($pageid, $answer->jumpto)) or ($this->lesson->custom && $answer->score > 0) ) {
+                if (!$useregexp) { // we are using 'normal analysis', which ignores case
+                    if (preg_match('/^'.$expectedanswer.'$/i',$studentanswer)) {
+                        $ismatch = true;
+                    }
+                } else {
+                    if (preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$studentanswer)) {
+                        $ismatch = true;
+                    }
+                }
+                if ($ismatch == true) {
+                    $result->correctanswer = true;
+                }
+            } else {
+               if (!$useregexp) { //we are using 'normal analysis'
+                    // see if user typed in any of the wrong answers; don't worry about case
+                    if (preg_match('/^'.$expectedanswer.'$/i',$studentanswer)) {
+                        $ismatch = true;
+                    }
+                } else { // we are using regular expressions analysis
+                    $startcode = substr($expectedanswer,0,2);
+                    switch ($startcode){
+                        //1- check for absence of required string in $studentanswer (coded by initial '--')
+                        case "--":
+                            $expectedanswer = substr($expectedanswer,2);
+                            if (!preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$studentanswer)) {
+                                $ismatch = true;
+                            }
+                            break;
+                        //2- check for code for marking wrong strings (coded by initial '++')
+                        case "++":
+                            $expectedanswer=substr($expectedanswer,2);
+                            $markit = true;
+                            //check for one or several matches
+                            if (preg_match_all('/'.$expectedanswer.'/'.$ignorecase,$studentanswer, $matches)) {
+                                $ismatch   = true;
+                                $nb        = count($matches[0]);
+                                $original  = array();
+                                $marked    = array();
+                                $fontStart = '<span class="incorrect matches">';
+                                $fontEnd   = '</span>';
+                                for ($i = 0; $i < $nb; $i++) {
+                                    array_push($original,$matches[0][$i]);
+                                    array_push($marked,$fontStart.$matches[0][$i].$fontEnd);
+                                }
+                                $studentanswer = str_replace($original, $marked, $studentanswer);
+                            }
+                            break;
+                        //3- check for wrong answers belonging neither to -- nor to ++ categories
+                        default:
+                            if (preg_match('/^'.$expectedanswer.'$/'.$ignorecase,$studentanswer, $matches)) {
+                                $ismatch = true;
+                            }
+                            break;
+                    }
+                    $result->correctanswer = false;
+                }
+            }
+            if ($ismatch) {
+                $result->newpageid = $answer->jumpto;
+                if (trim(strip_tags($answer->response))) {
+                    $result->response = $answer->response;
+                }
+                $result->answerid = $answer->id;
+                break; // quit answer analysis immediately after a match has been found
+            }
+        }
+        $result->studentanswer = $result->userresponse = $studentanswer;
+        return $result;
+    }
+
+    public function option_description_string() {
+        if ($this->properties->qoption) {
+            return " - ".get_string("casesensitive", "lesson");
+        }
+        return parent::option_description_string();
+    }
+
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            if ($this->lesson->custom && $answer->score > 0) {
+                // if the score is > 0, then it is correct
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->custom) {
+                $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                // underline correct answers
+                $cells[] = '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else {
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            }
+            $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("response", "lesson")." $i</span>";
+            $cells[] = format_text($answer->response, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("score", "lesson").'</span>';
+            $cells[] = $answer->score;
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson").'</span>';
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+            $i++;
+        }
+        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);
+        }
+        if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
+            $pagestats[$temp->pageid][$temp->useranswer]++;
+        } else {
+            $pagestats[$temp->pageid][$temp->useranswer] = 1;
+        }
+        if (isset($pagestats[$temp->pageid]["total"])) {
+            $pagestats[$temp->pageid]["total"]++;
+        } else {
+            $pagestats[$temp->pageid]["total"] = 1;
+        }
+        return true;
+    }
+
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($useranswer == null && $i == 0) {
+                // I have the $i == 0 because it is easier to blast through it all at once.
+                if (isset($pagestats[$this->properties->id])) {
+                    $stats = $pagestats[$this->properties->id];
+                    $total = $stats["total"];
+                    unset($stats["total"]);
+                    foreach ($stats as $valentered => $ntimes) {
+                        $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($valentered).'" />';
+                        $percent = $ntimes / $total * 100;
+                        $percent = round($percent, 2);
+                        $percent .= "% ".get_string("enteredthis", "lesson");
+                        $answerdata->answers[] = array($data, $percent);
+                    }
+                } else {
+                    $answerdata->answers[] = array(get_string("nooneansweredthisquestion", "lesson"), " ");
+                }
+                $i++;
+            } else if ($useranswer != null && ($answer->id == $useranswer->answerid || ($answer == end($answers) && empty($answerdata)))) {
+                 // get in here when what the user entered is not one of the answers
+                $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
+                if (isset($pagestats[$this->properties->id][$useranswer->useranswer])) {
+                    $percent = $pagestats[$this->properties->id][$useranswer->useranswer] / $pagestats[$this->properties->id]["total"] * 100;
+                    $percent = round($percent, 2);
+                    $percent .= "% ".get_string("enteredthis", "lesson");
+                } else {
+                    $percent = get_string("nooneenteredthis", "lesson");
+                }
+                $answerdata->answers[] = array($data, $percent);
+
+                if ($answer->id == $useranswer->answerid) {
+                    if ($answer->response == NULL) {
+                        if ($useranswer->correct) {
+                            $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                        } else {
+                            $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                        }
+                    } else {
+                        $answerdata->response = $answer->response;
+                    }
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } elseif ($useranswer->correct) {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                } else {
+                    $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": 0";
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                }
+            }
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+}
+
+
+class lesson_add_page_form_shortanswer extends lesson_add_page_form_base {
+    public $qtype = 'shortanswer';
+    public $qtypestring = 'shortanswer';
+
+    public function custom_definition() {
+
+        $this->_form->addElement('checkbox', 'qoption', get_string('options', 'lesson'), get_string('casesensitive', 'lesson'));
+        $this->_form->setDefault('qoption', true);
+        $this->_form->setHelpButton('qoption', array("questionoption", get_string("questionoption", "lesson"), "lesson"));
+
+        for ($i = 0; $i < $this->_customdata['lesson']->maxanswers; $i++) {
+            $this->_form->addElement('header', 'answertitle'.$i, get_string('answer').' '.($i+1));
+            $this->add_answer($i);
+            $this->add_response($i);
+            $this->add_jumpto($i);
+            $this->add_score($i, null, ($i===0)?1:0);
+        }
+    }
+}
+
+class lesson_display_answer_form_shortanswer extends moodleform {
+
+    public function definition() {
+        global $OUTPUT;
+        $mform = $this->_form;
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $mform->addElement('text', 'answer', get_string('youranswer', 'lesson'), array('size'=>'50', 'maxlength'=>'200'));
+        $mform->setType('answer', PARAM_TEXT);
+
+        $this->add_action_buttons(null, get_string("pleaseenteryouranswerinthebox", "lesson"));
+    }
+
+}
\ No newline at end of file
diff --git a/mod/lesson/pagetypes/truefalse.php b/mod/lesson/pagetypes/truefalse.php
new file mode 100644 (file)
index 0000000..4fc5c67
--- /dev/null
@@ -0,0 +1,317 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * True/false
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+ /** True/False question type */
+define("LESSON_PAGE_TRUEFALSE",     "2");
+
+class lesson_page_type_truefalse extends lesson_page {
+
+    protected $type = lesson_page::TYPE_QUESTION;
+    protected $typeidstring = 'truefalse';
+    protected $typeid = LESSON_PAGE_TRUEFALSE;
+    protected $string = null;
+
+    public function get_typeid() {
+        return $this->typeid;
+    }
+    public function get_typestring() {
+        if ($this->string===null) {
+            $this->string = get_string($this->typeidstring, 'lesson');
+        }
+        return $this->string;
+    }
+    public function get_idstring() {
+        return $this->typeidstring;
+    }
+    public function display($renderer, $attempt) {
+        global $USER, $CFG, $PAGE;
+        $answers = $this->get_answers();
+        shuffle($answers);
+
+        $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
+        $mform = new lesson_display_answer_form_truefalse($CFG->wwwroot.'/mod/lesson/continue.php', $params);
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->pageid = $this->properties->id;
+        $mform->set_data($data);
+        return $mform->display();
+    }
+    public function check_answer() {
+        global $DB, $CFG;
+        $answers = $this->get_answers();
+        shuffle($answers);
+        $params = array('answers'=>$answers, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
+        $mform = new lesson_display_answer_form_truefalse($CFG->wwwroot.'/mod/lesson/continue.php', $params);
+        $data = $mform->get_data();
+        require_sesskey();
+
+        $result = parent::check_answer();
+
+        $answerid = $data->answerid;
+        if ($answerid === false) {
+            $result->noanswer = true;
+            return $result;
+        }
+        $result->answerid = $answerid;
+        if (!$answer = $DB->get_record("lesson_answers", array("id" => $result->answerid))) {
+            print_error("Continue: answer record not found");
+        }
+        if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+            $result->correctanswer = true;
+        }
+        if ($this->lesson->custom) {
+            if ($answer->score > 0) {
+                $result->correctanswer = true;
+            } else {
+                $result->correctanswer = false;
+            }
+        }
+        $result->newpageid = $answer->jumpto;
+        $result->response  = trim($answer->response);
+        $result->studentanswer = $result->userresponse = $answer->answer;
+        return $result;
+    }
+
+    public function display_answers(html_table $table) {
+        $answers = $this->get_answers();
+        $options = new stdClass;
+        $options->noclean = true;
+        $options->para = false;
+        $i = 1;
+        foreach ($answers as $answer) {
+            $cells = array();
+            if ($this->lesson->custom && $answer->score > 0) {
+                // if the score is > 0, then it is correct
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->custom) {
+                $cells[] = '<span class="label">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
+                // underline correct answers
+                $cells[] = '<span class="correct">'.get_string("answer", "lesson")." $i</span>: \n";
+            } else {
+                $cells[] = '<span class="labelcorrect">'.get_string("answer", "lesson")." $i</span>: \n";
+            }
+            $cells[] = format_text($answer->answer, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("response", "lesson")." $i</span>";
+            $cells[] = format_text($answer->response, FORMAT_MOODLE, $options);
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("score", "lesson").'</span>';
+            $cells[] = $answer->score;
+            $table->data[] = html_table_row::make($cells);
+
+            $cells = array();
+            $cells[] = "<span class=\"label\">".get_string("jump", "lesson").'</span>';
+            $cells[] = $this->get_jump_name($answer->jumpto);
+            $table->data[] = html_table_row::make($cells);
+            
+            if ($i === 1){
+                $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
+            }
+
+            $i++;
+        }
+        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);
+        }
+        if ($this->properties->qoption) {
+            $userresponse = explode(",", $temp->useranswer);
+            foreach ($userresponse as $response) {
+                if (isset($pagestats[$temp->pageid][$response])) {
+                    $pagestats[$temp->pageid][$response]++;
+                } else {
+                    $pagestats[$temp->pageid][$response] = 1;
+                }
+            }
+        } else {
+            if (isset($pagestats[$temp->pageid][$temp->answerid])) {
+                $pagestats[$temp->pageid][$temp->answerid]++;
+            } else {
+                $pagestats[$temp->pageid][$temp->answerid] = 1;
+            }
+        }
+        if (isset($pagestats[$temp->pageid]["total"])) {
+            $pagestats[$temp->pageid]["total"]++;
+        } else {
+            $pagestats[$temp->pageid]["total"] = 1;
+        }
+        return true;
+    }
+
+    public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
+        $answers = $this->get_answers();
+        $formattextdefoptions = new stdClass;
+        $formattextdefoptions->para = false;  //I'll use it widely in this page
+        foreach ($answers as $answer) {
+            if ($this->properties->qoption) {
+                if ($useranswer == NULL) {
+                    $userresponse = array();
+                } else {
+                    $userresponse = explode(",", $useranswer->useranswer);
+                }
+                if (in_array($answer->id, $userresponse)) {
+                    // make checked
+                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
+                    if (!isset($answerdata->response)) {
+                        if ($answer->response == NULL) {
+                            if ($useranswer->correct) {
+                                $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                            } else {
+                                $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                            }
+                        } else {
+                            $answerdata->response = $answer->response;
+                        }
+                    }
+                    if (!isset($answerdata->score)) {
+                        if ($this->lesson->custom) {
+                            $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                        } elseif ($useranswer->correct) {
+                            $answerdata->score = get_string("receivedcredit", "lesson");
+                        } else {
+                            $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                        }
+                    }
+                } else {
+                    // unchecked
+                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
+                }
+                if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
+                    $data .= "<div class=highlight>".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</div>";
+                } else {
+                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
+                }
+            } else {
+                if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
+                    // make checked
+                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
+                    if ($answer->response == NULL) {
+                        if ($useranswer->correct) {
+                            $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
+                        } else {
+                            $answerdata->response = get_string("thatsthewronganswer", "lesson");
+                        }
+                    } else {
+                        $answerdata->response = $answer->response;
+                    }
+                    if ($this->lesson->custom) {
+                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
+                    } elseif ($useranswer->correct) {
+                        $answerdata->score = get_string("receivedcredit", "lesson");
+                    } else {
+                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
+                    }
+                } else {
+                    // unchecked
+                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
+                }
+                if (($answer->score > 0 && $this->lesson->custom) || ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto) && !$this->lesson->custom)) {
+                    $data .= "<div class=\"highlight\">".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</div>";
+                } else {
+                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
+                }
+            }
+            if (isset($pagestats[$this->properties->id][$answer->id])) {
+                $percent = $pagestats[$this->properties->id][$answer->id] / $pagestats[$this->properties->id]["total"] * 100;
+                $percent = round($percent, 2);
+                $percent .= "% ".get_string("checkedthisone", "lesson");
+            } else {
+                $percent = get_string("noonecheckedthis", "lesson");
+            }
+
+            $answerdata->answers[] = array($data, $percent);
+            $answerpage->answerdata = $answerdata;
+        }
+        return $answerpage;
+    }
+}
+
+class lesson_add_page_form_truefalse extends lesson_add_page_form_base {
+
+    public $qtype = 'truefalse';
+    public $qtypestring = 'truefalse';
+
+    public function custom_definition() {
+        $this->_form->addElement('header', 'answertitle0', get_string('correctresponse', 'lesson'));
+        $this->add_answer(0);
+        $this->add_response(0);
+        $this->add_jumpto(0, get_string('correctanswerjump', 'lesson'));
+        $this->add_score(0, get_string('correctanswerscore', 'lesson'), 1);
+
+        $this->_form->addElement('header', 'answertitle1', get_string('wrongresponse', 'lesson'));
+        $this->add_answer(1);
+        $this->add_response(1);
+        $this->add_jumpto(1, get_string('wronganswerjump', 'lesson'));
+        $this->add_score(1, get_string('wronganswerscore', 'lesson'), 0);
+    }
+}
+
+class lesson_display_answer_form_truefalse extends moodleform {
+
+    public function definition() {
+        global $USER, $OUTPUT;
+        $mform = $this->_form;
+        $answers = $this->_customdata['answers'];
+        $lessonid = $this->_customdata['lessonid'];
+        $contents = $this->_customdata['contents'];
+
+        $mform->addElement('header', 'pageheader', $OUTPUT->box($contents, 'contents'));
+
+        $options = new stdClass;
+        $options->para = false;
+        $options->noclean = true;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $i = 0;
+        foreach ($answers as $answer) {
+            $mform->addElement('html', '<div class="answeroption">');
+            $mform->addElement('radio','answerid',null,format_text(trim($answer->answer), FORMAT_MOODLE, $options),$answer->id);
+            $mform->setType('answerid', PARAM_INT);
+            if (isset($USER->modattempts[$lessonid]) && $answer->id == $attempt->answerid) {
+                $mform->setDefault('answerid', true);
+            }
+            $mform->addElement('html', '</div>');
+            $i++;
+        }
+
+        $this->add_action_buttons(null, get_string("pleasecheckoneanswer", "lesson"));
+    }
+    
+}
\ No newline at end of file
index 830629b5fcca951deb606119c6bf1222d893dcef..4f4ec0ace5be83ca30040f1d318623632f292916 100644 (file)
@@ -1,9 +1,26 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * jjg7:8/9/2004
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
 function removedoublecr($filename) {
diff --git a/mod/lesson/renderer.php b/mod/lesson/renderer.php
new file mode 100644 (file)
index 0000000..55caa98
--- /dev/null
@@ -0,0 +1,669 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Moodle renderer used to display special elements of the lesson module
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+class moodle_mod_lesson_renderer extends moodle_renderer_base {
+
+    /**
+     * A reference to the current general renderer probably {@see moodle_core_renderer}
+     * @var moodle_renderer_base
+     */
+    protected $output;
+
+    /**
+     * Contructor method, calls the parent constructor
+     * @param moodle_page $page
+     * @param moodle_renderer_base $output Probably moodle_core_renderer
+     */
+    public function __construct($page, $output) {
+        parent::__construct($page);
+        $this->output = $output;
+    }
+
+    /**
+     * Magic method used to pass calls otherwise meant for the standard renderer
+     * to it to ensure we don't go causing unnessecary greif.
+     * 
+     * @param string $method
+     * @param array $arguments
+     * @return mixed
+     */
+    public function __call($method, $arguments) {
+        if (method_exists($this->output, $method)) {
+            return call_user_func_array(array($this->output, $method), $arguments);
+        } else {
+            throw new coding_exception('Unknown method called against '.__CLASS__.' :: '.$method);
+        }
+    }
+
+    /**
+     * Returns the header for the lesson module
+     *
+     * @param lesson $lesson
+     * @param string $currenttab
+     * @param bool $extraeditbuttons
+     * @param int $lessonpageid
+     * @return string
+     */
+    public function header($lesson, $currenttab = '', $extraeditbuttons = false, $lessonpageid = null) {
+        global $CFG;
+
+        $activityname = format_string($lesson->name, true, $this->page->course->id);
+        $title = $this->page->course->shortname.": ".$activityname;
+
+        // Build the buttons
+        $context = get_context_instance(CONTEXT_MODULE, $this->page->cm->id);
+        if (has_capability('mod/lesson:edit', $context)) {
+            $buttons = $this->output->update_module_button($this->page->cm->id, 'lesson');
+            if ($extraeditbuttons) {
+                if ($lessonpageid === null) {
+                    print_error('invalidpageid', 'lesson');
+                }
+                if (!empty($lessonpageid) && $lessonpageid != LESSON_EOL) {
+                    $options = array('id'=>$this->page->cm->id, 'redirect'=>'navigation', 'pageid'=>$lessonpageid);
+                    $buttonform = html_form::make_button($CFG->wwwroot.'/mod/lesson/lesson.php', $options, get_string('editpagecontent', 'lesson'));
+                    $buttons .= $this->output->button($buttonform);
+                }
+                $buttons = $this->output->box($buttons, 'edit_buttons');
+            }
+        } else {
+            $buttons = '&nbsp;';
+        }
+
+    /// Header setup
+        $this->page->requires->css('mod/lesson/lesson.css');
+        $this->page->set_title($title);
+        $this->page->set_heading($this->page->course->fullname);
+        $this->page->set_button($buttons);
+        $output = $this->output->header();
+
+        if (has_capability('mod/lesson:manage', $context)) {
+
+            $helpicon = new moodle_help_icon();
+            $helpicon->text = $activityname;
+            $helpicon->page = "overview";
+            $helpicon->module = "lesson";
+
+            $output .= $this->output->heading_with_help($helpicon);
+
+            if (!empty($currenttab)) {
+                ob_start();
+                include($CFG->dirroot.'/mod/lesson/tabs.php');
+                $output .= ob_get_contents();
+                ob_end_clean();
+            }
+        } else {
+            $output .= $this->output->heading($activityname);
+        }
+
+        foreach ($lesson->messages as $message) {
+            $output .= $this->output->notification($message[0], $message[1], $message[2]);
+        }
+
+        return $output;
+    }
+
+    /**
+     * Returns the footer
+     * @return string
+     */
+    public function footer() {
+        return $this->output->footer();
+    }
+
+    /**
+     * Returns HTML for a lesson inaccessible message
+     *
+     * @param string $message
+     * @return <type>
+     */
+    public function lesson_inaccessible($message) {
+        global $CFG;
+        $output  =  $this->output->box_start('generalbox boxaligncenter');
+        $output .=  $this->output->box_start('center');
+        $output .=  $message;
+        $output .=  $this->output->box('<a href="'.$CFG->wwwroot.'/course/view.php?id='. $this->page->course->id .'">'. get_string('returnto', 'lesson', format_string($this->page->course->fullname, true)) .'</a>', 'lessonbutton standardbutton');
+        $output .=  $this->output->box_end();
+        $output .=  $this->output->box_end();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to prompt the user to log in
+     * @param lesson $lesson
+     * @param bool $failedattempt
+     * @return string
+     */
+    public function login_prompt(lesson $lesson, $failedattempt = false) {
+        global $CFG;
+        $output  = $this->output->box_start('password-form');
+        $output .= $this->output->box_start('generalbox boxaligncenter');
+        $output .=  '<form id="password" method="post" action="'.$CFG->wwwroot.'/mod/lesson/view.php" autocomplete="off">';
+        $output .=  '<fieldset class="invisiblefieldset center">';
+        $output .=  '<input type="hidden" name="id" value="'. $this->page->cm->id .'" />';
+        if ($failedattempt) {
+            $output .=  $this->output->notification(get_string('loginfail', 'lesson'));
+        }
+        $output .= get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name)).'<br /><br />';
+        $output .= get_string('enterpassword', 'lesson')." <input type=\"password\" name=\"userpassword\" /><br /><br />";
+        $output .= '<div class="lessonbutton standardbutton"><a href="'.$CFG->wwwroot.'/course/view.php?id='. $this->page->course->id .'">'. get_string('cancel', 'lesson') .'</a></div> ';
+        $output .= "<div class='lessonbutton standardbutton submitbutton'><input type='submit' value='".get_string('continue', 'lesson')."' /></div>";
+        $output .=  '</fieldset></form>';
+        $output .=  $this->output->box_end();
+        $output .=  $this->output->box_end();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to display dependancy errors
+     *
+     * @param object $dependentlesson
+     * @param array $errors
+     * @return string
+     */
+    public function dependancy_errors($dependentlesson, $errors) {
+        $output  = $this->output->box_start('generalbox boxaligncenter');
+        $output .= get_string('completethefollowingconditions', 'lesson', $dependentlesson->name);
+        $output .= $this->output->box(implode('<br />'.get_string('and', 'lesson').'<br />', $errors),'center');
+        $output .= $this->output->box_end();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to display a message
+     * @param string $message
+     * @param html_form $button
+     * @return string
+     */
+    public function message($message, html_form $button = null) {
+        $output  = $this->output->box_start('generalbox boxaligncenter');
+        $output .= $message;
+        if ($button !== null) {
+            $output .= $this->output->box($this->output->button($button),'lessonbutton standardbutton');
+        }
+        $output .= $this->output->box_end();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to display a continue button
+     * @param lesson $lesson
+     * @param int $lastpageseen
+     * @return string
+     */
+    public function continue_links(lesson $lesson, $lastpageseenid) {
+        global $CFG;
+        $output = $this->output->box(get_string('youhaveseen','lesson'), 'generalbox boxaligncenter');
+        $output .= $this->output->box_start('center');
+
+        $yeslink = html_link::make(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$this->page->cm->id, 'pageid'=>$lastpageseenid, 'startlastseen'=>'yes')), get_string('yes'));
+        $output .= $this->output->span($this->output->link($yeslink), 'lessonbutton standardbutton');
+
+        $nolink = html_link::make(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$this->page->cm->id, 'pageid'=>$lesson->firstpageid, 'startlastseen'=>'no')), get_string('no'));
+        $output .= $this->output->span($this->output->link($nolink), 'lessonbutton standardbutton');
+
+        $output .= $this->output->box_end();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to display a page to the user
+     * @param lesson $lesson
+     * @param lesson_page $page
+     * @param object $attempt
+     * @return string
+     */
+    public function display_page(lesson $lesson, lesson_page $page, $attempt) {
+        // We need to buffer here as there is an mforms display call
+        ob_start();
+        echo $page->display($this, $attempt);
+        $output = ob_get_contents();
+        ob_end_clean();
+        return $output;
+    }
+
+    /**
+     * Returns HTML to display a collapsed edit form
+     *
+     * @param lesson $lesson
+     * @param int $pageid
+     * @return string
+     */
+    public function display_edit_collapsed(lesson $lesson, $pageid) {
+        global $DB, $CFG;
+
+        $manager = lesson_page_type_manager::get($lesson);
+        $qtypes = $manager->get_page_type_strings();
+        $npages = count($lesson->load_all_pages());
+
+        $table = new html_table();
+        $table->head = array(get_string('pagetitle', 'lesson'), get_string('qtype', 'lesson'), get_string('jumps', 'lesson'), get_string('actions', 'lesson'));
+        $table->align = array('left', 'left', 'left', 'center');
+        $table->wrap = array('', 'nowrap', '', 'nowrap');
+        $table->tablealign = 'center';
+        $table->cellspacing = 0;
+        $table->cellpadding = '2px';
+        $table->width = '80%';
+        $table->data = array();
+
+        $canedit = has_capability('mod/lesson:edit', get_context_instance(CONTEXT_MODULE, $this->page->cm->id));
+
+        while ($pageid != 0) {
+            $page = $lesson->load_page($pageid);
+            $data = array();
+            $data[] = "<a href=\"$CFG->wwwroot/mod/lesson/edit.php?id=".$this->page->cm->id."&amp;mode=single&amp;pageid=".$page->id."\">".format_string($page->title,true).'</a>';
+            $data[] = $qtypes[$page->qtype];
+            $data[] = implode("<br />\n", $page->jumps);
+            if ($canedit) {
+                $data[] = $this->page_action_links($page, $npages, true);
+            } else {
+                $data[] = '';
+            }
+            $table->data[] = $data;
+            $pageid = $page->nextpageid;
+        }
+
+        return $this->output->table($table);
+    }
+
+    /**
+     * Returns HTML to display the full edit page
+     *
+     * @param lesson $lesson
+     * @param int $pageid
+     * @param int $prevpageid
+     * @param bool $single
+     * @return string
+     */
+    public function display_edit_full(lesson $lesson, $pageid, $prevpageid, $single=false) {
+        global $DB, $CFG;
+
+        $manager = lesson_page_type_manager::get($lesson);
+        $qtypes = $manager->get_page_type_strings();
+        $npages = count($lesson->load_all_pages());
+        $canedit = has_capability('mod/lesson:edit', get_context_instance(CONTEXT_MODULE, $this->page->cm->id));
+
+        $content = '';
+        if ($canedit) {
+            $content = $this->add_page_links($lesson, $prevpageid);
+        }
+
+        $options = new stdClass;
+        $options->noclean = true;
+
+        while ($pageid != 0 && $single!=='stop') {
+            $page = $lesson->load_page($pageid);
+
+            $pagetable = new html_table();
+            $pagetable->align = array('right','left');
+            $pagetable->width = '100%';
+            $pagetable->tablealign = 'center';
+            $pagetable->cellspacing = 0;
+            $pagetable->cellpadding = '5px';
+            $pagetable->data = array();
+
+            $pageheading = new html_table_cell();
+
+            $pageheading->text = format_string($page->title);
+            if ($canedit) {
+                $pageheading->text .= ' '.$this->page_action_links($page, $npages);
+            }
+            $pageheading->style = 'text-align:center';
+            $pageheading->colspan = 2;
+            $pageheading->scope = 'col';
+            $pagetable->head = array($pageheading);
+
+            $cell = new html_table_cell();
+            $cell->colspan = 2;
+            $cell->style = 'text-align:center';
+            $cell->text = format_text($page->contents, FORMAT_MOODLE, $options);
+            $pagetable->data[] = html_table_row::make(array($cell));
+
+            $cell = new html_table_cell();
+            $cell->colspan = 2;
+            $cell->style = 'text-align:center';
+            $cell->text = '<strong>'.$qtypes[$page->qtype] . $page->option_description_string().'</strong>';
+            $pagetable->data[] = html_table_row::make(array($cell));
+
+            $pagetable = $page->display_answers($pagetable);
+
+            $content .= $this->output->table($pagetable);
+
+            if ($canedit) {
+                $content .= $this->add_page_links($lesson, $pageid);
+            }
+
+            // check the prev links - fix (silently) if necessary - there was a bug in
+            // versions 1 and 2 when add new pages. Not serious then as the backwards
+            // links were not used in those versions
+            if ($page->prevpageid != $prevpageid) {
+                // fix it
+                $DB->set_field("lesson_pages", "prevpageid", $prevpageid, array("id" => $page->id));
+                debugging("<p>***prevpageid of page $page->id set to $prevpageid***");
+            }
+
+            $prevpageid = $page->id;
+            $pageid = $page->nextpageid;
+
+            if ($single === true) {
+                $single = 'stop';
+            }
+
+        }
+
+        return $this->output->box($content, 'edit_pages_box');
+    }
+
+    /**
+     * Returns HTML to display the add page links
+     *
+     * @param lesson $lesson
+     * @param int $prevpageid
+     * @return string
+     */
+    public function add_page_links(lesson $lesson, $prevpageid=false) {
+        global $CFG;
+
+        $links = array();
+
+        $importquestionsurl = new moodle_url($CFG->wwwroot.'/mod/lesson/import.php',array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid));
+        $links[] = html_link::make($importquestionsurl, get_string('importquestions', 'lesson'));
+
+        $manager = lesson_page_type_manager::get($lesson);
+        $links = array_merge($links, $manager->get_add_page_type_links($prevpageid));
+
+        $addquestionurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid));
+        $links[] = html_link::make($addquestionurl, get_string('addaquestionpagehere', 'lesson'));
+        
+        foreach ($links as $key=>$link) {
+            $links[$key] = $this->output->link($link);
+        }
+
+        return $this->output->box(implode(" | \n", $links), 'addlinks');
+    }
+
+    /**
+     * Return HTML to display add first page links
+     * @param lesson $lesson
+     * @return string
+     */
+    public function add_first_page_links(lesson $lesson) {
+        global $CFG;
+        $prevpageid = 0;
+
+        $output = $this->output->heading(get_string("whatdofirst", "lesson"), 3);
+        $links = array();
+
+        $importquestionsurl = new moodle_url($CFG->wwwroot.'/mod/lesson/import.php',array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid));
+        $links[] = html_link::make($importquestionsurl, get_string('importquestions', 'lesson'));
+
+        $importppturl = new moodle_url($CFG->wwwroot.'/mod/lesson/importppt.php',array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid));
+        $links[] = html_link::make($importppturl, get_string('importppt', 'lesson'));
+
+        $manager = lesson_page_type_manager::get($lesson);
+        $newpagelinks = $manager->get_add_page_type_links($prevpageid);
+        foreach ($newpagelinks as $link) {
+            $link->url->param('firstpage', 1);
+            $links[] = $link;
+        }
+
+        $addquestionurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$this->page->cm->id, 'pageid'=>$prevpageid, 'firstpage'=>1));
+        $links[] = html_link::make($addquestionurl, get_string('addaquestionpage', 'lesson'));
+
+        foreach ($links as $key=>$link) {
+            $links[$key] = $this->output->link($link);
+        }
+
+        return $this->output->box($output.'<p>'.implode('</p><p>', $links).'</p>', 'generalbox firstpageoptions');
+    }
+
+    /**
+     * Returns HTML to display action links for a page
+     *
+     * @param lesson_page $page
+     * @param bool $printmove
+     * @param bool $printaddpage
+     * @return string
+     */
+    public function page_action_links(lesson_page $page, $printmove, $printaddpage=false) {
+        global $CFG;
+
+        $actions = array();
+
+        if ($printmove) {
+            $printmovehtml = new moodle_url($CFG->wwwroot.'/mod/lesson/lesson.php', array('id'=>$this->page->cm->id, 'action'=>'move', 'pageid'=>$page->id, 'sesskey'=>sesskey()));
+            $actions[] = html_link::make($printmovehtml, '<img src="'.$this->output->old_icon_url('t/move').'" class="iconsmall" alt="'.get_string('move').'" />');
+        }
+        $url = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$this->page->cm->id, 'pageid'=>$page->id, 'edit'=>1));
+        $actions[] = html_link::make($url, '<img src="'.$this->output->old_icon_url('t/edit').'" class="iconsmall" alt="'.get_string('update').'" />');
+
+        $url = new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$this->page->cm->id, 'pageid'=>$page->id));
+        $actions[] = html_link::make($url, '<img src="'.$this->output->old_icon_url('t/preview').'" class="iconsmall" alt="'.get_string('preview').'" />');
+
+        $url = new moodle_url($CFG->wwwroot.'/mod/lesson/lesson.php', array('id'=>$this->page->cm->id, 'action'=>'confirmdelete', 'pageid'=>$page->id, 'sesskey'=>sesskey()));
+        $actions[] = html_link::make($url, '<img src="'.$this->output->old_icon_url('t/delete').'" class="iconsmall" alt="'.get_string('delete').'" />');
+
+        if ($printaddpage) {
+            $options = array();
+            $manager = lesson_page_type_manager::get($page->lesson);
+            $links = $manager->get_add_page_type_links($page->id);
+            foreach ($links as $link) {
+                $options[$link->url->param('qtype')] = $link->text;
+            }
+            $options[0] = get_string('question', 'lesson');
+            
+            $addpageurl = new moodle_url($CFG->wwwroot.'/mod/lesson/editpage.php', array('id'=>$this->page->cm->id, 'pageid'=>$page->id, 'sesskey'=>sesskey()));
+            $addpageselect = html_select::make_popup_form($addpageurl, 'qtype', $options, 'addpageafter'.$page->id);
+            $addpageselect->nothinglabel = get_string('addanewpage', 'lesson').'...';
+            $addpageselector = $this->output->select($addpageselect);
+        }
+
+        foreach ($actions as $key=>$action) {
+            $actions[$key] = $this->output->link($action);
+        }
+        if (isset($addpageselector)) {
+            $actions[] = $addpageselector;
+        }
+
+        return implode(' ', $actions);
+    }
+
+    /**
+     * Prints the on going message to the user.
+     *
+     * With custom grading On, displays points
+     * earned out of total points possible thus far.
+     * With custom grading Off, displays number of correct
+     * answers out of total attempted.
+     *
+     * @param object $lesson The lesson that the user is taking.
+     * @return void
+     **/
+
+     /**
+      * Prints the on going message to the user.
+      *
+      * With custom grading On, displays points
+      * earned out of total points possible thus far.
+      * With custom grading Off, displays number of correct
+      * answers out of total attempted.
+      *
+      * @param lesson $lesson
+      * @return string
+      */
+    public function ongoing_score(lesson $lesson) {
+        global $USER, $DB;
+
+        $context = get_context_instance(CONTEXT_MODULE, $this->page->cm->id);
+        if (has_capability('mod/lesson:manage', $context)) {
+            return '<p align="center">'.get_string('teacherongoingwarning', 'lesson').'</p>';
+        } else {
+            $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
+            if (isset($USER->modattempts[$lesson->id])) {
+                $ntries--;
+            }
+            $gradeinfo = lesson_grade($lesson, $ntries);
+            $a = new stdClass;
+            if ($lesson->custom) {
+                $a->score = $gradeinfo->earned;
+                $a->currenthigh = $gradeinfo->total;
+                return $this->output->box(get_string("ongoingcustom", "lesson", $a), "generalbox boxaligncenter");
+            } else {
+                $a->correct = $gradeinfo->earned;
+                $a->viewed = $gradeinfo->attempts;
+                return $this->output->box(get_string("ongoingnormal", "lesson", $a), "generalbox boxaligncenter");
+            }
+        }
+    }
+
+    /**
+     * Returns HTML to display a progress bar of progression through a lesson
+     *
+     * @param lesson $lesson
+     * @return string
+     */
+    public function progress_bar(lesson $lesson) {
+        global $CFG, $USER, $DB;
+
+        $context = get_context_instance(CONTEXT_MODULE, $this->page->cm->id);
+
+        // lesson setting to turn progress bar on or off
+        if (!$lesson->progressbar) {
+            return '';
+        }
+
+        // catch teachers
+        if (has_capability('mod/lesson:manage', $context)) {
+            return $this->output->notification(get_string('progressbarteacherwarning2', 'lesson'));
+        }
+        
+        if (!isset($USER->modattempts[$lesson->id])) {
+            // all of the lesson pages
+            $pages = $lesson->load_all_pages();
+            foreach ($pages as $page) {
+                if ($page->prevpageid == 0) {
+                    $pageid = $page->id;  // find the first page id
+                    break;
+                }
+            }
+
+            // current attempt number
+            if (!$ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id))) {
+                $ntries = 0;  // may not be necessary
+            }
+
+            
+            $viewedpageids = array();
+            if ($attempts = $lesson->get_attempts($ntries, true)) {
+                $viewedpageids = array_merge($viewedpageids, array_keys($attempts));
+            }
+
+            // collect all of the branch tables viewed
+            if ($viewedbranches = $DB->get_records_select("lesson_branch", array ("lessonid"=>$lesson->id, "userid"=>$USER->id, "retry"=>$ntries), 'timeseen DESC', 'pageid, id')) {
+                $viewedpageids = array_merge($viewedpageids, array_keys($viewedbranches));
+            }
+
+            // Filter out the following pages:
+            //      End of Cluster
+            //      End of Branch
+            //      Pages found inside of Clusters
+            // Do not filter out Cluster Page(s) because we count a cluster as one.
+            // By keeping the cluster page, we get our 1
+            $validpages = array();
+            while ($pageid != 0) {
+                $pageid = $pages[$pageid]->valid_page_and_view($validpages, $viewedpageids);
+            }
+
+            // progress calculation as a percent
+            $progress = round(count($viewedpageids)/count($validpages), 2) * 100;
+        } else {
+            $progress = 100;
+        }
+
+        // print out the Progress Bar.  Attempted to put as much as possible in the style sheets.
+        $cells = array();
+        if ($progress != 0) {  // some browsers do not repsect the 0 width.
+            $cells[0] = new html_table_cell();
+            $cells[0]->style = 'width:'.$progress.'%';
+            $cells[0]->set_classes('progress_bar_completed');
+            $cells[0]->text = ' ';
+        }
+        $cells[] = '<div class="progress_bar_token"></div>';
+
+        $table = new html_table();
+        $table->set_classes(array('progress_bar_table', 'center'));
+        $table->data = array(html_table_row::make($cells));
+        
+        return $this->output->box($this->output->table($table), 'progress_bar');
+    }
+
+    /**
+     * Returns HTML to show the start of a slideshow
+     * @param lesson $lesson
+     */
+    public function slideshow_start(lesson $lesson) {
+        $attributes = array();
+        $attributes['class'] = 'slideshow';
+        $attributes['style'] = 'background-color:'.$lesson->bgcolor.';height:'.$lesson->height.'px;width:'.$lesson->width.'px;';
+        $output = $this->output_start_tag('div', $attributes);
+    }
+    /**
+     * Returns HTML to show the end of a slideshow
+     */
+    public function slideshow_end() {
+        $output = $this->output_end_tag('div');
+    }
+    /**
+     * Returns a P tag containing contents
+     * @param string $contents
+     * @param string $class
+     */
+    public function paragraph($contents, $class='') {
+        $attributes = array();
+        if ($class !== '') {
+            $attributes['class'] = $class;
+        }
+        $output = $this->output_tag('p', $attributes, $contents);
+    }
+    /**
+     * Returns HTML to display add_highscores_form
+     * @param lesson $lesson
+     * @return string
+     */
+    public function add_highscores_form(lesson $lesson) {
+        global $CFG;
+        $output  = $this->output->box_start('generalbox boxaligncenter');
+        $output .= $this->output->box_start('mdl-align');
+        $output .= '<form id="nickname" method ="post" action="'.$CFG->wwwroot.'/mod/lesson/highscores.php" autocomplete="off">
+             <input type="hidden" name="id" value="'.$this->page->cm->id.'" />
+             <input type="hidden" name="mode" value="save" />
+             <input type="hidden" name="sesskey" value="'.sesskey().'" />';
+        $output .= get_string("entername", "lesson").": <input type=\"text\" name=\"name\" size=\"7\" maxlength=\"5\" />";
+        $output .= $this->output->box("<input type='submit' value='".get_string('submitname', 'lesson')."' />", 'lessonbutton center');
+        $output .= "</form>";
+        $output .= $this->output->box_end();
+        $output .= $this->output->box_end();
+        return $output;
+    }
+}
\ No newline at end of file
index 918445242c37fe74ddb11f177c80fa7aecf18233..5216adfd6449d92130ff00e8c65794fc42fdd922 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Displays the lesson statistics.
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
-    require_once('../../config.php');
-    require_once('lib.php');
-    require_once('locallib.php');
+require_once('../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+$id     = required_param('id', PARAM_INT);    // Course Module ID
+$pageid = optional_param('pageid', NULL, PARAM_INT);    // Lesson Page ID
+$action = optional_param('action', 'reportoverview', PARAM_ALPHA);  // action to take
+$nothingtodisplay = false;
+
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
 
-    $id     = required_param('id', PARAM_INT);    // Course Module ID
-    $pageid = optional_param('pageid', NULL, PARAM_INT);    // Lesson Page ID
-    $action = optional_param('action', 'reportoverview', PARAM_ALPHA);  // action to take
-    $nothingtodisplay = false;
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+require_capability('mod/lesson:manage', $context);
 
-    list($cm, $course, $lesson) = lesson_get_basics($id);
-    $params = array("lessonid" => $lesson->id);
-    if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
-        $params["groupid"] = $cm->groupingid;
-        $sql = "SELECT DISTINCT u.*
+$params = array("lessonid" => $lesson->id);
+if (!empty($CFG->enablegroupings) && !empty($cm->groupingid)) {
+    $params["groupid"] = $cm->groupingid;
+    $sql = "SELECT DISTINCT u.id, u.*
                 FROM {lesson_attempts} a
                     INNER JOIN {user} u ON u.id = a.userid
                     INNER JOIN {groups_members} gm ON gm.userid = u.id
                     INNER JOIN {groupings_groups} gg ON gm.groupid = :groupid
                 WHERE a.lessonid = :lessonid
                 ORDER BY u.lastname";
-    } else {
-        $sql = "SELECT u.*
-                FROM {user} u,
-                     {lesson_attempts} a
-                WHERE a.lessonid = :lessonid and
-                      u.id = a.userid
-                ORDER BY u.lastname";
-    }
-
-    if (! $students = $DB->get_records_sql($sql, $params)) {
-        $nothingtodisplay = true;
-    }
-
-// make sure people are where they should be
-    require_login($course->id, false, $cm);
+} else {
+    $sql = "SELECT DISTINCT u.id, u.*
+            FROM {user} u,
+                 {lesson_attempts} a
+            WHERE a.lessonid = :lessonid and
+                  u.id = a.userid
+            ORDER BY u.lastname";
+}
 
-    $url = new moodle_url($CFG->wwwroot.'/mod/lesson/report.php', array('id'=>$id));
-    if ($action !== 'reportoverview') {
-        $url->param('action', $action);
-    }
-    if ($pageid !== NULL) {
-        $url->param('pageid', $pageid);
-    }
-    $PAGE->set_url($url);
-    $PAGE->navbar->add(get_string('reports', 'lesson'), new moodle_url($CFG->wwwroot.'/mod/lesson/report.php', array('id'=>$id)));
+if (! $students = $DB->get_records_sql($sql, $params)) {
+    $nothingtodisplay = true;
+}
 
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    require_capability('mod/lesson:manage', $context);
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/report.php', array('id'=>$id));
+if ($action !== 'reportoverview') {
+    $url->param('action', $action);
+}
+if ($pageid !== NULL) {
+    $url->param('pageid', $pageid);
+}
+$PAGE->set_url($url);
+$PAGE->navbar->add(get_string('reports', 'lesson'), new moodle_url($CFG->wwwroot.'/mod/lesson/report.php', array('id'=>$id)));
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
 
 /// Process any form data before fetching attempts, grades and times
-    if (has_capability('mod/lesson:edit', $context) and
-        $form = data_submitted() and
-        confirm_sesskey()) {
-    /// Cycle through array of userids with nested arrays of tries
-        if (!empty($form->attempts)) {
-            foreach ($form->attempts as $userid => $tries) {
-                // Modifier IS VERY IMPORTANT!  What does it do?
-                //      Well, it is for when you delete multiple attempts for the same user.
-                //      If you delete try 1 and 3 for a user, then after deleting try 1, try 3 then
-                //      becomes try 2 (because try 1 is gone and all tries after try 1 get decremented).
-                //      So, the modifier makes sure that the submitted try refers to the current try in the
-                //      database - hope this all makes sense :)
-                $modifier = 0;
-
-                foreach ($tries as $try => $junk) {
-                    $try -= $modifier;
-
-                /// Clean up the timer table
-                $params = array ("userid" => $userid, "lessonid" => $lesson->id);
-                    $timeid = $DB->get_field_sql("SELECT id FROM {lesson_timer}
-                                             WHERE userid = :userid AND lessonid = :lessonid
-                                             ORDER BY starttime", $params, $try, 1);
-
-                    $DB->delete_records('lesson_timer', array('id' => $timeid));
-
-                /// Remove the grade from the grades and high_scores tables
-                    $gradeid = $DB->get_field_sql("SELECT id FROM {lesson_grades}
-                                              WHERE userid = :userid AND lessonid = :lessonid
-                                              ORDER BY completed", $params, $try, 1);
-
-                    $DB->delete_records('lesson_grades', array('id' => $gradeid));
-                    $DB->delete_records('lesson_high_scores', array('gradeid' => $gradeid, 'lessonid' => $lesson->id, 'userid' => $userid));
-
-                /// Remove attempts and update the retry number
-                    $DB->delete_records('lesson_attempts', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
-                    $DB->execute("UPDATE {lesson_attempts} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
-
-                /// Remove seen branches and update the retry number
-                    $DB->delete_records('lesson_branch', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
-                    $DB->execute("UPDATE {lesson_branch} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
-
-                /// update central gradebook
-                    lesson_update_grades($lesson, $userid);
-
-                    $modifier++;
-                }
+if (has_capability('mod/lesson:edit', $context) && $form = data_submitted() && confirm_sesskey()) {
+/// Cycle through array of userids with nested arrays of tries
+    if (!empty($form->attempts)) {
+        foreach ($form->attempts as $userid => $tries) {
+            // Modifier IS VERY IMPORTANT!  What does it do?
+            //      Well, it is for when you delete multiple attempts for the same user.
+            //      If you delete try 1 and 3 for a user, then after deleting try 1, try 3 then
+            //      becomes try 2 (because try 1 is gone and all tries after try 1 get decremented).
+            //      So, the modifier makes sure that the submitted try refers to the current try in the
+            //      database - hope this all makes sense :)
+            $modifier = 0;
+
+            foreach ($tries as $try => $junk) {
+                $try -= $modifier;
+
+            /// Clean up the timer table
+            $params = array ("userid" => $userid, "lessonid" => $lesson->id);
+                $timeid = $DB->get_field_sql("SELECT id FROM {lesson_timer}
+                                         WHERE userid = :userid AND lessonid = :lessonid
+                                         ORDER BY starttime", $params, $try, 1);
+
+                $DB->delete_records('lesson_timer', array('id' => $timeid));
+
+            /// Remove the grade from the grades and high_scores tables
+                $gradeid = $DB->get_field_sql("SELECT id FROM {lesson_grades}
+                                          WHERE userid = :userid AND lessonid = :lessonid
+                                          ORDER BY completed", $params, $try, 1);
+
+                $DB->delete_records('lesson_grades', array('id' => $gradeid));
+                $DB->delete_records('lesson_high_scores', array('gradeid' => $gradeid, 'lessonid' => $lesson->id, 'userid' => $userid));
+
+            /// Remove attempts and update the retry number
+                $DB->delete_records('lesson_attempts', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
+                $DB->execute("UPDATE {lesson_attempts} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
+
+            /// Remove seen branches and update the retry number
+                $DB->delete_records('lesson_branch', array('userid' => $userid, 'lessonid' => $lesson->id, 'retry' => $try));
+                $DB->execute("UPDATE {lesson_branch} SET retry = retry - 1 WHERE userid = ? AND lessonid = ? AND retry > ?", array($userid, $lesson->id, $try));
+
+            /// update central gradebook
+                lesson_update_grades($lesson, $userid);
+
+                $modifier++;
             }
-            lesson_set_message(get_string('attemptsdeleted', 'lesson'), 'notifysuccess');
         }
+        $lesson->add_message(get_string('attemptsdeleted', 'lesson'), 'notifysuccess');
     }
+}
 
-    if (! $attempts = $DB->get_records('lesson_attempts', array('lessonid' => $lesson->id), 'timeseen')) {
-        $nothingtodisplay = true;
-    }
+if (! $attempts = $DB->get_records('lesson_attempts', array('lessonid' => $lesson->id), 'timeseen')) {
+    $nothingtodisplay = true;
+}
 
-    if (! $grades = $DB->get_records('lesson_grades', array('lessonid' => $lesson->id), 'completed')) {
-        $grades = array();
-    }
+if (! $grades = $DB->get_records('lesson_grades', array('lessonid' => $lesson->id), 'completed')) {
+    $grades = array();
+}
 
-    if (! $times = $DB->get_records('lesson_timer', array('lessonid' => $lesson->id), 'starttime')) {
-        $times = array();
-    }
+if (! $times = $DB->get_records('lesson_timer', array('lessonid' => $lesson->id), 'starttime')) {
+    $times = array();
+}
 
-    lesson_print_header($cm, $course, $lesson, $action);
+echo $lessonoutput->header($lesson, $action);
 
-    $course_context = get_context_instance(CONTEXT_COURSE, $course->id);
-    if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
-        echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">'
-            . get_string('seeallcoursegrades', 'grades') . '</a></div>';
-    }
+$course_context = get_context_instance(CONTEXT_COURSE, $course->id);
+if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
+    $seeallgradeslink = new moodle_url($CFG->wwwroot.'/grade/report/grader/index.php', array('id'=>$course->id));
+    $seeallgradeslink = html_link::make($seeallgradeslink, get_string('seeallcoursegrades', 'grades'));
+    echo $OUTPUT->box($OUTPUT->link($seeallgradeslink), 'allcoursegrades');
+}
 
-    if ($nothingtodisplay) {
-        echo $OUTPUT->notification(get_string('nolessonattempts', 'lesson'));
-        echo $OUTPUT->footer();
-        exit();
-    }
+if ($nothingtodisplay) {
+    echo $OUTPUT->notification(get_string('nolessonattempts', 'lesson'));
+    echo $OUTPUT->footer();
+    exit();
+}
 
-    /**************************************************************************
-    this action is for default view and overview view
-    **************************************************************************/
-    if ($action == 'reportoverview') {
-        $studentdata = array();
-
-        // build an array for output
-        foreach ($attempts as $attempt) {
-            // if the user is not in the array or if the retry number is not in the sub array, add the data for that try.
-            if (!array_key_exists($attempt->userid, $studentdata) || !array_key_exists($attempt->retry, $studentdata[$attempt->userid])) {
-                // restore/setup defaults
-                $n = 0;
-                $timestart = 0;
-                $timeend = 0;
-                $usergrade = NULL;
-
-                // search for the grade record for this try. if not there, the nulls defined above will be used.
-                foreach($grades as $grade) {
-                    // check to see if the grade matches the correct user
-                    if ($grade->userid == $attempt->userid) {
-                        // see if n is = to the retry
-                        if ($n == $attempt->retry) {
-                            // get grade info
-                            $usergrade = round($grade->grade, 2); // round it here so we only have to do it once
-                            break;
-                        }
-                        $n++; // if not equal, then increment n
+/**************************************************************************
+this action is for default view and overview view
+**************************************************************************/
+if ($action == 'reportoverview') {
+    $studentdata = array();
+
+    // build an array for output
+    foreach ($attempts as $attempt) {
+        // if the user is not in the array or if the retry number is not in the sub array, add the data for that try.
+        if (!array_key_exists($attempt->userid, $studentdata) || !array_key_exists($attempt->retry, $studentdata[$attempt->userid])) {
+            // restore/setup defaults
+            $n = 0;
+            $timestart = 0;
+            $timeend = 0;
+            $usergrade = NULL;
+
+            // search for the grade record for this try. if not there, the nulls defined above will be used.
+            foreach($grades as $grade) {
+                // check to see if the grade matches the correct user
+                if ($grade->userid == $attempt->userid) {
+                    // see if n is = to the retry
+                    if ($n == $attempt->retry) {
+                        // get grade info
+                        $usergrade = round($grade->grade, 2); // round it here so we only have to do it once
+                        break;
                     }
+                    $n++; // if not equal, then increment n
                 }
-                $n = 0;
-                // search for the time record for this try. if not there, the nulls defined above will be used.
-                foreach($times as $time) {
-                    // check to see if the grade matches the correct user
-                    if ($time->userid == $attempt->userid) {
-                        // see if n is = to the retry
-                        if ($n == $attempt->retry) {
-                            // get grade info
-                            $timeend = $time->lessontime;
-                            $timestart = $time->starttime;
-                            break;
-                        }
-                        $n++; // if not equal, then increment n
+            }
+            $n = 0;
+            // search for the time record for this try. if not there, the nulls defined above will be used.
+            foreach($times as $time) {
+                // check to see if the grade matches the correct user
+                if ($time->userid == $attempt->userid) {
+                    // see if n is = to the retry
+                    if ($n == $attempt->retry) {
+                        // get grade info
+                        $timeend = $time->lessontime;
+                        $timestart = $time->starttime;
+                        break;
                     }
+                    $n++; // if not equal, then increment n
                 }
-
-                // build up the array.
-                // this array represents each student and all of their tries at the lesson
-                $studentdata[$attempt->userid][$attempt->retry] = array( "timestart" => $timestart,
-                                                                        "timeend" => $timeend,
-                                                                        "grade" => $usergrade,
-                                                                        "try" => $attempt->retry,
-                                                                        "userid" => $attempt->userid);
             }
+
+            // build up the array.
+            // this array represents each student and all of their tries at the lesson
+            $studentdata[$attempt->userid][$attempt->retry] = array( "timestart" => $timestart,
+                                                                    "timeend" => $timeend,
+                                                                    "grade" => $usergrade,
+                                                                    "try" => $attempt->retry,
+                                                                    "userid" => $attempt->userid);
         }
-        // set all the stats variables
-        $numofattempts = 0;
-        $avescore      = 0;
-        $avetime       = 0;
-        $highscore     = NULL;
-        $lowscore      = NULL;
-        $hightime      = NULL;
-        $lowtime       = NULL;
-
-        $table = new html_table();
-
-        // set up the table object
-        $table->head = array(get_string('name'), get_string('attempts', 'lesson'), get_string('highscore', 'lesson'));
-        $table->align = array("center", "left", "left");
-        $table->wrap = array("nowrap", "nowrap", "nowrap");
-        $table->width = "90%";
-        $table->size = array("*", "70%", "*");
-
-        // print out the $studentdata array
-        // going through each student that has attempted the lesson, so, each student should have something to be displayed
-        foreach ($students as $student) {
-            // check to see if the student has attempts to print out
-            if (array_key_exists($student->id, $studentdata)) {
-                // set/reset some variables
-                $attempts = array();
-                // gather the data for each user attempt
-                $bestgrade = 0;
-                $bestgradefound = false;
-                // $tries holds all the tries/retries a student has done
-                $tries = $studentdata[$student->id];
-                $studentname = "{$student->lastname},&nbsp;$student->firstname";
-                foreach ($tries as $try) {
-                // start to build up the checkbox and link
-                    if (has_capability('mod/lesson:edit', $context)) {
-                        $temp = '<input type="checkbox" id="attempts" name="attempts['.$try['userid'].']['.$try['try'].']" /> ';
-                    } else {
-                        $temp = '';
-                    }
+    }
+    // set all the stats variables
+    $numofattempts = 0;
+    $avescore      = 0;
+    $avetime       = 0;
+    $highscore     = NULL;
+    $lowscore      = NULL;
+    $hightime      = NULL;
+    $lowtime       = NULL;
+
+    $table = new html_table();
+
+    // set up the table object
+    $table->head = array(get_string('name'), get_string('attempts', 'lesson'), get_string('highscore', 'lesson'));
+    $table->align = array("center", "left", "left");
+    $table->wrap = array("nowrap", "nowrap", "nowrap");
+    $table->set_classes(array('standardtable', 'generaltable'));
+    $table->size = array("*", "70%", "*");
+
+    // print out the $studentdata array
+    // going through each student that has attempted the lesson, so, each student should have something to be displayed
+    foreach ($students as $student) {
+        // check to see if the student has attempts to print out
+        if (array_key_exists($student->id, $studentdata)) {
+            // set/reset some variables
+            $attempts = array();
+            // gather the data for each user attempt
+            $bestgrade = 0;
+            $bestgradefound = false;
+            // $tries holds all the tries/retries a student has done
+            $tries = $studentdata[$student->id];
+            $studentname = "{$student->lastname},&nbsp;$student->firstname";
+            foreach ($tries as $try) {
+            // start to build up the checkbox and link
+                if (has_capability('mod/lesson:edit', $context)) {
+                    $temp = '<input type="checkbox" id="attempts" name="attempts['.$try['userid'].']['.$try['try'].']" /> ';
+                } else {
+                    $temp = '';
+                }
 
-                    $temp .= "<a href=\"report.php?id=$cm->id&amp;action=reportdetail&amp;userid=".$try['userid'].'&amp;try='.$try['try'].'">';
-                    if ($try["grade"] !== NULL) { // if NULL then not done yet
-                        // this is what the link does when the user has completed the try
-                        $timetotake = $try["timeend"] - $try["timestart"];
-
-                        $temp .= $try["grade"]."%";
-                        $bestgradefound = true;
-                        if ($try["grade"] > $bestgrade) {
-                            $bestgrade = $try["grade"];
-                        }
-                        $temp .= "&nbsp;".userdate($try["timestart"]);
-                        $temp .= ",&nbsp;(".format_time($timetotake).")</a>";
-                    } else {
-                        // this is what the link does/looks like when the user has not completed the try
-                        $temp .= get_string("notcompleted", "lesson");
-                        $temp .= "&nbsp;".userdate($try["timestart"])."</a>";
-                        $timetotake = NULL;
+                $temp .= "<a href=\"report.php?id=$cm->id&amp;action=reportdetail&amp;userid=".$try['userid'].'&amp;try='.$try['try'].'">';
+                if ($try["grade"] !== NULL) { // if NULL then not done yet
+                    // this is what the link does when the user has completed the try
+                    $timetotake = $try["timeend"] - $try["timestart"];
+
+                    $temp .= $try["grade"]."%";
+                    $bestgradefound = true;
+                    if ($try["grade"] > $bestgrade) {
+                        $bestgrade = $try["grade"];
                     }
-                    // build up the attempts array
-                    $attempts[] = $temp;
-
-                    // run these lines for the stats only if the user finnished the lesson
-                    if ($try["grade"] !== NULL) {
-                        $numofattempts++;
-                        $avescore += $try["grade"];
-                        $avetime += $timetotake;
-                        if ($try["grade"] > $highscore || $highscore == NULL) {
-                            $highscore = $try["grade"];
-                        }
-                        if ($try["grade"] < $lowscore || $lowscore == NULL) {
-                            $lowscore = $try["grade"];
-                        }
-                        if ($timetotake > $hightime || $hightime == NULL) {
-                            $hightime = $timetotake;
-                        }
-                        if ($timetotake < $lowtime || $lowtime == NULL) {
-                            $lowtime = $timetotake;
-                        }
+                    $temp .= "&nbsp;".userdate($try["timestart"]);
+                    $temp .= ",&nbsp;(".format_time($timetotake).")</a>";
+                } else {
+                    // this is what the link does/looks like when the user has not completed the try
+                    $temp .= get_string("notcompleted", "lesson");
+                    $temp .= "&nbsp;".userdate($try["timestart"])."</a>";
+                    $timetotake = NULL;
+                }
+                // build up the attempts array
+                $attempts[] = $temp;
+
+                // run these lines for the stats only if the user finnished the lesson
+                if ($try["grade"] !== NULL) {
+                    $numofattempts++;
+                    $avescore += $try["grade"];
+                    $avetime += $timetotake;
+                    if ($try["grade"] > $highscore || $highscore == NULL) {
+                        $highscore = $try["grade"];
+                    }
+                    if ($try["grade"] < $lowscore || $lowscore == NULL) {
+                        $lowscore = $try["grade"];
+                    }
+                    if ($timetotake > $hightime || $hightime == NULL) {
+                        $hightime = $timetotake;
+                    }
+                    if ($timetotake < $lowtime || $lowtime == NULL) {
+                        $lowtime = $timetotake;
                     }
                 }
-                // get line breaks in after each attempt
-                $attempts = implode("<br />\n", $attempts);
-                // add it to the table data[] object
-                $table->data[] = array($studentname, $attempts, $bestgrade."%");
             }
+            // get line breaks in after each attempt
+            $attempts = implode("<br />\n", $attempts);
+            // add it to the table data[] object
+            $table->data[] = array($studentname, $attempts, $bestgrade."%");
         }
-        // print it all out !
-        if (has_capability('mod/lesson:edit', $context)) {
-            echo  "<form id=\"theform\" method=\"post\" action=\"report.php\">\n
-                   <input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n
-                   <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n
-                   <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
-        }
-        echo $OUTPUT->table($table);
-
-        if (has_capability('mod/lesson:edit', $context)) {
-            echo '<br /><table width="90%" align="center"><tr><td>'.
-                 '<a href="javascript: checkall();">'.get_string('selectall').'</a> / '.
-                 '<a href="javascript: checknone();">'.get_string('deselectall').'</a> ';
-
-            $select = new html_select();
-            $select->options = array('delete' => get_string('deleteselected'));
-            $select->name = 'attemptaction';
-            $select->selectedvalue = 0;
-            $select->add_action('change', 'submit_form_by_id', array('id' => 'theform'));
-            echo $OUTPUT->select($select);
-
-            echo '</td></tr></table></form>';
-        }
+    }
+    // print it all out !
+    if (has_capability('mod/lesson:edit', $context)) {
+        echo  "<form id=\"theform\" method=\"post\" action=\"report.php\">\n
+               <input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n
+               <input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
+    }
+    echo $OUTPUT->table($table);
+    if (has_capability('mod/lesson:edit', $context)) {
+        $checklinks  = '<a href="javascript: checkall();">'.get_string('selectall').'</a> / ';
+        $checklinks .='<a href="javascript: checknone();">'.get_string('deselectall').'</a>';
+        $select = new html_select();
+        $select->options = array('delete' => get_string('deleteselected'));
+        $select->name = 'attemptaction';
+        $select->selectedvalue = 0;
+        $select->add_action('change', 'submit_form_by_id', array('id' => 'theform'));
+        echo $OUTPUT->box($checklinks.$OUTPUT->select($select), 'center');
+        echo '</form>';
+    }
 
-        // some stat calculations
-        if ($numofattempts == 0) {
-            $avescore = get_string("notcompleted", "lesson");
-        } else {
-            $avescore = format_float($avescore/$numofattempts, 2);
-        }
-        if ($avetime == NULL) {
-            $avetime = get_string("notcompleted", "lesson");
-        } else {
-            $avetime = format_float($avetime/$numofattempts, 0);
-            $avetime = format_time($avetime);
-        }
-        if ($hightime == NULL) {
-            $hightime = get_string("notcompleted", "lesson");
-        } else {
-            $hightime = format_time($hightime);
-        }
-        if ($lowtime == NULL) {
-            $lowtime = get_string("notcompleted", "lesson");
-        } else {
-            $lowtime = format_time($lowtime);
-        }
-        if ($highscore == NULL) {
-            $highscore = get_string("notcompleted", "lesson");
-        }
-        if ($lowscore == NULL) {
-            $lowscore = get_string("notcompleted", "lesson");
-        }
+    // some stat calculations
+    if ($numofattempts == 0) {
+        $avescore = get_string("notcompleted", "lesson");
+    } else {
+        $avescore = format_float($avescore/$numofattempts, 2);
+    }
+    if ($avetime == NULL) {
+        $avetime = get_string("notcompleted", "lesson");
+    } else {
+        $avetime = format_float($avetime/$numofattempts, 0);
+        $avetime = format_time($avetime);
+    }
+    if ($hightime == NULL) {
+        $hightime = get_string("notcompleted", "lesson");
+    } else {
+        $hightime = format_time($hightime);
+    }
+    if ($lowtime == NULL) {
+        $lowtime = get_string("notcompleted", "lesson");
+    } else {
+        $lowtime = format_time($lowtime);
+    }
+    if ($highscore == NULL) {
+        $highscore = get_string("notcompleted", "lesson");
+    }
+    if ($lowscore == NULL) {
+        $lowscore = get_string("notcompleted", "lesson");
+    }
 
-        // output the stats
-        echo $OUTPUT->heading(get_string('lessonstats', 'lesson'));
-        $stattable = new stdClass;
-        $stattable->head = array(get_string('averagescore', 'lesson'), get_string('averagetime', 'lesson'),
-                                get_string('highscore', 'lesson'), get_string('lowscore', 'lesson'),
-                                get_string('hightime', 'lesson'), get_string('lowtime', 'lesson'));
-        $stattable->align = array("center", "center", "center", "center", "center", "center");
-        $stattable->wrap = array("nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap");
-        $stattable->width = "90%";
-        $stattable->data[] = array($avescore.'%', $avetime, $highscore.'%', $lowscore.'%', $hightime, $lowtime);
-
-        echo $OUTPUT->table($stattable);
-}
+    // output the stats
+    echo $OUTPUT->heading(get_string('lessonstats', 'lesson'));
+    $stattable = new html_table();
+    $stattable->head = array(get_string('averagescore', 'lesson'), get_string('averagetime', 'lesson'),
+                            get_string('highscore', 'lesson'), get_string('lowscore', 'lesson'),
+                            get_string('hightime', 'lesson'), get_string('lowtime', 'lesson'));
+    $stattable->align = array("center", "center", "center", "center", "center", "center");
+    $stattable->wrap = array("nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap");
+    $stattable->set_classes(array('standardtable', 'generaltable'));
+    $stattable->data[] = array($avescore.'%', $avetime, $highscore.'%', $lowscore.'%', $hightime, $lowtime);
+
+    echo $OUTPUT->table($stattable);
+} else if ($action == 'reportdetail') {
     /**************************************************************************
     this action is for a student detailed view and for the general detailed view
 
-        General flow of this section of the code
-        1.  Generate a object which holds values for the statistics for each question/answer
-        2.  Cycle through all the pages to create a object.  Foreach page, see if the student actually answered
-            the page.  Then process the page appropriatly.  Display all info about the question,
-            Highlight correct answers, show how the user answered the question, and display statistics
-            about each page
-        3.  Print out info about the try (if needed)
-        4.  Print out the object which contains all the try info
-
-    **************************************************************************/
-    else if ($action == 'reportdetail') {
-
-        $formattextdefoptions = new stdClass;
-        $formattextdefoptions->para = false;  //I'll use it widely in this page
-
-        $userid = optional_param('userid', NULL, PARAM_INT); // if empty, then will display the general detailed view
-        $try    = optional_param('try', NULL, PARAM_INT);
-
-        if (! $lessonpages = $DB->get_records("lesson_pages", array("lessonid" => $lesson->id))) {
-            print_error('cannotfindpages', 'lesson');
-        }
-        if (! $pageid = $DB->get_field("lesson_pages", "id", array("lessonid" => $lesson->id, "prevpageid" => 0))) {
-            print_error('cannotfindfirstpage', 'lesson');
+    General flow of this section of the code
+    1.  Generate a object which holds values for the statistics for each question/answer
+    2.  Cycle through all the pages to create a object.  Foreach page, see if the student actually answered
+        the page.  Then process the page appropriatly.  Display all info about the question,
+        Highlight correct answers, show how the user answered the question, and display statistics
+        about each page
+    3.  Print out info about the try (if needed)
+    4.  Print out the object which contains all the try info
+
+**************************************************************************/
+    $formattextdefoptions = new stdClass;
+    $formattextdefoptions->para = false;  //I'll use it widely in this page
+
+    $userid = optional_param('userid', NULL, PARAM_INT); // if empty, then will display the general detailed view
+    $try    = optional_param('try', NULL, PARAM_INT);
+
+    $lessonpages = $lesson->load_all_pages();
+    foreach ($lessonpages as $lessonpage) {
+        if ($lessonpage->prevpageid == 0) {
+            $pageid = $lessonpage->id;
         }
+    }
 
-        // now gather the stats into an object
-        $firstpageid = $pageid;
-        $pagestats = array();
-        while ($pageid != 0) { // EOL
-            $page = $lessonpages[$pageid];
-            $params = array ("lessonid" => $lesson->id, "pageid" => $page->id);
-            if ($allanswers = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND pageid = :pageid", $params, "timeseen")) {
-                // get them ready for processing
-                $orderedanswers = array();
-                foreach ($allanswers as $singleanswer) {
-                    // ordering them like this, will help to find the single attempt record that we want to keep.
-                    $orderedanswers[$singleanswer->userid][$singleanswer->retry][] = $singleanswer;
-                }
-                // this is foreach user and for each try for that user, keep one attempt record
-                foreach ($orderedanswers as $orderedanswer) {
-                    foreach($orderedanswer as $tries) {
-                        if(count($tries) > $lesson->maxattempts) { // if there are more tries than the max that is allowed, grab the last "legal" attempt
-                            $temp = $tries[$lesson->maxattempts - 1];
-                        } else {
-                            // else, user attempted the question less than the max, so grab the last one
-                            $temp = end($tries);
-                        }
-                        // page interpretation
-                        // depending on the page type, process stat info for that page
-                        switch ($page->qtype) {
-                            case LESSON_MULTICHOICE:
-                            case LESSON_TRUEFALSE:
-                                if ($page->qoption) {
-                                    $userresponse = explode(",", $temp->useranswer);
-                                    foreach ($userresponse as $response) {
-                                        if (isset($pagestats[$temp->pageid][$response])) {
-                                            $pagestats[$temp->pageid][$response]++;
-                                        } else {
-                                            $pagestats[$temp->pageid][$response] = 1;
-                                        }
-                                    }
-                                } else {
-                                    if (isset($pagestats[$temp->pageid][$temp->answerid])) {
-                                        $pagestats[$temp->pageid][$temp->answerid]++;
-                                    } else {
-                                        $pagestats[$temp->pageid][$temp->answerid] = 1;
-                                    }
-                                }
-                                if (isset($pagestats[$temp->pageid]["total"])) {
-                                    $pagestats[$temp->pageid]["total"]++;
-                                } else {
-                                    $pagestats[$temp->pageid]["total"] = 1;
-                                }
-                                break;
-                            case LESSON_SHORTANSWER:
-                            case LESSON_NUMERICAL:
-                                if (isset($pagestats[$temp->pageid][$temp->useranswer])) {
-                                    $pagestats[$temp->pageid][$temp->useranswer]++;
-                                } else {
-                                    $pagestats[$temp->pageid][$temp->useranswer] = 1;
-                                }
-                                if (isset($pagestats[$temp->pageid]["total"])) {
-                                    $pagestats[$temp->pageid]["total"]++;
-                                } else {
-                                    $pagestats[$temp->pageid]["total"] = 1;
-                                }
-                                break;
-                            case LESSON_MATCHING:
-                                if ($temp->correct) {
-                                    if (isset($pagestats[$temp->pageid]["correct"])) {
-                                        $pagestats[$temp->pageid]["correct"]++;
-                                    } else {
-                                        $pagestats[$temp->pageid]["correct"] = 1;
-                                    }
-                                }
-                                if (isset($pagestats[$temp->pageid]["total"])) {
-                                    $pagestats[$temp->pageid]["total"]++;
-                                } else {
-                                    $pagestats[$temp->pageid]["total"] = 1;
-                                }
-                                break;
-                            case LESSON_ESSAY:
-                                $essayinfo = unserialize($temp->useranswer);
-                                if ($essayinfo->graded) {
-                                    if (isset($pagestats[$temp->pageid])) {
-                                        $essaystats = $pagestats[$temp->pageid];
-                                        $essaystats->totalscore += $essayinfo->score;
-                                        $essaystats->total++;
-                                        $pagestats[$temp->pageid] = $essaystats;
-                                    } else {
-                                        $essaystats->totalscore = $essayinfo->score;
-                                        $essaystats->total = 1;
-                                        $pagestats[$temp->pageid] = $essaystats;
-                                    }
-                                }
-                                break;
-                        }
-                    }
+    // now gather the stats into an object
+    $firstpageid = $pageid;
+    $pagestats = array();
+    while ($pageid != 0) { // EOL
+        $page = $lessonpages[$pageid];
+        $params = array ("lessonid" => $lesson->id, "pageid" => $page->id);
+        if ($allanswers = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND pageid = :pageid", $params, "timeseen")) {
+            // get them ready for processing
+            $orderedanswers = array();
+            foreach ($allanswers as $singleanswer) {
+                // ordering them like this, will help to find the single attempt record that we want to keep.
+                $orderedanswers[$singleanswer->userid][$singleanswer->retry][] = $singleanswer;
+            }
+            // this is foreach user and for each try for that user, keep one attempt record
+            foreach ($orderedanswers as $orderedanswer) {
+                foreach($orderedanswer as $tries) {
+                    $page->stats($pagestats, $tries);
                 }
-
-            } else {
-                // no one answered yet...
             }
-            //unset($orderedanswers);  initialized above now
-            $pageid = $page->nextpageid;
+        } else {
+            // no one answered yet...
         }
+        //unset($orderedanswers);  initialized above now
+        $pageid = $page->nextpageid;
+    }
 
-
-
-        $answerpages = array();
-        $answerpage = "";
-        $pageid = $firstpageid;
-        // cycle through all the pages
-        //  foreach page, add to the $answerpages[] array all the data that is needed
-        //  from the question, the users attempt, and the statistics
-        // grayout pages that the user did not answer and Branch, end of branch, cluster
-        // and end of cluster pages
-        while ($pageid != 0) { // EOL
-            $page = $lessonpages[$pageid];
-            $answerpage = new stdClass;
-            $data ='';
-            $answerdata = new stdClass;
-
-            $answerpage->title = format_string($page->title);
-
-            $options = new stdClass;
-            $options->noclean = true;
-            $answerpage->contents = format_text($page->contents, FORMAT_MOODLE, $options);
-
-            // get the page qtype
-            switch ($page->qtype) {
-                case LESSON_ESSAY :
-                case LESSON_MATCHING :
-                case LESSON_TRUEFALSE :
-                case LESSON_NUMERICAL :
-                    $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
-                    $answerpage->grayout = 0;
-                    break;
-                case LESSON_SHORTANSWER :
-                    $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
-                    if ($page->qoption) {
-                        $answerpage->qtype .= " - ".get_string("casesensitive", "lesson");
-                    }
-                    $answerpage->grayout = 0;
-                    break;
-                case LESSON_MULTICHOICE :
-                    $answerpage->qtype = $LESSON_QUESTION_TYPE[$page->qtype];
-                    if ($page->qoption) {
-                        $answerpage->qtype .= " - ".get_string("multianswer", "lesson");
-                    }
-                    $answerpage->grayout = 0;
-                    break;
-                case LESSON_BRANCHTABLE :
-                    $answerpage->qtype = get_string("branchtable", "lesson");
-                    $answerpage->grayout = 1;
-                    break;
-                case LESSON_ENDOFBRANCH :
-                    $answerpage->qtype = get_string("endofbranch", "lesson");
-                    $answerpage->grayout = 1;
-                    break;
-                case LESSON_CLUSTER :
-                    $answerpage->qtype = get_string("clustertitle", "lesson");
-                    $answerpage->grayout = 1;
-                    break;
-                case LESSON_ENDOFCLUSTER :
-                    $answerpage->qtype = get_string("endofclustertitle", "lesson");
-                    $answerpage->grayout = 1;
-                    break;
+    $manager = lesson_page_type_manager::get($lesson);
+    $qtypes = $manager->get_page_type_strings();
+
+    $answerpages = array();
+    $answerpage = "";
+    $pageid = $firstpageid;
+    // cycle through all the pages
+    //  foreach page, add to the $answerpages[] array all the data that is needed
+    //  from the question, the users attempt, and the statistics
+    // grayout pages that the user did not answer and Branch, end of branch, cluster
+    // and end of cluster pages
+    while ($pageid != 0) { // EOL
+        $page = $lessonpages[$pageid];
+        $answerpage = new stdClass;
+        $data ='';
+        $answerdata = new stdClass;
+
+        $answerpage->title = format_string($page->title);
+
+        $options = new stdClass;
+        $options->noclean = true;
+        $answerpage->contents = format_text($page->contents, FORMAT_MOODLE, $options);
+
+        $answerpage->qtype = $qtypes[$page->qtype].$page->option_description_string();
+        $answerpage->grayout = $page->grayout;
+
+        if (empty($userid)) {
+            // there is no userid, so set these vars and display stats.
+            $answerpage->grayout = 0;
+            $useranswer = NULL;
+            $answerdata->score = NULL;
+            $answerdata->response = NULL;
+        } elseif ($useranswers = $DB->get_records("lesson_attempts",array("lessonid"=>$lesson->id, "userid"=>$userid, "retry"=>$try,"pageid"=>$page->id), "timeseen")) {
+            // get the user's answer for this page
+            // need to find the right one
+            $i = 0;
+            foreach ($useranswers as $userattempt) {
+                $useranswer = $userattempt;
+                $i++;
+                if ($lesson->maxattempts == $i) {
+                    break; // reached maxattempts, break out
+                }
             }
+        } else {
+            // user did not answer this page, gray it out and set some nulls
+            $answerpage->grayout = 1;
+            $useranswer = NULL;
+            $answerdata->score = NULL;
+            $answerdata->response = NULL;
 
+        }
+        $i = 0;
+        $n = 0;
+        $answerpages[] = $page->report_answers(clone($answerpage), clone($answerdata), $useranswer, $pagestats, $i, $n);
+        $pageid = $page->nextpageid;
+    }
 
-            if (empty($userid)) {
-                // there is no userid, so set these vars and display stats.
-                $answerpage->grayout = 0;
-                $useranswer = NULL;
-                $answerdata->score = NULL;
-                $answerdata->response = NULL;
-            } elseif ($useranswers = $DB->get_records_select("lesson_attempts",
-                                                         "lessonid = :lessonid AND userid = :userid AND retry = :retry AND pageid = :pageid",
-                                                         array("lessonid" => $lesson->id, "userid" => $userid, "retry" => $try, "pageid" => $page->id), "timeseen")) {
-                // get the user's answer for this page
-                // need to find the right one
-                $i = 0;
-                foreach ($useranswers as $userattempt) {
-                    $useranswer = $userattempt;
-                    $i++;
-                    if ($lesson->maxattempts == $i) {
-                        break; // reached maxattempts, break out
-                    }
-                }
-            } else {
-                // user did not answer this page, gray it out and set some nulls
-                $answerpage->grayout = 1;
-                $useranswer = NULL;
-                $answerdata->score = NULL;
-                $answerdata->response = NULL;
-
-            }
-            // build up the answer data
-            if ($answers = $DB->get_records("lesson_answers", array("pageid" => $page->id), "id")) {
-                $i = 0;
-                $n = 0;
-                // go through each answer and display it properly with statistics, highlight if correct answer,
-                // and display what the user entered
-                foreach ($answers as $answer) {
-                    switch ($page->qtype) {
-                        case LESSON_MULTICHOICE:
-                        case LESSON_TRUEFALSE:
-                            if ($page->qoption) {
-                                if ($useranswer == NULL) {
-                                    $userresponse = array();
-                                } else {
-                                    $userresponse = explode(",", $useranswer->useranswer);
-                                }
-                                if (in_array($answer->id, $userresponse)) {
-                                    // make checked
-                                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
-                                    if (!isset($answerdata->response)) {
-                                        if ($answer->response == NULL) {
-                                            if ($useranswer->correct) {
-                                                $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
-                                            } else {
-                                                $answerdata->response = get_string("thatsthewronganswer", "lesson");
-                                            }
-                                        } else {
-                                            $answerdata->response = $answer->response;
-                                        }
-                                    }
-                                    if (!isset($answerdata->score)) {
-                                        if ($lesson->custom) {
-                                            $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
-                                        } elseif ($useranswer->correct) {
-                                            $answerdata->score = get_string("receivedcredit", "lesson");
-                                        } else {
-                                            $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                        }
-                                    }
-                                } else {
-                                    // unchecked
-                                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
-                                }
-                                if (($answer->score > 0 && $lesson->custom) || (lesson_iscorrect($page->id, $answer->jumpto) && !$lesson->custom)) {
-                                    $data .= "<font class=highlight>".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</font>";
-                                } else {
-                                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
-                                }
-                            } else {
-                                if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
-                                    // make checked
-                                    $data = "<input  readonly=\"readonly\" disabled=\"disabled\" name=\"answer[$i]\" checked=\"checked\" type=\"checkbox\" value=\"1\" />";
-                                    if ($answer->response == NULL) {
-                                        if ($useranswer->correct) {
-                                            $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
-                                        } else {
-                                            $answerdata->response = get_string("thatsthewronganswer", "lesson");
-                                        }
-                                    } else {
-                                        $answerdata->response = $answer->response;
-                                    }
-                                    if ($lesson->custom) {
-                                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
-                                    } elseif ($useranswer->correct) {
-                                        $answerdata->score = get_string("receivedcredit", "lesson");
-                                    } else {
-                                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                    }
-                                } else {
-                                    // unchecked
-                                    $data = "<input type=\"checkbox\" readonly=\"readonly\" name=\"answer[$i]\" value=\"0\" disabled=\"disabled\" />";
-                                }
-                                if (($answer->score > 0 && $lesson->custom) || (lesson_iscorrect($page->id, $answer->jumpto) && !$lesson->custom)) {
-                                    $data .= "<font class=\"highlight\">".format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions)."</font>";
-                                } else {
-                                    $data .= format_text($answer->answer,FORMAT_MOODLE,$formattextdefoptions);
-                                }
-                            }
-                            if (isset($pagestats[$page->id][$answer->id])) {
-                                $percent = $pagestats[$page->id][$answer->id] / $pagestats[$page->id]["total"] * 100;
-                                $percent = round($percent, 2);
-                                $percent .= "% ".get_string("checkedthisone", "lesson");
-                            } else {
-                                $percent = get_string("noonecheckedthis", "lesson");
-                            }
-
-                            $answerdata->answers[] = array($data, $percent);
-                            break;
-                        case LESSON_SHORTANSWER:
-                        case LESSON_NUMERICAL:
-                            if ($useranswer == NULL && $i == 0) {
-                                // I have the $i == 0 because it is easier to blast through it all at once.
-                                if (isset($pagestats[$page->id])) {
-                                    $stats = $pagestats[$page->id];
-                                    $total = $stats["total"];
-                                    unset($stats["total"]);
-                                    foreach ($stats as $valentered => $ntimes) {
-                                        $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($valentered).'" />';
-                                        $percent = $ntimes / $total * 100;
-                                        $percent = round($percent, 2);
-                                        $percent .= "% ".get_string("enteredthis", "lesson");
-                                        $answerdata->answers[] = array($data, $percent);
-                                    }
-                                } else {
-                                    $answerdata->answers[] = array(get_string("nooneansweredthisquestion", "lesson"), " ");
-                                }
-                                $i++;
-                            } else if ($useranswer != NULL and $answer->id == $useranswer->answerid) {
-                                // get in here when a user answer matches one of the answers to the page
-                                $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
-                                if (isset($pagestats[$page->id][$useranswer->useranswer])) {
-                                    $percent = $pagestats[$page->id][$useranswer->useranswer] / $pagestats[$page->id]["total"] * 100;
-                                    $percent = round($percent, 2);
-                                    $percent .= "% ".get_string("enteredthis", "lesson");
-                                } else {
-                                    $percent = get_string("nooneenteredthis", "lesson");
-                                }
-                                $answerdata->answers[] = array($data, $percent);
-
-                                if ($answer->response == NULL) {
-                                    if ($useranswer->correct) {
-                                        $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
-                                    } else {
-                                        $answerdata->response = get_string("thatsthewronganswer", "lesson");
-                                    }
-                                } else {
-                                    $answerdata->response = $answer->response;
-                                }
-                                if ($lesson->custom) {
-                                    $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
-                                } elseif ($useranswer->correct) {
-                                    $answerdata->score = get_string("receivedcredit", "lesson");
-                                } else {
-                                    $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                }
-                            } elseif ($answer == end($answers) && empty($answerdata) && $useranswer != NULL) {
-                                // get in here when what the user entered is not one of the answers
-                                $data = '<input type="text" size="50" disabled="disabled" readonly="readonly" value="'.s($useranswer->useranswer).'">';
-                                if (isset($pagestats[$page->id][$useranswer->useranswer])) {
-                                    $percent = $pagestats[$page->id][$useranswer->useranswer] / $pagestats[$page->id]["total"] * 100;
-                                    $percent = round($percent, 2);
-                                    $percent .= "% ".get_string("enteredthis", "lesson");
-                                } else {
-                                    $percent = get_string("nooneenteredthis", "lesson");
-                                }
-                                $answerdata->answers[] = array($data, $percent);
-
-                                $answerdata->response = get_string("thatsthewronganswer", "lesson");
-                                if ($lesson->custom) {
-                                    $answerdata->score = get_string("pointsearned", "lesson").": 0";
-                                } else {
-                                    $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                }
-                            }
-                            break;
-                        case LESSON_MATCHING:
-                            if ($n == 0 && $useranswer != NULL && $useranswer->correct) {
-                                if ($answer->response == NULL && $useranswer != NULL) {
-                                    $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
-                                } else {
-                                    $answerdata->response = $answer->response;
-                                }
-                            } elseif ($n == 1 && $useranswer != NULL && !$useranswer->correct) {
-                                if ($answer->response == NULL && $useranswer != NULL) {
-                                    $answerdata->response = get_string("thatsthewronganswer", "lesson");
-                                } else {
-                                    $answerdata->response = $answer->response;
-                                }
-                            } elseif ($n > 1) {
-                                if ($n == 2 && $useranswer != NULL && $useranswer->correct) {
-                                    if ($lesson->custom) {
-                                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
-                                    } else {
-                                        $answerdata->score = get_string("receivedcredit", "lesson");
-                                    }
-                                } elseif ($n == 3 && $useranswer != NULL && !$useranswer->correct) {
-                                    if ($lesson->custom) {
-                                        $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
-                                    } else {
-                                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                    }
-                                }
-                                $data = "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->answer))."</option></select>";
-                                if ($useranswer != NULL) {
-                                    $userresponse = explode(",", $useranswer->useranswer);
-                                    $data .= "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answers[$userresponse[$i]]->response))."</option></select>";
-                                } else {
-                                    $data .= "<select disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->response))."</option></select>";
-                                }
-
-                                if ($n == 2) {
-                                    if (isset($pagestats[$page->id])) {
-                                        $percent = $pagestats[$page->id]["correct"] / $pagestats[$page->id]["total"] * 100;
-                                        $percent = round($percent, 2);
-                                        $percent .= "% ".get_string("answeredcorrectly", "lesson");
-                                    } else {
-                                        $percent = get_string("nooneansweredthisquestion", "lesson");
-                                    }
-                                } else {
-                                    $percent = "";
-                                }
-
-                                $answerdata->answers[] = array($data, $percent);
-                                $i++;
-                            }
-                            $n++;
-                            break;
-                        case LESSON_ESSAY :
-                            if ($useranswer != NULL) {
-                                $essayinfo = unserialize($useranswer->useranswer);
-                                if ($essayinfo->response == NULL) {
-                                    $answerdata->response = get_string("nocommentyet", "lesson");
-                                } else {
-                                    $answerdata->response = s($essayinfo->response);
-                                }
-                                if (isset($pagestats[$page->id])) {
-                                    $percent = $pagestats[$page->id]->totalscore / $pagestats[$page->id]->total * 100;
-                                    $percent = round($percent, 2);
-                                    $percent = get_string("averagescore", "lesson").": ". $percent ."%";
-                                } else {
-                                    // dont think this should ever be reached....
-                                    $percent = get_string("nooneansweredthisquestion", "lesson");
-                                }
-                                if ($essayinfo->graded) {
-                                    if ($lesson->custom) {
-                                        $answerdata->score = get_string("pointsearned", "lesson").": ".$essayinfo->score;
-                                    } elseif ($essayinfo->score) {
-                                        $answerdata->score = get_string("receivedcredit", "lesson");
-                                    } else {
-                                        $answerdata->score = get_string("didnotreceivecredit", "lesson");
-                                    }
-                                } else {
-                                    $answerdata->score = get_string("havenotgradedyet", "lesson");
-                                }
-                            } else {
-                                $essayinfo->answer = get_string("didnotanswerquestion", "lesson");
-                            }
-
-                            if (isset($pagestats[$page->id])) {
-                                $avescore = $pagestats[$page->id]->totalscore / $pagestats[$page->id]->total;
-                                $avescore = round($avescore, 2);
-                                $avescore = get_string("averagescore", "lesson").": ". $avescore ;
-                            } else {
-                                // dont think this should ever be reached....
-                                $avescore = get_string("nooneansweredthisquestion", "lesson");
-                            }
-                            $answerdata->answers[] = array(s($essayinfo->answer), $avescore);
-                            break;
-                        case LESSON_BRANCHTABLE :
-                            $data = "<input type=\"button\" name=\"$answer->id\" value=\"".strip_tags(format_text($answer->answer, FORMAT_MOODLE,$formattextdefoptions))."\" disabled=\"disabled\"> ";
-                            $data .= get_string('jumpsto', 'lesson', lesson_get_jump_name($answer->jumpto));
-
-                            $answerdata->answers[] = array($data, "");
-                            $answerpage->grayout = 1; // always grayed out
-                            break;
-                        case LESSON_ENDOFBRANCH :
-                        case LESSON_CLUSTER :
-                        case LESSON_ENDOFCLUSTER :
-                            $data = get_string('jumpsto', 'lesson', lesson_get_jump_name($answer->jumpto));
-
-                            $answerdata->answers[] = array($data, "");
-                            $answerpage->grayout = 1; // always grayed out
-                            break;
-                    }
-                    if (isset($answerdata)) {
-                        $answerpage->answerdata = $answerdata;
-                    }
-                }
-                $answerpages[] = $answerpage;
-            }
-            $pageid = $page->nextpageid;
+    /// actually start printing something
+    $table = new html_table();
+    $table->wrap = array();
+    $table->width = "60%";
+    if (!empty($userid)) {
+        // if looking at a students try, print out some basic stats at the top
+
+            // print out users name
+            //$headingobject->lastname = $students[$userid]->lastname;
+            //$headingobject->firstname = $students[$userid]->firstname;
+            //$headingobject->attempt = $try + 1;
+            //print_heading(get_string("studentattemptlesson", "lesson", $headingobject));
+        echo $OUTPUT->heading(get_string('attempt', 'lesson', $try+1));
+
+        $table->head = array();
+        $table->align = array("right", "left");
+        $table->set_classes(array('compacttable', 'generaltable'));
+
+        $params = array("lessonid"=>$lesson->id, "userid"=>$userid);
+        if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid and userid = :userid", $params, "completed", "*", $try, 1)) {
+            $grade = -1;
+            $completed = -1;
+        } else {
+            $grade = current($grades);
+            $completed = $grade->completed;
+            $grade = round($grade->grade, 2);
+        }
+        if (!$times = $DB->get_records_select("lesson_timer", "lessonid = :lessonid and userid = :userid", $params, "starttime", "*", $try, 1)) {
+            $timetotake = -1;
+        } else {
+            $timetotake = current($times);
+            $timetotake = $timetotake->lessontime - $timetotake->starttime;
         }
 
-        /// actually start printing something
-        $table = new html_table();
-        $table->wrap = array();
-        $table->width = "60%";
-
-
-        if (!empty($userid)) {
-            // if looking at a students try, print out some basic stats at the top
-
-                // print out users name
-                //$headingobject->lastname = $students[$userid]->lastname;
-                //$headingobject->firstname = $students[$userid]->firstname;
-                //$headingobject->attempt = $try + 1;
-                //print_heading(get_string("studentattemptlesson", "lesson", $headingobject));
-            echo $OUTPUT->heading(get_string('attempt', 'lesson', $try+1));
-
-            $table->head = array();
-            $table->align = array("right", "left");
-            $table->class = 'generaltable userinfotable';
-
-            $params = array ("lessonid" => $lesson->id, "userid" => $userid);
-            if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid and userid = :userid", $params, "completed", "*", $try, 1)) {
-                $grade = -1;
-                $completed = -1;
-            } else {
-                $grade = current($grades);
-                $completed = $grade->completed;
-                $grade = round($grade->grade, 2);
-            }
-            if (!$times = $DB->get_records_select("lesson_timer", "lessonid = :lessonid and userid = :userid", $params, "starttime", "*", $try, 1)) {
-                $timetotake = -1;
-            } else {
-                $timetotake = current($times);
-                $timetotake = $timetotake->lessontime - $timetotake->starttime;
-            }
+        if ($timetotake == -1 || $completed == -1 || $grade == -1) {
+            $table->align = array("center");
 
-            if ($timetotake == -1 || $completed == -1 || $grade == -1) {
-                $table->align = array("center");
+            $table->data[] = array(get_string("notcompleted", "lesson"));
+        } else {
+            $user = $students[$userid];
 
-                $table->data[] = array(get_string("notcompleted", "lesson"));
-            } else {
-                $user = $students[$userid];
+            $gradeinfo = lesson_grade($lesson, $try, $user->id);
 
-                $gradeinfo = lesson_grade($lesson, $try, $user->id);
+            $table->data[] = array(get_string('name').':', $OUTPUT->user_picture(moodle_user_picture::make($user, $course->id)).fullname($user, true));
+            $table->data[] = array(get_string("timetaken", "lesson").":", format_time($timetotake));
+            $table->data[] = array(get_string("completed", "lesson").":", userdate($completed));
+            $table->data[] = array(get_string('rawgrade', 'lesson').':', $gradeinfo->earned.'/'.$gradeinfo->total);
+            $table->data[] = array(get_string("grade", "lesson").":", $grade."%");
+        }
+        echo $OUTPUT->table($table);
 
-                $table->data[] = array(get_string('name').':', $OUTPUT->user_picture(moodle_user_picture::make($user, $course->id)).fullname($user, true));
-                $table->data[] = array(get_string("timetaken", "lesson").":", format_time($timetotake));
-                $table->data[] = array(get_string("completed", "lesson").":", userdate($completed));
-                $table->data[] = array(get_string('rawgrade', 'lesson').':', $gradeinfo->earned.'/'.$gradeinfo->total);
-                $table->data[] = array(get_string("grade", "lesson").":", $grade."%");
-            }
-            echo $OUTPUT->table($table);
+        // Don't want this class for later tables
+        $table->set_classes(array());
+    }
 
-            // Don't want this class for later tables
-            $table->set_classes();
-            echo "<br />";
-        }
 
+    $table->align = array("left", "left");
+    $table->size = array("70%", "*");
+    $table->set_classes(array('compacttable', 'generaltable'));
 
-        $table->align = array("left", "left");
-        $table->size = array("70%", "*");
-
-        foreach ($answerpages as $page) {
-            unset($table->data);
-            if ($page->grayout) { // set the color of text
-                $fontstart = "<span class=\"dimmed\">";
-                $fontend = "</font>";
-                $fontstart2 = $fontstart;
-                $fontend2 = $fontend;
-            } else {
-                $fontstart = "";
-                $fontend = "";
-                $fontstart2 = "";
-                $fontend2 = "";
-            }
+    foreach ($answerpages as $page) {
+        unset($table->data);
+        if ($page->grayout) { // set the color of text
+            $fontstart = "<span class=\"dimmed\">";
+            $fontend = "</font>";
+            $fontstart2 = $fontstart;
+            $fontend2 = $fontend;
+        } else {
+            $fontstart = "";
+            $fontend = "";
+            $fontstart2 = "";
+            $fontend2 = "";
+        }
 
-            $table->head = array($fontstart2.$page->qtype.": ".format_string($page->title).$fontend2, $fontstart2.get_string("classstats", "lesson").$fontend2);
-            $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " ");
-            $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend);
-            // apply the font to each answer
+        $table->head = array($fontstart2.$page->qtype.": ".format_string($page->title).$fontend2, $fontstart2.get_string("classstats", "lesson").$fontend2);
+        $table->data[] = array($fontstart.get_string("question", "lesson").": <br />".$fontend.$fontstart2.$page->contents.$fontend2, " ");
+        $table->data[] = array($fontstart.get_string("answer", "lesson").":".$fontend, ' ');
+        // apply the font to each answer
+        if (!empty($page->answerdata) && isset($page->answerdata->response)) {
             foreach ($page->answerdata->answers as $answer){
                 $modified = array();
                 foreach ($answer as $single) {
                 $table->data[] = array($fontstart.get_string("response", "lesson").": <br />".$fontend.$fontstart2.format_text($page->answerdata->response,FORMAT_MOODLE,$formattextdefoptions).$fontend2, " ");
             }
             $table->data[] = array($page->answerdata->score, " ");
-            echo $OUTPUT->table($table);
-            echo "<br />";
+        } else {
+            $table->data[] = array(0, " ");
         }
+        echo $OUTPUT->table($table);
     }
-
-    else {
-        print_error('unknowaction');
-    }
+} else {
+    print_error('unknowaction');
+}
 
 /// Finish the page
-    echo $OUTPUT->footer();
-
-
+echo $OUTPUT->footer();
index 505bd58f5a1d58184042014f74f58ef0674cb90f..4ae9cef2aaf3dd3011a9a532c339f849a5e8bfae 100644 (file)
@@ -1,32 +1,49 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * This php script contains all the stuff to restore lesson mods
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
     //This is the "graphical" structure of the lesson mod:
     //
-    //          lesson_default                  lesson ----------------------------|--------------------------|--------------------------|
-    //     (UL, pk->id,fk->courseid)         (CL,pk->id)                           |                          |                          |
-    //                                             |                               |                          |                          |
-    //                                             |                         lesson_grades              lesson_high_scores         lesson_timer
-    //                                             |                  (UL, pk->id,fk->lessonid)    (UL, pk->id,fk->lessonid)   (UL, pk->id,fk->lessonid)
-    //                                             |
-    //                                             |
-    //                                      lesson_pages---------------------------|
-    //                                  (CL,pk->id,fk->lessonid)                   |
-    //                                             |                               |
-    //                                             |                         lesson_branch
-    //                                             |                   (UL, pk->id,fk->pageid)
-    //                                       lesson_answers
-    //                                    (CL,pk->id,fk->pageid)
-    //                                             |
-    //                                             |
-    //                                             |
-    //                                       lesson_attempts
-    //                                  (UL,pk->id,fk->answerid)
+    //           lesson ----------------------------|--------------------------|--------------------------|
+    //        (CL,pk->id)                           |                          |                          |
+    //              |                               |                          |                          |
+    //              |                         lesson_grades              lesson_high_scores         lesson_timer
+    //              |                  (UL, pk->id,fk->lessonid)    (UL, pk->id,fk->lessonid)   (UL, pk->id,fk->lessonid)
+    //              |
+    //              |
+    //       lesson_pages---------------------------|
+    //   (CL,pk->id,fk->lessonid)                   |
+    //              |                               |
+    //              |                         lesson_branch
+    //              |                   (UL, pk->id,fk->pageid)
+    //        lesson_answers
+    //     (CL,pk->id,fk->pageid)
+    //              |
+    //              |
+    //              |
+    //        lesson_attempts
+    //   (UL,pk->id,fk->answerid)
     //
     // Meaning: pk->primary key field of the table
     //          fk->foreign key to link with parent
                             return false;
                         }
                     }
-                    // restore the default for the course.  Only do this once by checking for an id for lesson_default
-                    $lessondefault = backup_getid($restore->backup_unique_code,'lesson_default',$restore->course_id);
-                    if (!$lessondefault) {
-                        $status = lesson_default_restore_mods($info,$restore);
-                    }
-
                 }
             } else {
                 $status = false;
         return $status;
     }
 
-    //This function restores the lesson_default
-    function lesson_default_restore_mods($info, $restore) {
-        global $CFG, $DB;
-
-        $status = true;
-
-        //Get the default array (optional)
-        if (isset($info['MOD']['#']['DEFAULTS'])) {
-            $defaults = $info['MOD']['#']['DEFAULTS'];
-
-            //Iterate over defaults (should only be 1!)
-            for($i = 0; $i < sizeof($defaults); $i++) {
-                $default_info = $defaults[$i];
-                //traverse_xmlize($default_info);                       //Debug
-                //print_object ($GLOBALS['traverse_array']);            //Debug
-                //$GLOBALS['traverse_array']="";                        //Debug
-
-                //Now, build the lesson_default record structure
-                $default->course = $restore->course_id;
-                $default->practice = backup_todb($default_info['#']['PRACTICE']['0']['#']);
-                $default->modattempts = backup_todb($default_info['#']['MODATTEMPTS']['0']['#']);
-                $default->usepassword = backup_todb($default_info['#']['USEPASSWORD']['0']['#']);
-                $default->password = backup_todb($default_info['#']['PASSWORD']['0']['#']);
-                $default->conditions = backup_todb($default_info['#']['CONDITIONS']['0']['#']);
-                $default->grade = backup_todb($default_info['#']['GRADE']['0']['#']);
-                $default->custom = backup_todb($default_info['#']['CUSTOM']['0']['#']);
-                $default->ongoing = backup_todb($default_info['#']['ONGOING']['0']['#']);
-                $default->usemaxgrade = backup_todb($default_info['#']['USEMAXGRADE']['0']['#']);
-                $default->maxanswers = backup_todb($default_info['#']['MAXANSWERS']['0']['#']);
-                $default->maxattempts = backup_todb($default_info['#']['MAXATTEMPTS']['0']['#']);
-                $default->review = backup_todb($default_info['#']['REVIEW']['0']['#']);
-                $default->nextpagedefault = backup_todb($default_info['#']['NEXTPAGEDEFAULT']['0']['#']);
-                $default->feedback = backup_todb($default_info['#']['FEEDBACK']['0']['#']);
-                $default->minquestions = backup_todb($default_info['#']['MINQUESTIONS']['0']['#']);
-                $default->maxpages = backup_todb($default_info['#']['MAXPAGES']['0']['#']);
-                $default->timed = backup_todb($default_info['#']['TIMED']['0']['#']);
-                $default->maxtime = backup_todb($default_info['#']['MAXTIME']['0']['#']);
-                $default->retake = backup_todb($default_info['#']['RETAKE']['0']['#']);
-                $default->mediaheight = backup_todb($default_info['#']['MEDIAHEIGHT']['0']['#']);
-                $default->mediawidth = backup_todb($default_info['#']['MEDIAWIDTH']['0']['#']);
-                $default->mediaclose = backup_todb($default_info['#']['MEDIACLOSE']['0']['#']);
-                $default->slideshow = backup_todb($default_info['#']['SLIDESHOW']['0']['#']);
-                $default->width = backup_todb($default_info['#']['WIDTH']['0']['#']);
-                $default->height = backup_todb($default_info['#']['HEIGHT']['0']['#']);
-                $default->bgcolor = backup_todb($default_info['#']['BGCOLOR']['0']['#']);
-                $default->displayleft = backup_todb($default_info['#']['DISPLAYLEFT']['0']['#']);
-                $default->displayleftif = backup_todb($default_info['#']['DISPLAYLEFTIF']['0']['#']);
-                $default->progressbar = backup_todb($default_info['#']['PROGRESSBAR']['0']['#']);
-                $default->highscores = backup_todb($default_info['#']['HIGHSCORES']['0']['#']);
-                $default->maxhighscores = backup_todb($default_info['#']['MAXHIGHSCORES']['0']['#']);
-
-                //The structure is equal to the db, so insert the lesson_grade
-                $newid = $DB->insert_record ("lesson_default",$default);
-
-                if ($newid) {
-                    backup_putid($restore->backup_unique_code,'lesson_default',
-                                 $restore->course_id, $newid);
-                }
-
-                //Do some output
-                if (($i+1) % 50 == 0) {
-                    if (!defined('RESTORE_SILENTLY')) {
-                        echo ".";
-                        if (($i+1) % 1000 == 0) {
-                            echo "<br/>";
-                        }
-                    }
-                    backup_flush(300);
-                }
-
-                if (!$newid) {
-                    $status = false;
-                }
-            }
-        }
-
-        return $status;
-    }
-
     //Return a content decoded to support interactivities linking. Every module
     //should have its own. They are called automatically from
     //lesson_decode_content_links_caller() function in each module
diff --git a/mod/lesson/settings.php b/mod/lesson/settings.php
new file mode 100644 (file)
index 0000000..04243d1
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Settings used by the lesson module, were moved from mod_edit
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
+ **/
+
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+
+/** Slideshow settings */
+$settings->add(new admin_setting_configtext('lesson_slideshowwidth', get_string('slideshowwidth', 'lesson'),
+        get_string('configslideshowwidth', 'lesson'), 640, PARAM_INT));
+
+$settings->add(new admin_setting_configtext('lesson_slideshowheight', get_string('slideshowheight', 'lesson'),
+        get_string('configslideshowheight', 'lesson'), 480, PARAM_INT));
+
+$settings->add(new admin_setting_configtext('lesson_slideshowbgcolor', get_string('slideshowbgcolor', 'lesson'),
+        get_string('configslideshowbgcolor', 'lesson'), '#FFFFFF', PARAM_TEXT));
+
+/** Media file popup settings */
+$settings->add(new admin_setting_configtext('lesson_mediawidth', get_string('mediawidth', 'lesson'),
+        get_string('configmediawidth', 'lesson'), 640, PARAM_INT));
+
+$settings->add(new admin_setting_configtext('lesson_mediaheight', get_string('mediaheight', 'lesson'),
+        get_string('configmediaheight', 'lesson'), 480, PARAM_INT));
+
+$settings->add(new admin_setting_configcheckbox('lesson_mediaclose', get_string('mediaclose', 'lesson'),
+        get_string('configmediaclose', 'lesson'), false, PARAM_TEXT));
+
+/** Misc lesson settings */
+$settings->add(new admin_setting_configtext('lesson_maxhighscores', get_string('maxhighscores', 'lesson'),
+        get_string('configmaxhighscores','lesson'), 10, PARAM_INT));
+
+/** Default lesson settings */
+$numbers = array();
+for ($i=20; $i>1; $i--) {
+    $numbers[$i] = $i;
+}
+$settings->add(new admin_setting_configselect('lesson_maxanswers', get_string('maximumnumberofanswersbranches','lesson'),
+        get_string('configmaxanswers', 'lesson'), 4, $numbers));
+
+$defaultnextpages = array();
+$defaultnextpages[0] = get_string("normal", "lesson");
+$defaultnextpages[LESSON_UNSEENPAGE] = get_string("showanunseenpage", "lesson");
+$defaultnextpages[LESSON_UNANSWEREDPAGE] = get_string("showanunansweredpage", "lesson");
+$settings->add(new admin_setting_configselect('lesson_defaultnextpage', get_string('actionaftercorrectanswer','lesson'),
+        get_string('configactionaftercorrectanswer', 'lesson'), 0, $defaultnextpages));
index 2d715ee70dd420860d47d1436bb23c1f1535fc3c..b786541147215b2ee0d3cc900a73fcdef46ccfa8 100644 (file)
@@ -1,73 +1,88 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
 * Sets up the tabs used by the lesson pages for teachers.
 *
 * This file was adapted from the mod/quiz/tabs.php
 *
-* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
-* @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
 */
 
 /// This file to be included so we can assume config.php has already been included.
-    global $DB;
-    if (empty($lesson)) {
-        print_error('cannotcallscript');
-    }
-    if (!isset($currenttab)) {
-        $currenttab = '';
-    }
-    if (!isset($cm)) {
-        $cm = get_coursemodule_from_instance('lesson', $lesson->id);
-        $context = get_context_instance(CONTEXT_MODULE, $cm->id);
-    }
-    if (!isset($course)) {
-        $course = $DB->get_record('course', array('id' => $lesson->course));
-    }
+global $DB;
+if (empty($lesson)) {
+    print_error('cannotcallscript');
+}
+if (!isset($currenttab)) {
+    $currenttab = '';
+}
+if (!isset($cm)) {
+    $cm = get_coursemodule_from_instance('lesson', $lesson->id);
+    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+}
+if (!isset($course)) {
+    $course = $DB->get_record('course', array('id' => $lesson->course));
+}
 
-    $tabs = $row = $inactive = $activated = array();
+$tabs = $row = $inactive = $activated = array();
 
 /// user attempt count for reports link hover (completed attempts - much faster)
-    $attemptscount = $DB->count_records('lesson_grades', array('lessonid'=>$lesson->id));
-
-    $row[] = new tabobject('view', "$CFG->wwwroot/mod/lesson/view.php?id=$cm->id", get_string('preview', 'lesson'), get_string('previewlesson', 'lesson', format_string($lesson->name)));
-    $row[] = new tabobject('edit', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id", get_string('edit', 'lesson'), get_string('edit', 'moodle', format_string($lesson->name)));
-    $row[] = new tabobject('reports', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id", get_string('reports', 'lesson'), get_string('viewreports2', 'lesson', $attemptscount));
-    if (has_capability('mod/lesson:edit', $context)) {
-        $row[] = new tabobject('essay', "$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id", get_string('manualgrading', 'lesson'));
-    }
-    if ($lesson->highscores) {
-        $row[] = new tabobject('highscores', "$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id", get_string('highscores', 'lesson'));
-    }
-
-    $tabs[] = $row;
+$attemptscount = $DB->count_records('lesson_grades', array('lessonid'=>$lesson->id));
 
+$row[] = new tabobject('view', "$CFG->wwwroot/mod/lesson/view.php?id=$cm->id", get_string('preview', 'lesson'), get_string('previewlesson', 'lesson', format_string($lesson->name)));
+$row[] = new tabobject('edit', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id", get_string('edit', 'lesson'), get_string('edit', 'moodle', format_string($lesson->name)));
+$row[] = new tabobject('reports', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id", get_string('reports', 'lesson'), get_string('viewreports2', 'lesson', $attemptscount));
+if (has_capability('mod/lesson:edit', $context)) {
+    $row[] = new tabobject('essay', "$CFG->wwwroot/mod/lesson/essay.php?id=$cm->id", get_string('manualgrading', 'lesson'));
+}
+if ($lesson->highscores) {
+    $row[] = new tabobject('highscores', "$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id", get_string('highscores', 'lesson'));
+}
 
-    switch ($currenttab) {
-        case 'reportoverview':
-        case 'reportdetail':
-        /// sub tabs for reports (overview and detail)
-            $inactive[] = 'reports';
-            $activated[] = 'reports';
+$tabs[] = $row;
 
-            $row    = array();
-            $row[]  = new tabobject('reportoverview', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id&amp;action=reportoverview", get_string('overview', 'lesson'));
-            $row[]  = new tabobject('reportdetail', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id&amp;action=reportdetail", get_string('detailedstats', 'lesson'));
-            $tabs[] = $row;
-            break;
-        case 'collapsed':
-        case 'full':
-        case 'single':
-        /// sub tabs for edit view (collapsed and expanded aka full)
-            $inactive[] = 'edit';
-            $activated[] = 'edit';
 
-            $row    = array();
-            $row[]  = new tabobject('collapsed', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id&amp;mode=collapsed", get_string('collapsed', 'lesson'));
-            $row[]  = new tabobject('full', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id&amp;mode=full", get_string('full', 'lesson'));
-            $tabs[] = $row;
-            break;
-    }
+switch ($currenttab) {
+    case 'reportoverview':
+    case 'reportdetail':
+    /// sub tabs for reports (overview and detail)
+        $inactive[] = 'reports';
+        $activated[] = 'reports';
 
-    print_tabs($tabs, $currenttab, $inactive, $activated);
+        $row    = array();
+        $row[]  = new tabobject('reportoverview', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id&amp;action=reportoverview", get_string('overview', 'lesson'));
+        $row[]  = new tabobject('reportdetail', "$CFG->wwwroot/mod/lesson/report.php?id=$cm->id&amp;action=reportdetail", get_string('detailedstats', 'lesson'));
+        $tabs[] = $row;
+        break;
+    case 'collapsed':
+    case 'full':
+    case 'single':
+    /// sub tabs for edit view (collapsed and expanded aka full)
+        $inactive[] = 'edit';
+        $activated[] = 'edit';
 
+        $row    = array();
+        $row[]  = new tabobject('collapsed', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id&amp;mode=collapsed", get_string('collapsed', 'lesson'));
+        $row[]  = new tabobject('full', "$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id&amp;mode=full", get_string('full', 'lesson'));
+        $tabs[] = $row;
+        break;
+}
 
+print_tabs($tabs, $currenttab, $inactive, $activated);
index 79089a15fd399629d792b537b1de03153adaa054..aa8693191649471b6ad2c2b84e0a7c303cd7f58d 100644 (file)
         current = currentDate.getTime();
         current = Math.floor(current/1000);
 
+        var myclock = '<font style="color:'+myfont_color+'; font-family:'+myfont_face+'; font-size:'+myfont_size+'pt;">';
         if (current > starttime + testlength) {
-            myclock = '';
-            myclock += '<font style="color:'+myfont_color+'; font-family:'+myfont_face+'; font-size:'+myfont_size+'pt;">';
             myclock += "Time is up";
-            myclock += '</font>';
             stopclock = 1;
         } else {
             timeleft = starttime + testlength - current;
             if (minutes < 10) {
                 minutes = "0"+minutes;
             }
-            myclock = '';
-            myclock += '<font style="color:'+myfont_color+'; font-family:'+myfont_face+'; font-size:'+myfont_size+'pt;">';
             myclock += hours+":"+minutes+":"+secs;
-            myclock += '</font>';
         }
+        myclock += '</font>';
 
         if (old == "true") {
             document.write(myclock);
index 78d4fb719bd7100e5e644dd50c3afad6012151c8..57a8ec790b317d764e0e733ea0530a2eb88590f0 100644 (file)
@@ -1,13 +1,30 @@
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * Code fragment to define the version of lesson
  * This fragment is called by moodle_needs_upgrading() and /admin/index.php
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
-$module->version  = 2008112601;  // The current module version (Date: YYYYMMDDXX)
+$module->version  = 2009120800;  // The current module version (Date: YYYYMMDDXX)
 $module->requires = 2008072401;  // Requires this Moodle version
 $module->cron     = 0;           // Period for cron to check this module (secs)
 
index c338b70733555e10a2ecf6d91add86631b2a358e..9b0e5f1c951062702728efa790fb6267d7aba47b 100644 (file)
 <?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
  * This page prints a particular instance of lesson
  *
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package lesson
+ * @package   lesson
+ * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
  **/
 
-    require_once(dirname(__FILE__) . '/../../config.php');
-    require_once($CFG->dirroot.'/mod/lesson/locallib.php');
-    require_once($CFG->dirroot.'/mod/lesson/lib.php');
-    require_once($CFG->libdir . '/completionlib.php');
+require_once(dirname(__FILE__) . '/../../config.php');
+require_once($CFG->dirroot.'/mod/lesson/locallib.php');
+require_once($CFG->dirroot.'/mod/lesson/view_form.php');
+require_once($CFG->libdir . '/completionlib.php');
 
-    $id      = required_param('id', PARAM_INT);             // Course Module ID
-    $pageid  = optional_param('pageid', NULL, PARAM_INT);   // Lesson Page ID
-    $edit    = optional_param('edit', -1, PARAM_BOOL);
-    $userpassword = optional_param('userpassword','',PARAM_CLEAN);
+$id      = required_param('id', PARAM_INT);             // Course Module ID
+$pageid  = optional_param('pageid', NULL, PARAM_INT);   // Lesson Page ID
+$edit    = optional_param('edit', -1, PARAM_BOOL);
+$userpassword = optional_param('userpassword','',PARAM_CLEAN);
 
-    list($cm, $course, $lesson) = lesson_get_basics($id);
+try {
+    $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
+    $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+    $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
+} catch (Exception $e) {
+    print_error('invalidcoursemodule');
+}
+require_login($course, false, $cm);
 
-    require_login($course->id, false, $cm);
+$url = new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$id));
+if ($pageid !== null) {
+    $url->param('pageid', $pageid);
+}
+$PAGE->set_url($url);
 
-    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+$canmanage = has_capability('mod/lesson:manage', $context);
+
+$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE);
 
 /// Check these for students only TODO: Find a better method for doing this!
 ///     Check lesson availability
 ///     Check for password
 ///     Check dependencies
 ///     Check for high scores
-    if (!has_capability('mod/lesson:manage', $context)) {
-
-        if (($lesson->available != 0 and time() < $lesson->available) or
-            ($lesson->deadline != 0 and time() > $lesson->deadline)) {  // Deadline restrictions
-            if ($lesson->deadline != 0 and time() > $lesson->deadline) {
-                $message = get_string('lessonclosed', 'lesson', userdate($lesson->deadline));
-            } else {
-                $message = get_string('lessonopen', 'lesson', userdate($lesson->available));
+if (!$canmanage) {
+    if (!$lesson->is_accessible()) {  // Deadline restrictions
+        echo $lessonoutput->header($lesson);
+        if ($lesson->deadline != 0 && time() > $lesson->deadline) {
+            echo $lessonoutput->lesson_inaccessible(get_string('lessonclosed', 'lesson', userdate($lesson->deadline)));
+        } else {
+            echo $lessonoutput->lesson_inaccessible(get_string('lessonopen', 'lesson', userdate($lesson->available)));
+        }
+        echo $lessonoutput->footer();
+        exit();
+    } else if ($lesson->usepassword && empty($USER->lessonloggedin[$lesson->id])) { // Password protected lesson code
+        $correctpass = false;
+        if (!empty($userpassword) && (($lesson->password == md5(trim($userpassword))) || ($lesson->password == trim($userpassword)))) {
+            // with or without md5 for backward compatibility (MDL-11090)
+            $USER->lessonloggedin[$lesson->id] = true;
+            if ($lesson->highscores) {
+                // Logged in - redirect so we go through all of these checks before starting the lesson.
+                redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
             }
-
-            lesson_print_header($cm, $course, $lesson);
-            echo $OUTPUT->box_start('generalbox boxaligncenter');
-            echo '<div style="text-align:center;">';
-            echo '<p>'.$message.'</p>';
-            echo '<div class="lessonbutton standardbutton" style="padding: 5px;"><a href="'.$CFG->wwwroot.'/course/view.php?id='. $course->id .'">'. get_string('returnto', 'lesson', format_string($course->fullname, true)) .'</a></div>';
-            echo '</div>';
-            echo $OUTPUT->box_end();
-            echo $OUTPUT->footer();
+        } else {
+            echo $lessonoutput->header($lesson);
+            echo $lessonoutput->login_prompt($lesson, optional_param('userpassword', 0, PARAM_CLEAN));
+            echo $lessonoutput->footer();
             exit();
+        }
+    } else if ($lesson->dependency) { // check for dependencies
+        if ($dependentlesson = $DB->get_record('lesson', array('id' => $lesson->dependency))) {
+            // lesson exists, so we can proceed
+            $conditions = unserialize($lesson->conditions);
+            // assume false for all
+            $errors = array();
 
-        } else if ($lesson->usepassword and empty($USER->lessonloggedin[$lesson->id])) { // Password protected lesson code
-            $correctpass = false;
-            if (!empty($userpassword)) {
-                // with or without md5 for backward compatibility (MDL-11090)
-                if (($lesson->password == md5(trim($userpassword))) or ($lesson->password == trim($userpassword))) {
-                    $USER->lessonloggedin[$lesson->id] = true;
-                    $correctpass = true;
-                    if ($lesson->highscores) {
-                        // Logged in - redirect so we go through all of these checks before starting the lesson.
-                        redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
+            // check for the timespent condition
+            if ($conditions->timespent) {
+                $timespent = false;
+                if ($attempttimes = $DB->get_records('lesson_timer', array("userid"=>$USER->id, "lessonid"=>$dependentlesson->id))) {
+                    // go through all the times and test to see if any of them satisfy the condition
+                    foreach($attempttimes as $attempttime) {
+                        $duration = $attempttime->lessontime - $attempttime->starttime;
+                        if ($conditions->timespent < $duration/60) {
+                            $timespent = true;
+                        }
                     }
                 }
-            }
-
-            if (!$correctpass) {
-                lesson_print_header($cm, $course, $lesson);
-                echo "<div class=\"password-form\">\n";
-                echo $OUTPUT->box_start('generalbox boxaligncenter');
-                echo '<form id="password" method="post" action="'.$CFG->wwwroot.'/mod/lesson/view.php" autocomplete="off">' . "\n";
-                echo '<fieldset class="invisiblefieldset">';
-                echo '<input type="hidden" name="id" value="'. $cm->id .'" />' . "\n";
-                if (optional_param('userpassword', 0, PARAM_CLEAN)) {
-                    echo $OUTPUT->notification(get_string('loginfail', 'lesson'));
+                if (!$timespent) {
+                    $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent);
                 }
-
-                echo get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name))."<br /><br />\n".
-                     get_string('enterpassword', 'lesson')." <input type=\"password\" name=\"userpassword\" /><br /><br />\n<center>".
-                     '<span class="lessonbutton standardbutton"><a href="'.$CFG->wwwroot.'/course/view.php?id='. $course->id .'">'. get_string('cancel', 'lesson') .'</a></span> ';
-
-                lesson_print_submit_link(get_string('continue', 'lesson'), 'password', 'center', 'standardbutton submitbutton');
-                echo '</fieldset></form>';
-                echo $OUTPUT->box_end();
-                echo "</div>\n";
-                echo $OUTPUT->footer();
-                exit();
             }
 
-        } else if ($lesson->dependency) { // check for dependencies
-            if ($dependentlesson = $DB->get_record('lesson', array('id' => $lesson->dependency))) {
-                // lesson exists, so we can proceed
-                $conditions = unserialize($lesson->conditions);
-                // assume false for all
-                $timespent = false;
-                $completed = false;
+            // check for the gradebetterthan condition
+            if($conditions->gradebetterthan) {
                 $gradebetterthan = false;
-                // check for the timespent condition
-                if ($conditions->timespent) {
-                    $params = array ("userid" => $USER->id, "lessonid" => $dependentlesson->id);
-                    if ($attempttimes = $DB->get_records_select('lesson_timer', "userid = :userid AND lessonid = :lessonid", $params)) {
-                        // go through all the times and test to see if any of them satisfy the condition
-                        foreach($attempttimes as $attempttime) {
-                            $duration = $attempttime->lessontime - $attempttime->starttime;
-                            if ($conditions->timespent < $duration/60) {
-                                $timespent = true;
-                            }
-                        }
-                    }
-                } else {
-                    $timespent = true; // there isn't one set
-                }
-
-                // check for the gradebetterthan condition
-                if($conditions->gradebetterthan) {
-                    $params = array ("userid" => $USER->id, "lessonid" => $dependentlesson->id);
-                    if ($studentgrades = $DB->get_records_select('lesson_grades', "userid = :userid AND lessonid = :lessonid", $params)) {
-                        // go through all the grades and test to see if any of them satisfy the condition
-                        foreach($studentgrades as $studentgrade) {
-                            if ($studentgrade->grade >= $conditions->gradebetterthan) {
-                                $gradebetterthan = true;
-                            }
+                if ($studentgrades = $DB->get_records('lesson_grades', array("userid"=>$USER->id, "lessonid"=>$dependentlesson->id))) {
+                    // go through all the grades and test to see if any of them satisfy the condition
+                    foreach($studentgrades as $studentgrade) {
+                        if ($studentgrade->grade >= $conditions->gradebetterthan) {
+                            $gradebetterthan = true;
                         }
                     }
-                } else {
-                    $gradebetterthan = true; // there isn't one set
-                }
-
-                // check for the completed condition
-                if ($conditions->completed) {
-                    if ($DB->count_records('lesson_grades', array('userid'=>$USER->id, 'lessonid'=>$dependentlesson->id))) {
-                        $completed = true;
-                    }
-                } else {
-                    $completed = true; // not set
-                }
-
-                $errors = array();
-                // collect all of our error statements
-                if (!$timespent) {
-                    $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent);
-                }
-                if (!$completed) {
-                    $errors[] = get_string('completederror', 'lesson');
                 }
                 if (!$gradebetterthan) {
                     $errors[] = get_string('gradebetterthanerror', 'lesson', $conditions->gradebetterthan);
                 }
-                if (!empty($errors)) {  // print out the errors if any
-                    lesson_print_header($cm, $course, $lesson);
-                    echo '<p>';
-                    echo $OUTPUT->box_start('generalbox boxaligncenter');
-                    print_string('completethefollowingconditions', 'lesson', $dependentlesson->name);
-                    echo '<p style="text-align:center;">'.implode('<br />'.get_string('and', 'lesson').'<br />', $errors).'</p>';
-                    echo $OUTPUT->box_end();
-                    echo '</p>';
-                    echo $OUTPUT->footer();
-                    exit();
+            }
+
+            // check for the completed condition
+            if ($conditions->completed) {
+                if (!$DB->count_records('lesson_grades', array('userid'=>$USER->id, 'lessonid'=>$dependentlesson->id))) {
+                    $errors[] = get_string('completederror', 'lesson');
                 }
             }
 
-        } else if ($lesson->highscores and !$lesson->practice and !optional_param('viewed', 0, PARAM_INT) and empty($pageid)) {
-            // Display high scores before starting lesson
-            redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id");
+            if (!empty($errors)) {  // print out the errors if any
+                echo $lessonoutput->header($lesson);
+                echo $lessonoutput->dependancy_errors($dependentlesson, $errors);
+                echo $lessonoutput->footer();
+                exit();
+            }
         }
+    } else if ($lesson->highscores && !$lesson->practice && !optional_param('viewed', 0, PARAM_INT) && empty($pageid)) {
+        // Display high scores before starting lesson
+        redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/highscores.php', array("id"=>$cm->id)));
     }
-
-    // set up some general variables
-    $path = $CFG->wwwroot .'/course';
+}
 
     // this is called if a student leaves during a lesson
-    if($pageid == LESSON_UNSEENBRANCHPAGE) {
-        $pageid = lesson_unseen_question_jump($lesson->id, $USER->id, $pageid);
-    }
-
-    // display individual pages and their sets of answers
-    // if pageid is EOL then the end of the lesson has been reached
-           // for flow, changed to simple echo for flow styles, michaelp, moved lesson name and page title down
-   $attemptflag = false;
-    if (empty($pageid)) {
-        // make sure there are pages to view
-        if (!$DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
-            if (!has_capability('mod/lesson:manage', $context)) {
-                lesson_set_message(get_string('lessonnotready2', 'lesson')); // a nice message to the student
+if ($pageid == LESSON_UNSEENBRANCHPAGE) {
+    $pageid = lesson_unseen_question_jump($lesson, $USER->id, $pageid);
+}
+
+// display individual pages and their sets of answers
+// if pageid is EOL then the end of the lesson has been reached
+// for flow, changed to simple echo for flow styles, michaelp, moved lesson name and page title down
+$attemptflag = false;
+if (empty($pageid)) {
+    // make sure there are pages to view
+    if (!$DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
+        if (!$canmanage) {
+            $lesson->add_message(get_string('lessonnotready2', 'lesson')); // a nice message to the student
+        } else {
+            if (!$DB->count_records('lesson_pages', array('lessonid'=>$lesson->id))) {
+                redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
             } else {
-                if (!$DB->count_records('lesson_pages', array('lessonid'=>$lesson->id))) {
-                    redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
-                } else {
-                    lesson_set_message(get_string('lessonpagelinkingbroken', 'lesson'));  // ok, bad mojo
-                }
+                $lesson->add_message(get_string('lessonpagelinkingbroken', 'lesson'));  // ok, bad mojo
             }
         }
+    }
 
-        add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id);
-
-        // if no pageid given see if the lesson has been started
-        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-        if ($grades = $DB->get_records_select('lesson_grades', 'lessonid = :lessonid AND userid = :userid', $params,
-                    'grade DESC')) {
-            $retries = count($grades);
-        } else {
-            $retries = 0;
-        }
-        if ($retries) {
-            $attemptflag = true;
-        }
-
-        if (isset($USER->modattempts[$lesson->id])) {
-            unset($USER->modattempts[$lesson->id]);  // if no pageid, then student is NOT reviewing
-        }
+    add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id);
 
-        // if there are any questions have been answered correctly in this attempt
-        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $retries);
-        if ($attempts = $DB->get_records_select('lesson_attempts',
-                    "lessonid = :lessonid AND userid = :userid AND retry = :retry AND
-                    correct = 1", $params, 'timeseen DESC')) {
+    // if no pageid given see if the lesson has been started
+    $retries = $DB->count_records('lesson_grades', array("lessonid" => $lesson->id, "userid" => $USER->id));
+    if ($retries > 0) {
+        $attemptflag = true;
+    }
 
-            foreach ($attempts as $attempt) {
-                $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid));
-                // convert the jumpto to a proper page id
-                if ($jumpto == 0) { // unlikely value!
-                    $lastpageseen = $attempt->pageid;
-                } elseif ($jumpto == LESSON_NEXTPAGE) {
-                    if (!$lastpageseen = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $attempt->pageid))) {
-                        // no nextpage go to end of lesson
-                        $lastpageseen = LESSON_EOL;
-                    }
-                } else {
-                    $lastpageseen = $jumpto;
-                }
-                break; // only look at the latest correct attempt
-            }
-        } else {
-            $attempts = NULL;
-        }
+    if (isset($USER->modattempts[$lesson->id])) {
+        unset($USER->modattempts[$lesson->id]);  // if no pageid, then student is NOT reviewing
+    }
 
-        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $retries);
-        if ($branchtables = $DB->get_records_select('lesson_branch',
-                            "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, 'timeseen DESC')) {
-            // in here, user has viewed a branch table
-            $lastbranchtable = current($branchtables);
-            if ($attempts != NULL) {
-                foreach($attempts as $attempt) {
-                    if ($lastbranchtable->timeseen > $attempt->timeseen) {
-                        // branch table was viewed later than the last attempt
-                        $lastpageseen = $lastbranchtable->pageid;
-                    }
-                    break;
+    // if there are any questions have been answered correctly in this attempt
+    $corrrectattempts = $lesson->get_attempts($retries, true);
+    if ($corrrectattempts>0) {
+        foreach ($corrrectattempts as $attempt) {
+            $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid));
+            // convert the jumpto to a proper page id
+            if ($jumpto == 0) { // unlikely value!
+                $lastpageseen = $attempt->pageid;
+            } elseif ($jumpto == LESSON_NEXTPAGE) {
+                if (!$lastpageseen = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $attempt->pageid))) {
+                    // no nextpage go to end of lesson
+                    $lastpageseen = LESSON_EOL;
                 }
             } else {
-                // hasnt answered any questions but has viewed a branch table
-                $lastpageseen = $lastbranchtable->pageid;
+                $lastpageseen = $jumpto;
             }
+            break; // only look at the latest correct attempt
         }
-        //if ($lastpageseen != $firstpageid) {
-        if (isset($lastpageseen) and $DB->count_records('lesson_attempts', array('lessonid'=>$lesson->id, 'userid'=>$USER->id, 'retry'=>$retries)) > 0) {
-            // get the first page
-            if (!$firstpageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id,
-                        'prevpageid' => 0))) {
-                print_error('cannotfindfirstpage', 'lesson');
-            }
-            lesson_print_header($cm, $course, $lesson);
-            if ($lesson->timed) {
-                if ($lesson->retake) {
-                    echo $OUTPUT->box('<p style="text-align:center;">'. get_string('leftduringtimed', 'lesson') .'</p>', 'generalbox boxaligncenter');
-                    echo '<div style="text-align:center;" class="lessonbutton standardbutton">'.
-                              '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
-                                get_string('continue', 'lesson').'</a></div>';
-                } else {
-                    echo $OUTPUT->box_start('generalbox boxaligncenter');
-                    echo '<div style="text-align:center;">';
-                    echo get_string('leftduringtimednoretake', 'lesson');
-                    echo '<br /><br /><div class="lessonbutton standardbutton"><a href="../../course/view.php?id='. $course->id .'">'. get_string('returntocourse', 'lesson') .'</a></div>';
-                    echo '</div>';
-                    echo $OUTPUT->box_end();
-                }
-
-            } else {
-                echo $OUTPUT->box("<p style=\"text-align:center;\">".get_string('youhaveseen','lesson').'</p>',
-                        'generalbox boxaligncenter');
-
-                echo '<div style="text-align:center;">';
-                echo '<span class="lessonbutton standardbutton">'.
-                        '<a href="view.php?id='.$cm->id.'&amp;pageid='.$lastpageseen.'&amp;startlastseen=yes">'.
-                        get_string('yes').'</a></span>&nbsp;&nbsp;&nbsp;';
-                echo '<span class="lessonbutton standardbutton">'.
-                        '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
-                        get_string('no').'</a></div>';
-                echo '</span>';
-            }
-            echo $OUTPUT->footer();
-            exit();
-        }
+    }
 
-        if ($grades) {
-            foreach ($grades as $grade) {
-                $bestgrade = $grade->grade;
+    if ($branchtables = $DB->get_records('lesson_branch', array("lessonid"=>$lesson->id, "userid"=>$USER->id, "retry"=>$retries), 'timeseen DESC')) {
+        // in here, user has viewed a branch table
+        $lastbranchtable = current($branchtables);
+        if (count($corrrectattempts)>0) {
+            foreach($corrrectattempts as $attempt) {
+                if ($lastbranchtable->timeseen > $attempt->timeseen) {
+                    // branch table was viewed later than the last attempt
+                    $lastpageseen = $lastbranchtable->pageid;
+                }
                 break;
             }
-            if (!$lesson->retake) {
-                lesson_print_header($cm, $course, $lesson, 'view');
-                echo $OUTPUT->box_start('generalbox boxaligncenter');
-                echo "<div style=\"text-align:center;\">";
-                echo get_string("noretake", "lesson");
-                echo "<br /><br /><div class=\"lessonbutton standardbutton\"><a href=\"../../course/view.php?id=$course->id\">".get_string('returntocourse', 'lesson').'</a></div>';
-                echo "</div>";
-                echo $OUTPUT->box_end();
-                echo $OUTPUT->footer();
-                exit();
-                  //redirect("../../course/view.php?id=$course->id", get_string("alreadytaken", "lesson"));
-            // allow student to retake course even if they have the maximum grade
-            // } elseif ($bestgrade == 100) {
-              //     redirect("../../course/view.php?id=$course->id", get_string("maximumgradeachieved",
-            //                 "lesson"));
-            }
-        }
-        // start at the first page
-        if (!$pageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
-                print_error('cannotfindfirstpage', 'lesson');
-        }
-        /// This is the code for starting a timed test
-        if(!isset($USER->startlesson[$lesson->id]) && !has_capability('mod/lesson:manage', $context)) {
-            $USER->startlesson[$lesson->id] = true;
-            $startlesson = new stdClass;
-            $startlesson->lessonid = $lesson->id;
-            $startlesson->userid = $USER->id;
-            $startlesson->starttime = time();
-            $startlesson->lessontime = time();
-
-            $DB->insert_record('lesson_timer', $startlesson);
-            if ($lesson->timed) {
-                lesson_set_message(get_string('maxtimewarning', 'lesson', $lesson->maxtime), 'center');
-            }
+        } else {
+            // hasnt answered any questions but has viewed a branch table
+            $lastpageseen = $lastbranchtable->pageid;
         }
     }
-    if ($pageid != LESSON_EOL) {
-        /// This is the code updates the lessontime for a timed test
-        if ($startlastseen = optional_param('startlastseen', '', PARAM_ALPHA)) {  /// this deletes old records  not totally sure if this is necessary anymore
-            if ($startlastseen == 'no') {
-                $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-                if ($grades = $DB->get_records_select('lesson_grades', "lessonid = :lessonid AND userid = :userid", $params,
-                            'grade DESC')) {
-                    $retries = count($grades);
-                } else {
-                    $retries = 0;
-                }
-                $DB->delete_records('lesson_attempts', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
-                $DB->delete_records('lesson_branch', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
-            }
-        }
-
-        add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
-
-        if (!$page = $DB->get_record('lesson_pages', array('id' => $pageid))) {
-            print_error('cannotfindpages', 'lesson');
-        }
-
-        if ($page->qtype == LESSON_CLUSTER) {  //this only gets called when a user starts up a new lesson and the first page is a cluster page
-            if (!has_capability('mod/lesson:manage', $context)) {
-                // get new id
-                $pageid = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
-                // get new page info
-                if (!$page = $DB->get_record('lesson_pages', array('id' => $pageid))) {
-                    print_error('cannotfindpages', 'lesson');
-                }
-                add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
-            } else {
-                // get the next page
-                $pageid = $page->nextpageid;
-                if (!$page = $DB->get_record('lesson_pages', array('id' => $pageid))) {
-                    print_error('cannotfindpages', 'lesson');
-                }
-            }
-        } elseif ($page->qtype == LESSON_ENDOFCLUSTER) { // Check for endofclusters
-            if ($page->nextpageid == 0) {
-                $nextpageid = LESSON_EOL;
-            } else {
-                $nextpageid = $page->nextpageid;
-            }
-            redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$nextpageid");
-        } else if ($page->qtype == LESSON_ENDOFBRANCH) { // Check for endofbranches
-            if ($answers = $DB->get_records('lesson_answers', array('pageid' => $page->id), 'id')) {
-                // print_heading(get_string('endofbranch', 'lesson'));
-                foreach ($answers as $answer) {
-                    // just need the first answer
-                    if ($answer->jumpto == LESSON_RANDOMBRANCH) {
-                        $answer->jumpto = lesson_unseen_branch_jump($lesson->id, $USER->id);
-                    } elseif ($answer->jumpto == LESSON_CLUSTERJUMP) {
-                        if (!has_capability('mod/lesson:manage', $context)) {
-                            $answer->jumpto = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
-                        } else {
-                            if ($page->nextpageid == 0) {
-                                $answer->jumpto = LESSON_EOL;
-                            } else {
-                                $answer->jumpto = $page->nextpageid;
-                            }
-                        }
-                    } else if ($answer->jumpto == LESSON_NEXTPAGE) {
-                        if ($page->nextpageid == 0) {
-                            $answer->jumpto = LESSON_EOL;
-                        } else {
-                            $answer->jumpto = $page->nextpageid;
-                        }
-                    } else if ($answer->jumpto == 0) {
-                        $answer->jumpto = $page->id;
-                    } else if ($answer->jumpto == LESSON_PREVIOUSPAGE) {
-                        $answer->jumpto = $page->prevpageid;
-                    }
-                    redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$answer->jumpto");
-                    break;
-                }
+    if (isset($lastpageseen) && $DB->count_records('lesson_attempts', array('lessonid'=>$lesson->id, 'userid'=>$USER->id, 'retry'=>$retries)) > 0) {
+        echo $lessonoutput->header($lesson);
+        if ($lesson->timed) {
+            if ($lesson->retake) {
+                $continuelink = html_form::make_button($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$cm->id, 'pageid'=>$lesson->firstpageid, 'startlastseen'=>'no'), get_string('continue', 'lesson'), 'get');
+                echo $lessonoutput->message(get_string('leftduringtimed', 'lesson'), $continuelink);
             } else {
-                print_error('cannotfindanswer', 'lesson');
+                $courselink = html_form::make_button($CFG->wwwroot.'/course/view.php', array('id'=>$PAGE->course->id), get_string('returntocourse', 'lesson'), 'get');
+                echo $lessonoutput->message(get_string('leftduringtimednoretake', 'lesson'), $courselink);
             }
+        } else {
+            echo $lessonoutput->continue_links($lesson, $lastpageseen);
         }
+        echo $lessonoutput->footer();
+        exit();
+    }
 
-        // check to see if the user can see the left menu
-        if (!has_capability('mod/lesson:manage', $context)) {
-            $lesson->displayleft = lesson_displayleftif($lesson);
+    if ($attemptflag) {
+        if (!$lesson->retake) {
+            echo $lessonoutput->header($lesson, 'view');
+            $courselink = html_form::make_button($CFG->wwwroot.'/course/view.php', array('id'=>$PAGE->course->id), get_string('returntocourse', 'lesson'), 'get');
+            echo $lessonoutput->message(get_string("noretake", "lesson"), $courselink);
+            echo $lessonoutput->footer();
+            exit();
         }
+    }
+    // start at the first page
+    if (!$pageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
+            print_error('cannotfindfirstpage', 'lesson');
+    }
+    /// This is the code for starting a timed test
+    if(!isset($USER->startlesson[$lesson->id]) && !$canmanage) {
+        $lesson->start_timer();
+    }
+}
+
+$currenttab = 'view';
+$extraeditbuttons = false;
+$lessonpageid = null;
+$timer = null;
+
+if ($pageid != LESSON_EOL) {
+    /// This is the code updates the lessontime for a timed test
+    $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
+    if ($startlastseen == 'no') {
+        // this deletes old records  not totally sure if this is necessary anymore
+        $retries = $DB->count_records('lesson_grades', array('lessonid'=>$lesson->id, 'userid'=>$USER->id));
+        $DB->delete_records('lesson_attempts', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
+        $DB->delete_records('lesson_branch', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
+    }
 
-        // This is where several messages (usually warnings) are displayed
-        // all of this is displayed above the actual page
-
-        // clock code
-        // get time information for this user
-        $timer = new stdClass;
-        if(!has_capability('mod/lesson:manage', $context)) {
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-            if (!$timer = $DB->get_records_select('lesson_timer', "lessonid = :lessonid AND userid = :userid", $params, 'starttime')) {
-                print_error('cannotfindtimer', 'lesson');
-            } else {
-                $timer = array_pop($timer); // this will get the latest start time record
-            }
-        }
+    $page = $lesson->load_page($pageid);    
+    // Check if the page is of a special type and if so take any nessecary action
+    $newpageid = $page->callback_on_view($canmanage);
+    if (is_numeric($newpageid)) {
+        $page = $lesson->load_page($newpageid);
+    }
 
-        $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
-        if ($startlastseen == 'yes') {  // continue a previous test, need to update the clock  (think this option is disabled atm)
-            $timer->starttime = time() - ($timer->lessontime - $timer->starttime);
-            $timer->lessontime = time();
-        } else if ($startlastseen == 'no') {  // starting over
-            // starting over, so reset the clock
-            $timer->starttime = time();
-            $timer->lessontime = time();
-        }
+    add_to_log($PAGE->course->id, 'lesson', 'view', 'view.php?id='. $PAGE->cm->id, $page->id, $PAGE->cm->id);
 
-        // for timed lessons, display clock
-        if ($lesson->timed) {
-            if(has_capability('mod/lesson:manage', $context)) {
-                lesson_set_message(get_string('teachertimerwarning', 'lesson'));
-            } else {
-                $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
+    // This is where several messages (usually warnings) are displayed
+    // all of this is displayed above the actual page
 
-                if ($timeleft <= 0) {
-                    // Out of time
-                    lesson_set_message(get_string('eolstudentoutoftime', 'lesson'));
-                    redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=".LESSON_EOL."&amp;outoftime=normal");
-                    die; // Shouldn't be reached, but make sure
-                } else if ($timeleft < 60) {
-                    // One minute warning
-                    lesson_set_message(get_string('studentoneminwarning', 'lesson'));
-                }
-            }
-        }
+    // check to see if the user can see the left menu
+    if (!$canmanage) {
+        $lesson->displayleft = lesson_displayleftif($lesson);
 
-        // update the clock
-        if (!has_capability('mod/lesson:manage', $context)) {
-            $timer->lessontime = time();
-            $DB->update_record('lesson_timer', $timer);
-        }
+        $continue = ($startlastseen !== '');
+        $restart  = ($continue && $startlastseen == 'yes');
+        $timer = $lesson->update_timer($continue, $restart);
 
-         ///  This is the warning msg for teachers to inform them that cluster and unseen does not work while logged in as a teacher
-        if(has_capability('mod/lesson:manage', $context)) {
-            if (lesson_display_teacher_warning($lesson->id)) {
-                $warningvars->cluster = get_string('clusterjump', 'lesson');
-                $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
-                lesson_set_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
+        if ($lesson->timed) {
+            $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
+            if ($timeleft <= 0) {
+                // Out of time
+                $lesson->add_message(get_string('eolstudentoutoftime', 'lesson'));
+                redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$cm->id,'pageid'=>LESSON_EOL, 'outoftime'=>'normal')));
+                die; // Shouldn't be reached, but make sure
+            } else if ($timeleft < 60) {
+                // One minute warning
+                $lesson->add_message(get_string('studentoneminwarning', 'lesson'));
             }
         }
 
-        if ($page->qtype == LESSON_BRANCHTABLE) {
-            if ($lesson->minquestions and !has_capability('mod/lesson:manage', $context)) {
-                // tell student how many questions they have seen, how many are required and their grade
-                $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-
-                $gradeinfo = lesson_grade($lesson, $ntries);
-
-                if ($gradeinfo->attempts) {
-                    if ($gradeinfo->nquestions < $lesson->minquestions) {
-                        $a = new stdClass;
-                        $a->nquestions   = $gradeinfo->nquestions;
-                        $a->minquestions = $lesson->minquestions;
-                        lesson_set_message(get_string('numberofpagesviewednotice', 'lesson', $a));
-                    }
-                    lesson_set_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'notify');
+        if ($page->qtype == LESSON_PAGE_BRANCHTABLE && $lesson->minquestions) {
+            // tell student how many questions they have seen, how many are required and their grade
+            $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
+            $gradeinfo = lesson_grade($lesson, $ntries);
+            if ($gradeinfo->attempts) {
+                if ($gradeinfo->nquestions < $lesson->minquestions) {
                     $a = new stdClass;
-                    $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
-                    $a->total = $lesson->grade;
-                    lesson_set_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
+                    $a->nquestions   = $gradeinfo->nquestions;
+                    $a->minquestions = $lesson->minquestions;
+                    $lesson->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
                 }
+                $lesson->add_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'notify');
+                $a = new stdClass;
+                $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
+                $a->total = $lesson->grade;
+                $lesson->add_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
             }
         }
-
-        $PAGE->set_url('mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id));
-        $PAGE->set_subpage($page->id);
-
-        if (($edit != -1) and $PAGE->user_allowed_editing()) {
-            $USER->editing = $edit;
-        }
-
-    /// Print the page header, heading and tabs
-        lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
-        lesson_print_header($cm, $course, $lesson, 'view', 'true', $page->id);
-
-        if ($attemptflag) {
-            echo $OUTPUT->heading(get_string('attempt', 'lesson', $retries + 1));
-        }
-
-        /// This calculates and prints the ongoing score
-        if ($lesson->ongoing and !empty($pageid)) {
-            lesson_print_ongoing_score($lesson);
-        }
-
-        if ($lesson->displayleft) {
-            echo '<a name="maincontent" id="maincontent" title="' . get_string('anchortitle', 'lesson') . '"></a>';
+    } else {
+        $timer = null;
+        if ($lesson->timed) {
+            $lesson->add_message(get_string('teachertimerwarning', 'lesson'));
         }
-
-        if ($lesson->slideshow && $page->qtype == LESSON_BRANCHTABLE) { // Starts the slideshow div
-            echo '<div class="slideshow" style="background-color: ' . $lesson->bgcolor .
-                    '; height: ' . $lesson->height . 'px; width: ' . $lesson->width . 'px;">';
+        if (lesson_display_teacher_warning($lesson)) {
+            // This is the warning msg for teachers to inform them that cluster
+            // and unseen does not work while logged in as a teacher
+            $warningvars->cluster = get_string('clusterjump', 'lesson');
+            $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
+            $lesson->add_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
         }
+    }
 
-        // now starting to print the page's contents
-        if ($page->qtype == LESSON_BRANCHTABLE) {
-            echo $OUTPUT->heading(format_string($page->title));
-        } else {
-            $lesson->slideshow = false; // turn off slide show for all pages other than LESSON_BRANTCHTABLE
-        }
+    $PAGE->set_url('mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id));
+    $PAGE->set_subpage($page->id);
+    $currenttab = 'view';
+    $extraeditbuttons = true;
+    $lessonpageid = $page->id;
 
-        if (!$lesson->slideshow) {
-            $options = new stdClass;
-            $options->noclean = true;
-            echo $OUTPUT->box('<div class="contents">'.
-                            format_text($page->contents, FORMAT_MOODLE, $options).
-                            '</div>', 'generalbox boxaligncenter');
-        }
+    if (($edit != -1) && $PAGE->user_allowed_editing()) {
+        $USER->editing = $edit;
+    }
 
+    if (is_array($page->answers) && count($page->answers)>0) {
         // this is for modattempts option.  Find the users previous answer to this page,
         //   and then display it below in answer processing
         if (isset($USER->modattempts[$lesson->id])) {
             $retries = $DB->count_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-            $retries--;
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "pageid" => $page->id, "retry" => $retries);
-            if (! $attempts = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND pageid = :pageid AND retry = :retry", $params, "timeseen")) {
+            if (!$attempts = $lesson->get_attempts($retries-1, false, $page->id)) {
                 print_error('cannotfindpreattempt', 'lesson');
             }
             $attempt = end($attempts);
+        } else {
+            $attempt = false;
         }
+        $lessoncontent = $lessonoutput->display_page($lesson, $page, $attempt);
+    } else {
 
-        // get the answers in a set order, the id order
-        if ($answers = $DB->get_records("lesson_answers", array("pageid" => $page->id), "id")) {
-            if ($page->qtype != LESSON_BRANCHTABLE) {  // To fix XHTML problem (BT have their own forms)
-                echo "<form id=\"answerform\" method =\"post\" action=\"lesson.php\" autocomplete=\"off\">";
-                echo '<fieldset class="invisiblefieldset">';
-                echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />";
-                echo "<input type=\"hidden\" name=\"action\" value=\"continue\" />";
-                echo "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />";
-                echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
-                echo $OUTPUT->box_start('generalbox boxaligncenter');
-                echo '<table width="100%">';
-            }
-            // default format text options
-            $options = new stdClass;
-            $options->para = false; // no <p></p>
-            $options->noclean = true;
-            // echo "qtype is $page->qtype"; // debug
-            switch ($page->qtype) {
-                case LESSON_SHORTANSWER :
-                case LESSON_NUMERICAL :
-                    if (isset($USER->modattempts[$lesson->id])) {
-                        $value = 'value="'.s($attempt->useranswer).'"';
-                    } else {
-                        $value = "";
-                    }
-                    echo '<tr><td style="text-align:center;"><label for="answer">'.get_string('youranswer', 'lesson').'</label>'.
-                        ": <input type=\"text\" id=\"answer\" name=\"answer\" size=\"50\" maxlength=\"200\" $value />\n";
-                    echo '</td></tr></table>';
-                    echo $OUTPUT->box_end();
-                    lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
-                    break;
-                case LESSON_TRUEFALSE :
-                    shuffle($answers);
-                    $i = 0;
-                    foreach ($answers as $answer) {
-                        echo '<tr><td valign="top">';
-                        if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
-                            $checked = 'checked="checked"';
-                        } else {
-                            $checked = '';
-                        }
-                        echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\" $checked />";
-                        echo "</td><td>";
-                        echo "<label for=\"answerid$i\">".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
-                        echo '</td></tr>';
-                        if ($answer != end($answers)) {
-                            echo "<tr><td><br /></td></tr>";
-                        }
-                        $i++;
-                    }
-                    echo '</table>';
-                    echo $OUTPUT->box_end();
-                    lesson_print_submit_link(get_string('pleasecheckoneanswer', 'lesson'), 'answerform');
-                    break;
-                case LESSON_MULTICHOICE :
-                    $i = 0;
-                    shuffle($answers);
-
-                    foreach ($answers as $answer) {
-                        echo '<tr><td valign="top">';
-                        if ($page->qoption) {
-                            $checked = '';
-                            if (isset($USER->modattempts[$lesson->id])) {
-                                $answerids = explode(",", $attempt->useranswer);
-                                if (in_array($answer->id, $answerids)) {
-                                    $checked = ' checked="checked"';
-                                } else {
-                                    $checked = '';
-                                }
-                            }
-                            // more than one answer allowed
-                            echo "<input type=\"checkbox\" id=\"answerid$i\" name=\"answer[$i]\" value=\"{$answer->id}\"$checked />";
-                        } else {
-                            if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
-                                $checked = ' checked="checked"';
-                            } else {
-                                $checked = '';
-                            }
-                            // only one answer allowed
-                            echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\"$checked />";
-                        }
-                        echo '</td><td>';
-                        echo "<label for=\"answerid$i\" >".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
-                        echo '</td></tr>';
-                        if ($answer != end($answers)) {
-                            echo '<tr><td><br /></td></tr>';
-                        }
-                        $i++;
-                    }
-                    echo '</table>';
-                    echo $OUTPUT->box_end();
-                    if ($page->qoption) {
-                        $linkname = get_string('pleasecheckoneormoreanswers', 'lesson');
-                    } else {
-                        $linkname = get_string('pleasecheckoneanswer', 'lesson');
-                    }
-                    lesson_print_submit_link($linkname, 'answerform');
-                    break;
-
-                case LESSON_MATCHING :
-                    // don't suffle answers (could be an option??)
-                    foreach ($answers as $answer) {
-                        // get all the response
-                        if ($answer->response != NULL) {
-                            $responses[] = trim($answer->response);
-                        }
-                    }
-
-                    $responseoptions = array();
-                    if (!empty($responses)) {
-                        shuffle($responses);
-                        $responses = array_unique($responses);
-                        foreach ($responses as $response) {
-                            $responseoptions[htmlspecialchars(trim($response))] = $response;
-                        }
-                    }
-                    if (isset($USER->modattempts[$lesson->id])) {
-                        $useranswers = explode(',', $attempt->useranswer);
-                        $t = 0;
-                    }
-                    foreach ($answers as $answer) {
-                        if ($answer->response != NULL) {
-                            echo '<tr><td align="right">';
-                            echo "<b><label for=\"menuresponse[$answer->id]\">".
-                                    format_text($answer->answer,FORMAT_MOODLE,$options).
-                                    '</label>: </b></td><td valign="bottom">';
-
-                            if (isset($USER->modattempts[$lesson->id])) {
-                                $selected = htmlspecialchars(trim($answers[$useranswers[$t]]->response));  // gets the user's previous answer
-                                echo $OUTPUT->select(html_select::make ($responseoptions, "response[$answer->id]", $selected));
-                                $t++;
-                            } else {
-                                echo $OUTPUT->select(html_select::make ($responseoptions, "response[$answer->id]"));
-                            }
-                            echo '</td></tr>';
-                            if ($answer != end($answers)) {
-                                echo '<tr><td><br /></td></tr>';
-                            }
-                        }
-                    }
-                    echo '</table>';
-                    echo $OUTPUT->box_end();
-                    lesson_print_submit_link(get_string('pleasematchtheabovepairs', 'lesson'), 'answerform');
-                    break;
-                case LESSON_BRANCHTABLE :
-                    $options = new stdClass;
-                    $options->para = false;
-                    $buttons = array();
-                    $i = 0;
-                    foreach ($answers as $answer) {
-                        // Each button must have its own form inorder for it to work with JavaScript turned off
-                        $button  = "<form id=\"answerform$i\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/lesson.php\">\n".
-                                   '<div>'.
-                                   "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n".
-                                   "<input type=\"hidden\" name=\"action\" value=\"continue\" />\n".
-                                   "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />\n".
-                                   "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n".
-                                   "<input type=\"hidden\" name=\"jumpto\" value=\"$answer->jumpto\" />\n".
-                                   lesson_print_submit_link(strip_tags(format_text($answer->answer, FORMAT_MOODLE, $options)), "answerform$i", '', '', '', '', true).
-                                   '</div>'.
-                                   '</form>';
-
-                        $buttons[] = $button;
-                        $i++;
-                    }
+        $nextpage = $lesson->get_next_page($page->nextpageid);
 
-                /// Set the orientation
-                    if ($page->layout) {
-                        $orientation = 'horizontal';
-                    } else {
-                        $orientation = 'vertical';
-                    }
+        $data = new stdClass;
+        $data->id = $PAGE->cm->id;
+        $data->newpageid = $nextpage->id;
 
-                    $fullbuttonhtml = "\n<div class=\"branchbuttoncontainer $orientation\">\n" .
-                                      implode("\n", $buttons).
-                                      "\n</div>\n";
-
-                    if ($lesson->slideshow) {
-                        $options = new stdClass;
-                        $options->noclean = true;
-                        echo '<div class="contents">'.format_text($page->contents, FORMAT_MOODLE, $options)."</div>\n";
-                        echo '</div><!--end slideshow div-->';
-                        echo $fullbuttonhtml;
-                    } else {
-                        echo $fullbuttonhtml;
-                    }
+        $mform = lesson_page_without_answers();
+        $mform->set_data($data);
+        ob_start();
+        $mform->display();
+        $lessoncontent = ob_get_contents();
+        ob_end_clean();
+    }
 
-                    break;
-                case LESSON_ESSAY :
-                    if (isset($USER->modattempts[$lesson->id])) {
-                        $essayinfo = unserialize($attempt->useranswer);
-                        $value = s($essayinfo->answer);
-                    } else {
-                        $value = "";
+    lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
+    echo $lessonoutput->header($lesson, $currenttab, $extraeditbuttons, $lessonpageid);
+    if ($attemptflag) {
+        echo $OUTPUT->heading(get_string('attempt', 'lesson', $retries));
+    }
+    /// This calculates and prints the ongoing score
+    if ($lesson->ongoing && !empty($pageid)) {
+        echo $lessonoutput->ongoing_score($lesson);
+    }
+    if ($lesson->displayleft) {
+        echo '<a name="maincontent" id="maincontent" title="' . get_string('anchortitle', 'lesson') . '"></a>';
+    }
+    echo $lessoncontent;
+    echo $lessonoutput->slideshow_end();
+    echo $lessonoutput->progress_bar($lesson);
+    echo $lessonoutput->footer();
+
+} else {
+
+    $lessoncontent = '';
+    // end of lesson reached work out grade
+    // Used to check to see if the student ran out of time
+    $outoftime = optional_param('outoftime', '', PARAM_ALPHA);
+
+    // Update the clock / get time information for this user
+    add_to_log($course->id, "lesson", "end", "view.php?id=".$PAGE->cm->id, "$lesson->id", $PAGE->cm->id);
+
+    $lessoncontent .= $OUTPUT->heading(get_string("congratulations", "lesson"));
+    $lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
+    $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
+    if (isset($USER->modattempts[$lesson->id])) {
+        $ntries--;  // need to look at the old attempts :)
+    }
+    if (!$canmanage) {
+        $lesson->stop_timer();
+        $gradeinfo = lesson_grade($lesson, $ntries);
+
+        if ($gradeinfo->attempts) {
+            if (!$lesson->custom) {
+                $lessoncontent .= $lessonoutput->paragraph(get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions), 'center');
+                if ($lesson->minquestions) {
+                    if ($gradeinfo->nquestions < $lesson->minquestions) {
+                        // print a warning and set nviewed to minquestions
+                        $lessoncontent .= $lessonoutput->paragraph(get_string("youshouldview", "lesson", $lesson->minquestions), 'center');
                     }
-                    echo '<tr><td style="text-align:center;" valign="top" nowrap="nowrap"><label for="answer">'.get_string("youranswer", "lesson").'</label>:</td><td>'.
-                         '<textarea id="answer" name="answer" rows="15" cols="60">'.$value."</textarea>\n";
-                    echo '</td></tr></table>';
-                    echo $OUTPUT->box_end();
-                    lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
-                    break;
-                default: // close the tags MDL-7861
-                    echo ('</table>');
-                    echo $OUTPUT->box_end();
-                break;
+                }
+                $lessoncontent .= $lessonoutput->paragraph(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'center');
             }
-            if ($page->qtype != LESSON_BRANCHTABLE) {  // To fix XHTML problem (BT have their own forms)
-                echo '</fieldset>';
-                echo "</form>\n";
+            $a = new stdClass;
+            $a->score = $gradeinfo->earned;
+            $a->grade = $gradeinfo->total;
+            if ($gradeinfo->nmanual) {
+                $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
+                $a->essayquestions = $gradeinfo->nmanual;
+                $lessoncontent .= $OUTPUT->box(get_string("displayscorewithessays", "lesson", $a), 'center');
+            } else {
+                $lessoncontent .= $OUTPUT->box(get_string("displayscorewithoutessays", "lesson", $a), 'center');
             }
-        } else {
-            // a page without answers - find the next (logical) page
-            echo "<form id=\"pageform\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/view.php\">\n";
-            echo '<div>';
-            echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
-            if ($lesson->nextpagedefault) {
-                // in Flash Card mode...
-                // ...first get number of retakes
-                $nretakes = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-                // ...then get the page ids (lessonid the 5th param is needed to make $DB->get_records play)
-                $allpages = $DB->get_records("lesson_pages", array("lessonid" => $lesson->id), "id", "id,lessonid");
-                shuffle ($allpages);
-                $found = false;
-                if ($lesson->nextpagedefault == LESSON_UNSEENPAGE) {
-                    foreach ($allpages as $thispage) {
-                        if (!$DB->count_records("lesson_attempts", array("pageid"=>$thispage->id, "userid"=>$USER->id, "retry"=>$nretakes))) {
-                            $found = true;
-                            break;
-                        }
-                    }
-                } elseif ($lesson->nextpagedefault == LESSON_UNANSWEREDPAGE) {
-                    foreach ($allpages as $thispage) {
-                        if (!$DB->count_records("lesson_attempts", array('pageid'=>$thispage->id,
-                                    'userid'=>$USER->id, 'correct'=>1, 'retry'=>$nretakes))) {
-                            $found = true;
-                            break;
-                        }
-                    }
-                }
-                if ($found) {
-                    $newpageid = $thispage->id;
-                    if ($lesson->maxpages) {
-                        // check number of pages viewed (in the lesson)
-                        if ($DB->count_records("lesson_attempts", array("lessonid"=>$lesson->id, "userid"=>$USER->id,
-                                "retry"=>$nretakes)) >= $lesson->maxpages) {
-                            $newpageid = LESSON_EOL;
-                        }
+            $a = new stdClass;
+            $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
+            $a->total = $lesson->grade;
+            $lessoncontent .= $lessonoutput->paragraph(get_string("yourcurrentgradeisoutof", "lesson", $a), 'center');
+
+            $grade->lessonid = $lesson->id;
+            $grade->userid = $USER->id;
+            $grade->grade = $gradeinfo->grade;
+            $grade->completed = time();
+            if (!$lesson->practice) {
+                if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
+                    if (!$grades = $DB->get_records("lesson_grades", array("lessonid" => $lesson->id, "userid" => $USER->id), "completed DESC", '*', 0, 1)) {
+                        print_error('cannotfindgrade', 'lesson');
                     }
+                    $oldgrade = array_shift($grades);
+                    $grade->id = $oldgrade->id;
+                    $DB->update_record("lesson_grades", $grade);
                 } else {
-                    $newpageid = LESSON_EOL;
+                    $newgradeid = $DB->insert_record("lesson_grades", $grade);
                 }
             } else {
-                // in normal lesson mode...
-                if (!$newpageid = $DB->get_field("lesson_pages", "nextpageid", array("id" => $pageid))) {
-                    // this is the last page - flag end of lesson
-                    $newpageid = LESSON_EOL;
-                }
+                $DB->delete_records("lesson_attempts", array("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $ntries));
             }
-            echo "<input type=\"hidden\" name=\"pageid\" value=\"$newpageid\" />\n";
-            lesson_print_submit_link(get_string('continue', 'lesson'), 'pageform');
-            echo '</div>';
-            echo "</form>\n";
-        }
-
-        // Finish of the page
-        lesson_print_progress_bar($lesson, $course);
-
-    } else {
-        // end of lesson reached work out grade
-
-        // Used to check to see if the student ran out of time
-        $outoftime = optional_param('outoftime', '', PARAM_ALPHA);
-
-        // Update the clock / get time information for this user
-        if (!has_capability('mod/lesson:manage', $context)) {
-            unset($USER->startlesson[$lesson->id]);
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-            if (!$timer = $DB->get_records_select('lesson_timer', "lessonid = :lessonid AND userid = :userid", $params, 'starttime')) {
-                print_error('cannotfindtimer', 'lesson');
+        } else {
+            if ($lesson->timed) {
+                if ($outoftime == 'normal') {
+                    $grade = new stdClass;
+                    $grade->lessonid = $lesson->id;
+                    $grade->userid = $USER->id;
+                    $grade->grade = 0;
+                    $grade->completed = time();
+                    if (!$lesson->practice) {
+                        $newgradeid = $DB->insert_record("lesson_grades", $grade);
+                    }
+                    $lessoncontent .= get_string("eolstudentoutoftimenoanswers", "lesson");
+                }
             } else {
-                $timer = array_pop($timer); // this will get the latest start time record
+                $lessoncontent .= get_string("welldone", "lesson");
             }
-            $timer->lessontime = time();
-
-            $DB->update_record("lesson_timer", $timer);
         }
 
-        add_to_log($course->id, "lesson", "end", "view.php?id=$cm->id", "$lesson->id", $cm->id);
+        // update central gradebook
+        lesson_update_grades($lesson, $USER->id);
 
-        lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
-        lesson_print_header($cm, $course, $lesson, 'view');
-        echo $OUTPUT->heading(get_string("congratulations", "lesson"));
-        echo $OUTPUT->box_start('generalbox boxaligncenter');
-        $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
-        if (isset($USER->modattempts[$lesson->id])) {
-            $ntries--;  // need to look at the old attempts :)
-        }
-        if (!has_capability('mod/lesson:manage', $context)) {
+    } else {
+        // display for teacher
+        $lessoncontent .= $lessonoutput->paragraph(get_string("displayofgrade", "lesson"), 'center');
+    }
+    $lessoncontent .= $OUTPUT->box_end(); //End of Lesson button to Continue.
 
-            $gradeinfo = lesson_grade($lesson, $ntries);
+    // after all the grade processing, check to see if "Show Grades" is off for the course
+    // if yes, redirect to the course page
+    if (!$course->showgrades) {
+        redirect(new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id)));
+    }
 
-            if ($gradeinfo->attempts) {
-                if (!$lesson->custom) {
-                    echo "<p style=\"text-align:center;\">".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
-                        "</p>\n";
-                    if ($lesson->minquestions) {
-                        if ($gradeinfo->nquestions < $lesson->minquestions) {
-                            // print a warning and set nviewed to minquestions
-                            echo "<p style=\"text-align:center;\">".get_string("youshouldview", "lesson",
-                                    $lesson->minquestions)."</p>\n";
-                        }
-                    }
-                    echo "<p style=\"text-align:center;\">".get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned).
-                        "</p>\n";
-                }
-                $a = new stdClass;
-                $a->score = $gradeinfo->earned;
-                $a->grade = $gradeinfo->total;
-                if ($gradeinfo->nmanual) {
-                    $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
-                    $a->essayquestions = $gradeinfo->nmanual;
-                    echo "<div style=\"text-align:center;\">".get_string("displayscorewithessays", "lesson", $a)."</div>";
-                } else {
-                    echo "<div style=\"text-align:center;\">".get_string("displayscorewithoutessays", "lesson", $a)."</div>";
+    // high scores code
+    if ($lesson->highscores && !$canmanage && !$lesson->practice) {
+        $lessoncontent .= $OUTPUT->box_start('center');
+        if ($grades = $DB->get_records("lesson_grades", array("lessonid" => $lesson->id), "completed")) {
+            $madeit = false;
+            if ($highscores = $DB->get_records("lesson_high_scores", array("lessonid" => $lesson->id))) {
+                // get all the high scores into an array
+                $topscores = array();
+                $uniquescores = array();
+                foreach ($highscores as $highscore) {
+                    $grade = $grades[$highscore->gradeid]->grade;
+                    $topscores[] = $grade;
+                    $uniquescores[$grade] = 1;
                 }
-                $a = new stdClass;
-                $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
-                $a->total = $lesson->grade;
-                echo "<p style=\"text-align:center;\">".get_string('yourcurrentgradeisoutof', 'lesson', $a)."</p>\n";
+                // sort to find the lowest score
+                sort($topscores);
+                $lowscore = $topscores[0];
 
-                $grade->lessonid = $lesson->id;
-                $grade->userid = $USER->id;
-                $grade->grade = $gradeinfo->grade;
-                $grade->completed = time();
-                if (!$lesson->practice) {
-                    if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
-                        $params = array ("lessonid" => $lesson->id, "userid" => $USER->id);
-                        if (!$grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid and userid = :userid", $params, "completed")) {
-                            print_error('cannotfindgrade', 'lesson');
-                        }
-                        $oldgrade = end($grades);
-                        $grade->id = $oldgrade->id;
-                        $DB->update_record("lesson_grades", $grade);
-                    } else {
-                        $newgradeid = $DB->insert_record("lesson_grades", $grade);
-                    }
-                } else {
-                    $DB->delete_records("lesson_attempts", array("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $ntries));
+                if ($gradeinfo->grade >= $lowscore || count($uniquescores) <= $lesson->maxhighscores) {
+                    $madeit = true;
                 }
+            }
+            if (!$highscores or $madeit) {
+                $lessoncontent .= $lessonoutput->paragraph(get_string("youmadehighscore", "lesson", $lesson->maxhighscores), 'center');
+                $params = array('id'=>$PAGE->cm->id, 'sesskey'=>sesskey());
+                $highscoresbutton = html_form::make_button($CFG->wwwroot.'/mod/lesson/highscores.php', $params, get_string('clicktopost', 'lesson'));
+                $lessoncontent .= $OUTPUT->button($highscoresbutton);
             } else {
-                if ($lesson->timed) {
-                    if ($outoftime == 'normal') {
-                        $grade = new stdClass;
-                        $grade->lessonid = $lesson->id;
-                        $grade->userid = $USER->id;
-                        $grade->grade = 0;
-                        $grade->completed = time();
-                        if (!$lesson->practice) {
-                            $newgradeid = $DB->insert_record("lesson_grades", $grade);
-                        }
-                        echo get_string("eolstudentoutoftimenoanswers", "lesson");
-                    }
-                } else {
-                    echo get_string("welldone", "lesson");
-                }
+                $lessoncontent .= get_string("nothighscore", "lesson", $lesson->maxhighscores)."<br />";
             }
-
-            // update central gradebook
-            lesson_update_grades($lesson, $USER->id);
-
-        } else {
-            // display for teacher
-            echo "<p style=\"text-align:center;\">".get_string("displayofgrade", "lesson")."</p>\n";
         }
-        echo $OUTPUT->box_end(); //End of Lesson button to Continue.
-
-        // after all the grade processing, check to see if "Show Grades" is off for the course
-        // if yes, redirect to the course page
-        if (!$course->showgrades) {
-            redirect($CFG->wwwroot.'/course/view.php?id='.$course->id);
-        }
-
-        // high scores code
-        if ($lesson->highscores && !has_capability('mod/lesson:manage', $context) && !$lesson->practice) {
-            echo "<div style=\"text-align:center;\"><br />";
-            $params = array ("lessonid" => $lesson->id);
-            if ($grades = $DB->get_records_select("lesson_grades", "lessonid = :lessonid", $params, "completed")) {
-                $madeit = false;
-                if ($highscores = $DB->get_records_select("lesson_high_scores", "lessonid = :lessonid", $params)) {
-                    // get all the high scores into an array
-                    $topscores = array();
-                    $uniquescores = array();
-                    foreach ($highscores as $highscore) {
-                        $grade = $grades[$highscore->gradeid]->grade;
-                        $topscores[] = $grade;
-                        $uniquescores[$grade] = 1;
-                    }
-                    // sort to find the lowest score
-                    sort($topscores);
-                    $lowscore = $topscores[0];
+        $link = html_link::make(new moodle_url($CFG->wwwroot.'/mod/lesson/highscores.php', array('id'=>$PAGE->cm->id, 'link'=>'1')), get_string('viewhighscores', 'lesson'));
+        $link->set_classes(array('centerpadded','lessonbutton','standardbutton'));
+        $lessoncontent .= $OUTPUT->link($link);
+        $lessoncontent .= $OUTPUT->box_end();
+    }
 
-                    if ($gradeinfo->grade >= $lowscore || count($uniquescores) <= $lesson->maxhighscores) {
-                        $madeit = true;
-                    }
-                }
-                if (!$highscores or $madeit) {
-                    echo '<p>'.get_string("youmadehighscore", "lesson", $lesson->maxhighscores).
-                         '</p>
-                          <form method="post" id="highscores" action="'.$CFG->wwwroot.'/mod/lesson/highscores.php">
-                          <div>
-                          <input type="hidden" name="mode" value="add" />
-                          <input type="hidden" name="id" value="'.$cm->id.'" />
-                          <input type="hidden" name="sesskey" value="'.sesskey().'" />
-                          <p>';
-                          lesson_print_submit_link(get_string('clicktopost', 'lesson'), 'highscores');
-                    echo '</p>
-                          </div>
-                          </form>';
-                } else {
-                    echo get_string("nothighscore", "lesson", $lesson->maxhighscores)."<br />";
-                }
-            }
-            echo "<br /><div style=\"padding: 5px;\" class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id&amp;link=1\">".get_string("viewhighscores", "lesson").'</a></div>';
-            echo "</div>";
-        }
+    if ($lesson->modattempts && !$canmanage) {
+        // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
+        // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
+        // to pass to view again.  This is slick cause it wont call the empty($pageid) code
+        // $ntries is decremented above
+        if (!$attempts = $lesson->get_attempts($ntries)) {
+            $attempts = array();
+        }
+        $firstattempt = current($attempts);
+        $pageid = $firstattempt->pageid;
+        // IF the student wishes to review, need to know the last question page that the student answered.  This will help to make
+        // sure that the student can leave the lesson via pushing the continue button.
+        $lastattempt = end($attempts);
+        $USER->modattempts[$lesson->id] = $lastattempt->pageid;
+
+        $link = html_link::make(new moodle_url($CFG->wwwroot.'/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$pageid)), get_string('reviewlesson', 'lesson'));
+        $link->set_classes(array('centerpadded','lessonbutton','standardbutton'));
+        $lessoncontent .= $OUTPUT->link($link);
+
+    } elseif ($lesson->modattempts && $canmanage) {
+        $lessoncontent .= $lessonoutput->paragraph(get_string("modattemptsnoteacher", "lesson"), 'centerpadded');
+    }
 
-        if ($lesson->modattempts && !has_capability('mod/lesson:manage', $context)) {
-            // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
-            // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
-            // to pass to view again.  This is slick cause it wont call the empty($pageid) code
-            // $ntries is decremented above
-            $params = array ("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $ntries);
-            if (!$attempts = $DB->get_records_select("lesson_attempts", "lessonid = :lessonid AND userid = :userid AND retry = :retry", $params, "timeseen")) {
-                $attempts = array();
-            }
-            $firstattempt = current($attempts);
-            $pageid = $firstattempt->pageid;
-            // IF the student wishes to review, need to know the last question page that the student answered.  This will help to make
-            // sure that the student can leave the lesson via pushing the continue button.
-            $lastattempt = end($attempts);
-            $USER->modattempts[$lesson->id] = $lastattempt->pageid;
-            echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\"><a href=\"view.php?id=$cm->id&amp;pageid=$pageid\">".get_string("reviewlesson", "lesson")."</a></div>\n";
-        } elseif ($lesson->modattempts && has_capability('mod/lesson:manage', $context)) {
-            echo "<p style=\"text-align:center;\">".get_string("modattemptsnoteacher", "lesson")."</p>";
+    if ($lesson->activitylink) {
+        $link = $lesson->link_for_activitylink();
+        if ($link instanceof html_link) {
+            $lessoncontent .= $OUTPUT->link($link);
         }
+    }
 
-        if ($lesson->activitylink) {
-            if ($module = $DB->get_record('course_modules', array('id' => $lesson->activitylink))) {
-                if ($modname = $DB->get_field('modules', 'name', array('id' => $module->module)))
-                    if ($instance = $DB->get_record($modname, array('id' => $module->instance))) {
-                        echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\">".
-                                "<a href=\"$CFG->wwwroot/mod/$modname/view.php?id=$lesson->activitylink\">".
-                                get_string('activitylinkname', 'lesson', $instance->name)."</a></div>\n";
-                    }
-            }
-        }
+    $link = html_link::make(new moodle_url($CFG->wwwroot.'/course/view.php', array('id'=>$course->id)), get_string('returnto', 'lesson', format_string($course->fullname, true)));
+    $link->set_classes(array('centerpadded','lessonbutton','standardbutton'));
+    $lessoncontent .= $OUTPUT->link($link);
 
-        echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">".get_string('returnto', 'lesson', format_string($course->fullname, true))."</a></div>\n";
-        echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\"><a href=\"$CFG->wwwroot/grade/index.php?id=$course->id\">".get_string('viewgrades', 'lesson')."</a></div>\n";
-    }
+    $link = html_link::make(new moodle_url($CFG->wwwroot.'/grade/index.php', array('id'=>$course->id)), get_string('viewgrades', 'lesson'));
+    $link->set_classes(array('centerpadded','lessonbutton','standardbutton'));
+    $lessoncontent .= $OUTPUT->link($link);
 
-/// Finish the page
-    echo $OUTPUT->footer();
+    lesson_add_pretend_blocks($PAGE, $cm, $lesson, $timer);
+    echo $lessonoutput->header($lesson, $currenttab, $extraeditbuttons, $lessonpageid);
+    echo $lessoncontent;
+    echo $lessonoutput->footer();
+}
 
 /// Mark as viewed
-    $completion=new completion_info($course);
-    $completion->set_module_viewed($cm);
-
+$completion=new completion_info($course);
+$completion->set_module_viewed($cm);
diff --git a/mod/lesson/view_form.php b/mod/lesson/view_form.php
new file mode 100644 (file)
index 0000000..510a282
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Lesson page without answers
+ *
+ * @package   lesson
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+
+/**
+ * Include formslib if it has not already been included
+ */
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Lesson page without answers
+ *
+ * @copyright 2009 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ **/
+class lesson_page_without_answers extends moodleform {
+
+    public function definition() {
+
+        $mform = $this->_form;
+
+        $mform->addElement('hidden', 'id');
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'pageid');
+        $mform->setType('pageid', PARAM_INT);
+
+        $this->add_action_buttons(null, get_string("continue", "lesson"));
+
+    }
+
+}
\ No newline at end of file