Fixes to the PaintWeb cron task.
[moodle/mihaisucan.git] / mod / lesson / view.php
blob4cf562f1caf31478c16743e1db848c687d291a63
1 <?php // $Id$
2 /**
3 * This page prints a particular instance of lesson
5 * @version $Id$
6 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7 * @package lesson
8 **/
10 require_once('../../config.php');
11 require_once($CFG->dirroot.'/mod/lesson/locallib.php');
12 require_once($CFG->dirroot.'/mod/lesson/lib.php');
13 require_once($CFG->dirroot.'/mod/lesson/pagelib.php');
14 require_once($CFG->libdir.'/blocklib.php');
16 $id = required_param('id', PARAM_INT); // Course Module ID
17 $pageid = optional_param('pageid', NULL, PARAM_INT); // Lesson Page ID
18 $edit = optional_param('edit', -1, PARAM_BOOL);
19 $userpassword = optional_param('userpassword','',PARAM_CLEAN);
21 list($cm, $course, $lesson) = lesson_get_basics($id);
23 require_login($course->id, false, $cm);
25 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
27 /// Check these for students only TODO: Find a better method for doing this!
28 /// Check lesson availability
29 /// Check for password
30 /// Check dependencies
31 /// Check for high scores
32 if (!has_capability('mod/lesson:manage', $context)) {
34 if (($lesson->available != 0 and time() < $lesson->available) or
35 ($lesson->deadline != 0 and time() > $lesson->deadline)) { // Deadline restrictions
36 if ($lesson->deadline != 0 and time() > $lesson->deadline) {
37 $message = get_string('lessonclosed', 'lesson', userdate($lesson->deadline));
38 } else {
39 $message = get_string('lessonopen', 'lesson', userdate($lesson->available));
42 lesson_print_header($cm, $course, $lesson);
43 print_simple_box_start('center');
44 echo '<div style="text-align:center;">';
45 echo '<p>'.$message.'</p>';
46 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>';
47 echo '</div>';
48 print_simple_box_end();
49 print_footer($course);
50 exit();
52 } else if ($lesson->usepassword and empty($USER->lessonloggedin[$lesson->id])) { // Password protected lesson code
53 $correctpass = false;
54 if (!empty($userpassword)) {
55 // with or without md5 for backward compatibility (MDL-11090)
56 if (($lesson->password == md5(trim($userpassword))) or ($lesson->password == trim($userpassword))) {
57 $USER->lessonloggedin[$lesson->id] = true;
58 $correctpass = true;
59 if ($lesson->highscores) {
60 // Logged in - redirect so we go through all of these checks before starting the lesson.
61 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
66 if (!$correctpass) {
67 lesson_print_header($cm, $course, $lesson);
68 echo "<div class=\"password-form\">\n";
69 print_simple_box_start('center');
70 echo '<form id="password" method="post" action="'.$CFG->wwwroot.'/mod/lesson/view.php" autocomplete="off">' . "\n";
71 echo '<fieldset class="invisiblefieldset">';
72 echo '<input type="hidden" name="id" value="'. $cm->id .'" />' . "\n";
73 if (optional_param('userpassword', 0, PARAM_CLEAN)) {
74 notify(get_string('loginfail', 'lesson'));
77 echo get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name))."<br /><br />\n".
78 get_string('enterpassword', 'lesson')." <input type=\"password\" name=\"userpassword\" /><br /><br />\n<center>".
79 '<span class="lessonbutton standardbutton"><a href="'.$CFG->wwwroot.'/course/view.php?id='. $course->id .'">'. get_string('cancel', 'lesson') .'</a></span> ';
81 lesson_print_submit_link(get_string('continue', 'lesson'), 'password', 'center', 'standardbutton submitbutton');
82 echo '</fieldset></form>';
83 print_simple_box_end();
84 echo "</div>\n";
85 print_footer($course);
86 exit();
89 } else if ($lesson->dependency) { // check for dependencies
90 if ($dependentlesson = get_record('lesson', 'id', $lesson->dependency)) {
91 // lesson exists, so we can proceed
92 $conditions = unserialize($lesson->conditions);
93 // assume false for all
94 $timespent = false;
95 $completed = false;
96 $gradebetterthan = false;
97 // check for the timespent condition
98 if ($conditions->timespent) {
99 if ($attempttimes = get_records_select('lesson_timer', "userid = $USER->id AND 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;
108 } else {
109 $timespent = true; // there isn't one set
112 // check for the gradebetterthan condition
113 if($conditions->gradebetterthan) {
114 if ($studentgrades = get_records_select('lesson_grades', "userid = $USER->id AND lessonid = $dependentlesson->id")) {
115 // go through all the grades and test to see if any of them satisfy the condition
116 foreach($studentgrades as $studentgrade) {
117 if ($studentgrade->grade >= $conditions->gradebetterthan) {
118 $gradebetterthan = true;
122 } else {
123 $gradebetterthan = true; // there isn't one set
126 // check for the completed condition
127 if ($conditions->completed) {
128 if (count_records('lesson_grades', 'userid', $USER->id, 'lessonid', $dependentlesson->id)) {
129 $completed = true;
131 } else {
132 $completed = true; // not set
135 $errors = array();
136 // collect all of our error statements
137 if (!$timespent) {
138 $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent);
140 if (!$completed) {
141 $errors[] = get_string('completederror', 'lesson');
143 if (!$gradebetterthan) {
144 $errors[] = get_string('gradebetterthanerror', 'lesson', $conditions->gradebetterthan);
146 if (!empty($errors)) { // print out the errors if any
147 lesson_print_header($cm, $course, $lesson);
148 echo '<p>';
149 print_simple_box_start('center');
150 print_string('completethefollowingconditions', 'lesson', $dependentlesson->name);
151 echo '<p style="text-align:center;">'.implode('<br />'.get_string('and', 'lesson').'<br />', $errors).'</p>';
152 print_simple_box_end();
153 echo '</p>';
154 print_footer($course);
155 exit();
159 } else if ($lesson->highscores and !$lesson->practice and !optional_param('viewed', 0) and empty($pageid)) {
160 // Display high scores before starting lesson
161 redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id");
165 // set up some general variables
166 $path = $CFG->wwwroot .'/course';
168 // this is called if a student leaves during a lesson
169 if($pageid == LESSON_UNSEENBRANCHPAGE) {
170 $pageid = lesson_unseen_question_jump($lesson->id, $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 (!get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0)) {
180 if (!has_capability('mod/lesson:manage', $context)) {
181 lesson_set_message(get_string('lessonnotready', 'lesson', $course->teacher)); // a nice message to the student
182 } else {
183 if (!count_records('lesson_pages', 'lessonid', $lesson->id)) {
184 redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
185 } else {
186 lesson_set_message(get_string('lessonpagelinkingbroken', 'lesson')); // ok, bad mojo
191 add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id);
193 // if no pageid given see if the lesson has been started
194 if ($grades = get_records_select('lesson_grades', 'lessonid = '. $lesson->id .' AND userid = '. $USER->id,
195 'grade DESC')) {
196 $retries = count($grades);
197 } else {
198 $retries = 0;
200 if ($retries) {
201 $attemptflag = true;
204 if (isset($USER->modattempts[$lesson->id])) {
205 unset($USER->modattempts[$lesson->id]); // if no pageid, then student is NOT reviewing
208 // if there are any questions have been answered correctly in this attempt
209 if ($attempts = get_records_select('lesson_attempts',
210 "lessonid = $lesson->id AND userid = $USER->id AND retry = $retries AND
211 correct = 1", 'timeseen DESC')) {
213 foreach ($attempts as $attempt) {
214 $jumpto = get_field('lesson_answers', 'jumpto', 'id', $attempt->answerid);
215 // convert the jumpto to a proper page id
216 if ($jumpto == 0) { // unlikely value!
217 $lastpageseen = $attempt->pageid;
218 } elseif ($jumpto == LESSON_NEXTPAGE) {
219 if (!$lastpageseen = get_field('lesson_pages', 'nextpageid', 'id',
220 $attempt->pageid)) {
221 // no nextpage go to end of lesson
222 $lastpageseen = LESSON_EOL;
224 } else {
225 $lastpageseen = $jumpto;
227 break; // only look at the latest correct attempt
229 } else {
230 $attempts = NULL;
233 if ($branchtables = get_records_select('lesson_branch',
234 "lessonid = $lesson->id AND userid = $USER->id AND retry = $retries", 'timeseen DESC')) {
235 // in here, user has viewed a branch table
236 $lastbranchtable = current($branchtables);
237 if ($attempts != NULL) {
238 foreach($attempts as $attempt) {
239 if ($lastbranchtable->timeseen > $attempt->timeseen) {
240 // branch table was viewed later than the last attempt
241 $lastpageseen = $lastbranchtable->pageid;
243 break;
245 } else {
246 // hasnt answered any questions but has viewed a branch table
247 $lastpageseen = $lastbranchtable->pageid;
250 //if ($lastpageseen != $firstpageid) {
251 if (isset($lastpageseen) and count_records('lesson_attempts', 'lessonid', $lesson->id, 'userid', $USER->id, 'retry', $retries) > 0) {
252 // get the first page
253 if (!$firstpageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id,
254 'prevpageid', 0)) {
255 error('Navigation: first page not found');
257 lesson_print_header($cm, $course, $lesson);
258 if ($lesson->timed) {
259 if ($lesson->retake) {
260 print_simple_box('<p style="text-align:center;">'. get_string('leftduringtimed', 'lesson') .'</p>', 'center');
261 echo '<div style="text-align:center;" class="lessonbutton standardbutton">'.
262 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
263 get_string('continue', 'lesson').'</a></div>';
264 } else {
265 print_simple_box_start('center');
266 echo '<div style="text-align:center;">';
267 echo get_string('leftduringtimednoretake', 'lesson');
268 echo '<br /><br /><div class="lessonbutton standardbutton"><a href="../../course/view.php?id='. $course->id .'">'. get_string('returntocourse', 'lesson') .'</a></div>';
269 echo '</div>';
270 print_simple_box_end();
273 } else {
274 print_simple_box("<p style=\"text-align:center;\">".get_string('youhaveseen','lesson').'</p>',
275 "center");
277 echo '<div style="text-align:center;">';
278 echo '<span class="lessonbutton standardbutton">'.
279 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$lastpageseen.'&amp;startlastseen=yes">'.
280 get_string('yes').'</a></span>&nbsp;&nbsp;&nbsp;';
281 echo '<span class="lessonbutton standardbutton">'.
282 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
283 get_string('no').'</a></div>';
284 echo '</span>';
286 print_footer($course);
287 exit();
290 if ($grades) {
291 foreach ($grades as $grade) {
292 $bestgrade = $grade->grade;
293 break;
295 if (!$lesson->retake) {
296 lesson_print_header($cm, $course, $lesson, 'view');
297 print_simple_box_start('center');
298 echo "<div style=\"text-align:center;\">";
299 echo get_string("noretake", "lesson");
300 echo "<br /><br /><div class=\"lessonbutton standardbutton\"><a href=\"../../course/view.php?id=$course->id\">".get_string('returntocourse', 'lesson').'</a></div>';
301 echo "</div>";
302 print_simple_box_end();
303 print_footer($course);
304 exit();
305 //redirect("../../course/view.php?id=$course->id", get_string("alreadytaken", "lesson"));
306 // allow student to retake course even if they have the maximum grade
307 // } elseif ($bestgrade == 100) {
308 // redirect("../../course/view.php?id=$course->id", get_string("maximumgradeachieved",
309 // "lesson"));
312 // start at the first page
313 if (!$pageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0)) {
314 error('Navigation: first page not found');
316 /// This is the code for starting a timed test
317 if(!isset($USER->startlesson[$lesson->id]) && !has_capability('mod/lesson:manage', $context)) {
318 $USER->startlesson[$lesson->id] = true;
319 $startlesson = new stdClass;
320 $startlesson->lessonid = $lesson->id;
321 $startlesson->userid = $USER->id;
322 $startlesson->starttime = time();
323 $startlesson->lessontime = time();
325 if (!insert_record('lesson_timer', $startlesson)) {
326 error('Error: could not insert row into lesson_timer table');
328 if ($lesson->timed) {
329 lesson_set_message(get_string('maxtimewarning', 'lesson', $lesson->maxtime), 'center');
333 if ($pageid != LESSON_EOL) {
334 /// This is the code updates the lessontime for a timed test
335 if ($startlastseen = optional_param('startlastseen', '', PARAM_ALPHA)) { /// this deletes old records not totally sure if this is necessary anymore
336 if ($startlastseen == 'no') {
337 if ($grades = get_records_select('lesson_grades', "lessonid = $lesson->id AND userid = $USER->id",
338 'grade DESC')) {
339 $retries = count($grades);
340 } else {
341 $retries = 0;
343 if (!delete_records('lesson_attempts', 'userid', $USER->id, 'lessonid', $lesson->id, 'retry', $retries)) {
344 error('Error: could not delete old attempts');
346 if (!delete_records('lesson_branch', 'userid', $USER->id, 'lessonid', $lesson->id, 'retry', $retries)) {
347 error('Error: could not delete old seen branches');
352 add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
354 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
355 error('Navigation: the page record not found');
358 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
359 if (!has_capability('mod/lesson:manage', $context)) {
360 // get new id
361 $pageid = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
362 // get new page info
363 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
364 error('Navigation: the page record not found');
366 add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
367 } else {
368 // get the next page
369 $pageid = $page->nextpageid;
370 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
371 error('Navigation: the page record not found');
374 } elseif ($page->qtype == LESSON_ENDOFCLUSTER) { // Check for endofclusters
375 if ($page->nextpageid == 0) {
376 $nextpageid = LESSON_EOL;
377 } else {
378 $nextpageid = $page->nextpageid;
380 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$nextpageid");
381 } else if ($page->qtype == LESSON_ENDOFBRANCH) { // Check for endofbranches
382 if ($answers = get_records('lesson_answers', 'pageid', $page->id, 'id')) {
383 // print_heading(get_string('endofbranch', 'lesson'));
384 foreach ($answers as $answer) {
385 // just need the first answer
386 if ($answer->jumpto == LESSON_RANDOMBRANCH) {
387 $answer->jumpto = lesson_unseen_branch_jump($lesson->id, $USER->id);
388 } elseif ($answer->jumpto == LESSON_CLUSTERJUMP) {
389 if (!has_capability('mod/lesson:manage', $context)) {
390 $answer->jumpto = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
391 } else {
392 if ($page->nextpageid == 0) {
393 $answer->jumpto = LESSON_EOL;
394 } else {
395 $answer->jumpto = $page->nextpageid;
398 } else if ($answer->jumpto == LESSON_NEXTPAGE) {
399 if ($page->nextpageid == 0) {
400 $answer->jumpto = LESSON_EOL;
401 } else {
402 $answer->jumpto = $page->nextpageid;
404 } else if ($answer->jumpto == 0) {
405 $answer->jumpto = $page->id;
406 } else if ($answer->jumpto == LESSON_PREVIOUSPAGE) {
407 $answer->jumpto = $page->prevpageid;
409 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$answer->jumpto");
410 break;
412 } else {
413 error('Navigation: No answers on EOB');
417 // check to see if the user can see the left menu
418 if (!has_capability('mod/lesson:manage', $context)) {
419 $lesson->displayleft = lesson_displayleftif($lesson);
422 // This is where several messages (usually warnings) are displayed
423 // all of this is displayed above the actual page
425 // clock code
426 // get time information for this user
427 $timer = new stdClass;
428 if(!has_capability('mod/lesson:manage', $context)) {
429 if (!$timer = get_records_select('lesson_timer', "lessonid = $lesson->id AND userid = $USER->id", 'starttime')) {
430 error('Error: could not find records');
431 } else {
432 $timer = array_pop($timer); // this will get the latest start time record
436 $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
437 if ($startlastseen == 'yes') { // continue a previous test, need to update the clock (think this option is disabled atm)
438 $timer->starttime = time() - ($timer->lessontime - $timer->starttime);
439 $timer->lessontime = time();
440 } else if ($startlastseen == 'no') { // starting over
441 // starting over, so reset the clock
442 $timer->starttime = time();
443 $timer->lessontime = time();
446 // for timed lessons, display clock
447 if ($lesson->timed) {
448 if(has_capability('mod/lesson:manage', $context)) {
449 lesson_set_message(get_string('teachertimerwarning', 'lesson'));
450 } else {
451 $timeleft = ($timer->starttime + $lesson->maxtime * 60) - time();
453 if ($timeleft <= 0) {
454 // Out of time
455 lesson_set_message(get_string('eolstudentoutoftime', 'lesson'));
456 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=".LESSON_EOL."&amp;outoftime=normal");
457 die; // Shouldn't be reached, but make sure
458 } else if ($timeleft < 60) {
459 // One minute warning
460 lesson_set_message(get_string('studentoneminwarning', 'lesson'));
465 // update the clock
466 if (!has_capability('mod/lesson:manage', $context)) {
467 $timer->lessontime = time();
468 if (!update_record('lesson_timer', $timer)) {
469 error('Error: could not update lesson_timer table');
473 /// This is the warning msg for teachers to inform them that cluster and unseen does not work while logged in as a teacher
474 if(has_capability('mod/lesson:manage', $context)) {
475 if (lesson_display_teacher_warning($lesson->id)) {
476 $warningvars->cluster = get_string('clusterjump', 'lesson');
477 $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
478 lesson_set_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
482 if ($page->qtype == LESSON_BRANCHTABLE) {
483 if ($lesson->minquestions and !has_capability('mod/lesson:manage', $context)) {
484 // tell student how many questions they have seen, how many are required and their grade
485 $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
487 $gradeinfo = lesson_grade($lesson, $ntries);
489 if ($gradeinfo->attempts) {
490 if ($gradeinfo->nquestions < $lesson->minquestions) {
491 $a = new stdClass;
492 $a->nquestions = $gradeinfo->nquestions;
493 $a->minquestions = $lesson->minquestions;
494 lesson_set_message(get_string('numberofpagesviewednotice', 'lesson', $a));
496 lesson_set_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'notify');
497 $a = new stdClass;
498 $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
499 $a->total = $lesson->grade;
500 lesson_set_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
505 $PAGE = page_create_instance($lesson->id);
506 $PAGE->set_lessonpageid($page->id);
507 $pageblocks = blocks_setup($PAGE);
509 $leftcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
510 $rightcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210);
512 if (($edit != -1) and $PAGE->user_allowed_editing()) {
513 $USER->editing = $edit;
516 /// Print the page header, heading and tabs
517 $PAGE->print_header();
519 if ($attemptflag) {
520 print_heading(get_string('attempt', 'lesson', $retries + 1));
523 /// This calculates and prints the ongoing score
524 if ($lesson->ongoing and !empty($pageid)) {
525 lesson_print_ongoing_score($lesson);
528 require($CFG->dirroot.'/mod/lesson/viewstart.html');
530 // now starting to print the page's contents
531 if ($page->qtype == LESSON_BRANCHTABLE) {
532 print_heading(format_string($page->title));
533 } else {
534 $lesson->slideshow = false; // turn off slide show for all pages other than LESSON_BRANTCHTABLE
537 if (!$lesson->slideshow) {
538 $options = new stdClass;
539 $options->noclean = true;
540 print_simple_box('<div class="contents">'.
541 format_text($page->contents, FORMAT_MOODLE, $options).
542 '</div>', 'center');
545 // this is for modattempts option. Find the users previous answer to this page,
546 // and then display it below in answer processing
547 if (isset($USER->modattempts[$lesson->id])) {
548 $retries = count_records('lesson_grades', "lessonid", $lesson->id, "userid", $USER->id);
549 $retries--;
550 if (! $attempts = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND pageid = $page->id AND retry = $retries", "timeseen")) {
551 error("Previous attempt record could not be found!");
553 $attempt = end($attempts);
556 // get the answers in a set order, the id order
557 if ($answers = get_records("lesson_answers", "pageid", $page->id, "id")) {
558 if ($page->qtype != LESSON_BRANCHTABLE) { // To fix XHTML problem (BT have their own forms)
559 echo "<form id=\"answerform\" method =\"post\" action=\"lesson.php\" autocomplete=\"off\">";
560 echo '<fieldset class="invisiblefieldset">';
561 echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />";
562 echo "<input type=\"hidden\" name=\"action\" value=\"continue\" />";
563 echo "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />";
564 echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
565 print_simple_box_start("center");
566 echo '<table width="100%">';
568 // default format text options
569 $options = new stdClass;
570 $options->para = false; // no <p></p>
571 $options->noclean = true;
572 // echo "qtype is $page->qtype"; // debug
573 switch ($page->qtype) {
574 case LESSON_SHORTANSWER :
575 case LESSON_NUMERICAL :
576 if (isset($USER->modattempts[$lesson->id])) {
577 $value = 'value="'.s($attempt->useranswer).'"';
578 } else {
579 $value = "";
581 echo '<tr><td style="text-align:center;"><label for="answer">'.get_string('youranswer', 'lesson').'</label>'.
582 ": <input type=\"text\" id=\"answer\" name=\"answer\" size=\"50\" maxlength=\"200\" $value />\n";
583 echo '</td></tr></table>';
584 print_simple_box_end();
585 lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
586 break;
587 case LESSON_TRUEFALSE :
588 shuffle($answers);
589 $i = 0;
590 foreach ($answers as $answer) {
591 echo '<tr><td valign="top">';
592 if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
593 $checked = 'checked="checked"';
594 } else {
595 $checked = '';
597 echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\" $checked />";
598 echo "</td><td>";
599 echo "<label for=\"answerid$i\">".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
600 echo '</td></tr>';
601 if ($answer != end($answers)) {
602 echo "<tr><td><br /></td></tr>";
604 $i++;
606 echo '</table>';
607 print_simple_box_end();
608 lesson_print_submit_link(get_string('pleasecheckoneanswer', 'lesson'), 'answerform');
609 break;
610 case LESSON_MULTICHOICE :
611 $i = 0;
612 shuffle($answers);
614 foreach ($answers as $answer) {
615 echo '<tr><td valign="top">';
616 if ($page->qoption) {
617 $checked = '';
618 if (isset($USER->modattempts[$lesson->id])) {
619 $answerids = explode(",", $attempt->useranswer);
620 if (in_array($answer->id, $answerids)) {
621 $checked = ' checked="checked"';
622 } else {
623 $checked = '';
626 // more than one answer allowed
627 echo "<input type=\"checkbox\" id=\"answerid$i\" name=\"answer[$i]\" value=\"{$answer->id}\"$checked />";
628 } else {
629 if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
630 $checked = ' checked="checked"';
631 } else {
632 $checked = '';
634 // only one answer allowed
635 echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\"$checked />";
637 echo '</td><td>';
638 echo "<label for=\"answerid$i\" >".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
639 echo '</td></tr>';
640 if ($answer != end($answers)) {
641 echo '<tr><td><br /></td></tr>';
643 $i++;
645 echo '</table>';
646 print_simple_box_end();
647 if ($page->qoption) {
648 $linkname = get_string('pleasecheckoneormoreanswers', 'lesson');
649 } else {
650 $linkname = get_string('pleasecheckoneanswer', 'lesson');
652 lesson_print_submit_link($linkname, 'answerform');
653 break;
655 case LESSON_MATCHING :
656 // don't suffle answers (could be an option??)
657 foreach ($answers as $answer) {
658 // get all the response
659 if ($answer->response != NULL) {
660 $responses[] = trim($answer->response);
664 $responseoptions = array();
665 if (!empty($responses)) {
666 shuffle($responses);
667 $responses = array_unique($responses);
668 foreach ($responses as $response) {
669 $responseoptions[htmlspecialchars(trim($response))] = $response;
672 if (isset($USER->modattempts[$lesson->id])) {
673 $useranswers = explode(',', $attempt->useranswer);
674 $t = 0;
676 foreach ($answers as $answer) {
677 if ($answer->response != NULL) {
678 echo '<tr><td align="right">';
679 echo "<b><label for=\"menuresponse[$answer->id]\">".
680 format_text($answer->answer,FORMAT_MOODLE,$options).
681 '</label>: </b></td><td valign="bottom">';
683 if (isset($USER->modattempts[$lesson->id])) {
684 $selected = htmlspecialchars(trim($answers[$useranswers[$t]]->response)); // gets the user's previous answer
685 choose_from_menu ($responseoptions, "response[$answer->id]", $selected);
686 $t++;
687 } else {
688 choose_from_menu ($responseoptions, "response[$answer->id]");
690 echo '</td></tr>';
691 if ($answer != end($answers)) {
692 echo '<tr><td><br /></td></tr>';
696 echo '</table>';
697 print_simple_box_end();
698 lesson_print_submit_link(get_string('pleasematchtheabovepairs', 'lesson'), 'answerform');
699 break;
700 case LESSON_BRANCHTABLE :
701 $options = new stdClass;
702 $options->para = false;
703 $buttons = array();
704 $i = 0;
705 foreach ($answers as $answer) {
706 // Each button must have its own form inorder for it to work with JavaScript turned off
707 $button = "<form id=\"answerform$i\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/lesson.php\">\n".
708 '<div>'.
709 "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n".
710 "<input type=\"hidden\" name=\"action\" value=\"continue\" />\n".
711 "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />\n".
712 "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n".
713 "<input type=\"hidden\" name=\"jumpto\" value=\"$answer->jumpto\" />\n".
714 lesson_print_submit_link(strip_tags(format_text($answer->answer, FORMAT_MOODLE, $options)), "answerform$i", '', '', '', '', true).
715 '</div>'.
716 '</form>';
718 $buttons[] = $button;
719 $i++;
722 /// Set the orientation
723 if ($page->layout) {
724 $orientation = 'horizontal';
725 } else {
726 $orientation = 'vertical';
729 $fullbuttonhtml = "\n<div class=\"branchbuttoncontainer $orientation\">\n" .
730 implode("\n", $buttons).
731 "\n</div>\n";
733 if ($lesson->slideshow) {
734 $options = new stdClass;
735 $options->noclean = true;
736 echo '<div class="contents">'.format_text($page->contents, FORMAT_MOODLE, $options)."</div>\n";
737 echo '</div><!--end slideshow div-->';
738 echo $fullbuttonhtml;
739 } else {
740 echo $fullbuttonhtml;
743 break;
744 case LESSON_ESSAY :
745 if (isset($USER->modattempts[$lesson->id])) {
746 $essayinfo = unserialize($attempt->useranswer);
747 $value = s(stripslashes_safe($essayinfo->answer));
748 } else {
749 $value = "";
751 echo '<tr><td style="text-align:center;" valign="top" nowrap="nowrap"><label for="answer">'.get_string("youranswer", "lesson").'</label>:</td><td>'.
752 '<textarea id="answer" name="answer" rows="15" cols="60">'.$value."</textarea>\n";
753 echo '</td></tr></table>';
754 print_simple_box_end();
755 lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
756 break;
757 default: // close the tags MDL-7861
758 echo ('</table>');
759 print_simple_box_end();
760 break;
762 if ($page->qtype != LESSON_BRANCHTABLE) { // To fix XHTML problem (BT have their own forms)
763 echo '</fieldset>';
764 echo "</form>\n";
766 } else {
767 // a page without answers - find the next (logical) page
768 echo "<form id=\"pageform\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/view.php\">\n";
769 echo '<div>';
770 echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
771 if ($lesson->nextpagedefault) {
772 // in Flash Card mode...
773 // ...first get number of retakes
774 $nretakes = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
775 // ...then get the page ids (lessonid the 5th param is needed to make get_records play)
776 $allpages = get_records("lesson_pages", "lessonid", $lesson->id, "id", "id,lessonid");
777 shuffle ($allpages);
778 $found = false;
779 if ($lesson->nextpagedefault == LESSON_UNSEENPAGE) {
780 foreach ($allpages as $thispage) {
781 if (!count_records("lesson_attempts", "pageid", $thispage->id, "userid",
782 $USER->id, "retry", $nretakes)) {
783 $found = true;
784 break;
787 } elseif ($lesson->nextpagedefault == LESSON_UNANSWEREDPAGE) {
788 foreach ($allpages as $thispage) {
789 if (!count_records_select("lesson_attempts", "pageid = $thispage->id AND
790 userid = $USER->id AND correct = 1 AND retry = $nretakes")) {
791 $found = true;
792 break;
796 if ($found) {
797 $newpageid = $thispage->id;
798 if ($lesson->maxpages) {
799 // check number of pages viewed (in the lesson)
800 if (count_records("lesson_attempts", "lessonid", $lesson->id, "userid", $USER->id,
801 "retry", $nretakes) >= $lesson->maxpages) {
802 $newpageid = LESSON_EOL;
805 } else {
806 $newpageid = LESSON_EOL;
808 } else {
809 // in normal lesson mode...
810 if (!$newpageid = get_field("lesson_pages", "nextpageid", "id", $pageid)) {
811 // this is the last page - flag end of lesson
812 $newpageid = LESSON_EOL;
815 echo "<input type=\"hidden\" name=\"pageid\" value=\"$newpageid\" />\n";
816 lesson_print_submit_link(get_string('continue', 'lesson'), 'pageform');
817 echo '</div>';
818 echo "</form>\n";
821 // Finish of the page
822 lesson_print_progress_bar($lesson, $course);
823 require($CFG->dirroot.'/mod/lesson/viewend.html');
824 } else {
825 // end of lesson reached work out grade
827 // Used to check to see if the student ran out of time
828 $outoftime = optional_param('outoftime', '', PARAM_ALPHA);
830 // Update the clock / get time information for this user
831 if (!has_capability('mod/lesson:manage', $context)) {
832 unset($USER->startlesson[$lesson->id]);
833 if (!$timer = get_records_select('lesson_timer', "lessonid = $lesson->id AND userid = $USER->id", 'starttime')) {
834 error('Error: could not find records');
835 } else {
836 $timer = array_pop($timer); // this will get the latest start time record
838 $timer->lessontime = time();
840 if (!update_record("lesson_timer", $timer)) {
841 error("Error: could not update lesson_timer table");
845 add_to_log($course->id, "lesson", "end", "view.php?id=$cm->id", "$lesson->id", $cm->id);
847 lesson_print_header($cm, $course, $lesson, 'view');
848 print_heading(get_string("congratulations", "lesson"));
849 print_simple_box_start("center");
850 $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
851 if (isset($USER->modattempts[$lesson->id])) {
852 $ntries--; // need to look at the old attempts :)
854 if (!has_capability('mod/lesson:manage', $context)) {
856 $gradeinfo = lesson_grade($lesson, $ntries);
858 if ($gradeinfo->attempts) {
859 if (!$lesson->custom) {
860 echo "<p style=\"text-align:center;\">".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
861 "</p>\n";
862 if ($lesson->minquestions) {
863 if ($gradeinfo->nquestions < $lesson->minquestions) {
864 // print a warning and set nviewed to minquestions
865 echo "<p style=\"text-align:center;\">".get_string("youshouldview", "lesson",
866 $lesson->minquestions)."</p>\n";
869 echo "<p style=\"text-align:center;\">".get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned).
870 "</p>\n";
872 $a = new stdClass;
873 $a->score = $gradeinfo->earned;
874 $a->grade = $gradeinfo->total;
875 if ($gradeinfo->nmanual) {
876 $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
877 $a->essayquestions = $gradeinfo->nmanual;
878 echo "<div style=\"text-align:center;\">".get_string("displayscorewithessays", "lesson", $a)."</div>";
879 } else {
880 echo "<div style=\"text-align:center;\">".get_string("displayscorewithoutessays", "lesson", $a)."</div>";
882 $a = new stdClass;
883 $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
884 $a->total = $lesson->grade;
885 echo "<p style=\"text-align:center;\">".get_string('yourcurrentgradeisoutof', 'lesson', $a)."</p>\n";
887 $grade->lessonid = $lesson->id;
888 $grade->userid = $USER->id;
889 $grade->grade = $gradeinfo->grade;
890 $grade->completed = time();
891 if (!$lesson->practice) {
892 if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
893 if (!$grades = get_records_select("lesson_grades", "lessonid = $lesson->id and userid = $USER->id", "completed")) {
894 error("Could not find Grade Records");
896 $oldgrade = end($grades);
897 $grade->id = $oldgrade->id;
898 if (!$update = update_record("lesson_grades", $grade)) {
899 error("Navigation: grade not updated");
901 } else {
902 if (!$newgradeid = insert_record("lesson_grades", $grade)) {
903 error("Navigation: grade not inserted");
906 } else {
907 if (!delete_records("lesson_attempts", "lessonid", $lesson->id, "userid", $USER->id, "retry", $ntries)) {
908 error("Could not delete lesson attempts");
911 } else {
912 if ($lesson->timed) {
913 if ($outoftime == 'normal') {
914 $grade = new stdClass;
915 $grade->lessonid = $lesson->id;
916 $grade->userid = $USER->id;
917 $grade->grade = 0;
918 $grade->completed = time();
919 if (!$lesson->practice) {
920 if (!$newgradeid = insert_record("lesson_grades", $grade)) {
921 error("Navigation: grade not inserted");
924 echo get_string("eolstudentoutoftimenoanswers", "lesson");
926 } else {
927 echo get_string("welldone", "lesson");
931 // update central gradebook
932 lesson_update_grades($lesson, $USER->id);
934 } else {
935 // display for teacher
936 echo "<p style=\"text-align:center;\">".get_string("displayofgrade", "lesson")."</p>\n";
938 print_simple_box_end(); //End of Lesson button to Continue.
940 // after all the grade processing, check to see if "Show Grades" is off for the course
941 // if yes, redirect to the course page
942 if (!$course->showgrades) {
943 redirect($CFG->wwwroot.'/course/view.php?id='.$course->id);
946 // high scores code
947 if ($lesson->highscores && !has_capability('mod/lesson:manage', $context) && !$lesson->practice) {
948 echo "<div style=\"text-align:center;\"><br />";
949 if ($grades = get_records_select("lesson_grades", "lessonid = $lesson->id", "completed")) {
950 $madeit = false;
951 if ($highscores = get_records_select("lesson_high_scores", "lessonid = $lesson->id")) {
952 // get all the high scores into an array
953 $topscores = array();
954 $uniquescores = array();
955 foreach ($highscores as $highscore) {
956 $grade = $grades[$highscore->gradeid]->grade;
957 $topscores[] = $grade;
958 $uniquescores[$grade] = 1;
960 // sort to find the lowest score
961 sort($topscores);
962 $lowscore = $topscores[0];
964 if ($gradeinfo->grade >= $lowscore || count($uniquescores) <= $lesson->maxhighscores) {
965 $madeit = true;
968 if (!$highscores or $madeit) {
969 echo '<p>'.get_string("youmadehighscore", "lesson", $lesson->maxhighscores).
970 '</p>
971 <form method="post" id="highscores" action="'.$CFG->wwwroot.'/mod/lesson/highscores.php">
972 <div>
973 <input type="hidden" name="mode" value="add" />
974 <input type="hidden" name="id" value="'.$cm->id.'" />
975 <input type="hidden" name="sesskey" value="'.sesskey().'" />
976 <p>';
977 lesson_print_submit_link(get_string('clicktopost', 'lesson'), 'highscores');
978 echo '</p>
979 </div>
980 </form>';
981 } else {
982 echo get_string("nothighscore", "lesson", $lesson->maxhighscores)."<br />";
985 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>';
986 echo "</div>";
989 if ($lesson->modattempts && !has_capability('mod/lesson:manage', $context)) {
990 // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
991 // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
992 // to pass to view again. This is slick cause it wont call the empty($pageid) code
993 // $ntries is decremented above
994 if (!$attempts = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries", "timeseen")) {
995 $attempts = array();
997 $firstattempt = current($attempts);
998 $pageid = $firstattempt->pageid;
999 // IF the student wishes to review, need to know the last question page that the student answered. This will help to make
1000 // sure that the student can leave the lesson via pushing the continue button.
1001 $lastattempt = end($attempts);
1002 $USER->modattempts[$lesson->id] = $lastattempt->pageid;
1003 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";
1004 } elseif ($lesson->modattempts && has_capability('mod/lesson:manage', $context)) {
1005 echo "<p style=\"text-align:center;\">".get_string("modattemptsnoteacher", "lesson")."</p>";
1008 if ($lesson->activitylink) {
1009 if ($module = get_record('course_modules', 'id', $lesson->activitylink)) {
1010 if ($modname = get_field('modules', 'name', 'id', $module->module))
1011 if ($instance = get_record($modname, 'id', $module->instance)) {
1012 echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\">".
1013 "<a href=\"$CFG->wwwroot/mod/$modname/view.php?id=$lesson->activitylink\">".
1014 get_string('activitylinkname', 'lesson', $instance->name)."</a></div>\n";
1019 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";
1020 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";
1023 /// Finish the page
1024 print_footer($course);