Fix a problem with glossary not being able to sort by firstname.
[moodle.git] / mod / lesson / locallib.php
CommitLineData
9fcf51d9 1<?php // $Id$
5491947a 2/**
3 * Local library file for Lesson. These are non-standard functions that are used
4 * only by Lesson.
5 *
6 * @version $Id$
7 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8 * @package lesson
9 **/
4b55d2af 10
11/**
12* Next page -> any page not seen before
13*/
5e7856af 14if (!defined("LESSON_UNSEENPAGE")) {
ac8e16be 15 define("LESSON_UNSEENPAGE", 1); // Next page -> any page not seen before
4b55d2af 16}
17/**
18* Next page -> any page not answered correctly
19*/
5e7856af 20if (!defined("LESSON_UNANSWEREDPAGE")) {
ac8e16be 21 define("LESSON_UNANSWEREDPAGE", 2); // Next page -> any page not answered correctly
4b55d2af 22}
5e7856af 23
4b55d2af 24/**
25* Define different lesson flows for next page
26*/
5e7856af 27$LESSON_NEXTPAGE_ACTION = array (0 => get_string("normal", "lesson"),
28 LESSON_UNSEENPAGE => get_string("showanunseenpage", "lesson"),
29 LESSON_UNANSWEREDPAGE => get_string("showanunansweredpage", "lesson") );
30
4b55d2af 31// Lesson jump types defined
32// TODO: instead of using define statements, create an array with all the jump values
5e7856af 33
4b55d2af 34/**
35 * Jump to Next Page
36 */
5e7856af 37if (!defined("LESSON_NEXTPAGE")) {
4b55d2af 38 define("LESSON_NEXTPAGE", -1);
39}
40/**
41 * End of Lesson
42 */
5e7856af 43if (!defined("LESSON_EOL")) {
4b55d2af 44 define("LESSON_EOL", -9);
45}
46/**
47 * Jump to an unseen page within a branch and end of branch or end of lesson
48 */
5e7856af 49if (!defined("LESSON_UNSEENBRANCHPAGE")) {
4b55d2af 50 define("LESSON_UNSEENBRANCHPAGE", -50);
51}
52/**
53 * Jump to Previous Page
54 */
5e7856af 55if (!defined("LESSON_PREVIOUSPAGE")) {
4b55d2af 56 define("LESSON_PREVIOUSPAGE", -40);
57}
58/**
59 * Jump to a random page within a branch and end of branch or end of lesson
60 */
5e7856af 61if (!defined("LESSON_RANDOMPAGE")) {
4b55d2af 62 define("LESSON_RANDOMPAGE", -60);
63}
64/**
65 * Jump to a random Branch
66 */
5e7856af 67if (!defined("LESSON_RANDOMBRANCH")) {
4b55d2af 68 define("LESSON_RANDOMBRANCH", -70);
69}
70/**
71 * Cluster Jump
72 */
5e7856af 73if (!defined("LESSON_CLUSTERJUMP")) {
4b55d2af 74 define("LESSON_CLUSTERJUMP", -80);
75}
76/**
77 * Undefined
78 */
5e7856af 79if (!defined("LESSON_UNDEFINED")) {
4b55d2af 80 define("LESSON_UNDEFINED", -99);
81}
82
83// Lesson question types defined
5e7856af 84
4b55d2af 85/**
86 * Short answer question type
87 */
5e7856af 88if (!defined("LESSON_SHORTANSWER")) {
89 define("LESSON_SHORTANSWER", "1");
90}
4b55d2af 91/**
92 * True/False question type
93 */
5e7856af 94if (!defined("LESSON_TRUEFALSE")) {
95 define("LESSON_TRUEFALSE", "2");
96}
4b55d2af 97/**
98 * Multichoice question type
99 *
100 * If you change the value of this then you need
101 * to change it in restorelib.php as well.
102 */
103if (!defined("LESSON_MULTICHOICE")) {
5e7856af 104 define("LESSON_MULTICHOICE", "3");
105}
4b55d2af 106/**
107 * Random question type - not used
108 */
5e7856af 109if (!defined("LESSON_RANDOM")) {
110 define("LESSON_RANDOM", "4");
111}
4b55d2af 112/**
113 * Matching question type
114 *
115 * If you change the value of this then you need
116 * to change it in restorelib.php, in mysql.php
117 * and postgres7.php as well.
118 */
119if (!defined("LESSON_MATCHING")) {
b9869082 120 define("LESSON_MATCHING", "5");
5e7856af 121}
4b55d2af 122/**
123 * Not sure - not used
124 */
5e7856af 125if (!defined("LESSON_RANDOMSAMATCH")) {
126 define("LESSON_RANDOMSAMATCH", "6");
127}
4b55d2af 128/**
129 * Not sure - not used
130 */
5e7856af 131if (!defined("LESSON_DESCRIPTION")) {
132 define("LESSON_DESCRIPTION", "7");
133}
4b55d2af 134/**
135 * Numerical question type
136 */
5e7856af 137if (!defined("LESSON_NUMERICAL")) {
138 define("LESSON_NUMERICAL", "8");
139}
4b55d2af 140/**
141 * Multichoice with multianswer question type
142 */
5e7856af 143if (!defined("LESSON_MULTIANSWER")) {
144 define("LESSON_MULTIANSWER", "9");
145}
4b55d2af 146/**
147 * Essay question type
148 */
5e7856af 149if (!defined("LESSON_ESSAY")) {
ac8e16be 150 define("LESSON_ESSAY", "10");
5e7856af 151}
5e7856af 152
4b55d2af 153/**
154 * Lesson question type array.
155 * Contains all question types used
156 */
5e7856af 157$LESSON_QUESTION_TYPE = array ( LESSON_MULTICHOICE => get_string("multichoice", "quiz"),
158 LESSON_TRUEFALSE => get_string("truefalse", "quiz"),
159 LESSON_SHORTANSWER => get_string("shortanswer", "quiz"),
160 LESSON_NUMERICAL => get_string("numerical", "quiz"),
161 LESSON_MATCHING => get_string("match", "quiz"),
62eda6ea 162 LESSON_ESSAY => get_string("essay", "lesson")
5e7856af 163// LESSON_DESCRIPTION => get_string("description", "quiz"),
164// LESSON_RANDOM => get_string("random", "quiz"),
165// LESSON_RANDOMSAMATCH => get_string("randomsamatch", "quiz"),
166// LESSON_MULTIANSWER => get_string("multianswer", "quiz"),
167 );
168
4b55d2af 169// Non-question page types
170
171/**
172 * Branch Table page
173 */
5e7856af 174if (!defined("LESSON_BRANCHTABLE")) {
175 define("LESSON_BRANCHTABLE", "20");
176}
4b55d2af 177/**
178 * End of Branch page
179 */
5e7856af 180if (!defined("LESSON_ENDOFBRANCH")) {
181 define("LESSON_ENDOFBRANCH", "21");
182}
4b55d2af 183/**
184 * Start of Cluster page
185 */
186if (!defined("LESSON_CLUSTER")) {
187 define("LESSON_CLUSTER", "30");
188}
189/**
190 * End of Cluster page
191 */
192if (!defined("LESSON_ENDOFCLUSTER")) {
193 define("LESSON_ENDOFCLUSTER", "31");
194}
195
196// other variables...
5e7856af 197
4b55d2af 198/**
199 * Flag for the editor for the answer textarea.
200 */
5e7856af 201if (!defined("LESSON_ANSWER_EDITOR")) {
202 define("LESSON_ANSWER_EDITOR", "1");
203}
4b55d2af 204/**
205 * Flag for the editor for the response textarea.
206 */
5e7856af 207if (!defined("LESSON_RESPONSE_EDITOR")) {
208 define("LESSON_RESPONSE_EDITOR", "2");
209}
210
211//////////////////////////////////////////////////////////////////////////////////////
212/// Any other lesson functions go here. Each of them must have a name that
213/// starts with lesson_
214
9fcf51d9 215/**
216 * Print the standard header for lesson module
217 *
68a1e8fb 218 * @uses $CFG
219 * @uses $USER
9fcf51d9 220 * @param object $cm Course module record object
221 * @param object $course Couse record object
222 * @param object $lesson Lesson module record object
223 * @param string $currenttab Current tab for the lesson tabs
68a1e8fb 224 * @return boolean
9fcf51d9 225 **/
d1b025d0 226function lesson_print_header($cm, $course, $lesson, $currenttab = '') {
9fcf51d9 227 global $CFG, $USER;
fb992d71 228
229 $strlessons = get_string('modulenameplural', 'lesson');
230 $strlesson = get_string('modulename', 'lesson');
231 $strname = format_string($lesson->name, true);
232
6e1ff5c8 233 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
9fcf51d9 234
fb992d71 235 // Changed the update_module_button and added another button when a teacher is checking the navigation of the lesson
236 if (has_capability('mod/lesson:edit', $context)) {
237
238 $button = update_module_button($cm->id, $course->id, $strlesson);
239
240 if ($currenttab == 'view') {
241 if (!$pageid = optional_param('pageid', 0, PARAM_INT)) {
242 $pageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0);
243 }
244 if (!empty($pageid) and $pageid != LESSON_EOL) {
245 $button = '<table><tr><td>'.$button.
246 '</td><td>'.
fa738731 247 '<form '.$CFG->frametarget.' method="get" action="'. $CFG->wwwroot .'/mod/lesson/lesson.php">'.
76d4ec00 248 '<div>'.
fb992d71 249 '<input type="hidden" name="id" value="'. $cm->id .'" />'.
250 '<input type="hidden" name="action" value="editpage" />'.
251 '<input type="hidden" name="redirect" value="navigation" />'.
252 '<input type="hidden" name="pageid" value="'. $pageid .'" />'.
4085962a 253 '<input type="submit" value="'. get_string('editpagecontent', 'lesson') .'" />'.
76d4ec00 254 '</div>'.
4085962a 255 '</form>'.
256 '</td></tr></table>';
fb992d71 257 }
258 }
259 } else {
260 $button = '';
261 }
262
5631925a 263 if (!optional_param('pageid', 0, PARAM_INT) and !empty($lesson->mediafile)) {
264 // open our pop-up
265 $url = '/mod/lesson/mediafile.php?id='.$cm->id;
266 $name = 'lessonmediafile';
267 $options = 'menubar=0,location=0,left=5,top=5,scrollbars,resizable,width='. $lesson->mediawidth .',height='. $lesson->mediaheight;
32f0b38a 268 $meta = "\n<script type=\"text/javascript\">";
5631925a 269 $meta .= "\n<!--\n";
270 $meta .= " openpopup('$url', '$name', '$options', 0);";
271 $meta .= "\n-->\n";
272 $meta .= '</script>';
273 } else {
274 $meta = '';
275 }
276
9fcf51d9 277/// Header setup
18ec35d9 278 $navigation = array();
1936c10e 279 if ($course->id != SITEID) {
18ec35d9 280 $navigation[$course->shortname] = "$CFG->wwwroot/course/view.php?id=$course->id";
9fcf51d9 281 }
18ec35d9 282 $navigation[$strlessons] = "$CFG->wwwroot/mod/lesson/index.php?id=$course->id";
283 $navigation[$strname] = '';
9fcf51d9 284
ccfe8fdd 285 $urls = array();
286 foreach($navigation as $text => $href) {
287 if (empty($href)) {
288 $urls[] = $text;
289 } else {
290 $urls[] = '<a href="'.$href.'">'.$text.'</a>';
291 }
292 }
293 $breadcrumb = implode(' -> ', $urls);
294
9fcf51d9 295/// Print header, heading, tabs and messages
ccfe8fdd 296 print_header("$course->shortname: $strname", $course->fullname, $breadcrumb,
5631925a 297 '', $meta, true, $button, navmenu($course, $cm));
9fcf51d9 298
0ae3b5d3 299 if (has_capability('mod/lesson:manage', $context)) {
9fcf51d9 300 print_heading_with_help(format_string($lesson->name, true), "overview", "lesson");
d1b025d0 301 } else {
302 print_heading($lesson->name);
9fcf51d9 303 }
304
6e1ff5c8 305 if (!empty($currenttab) and has_capability('mod/lesson:manage', $context)) {
9fcf51d9 306 include($CFG->dirroot.'/mod/lesson/tabs.php');
307 }
f15eb92c 308
309 lesson_print_messages();
68a1e8fb 310
311 return true;
9fcf51d9 312}
313
314/**
315 * Returns course module, course and module instance given
316 * either the course module ID or a lesson module ID.
317 *
318 * @param int $cmid Course Module ID
319 * @param int $lessonid Lesson module instance ID
320 * @return array array($cm, $course, $lesson)
321 **/
322function lesson_get_basics($cmid = 0, $lessonid = 0) {
323 if ($cmid) {
f15eb92c 324 if (!$cm = get_coursemodule_from_id('lesson', $cmid)) {
9fcf51d9 325 error('Course Module ID was incorrect');
326 }
327 if (!$course = get_record('course', 'id', $cm->course)) {
328 error('Course is misconfigured');
329 }
330 if (!$lesson = get_record('lesson', 'id', $cm->instance)) {
331 error('Course module is incorrect');
332 }
333 } else if ($lessonid) {
334 if (!$lesson = get_record('lesson', 'id', $lessonid)) {
335 error('Course module is incorrect');
336 }
337 if (!$course = get_record('course', 'id', $lesson->course)) {
338 error('Course is misconfigured');
339 }
340 if (!$cm = get_coursemodule_from_instance('lesson', $lesson->id, $course->id)) {
341 error('Course Module ID was incorrect');
342 }
343 } else {
344 error('No course module ID or lesson ID were passed');
345 }
346
347 return array($cm, $course, $lesson);
348}
349
6e1ff5c8 350/**
351 * Sets a message to be printed. Messages are printed
352 * by calling {@link lesson_print_messages()}.
353 *
354 * @uses $SESSION
355 * @param string $message The message to be printed
356 * @param string $class Class to be passed to {@link notify()}. Usually notifyproblem or notifysuccess.
357 * @param string $align Alignment of the message
358 * @return boolean
359 **/
360function lesson_set_message($message, $class="notifyproblem", $align='center') {
361 global $SESSION;
362
363 if (empty($SESSION->lesson_messages) or !is_array($SESSION->lesson_messages)) {
364 $SESSION->lesson_messages = array();
365 }
366
367 $SESSION->lesson_messages[] = array($message, $class, $align);
368
369 return true;
370}
371
372/**
373 * Print all set messages.
374 *
375 * See {@link lesson_set_message()} for setting messages.
376 *
377 * Uses {@link notify()} to print the messages.
378 *
379 * @uses $SESSION
380 * @return boolean
381 **/
382function lesson_print_messages() {
383 global $SESSION;
384
385 if (empty($SESSION->lesson_messages)) {
386 // No messages to print
387 return true;
388 }
389
390 foreach($SESSION->lesson_messages as $message) {
391 notify($message[0], $message[1], $message[2]);
392 }
393
394 // Reset
395 unset($SESSION->lesson_messages);
396
397 return true;
398}
399
259990d2 400/**
401 * Prints a lesson link that submits a form.
402 *
403 * If Javascript is disabled, then a regular submit button is printed
404 *
68a1e8fb 405 * @param string $name Name of the link or button
406 * @param string $form The name of the form to be submitted
407 * @param string $align Alignment of the button
408 * @param string $class Class names to add to the div wrapper
409 * @param string $title Title for the link (Not used if javascript is disabled)
410 * @param string $id ID tag
411 * @param boolean $return Return flag
259990d2 412 * @return mixed boolean/html
413 **/
414function lesson_print_submit_link($name, $form, $align = 'center', $class='standardbutton', $title = '', $id = '', $return = false) {
563106f0 415 if (!empty($align)) {
4085962a 416 $align = " style=\"text-align:$align\"";
563106f0 417 }
259990d2 418 if (!empty($id)) {
419 $id = " id=\"$id\"";
420 }
421 if (empty($title)) {
422 $title = $name;
423 }
62bb11d8 424
4cb35c1b 425 $output = "<div class=\"lessonbutton $class\" $align>\n";
37aa59a9 426 $output .= "<input type=\"submit\" value=\"$name\" $align $id />";
259990d2 427 $output .= "</div>\n";
428
2cb24b64 429 if ($return) {
430 return $output;
431 } else {
432 echo $output;
433 return true;
434 }
435}
436
437/**
438 * Prints a time remaining in the following format: H:MM:SS
439 *
440 * @param int $starttime Time when the lesson started
441 * @param int $maxtime Length of the lesson
442 * @param boolean $return Return output switch
443 * @return mixed boolean/string
444 **/
2163c226 445function lesson_print_time_remaining($starttime, $maxtime, $return = false) {
2cb24b64 446 // Calculate hours, minutes and seconds
447 $timeleft = $starttime + $maxtime * 60 - time();
448 $hours = floor($timeleft/3600);
449 $timeleft = $timeleft - ($hours * 3600);
450 $minutes = floor($timeleft/60);
451 $secs = $timeleft - ($minutes * 60);
452
453 if ($minutes < 10) {
454 $minutes = "0$minutes";
455 }
456 if ($secs < 10) {
457 $secs = "0$secs";
458 }
459 $output = array();
460 $output[] = $hours;
461 $output[] = $minutes;
462 $output[] = $secs;
463
464 $output = implode(':', $output);
465
259990d2 466 if ($return) {
467 return $output;
468 } else {
469 echo $output;
470 return true;
471 }
472}
473
68a1e8fb 474/**
475 * Prints the page action buttons
476 *
477 * Move/Edit/Preview/Delete
478 *
479 * @uses $CFG
480 * @param int $cmid Course Module ID
260a56b1 481 * @param object $page Page record
68a1e8fb 482 * @param boolean $printmove Flag to print the move button or not
260a56b1 483 * @param boolean $printaddpage Flag to print the add page drop-down or not
68a1e8fb 484 * @param boolean $return Return flag
485 * @return mixed boolean/string
486 **/
260a56b1 487function lesson_print_page_actions($cmid, $page, $printmove, $printaddpage = false, $return = false) {
68a1e8fb 488 global $CFG;
489
490 $context = get_context_instance(CONTEXT_MODULE, $cmid);
491 $actions = array();
492
493 if (has_capability('mod/lesson:edit', $context)) {
494 if ($printmove) {
2ba9db3c 495 $actions[] = "<a title=\"".get_string('move')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=move&amp;pageid=$page->id\">
0d905d9f 496 <img src=\"$CFG->pixpath/t/move.gif\" class=\"iconsmall\" alt=\"".get_string('move')."\" /></a>\n";
68a1e8fb 497 }
260a56b1 498 $actions[] = "<a title=\"".get_string('update')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=editpage&amp;pageid=$page->id\">
0d905d9f 499 <img src=\"$CFG->pixpath/t/edit.gif\" class=\"iconsmall\" alt=\"".get_string('update')."\" /></a>\n";
68a1e8fb 500
260a56b1 501 $actions[] = "<a title=\"".get_string('preview')."\" href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cmid&amp;pageid=$page->id\">
0d905d9f 502 <img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"".get_string('preview')."\" /></a>\n";
68a1e8fb 503
260a56b1 504 $actions[] = "<a title=\"".get_string('delete')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=confirmdelete&amp;pageid=$page->id\">
0d905d9f 505 <img src=\"$CFG->pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"".get_string('delete')."\" /></a>\n";
68a1e8fb 506
260a56b1 507 if ($printaddpage) {
508 // Add page drop-down
509 $options = array();
510 $options['addcluster&amp;sesskey='.sesskey()] = get_string('clustertitle', 'lesson');
511 $options['addendofcluster&amp;sesskey='.sesskey()] = get_string('endofclustertitle', 'lesson');
512 $options['addbranchtable'] = get_string('branchtable', 'lesson');
513 $options['addendofbranch&amp;sesskey='.sesskey()] = get_string('endofbranch', 'lesson');
514 $options['addpage'] = get_string('question', 'lesson');
515 // Base url
516 $common = "$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;pageid=$page->id&amp;action=";
517
518 $actions[] = popup_form($common, $options, "addpage_$page->id", '', get_string('addpage', 'lesson').'...', '', '', true);
519 }
68a1e8fb 520 }
521
522 $actions = implode(' ', $actions);
523
524 if ($return) {
525 return $actions;
526 } else {
527 echo $actions;
528 return false;
529 }
530}
531
532/**
533 * Prints the add links in expanded view or single view when editing
534 *
535 * @uses $CFG
536 * @param int $cmid Course Module ID
537 * @param int $prevpageid Previous page id
538 * @param boolean $return Return flag
539 * @return mixed boolean/string
540 * @todo &amp;pageid does not make sense, it is prevpageid
541 **/
542function lesson_print_add_links($cmid, $prevpageid, $return = false) {
543 global $CFG;
544
545 $context = get_context_instance(CONTEXT_MODULE, $cmid);
546
547 $links = '';
548 if (has_capability('mod/lesson:edit', $context)) {
549 $links = array();
550 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/import.php?id=$cmid&amp;pageid=$prevpageid\">".
551 get_string('importquestions', 'lesson').'</a>';
552
553 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addcluster&amp;pageid=$prevpageid\">".
554 get_string('addcluster', 'lesson').'</a>';
555
556 if ($prevpageid != 0) {
557 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addendofcluster&amp;pageid=$prevpageid\">".
558 get_string('addendofcluster', 'lesson').'</a>';
559 }
560 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=addbranchtable&amp;pageid=$prevpageid\">".
561 get_string('addabranchtable', 'lesson').'</a>';
562
563 if ($prevpageid != 0) {
564 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;sesskey=".sesskey()."&amp;action=addendofbranch&amp;pageid=$prevpageid\">".
565 get_string('addanendofbranch', 'lesson').'</a>';
566 }
567
568 $links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&amp;action=addpage&amp;pageid=$prevpageid\">".
569 get_string('addaquestionpagehere', 'lesson').'</a>';
570
571 $links = implode(" | \n", $links);
572 $links = "\n<div class=\"addlinks\">\n$links\n</div>\n";
573 }
574
575 if ($return) {
576 return $links;
577 } else {
578 echo $links;
579 return true;
580 }
581}
582
583/**
584 * Returns the string for a page type
585 *
586 * @uses $LESSON_QUESTION_TYPE
587 * @param int $qtype Page type
588 * @return string
589 **/
590function lesson_get_qtype_name($qtype) {
591 global $LESSON_QUESTION_TYPE;
592 switch ($qtype) {
593 case LESSON_ESSAY :
594 case LESSON_SHORTANSWER :
595 case LESSON_MULTICHOICE :
596 case LESSON_MATCHING :
597 case LESSON_TRUEFALSE :
598 case LESSON_NUMERICAL :
599 return $LESSON_QUESTION_TYPE[$qtype];
600 break;
601 case LESSON_BRANCHTABLE :
602 return get_string("branchtable", "lesson");
603 break;
604 case LESSON_ENDOFBRANCH :
605 return get_string("endofbranch", "lesson");
606 break;
607 case LESSON_CLUSTER :
608 return get_string("clustertitle", "lesson");
609 break;
610 case LESSON_ENDOFCLUSTER :
611 return get_string("endofclustertitle", "lesson");
612 break;
613 default:
614 return '';
615 break;
616 }
617}
618
619/**
620 * Returns the string for a jump name
621 *
622 * @param int $jumpto Jump code or page ID
623 * @return string
624 **/
625function lesson_get_jump_name($jumpto) {
626 if ($jumpto == 0) {
627 $jumptitle = get_string('thispage', 'lesson');
628 } elseif ($jumpto == LESSON_NEXTPAGE) {
629 $jumptitle = get_string('nextpage', 'lesson');
630 } elseif ($jumpto == LESSON_EOL) {
631 $jumptitle = get_string('endoflesson', 'lesson');
632 } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
633 $jumptitle = get_string('unseenpageinbranch', 'lesson');
634 } elseif ($jumpto == LESSON_PREVIOUSPAGE) {
635 $jumptitle = get_string('previouspage', 'lesson');
636 } elseif ($jumpto == LESSON_RANDOMPAGE) {
637 $jumptitle = get_string('randompageinbranch', 'lesson');
638 } elseif ($jumpto == LESSON_RANDOMBRANCH) {
639 $jumptitle = get_string('randombranch', 'lesson');
640 } elseif ($jumpto == LESSON_CLUSTERJUMP) {
641 $jumptitle = get_string('clusterjump', 'lesson');
642 } else {
643 if (!$jumptitle = get_field('lesson_pages', 'title', 'id', $jumpto)) {
644 $jumptitle = '<strong>'.get_string('notdefined', 'lesson').'</strong>';
645 }
646 }
647
648 return format_string($jumptitle,true);
649}
650
4b55d2af 651/**
652 * Given some question info and some data about the the answers
653 * this function parses, organises and saves the question
654 *
655 * This is only used when IMPORTING questions and is only called
656 * from format.php
657 * Lifted from mod/quiz/lib.php -
658 * 1. all reference to oldanswers removed
659 * 2. all reference to quiz_multichoice table removed
660 * 3. In SHORTANSWER questions usecase is store in the qoption field
661 * 4. In NUMERIC questions store the range as two answers
662 * 5. TRUEFALSE options are ignored
663 * 6. For MULTICHOICE questions with more than one answer the qoption field is true
664 *
665 * @param opject $question Contains question data like question, type and answers.
666 * @return object Returns $result->error or $result->notice.
667 **/
5e7856af 668function lesson_save_question_options($question) {
5e7856af 669
670 $timenow = time();
671 switch ($question->qtype) {
672 case LESSON_SHORTANSWER:
673
674 $answers = array();
675 $maxfraction = -1;
676
677 // Insert all the new answers
678 foreach ($question->answer as $key => $dataanswer) {
679 if ($dataanswer != "") {
f7ffb898 680 $answer = new stdClass;
5e7856af 681 $answer->lessonid = $question->lessonid;
682 $answer->pageid = $question->id;
683 if ($question->fraction[$key] >=0.5) {
684 $answer->jumpto = LESSON_NEXTPAGE;
685 }
686 $answer->timecreated = $timenow;
687 $answer->grade = $question->fraction[$key] * 100;
688 $answer->answer = $dataanswer;
c87a341c 689 $answer->response = $question->feedback[$key];
5e7856af 690 if (!$answer->id = insert_record("lesson_answers", $answer)) {
691 $result->error = "Could not insert shortanswer quiz answer!";
692 return $result;
693 }
694 $answers[] = $answer->id;
695 if ($question->fraction[$key] > $maxfraction) {
696 $maxfraction = $question->fraction[$key];
697 }
698 }
699 }
700
701
702 /// Perform sanity checks on fractional grades
703 if ($maxfraction != 1) {
704 $maxfraction = $maxfraction * 100;
705 $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
706 return $result;
707 }
708 break;
709
710 case LESSON_NUMERICAL: // Note similarities to SHORTANSWER
711
712 $answers = array();
713 $maxfraction = -1;
714
715
716 // for each answer store the pair of min and max values even if they are the same
717 foreach ($question->answer as $key => $dataanswer) {
718 if ($dataanswer != "") {
f7ffb898 719 $answer = new stdClass;
5e7856af 720 $answer->lessonid = $question->lessonid;
721 $answer->pageid = $question->id;
722 $answer->jumpto = LESSON_NEXTPAGE;
723 $answer->timecreated = $timenow;
724 $answer->grade = $question->fraction[$key] * 100;
dd192b26 725 $min = $question->answer[$key] - $question->tolerance[$key];
726 $max = $question->answer[$key] + $question->tolerance[$key];
727 $answer->answer = $min.":".$max;
728 // $answer->answer = $question->min[$key].":".$question->max[$key]; original line for min/max
5e7856af 729 $answer->response = $question->feedback[$key];
730 if (!$answer->id = insert_record("lesson_answers", $answer)) {
731 $result->error = "Could not insert numerical quiz answer!";
732 return $result;
733 }
734
735 $answers[] = $answer->id;
736 if ($question->fraction[$key] > $maxfraction) {
737 $maxfraction = $question->fraction[$key];
738 }
739 }
740 }
741
742 /// Perform sanity checks on fractional grades
743 if ($maxfraction != 1) {
744 $maxfraction = $maxfraction * 100;
745 $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
746 return $result;
747 }
748 break;
749
750
751 case LESSON_TRUEFALSE:
752
753 // the truth
754 $answer->lessonid = $question->lessonid;
755 $answer->pageid = $question->id;
756 $answer->timecreated = $timenow;
757 $answer->answer = get_string("true", "quiz");
758 $answer->grade = $question->answer * 100;
759 if ($answer->grade > 50 ) {
760 $answer->jumpto = LESSON_NEXTPAGE;
761 }
762 if (isset($question->feedbacktrue)) {
763 $answer->response = $question->feedbacktrue;
764 }
765 if (!$true->id = insert_record("lesson_answers", $answer)) {
766 $result->error = "Could not insert quiz answer \"true\")!";
767 return $result;
768 }
769
770 // the lie
f7ffb898 771 $answer = new stdClass;
5e7856af 772 $answer->lessonid = $question->lessonid;
773 $answer->pageid = $question->id;
774 $answer->timecreated = $timenow;
775 $answer->answer = get_string("false", "quiz");
776 $answer->grade = (1 - (int)$question->answer) * 100;
777 if ($answer->grade > 50 ) {
778 $answer->jumpto = LESSON_NEXTPAGE;
779 }
780 if (isset($question->feedbackfalse)) {
781 $answer->response = $question->feedbackfalse;
782 }
783 if (!$false->id = insert_record("lesson_answers", $answer)) {
784 $result->error = "Could not insert quiz answer \"false\")!";
785 return $result;
786 }
787
788 break;
789
790
791 case LESSON_MULTICHOICE:
792
793 $totalfraction = 0;
794 $maxfraction = -1;
795
796 $answers = array();
797
798 // Insert all the new answers
799 foreach ($question->answer as $key => $dataanswer) {
800 if ($dataanswer != "") {
f7ffb898 801 $answer = new stdClass;
5e7856af 802 $answer->lessonid = $question->lessonid;
803 $answer->pageid = $question->id;
804 $answer->timecreated = $timenow;
805 $answer->grade = $question->fraction[$key] * 100;
62eda6ea 806 // changed some defaults
ac8e16be 807 /* Original Code
808 if ($answer->grade > 50 ) {
5e7856af 809 $answer->jumpto = LESSON_NEXTPAGE;
810 }
ac8e16be 811 Replaced with: */
812 if ($answer->grade > 50 ) {
813 $answer->jumpto = LESSON_NEXTPAGE;
5e7856af 814 $answer->score = 1;
815 }
ac8e16be 816 // end Replace
5e7856af 817 $answer->answer = $dataanswer;
818 $answer->response = $question->feedback[$key];
819 if (!$answer->id = insert_record("lesson_answers", $answer)) {
820 $result->error = "Could not insert multichoice quiz answer! ";
821 return $result;
822 }
823 // for Sanity checks
824 if ($question->fraction[$key] > 0) {
825 $totalfraction += $question->fraction[$key];
826 }
827 if ($question->fraction[$key] > $maxfraction) {
828 $maxfraction = $question->fraction[$key];
829 }
830 }
831 }
832
833 /// Perform sanity checks on fractional grades
834 if ($question->single) {
835 if ($maxfraction != 1) {
836 $maxfraction = $maxfraction * 100;
837 $result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
838 return $result;
839 }
840 } else {
841 $totalfraction = round($totalfraction,2);
842 if ($totalfraction != 1) {
843 $totalfraction = $totalfraction * 100;
844 $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
845 return $result;
846 }
847 }
848 break;
849
850 case LESSON_MATCHING:
851
852 $subquestions = array();
853
854 $i = 0;
855 // Insert all the new question+answer pairs
856 foreach ($question->subquestions as $key => $questiontext) {
90455bb3 857 $answertext = $question->subanswers[$key];
5e7856af 858 if (!empty($questiontext) and !empty($answertext)) {
f7ffb898 859 $answer = new stdClass;
5e7856af 860 $answer->lessonid = $question->lessonid;
861 $answer->pageid = $question->id;
862 $answer->timecreated = $timenow;
863 $answer->answer = $questiontext;
864 $answer->response = $answertext;
865 if ($i == 0) {
866 // first answer contains the correct answer jump
867 $answer->jumpto = LESSON_NEXTPAGE;
868 }
869 if (!$subquestion->id = insert_record("lesson_answers", $answer)) {
870 $result->error = "Could not insert quiz match subquestion!";
871 return $result;
872 }
873 $subquestions[] = $subquestion->id;
874 $i++;
875 }
876 }
877
878 if (count($subquestions) < 3) {
879 $result->notice = get_string("notenoughsubquestions", "quiz");
880 return $result;
881 }
882
883 break;
884
885
886 case LESSON_RANDOMSAMATCH:
887 $options->question = $question->id;
888 $options->choose = $question->choose;
889 if ($existing = get_record("quiz_randomsamatch", "question", $options->question)) {
890 $options->id = $existing->id;
891 if (!update_record("quiz_randomsamatch", $options)) {
892 $result->error = "Could not update quiz randomsamatch options!";
893 return $result;
894 }
895 } else {
896 if (!insert_record("quiz_randomsamatch", $options)) {
897 $result->error = "Could not insert quiz randomsamatch options!";
898 return $result;
899 }
900 }
901 break;
902
903 case LESSON_MULTIANSWER:
904 if (!$oldmultianswers = get_records("quiz_multianswers", "question", $question->id, "id ASC")) {
905 $oldmultianswers = array();
906 }
907
908 // Insert all the new multi answers
909 foreach ($question->answers as $dataanswer) {
910 if ($oldmultianswer = array_shift($oldmultianswers)) { // Existing answer, so reuse it
911 $multianswer = $oldmultianswer;
912 $multianswer->positionkey = $dataanswer->positionkey;
913 $multianswer->norm = $dataanswer->norm;
914 $multianswer->answertype = $dataanswer->answertype;
915
916 if (! $multianswer->answers = quiz_save_multianswer_alternatives
917 ($question->id, $dataanswer->answertype,
918 $dataanswer->alternatives, $oldmultianswer->answers))
919 {
920 $result->error = "Could not update multianswer alternatives! (id=$multianswer->id)";
921 return $result;
922 }
923 if (!update_record("quiz_multianswers", $multianswer)) {
924 $result->error = "Could not update quiz multianswer! (id=$multianswer->id)";
925 return $result;
926 }
927 } else { // This is a completely new answer
f7ffb898 928 $multianswer = new stdClass;
5e7856af 929 $multianswer->question = $question->id;
930 $multianswer->positionkey = $dataanswer->positionkey;
931 $multianswer->norm = $dataanswer->norm;
932 $multianswer->answertype = $dataanswer->answertype;
933
934 if (! $multianswer->answers = quiz_save_multianswer_alternatives
935 ($question->id, $dataanswer->answertype,
936 $dataanswer->alternatives))
937 {
938 $result->error = "Could not insert multianswer alternatives! (questionid=$question->id)";
939 return $result;
940 }
941 if (!insert_record("quiz_multianswers", $multianswer)) {
942 $result->error = "Could not insert quiz multianswer!";
943 return $result;
944 }
945 }
946 }
947 break;
948
949 case LESSON_RANDOM:
950 break;
951
952 case LESSON_DESCRIPTION:
953 break;
954
955 default:
956 $result->error = "Unsupported question type ($question->qtype)!";
957 return $result;
958 break;
959 }
960 return true;
961}
4b55d2af 962
4b55d2af 963/**
964 * Determins if a jumpto value is correct or not.
965 *
966 * returns true if jumpto page is (logically) after the pageid page or
967 * if the jumpto value is a special value. Returns false in all other cases.
968 *
969 * @param int $pageid Id of the page from which you are jumping from.
970 * @param int $jumpto The jumpto number.
971 * @return boolean True or false after a series of tests.
4b55d2af 972 **/
5e7856af 973function lesson_iscorrect($pageid, $jumpto) {
5e7856af 974
975 // first test the special values
976 if (!$jumpto) {
977 // same page
978 return false;
979 } elseif ($jumpto == LESSON_NEXTPAGE) {
980 return true;
ac8e16be 981 } elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
5e7856af 982 return true;
983 } elseif ($jumpto == LESSON_RANDOMPAGE) {
984 return true;
985 } elseif ($jumpto == LESSON_CLUSTERJUMP) {
986 return true;
5e7856af 987 } elseif ($jumpto == LESSON_EOL) {
988 return true;
989 }
990 // we have to run through the pages from pageid looking for jumpid
f521f98a 991 if ($lessonid = get_field('lesson_pages', 'lessonid', 'id', $pageid)) {
992 if ($pages = get_records('lesson_pages', 'lessonid', $lessonid, '', 'id, nextpageid')) {
993 $apageid = $pages[$pageid]->nextpageid;
994 while ($apageid != 0) {
995 if ($jumpto == $apageid) {
996 return true;
997 }
998 $apageid = $pages[$apageid]->nextpageid;
999 }
5e7856af 1000 }
1001 }
f521f98a 1002 return false;
5e7856af 1003}
1004
4b55d2af 1005/**
1006 * Checks to see if a page is a branch table or is
1007 * a page that is enclosed by a branch table and an end of branch or end of lesson.
1008 * May call this function: {@link lesson_is_page_in_branch()}
1009 *
f521f98a 1010 * @param int $lesson Id of the lesson to which the page belongs.
4b55d2af 1011 * @param int $pageid Id of the page.
1012 * @return boolean True or false.
4b55d2af 1013 **/
f521f98a 1014function lesson_display_branch_jumps($lessonid, $pageid) {
ac8e16be 1015 if($pageid == 0) {
1016 // first page
1017 return false;
1018 }
1019 // get all of the lesson pages
f521f98a 1020 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
ac8e16be 1021 // adding first page
1022 return false;
1023 }
1024
1025 if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
1026 return true;
1027 }
1028
1029 return lesson_is_page_in_branch($lessonpages, $pageid);
5e7856af 1030}
1031
4b55d2af 1032/**
1033 * Checks to see if a page is a cluster page or is
1034 * a page that is enclosed by a cluster page and an end of cluster or end of lesson
1035 * May call this function: {@link lesson_is_page_in_cluster()}
1036 *
f521f98a 1037 * @param int $lesson Id of the lesson to which the page belongs.
4b55d2af 1038 * @param int $pageid Id of the page.
1039 * @return boolean True or false.
4b55d2af 1040 **/
f521f98a 1041function lesson_display_cluster_jump($lesson, $pageid) {
ac8e16be 1042 if($pageid == 0) {
1043 // first page
1044 return false;
1045 }
1046 // get all of the lesson pages
f521f98a 1047 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lesson")) {
ac8e16be 1048 // adding first page
1049 return false;
1050 }
1051
1052 if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
1053 return true;
1054 }
1055
1056 return lesson_is_page_in_cluster($lessonpages, $pageid);
5e7856af 1057
1058}
1059
4b55d2af 1060/**
1061 * Checks to see if a LESSON_CLUSTERJUMP or
1062 * a LESSON_UNSEENBRANCHPAGE is used in a lesson.
1063 *
1064 * This function is only executed when a teacher is
1065 * checking the navigation for a lesson.
1066 *
06469639 1067 * @param int $lesson Id of the lesson that is to be checked.
4b55d2af 1068 * @return boolean True or false.
1069 **/
06469639 1070function lesson_display_teacher_warning($lesson) {
ac8e16be 1071 // get all of the lesson answers
1072 if (!$lessonanswers = get_records_select("lesson_answers", "lessonid = $lesson")) {
1073 // no answers, then not useing cluster or unseen
1074 return false;
1075 }
1076 // just check for the first one that fulfills the requirements
1077 foreach ($lessonanswers as $lessonanswer) {
1078 if ($lessonanswer->jumpto == LESSON_CLUSTERJUMP || $lessonanswer->jumpto == LESSON_UNSEENBRANCHPAGE) {
1079 return true;
1080 }
1081 }
1082
1083 // if no answers use either of the two jumps
1084 return false;
5e7856af 1085}
1086
1087
4b55d2af 1088/**
1089 * Interprets LESSON_CLUSTERJUMP jumpto value.
1090 *
1091 * This will select a page randomly
1092 * and the page selected will be inbetween a cluster page and end of cluter or end of lesson
1093 * and the page selected will be a page that has not been viewed already
1094 * and if any pages are within a branch table or end of branch then only 1 page within
1095 * the branch table or end of branch will be randomly selected (sub clustering).
1096 *
f521f98a 1097 * @param int $lessonid Id of the lesson.
1098 * @param int $userid Id of the user.
4b55d2af 1099 * @param int $pageid Id of the current page from which we are jumping from.
1100 * @return int The id of the next page.
4b55d2af 1101 **/
f521f98a 1102function lesson_cluster_jump($lessonid, $userid, $pageid) {
ac8e16be 1103 // get the number of retakes
f521f98a 1104 if (!$retakes = count_records("lesson_grades", "lessonid", $lessonid, "userid", $userid)) {
ac8e16be 1105 $retakes = 0;
1106 }
1107
1108 // get all the lesson_attempts aka what the user has seen
f521f98a 1109 if ($seen = get_records_select("lesson_attempts", "lessonid = $lessonid AND userid = $userid AND retry = $retakes", "timeseen DESC")) {
ac8e16be 1110 foreach ($seen as $value) { // load it into an array that I can more easily use
1111 $seenpages[$value->pageid] = $value->pageid;
1112 }
1113 } else {
1114 $seenpages = array();
1115 }
1116
1117 // get the lesson pages
f521f98a 1118 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
ac8e16be 1119 error("Error: could not find records in lesson_pages table");
1120 }
1121 // find the start of the cluster
1122 while ($pageid != 0) { // this condition should not be satisfied... should be a cluster page
1123 if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
1124 break;
1125 }
1126 $pageid = $lessonpages[$pageid]->prevpageid;
1127 }
1128
1129 $pageid = $lessonpages[$pageid]->nextpageid; // move down from the cluster page
1130
1131 $clusterpages = array();
1132 while (true) { // now load all the pages into the cluster that are not already inside of a branch table.
1133 if ($lessonpages[$pageid]->qtype == LESSON_ENDOFCLUSTER) {
1134 // store the endofcluster page's jump
f521f98a 1135 $exitjump = get_field("lesson_answers", "jumpto", "pageid", $pageid, "lessonid", $lessonid);
ac8e16be 1136 if ($exitjump == LESSON_NEXTPAGE) {
1137 $exitjump = $lessonpages[$pageid]->nextpageid;
1138 }
1139 if ($exitjump == 0) {
1140 $exitjump = LESSON_EOL;
1141 }
1142 break;
1143 } elseif (!lesson_is_page_in_branch($lessonpages, $pageid) && $lessonpages[$pageid]->qtype != LESSON_ENDOFBRANCH) {
1144 // load page into array when it is not in a branch table and when it is not an endofbranch
1145 $clusterpages[] = $lessonpages[$pageid];
1146 }
1147 if ($lessonpages[$pageid]->nextpageid == 0) {
1148 // shouldn't ever get here... should be using endofcluster
1149 $exitjump = LESSON_EOL;
1150 break;
1151 } else {
1152 $pageid = $lessonpages[$pageid]->nextpageid;
1153 }
1154 }
1155
1156 // filter out the ones we have seen
1157 $unseen = array();
1158 foreach ($clusterpages as $clusterpage) {
1159 if ($clusterpage->qtype == LESSON_BRANCHTABLE) { // if branchtable, check to see if any pages inside have been viewed
1160 $branchpages = lesson_pages_in_branch($lessonpages, $clusterpage->id); // get the pages in the branchtable
1161 $flag = true;
1162 foreach ($branchpages as $branchpage) {
1163 if (array_key_exists($branchpage->id, $seenpages)) { // check if any of the pages have been viewed
1164 $flag = false;
1165 }
1166 }
1167 if ($flag && count($branchpages) > 0) {
1168 // add branch table
1169 $unseen[] = $clusterpage;
1170 }
1171 } else {
1172 // add any other type of page that has not already been viewed
1173 if (!array_key_exists($clusterpage->id, $seenpages)) {
1174 $unseen[] = $clusterpage;
1175 }
1176 }
1177 }
1178
1179 if (count($unseen) > 0) { // it does not contain elements, then use exitjump, otherwise find out next page/branch
1180 $nextpage = $unseen[rand(0, count($unseen)-1)];
1181 } else {
1182 return $exitjump; // seen all there is to see, leave the cluster
1183 }
1184
1185 if ($nextpage->qtype == LESSON_BRANCHTABLE) { // if branch table, then pick a random page inside of it
1186 $branchpages = lesson_pages_in_branch($lessonpages, $nextpage->id);
1187 return $branchpages[rand(0, count($branchpages)-1)]->id;
1188 } else { // otherwise, return the page's id
1189 return $nextpage->id;
1190 }
5e7856af 1191}
1192
4b55d2af 1193/**
1194 * Returns pages that are within a branch table and another branch table, end of branch or end of lesson
1195 *
1196 * @param array $lessonpages An array of lesson page objects.
1197 * @param int $branchid The id of the branch table that we would like the containing pages for.
1198 * @return array An array of lesson page objects.
1199 **/
5e7856af 1200function lesson_pages_in_branch($lessonpages, $branchid) {
ac8e16be 1201 $pageid = $lessonpages[$branchid]->nextpageid; // move to the first page after the branch table
1202 $pagesinbranch = array();
1203
1204 while (true) {
1205 if ($pageid == 0) { // EOL
1206 break;
1207 } elseif ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
1208 break;
1209 } elseif ($lessonpages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
1210 break;
1211 }
1212 $pagesinbranch[] = $lessonpages[$pageid];
1213 $pageid = $lessonpages[$pageid]->nextpageid;
1214 }
1215
1216 return $pagesinbranch;
5e7856af 1217}
1218
4b55d2af 1219/**
1220 * Interprets the LESSON_UNSEENBRANCHPAGE jump.
1221 *
1222 * will return the pageid of a random unseen page that is within a branch
1223 *
1224 * @see lesson_pages_in_branch()
1225 * @param int $lesson Id of the lesson.
f521f98a 1226 * @param int $userid Id of the user.
4b55d2af 1227 * @param int $pageid Id of the page from which we are jumping.
1228 * @return int Id of the next page.
4b55d2af 1229 **/
5e7856af 1230function lesson_unseen_question_jump($lesson, $user, $pageid) {
ac8e16be 1231 // get the number of retakes
5e7856af 1232 if (!$retakes = count_records("lesson_grades", "lessonid", $lesson, "userid", $user)) {
ac8e16be 1233 $retakes = 0;
1234 }
1235
1236 // get all the lesson_attempts aka what the user has seen
1237 if ($viewedpages = get_records_select("lesson_attempts", "lessonid = $lesson AND userid = $user AND retry = $retakes", "timeseen DESC")) {
1238 foreach($viewedpages as $viewed) {
1239 $seenpages[] = $viewed->pageid;
1240 }
1241 } else {
1242 $seenpages = array();
1243 }
1244
1245 // get the lesson pages
1246 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lesson")) {
1247 error("Error: could not find records in lesson_pages table");
1248 }
1249
1250 if ($pageid == LESSON_UNSEENBRANCHPAGE) { // this only happens when a student leaves in the middle of an unseen question within a branch series
1251 $pageid = $seenpages[0]; // just change the pageid to the last page viewed inside the branch table
1252 }
1253
1254 // go up the pages till branch table
1255 while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
1256 if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
1257 break;
1258 }
1259 $pageid = $lessonpages[$pageid]->prevpageid;
1260 }
1261
1262 $pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
1263
1264 // this foreach loop stores all the pages that are within the branch table but are not in the $seenpages array
1265 $unseen = array();
1266 foreach($pagesinbranch as $page) {
1267 if (!in_array($page->id, $seenpages)) {
1268 $unseen[] = $page->id;
1269 }
1270 }
1271
1272 if(count($unseen) == 0) {
1273 if(isset($pagesinbranch)) {
1274 $temp = end($pagesinbranch);
1275 $nextpage = $temp->nextpageid; // they have seen all the pages in the branch, so go to EOB/next branch table/EOL
1276 } else {
1277 // there are no pages inside the branch, so return the next page
1278 $nextpage = $lessonpages[$pageid]->nextpageid;
1279 }
1280 if ($nextpage == 0) {
1281 return LESSON_EOL;
1282 } else {
1283 return $nextpage;
1284 }
1285 } else {
1286 return $unseen[rand(0, count($unseen)-1)]; // returns a random page id for the next page
1287 }
5e7856af 1288}
1289
4b55d2af 1290/**
1291 * Handles the unseen branch table jump.
1292 *
f521f98a 1293 * @param int $lessonid Lesson id.
1294 * @param int $userid User id.
4b55d2af 1295 * @return int Will return the page id of a branch table or end of lesson
4b55d2af 1296 **/
f521f98a 1297function lesson_unseen_branch_jump($lesson, $userid) {
1298 if (!$retakes = count_records("lesson_grades", "lessonid", $lessonid, "userid", $userid)) {
ac8e16be 1299 $retakes = 0;
1300 }
1301
f521f98a 1302 if (!$seenbranches = get_records_select("lesson_branch", "lessonid = $lessonid AND userid = $userid AND retry = $retakes",
ac8e16be 1303 "timeseen DESC")) {
1304 error("Error: could not find records in lesson_branch table");
1305 }
1306
1307 // get the lesson pages
f521f98a 1308 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
ac8e16be 1309 error("Error: could not find records in lesson_pages table");
1310 }
1311
1312 // this loads all the viewed branch tables into $seen untill it finds the branch table with the flag
1313 // which is the branch table that starts the unseenbranch function
1314 $seen = array();
1315 foreach ($seenbranches as $seenbranch) {
1316 if (!$seenbranch->flag) {
1317 $seen[$seenbranch->pageid] = $seenbranch->pageid;
1318 } else {
1319 $start = $seenbranch->pageid;
1320 break;
1321 }
1322 }
1323 // this function searches through the lesson pages to find all the branch tables
1324 // that follow the flagged branch table
1325 $pageid = $lessonpages[$start]->nextpageid; // move down from the flagged branch table
1326 while ($pageid != 0) { // grab all of the branch table till eol
1327 if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
1328 $branchtables[] = $lessonpages[$pageid]->id;
1329 }
1330 $pageid = $lessonpages[$pageid]->nextpageid;
1331 }
1332 $unseen = array();
1333 foreach ($branchtables as $branchtable) {
1334 // load all of the unseen branch tables into unseen
1335 if (!array_key_exists($branchtable, $seen)) {
1336 $unseen[] = $branchtable;
1337 }
1338 }
1339 if (count($unseen) > 0) {
1340 return $unseen[rand(0, count($unseen)-1)]; // returns a random page id for the next page
1341 } else {
1342 return LESSON_EOL; // has viewed all of the branch tables
1343 }
5e7856af 1344}
1345
4b55d2af 1346/**
1347 * Handles the random jump between a branch table and end of branch or end of lesson (LESSON_RANDOMPAGE).
1348 *
f521f98a 1349 * @param int $lessonid Lesson id.
4b55d2af 1350 * @param int $pageid The id of the page that we are jumping from (?)
1351 * @return int The pageid of a random page that is within a branch table
4b55d2af 1352 **/
f521f98a 1353function lesson_random_question_jump($lessonid, $pageid) {
ac8e16be 1354 // get the lesson pages
f521f98a 1355 if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
ac8e16be 1356 error("Error: could not find records in lesson_pages table");
1357 }
1358
1359 // go up the pages till branch table
1360 while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
1361
1362 if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
1363 break;
1364 }
1365 $pageid = $lessonpages[$pageid]->prevpageid;
1366 }
1367
1368 // get the pages within the branch
1369 $pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
1370
1371 if(count($pagesinbranch) == 0) {
1372 // there are no pages inside the branch, so return the next page
1373 return $lessonpages[$pageid]->nextpageid;
1374 } else {
1375 return $pagesinbranch[rand(0, count($pagesinbranch)-1)]->id; // returns a random page id for the next page
1376 }
5e7856af 1377}
1378
4b55d2af 1379/**
1380 * Check to see if a page is below a branch table (logically).
1381 *
1382 * Will return true if a branch table is found logically above the page.
1383 * Will return false if an end of branch, cluster or the beginning
1384 * of the lesson is found before a branch table.
1385 *
1386 * @param array $pages An array of lesson page objects.
1387 * @param int $pageid Id of the page for testing.
1388 * @return boolean
1389 */
5e7856af 1390function lesson_is_page_in_branch($pages, $pageid) {
ac8e16be 1391 $pageid = $pages[$pageid]->prevpageid; // move up one
1392
1393 // go up the pages till branch table
1394 while (true) {
1395 if ($pageid == 0) { // ran into the beginning of the lesson
1396 return false;
1397 } elseif ($pages[$pageid]->qtype == LESSON_ENDOFBRANCH) { // ran into the end of another branch table
1398 return false;
1399 } elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // do not look beyond a cluster
1400 return false;
1401 } elseif ($pages[$pageid]->qtype == LESSON_BRANCHTABLE) { // hit a branch table
1402 return true;
1403 }
1404 $pageid = $pages[$pageid]->prevpageid;
1405 }
5e7856af 1406
1407}
1408
4b55d2af 1409/**
1410 * Check to see if a page is below a cluster page (logically).
1411 *
1412 * Will return true if a cluster is found logically above the page.
1413 * Will return false if an end of cluster or the beginning
1414 * of the lesson is found before a cluster page.
1415 *
1416 * @param array $pages An array of lesson page objects.
1417 * @param int $pageid Id of the page for testing.
1418 * @return boolean
1419 */
5e7856af 1420function lesson_is_page_in_cluster($pages, $pageid) {
ac8e16be 1421 $pageid = $pages[$pageid]->prevpageid; // move up one
1422
1423 // go up the pages till branch table
1424 while (true) {
1425 if ($pageid == 0) { // ran into the beginning of the lesson
1426 return false;
1427 } elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER) { // ran into the end of another branch table
1428 return false;
1429 } elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // hit a branch table
1430 return true;
1431 }
1432 $pageid = $pages[$pageid]->prevpageid;
1433 }
5e7856af 1434}
1435
4b55d2af 1436/**
1437 * Calculates a user's grade for a lesson.
1438 *
4b55d2af 1439 * @param object $lesson The lesson that the user is taking.
4b55d2af 1440 * @param int $retries The attempt number.
88427c07 1441 * @param int $userid Id of the user (optinal, default current user).
1442 * @return object { nquestions => number of questions answered
1443 attempts => number of question attempts
1444 total => max points possible
1445 earned => points earned by student
1446 grade => calculated percentage grade
1447 nmanual => number of manually graded questions
1448 manualpoints => point value for manually graded questions }
4b55d2af 1449 */
88427c07 1450function lesson_grade($lesson, $ntries, $userid = 0) {
1451 global $USER;
ac8e16be 1452
88427c07 1453 if (empty($userid)) {
1454 $userid = $USER->id;
1455 }
1456
1457 // Zero out everything
1458 $ncorrect = 0;
1459 $nviewed = 0;
1460 $score = 0;
1461 $nmanual = 0;
1462 $manualpoints = 0;
1463 $thegrade = 0;
1464 $nquestions = 0;
1465 $total = 0;
1466 $earned = 0;
1467
1468 if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
1469 userid = $userid AND retry = $ntries", "timeseen")) {
1470 // group each try with its page
1471 $attemptset = array();
1472 foreach ($useranswers as $useranswer) {
1473 $attemptset[$useranswer->pageid][] = $useranswer;
ac8e16be 1474 }
88427c07 1475
1476 // Drop all attempts that go beyond max attempts for the lesson
1477 foreach ($attemptset as $key => $set) {
1478 $attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
1479 }
1480
1481 $pageids = implode(",", array_keys($attemptset));
1482
1483 // get only the pages and their answers that the user answered
1484 $pages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
1485 $answers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
1486
1487 // Number of pages answered
1488 $nquestions = count($pages);
1489
1490 foreach ($attemptset as $attempts) {
1491 if ($lesson->custom) {
1492 $attempt = end($attempts);
1493 // If essay question, handle it, otherwise add to score
1494 if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
ac8e16be 1495 $essayinfo = unserialize($attempt->useranswer);
88427c07 1496 $earned += $essayinfo->score;
1497 $nmanual++;
1498 $manualpoints += $answers[$attempt->answerid]->score;
ac8e16be 1499 } else {
88427c07 1500 $earned += $answers[$attempt->answerid]->score;
1501 }
1502 } else {
1503 foreach ($attempts as $attempt) {
1504 $earned += $attempt->correct;
1505 }
1506 $attempt = end($attempts); // doesn't matter which one
1507 // If essay question, increase numbers
1508 if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
1509 $nmanual++;
1510 $manualpoints++;
ac8e16be 1511 }
1512 }
88427c07 1513 // Number of times answered
1514 $nviewed += count($attempts);
1515 }
1516
1517 if ($lesson->custom) {
ac8e16be 1518 $bestscores = array();
88427c07 1519 // Find the highest possible score per page to get our total
1520 foreach ($answers as $answer) {
46341ab7 1521 if(!isset($bestscores[$answer->pageid])) {
88427c07 1522 $bestscores[$answer->pageid] = $answer->score;
46341ab7 1523 } else if ($bestscores[$answer->pageid] < $answer->score) {
88427c07 1524 $bestscores[$answer->pageid] = $answer->score;
ac8e16be 1525 }
1526 }
88427c07 1527 $total = array_sum($bestscores);
1528 } else {
1529 // Check to make sure the student has answered the minimum questions
1530 if ($lesson->minquestions and $nquestions < $lesson->minquestions) {
1531 // Nope, increase number viewed by the amount of unanswered questions
1532 $total = $nviewed + ($lesson->minquestions - $nquestions);
1533 } else {
1534 $total = $nviewed;
1535 }
ac8e16be 1536 }
88427c07 1537 }
1538
1539 if ($total) { // not zero
1540 $thegrade = round(100 * $earned / $total, 5);
1541 }
1542
1543 // Build the grade information object
1544 $gradeinfo = new stdClass;
1545 $gradeinfo->nquestions = $nquestions;
1546 $gradeinfo->attempts = $nviewed;
1547 $gradeinfo->total = $total;
1548 $gradeinfo->earned = $earned;
1549 $gradeinfo->grade = $thegrade;
1550 $gradeinfo->nmanual = $nmanual;
1551 $gradeinfo->manualpoints = $manualpoints;
1552
1553 return $gradeinfo;
1554}
1555
1556/**
1557 * Prints the on going message to the user.
1558 *
1559 * With custom grading On, displays points
1560 * earned out of total points possible thus far.
1561 * With custom grading Off, displays number of correct
1562 * answers out of total attempted.
1563 *
1564 * @param object $lesson The lesson that the user is taking.
1565 * @return void
1566 **/
1567function lesson_print_ongoing_score($lesson) {
1568 global $USER;
6e1ff5c8 1569 $cm = get_coursemodule_from_instance('lesson', $lesson->id);
1570 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1571
1572 if (has_capability('mod/lesson:manage', $context)) {
88427c07 1573 echo "<p align=\"center\">".get_string('teacherongoingwarning', 'lesson').'</p>';
1574 } else {
1575 $ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
1576 if (isset($USER->modattempts[$lesson->id])) {
1577 $ntries--;
1578 }
1579 $gradeinfo = lesson_grade($lesson, $ntries);
ac8e16be 1580
88427c07 1581 $a = new stdClass;
1582 if ($lesson->custom) {
1583 $a->score = $gradeinfo->earned;
1584 $a->currenthigh = $gradeinfo->total;
1585 print_simple_box(get_string("ongoingcustom", "lesson", $a), "center");
ac8e16be 1586 } else {
88427c07 1587 $a->correct = $gradeinfo->earned;
1588 $a->viewed = $gradeinfo->attempts;
1589 print_simple_box(get_string("ongoingnormal", "lesson", $a), "center");
ac8e16be 1590 }
1591 }
5e7856af 1592}
1593
4b55d2af 1594/**
1595 * Prints tabs for the editing and adding pages. Each tab is a question type.
1596 *
1597 * @param array $qtypes The question types array (may not need to pass this because it is defined in this file)
1598 * @param string $selected Current selected tab
1599 * @param string $link The base href value of the link for the tab
1600 * @param string $onclick Javascript for the tab link
1601 * @return void
1602 */
5e7856af 1603function lesson_qtype_menu($qtypes, $selected="", $link="", $onclick="") {
271fea97 1604 $tabs = array();
1605 $tabrows = array();
1606
9638a1f4 1607 foreach ($qtypes as $qtype => $qtypename) {
4085962a 1608 $tabrows[] = new tabobject($qtype, "$link&amp;qtype=$qtype\" onclick=\"$onclick", $qtypename);
ac8e16be 1609 }
271fea97 1610 $tabs[] = $tabrows;
1611 print_tabs($tabs, $selected);
1612 echo "<input type=\"hidden\" name=\"qtype\" value=\"$selected\" /> \n";
9638a1f4 1613
5e7856af 1614}
1615
62eda6ea 1616/**
1617 * Prints out a Progress Bar which depicts a user's progress within a lesson.
1618 *
1619 * Currently works best with a linear lesson. Clusters are counted as a single page.
1620 * Also, only viewed branch tables and questions that have been answered correctly count
1621 * toward lesson completion (or progress). Only Students can see the Progress bar as well.
1622 *
1623 * @param object $lesson The lesson that the user is currently taking.
1624 * @param object $course The course that the to which the lesson belongs.
1625 * @return boolean The return is not significant as of yet. Will return true/false.
62eda6ea 1626 **/
1627function lesson_print_progress_bar($lesson, $course) {
1628 global $CFG, $USER;
6e1ff5c8 1629 $cm = get_coursemodule_from_instance('lesson', $lesson->id);
1630 $context = get_context_instance(CONTEXT_MODULE, $cm->id);
1631
62eda6ea 1632 // lesson setting to turn progress bar on or off
1633 if (!$lesson->progressbar) {
1634 return false;
1635 }
1636
1637 // catch teachers
6e1ff5c8 1638 if (has_capability('mod/lesson:manage', $context)) {
62eda6ea 1639 notify(get_string('progressbarteacherwarning', 'lesson', $course->teachers));
1640 return false;
1641 }
acab9099 1642 if (!isset($USER->modattempts[$lesson->id])) {
1643 // all of the lesson pages
1644 if (!$pages = get_records('lesson_pages', 'lessonid', $lesson->id)) {
1645 return false;
1646 } else {
1647 foreach ($pages as $page) {
1648 if ($page->prevpageid == 0) {
1649 $pageid = $page->id; // find the first page id
1650 break;
1651 }
62eda6ea 1652 }
1653 }
62eda6ea 1654
acab9099 1655 // current attempt number
1656 if (!$ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id)) {
1657 $ntries = 0; // may not be necessary
1658 }
62eda6ea 1659
acab9099 1660 $viewedpageids = array();
62eda6ea 1661
acab9099 1662 // collect all of the correctly answered questions
1663 if ($viewedpages = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries AND correct = 1", 'timeseen DESC', 'pageid, id')) {
1664 $viewedpageids = array_keys($viewedpages);
1665 }
1666 // collect all of the branch tables viewed
1667 if ($viewedbranches = get_records_select("lesson_branch", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries", 'timeseen DESC', 'pageid, id')) {
1668 $viewedpageids = array_merge($viewedpageids, array_keys($viewedbranches));
1669 }
1670
1671 // Filter out the following pages:
1672 // End of Cluster
1673 // End of Branch
1674 // Pages found inside of Clusters
1675 // Do not filter out Cluster Page(s) because we count a cluster as one.
1676 // By keeping the cluster page, we get our 1
1677 $validpages = array();
1678 while ($pageid != 0) {
1679 if ($pages[$pageid]->qtype == LESSON_CLUSTER) {
1680 $clusterpageid = $pageid; // copy it
1681 $validpages[$clusterpageid] = 1; // add the cluster page as a valid page
1682 $pageid = $pages[$pageid]->nextpageid; // get next page
62eda6ea 1683
acab9099 1684 // now, remove all necessary viewed paged ids from the viewedpageids array.
1685 while ($pages[$pageid]->qtype != LESSON_ENDOFCLUSTER and $pageid != 0) {
1686 if (in_array($pageid, $viewedpageids)) {
1687 unset($viewedpageids[array_search($pageid, $viewedpageids)]); // remove it
1688 // since the user did see one page in the cluster, add the cluster pageid to the viewedpageids
1689 if (!in_array($clusterpageid, $viewedpageids)) {
1690 $viewedpageids[] = $clusterpageid;
1691 }
62eda6ea 1692 }
acab9099 1693 $pageid = $pages[$pageid]->nextpageid;
62eda6ea 1694 }
acab9099 1695 } elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER or $pages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
1696 // dont count these, just go to next
1697 $pageid = $pages[$pageid]->nextpageid;
1698 } else {
1699 // a counted page
1700 $validpages[$pageid] = 1;
62eda6ea 1701 $pageid = $pages[$pageid]->nextpageid;
1702 }
acab9099 1703 }
62eda6ea 1704
acab9099 1705 // progress calculation as a percent
1706 $progress = round(count($viewedpageids)/count($validpages), 2) * 100;
1707 } else {
1708 $progress = 100;
1709 }
62eda6ea 1710
1711 // print out the Progress Bar. Attempted to put as much as possible in the style sheets.
1712 echo '<div class="progress_bar" align="center">';
1713 echo '<table class="progress_bar_table"><tr>';
1714 if ($progress != 0) { // some browsers do not repsect the 0 width.
4085962a 1715 echo '<td style="width:'.$progress.'%;" class="progress_bar_completed">';
62eda6ea 1716 echo '</td>';
1717 }
1718 echo '<td class="progress_bar_todo">';
1719 echo '<div class="progress_bar_token"></div>';
1720 echo '</td>';
1721 echo '</tr></table>';
1722 echo '</div>';
1723
1724 return true;
1725}
1726
1727/**
1728 * Determines if a user can view the left menu. The determining factor
1729 * is whether a user has a grade greater than or equal to the lesson setting
1730 * of displayleftif
1731 *
1732 * @param object $lesson Lesson object of the current lesson
1733 * @return boolean 0 if the user cannot see, or $lesson->displayleft to keep displayleft unchanged
62eda6ea 1734 **/
1735function lesson_displayleftif($lesson) {
1736 global $CFG, $USER;
1737
1738 if (!empty($lesson->displayleftif)) {
1739 // get the current user's max grade for this lesson
1740 if ($maxgrade = get_record_sql('SELECT userid, MAX(grade) AS maxgrade FROM '.$CFG->prefix.'lesson_grades WHERE userid = '.$USER->id.' AND lessonid = '.$lesson->id.' GROUP BY userid')) {
1741 if ($maxgrade->maxgrade < $lesson->displayleftif) {
1742 return 0; // turn off the displayleft
1743 }
1744 } else {
1745 return 0; // no grades
1746 }
1747 }
1748
1749 // if we get to here, keep the original state of displayleft lesson setting
1750 return $lesson->displayleft;
1751}
5e7856af 1752
f521f98a 1753/**
1754 * If there is a media file associated with this
1755 * lesson, then print it in a block.
1756 *
1757 * @param int $cmid Course Module ID for this lesson
1758 * @param object $lesson Full lesson record object
1759 * @return void
1760 **/
1761function print_mediafile_block($cmid, $lesson) {
1762 if (!empty($lesson->mediafile)) {
1763 $url = '/mod/lesson/mediafile.php?id='.$cmid;
1764 $options = 'menubar=0,location=0,left=5,top=5,scrollbars,resizable,width='. $lesson->mediawidth .',height='. $lesson->mediaheight;
1765 $name = 'lessonmediafile';
1766
1767 $content = link_to_popup_window ($url, $name, get_string('mediafilepopup', 'lesson'), '', '', get_string('mediafilepopup', 'lesson'), $options, true);
1768 $content .= helpbutton("mediafilestudent", get_string("mediafile", "lesson"), "lesson", true, false, '', true);
1769
1770 print_side_block(get_string('linkedmedia', 'lesson'), $content, NULL, NULL, '', array('class' => 'mediafile'), get_string('linkedmedia', 'lesson'));
1771 }
1772}
1773
1774/**
1775 * If a timed lesson and not a teacher, then
1776 * print the clock
1777 *
1778 * @param int $cmid Course Module ID for this lesson
1779 * @param object $lesson Full lesson record object
1780 * @param object $timer Full timer record object
1781 * @return void
1782 **/
1783function print_clock_block($cmid, $lesson, $timer) {
1784 global $CFG;
1785
1786 $context = get_context_instance(CONTEXT_MODULE, $cmid);
1787
1788 // Display for timed lessons and for students only
1789 if($lesson->timed and !has_capability('mod/lesson:manage', $context) and !empty($timer)) {
1790 $content = '<script type="text/javascript" charset="utf-8">'."\n";
1791 $content .= "<!--\n";
1792 $content .= ' var starttime = '.$timer->starttime.";\n";
1793 $content .= ' var servertime = '.time().";\n";
1794 $content .= ' var testlength = '.($lesson->maxtime * 60).";\n";
1795 $content .= ' document.write(\'<script type="text/javascript" src="'.$CFG->wwwroot.'/mod/lesson/timer.js" charset="utf-8"><\/script>\');'."\n";
1796 $content .= " window.onload = function () { show_clock(); };\n";
1797 $content .= "// -->\n";
1798 $content .= "</script>\n";
1799 $content .= "<noscript>\n";
1800 $content .= lesson_print_time_remaining($timer->starttime, $lesson->maxtime, true)."\n";
1801 $content .= "</noscript>\n";
1802
1803 print_side_block(get_string('timeremaining', 'lesson'), $content, NULL, NULL, '', array('class' => 'clock'), get_string('timeremaining', 'lesson'));
1804 }
1805}
1806
1807/**
1808 * If left menu is turned on, then this will
1809 * print the menu in a block
1810 *
1811 * @param int $cmid Course Module ID for this lesson
1812 * @param object $lesson Full lesson record object
1813 * @return void
1814 **/
1815function print_menu_block($cmid, $lesson) {
1816 global $CFG;
1817
1818 if ($lesson->displayleft) {
1819 $pageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0);
1820 $pages = get_records_select('lesson_pages', "lessonid = $lesson->id");
1821 $currentpageid = optional_param('pageid', $pageid, PARAM_INT);
1822
1823 if ($pageid and $pages) {
1824 $content = '<a href="#maincontent" class="skip">'.get_string('skip', 'lesson')."</a>\n<div class=\"menuwrapper\">\n<ul>\n";
1825
1826 while ($pageid != 0) {
1827 $page = $pages[$pageid];
1828
1829 // Only process branch tables with display turned on
1830 if ($page->qtype == LESSON_BRANCHTABLE and $page->display) {
1831 if ($page->id == $currentpageid) {
1832 $content .= '<li class="selected">'.format_string($page->title,true)."</a></li>\n";
1833 } else {
1834 $content .= "<li class=\"notselected\"><a href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cmid&amp;pageid=$page->id\">".format_string($page->title,true)."</a></li>\n";
1835 }
1836
1837 }
1838 $pageid = $page->nextpageid;
1839 }
1840 $content .= "</ul>\n</div>\n";
1841 print_side_block(get_string('lessonmenu', 'lesson'), $content, NULL, NULL, '', array('class' => 'menu'), get_string('lessonmenu', 'lesson'));
1842 }
1843 }
1844}
1845
2a488ba5 1846?>