MDL-10240:
[moodle-linuxchix.git] / mod / lesson / view.php
blobc56ab0d86b07a3b61d254e6713dce59e93251d8d
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);
20 list($cm, $course, $lesson) = lesson_get_basics($id);
22 require_login($course->id, false, $cm);
24 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
26 /// Check these for students only TODO: Find a better method for doing this!
27 /// Check lesson availability
28 /// Check for password
29 /// Check dependencies
30 /// Check for high scores
31 if (!has_capability('mod/lesson:manage', $context)) {
33 if (time() < $lesson->available or time() > $lesson->deadline) { // Deadline restrictions
34 if (time() > $lesson->deadline) {
35 $message = get_string('lessonclosed', 'lesson', userdate($lesson->deadline));
36 } else {
37 $message = get_string('lessonopen', 'lesson', userdate($lesson->available));
40 lesson_print_header($cm, $course, $lesson);
41 print_simple_box_start('center');
42 echo '<div style="text-align:center;">';
43 echo '<p>'.$message.'</p>';
44 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>';
45 echo '</div>';
46 print_simple_box_end();
47 print_footer($course);
48 exit();
50 } else if ($lesson->usepassword and empty($USER->lessonloggedin[$lesson->id])) { // Password protected lesson code
51 $correctpass = false;
52 if ($password = optional_param('userpassword', '', PARAM_CLEAN)) {
53 if ($lesson->password == md5(trim($password))) {
54 $USER->lessonloggedin[$lesson->id] = true;
55 $correctpass = true;
56 if ($lesson->highscores) {
57 // Logged in - redirect so we go through all of these checks before starting the lesson.
58 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
63 if (!$correctpass) {
64 lesson_print_header($cm, $course, $lesson);
65 echo "<div class=\"password-form\">\n";
66 print_simple_box_start('center');
67 echo '<form id="password" method="post" action="'.$CFG->wwwroot.'/mod/lesson/view.php" autocomplete="off">' . "\n";
68 echo '<fieldset class="invisiblefieldset">';
69 echo '<input type="hidden" name="id" value="'. $cm->id .'" />' . "\n";
70 if (optional_param('userpassword', 0, PARAM_CLEAN)) {
71 notify(get_string('loginfail', 'lesson'));
74 echo get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name))."<br /><br />\n".
75 get_string('enterpassword', 'lesson')." <input type=\"password\" name=\"userpassword\" /><br /><br />\n<center>".
76 '<span class="lessonbutton standardbutton"><a href="'.$CFG->wwwroot.'/course/view.php?id='. $course->id .'">'. get_string('cancel', 'lesson') .'</a></span> ';
78 lesson_print_submit_link(get_string('continue', 'lesson'), 'password', 'center', 'standardbutton submitbutton');
79 echo '</fieldset></form>';
80 print_simple_box_end();
81 echo "</div>\n";
82 print_footer($course);
83 exit();
86 } else if ($lesson->dependency) { // check for dependencies
87 if ($dependentlesson = get_record('lesson', 'id', $lesson->dependency)) {
88 // lesson exists, so we can proceed
89 $conditions = unserialize($lesson->conditions);
90 // assume false for all
91 $timespent = false;
92 $completed = false;
93 $gradebetterthan = false;
94 // check for the timespent condition
95 if ($conditions->timespent) {
96 if ($attempttimes = get_records_select('lesson_timer', "userid = $USER->id AND lessonid = $dependentlesson->id")) {
97 // go through all the times and test to see if any of them satisfy the condition
98 foreach($attempttimes as $attempttime) {
99 $duration = $attempttime->lessontime - $attempttime->starttime;
100 if ($conditions->timespent < $duration/60) {
101 $timespent = true;
105 } else {
106 $timespent = true; // there isn't one set
109 // check for the gradebetterthan condition
110 if($conditions->gradebetterthan) {
111 if ($studentgrades = get_records_select('lesson_grades', "userid = $USER->id AND lessonid = $dependentlesson->id")) {
112 // go through all the grades and test to see if any of them satisfy the condition
113 foreach($studentgrades as $studentgrade) {
114 if ($studentgrade->grade >= $conditions->gradebetterthan) {
115 $gradebetterthan = true;
119 } else {
120 $gradebetterthan = true; // there isn't one set
123 // check for the completed condition
124 if ($conditions->completed) {
125 if (count_records('lesson_grades', 'userid', $USER->id, 'lessonid', $dependentlesson->id)) {
126 $completed = true;
128 } else {
129 $completed = true; // not set
132 $errors = array();
133 // collect all of our error statements
134 if (!$timespent) {
135 $errors[] = get_string('timespenterror', 'lesson', $conditions->timespent);
137 if (!$completed) {
138 $errors[] = get_string('completederror', 'lesson');
140 if (!$gradebetterthan) {
141 $errors[] = get_string('gradebetterthanerror', 'lesson', $conditions->gradebetterthan);
143 if (!empty($errors)) { // print out the errors if any
144 lesson_print_header($cm, $course, $lesson);
145 echo '<p>';
146 print_simple_box_start('center');
147 print_string('completethefollowingconditions', 'lesson', $dependentlesson->name);
148 echo '<p style="text-align:center;">'.implode('<br />'.get_string('and', 'lesson').'<br />', $errors).'</p>';
149 print_simple_box_end();
150 echo '</p>';
151 print_footer($course);
152 exit();
156 } else if ($lesson->highscores and !$lesson->practice and !optional_param('viewed', 0) and empty($pageid)) {
157 // Display high scores before starting lesson
158 redirect("$CFG->wwwroot/mod/lesson/highscores.php?id=$cm->id");
162 // set up some general variables
163 $path = $CFG->wwwroot .'/course';
165 // this is called if a student leaves during a lesson
166 if($pageid == LESSON_UNSEENBRANCHPAGE) {
167 $pageid = lesson_unseen_question_jump($lesson->id, $USER->id, $pageid);
170 // display individual pages and their sets of answers
171 // if pageid is EOL then the end of the lesson has been reached
172 // for flow, changed to simple echo for flow styles, michaelp, moved lesson name and page title down
173 $attemptflag = false;
174 if (empty($pageid)) {
175 // make sure there are pages to view
176 if (!get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0)) {
177 if (!has_capability('mod/lesson:manage', $context)) {
178 lesson_set_message(get_string('lessonnotready', 'lesson', $course->teacher)); // a nice message to the student
179 } else {
180 if (!count_records('lesson_pages', 'lessonid', $lesson->id)) {
181 redirect("$CFG->wwwroot/mod/lesson/edit.php?id=$cm->id"); // no pages - redirect to add pages
182 } else {
183 lesson_set_message(get_string('lessonpagelinkingbroken', 'lesson')); // ok, bad mojo
188 add_to_log($course->id, 'lesson', 'start', 'view.php?id='. $cm->id, $lesson->id, $cm->id);
190 // if no pageid given see if the lesson has been started
191 if ($grades = get_records_select('lesson_grades', 'lessonid = '. $lesson->id .' AND userid = '. $USER->id,
192 'grade DESC')) {
193 $retries = count($grades);
194 } else {
195 $retries = 0;
197 if ($retries) {
198 $attemptflag = true;
201 if (isset($USER->modattempts[$lesson->id])) {
202 unset($USER->modattempts[$lesson->id]); // if no pageid, then student is NOT reviewing
205 // if there are any questions have been answered correctly in this attempt
206 if ($attempts = get_records_select('lesson_attempts',
207 "lessonid = $lesson->id AND userid = $USER->id AND retry = $retries AND
208 correct = 1", 'timeseen DESC')) {
210 foreach ($attempts as $attempt) {
211 $jumpto = get_field('lesson_answers', 'jumpto', 'id', $attempt->answerid);
212 // convert the jumpto to a proper page id
213 if ($jumpto == 0) { // unlikely value!
214 $lastpageseen = $attempt->pageid;
215 } elseif ($jumpto == LESSON_NEXTPAGE) {
216 if (!$lastpageseen = get_field('lesson_pages', 'nextpageid', 'id',
217 $attempt->pageid)) {
218 // no nextpage go to end of lesson
219 $lastpageseen = LESSON_EOL;
221 } else {
222 $lastpageseen = $jumpto;
224 break; // only look at the latest correct attempt
226 } else {
227 $attempts = NULL;
230 if ($branchtables = get_records_select('lesson_branch',
231 "lessonid = $lesson->id AND userid = $USER->id AND retry = $retries", 'timeseen DESC')) {
232 // in here, user has viewed a branch table
233 $lastbranchtable = current($branchtables);
234 if ($attempts != NULL) {
235 foreach($attempts as $attempt) {
236 if ($lastbranchtable->timeseen > $attempt->timeseen) {
237 // branch table was viewed later than the last attempt
238 $lastpageseen = $lastbranchtable->pageid;
240 break;
242 } else {
243 // hasnt answered any questions but has viewed a branch table
244 $lastpageseen = $lastbranchtable->pageid;
247 //if ($lastpageseen != $firstpageid) {
248 if (isset($lastpageseen) and count_records('lesson_attempts', 'lessonid', $lesson->id, 'userid', $USER->id, 'retry', $retries) > 0) {
249 // get the first page
250 if (!$firstpageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id,
251 'prevpageid', 0)) {
252 error('Navigation: first page not found');
254 lesson_print_header($cm, $course, $lesson);
255 if ($lesson->timed) {
256 if ($lesson->retake) {
257 print_simple_box('<p style="text-align:center;">'. get_string('leftduringtimed', 'lesson') .'</p>', 'center');
258 echo '<div style="text-align:center;" class="lessonbutton standardbutton">'.
259 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
260 get_string('continue', 'lesson').'</a></div>';
261 } else {
262 print_simple_box_start('center');
263 echo '<div style="text-align:center;">';
264 echo get_string('leftduringtimednoretake', 'lesson');
265 echo '<br /><br /><div class="lessonbutton standardbutton"><a href="../../course/view.php?id='. $course->id .'">'. get_string('returntocourse', 'lesson') .'</a></div>';
266 echo '</div>';
267 print_simple_box_end();
270 } else {
271 print_simple_box("<p style=\"text-align:center;\">".get_string('youhaveseen','lesson').'</p>',
272 "center");
274 echo '<div style="text-align:center;">';
275 echo '<span class="lessonbutton standardbutton">'.
276 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$lastpageseen.'&amp;startlastseen=yes">'.
277 get_string('yes').'</a></span>&nbsp;&nbsp;&nbsp;';
278 echo '<span class="lessonbutton standardbutton">'.
279 '<a href="view.php?id='.$cm->id.'&amp;pageid='.$firstpageid.'&amp;startlastseen=no">'.
280 get_string('no').'</a></div>';
281 echo '</span>';
283 print_footer($course);
284 exit();
287 if ($grades) {
288 foreach ($grades as $grade) {
289 $bestgrade = $grade->grade;
290 break;
292 if (!$lesson->retake) {
293 lesson_print_header($cm, $course, $lesson, 'view');
294 print_simple_box_start('center');
295 echo "<div style=\"text-align:center;\">";
296 echo get_string("noretake", "lesson");
297 echo "<br /><br /><div class=\"lessonbutton standardbutton\"><a href=\"../../course/view.php?id=$course->id\">".get_string('returntocourse', 'lesson').'</a></div>';
298 echo "</div>";
299 print_simple_box_end();
300 print_footer($course);
301 exit();
302 //redirect("../../course/view.php?id=$course->id", get_string("alreadytaken", "lesson"));
303 // allow student to retake course even if they have the maximum grade
304 // } elseif ($bestgrade == 100) {
305 // redirect("../../course/view.php?id=$course->id", get_string("maximumgradeachieved",
306 // "lesson"));
309 // start at the first page
310 if (!$pageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0)) {
311 error('Navigation: first page not found');
313 /// This is the code for starting a timed test
314 if(!isset($USER->startlesson[$lesson->id]) && !has_capability('mod/lesson:manage', $context)) {
315 $USER->startlesson[$lesson->id] = true;
316 $startlesson = new stdClass;
317 $startlesson->lessonid = $lesson->id;
318 $startlesson->userid = $USER->id;
319 $startlesson->starttime = time();
320 $startlesson->lessontime = time();
322 if (!insert_record('lesson_timer', $startlesson)) {
323 error('Error: could not insert row into lesson_timer table');
325 if ($lesson->timed) {
326 lesson_set_message(get_string('maxtimewarning', 'lesson', $lesson->maxtime), 'center');
330 if ($pageid != LESSON_EOL) {
331 /// This is the code updates the lessontime for a timed test
332 if ($startlastseen = optional_param('startlastseen', '', PARAM_ALPHA)) { /// this deletes old records not totally sure if this is necessary anymore
333 if ($startlastseen == 'no') {
334 if ($grades = get_records_select('lesson_grades', "lessonid = $lesson->id AND userid = $USER->id",
335 'grade DESC')) {
336 $retries = count($grades);
337 } else {
338 $retries = 0;
340 if (!delete_records('lesson_attempts', 'userid', $USER->id, 'lessonid', $lesson->id, 'retry', $retries)) {
341 error('Error: could not delete old attempts');
343 if (!delete_records('lesson_branch', 'userid', $USER->id, 'lessonid', $lesson->id, 'retry', $retries)) {
344 error('Error: could not delete old seen branches');
349 add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
351 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
352 error('Navigation: the page record not found');
355 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
356 if (!has_capability('mod/lesson:manage', $context)) {
357 // get new id
358 $pageid = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
359 // get new page info
360 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
361 error('Navigation: the page record not found');
363 add_to_log($course->id, 'lesson', 'view', 'view.php?id='. $cm->id, $pageid, $cm->id);
364 } else {
365 // get the next page
366 $pageid = $page->nextpageid;
367 if (!$page = get_record('lesson_pages', 'id', $pageid)) {
368 error('Navigation: the page record not found');
371 } elseif ($page->qtype == LESSON_ENDOFCLUSTER) { // Check for endofclusters
372 if ($page->nextpageid == 0) {
373 $nextpageid = LESSON_EOL;
374 } else {
375 $nextpageid = $page->nextpageid;
377 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$nextpageid");
378 } else if ($page->qtype == LESSON_ENDOFBRANCH) { // Check for endofbranches
379 if ($answers = get_records('lesson_answers', 'pageid', $page->id, 'id')) {
380 // print_heading(get_string('endofbranch', 'lesson'));
381 foreach ($answers as $answer) {
382 // just need the first answer
383 if ($answer->jumpto == LESSON_RANDOMBRANCH) {
384 $answer->jumpto = lesson_unseen_branch_jump($lesson->id, $USER->id);
385 } elseif ($answer->jumpto == LESSON_CLUSTERJUMP) {
386 if (!has_capability('mod/lesson:manage', $context)) {
387 $answer->jumpto = lesson_cluster_jump($lesson->id, $USER->id, $pageid);
388 } else {
389 if ($page->nextpageid == 0) {
390 $answer->jumpto = LESSON_EOL;
391 } else {
392 $answer->jumpto = $page->nextpageid;
395 } else if ($answer->jumpto == LESSON_NEXTPAGE) {
396 if ($page->nextpageid == 0) {
397 $answer->jumpto = LESSON_EOL;
398 } else {
399 $answer->jumpto = $page->nextpageid;
401 } else if ($answer->jumpto == 0) {
402 $answer->jumpto = $page->id;
403 } else if ($answer->jumpto == LESSON_PREVIOUSPAGE) {
404 $answer->jumpto = $page->prevpageid;
406 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=$answer->jumpto");
407 break;
409 } else {
410 error('Navigation: No answers on EOB');
414 // check to see if the user can see the left menu
415 if (!has_capability('mod/lesson:manage', $context)) {
416 $lesson->displayleft = lesson_displayleftif($lesson);
419 // This is where several messages (usually warnings) are displayed
420 // all of this is displayed above the actual page
422 // clock code
423 // get time information for this user
424 $timer = new stdClass;
425 if(!has_capability('mod/lesson:manage', $context)) {
426 if (!$timer = get_records_select('lesson_timer', "lessonid = $lesson->id AND userid = $USER->id", 'starttime')) {
427 error('Error: could not find records');
428 } else {
429 $timer = array_pop($timer); // this will get the latest start time record
433 $startlastseen = optional_param('startlastseen', '', PARAM_ALPHA);
434 if ($startlastseen == 'yes') { // continue a previous test, need to update the clock (think this option is disabled atm)
435 $timer->starttime = time() - ($timer->lessontime - $timer->starttime);
436 $timer->lessontime = time();
437 } else if ($startlastseen == 'no') { // starting over
438 // starting over, so reset the clock
439 $timer->starttime = time();
440 $timer->lessontime = time();
443 // for timed lessons, display clock
444 if ($lesson->timed) {
445 if(has_capability('mod/lesson:manage', $context)) {
446 lesson_set_message(get_string('teachertimerwarning', 'lesson'));
447 } else {
448 if ((($timer->starttime + $lesson->maxtime * 60) - time()) <= 0) {
449 lesson_set_message(get_string('eolstudentoutoftime', 'lesson'));
450 redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id&amp;pageid=".LESSON_EOL."&amp;outoftime=normal", get_string("outoftime", "lesson"));
452 // update clock when viewing a new page... no special treatment
453 if ((($timer->starttime + $lesson->maxtime * 60) - time()) < 60) {
454 lesson_set_message(get_string('studentoneminwarning', 'lesson'));
459 // update the clock
460 if (!has_capability('mod/lesson:manage', $context)) {
461 $timer->lessontime = time();
462 if (!update_record('lesson_timer', $timer)) {
463 error('Error: could not update lesson_timer table');
467 /// This is the warning msg for teachers to inform them that cluster and unseen does not work while logged in as a teacher
468 if(has_capability('mod/lesson:manage', $context)) {
469 if (lesson_display_teacher_warning($lesson->id)) {
470 $warningvars->cluster = get_string('clusterjump', 'lesson');
471 $warningvars->unseen = get_string('unseenpageinbranch', 'lesson');
472 lesson_set_message(get_string('teacherjumpwarning', 'lesson', $warningvars));
476 if ($page->qtype == LESSON_BRANCHTABLE) {
477 if ($lesson->minquestions and !has_capability('mod/lesson:manage', $context)) {
478 // tell student how many questions they have seen, how many are required and their grade
479 $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
481 $gradeinfo = lesson_grade($lesson, $ntries);
483 if ($gradeinfo->attempts) {
484 if ($gradeinfo->nquestions < $lesson->minquestions) {
485 $a = new stdClass;
486 $a->nquestions = $gradeinfo->nquestions;
487 $a->minquestions = $lesson->minquestions;
488 lesson_set_message(get_string('numberofpagesviewednotice', 'lesson', $a));
490 lesson_set_message(get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned), 'notify');
491 $a = new stdClass;
492 $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
493 $a->total = $lesson->grade;
494 lesson_set_message(get_string('yourcurrentgradeisoutof', 'lesson', $a), 'notify');
499 $PAGE = page_create_instance($lesson->id);
500 $PAGE->set_lessonpageid($page->id);
501 $pageblocks = blocks_setup($PAGE);
503 $leftcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
504 $rightcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210);
506 if (($edit != -1) and $PAGE->user_allowed_editing()) {
507 $USER->editing = $edit;
510 /// Print the page header, heading and tabs
511 $PAGE->print_header();
512 require($CFG->dirroot.'/mod/lesson/viewstart.html');
514 // now starting to print the page's contents
515 if ($page->qtype == LESSON_BRANCHTABLE) {
516 print_heading(format_string($page->title));
517 } else {
518 $lesson->slideshow = false; // turn off slide show for all pages other than LESSON_BRANTCHTABLE
521 if (!$lesson->slideshow) {
522 $options = new stdClass;
523 $options->noclean = true;
524 print_simple_box('<div class="contents">'.
525 format_text($page->contents, FORMAT_MOODLE, $options).
526 '</div>', 'center');
529 // this is for modattempts option. Find the users previous answer to this page,
530 // and then display it below in answer processing
531 if (isset($USER->modattempts[$lesson->id])) {
532 $retries = count_records('lesson_grades', "lessonid", $lesson->id, "userid", $USER->id);
533 $retries--;
534 if (! $attempts = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND pageid = $page->id AND retry = $retries", "timeseen")) {
535 error("Previous attempt record could not be found!");
537 $attempt = end($attempts);
540 // get the answers in a set order, the id order
541 if ($answers = get_records("lesson_answers", "pageid", $page->id, "id")) {
542 if ($page->qtype != LESSON_BRANCHTABLE) { // To fix XHTML problem (BT have their own forms)
543 echo "<form id=\"answerform\" method =\"post\" action=\"lesson.php\" autocomplete=\"off\">";
544 echo '<fieldset class="invisiblefieldset">';
545 echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />";
546 echo "<input type=\"hidden\" name=\"action\" value=\"continue\" />";
547 echo "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />";
548 echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />";
549 print_simple_box_start("center");
550 echo '<table width="100%">';
552 // default format text options
553 $options = new stdClass;
554 $options->para = false; // no <p></p>
555 $options->noclean = true;
556 // echo "qtype is $page->qtype"; // debug
557 switch ($page->qtype) {
558 case LESSON_SHORTANSWER :
559 case LESSON_NUMERICAL :
560 if (isset($USER->modattempts[$lesson->id])) {
561 $value = 'value="'.s($attempt->useranswer).'"';
562 } else {
563 $value = "";
565 echo '<tr><td style="text-align:center;"><label for="answer">'.get_string('youranswer', 'lesson').'</label>'.
566 ": <input type=\"text\" id=\"answer\" name=\"answer\" size=\"50\" maxlength=\"200\" $value />\n";
567 echo '</td></tr></table>';
568 print_simple_box_end();
569 lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
570 break;
571 case LESSON_TRUEFALSE :
572 shuffle($answers);
573 $i = 0;
574 foreach ($answers as $answer) {
575 echo '<tr><td valign="top">';
576 if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
577 $checked = 'checked="checked"';
578 } else {
579 $checked = '';
581 echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\" $checked />";
582 echo "</td><td>";
583 echo "<label for=\"answerid$i\">".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
584 echo '</td></tr>';
585 if ($answer != end($answers)) {
586 echo "<tr><td><br /></td></tr>";
588 $i++;
590 echo '</table>';
591 print_simple_box_end();
592 lesson_print_submit_link(get_string('pleasecheckoneanswer', 'lesson'), 'answerform');
593 break;
594 case LESSON_MULTICHOICE :
595 $i = 0;
596 shuffle($answers);
598 foreach ($answers as $answer) {
599 echo '<tr><td valign="top">';
600 if ($page->qoption) {
601 $checked = '';
602 if (isset($USER->modattempts[$lesson->id])) {
603 $answerids = explode(",", $attempt->useranswer);
604 if (in_array($answer->id, $answerids)) {
605 $checked = ' checked="checked"';
606 } else {
607 $checked = '';
610 // more than one answer allowed
611 echo "<input type=\"checkbox\" id=\"answerid$i\" name=\"answer[$i]\" value=\"{$answer->id}\"$checked />";
612 } else {
613 if (isset($USER->modattempts[$lesson->id]) && $answer->id == $attempt->answerid) {
614 $checked = ' checked="checked"';
615 } else {
616 $checked = '';
618 // only one answer allowed
619 echo "<input type=\"radio\" id=\"answerid$i\" name=\"answerid\" value=\"{$answer->id}\"$checked />";
621 echo '</td><td>';
622 echo "<label for=\"answerid$i\" >".format_text(trim($answer->answer), FORMAT_MOODLE, $options).'</label>';
623 echo '</td></tr>';
624 if ($answer != end($answers)) {
625 echo '<tr><td><br /></td></tr>';
627 $i++;
629 echo '</table>';
630 print_simple_box_end();
631 if ($page->qoption) {
632 $linkname = get_string('pleasecheckoneormoreanswers', 'lesson');
633 } else {
634 $linkname = get_string('pleasecheckoneanswer', 'lesson');
636 lesson_print_submit_link($linkname, 'answerform');
637 break;
639 case LESSON_MATCHING :
640 echo '<tr><td><table width="100%">';
641 // don't suffle answers (could be an option??)
642 foreach ($answers as $answer) {
643 // get all the response
644 if ($answer->response != NULL) {
645 $responses[] = trim($answer->response);
649 $responseoptions = array();
650 if (!empty($responses)) {
651 shuffle($responses);
652 $responses = array_unique($responses);
653 foreach ($responses as $response) {
654 $responseoptions[htmlspecialchars(trim($response))] = $response;
657 if (isset($USER->modattempts[$lesson->id])) {
658 $useranswers = explode(',', $attempt->useranswer);
659 $t = 0;
661 foreach ($answers as $answer) {
662 if ($answer->response != NULL) {
663 echo '<tr><td align="right">';
664 echo "<b><label for=\"menuresponse[$answer->id]\">".
665 format_text($answer->answer,FORMAT_MOODLE,$options).
666 '</label>: </b></td><td valign="bottom">';
668 if (isset($USER->modattempts[$lesson->id])) {
669 $selected = htmlspecialchars(trim($answers[$useranswers[$t]]->response)); // gets the user's previous answer
670 choose_from_menu ($responseoptions, "response[$answer->id]", $selected);
671 $t++;
672 } else {
673 choose_from_menu ($responseoptions, "response[$answer->id]");
675 echo '</td></tr>';
676 if ($answer != end($answers)) {
677 echo '<tr><td><br /></td></tr>';
681 echo '</table></td></tr></table>';
682 print_simple_box_end();
683 lesson_print_submit_link(get_string('pleasematchtheabovepairs', 'lesson'), 'answerform');
684 break;
685 case LESSON_BRANCHTABLE :
686 $options = new stdClass;
687 $options->para = false;
688 $buttons = array();
689 $i = 0;
690 foreach ($answers as $answer) {
691 // Each button must have its own form inorder for it to work with JavaScript turned off
692 $button = "<form id=\"answerform$i\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/lesson.php\">\n".
693 '<div>'.
694 "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n".
695 "<input type=\"hidden\" name=\"action\" value=\"continue\" />\n".
696 "<input type=\"hidden\" name=\"pageid\" value=\"$pageid\" />\n".
697 "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n".
698 "<input type=\"hidden\" name=\"jumpto\" value=\"$answer->jumpto\" />\n".
699 lesson_print_submit_link(strip_tags(format_text($answer->answer, FORMAT_MOODLE, $options)), "answerform$i", '', '', '', '', true).
700 '</div>'.
701 '</form>';
703 $buttons[] = $button;
704 $i++;
707 /// Set the orientation
708 if ($page->layout) {
709 $orientation = 'horizontal';
710 } else {
711 $orientation = 'vertical';
714 $fullbuttonhtml = "\n<div class=\"branchbuttoncontainer $orientation\">\n" .
715 implode("\n", $buttons).
716 "\n</div>\n";
718 if ($lesson->slideshow) {
719 $options = new stdClass;
720 $options->noclean = true;
721 echo '<div class="contents">'.format_text($page->contents, FORMAT_MOODLE, $options)."</div>\n";
722 echo '</div><!--end slideshow div-->';
723 echo $fullbuttonhtml;
724 } else {
725 echo $fullbuttonhtml;
728 break;
729 case LESSON_ESSAY :
730 if (isset($USER->modattempts[$lesson->id])) {
731 $essayinfo = unserialize($attempt->useranswer);
732 $value = s(stripslashes_safe($essayinfo->answer));
733 } else {
734 $value = "";
736 echo '<tr><td style="text-align:center;" valign="top" nowrap="nowrap"><label for="answer">'.get_string("youranswer", "lesson").'</label>:</td><td>'.
737 '<textarea id="answer" name="answer" rows="15" cols="60">'.$value."</textarea>\n";
738 echo '</td></tr></table>';
739 print_simple_box_end();
740 lesson_print_submit_link(get_string('pleaseenteryouranswerinthebox', 'lesson'), 'answerform');
741 break;
742 default: // close the tags MDL-7861
743 echo ('</table>');
744 print_simple_box_end();
745 break;
747 if ($page->qtype != LESSON_BRANCHTABLE) { // To fix XHTML problem (BT have their own forms)
748 echo '</fieldset>';
749 echo "</form>\n";
751 } else {
752 // a page without answers - find the next (logical) page
753 echo "<form id=\"pageform\" method=\"post\" action=\"$CFG->wwwroot/mod/lesson/view.php\">\n";
754 echo '<div>';
755 echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
756 if ($lesson->nextpagedefault) {
757 // in Flash Card mode...
758 // ...first get number of retakes
759 $nretakes = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
760 // ...then get the page ids (lessonid the 5th param is needed to make get_records play)
761 $allpages = get_records("lesson_pages", "lessonid", $lesson->id, "id", "id,lessonid");
762 shuffle ($allpages);
763 $found = false;
764 if ($lesson->nextpagedefault == LESSON_UNSEENPAGE) {
765 foreach ($allpages as $thispage) {
766 if (!count_records("lesson_attempts", "pageid", $thispage->id, "userid",
767 $USER->id, "retry", $nretakes)) {
768 $found = true;
769 break;
772 } elseif ($lesson->nextpagedefault == LESSON_UNANSWEREDPAGE) {
773 foreach ($allpages as $thispage) {
774 if (!count_records_select("lesson_attempts", "pageid = $thispage->id AND
775 userid = $USER->id AND correct = 1 AND retry = $nretakes")) {
776 $found = true;
777 break;
781 if ($found) {
782 $newpageid = $thispage->id;
783 if ($lesson->maxpages) {
784 // check number of pages viewed (in the lesson)
785 if (count_records("lesson_attempts", "lessonid", $lesson->id, "userid", $USER->id,
786 "retry", $nretakes) >= $lesson->maxpages) {
787 $newpageid = LESSON_EOL;
790 } else {
791 $newpageid = LESSON_EOL;
793 } else {
794 // in normal lesson mode...
795 if (!$newpageid = get_field("lesson_pages", "nextpageid", "id", $pageid)) {
796 // this is the last page - flag end of lesson
797 $newpageid = LESSON_EOL;
800 echo "<input type=\"hidden\" name=\"pageid\" value=\"$newpageid\" />\n";
801 lesson_print_submit_link(get_string('continue', 'lesson'), 'pageform');
802 echo '</div>';
803 echo "</form>\n";
806 // Finish of the page
807 lesson_print_progress_bar($lesson, $course);
808 require($CFG->dirroot.'/mod/lesson/viewend.html');
809 } else {
810 // end of lesson reached work out grade
812 // Used to check to see if the student ran out of time
813 $outoftime = optional_param('outoftime', '', PARAM_ALPHA);
815 // Update the clock / get time information for this user
816 if (!has_capability('mod/lesson:manage', $context)) {
817 unset($USER->startlesson[$lesson->id]);
818 if (!$timer = get_records_select('lesson_timer', "lessonid = $lesson->id AND userid = $USER->id", 'starttime')) {
819 error('Error: could not find records');
820 } else {
821 $timer = array_pop($timer); // this will get the latest start time record
823 $timer->lessontime = time();
825 if (!update_record("lesson_timer", $timer)) {
826 error("Error: could not update lesson_timer table");
830 add_to_log($course->id, "lesson", "end", "view.php?id=$cm->id", "$lesson->id", $cm->id);
832 lesson_print_header($cm, $course, $lesson, 'view');
833 print_heading(get_string("congratulations", "lesson"));
834 print_simple_box_start("center");
835 $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
836 if (isset($USER->modattempts[$lesson->id])) {
837 $ntries--; // need to look at the old attempts :)
839 if (!has_capability('mod/lesson:manage', $context)) {
841 $gradeinfo = lesson_grade($lesson, $ntries);
843 if ($gradeinfo->attempts) {
844 if (!$lesson->custom) {
845 echo "<p style=\"text-align:center;\">".get_string("numberofpagesviewed", "lesson", $gradeinfo->nquestions).
846 "</p>\n";
847 if ($lesson->minquestions) {
848 if ($gradeinfo->nquestions < $lesson->minquestions) {
849 // print a warning and set nviewed to minquestions
850 echo "<p style=\"text-align:center;\">".get_string("youshouldview", "lesson",
851 $lesson->minquestions)."</p>\n";
854 echo "<p style=\"text-align:center;\">".get_string("numberofcorrectanswers", "lesson", $gradeinfo->earned).
855 "</p>\n";
857 $a = new stdClass;
858 $a->score = $gradeinfo->earned;
859 $a->grade = $gradeinfo->total;
860 if ($gradeinfo->nmanual) {
861 $a->tempmaxgrade = $gradeinfo->total - $gradeinfo->manualpoints;
862 $a->essayquestions = $gradeinfo->nmanual;
863 echo "<div style=\"text-align:center;\">".get_string("displayscorewithessays", "lesson", $a)."</div>";
864 } else {
865 echo "<div style=\"text-align:center;\">".get_string("displayscorewithoutessays", "lesson", $a)."</div>";
867 $a = new stdClass;
868 $a->grade = number_format($gradeinfo->grade * $lesson->grade / 100, 1);
869 $a->total = $lesson->grade;
870 echo "<p style=\"text-align:center;\">".get_string('yourcurrentgradeisoutof', 'lesson', $a)."</p>\n";
872 $grade->lessonid = $lesson->id;
873 $grade->userid = $USER->id;
874 $grade->grade = $gradeinfo->grade;
875 $grade->completed = time();
876 if (!$lesson->practice) {
877 if (isset($USER->modattempts[$lesson->id])) { // if reviewing, make sure update old grade record
878 if (!$grades = get_records_select("lesson_grades", "lessonid = $lesson->id and userid = $USER->id", "completed")) {
879 error("Could not find Grade Records");
881 $oldgrade = end($grades);
882 $grade->id = $oldgrade->id;
883 if (!$update = update_record("lesson_grades", $grade)) {
884 error("Navigation: grade not updated");
886 } else {
887 if (!$newgradeid = insert_record("lesson_grades", $grade)) {
888 error("Navigation: grade not inserted");
891 } else {
892 if (!delete_records("lesson_attempts", "lessonid", $lesson->id, "userid", $USER->id, "retry", $ntries)) {
893 error("Could not delete lesson attempts");
896 } else {
897 if ($lesson->timed) {
898 if ($outoftime == 'normal') {
899 $grade = new stdClass;
900 $grade->lessonid = $lesson->id;
901 $grade->userid = $USER->id;
902 $grade->grade = 0;
903 $grade->completed = time();
904 if (!$lesson->practice) {
905 if (!$newgradeid = insert_record("lesson_grades", $grade)) {
906 error("Navigation: grade not inserted");
909 echo get_string("eolstudentoutoftimenoanswers", "lesson");
911 } else {
912 echo get_string("welldone", "lesson");
916 // update central gradebook
917 lesson_update_grades($lesson, $USER->id);
919 } else {
920 // display for teacher
921 echo "<p style=\"text-align:center;\">".get_string("displayofgrade", "lesson")."</p>\n";
923 print_simple_box_end(); //End of Lesson button to Continue.
925 // after all the grade processing, check to see if "Show Grades" is off for the course
926 // if yes, redirect to the course page
927 if (!$course->showgrades) {
928 redirect($CFG->wwwroot.'/course/view.php?id='.$course->id);
931 // high scores code
932 if ($lesson->highscores && !has_capability('mod/lesson:manage', $context) && !$lesson->practice) {
933 echo "<div style=\"text-align:center;\"><br />";
934 if ($grades = get_records_select("lesson_grades", "lessonid = $lesson->id", "completed")) {
935 $madeit = false;
936 if ($highscores = get_records_select("lesson_high_scores", "lessonid = $lesson->id")) {
937 // get all the high scores into an array
938 $topscores = array();
939 $uniquescores = array();
940 foreach ($highscores as $highscore) {
941 $grade = $grades[$highscore->gradeid]->grade;
942 $topscores[] = $grade;
943 $uniquescores[$grade] = 1;
945 // sort to find the lowest score
946 sort($topscores);
947 $lowscore = $topscores[0];
949 if ($gradeinfo->grade >= $lowscore || count($uniquescores) <= $lesson->maxhighscores) {
950 $madeit = true;
953 if (!$highscores or $madeit) {
954 echo '<p>'.get_string("youmadehighscore", "lesson", $lesson->maxhighscores).
955 '</p>
956 <form method="post" id="highscores" action="'.$CFG->wwwroot.'/mod/lesson/highscores.php">
957 <div>
958 <input type="hidden" name="mode" value="add" />
959 <input type="hidden" name="id" value="'.$cm->id.'" />
960 <input type="hidden" name="sesskey" value="'.sesskey().'" />
961 <p>';
962 lesson_print_submit_link(get_string('clicktopost', 'lesson'), 'highscores');
963 echo '</p>
964 </div>
965 </form>';
966 } else {
967 echo get_string("nothighscore", "lesson", $lesson->maxhighscores)."<br />";
970 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>';
971 echo "</div>";
974 if ($lesson->modattempts && !has_capability('mod/lesson:manage', $context)) {
975 // make sure if the student is reviewing, that he/she sees the same pages/page path that he/she saw the first time
976 // look at the attempt records to find the first QUESTION page that the user answered, then use that page id
977 // to pass to view again. This is slick cause it wont call the empty($pageid) code
978 // $ntries is decremented above
979 if (!$attempts = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries", "timeseen")) {
980 $attempts = array();
982 $firstattempt = current($attempts);
983 $pageid = $firstattempt->pageid;
984 // IF the student wishes to review, need to know the last question page that the student answered. This will help to make
985 // sure that the student can leave the lesson via pushing the continue button.
986 $lastattempt = end($attempts);
987 $USER->modattempts[$lesson->id] = $lastattempt->pageid;
988 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";
989 } elseif ($lesson->modattempts && has_capability('mod/lesson:manage', $context)) {
990 echo "<p style=\"text-align:center;\">".get_string("modattemptsnoteacher", "lesson")."</p>";
993 if ($lesson->activitylink) {
994 if ($module = get_record('course_modules', 'id', $lesson->activitylink)) {
995 if ($modname = get_field('modules', 'name', 'id', $module->module))
996 if ($instance = get_record($modname, 'id', $module->instance)) {
997 echo "<div style=\"text-align:center; padding:5px;\" class=\"lessonbutton standardbutton\">".
998 "<a href=\"$CFG->wwwroot/mod/$modname/view.php?id=$lesson->activitylink\">".
999 get_string('activitylinkname', 'lesson', $instance->name)."</a></div>\n";
1004 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";
1005 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";
1008 /// Finish the page
1009 print_footer($course);