3 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * This page prints a particular instance of lesson
22 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late
26 require_once(dirname(__FILE__
) . '/../../config.php');
27 require_once($CFG->dirroot
.'/mod/lesson/locallib.php');
28 require_once($CFG->dirroot
.'/mod/lesson/view_form.php');
29 require_once($CFG->libdir
. '/completionlib.php');
30 require_once($CFG->libdir
. '/grade/constants.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);
45 redirect(new moodle_url('/course/view.php', array('id'=>$course->id
)));
49 $lesson->update_effective_access($USER->id
);
52 $completion = new completion_info($course);
53 $completion->set_module_viewed($cm);
55 $url = new moodle_url('/mod/lesson/view.php', array('id'=>$id));
56 if ($pageid !== null) {
57 $url->param('pageid', $pageid);
61 $context = context_module
::instance($cm->id
);
62 $canmanage = has_capability('mod/lesson:manage', $context);
64 $lessonoutput = $PAGE->get_renderer('mod_lesson');
67 $userhasgrade = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id
, "userid"=>$USER->id
));
68 if ($userhasgrade && !$lesson->retake
) {
72 /// Check these for students only TODO: Find a better method for doing this!
73 /// Check lesson availability
74 /// Check for password
75 /// Check dependencies
77 if (!$lesson->is_accessible()) { // Deadline restrictions
78 echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('notavailable'));
79 if ($lesson->deadline
!= 0 && time() > $lesson->deadline
) {
80 echo $lessonoutput->lesson_inaccessible(get_string('lessonclosed', 'lesson', userdate($lesson->deadline
)));
82 echo $lessonoutput->lesson_inaccessible(get_string('lessonopen', 'lesson', userdate($lesson->available
)));
84 echo $lessonoutput->footer();
86 } else if ($lesson->usepassword
&& empty($USER->lessonloggedin
[$lesson->id
])) { // Password protected lesson code
88 if (!empty($userpassword) && (($lesson->password
== md5(trim($userpassword))) ||
($lesson->password
== trim($userpassword)))) {
90 // with or without md5 for backward compatibility (MDL-11090)
92 $USER->lessonloggedin
[$lesson->id
] = true;
94 } else if (isset($lesson->extrapasswords
)) {
96 // Group overrides may have additional passwords.
97 foreach ($lesson->extrapasswords
as $password) {
98 if (strcmp($password, md5(trim($userpassword))) === 0 ||
strcmp($password, trim($userpassword)) === 0) {
101 $USER->lessonloggedin
[$lesson->id
] = true;
106 echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name
)));
107 echo $lessonoutput->login_prompt($lesson, $userpassword !== '');
108 echo $lessonoutput->footer();
111 } else if ($lesson->dependency
) { // check for dependencies
112 if ($dependentlesson = $DB->get_record('lesson', array('id' => $lesson->dependency
))) {
113 // lesson exists, so we can proceed
114 $conditions = unserialize($lesson->conditions
);
115 // assume false for all
118 // check for the timespent condition
119 if ($conditions->timespent
) {
121 if ($attempttimes = $DB->get_records('lesson_timer', array("userid"=>$USER->id
, "lessonid"=>$dependentlesson->id
))) {
122 // go through all the times and test to see if any of them satisfy the condition
123 foreach($attempttimes as $attempttime) {
124 $duration = $attempttime->lessontime
- $attempttime->starttime
;
125 if ($conditions->timespent
< $duration/60) {
131 $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent
);
135 // check for the gradebetterthan condition
136 if($conditions->gradebetterthan
) {
137 $gradebetterthan = false;
138 if ($studentgrades = $DB->get_records('lesson_grades', array("userid"=>$USER->id
, "lessonid"=>$dependentlesson->id
))) {
139 // go through all the grades and test to see if any of them satisfy the condition
140 foreach($studentgrades as $studentgrade) {
141 if ($studentgrade->grade
>= $conditions->gradebetterthan
) {
142 $gradebetterthan = true;
146 if (!$gradebetterthan) {
147 $errors[] = get_string('gradebetterthanerror', 'lesson', $conditions->gradebetterthan
);
151 // check for the completed condition
152 if ($conditions->completed
) {
153 if (!$DB->count_records('lesson_grades', array('userid'=>$USER->id
, 'lessonid'=>$dependentlesson->id
))) {
154 $errors[] = get_string('completederror', 'lesson');
158 if (!empty($errors)) { // print out the errors if any
159 echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('completethefollowingconditions', 'lesson', format_string($lesson->name
)));
160 echo $lessonoutput->dependancy_errors($dependentlesson, $errors);
161 echo $lessonoutput->footer();
168 // this is called if a student leaves during a lesson
169 if ($pageid == LESSON_UNSEENBRANCHPAGE
) {
170 $pageid = lesson_unseen_question_jump($lesson, $USER->id
, $pageid);
173 // display individual pages and their sets of answers
174 // if pageid is EOL then the end of the lesson has been reached
175 // for flow, changed to simple echo for flow styles, michaelp, moved lesson name and page title down
176 $attemptflag = false;
177 if (empty($pageid)) {
178 // make sure there are pages to view
179 if (!$DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id
, 'prevpageid' => 0))) {
181 $lesson->add_message(get_string('lessonnotready2', 'lesson')); // a nice message to the student
183 if (!$DB->count_records('lesson_pages', array('lessonid'=>$lesson->id
))) {
184 redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
186 $lesson->add_message(get_string('lessonpagelinkingbroken', 'lesson')); // ok, bad mojo
191 // if no pageid given see if the lesson has been started
192 $retries = $DB->count_records('lesson_grades', array("lessonid" => $lesson->id
, "userid" => $USER->id
));
197 if (isset($USER->modattempts
[$lesson->id
])) {
198 unset($USER->modattempts
[$lesson->id
]); // if no pageid, then student is NOT reviewing
201 // If there are any questions that have been answered correctly (or not) in this attempt.
202 $allattempts = $lesson->get_attempts($retries);
203 if (!empty($allattempts)) {
204 $attempt = end($allattempts);
205 $attemptpage = $lesson->load_page($attempt->pageid
);
206 $jumpto = $DB->get_field('lesson_answers', 'jumpto', array('id' => $attempt->answerid
));
207 // convert the jumpto to a proper page id
209 // Check if a question has been incorrectly answered AND no more attempts at it are left.
210 $nattempts = $lesson->get_attempts($attempt->retry
, false, $attempt->pageid
, $USER->id
);
211 if (count($nattempts) >= $lesson->maxattempts
) {
212 $lastpageseen = $lesson->get_next_page($attemptpage->nextpageid
);
214 $lastpageseen = $attempt->pageid
;
216 } elseif ($jumpto == LESSON_NEXTPAGE
) {
217 $lastpageseen = $lesson->get_next_page($attemptpage->nextpageid
);
218 } else if ($jumpto == LESSON_CLUSTERJUMP
) {
219 $lastpageseen = $lesson->cluster_jump($attempt->pageid
);
221 $lastpageseen = $jumpto;
225 if ($branchtables = $DB->get_records('lesson_branch', array("lessonid" => $lesson->id
, "userid" => $USER->id
, "retry" => $retries), 'timeseen DESC')) {
226 // in here, user has viewed a branch table
227 $lastbranchtable = current($branchtables);
228 if (count($allattempts) > 0) {
229 if ($lastbranchtable->timeseen
> $attempt->timeseen
) {
230 // This branch table was viewed more recently than the question page.
231 if (!empty($lastbranchtable->nextpageid
)) {
232 $lastpageseen = $lastbranchtable->nextpageid
;
234 // Next page ID did not exist prior to MDL-34006.
235 $lastpageseen = $lastbranchtable->pageid
;
239 // Has not answered any questions but has viewed a branch table.
240 if (!empty($lastbranchtable->nextpageid
)) {
241 $lastpageseen = $lastbranchtable->nextpageid
;
243 // Next page ID did not exist prior to MDL-34006.
244 $lastpageseen = $lastbranchtable->pageid
;
248 // Check to see if end of lesson was reached.
249 if ((isset($lastpageseen) && ($lastpageseen != LESSON_EOL
))) {
250 if (($DB->count_records('lesson_attempts', array('lessonid' => $lesson->id
, 'userid' => $USER->id
, 'retry' => $retries)) > 0)
251 ||
$DB->count_records('lesson_branch', array("lessonid" => $lesson->id
, "userid" => $USER->id
, "retry" => $retries)) > 0) {
253 echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('leftduringtimedsession', 'lesson'));
254 if ($lesson->timelimit
) {
255 if ($lesson->retake
) {
256 $continuelink = new single_button(new moodle_url('/mod/lesson/view.php',
257 array('id' => $cm->id
, 'pageid' => $lesson->firstpageid
, 'startlastseen' => 'no')),
258 get_string('continue', 'lesson'), 'get');
260 echo html_writer
::div($lessonoutput->message(get_string('leftduringtimed', 'lesson'), $continuelink),
261 'center leftduring');
264 $courselink = new single_button(new moodle_url('/course/view.php',
265 array('id' => $PAGE->course
->id
)), get_string('returntocourse', 'lesson'), 'get');
267 echo html_writer
::div($lessonoutput->message(get_string('leftduringtimednoretake', 'lesson'), $courselink),
268 'center leftduring');
271 echo $lessonoutput->continue_links($lesson, $lastpageseen);
273 echo $lessonoutput->footer();
279 if (!$lesson->retake
) {
280 echo $lessonoutput->header($lesson, $cm, 'view', '', null, get_string("noretake", "lesson"));
281 $courselink = new single_button(new moodle_url('/course/view.php', array('id'=>$PAGE->course
->id
)), get_string('returntocourse', 'lesson'), 'get');
282 echo $lessonoutput->message(get_string("noretake", "lesson"), $courselink);
283 echo $lessonoutput->footer();
287 // start at the first page
288 if (!$pageid = $DB->get_field('lesson_pages', 'id', array('lessonid' => $lesson->id
, 'prevpageid' => 0))) {
289 print_error('cannotfindfirstpage', 'lesson');
291 /// This is the code for starting a timed test
292 if(!isset($USER->startlesson
[$lesson->id
]) && !$canmanage) {
293 $lesson->start_timer();
297 $currenttab = 'view';
298 $extraeditbuttons = false;
299 $lessonpageid = null;
302 if ($pageid != LESSON_EOL
) {
303 /// This is the code updates the lessontime for a timed test
304 $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA
);
306 $page = $lesson->load_page($pageid);
307 // Check if the page is of a special type and if so take any nessecary action
308 $newpageid = $page->callback_on_view($canmanage);
309 if (is_numeric($newpageid)) {
310 $page = $lesson->load_page($newpageid);
313 // Trigger module viewed event.
314 $event = \mod_lesson\event\course_module_viewed
::create(array(
315 'objectid' => $lesson->id
,
316 'context' => $context
318 $event->add_record_snapshot('course_modules', $cm);
319 $event->add_record_snapshot('course', $course);
322 // This is where several messages (usually warnings) are displayed
323 // all of this is displayed above the actual page
325 // check to see if the user can see the left menu
327 $lesson->displayleft
= lesson_displayleftif($lesson);
329 $continue = ($startlastseen !== '');
330 $restart = ($continue && $startlastseen == 'yes');
331 $timer = $lesson->update_timer($continue, $restart);
333 if ($lesson->timelimit
) {
334 $timeleft = $timer->starttime +
$lesson->timelimit
- time();
335 if ($timeleft <= 0) {
337 $lesson->add_message(get_string('eolstudentoutoftime', 'lesson'));
338 redirect(new moodle_url('/mod/lesson/view.php', array('id'=>$cm->id
,'pageid'=>LESSON_EOL
, 'outoftime'=>'normal')));
339 die; // Shouldn't be reached, but make sure
340 } else if ($timeleft < 60) {
341 // One minute warning
342 $lesson->add_message(get_string('studentoneminwarning', 'lesson'));
346 if ($page->qtype
== LESSON_PAGE_BRANCHTABLE
&& $lesson->minquestions
) {
347 // tell student how many questions they have seen, how many are required and their grade
348 $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id
, "userid"=>$USER->id
));
349 $gradeinfo = lesson_grade($lesson, $ntries);
350 if ($gradeinfo->attempts
) {
351 if ($gradeinfo->nquestions
< $lesson->minquestions
) {
353 $a->nquestions
= $gradeinfo->nquestions
;
354 $a->minquestions
= $lesson->minquestions
;
355 $lesson->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
358 if (!$reviewmode && !$lesson->retake
){
359 $lesson->add_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned
), 'notify');
360 if ($lesson->grade
!= GRADE_TYPE_NONE
) {
362 $a->grade
= number_format($gradeinfo->grade
* $lesson->grade
/ 100, 1);
363 $a->total
= $lesson->grade
;
364 $lesson->add_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
371 if ($lesson->timelimit
) {
372 $lesson->add_message(get_string('teachertimerwarning', 'lesson'));
374 if (lesson_display_teacher_warning($lesson)) {
375 // This is the warning msg for teachers to inform them that cluster
376 // and unseen does not work while logged in as a teacher
377 $warningvars = new stdClass();
378 $warningvars->cluster
= get_string('clusterjump', 'lesson');
379 $warningvars->unseen
= get_string('unseenpageinbranch', 'lesson');
380 $lesson->add_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
384 $PAGE->set_subpage($page->id
);
385 $currenttab = 'view';
386 $extraeditbuttons = true;
387 $lessonpageid = $page->id
;
388 $extrapagetitle = $page->title
;
390 if (($edit != -1) && $PAGE->user_allowed_editing()) {
391 $USER->editing
= $edit;
394 if (is_array($page->answers
) && count($page->answers
)>0) {
395 // this is for modattempts option. Find the users previous answer to this page,
396 // and then display it below in answer processing
397 if (isset($USER->modattempts
[$lesson->id
])) {
398 $retries = $DB->count_records('lesson_grades', array("lessonid"=>$lesson->id
, "userid"=>$USER->id
));
399 if (!$attempts = $lesson->get_attempts($retries-1, false, $page->id
)) {
400 print_error('cannotfindpreattempt', 'lesson');
402 $attempt = end($attempts);
403 $USER->modattempts
[$lesson->id
] = $attempt;
407 $lessoncontent = $lessonoutput->display_page($lesson, $page, $attempt);
409 $data = new stdClass
;
410 $data->id
= $PAGE->cm
->id
;
411 $data->pageid
= $page->id
;
412 $data->newpageid
= $lesson->get_next_page($page->nextpageid
);
415 'title' => $page->title
,
416 'contents' => $page->get_contents()
418 $mform = new lesson_page_without_answers($CFG->wwwroot
.'/mod/lesson/continue.php', $customdata);
419 $mform->set_data($data);
422 $lessoncontent = ob_get_contents();
426 lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
427 echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid, $extrapagetitle);
429 // We are using level 3 header because attempt heading is a sub-heading of lesson title (MDL-30911).
430 echo $OUTPUT->heading(get_string('attempt', 'lesson', $retries), 3);
432 /// This calculates and prints the ongoing score
433 if ($lesson->ongoing
&& !empty($pageid) && !$reviewmode) {
434 echo $lessonoutput->ongoing_score($lesson);
436 if ($lesson->displayleft
) {
437 echo '<a name="maincontent" id="maincontent" title="' . get_string('anchortitle', 'lesson') . '"></a>';
440 echo $lessonoutput->progress_bar($lesson);
441 echo $lessonoutput->footer();
446 // end of lesson reached work out grade
447 // Used to check to see if the student ran out of time
448 $outoftime = optional_param('outoftime', '', PARAM_ALPHA
);
450 $ntries = $DB->count_records("lesson_grades", array("lessonid"=>$lesson->id
, "userid"=>$USER->id
));
451 if (isset($USER->modattempts
[$lesson->id
])) {
452 $ntries--; // need to look at the old attempts :)
455 $gradeinfo = lesson_grade($lesson, $ntries);
456 if ($lesson->custom
&& !$canmanage) {
457 // Before we calculate the custom score make sure they answered the minimum
458 // number of questions. We only need to do this for custom scoring as we can
459 // not get the miniumum score the user should achieve. If we are not using
460 // custom scoring (so all questions are valued as 1) then we simply check if
461 // they answered more than the minimum questions, if not, we mark it out of the
462 // number specified in the minimum questions setting - which is done in lesson_grade().
463 // Get the number of answers given.
464 if ($gradeinfo->nquestions
< $lesson->minquestions
) {
465 $gradelesson = false;
467 $a->nquestions
= $gradeinfo->nquestions
;
468 $a->minquestions
= $lesson->minquestions
;
469 $lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
470 $lesson->add_message(get_string('numberofpagesviewednotice', 'lesson', $a));
474 // We are using level 3 header because the page title is a sub-heading of lesson title (MDL-30911).
475 $lessoncontent .= $OUTPUT->heading(get_string("congratulations", "lesson"), 3);
476 $lessoncontent .= $OUTPUT->box_start('generalbox boxaligncenter');
480 // Store this now before any modifications to pages viewed.
481 $progressbar = $lessonoutput->progress_bar($lesson);
482 // Update the clock / get time information for this user.
483 $lesson->stop_timer();
485 // Update completion state.
486 $completion = new completion_info($course);
487 if ($completion->is_enabled($cm) && $lesson->completionendreached
) {
488 $completion->update_state($cm, COMPLETION_COMPLETE
);
491 if ($lesson->completiontimespent
> 0) {
492 $duration = $DB->get_field_sql(
493 "SELECT SUM(lessontime - starttime)
495 WHERE lessonid = :lessonid
496 AND userid = :userid",
497 array('userid' => $USER->id
, 'lessonid' => $lesson->id
));
502 // If student has not spend enough time in the lesson, display a message.
503 if ($duration < $lesson->completiontimespent
) {
505 $a->timespent
= format_time($duration);
506 $a->timerequired
= format_time($lesson->completiontimespent
);
507 $lessoncontent .= $lessonoutput->paragraph(get_string("notenoughtimespent", "lesson", $a), 'center');
512 if ($gradeinfo->attempts
) {
513 if (!$lesson->custom
) {
514 $lessoncontent .= $lessonoutput->paragraph(get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions
), 'center');
515 if ($lesson->minquestions
) {
516 if ($gradeinfo->nquestions
< $lesson->minquestions
) {
517 // print a warning and set nviewed to minquestions
518 $lessoncontent .= $lessonoutput->paragraph(get_string("youshouldview", "lesson", $lesson->minquestions
), 'center');
521 $lessoncontent .= $lessonoutput->paragraph(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned
), 'center');
524 $a->score
= $gradeinfo->earned
;
525 $a->grade
= $gradeinfo->total
;
526 if ($gradeinfo->nmanual
) {
527 $a->tempmaxgrade
= $gradeinfo->total
- $gradeinfo->manualpoints
;
528 $a->essayquestions
= $gradeinfo->nmanual
;
529 $lessoncontent .= $OUTPUT->box(get_string("displayscorewithessays", "lesson", $a), 'center');
531 $lessoncontent .= $OUTPUT->box(get_string("displayscorewithoutessays", "lesson", $a), 'center');
533 if ($lesson->grade
!= GRADE_TYPE_NONE
) {
535 $a->grade
= number_format($gradeinfo->grade
* $lesson->grade
/ 100, 1);
536 $a->total
= $lesson->grade
;
537 $lessoncontent .= $lessonoutput->paragraph(get_string("yourcurrentgradeisoutof", "lesson", $a), 'center');
540 $grade = new stdClass();
541 $grade->lessonid
= $lesson->id
;
542 $grade->userid
= $USER->id
;
543 $grade->grade
= $gradeinfo->grade
;
544 $grade->completed
= time();
545 if (isset($USER->modattempts
[$lesson->id
])) { // If reviewing, make sure update old grade record.
546 if (!$grades = $DB->get_records("lesson_grades",
547 array("lessonid" => $lesson->id
, "userid" => $USER->id
), "completed DESC", '*', 0, 1)) {
548 print_error('cannotfindgrade', 'lesson');
550 $oldgrade = array_shift($grades);
551 $grade->id
= $oldgrade->id
;
552 $DB->update_record("lesson_grades", $grade);
554 $newgradeid = $DB->insert_record("lesson_grades", $grade);
557 if ($lesson->timelimit
) {
558 if ($outoftime == 'normal') {
559 $grade = new stdClass();
560 $grade->lessonid
= $lesson->id
;
561 $grade->userid
= $USER->id
;
563 $grade->completed
= time();
564 $newgradeid = $DB->insert_record("lesson_grades", $grade);
565 $lessoncontent .= $lessonoutput->paragraph(get_string("eolstudentoutoftimenoanswers", "lesson"));
568 $lessoncontent .= $lessonoutput->paragraph(get_string("welldone", "lesson"));
572 // update central gradebook
573 lesson_update_grades($lesson, $USER->id
);
574 $lessoncontent .= $progressbar;
577 // display for teacher
578 if ($lesson->grade
!= GRADE_TYPE_NONE
) {
579 $lessoncontent .= $lessonoutput->paragraph(get_string("displayofgrade", "lesson"), 'center');
582 $lessoncontent .= $OUTPUT->box_end(); //End of Lesson button to Continue.
584 if ($lesson->modattempts
&& !$canmanage) {
585 // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
586 // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
587 // to pass to view again. This is slick cause it wont call the empty($pageid) code
588 // $ntries is decremented above
589 if (!$attempts = $lesson->get_attempts($ntries)) {
591 $url = new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm
->id
));
593 $firstattempt = current($attempts);
594 $pageid = $firstattempt->pageid
;
595 // IF the student wishes to review, need to know the last question page that the student answered. This will help to make
596 // sure that the student can leave the lesson via pushing the continue button.
597 $lastattempt = end($attempts);
598 $USER->modattempts
[$lesson->id
] = $lastattempt->pageid
;
600 $url = new moodle_url('/mod/lesson/view.php', array('id'=>$PAGE->cm
->id
, 'pageid'=>$pageid));
602 $lessoncontent .= html_writer
::link($url, get_string('reviewlesson', 'lesson'), array('class' => 'centerpadded lessonbutton standardbutton'));
603 } elseif ($lesson->modattempts
&& $canmanage) {
604 $lessoncontent .= $lessonoutput->paragraph(get_string("modattemptsnoteacher", "lesson"), 'centerpadded');
607 if ($lesson->activitylink
) {
608 $lessoncontent .= $lesson->link_for_activitylink();
611 $url = new moodle_url('/course/view.php', array('id'=>$course->id
));
612 $lessoncontent .= html_writer
::link($url, get_string('returnto', 'lesson', format_string($course->fullname
, true)), array('class'=>'centerpadded lessonbutton standardbutton'));
614 if (has_capability('gradereport/user:view', context_course
::instance($course->id
))
615 && $course->showgrades
&& $lesson->grade
!= 0 && !$lesson->practice
) {
616 $url = new moodle_url('/grade/index.php', array('id' => $course->id
));
617 $lessoncontent .= html_writer
::link($url, get_string('viewgrades', 'lesson'),
618 array('class' => 'centerpadded lessonbutton standardbutton'));
621 lesson_add_fake_blocks($PAGE, $cm, $lesson, $timer);
622 echo $lessonoutput->header($lesson, $cm, $currenttab, $extraeditbuttons, $lessonpageid, get_string("congratulations", "lesson"));
624 echo $lessonoutput->footer();