blocklib MDL-25654 fix API inconsistency be renaming add_pretend_block to add_fake_block.
[moodle.git] / mod / lesson / view.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * This page prints a particular instance of lesson
20  *
21  * @package    mod
22  * @subpackage lesson
23  * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
25  **/
27 require_once(dirname(__FILE__) . '/../../config.php');
28 require_once($CFG->dirroot.'/mod/lesson/locallib.php');
29 require_once($CFG->dirroot.'/mod/lesson/view_form.php');
30 require_once($CFG->libdir . '/completionlib.php');
32 $id      = required_param('id', PARAM_INT);             // Course Module ID
33 $pageid  = optional_param('pageid', NULL, PARAM_INT);   // Lesson Page ID
34 $edit    = optional_param('edit', -1, PARAM_BOOL);
35 $userpassword = optional_param('userpassword','',PARAM_RAW);
36 $backtocourse = optional_param('backtocourse', false, PARAM_RAW);
38 $cm = get_coursemodule_from_id('lesson', $id, 0, false, MUST_EXIST);;
39 $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
40 $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
42 require_login($course, false, $cm);
44 if ($backtocourse) {
45     redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
46 }
48 $url = new moodle_url('/mod/lesson/view.php', array('id'=>$id));
49 if ($pageid !== null) {
50     $url->param('pageid', $pageid);
51 }
52 $PAGE->set_url($url);
54 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
55 $canmanage = has_capability('mod/lesson:manage', $context);
57 $lessonoutput = $PAGE->get_renderer('mod_lesson');
59 /// Check these for students only TODO: Find a better method for doing this!
60 ///     Check lesson availability
61 ///     Check for password
62 ///     Check dependencies
63 ///     Check for high scores
64 if (!$canmanage) {
65     if (!$lesson->is_accessible()) {  // Deadline restrictions
66         echo $lessonoutput->header($lesson, $cm);
67         if ($lesson->deadline != 0 && time() > $lesson->deadline) {
68             echo $lessonoutput->lesson_inaccessible(get_string('lessonclosed', 'lesson', userdate($lesson->deadline)));
69         } else {
70             echo $lessonoutput->lesson_inaccessible(get_string('lessonopen', 'lesson', userdate($lesson->available)));
71         }
72         echo $lessonoutput->footer();
73         exit();
74     } else if ($lesson->usepassword && empty($USER->lessonloggedin[$lesson->id])) { // Password protected lesson code
75         $correctpass = false;
76         if (!empty($userpassword) && (($lesson->password == md5(trim($userpassword))) || ($lesson->password == trim($userpassword)))) {
77             // with or without md5 for backward compatibility (MDL-11090)
78             $USER->lessonloggedin[$lesson->id] = true;
79             if ($lesson->highscores) {
80                 // Logged in - redirect so we go through all of these checks before starting the lesson.
81                 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
82             }
83         } else {
84             echo $lessonoutput->header($lesson, $cm);
85             echo $lessonoutput->login_prompt($lesson, $userpassword !== '');
86             echo $lessonoutput->footer();
87             exit();
88         }
89     } else if ($lesson->dependency) { // check for dependencies
90         if ($dependentlesson = $DB->get_record('lesson', array('id' => $lesson->dependency))) {
91             // lesson exists, so we can proceed
92             $conditions = unserialize($lesson->conditions);
93             // assume false for all
94             $errors = array();
96             // check for the timespent condition
97             if ($conditions->timespent) {
98                 $timespent = false;
99                 if ($attempttimes = $DB->get_records('lesson_timer', array("userid"=>$USER->id, "lessonid"=>$dependentlesson->id))) {
100                     // go through all the times and test to see if any of them satisfy the condition
101                     foreach($attempttimes as $attempttime) {
102                         $duration = $attempttime->lessontime - $attempttime->starttime;
103                         if ($conditions->timespent < $duration/60) {
104                             $timespent = true;
105                         }
106                     }
107                 }
108                 if (!$timespent) {
109                     $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent);
110                 }
111             }
113             // check for the gradebetterthan condition
114             if($conditions->gradebetterthan) {
115                 $gradebetterthan = false;
116                 if ($studentgrades = $DB->get_records('lesson_grades', array("userid"=>$USER->id, "lessonid"=>$dependentlesson->id))) {
117                     // go through all the grades and test to see if any of them satisfy the condition
118                     foreach($studentgrades as $studentgrade) {
119                         if ($studentgrade->grade >= $conditions->gradebetterthan) {
120                             $gradebetterthan = true;
121                         }
122                     }
123                 }
124                 if (!$gradebetterthan) {
125                     $errors[] = get_string('gradebetterthanerror', 'lesson', $conditions->gradebetterthan);
126                 }
127             }
129             // check for the completed condition
130             if ($conditions->completed) {
131                 if (!$DB->count_records('lesson_grades', array('userid'=>$USER->id, 'lessonid'=>$dependentlesson->id))) {
132                     $errors[] = get_string('completederror', 'lesson');
133                 }
134             }
136             if (!empty($errors)) {  // print out the errors if any
137                 echo $lessonoutput->header($lesson, $cm);
138                 echo $lessonoutput->dependancy_errors($dependentlesson, $errors);
139                 echo $lessonoutput->footer();
140                 exit();
141             }
142         }
143     } else if ($lesson->highscores && !$lesson->practice && !optional_param('viewed', 0, PARAM_INT) && empty($pageid)) {
144         // Display high scores before starting lesson
145         redirect(new moodle_url('/mod/lesson/highscores.php', array("id"=>$cm->id)));
146     }
149     // this is called if a student leaves during a lesson
150 if ($pageid == LESSON_UNSEENBRANCHPAGE) {
151     $pageid = lesson_unseen_question_jump($lesson, $USER->id, $pageid);
154 // display individual pages and their sets of answers
155 // if pageid is EOL then the end of the lesson has been reached
156 // for flow, changed to simple echo for flow styles, michaelp, moved lesson name and page title down
157 $attemptflag = false;
158 if (empty($pageid)) {
159     // make sure there are pages to view
160     if (!$DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
161         if (!$canmanage) {
162             $lesson->add_message(get_string('lessonnotready2', 'lesson')); // a nice message to the student
163         } else {
164             if (!$DB->count_records('lesson_pages', array('lessonid'=>$lesson->id))) {
165                 redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
166             } else {
167                 $lesson->add_message(get_string('lessonpagelinkingbroken', 'lesson'));  // ok, bad mojo
168             }
169         }
170     }
172     add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id);
174     // if no pageid given see if the lesson has been started
175     $retries = $DB->count_records('lesson_grades', array("lessonid" => $lesson->id, "userid" => $USER->id));
176     if ($retries > 0) {
177         $attemptflag = true;
178     }
180     if (isset($USER->modattempts[$lesson->id])) {
181         unset($USER->modattempts[$lesson->id]);  // if no pageid, then student is NOT reviewing
182     }
184     // if there are any questions have been answered correctly in this attempt
185     $corrrectattempts = $lesson->get_attempts($retries, true);
186     if ($corrrectattempts>0) {
187         foreach ($corrrectattempts as $attempt) {
188             $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid));
189             // convert the jumpto to a proper page id
190             if ($jumpto == 0) { // unlikely value!
191                 $lastpageseen = $attempt->pageid;
192             } elseif ($jumpto == LESSON_NEXTPAGE) {
193                 if (!$lastpageseen = $DB->get_field('lesson_pages', 'nextpageid', array('id' => $attempt->pageid))) {
194                     // no nextpage go to end of lesson
195                     $lastpageseen = LESSON_EOL;
196                 }
197             } else {
198                 $lastpageseen = $jumpto;
199             }
200             break; // only look at the latest correct attempt
201         }
202     }
204     if ($branchtables = $DB->get_records('lesson_branch', array("lessonid"=>$lesson->id, "userid"=>$USER->id, "retry"=>$retries), 'timeseen DESC')) {
205         // in here, user has viewed a branch table
206         $lastbranchtable = current($branchtables);
207         if (count($corrrectattempts)>0) {
208             foreach($corrrectattempts as $attempt) {
209                 if ($lastbranchtable->timeseen > $attempt->timeseen) {
210                     // branch table was viewed later than the last attempt
211                     $lastpageseen = $lastbranchtable->pageid;
212                 }
213                 break;
214             }
215         } else {
216             // hasnt answered any questions but has viewed a branch table
217             $lastpageseen = $lastbranchtable->pageid;
218         }
219     }
220     if (isset($lastpageseen) && $DB->count_records('lesson_attempts', array('lessonid'=>$lesson->id, 'userid'=>$USER->id, 'retry'=>$retries)) > 0) {
221         echo $lessonoutput->header($lesson, $cm);
222         if ($lesson->timed) {
223             if ($lesson->retake) {
224                 $continuelink = new single_button(new moodle_url('/mod/lesson/view.php', array('id'=>$cm->id, 'pageid'=>$lesson->firstpageid, 'startlastseen'=>'no')), get_string('continue', 'lesson'), 'get');
225                 echo '<div class="center leftduring">'.$lessonoutput->message(get_string('leftduringtimed', 'lesson'), $continuelink).'</div>';
226             } else {
227                 $courselink = new single_button(new moodle_url('/course/view.php', array('id'=>$PAGE->course->id)), get_string('returntocourse', 'lesson'), 'get');
228                 echo '<div class="center leftduring">'.$lessonoutput->message(get_string('leftduringtimednoretake', 'lesson'), $courselink).'</div>';
229             }
230         } else {
231             echo $lessonoutput->continue_links($lesson, $lastpageseen);
232         }
233         echo $lessonoutput->footer();
234         exit();
235     }
237     if ($attemptflag) {
238         if (!$lesson->retake) {
239             echo $lessonoutput->header($lesson, $cm, 'view');
240             $courselink = new single_button(new moodle_url('/course/view.php', array('id'=>$PAGE->course->id)), get_string('returntocourse', 'lesson'), 'get');
241             echo $lessonoutput->message(get_string("noretake", "lesson"), $courselink);
242             echo $lessonoutput->footer();
243             exit();
244         }
245     }
246     // start at the first page
247     if (!$pageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id, 'prevpageid' => 0))) {
248             print_error('cannotfindfirstpage', 'lesson');
249     }
250     /// This is the code for starting a timed test
251     if(!isset($USER->startlesson[$lesson->id]) && !$canmanage) {
252         $lesson->start_timer();
253     }
256 $currenttab = 'view';
257 $extraeditbuttons = false;
258 $lessonpageid = null;
259 $timer = null;
261 if ($pageid != LESSON_EOL) {
262     /// This is the code updates the lessontime for a timed test
263     $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
264     if ($startlastseen == 'no') {
265         // this deletes old records  not totally sure if this is necessary anymore
266         $retries = $DB->count_records('lesson_grades', array('lessonid'=>$lesson->id, 'userid'=>$USER->id));
267         $DB->delete_records('lesson_attempts', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
268         $DB->delete_records('lesson_branch', array('userid' => $USER->id, 'lessonid' => $lesson->id, 'retry' => $retries));
269     }
271     $page = $lesson->load_page($pageid);
272     // Check if the page is of a special type and if so take any nessecary action
273     $newpageid = $page->callback_on_view($canmanage);
274     if (is_numeric($newpageid)) {
275         $page = $lesson->load_page($newpageid);
276     }
278     add_to_log($PAGE->course->id, 'lesson', 'view', 'view.php?id='. $PAGE->cm->id, $page->id, $PAGE->cm->id);
280     // This is where several messages (usually warnings) are displayed
281     // all of this is displayed above the actual page
283     // check to see if the user can see the left menu
284     if (!$canmanage) {
285         $lesson->displayleft = lesson_displayleftif($lesson);
287         $continue = ($startlastseen !== '');
288         $restart  = ($continue && $startlastseen == 'yes');
289         $timer = $lesson->update_timer($continue, $restart);
291         if ($lesson->timed) {
292             $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
293             if ($timeleft <= 0) {
294                 // Out of time
295                 $lesson->add_message(get_string('eolstudentoutoftime', 'lesson'));
296                 redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$cm->id,'pageid'=>LESSON_EOL, 'outoftime'=>'normal')));
297                 die; // Shouldn't be reached, but make sure
298             } else if ($timeleft < 60) {
299                 // One minute warning
300                 $lesson->add_message(get_string('studentoneminwarning', 'lesson'));
301             }
302         }
304         if ($page->qtype == LESSON_PAGE_BRANCHTABLE && $lesson->minquestions) {
305             // tell student how many questions they have seen, how many are required and their grade
306             $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
307             $gradeinfo = lesson_grade($lesson, $ntries);
308             if ($gradeinfo->attempts) {
309                 if ($gradeinfo->nquestions < $lesson->minquestions) {
310                     $a = new stdClass;
311                     $a->nquestions   = $gradeinfo->nquestions;
312                     $a->minquestions = $lesson->minquestions;
313                     $lesson->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
314                 }
315                 $lesson->add_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'notify');
316                 $a = new stdClass;
317                 $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
318                 $a->total = $lesson->grade;
319                 $lesson->add_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
320             }
321         }
322     } else {
323         $timer = null;
324         if ($lesson->timed) {
325             $lesson->add_message(get_string('teachertimerwarning', 'lesson'));
326         }
327         if (lesson_display_teacher_warning($lesson)) {
328             // This is the warning msg for teachers to inform them that cluster
329             // and unseen does not work while logged in as a teacher
330             $warningvars->cluster = get_string('clusterjump', 'lesson');
331             $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
332             $lesson->add_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
333         }
334     }
336     $PAGE->set_url('/mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id));
337     $PAGE->set_subpage($page->id);
338     $currenttab = 'view';
339     $extraeditbuttons = true;
340     $lessonpageid = $page->id;
342     if (($edit != -1) && $PAGE->user_allowed_editing()) {
343         $USER->editing = $edit;
344     }
346     if (is_array($page->answers) && count($page->answers)>0) {
347         // this is for modattempts option.  Find the users previous answer to this page,
348         //   and then display it below in answer processing
349         if (isset($USER->modattempts[$lesson->id])) {
350             $retries = $DB->count_records('lesson_grades', array("lessonid"=>$lesson->id, "userid"=>$USER->id));
351             if (!$attempts = $lesson->get_attempts($retries-1, false, $page->id)) {
352                 print_error('cannotfindpreattempt', 'lesson');
353             }
354             $attempt = end($attempts);
355         } else {
356             $attempt = false;
357         }
358         $lessoncontent = $lessonoutput->display_page($lesson, $page, $attempt);
359     } else {
360         $data = new stdClass;
361         $data->id = $PAGE->cm->id;
362         if ($nextpage = $lesson->get_next_page($page->nextpageid)) {
363             $data->newpageid = $nextpage->id;
364         }
366         $mform = new lesson_page_without_answers();
367         $mform->set_data($data);
368         ob_start();
369         $mform->display();
370         $lessoncontent = ob_get_contents();
371         ob_end_clean();
372     }
374     lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
375     echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid);
376     if ($attemptflag) {
377         echo $OUTPUT->heading(get_string('attempt', 'lesson', $retries));
378     }
379     /// This calculates and prints the ongoing score
380     if ($lesson->ongoing && !empty($pageid)) {
381         echo $lessonoutput->ongoing_score($lesson);
382     }
383     if ($lesson->displayleft) {
384         echo '<a name="maincontent" id="maincontent" title="' . get_string('anchortitle', 'lesson') . '"></a>';
385     }
386     echo $lessoncontent;
387     echo $lessonoutput->slideshow_end();
388     echo $lessonoutput->progress_bar($lesson);
389     echo $lessonoutput->footer();
391 } else {
393     $lessoncontent = '';
394     // end of lesson reached work out grade
395     // Used to check to see if the student ran out of time
396     $outoftime = optional_param('outoftime', '', PARAM_ALPHA);
398     // Update the clock / get time information for this user
399     add_to_log($course->id, "lesson", "end", "view.php?id=".$PAGE->cm->id, "$lesson->id", $PAGE->cm->id);
401     $lessoncontent .= $OUTPUT->heading(get_string("congratulations", "lesson"));
402     $lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
403     $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id, "userid"=>$USER->id));
404     if (isset($USER->modattempts[$lesson->id])) {
405         $ntries--;  // need to look at the old attempts :)
406     }
407     if (!$canmanage) {
408         $lesson->stop_timer();
409         $gradeinfo = lesson_grade($lesson, $ntries);
411         if ($gradeinfo->attempts) {
412             if (!$lesson->custom) {
413                 $lessoncontent .= $lessonoutput->paragraph(get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions), 'center');
414                 if ($lesson->minquestions) {
415                     if ($gradeinfo->nquestions < $lesson->minquestions) {
416                         // print a warning and set nviewed to minquestions
417                         $lessoncontent .= $lessonoutput->paragraph(get_string("youshouldview", "lesson", $lesson->minquestions), 'center');
418                     }
419                 }
420                 $lessoncontent .= $lessonoutput->paragraph(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'center');
421             }
422             $a = new stdClass;
423             $a->score = $gradeinfo->earned;
424             $a->grade = $gradeinfo->total;
425             if ($gradeinfo->nmanual) {
426                 $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
427                 $a->essayquestions = $gradeinfo->nmanual;
428                 $lessoncontent .= $OUTPUT->box(get_string("displayscorewithessays", "lesson", $a), 'center');
429             } else {
430                 $lessoncontent .= $OUTPUT->box(get_string("displayscorewithoutessays", "lesson", $a), 'center');
431             }
432             $a = new stdClass;
433             $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
434             $a->total = $lesson->grade;
435             $lessoncontent .= $lessonoutput->paragraph(get_string("yourcurrentgradeisoutof", "lesson", $a), 'center');
437             $grade = new stdClass();
438             $grade->lessonid = $lesson->id;
439             $grade->userid = $USER->id;
440             $grade->grade = $gradeinfo->grade;
441             $grade->completed = time();
442             if (!$lesson->practice) {
443                 if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
444                     if (!$grades = $DB->get_records("lesson_grades", array("lessonid" => $lesson->id, "userid" => $USER->id), "completed DESC", '*', 0, 1)) {
445                         print_error('cannotfindgrade', 'lesson');
446                     }
447                     $oldgrade = array_shift($grades);
448                     $grade->id = $oldgrade->id;
449                     $DB->update_record("lesson_grades", $grade);
450                 } else {
451                     $newgradeid = $DB->insert_record("lesson_grades", $grade);
452                 }
453             } else {
454                 $DB->delete_records("lesson_attempts", array("lessonid" => $lesson->id, "userid" => $USER->id, "retry" => $ntries));
455             }
456         } else {
457             if ($lesson->timed) {
458                 if ($outoftime == 'normal') {
459                     $grade = new stdClass();;
460                     $grade->lessonid = $lesson->id;
461                     $grade->userid = $USER->id;
462                     $grade->grade = 0;
463                     $grade->completed = time();
464                     if (!$lesson->practice) {
465                         $newgradeid = $DB->insert_record("lesson_grades", $grade);
466                     }
467                     $lessoncontent .= get_string("eolstudentoutoftimenoanswers", "lesson");
468                 }
469             } else {
470                 $lessoncontent .= get_string("welldone", "lesson");
471             }
472         }
474         // update central gradebook
475         lesson_update_grades($lesson, $USER->id);
477     } else {
478         // display for teacher
479         $lessoncontent .= $lessonoutput->paragraph(get_string("displayofgrade", "lesson"), 'center');
480     }
481     $lessoncontent .= $OUTPUT->box_end(); //End of Lesson button to Continue.
483     // after all the grade processing, check to see if "Show Grades" is off for the course
484     // if yes, redirect to the course page
485     if (!$course->showgrades) {
486         redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
487     }
489     // high scores code
490     if ($lesson->highscores && !$canmanage && !$lesson->practice) {
491         $lessoncontent .= $OUTPUT->box_start('center');
492         if ($grades = $DB->get_records("lesson_grades", array("lessonid" => $lesson->id), "completed")) {
493             $madeit = false;
494             if ($highscores = $DB->get_records("lesson_high_scores", array("lessonid" => $lesson->id))) {
495                 // get all the high scores into an array
496                 $topscores = array();
497                 $uniquescores = array();
498                 foreach ($highscores as $highscore) {
499                     $grade = $grades[$highscore->gradeid]->grade;
500                     $topscores[] = $grade;
501                     $uniquescores[$grade] = 1;
502                 }
503                 // sort to find the lowest score
504                 sort($topscores);
505                 $lowscore = $topscores[0];
507                 if ($gradeinfo->grade >= $lowscore || count($uniquescores) <= $lesson->maxhighscores) {
508                     $madeit = true;
509                 }
510             }
511             if (!$highscores or $madeit) {
512                 $lessoncontent .= $lessonoutput->paragraph(get_string("youmadehighscore", "lesson", $lesson->maxhighscores), 'center');
513                 $aurl = new moodle_url('/mod/lesson/highscores.php', array('id'=>$PAGE->cm->id, 'sesskey'=>sesskey()));
514                 $lessoncontent .= $OUTPUT->single_button($aurl, get_string('clicktopost', 'lesson'));
515             } else {
516                 $lessoncontent .= get_string("nothighscore", "lesson", $lesson->maxhighscores)."<br />";
517             }
518         }
519         $url = new moodle_url('/mod/lesson/highscores.php', array('id'=>$PAGE->cm->id, 'link'=>'1'));
520         $lessoncontent .= html_writer::link($url, get_string('viewhighscores', 'lesson'), array('class'=>'centerpadded lessonbutton standardbutton'));
521         $lessoncontent .= $OUTPUT->box_end();
522     }
524     if ($lesson->modattempts && !$canmanage) {
525         // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
526         // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
527         // to pass to view again.  This is slick cause it wont call the empty($pageid) code
528         // $ntries is decremented above
529         if (!$attempts = $lesson->get_attempts($ntries)) {
530             $attempts = array();
531         }
532         $firstattempt = current($attempts);
533         $pageid = $firstattempt->pageid;
534         // IF the student wishes to review, need to know the last question page that the student answered.  This will help to make
535         // sure that the student can leave the lesson via pushing the continue button.
536         $lastattempt = end($attempts);
537         $USER->modattempts[$lesson->id] = $lastattempt->pageid;
539         $url = new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm->id, 'pageid'=>$pageid));
540         $lessoncontent .= html_writer::link($url, get_string('reviewlesson', 'lesson'), array('class' => 'centerpadded lessonbutton standardbutton'));
542     } elseif ($lesson->modattempts && $canmanage) {
543         $lessoncontent .= $lessonoutput->paragraph(get_string("modattemptsnoteacher", "lesson"), 'centerpadded');
544     }
546     if ($lesson->activitylink) {
547         $lessoncontent .= $lesson->link_for_activitylink();
548     }
550     $url = new moodle_url('/course/view.php', array('id'=>$course->id));
551     $lessoncontent .= html_writer::link($url, get_string('returnto', 'lesson', format_string($course->fullname, true)), array('class'=>'centerpadded lessonbutton standardbutton'));
553     $url = new moodle_url('/grade/index.php', array('id'=>$course->id));
554     $lessoncontent .= html_writer::link($url, get_string('viewgrades', 'lesson'), array('class'=>'centerpadded lessonbutton standardbutton'));
556     lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
557     echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid);
558     echo $lessoncontent;
559     echo $lessonoutput->footer();
562 /// Mark as viewed
563 $completion=new completion_info($course);
564 $completion->set_module_viewed($cm);