mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
1836 lines
66 KiB
PHP
1836 lines
66 KiB
PHP
<?php // $Id$
|
|
/**
|
|
* Local library file for Lesson. These are non-standard functions that are used
|
|
* only by Lesson.
|
|
*
|
|
* @version $Id$
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
|
* @package lesson
|
|
**/
|
|
|
|
/**
|
|
* Next page -> any page not seen before
|
|
*/
|
|
if (!defined("LESSON_UNSEENPAGE")) {
|
|
define("LESSON_UNSEENPAGE", 1); // Next page -> any page not seen before
|
|
}
|
|
/**
|
|
* Next page -> any page not answered correctly
|
|
*/
|
|
if (!defined("LESSON_UNANSWEREDPAGE")) {
|
|
define("LESSON_UNANSWEREDPAGE", 2); // Next page -> any page not answered correctly
|
|
}
|
|
|
|
/**
|
|
* Define different lesson flows for next page
|
|
*/
|
|
$LESSON_NEXTPAGE_ACTION = array (0 => get_string("normal", "lesson"),
|
|
LESSON_UNSEENPAGE => get_string("showanunseenpage", "lesson"),
|
|
LESSON_UNANSWEREDPAGE => get_string("showanunansweredpage", "lesson") );
|
|
|
|
// Lesson jump types defined
|
|
// TODO: instead of using define statements, create an array with all the jump values
|
|
|
|
/**
|
|
* Jump to Next Page
|
|
*/
|
|
if (!defined("LESSON_NEXTPAGE")) {
|
|
define("LESSON_NEXTPAGE", -1);
|
|
}
|
|
/**
|
|
* End of Lesson
|
|
*/
|
|
if (!defined("LESSON_EOL")) {
|
|
define("LESSON_EOL", -9);
|
|
}
|
|
/**
|
|
* Jump to an unseen page within a branch and end of branch or end of lesson
|
|
*/
|
|
if (!defined("LESSON_UNSEENBRANCHPAGE")) {
|
|
define("LESSON_UNSEENBRANCHPAGE", -50);
|
|
}
|
|
/**
|
|
* Jump to Previous Page
|
|
*/
|
|
if (!defined("LESSON_PREVIOUSPAGE")) {
|
|
define("LESSON_PREVIOUSPAGE", -40);
|
|
}
|
|
/**
|
|
* Jump to a random page within a branch and end of branch or end of lesson
|
|
*/
|
|
if (!defined("LESSON_RANDOMPAGE")) {
|
|
define("LESSON_RANDOMPAGE", -60);
|
|
}
|
|
/**
|
|
* Jump to a random Branch
|
|
*/
|
|
if (!defined("LESSON_RANDOMBRANCH")) {
|
|
define("LESSON_RANDOMBRANCH", -70);
|
|
}
|
|
/**
|
|
* Cluster Jump
|
|
*/
|
|
if (!defined("LESSON_CLUSTERJUMP")) {
|
|
define("LESSON_CLUSTERJUMP", -80);
|
|
}
|
|
/**
|
|
* Undefined
|
|
*/
|
|
if (!defined("LESSON_UNDEFINED")) {
|
|
define("LESSON_UNDEFINED", -99);
|
|
}
|
|
|
|
// Lesson question types defined
|
|
|
|
/**
|
|
* Short answer question type
|
|
*/
|
|
if (!defined("LESSON_SHORTANSWER")) {
|
|
define("LESSON_SHORTANSWER", "1");
|
|
}
|
|
/**
|
|
* True/False question type
|
|
*/
|
|
if (!defined("LESSON_TRUEFALSE")) {
|
|
define("LESSON_TRUEFALSE", "2");
|
|
}
|
|
/**
|
|
* Multichoice question type
|
|
*
|
|
* If you change the value of this then you need
|
|
* to change it in restorelib.php as well.
|
|
*/
|
|
if (!defined("LESSON_MULTICHOICE")) {
|
|
define("LESSON_MULTICHOICE", "3");
|
|
}
|
|
/**
|
|
* Random question type - not used
|
|
*/
|
|
if (!defined("LESSON_RANDOM")) {
|
|
define("LESSON_RANDOM", "4");
|
|
}
|
|
/**
|
|
* Matching question type
|
|
*
|
|
* If you change the value of this then you need
|
|
* to change it in restorelib.php, in mysql.php
|
|
* and postgres7.php as well.
|
|
*/
|
|
if (!defined("LESSON_MATCHING")) {
|
|
define("LESSON_MATCHING", "5");
|
|
}
|
|
/**
|
|
* Not sure - not used
|
|
*/
|
|
if (!defined("LESSON_RANDOMSAMATCH")) {
|
|
define("LESSON_RANDOMSAMATCH", "6");
|
|
}
|
|
/**
|
|
* Not sure - not used
|
|
*/
|
|
if (!defined("LESSON_DESCRIPTION")) {
|
|
define("LESSON_DESCRIPTION", "7");
|
|
}
|
|
/**
|
|
* Numerical question type
|
|
*/
|
|
if (!defined("LESSON_NUMERICAL")) {
|
|
define("LESSON_NUMERICAL", "8");
|
|
}
|
|
/**
|
|
* Multichoice with multianswer question type
|
|
*/
|
|
if (!defined("LESSON_MULTIANSWER")) {
|
|
define("LESSON_MULTIANSWER", "9");
|
|
}
|
|
/**
|
|
* Essay question type
|
|
*/
|
|
if (!defined("LESSON_ESSAY")) {
|
|
define("LESSON_ESSAY", "10");
|
|
}
|
|
|
|
/**
|
|
* Lesson question type array.
|
|
* Contains all question types used
|
|
*/
|
|
$LESSON_QUESTION_TYPE = array ( LESSON_MULTICHOICE => get_string("multichoice", "quiz"),
|
|
LESSON_TRUEFALSE => get_string("truefalse", "quiz"),
|
|
LESSON_SHORTANSWER => get_string("shortanswer", "quiz"),
|
|
LESSON_NUMERICAL => get_string("numerical", "quiz"),
|
|
LESSON_MATCHING => get_string("match", "quiz"),
|
|
LESSON_ESSAY => get_string("essay", "lesson")
|
|
// LESSON_DESCRIPTION => get_string("description", "quiz"),
|
|
// LESSON_RANDOM => get_string("random", "quiz"),
|
|
// LESSON_RANDOMSAMATCH => get_string("randomsamatch", "quiz"),
|
|
// LESSON_MULTIANSWER => get_string("multianswer", "quiz"),
|
|
);
|
|
|
|
// Non-question page types
|
|
|
|
/**
|
|
* Branch Table page
|
|
*/
|
|
if (!defined("LESSON_BRANCHTABLE")) {
|
|
define("LESSON_BRANCHTABLE", "20");
|
|
}
|
|
/**
|
|
* End of Branch page
|
|
*/
|
|
if (!defined("LESSON_ENDOFBRANCH")) {
|
|
define("LESSON_ENDOFBRANCH", "21");
|
|
}
|
|
/**
|
|
* Start of Cluster page
|
|
*/
|
|
if (!defined("LESSON_CLUSTER")) {
|
|
define("LESSON_CLUSTER", "30");
|
|
}
|
|
/**
|
|
* End of Cluster page
|
|
*/
|
|
if (!defined("LESSON_ENDOFCLUSTER")) {
|
|
define("LESSON_ENDOFCLUSTER", "31");
|
|
}
|
|
|
|
// other variables...
|
|
|
|
/**
|
|
* Flag for the editor for the answer textarea.
|
|
*/
|
|
if (!defined("LESSON_ANSWER_EDITOR")) {
|
|
define("LESSON_ANSWER_EDITOR", "1");
|
|
}
|
|
/**
|
|
* Flag for the editor for the response textarea.
|
|
*/
|
|
if (!defined("LESSON_RESPONSE_EDITOR")) {
|
|
define("LESSON_RESPONSE_EDITOR", "2");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
/// Any other lesson functions go here. Each of them must have a name that
|
|
/// starts with lesson_
|
|
|
|
/**
|
|
* Print the standard header for lesson module
|
|
*
|
|
* @uses $CFG
|
|
* @uses $USER
|
|
* @param object $cm Course module record object
|
|
* @param object $course Couse record object
|
|
* @param object $lesson Lesson module record object
|
|
* @param string $currenttab Current tab for the lesson tabs
|
|
* @return boolean
|
|
**/
|
|
function lesson_print_header($cm, $course, $lesson, $currenttab = '') {
|
|
global $CFG, $USER;
|
|
|
|
$strlesson = get_string('modulename', 'lesson');
|
|
$strname = format_string($lesson->name, true, $course->id);
|
|
|
|
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
|
|
|
if (has_capability('mod/lesson:edit', $context)) {
|
|
$button = update_module_button($cm->id, $course->id, $strlesson);
|
|
} else {
|
|
$button = '';
|
|
}
|
|
|
|
/// Header setup
|
|
$navigation = build_navigation('', $cm);
|
|
|
|
/// Print header, heading, tabs and messages
|
|
print_header("$course->shortname: $strname", $course->fullname, $navigation,
|
|
'', '', true, $button, navmenu($course, $cm));
|
|
|
|
if (has_capability('mod/lesson:manage', $context)) {
|
|
print_heading_with_help($strname, "overview", "lesson");
|
|
|
|
if (!empty($currenttab)) {
|
|
include($CFG->dirroot.'/mod/lesson/tabs.php');
|
|
}
|
|
} else {
|
|
print_heading($strname);
|
|
}
|
|
|
|
lesson_print_messages();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns course module, course and module instance given
|
|
* either the course module ID or a lesson module ID.
|
|
*
|
|
* @param int $cmid Course Module ID
|
|
* @param int $lessonid Lesson module instance ID
|
|
* @return array array($cm, $course, $lesson)
|
|
**/
|
|
function lesson_get_basics($cmid = 0, $lessonid = 0) {
|
|
if ($cmid) {
|
|
if (!$cm = get_coursemodule_from_id('lesson', $cmid)) {
|
|
print_error('Course Module ID was incorrect');
|
|
}
|
|
if (!$course = get_record('course', 'id', $cm->course)) {
|
|
print_error('Course is misconfigured');
|
|
}
|
|
if (!$lesson = get_record('lesson', 'id', $cm->instance)) {
|
|
print_error('Course module is incorrect');
|
|
}
|
|
} else if ($lessonid) {
|
|
if (!$lesson = get_record('lesson', 'id', $lessonid)) {
|
|
print_error('Course module is incorrect');
|
|
}
|
|
if (!$course = get_record('course', 'id', $lesson->course)) {
|
|
print_error('Course is misconfigured');
|
|
}
|
|
if (!$cm = get_coursemodule_from_instance('lesson', $lesson->id, $course->id)) {
|
|
print_error('Course Module ID was incorrect');
|
|
}
|
|
} else {
|
|
print_error('No course module ID or lesson ID were passed');
|
|
}
|
|
|
|
return array($cm, $course, $lesson);
|
|
}
|
|
|
|
/**
|
|
* Sets a message to be printed. Messages are printed
|
|
* by calling {@link lesson_print_messages()}.
|
|
*
|
|
* @uses $SESSION
|
|
* @param string $message The message to be printed
|
|
* @param string $class Class to be passed to {@link notify()}. Usually notifyproblem or notifysuccess.
|
|
* @param string $align Alignment of the message
|
|
* @return boolean
|
|
**/
|
|
function lesson_set_message($message, $class="notifyproblem", $align='center') {
|
|
global $SESSION;
|
|
|
|
if (empty($SESSION->lesson_messages) or !is_array($SESSION->lesson_messages)) {
|
|
$SESSION->lesson_messages = array();
|
|
}
|
|
|
|
$SESSION->lesson_messages[] = array($message, $class, $align);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Print all set messages.
|
|
*
|
|
* See {@link lesson_set_message()} for setting messages.
|
|
*
|
|
* Uses {@link notify()} to print the messages.
|
|
*
|
|
* @uses $SESSION
|
|
* @return boolean
|
|
**/
|
|
function lesson_print_messages() {
|
|
global $SESSION;
|
|
|
|
if (empty($SESSION->lesson_messages)) {
|
|
// No messages to print
|
|
return true;
|
|
}
|
|
|
|
foreach($SESSION->lesson_messages as $message) {
|
|
notify($message[0], $message[1], $message[2]);
|
|
}
|
|
|
|
// Reset
|
|
unset($SESSION->lesson_messages);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Prints a lesson link that submits a form.
|
|
*
|
|
* If Javascript is disabled, then a regular submit button is printed
|
|
*
|
|
* @param string $name Name of the link or button
|
|
* @param string $form The name of the form to be submitted
|
|
* @param string $align Alignment of the button
|
|
* @param string $class Class names to add to the div wrapper
|
|
* @param string $title Title for the link (Not used if javascript is disabled)
|
|
* @param string $id ID tag
|
|
* @param boolean $return Return flag
|
|
* @return mixed boolean/html
|
|
**/
|
|
function lesson_print_submit_link($name, $form, $align = 'center', $class='standardbutton', $title = '', $id = '', $return = false) {
|
|
if (!empty($align)) {
|
|
$align = " style=\"text-align:$align\"";
|
|
}
|
|
if (!empty($id)) {
|
|
$id = " id=\"$id\"";
|
|
}
|
|
if (empty($title)) {
|
|
$title = $name;
|
|
}
|
|
|
|
$output = "<div class=\"lessonbutton $class\" $align>\n";
|
|
$output .= "<input type=\"submit\" value=\"$name\" $align $id />";
|
|
$output .= "</div>\n";
|
|
|
|
if ($return) {
|
|
return $output;
|
|
} else {
|
|
echo $output;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints a time remaining in the following format: H:MM:SS
|
|
*
|
|
* @param int $starttime Time when the lesson started
|
|
* @param int $maxtime Length of the lesson
|
|
* @param boolean $return Return output switch
|
|
* @return mixed boolean/string
|
|
**/
|
|
function lesson_print_time_remaining($starttime, $maxtime, $return = false) {
|
|
// Calculate hours, minutes and seconds
|
|
$timeleft = $starttime + $maxtime * 60 - time();
|
|
$hours = floor($timeleft/3600);
|
|
$timeleft = $timeleft - ($hours * 3600);
|
|
$minutes = floor($timeleft/60);
|
|
$secs = $timeleft - ($minutes * 60);
|
|
|
|
if ($minutes < 10) {
|
|
$minutes = "0$minutes";
|
|
}
|
|
if ($secs < 10) {
|
|
$secs = "0$secs";
|
|
}
|
|
$output = array();
|
|
$output[] = $hours;
|
|
$output[] = $minutes;
|
|
$output[] = $secs;
|
|
|
|
$output = implode(':', $output);
|
|
|
|
if ($return) {
|
|
return $output;
|
|
} else {
|
|
echo $output;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints the page action buttons
|
|
*
|
|
* Move/Edit/Preview/Delete
|
|
*
|
|
* @uses $CFG
|
|
* @param int $cmid Course Module ID
|
|
* @param object $page Page record
|
|
* @param boolean $printmove Flag to print the move button or not
|
|
* @param boolean $printaddpage Flag to print the add page drop-down or not
|
|
* @param boolean $return Return flag
|
|
* @return mixed boolean/string
|
|
**/
|
|
function lesson_print_page_actions($cmid, $page, $printmove, $printaddpage = false, $return = false) {
|
|
global $CFG;
|
|
|
|
$context = get_context_instance(CONTEXT_MODULE, $cmid);
|
|
$actions = array();
|
|
|
|
if (has_capability('mod/lesson:edit', $context)) {
|
|
if ($printmove) {
|
|
$actions[] = "<a title=\"".get_string('move')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&action=move&pageid=$page->id\">
|
|
<img src=\"$CFG->pixpath/t/move.gif\" class=\"iconsmall\" alt=\"".get_string('move')."\" /></a>\n";
|
|
}
|
|
$actions[] = "<a title=\"".get_string('update')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&action=editpage&pageid=$page->id\">
|
|
<img src=\"$CFG->pixpath/t/edit.gif\" class=\"iconsmall\" alt=\"".get_string('update')."\" /></a>\n";
|
|
|
|
$actions[] = "<a title=\"".get_string('preview')."\" href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cmid&pageid=$page->id\">
|
|
<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"".get_string('preview')."\" /></a>\n";
|
|
|
|
$actions[] = "<a title=\"".get_string('delete')."\" href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&sesskey=".sesskey()."&action=confirmdelete&pageid=$page->id\">
|
|
<img src=\"$CFG->pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"".get_string('delete')."\" /></a>\n";
|
|
|
|
if ($printaddpage) {
|
|
// Add page drop-down
|
|
$options = array();
|
|
$options['addcluster&sesskey='.sesskey()] = get_string('clustertitle', 'lesson');
|
|
$options['addendofcluster&sesskey='.sesskey()] = get_string('endofclustertitle', 'lesson');
|
|
$options['addbranchtable'] = get_string('branchtable', 'lesson');
|
|
$options['addendofbranch&sesskey='.sesskey()] = get_string('endofbranch', 'lesson');
|
|
$options['addpage'] = get_string('question', 'lesson');
|
|
// Base url
|
|
$common = "$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&pageid=$page->id&action=";
|
|
|
|
$actions[] = popup_form($common, $options, "addpage_$page->id", '', get_string('addpage', 'lesson').'...', '', '', true);
|
|
}
|
|
}
|
|
|
|
$actions = implode(' ', $actions);
|
|
|
|
if ($return) {
|
|
return $actions;
|
|
} else {
|
|
echo $actions;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints the add links in expanded view or single view when editing
|
|
*
|
|
* @uses $CFG
|
|
* @param int $cmid Course Module ID
|
|
* @param int $prevpageid Previous page id
|
|
* @param boolean $return Return flag
|
|
* @return mixed boolean/string
|
|
* @todo &pageid does not make sense, it is prevpageid
|
|
**/
|
|
function lesson_print_add_links($cmid, $prevpageid, $return = false) {
|
|
global $CFG;
|
|
|
|
$context = get_context_instance(CONTEXT_MODULE, $cmid);
|
|
|
|
$links = '';
|
|
if (has_capability('mod/lesson:edit', $context)) {
|
|
$links = array();
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/import.php?id=$cmid&pageid=$prevpageid\">".
|
|
get_string('importquestions', 'lesson').'</a>';
|
|
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&sesskey=".sesskey()."&action=addcluster&pageid=$prevpageid\">".
|
|
get_string('addcluster', 'lesson').'</a>';
|
|
|
|
if ($prevpageid != 0) {
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&sesskey=".sesskey()."&action=addendofcluster&pageid=$prevpageid\">".
|
|
get_string('addendofcluster', 'lesson').'</a>';
|
|
}
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&action=addbranchtable&pageid=$prevpageid\">".
|
|
get_string('addabranchtable', 'lesson').'</a>';
|
|
|
|
if ($prevpageid != 0) {
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&sesskey=".sesskey()."&action=addendofbranch&pageid=$prevpageid\">".
|
|
get_string('addanendofbranch', 'lesson').'</a>';
|
|
}
|
|
|
|
$links[] = "<a href=\"$CFG->wwwroot/mod/lesson/lesson.php?id=$cmid&action=addpage&pageid=$prevpageid\">".
|
|
get_string('addaquestionpagehere', 'lesson').'</a>';
|
|
|
|
$links = implode(" | \n", $links);
|
|
$links = "\n<div class=\"addlinks\">\n$links\n</div>\n";
|
|
}
|
|
|
|
if ($return) {
|
|
return $links;
|
|
} else {
|
|
echo $links;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the string for a page type
|
|
*
|
|
* @uses $LESSON_QUESTION_TYPE
|
|
* @param int $qtype Page type
|
|
* @return string
|
|
**/
|
|
function lesson_get_qtype_name($qtype) {
|
|
global $LESSON_QUESTION_TYPE;
|
|
switch ($qtype) {
|
|
case LESSON_ESSAY :
|
|
case LESSON_SHORTANSWER :
|
|
case LESSON_MULTICHOICE :
|
|
case LESSON_MATCHING :
|
|
case LESSON_TRUEFALSE :
|
|
case LESSON_NUMERICAL :
|
|
return $LESSON_QUESTION_TYPE[$qtype];
|
|
break;
|
|
case LESSON_BRANCHTABLE :
|
|
return get_string("branchtable", "lesson");
|
|
break;
|
|
case LESSON_ENDOFBRANCH :
|
|
return get_string("endofbranch", "lesson");
|
|
break;
|
|
case LESSON_CLUSTER :
|
|
return get_string("clustertitle", "lesson");
|
|
break;
|
|
case LESSON_ENDOFCLUSTER :
|
|
return get_string("endofclustertitle", "lesson");
|
|
break;
|
|
default:
|
|
return '';
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the string for a jump name
|
|
*
|
|
* @param int $jumpto Jump code or page ID
|
|
* @return string
|
|
**/
|
|
function lesson_get_jump_name($jumpto) {
|
|
if ($jumpto == 0) {
|
|
$jumptitle = get_string('thispage', 'lesson');
|
|
} elseif ($jumpto == LESSON_NEXTPAGE) {
|
|
$jumptitle = get_string('nextpage', 'lesson');
|
|
} elseif ($jumpto == LESSON_EOL) {
|
|
$jumptitle = get_string('endoflesson', 'lesson');
|
|
} elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
|
|
$jumptitle = get_string('unseenpageinbranch', 'lesson');
|
|
} elseif ($jumpto == LESSON_PREVIOUSPAGE) {
|
|
$jumptitle = get_string('previouspage', 'lesson');
|
|
} elseif ($jumpto == LESSON_RANDOMPAGE) {
|
|
$jumptitle = get_string('randompageinbranch', 'lesson');
|
|
} elseif ($jumpto == LESSON_RANDOMBRANCH) {
|
|
$jumptitle = get_string('randombranch', 'lesson');
|
|
} elseif ($jumpto == LESSON_CLUSTERJUMP) {
|
|
$jumptitle = get_string('clusterjump', 'lesson');
|
|
} else {
|
|
if (!$jumptitle = get_field('lesson_pages', 'title', 'id', $jumpto)) {
|
|
$jumptitle = '<strong>'.get_string('notdefined', 'lesson').'</strong>';
|
|
}
|
|
}
|
|
|
|
return format_string($jumptitle,true);
|
|
}
|
|
|
|
/**
|
|
* Given some question info and some data about the the answers
|
|
* this function parses, organises and saves the question
|
|
*
|
|
* This is only used when IMPORTING questions and is only called
|
|
* from format.php
|
|
* Lifted from mod/quiz/lib.php -
|
|
* 1. all reference to oldanswers removed
|
|
* 2. all reference to quiz_multichoice table removed
|
|
* 3. In SHORTANSWER questions usecase is store in the qoption field
|
|
* 4. In NUMERIC questions store the range as two answers
|
|
* 5. TRUEFALSE options are ignored
|
|
* 6. For MULTICHOICE questions with more than one answer the qoption field is true
|
|
*
|
|
* @param opject $question Contains question data like question, type and answers.
|
|
* @return object Returns $result->error or $result->notice.
|
|
**/
|
|
function lesson_save_question_options($question) {
|
|
|
|
$timenow = time();
|
|
switch ($question->qtype) {
|
|
case LESSON_SHORTANSWER:
|
|
|
|
$answers = array();
|
|
$maxfraction = -1;
|
|
|
|
// Insert all the new answers
|
|
foreach ($question->answer as $key => $dataanswer) {
|
|
if ($dataanswer != "") {
|
|
$answer = new stdClass;
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
if ($question->fraction[$key] >=0.5) {
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
}
|
|
$answer->timecreated = $timenow;
|
|
$answer->grade = $question->fraction[$key] * 100;
|
|
$answer->answer = $dataanswer;
|
|
$answer->response = $question->feedback[$key];
|
|
if (!$answer->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert shortanswer quiz answer!";
|
|
return $result;
|
|
}
|
|
$answers[] = $answer->id;
|
|
if ($question->fraction[$key] > $maxfraction) {
|
|
$maxfraction = $question->fraction[$key];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// Perform sanity checks on fractional grades
|
|
if ($maxfraction != 1) {
|
|
$maxfraction = $maxfraction * 100;
|
|
$result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
|
|
return $result;
|
|
}
|
|
break;
|
|
|
|
case LESSON_NUMERICAL: // Note similarities to SHORTANSWER
|
|
|
|
$answers = array();
|
|
$maxfraction = -1;
|
|
|
|
|
|
// for each answer store the pair of min and max values even if they are the same
|
|
foreach ($question->answer as $key => $dataanswer) {
|
|
if ($dataanswer != "") {
|
|
$answer = new stdClass;
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
$answer->timecreated = $timenow;
|
|
$answer->grade = $question->fraction[$key] * 100;
|
|
$min = $question->answer[$key] - $question->tolerance[$key];
|
|
$max = $question->answer[$key] + $question->tolerance[$key];
|
|
$answer->answer = $min.":".$max;
|
|
// $answer->answer = $question->min[$key].":".$question->max[$key]; original line for min/max
|
|
$answer->response = $question->feedback[$key];
|
|
if (!$answer->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert numerical quiz answer!";
|
|
return $result;
|
|
}
|
|
|
|
$answers[] = $answer->id;
|
|
if ($question->fraction[$key] > $maxfraction) {
|
|
$maxfraction = $question->fraction[$key];
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Perform sanity checks on fractional grades
|
|
if ($maxfraction != 1) {
|
|
$maxfraction = $maxfraction * 100;
|
|
$result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
|
|
return $result;
|
|
}
|
|
break;
|
|
|
|
|
|
case LESSON_TRUEFALSE:
|
|
|
|
// the truth
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
$answer->timecreated = $timenow;
|
|
$answer->answer = get_string("true", "quiz");
|
|
$answer->grade = $question->answer * 100;
|
|
if ($answer->grade > 50 ) {
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
}
|
|
if (isset($question->feedbacktrue)) {
|
|
$answer->response = $question->feedbacktrue;
|
|
}
|
|
if (!$true->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert quiz answer \"true\")!";
|
|
return $result;
|
|
}
|
|
|
|
// the lie
|
|
$answer = new stdClass;
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
$answer->timecreated = $timenow;
|
|
$answer->answer = get_string("false", "quiz");
|
|
$answer->grade = (1 - (int)$question->answer) * 100;
|
|
if ($answer->grade > 50 ) {
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
}
|
|
if (isset($question->feedbackfalse)) {
|
|
$answer->response = $question->feedbackfalse;
|
|
}
|
|
if (!$false->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert quiz answer \"false\")!";
|
|
return $result;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case LESSON_MULTICHOICE:
|
|
|
|
$totalfraction = 0;
|
|
$maxfraction = -1;
|
|
|
|
$answers = array();
|
|
|
|
// Insert all the new answers
|
|
foreach ($question->answer as $key => $dataanswer) {
|
|
if ($dataanswer != "") {
|
|
$answer = new stdClass;
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
$answer->timecreated = $timenow;
|
|
$answer->grade = $question->fraction[$key] * 100;
|
|
// changed some defaults
|
|
/* Original Code
|
|
if ($answer->grade > 50 ) {
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
}
|
|
Replaced with: */
|
|
if ($answer->grade > 50 ) {
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
$answer->score = 1;
|
|
}
|
|
// end Replace
|
|
$answer->answer = $dataanswer;
|
|
$answer->response = $question->feedback[$key];
|
|
if (!$answer->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert multichoice quiz answer! ";
|
|
return $result;
|
|
}
|
|
// for Sanity checks
|
|
if ($question->fraction[$key] > 0) {
|
|
$totalfraction += $question->fraction[$key];
|
|
}
|
|
if ($question->fraction[$key] > $maxfraction) {
|
|
$maxfraction = $question->fraction[$key];
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Perform sanity checks on fractional grades
|
|
if ($question->single) {
|
|
if ($maxfraction != 1) {
|
|
$maxfraction = $maxfraction * 100;
|
|
$result->notice = get_string("fractionsnomax", "quiz", $maxfraction);
|
|
return $result;
|
|
}
|
|
} else {
|
|
$totalfraction = round($totalfraction,2);
|
|
if ($totalfraction != 1) {
|
|
$totalfraction = $totalfraction * 100;
|
|
$result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction);
|
|
return $result;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LESSON_MATCHING:
|
|
|
|
$subquestions = array();
|
|
|
|
$i = 0;
|
|
// Insert all the new question+answer pairs
|
|
foreach ($question->subquestions as $key => $questiontext) {
|
|
$answertext = $question->subanswers[$key];
|
|
if (!empty($questiontext) and !empty($answertext)) {
|
|
$answer = new stdClass;
|
|
$answer->lessonid = $question->lessonid;
|
|
$answer->pageid = $question->id;
|
|
$answer->timecreated = $timenow;
|
|
$answer->answer = $questiontext;
|
|
$answer->response = $answertext;
|
|
if ($i == 0) {
|
|
// first answer contains the correct answer jump
|
|
$answer->jumpto = LESSON_NEXTPAGE;
|
|
}
|
|
if (!$subquestion->id = insert_record("lesson_answers", $answer)) {
|
|
$result->error = "Could not insert quiz match subquestion!";
|
|
return $result;
|
|
}
|
|
$subquestions[] = $subquestion->id;
|
|
$i++;
|
|
}
|
|
}
|
|
|
|
if (count($subquestions) < 3) {
|
|
$result->notice = get_string("notenoughsubquestions", "quiz");
|
|
return $result;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
case LESSON_RANDOMSAMATCH:
|
|
$options->question = $question->id;
|
|
$options->choose = $question->choose;
|
|
if ($existing = get_record("quiz_randomsamatch", "question", $options->question)) {
|
|
$options->id = $existing->id;
|
|
if (!update_record("quiz_randomsamatch", $options)) {
|
|
$result->error = "Could not update quiz randomsamatch options!";
|
|
return $result;
|
|
}
|
|
} else {
|
|
if (!insert_record("quiz_randomsamatch", $options)) {
|
|
$result->error = "Could not insert quiz randomsamatch options!";
|
|
return $result;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LESSON_MULTIANSWER:
|
|
if (!$oldmultianswers = get_records("quiz_multianswers", "question", $question->id, "id ASC")) {
|
|
$oldmultianswers = array();
|
|
}
|
|
|
|
// Insert all the new multi answers
|
|
foreach ($question->answers as $dataanswer) {
|
|
if ($oldmultianswer = array_shift($oldmultianswers)) { // Existing answer, so reuse it
|
|
$multianswer = $oldmultianswer;
|
|
$multianswer->positionkey = $dataanswer->positionkey;
|
|
$multianswer->norm = $dataanswer->norm;
|
|
$multianswer->answertype = $dataanswer->answertype;
|
|
|
|
if (! $multianswer->answers = quiz_save_multianswer_alternatives
|
|
($question->id, $dataanswer->answertype,
|
|
$dataanswer->alternatives, $oldmultianswer->answers))
|
|
{
|
|
$result->error = "Could not update multianswer alternatives! (id=$multianswer->id)";
|
|
return $result;
|
|
}
|
|
if (!update_record("quiz_multianswers", $multianswer)) {
|
|
$result->error = "Could not update quiz multianswer! (id=$multianswer->id)";
|
|
return $result;
|
|
}
|
|
} else { // This is a completely new answer
|
|
$multianswer = new stdClass;
|
|
$multianswer->question = $question->id;
|
|
$multianswer->positionkey = $dataanswer->positionkey;
|
|
$multianswer->norm = $dataanswer->norm;
|
|
$multianswer->answertype = $dataanswer->answertype;
|
|
|
|
if (! $multianswer->answers = quiz_save_multianswer_alternatives
|
|
($question->id, $dataanswer->answertype,
|
|
$dataanswer->alternatives))
|
|
{
|
|
$result->error = "Could not insert multianswer alternatives! (questionid=$question->id)";
|
|
return $result;
|
|
}
|
|
if (!insert_record("quiz_multianswers", $multianswer)) {
|
|
$result->error = "Could not insert quiz multianswer!";
|
|
return $result;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LESSON_RANDOM:
|
|
break;
|
|
|
|
case LESSON_DESCRIPTION:
|
|
break;
|
|
|
|
default:
|
|
$result->error = "Unsupported question type ($question->qtype)!";
|
|
return $result;
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Determins if a jumpto value is correct or not.
|
|
*
|
|
* returns true if jumpto page is (logically) after the pageid page or
|
|
* if the jumpto value is a special value. Returns false in all other cases.
|
|
*
|
|
* @param int $pageid Id of the page from which you are jumping from.
|
|
* @param int $jumpto The jumpto number.
|
|
* @return boolean True or false after a series of tests.
|
|
**/
|
|
function lesson_iscorrect($pageid, $jumpto) {
|
|
|
|
// first test the special values
|
|
if (!$jumpto) {
|
|
// same page
|
|
return false;
|
|
} elseif ($jumpto == LESSON_NEXTPAGE) {
|
|
return true;
|
|
} elseif ($jumpto == LESSON_UNSEENBRANCHPAGE) {
|
|
return true;
|
|
} elseif ($jumpto == LESSON_RANDOMPAGE) {
|
|
return true;
|
|
} elseif ($jumpto == LESSON_CLUSTERJUMP) {
|
|
return true;
|
|
} elseif ($jumpto == LESSON_EOL) {
|
|
return true;
|
|
}
|
|
// we have to run through the pages from pageid looking for jumpid
|
|
if ($lessonid = get_field('lesson_pages', 'lessonid', 'id', $pageid)) {
|
|
if ($pages = get_records('lesson_pages', 'lessonid', $lessonid, '', 'id, nextpageid')) {
|
|
$apageid = $pages[$pageid]->nextpageid;
|
|
while ($apageid != 0) {
|
|
if ($jumpto == $apageid) {
|
|
return true;
|
|
}
|
|
$apageid = $pages[$apageid]->nextpageid;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Checks to see if a page is a branch table or is
|
|
* a page that is enclosed by a branch table and an end of branch or end of lesson.
|
|
* May call this function: {@link lesson_is_page_in_branch()}
|
|
*
|
|
* @param int $lesson Id of the lesson to which the page belongs.
|
|
* @param int $pageid Id of the page.
|
|
* @return boolean True or false.
|
|
**/
|
|
function lesson_display_branch_jumps($lessonid, $pageid) {
|
|
if($pageid == 0) {
|
|
// first page
|
|
return false;
|
|
}
|
|
// get all of the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
|
|
// adding first page
|
|
return false;
|
|
}
|
|
|
|
if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
|
|
return true;
|
|
}
|
|
|
|
return lesson_is_page_in_branch($lessonpages, $pageid);
|
|
}
|
|
|
|
/**
|
|
* Checks to see if a page is a cluster page or is
|
|
* a page that is enclosed by a cluster page and an end of cluster or end of lesson
|
|
* May call this function: {@link lesson_is_page_in_cluster()}
|
|
*
|
|
* @param int $lesson Id of the lesson to which the page belongs.
|
|
* @param int $pageid Id of the page.
|
|
* @return boolean True or false.
|
|
**/
|
|
function lesson_display_cluster_jump($lesson, $pageid) {
|
|
if($pageid == 0) {
|
|
// first page
|
|
return false;
|
|
}
|
|
// get all of the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lesson")) {
|
|
// adding first page
|
|
return false;
|
|
}
|
|
|
|
if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
|
|
return true;
|
|
}
|
|
|
|
return lesson_is_page_in_cluster($lessonpages, $pageid);
|
|
|
|
}
|
|
|
|
/**
|
|
* Checks to see if a LESSON_CLUSTERJUMP or
|
|
* a LESSON_UNSEENBRANCHPAGE is used in a lesson.
|
|
*
|
|
* This function is only executed when a teacher is
|
|
* checking the navigation for a lesson.
|
|
*
|
|
* @param int $lesson Id of the lesson that is to be checked.
|
|
* @return boolean True or false.
|
|
**/
|
|
function lesson_display_teacher_warning($lesson) {
|
|
// get all of the lesson answers
|
|
if (!$lessonanswers = get_records_select("lesson_answers", "lessonid = $lesson")) {
|
|
// no answers, then not useing cluster or unseen
|
|
return false;
|
|
}
|
|
// just check for the first one that fulfills the requirements
|
|
foreach ($lessonanswers as $lessonanswer) {
|
|
if ($lessonanswer->jumpto == LESSON_CLUSTERJUMP || $lessonanswer->jumpto == LESSON_UNSEENBRANCHPAGE) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// if no answers use either of the two jumps
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Interprets LESSON_CLUSTERJUMP jumpto value.
|
|
*
|
|
* This will select a page randomly
|
|
* and the page selected will be inbetween a cluster page and end of cluter or end of lesson
|
|
* and the page selected will be a page that has not been viewed already
|
|
* and if any pages are within a branch table or end of branch then only 1 page within
|
|
* the branch table or end of branch will be randomly selected (sub clustering).
|
|
*
|
|
* @param int $lessonid Id of the lesson.
|
|
* @param int $userid Id of the user.
|
|
* @param int $pageid Id of the current page from which we are jumping from.
|
|
* @return int The id of the next page.
|
|
**/
|
|
function lesson_cluster_jump($lessonid, $userid, $pageid) {
|
|
// get the number of retakes
|
|
if (!$retakes = count_records("lesson_grades", "lessonid", $lessonid, "userid", $userid)) {
|
|
$retakes = 0;
|
|
}
|
|
|
|
// get all the lesson_attempts aka what the user has seen
|
|
if ($seen = get_records_select("lesson_attempts", "lessonid = $lessonid AND userid = $userid AND retry = $retakes", "timeseen DESC")) {
|
|
foreach ($seen as $value) { // load it into an array that I can more easily use
|
|
$seenpages[$value->pageid] = $value->pageid;
|
|
}
|
|
} else {
|
|
$seenpages = array();
|
|
}
|
|
|
|
// get the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
|
|
print_error("Error: could not find records in lesson_pages table");
|
|
}
|
|
// find the start of the cluster
|
|
while ($pageid != 0) { // this condition should not be satisfied... should be a cluster page
|
|
if ($lessonpages[$pageid]->qtype == LESSON_CLUSTER) {
|
|
break;
|
|
}
|
|
$pageid = $lessonpages[$pageid]->prevpageid;
|
|
}
|
|
|
|
$pageid = $lessonpages[$pageid]->nextpageid; // move down from the cluster page
|
|
|
|
$clusterpages = array();
|
|
while (true) { // now load all the pages into the cluster that are not already inside of a branch table.
|
|
if ($lessonpages[$pageid]->qtype == LESSON_ENDOFCLUSTER) {
|
|
// store the endofcluster page's jump
|
|
$exitjump = get_field("lesson_answers", "jumpto", "pageid", $pageid, "lessonid", $lessonid);
|
|
if ($exitjump == LESSON_NEXTPAGE) {
|
|
$exitjump = $lessonpages[$pageid]->nextpageid;
|
|
}
|
|
if ($exitjump == 0) {
|
|
$exitjump = LESSON_EOL;
|
|
}
|
|
break;
|
|
} elseif (!lesson_is_page_in_branch($lessonpages, $pageid) && $lessonpages[$pageid]->qtype != LESSON_ENDOFBRANCH) {
|
|
// load page into array when it is not in a branch table and when it is not an endofbranch
|
|
$clusterpages[] = $lessonpages[$pageid];
|
|
}
|
|
if ($lessonpages[$pageid]->nextpageid == 0) {
|
|
// shouldn't ever get here... should be using endofcluster
|
|
$exitjump = LESSON_EOL;
|
|
break;
|
|
} else {
|
|
$pageid = $lessonpages[$pageid]->nextpageid;
|
|
}
|
|
}
|
|
|
|
// filter out the ones we have seen
|
|
$unseen = array();
|
|
foreach ($clusterpages as $clusterpage) {
|
|
if ($clusterpage->qtype == LESSON_BRANCHTABLE) { // if branchtable, check to see if any pages inside have been viewed
|
|
$branchpages = lesson_pages_in_branch($lessonpages, $clusterpage->id); // get the pages in the branchtable
|
|
$flag = true;
|
|
foreach ($branchpages as $branchpage) {
|
|
if (array_key_exists($branchpage->id, $seenpages)) { // check if any of the pages have been viewed
|
|
$flag = false;
|
|
}
|
|
}
|
|
if ($flag && count($branchpages) > 0) {
|
|
// add branch table
|
|
$unseen[] = $clusterpage;
|
|
}
|
|
} else {
|
|
// add any other type of page that has not already been viewed
|
|
if (!array_key_exists($clusterpage->id, $seenpages)) {
|
|
$unseen[] = $clusterpage;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count($unseen) > 0) { // it does not contain elements, then use exitjump, otherwise find out next page/branch
|
|
$nextpage = $unseen[rand(0, count($unseen)-1)];
|
|
} else {
|
|
return $exitjump; // seen all there is to see, leave the cluster
|
|
}
|
|
|
|
if ($nextpage->qtype == LESSON_BRANCHTABLE) { // if branch table, then pick a random page inside of it
|
|
$branchpages = lesson_pages_in_branch($lessonpages, $nextpage->id);
|
|
return $branchpages[rand(0, count($branchpages)-1)]->id;
|
|
} else { // otherwise, return the page's id
|
|
return $nextpage->id;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns pages that are within a branch table and another branch table, end of branch or end of lesson
|
|
*
|
|
* @param array $lessonpages An array of lesson page objects.
|
|
* @param int $branchid The id of the branch table that we would like the containing pages for.
|
|
* @return array An array of lesson page objects.
|
|
**/
|
|
function lesson_pages_in_branch($lessonpages, $branchid) {
|
|
$pageid = $lessonpages[$branchid]->nextpageid; // move to the first page after the branch table
|
|
$pagesinbranch = array();
|
|
|
|
while (true) {
|
|
if ($pageid == 0) { // EOL
|
|
break;
|
|
} elseif ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
|
|
break;
|
|
} elseif ($lessonpages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
|
|
break;
|
|
}
|
|
$pagesinbranch[] = $lessonpages[$pageid];
|
|
$pageid = $lessonpages[$pageid]->nextpageid;
|
|
}
|
|
|
|
return $pagesinbranch;
|
|
}
|
|
|
|
/**
|
|
* Interprets the LESSON_UNSEENBRANCHPAGE jump.
|
|
*
|
|
* will return the pageid of a random unseen page that is within a branch
|
|
*
|
|
* @see lesson_pages_in_branch()
|
|
* @param int $lesson Id of the lesson.
|
|
* @param int $userid Id of the user.
|
|
* @param int $pageid Id of the page from which we are jumping.
|
|
* @return int Id of the next page.
|
|
**/
|
|
function lesson_unseen_question_jump($lesson, $user, $pageid) {
|
|
// get the number of retakes
|
|
if (!$retakes = count_records("lesson_grades", "lessonid", $lesson, "userid", $user)) {
|
|
$retakes = 0;
|
|
}
|
|
|
|
// get all the lesson_attempts aka what the user has seen
|
|
if ($viewedpages = get_records_select("lesson_attempts", "lessonid = $lesson AND userid = $user AND retry = $retakes", "timeseen DESC")) {
|
|
foreach($viewedpages as $viewed) {
|
|
$seenpages[] = $viewed->pageid;
|
|
}
|
|
} else {
|
|
$seenpages = array();
|
|
}
|
|
|
|
// get the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lesson")) {
|
|
print_error("Error: could not find records in lesson_pages table");
|
|
}
|
|
|
|
if ($pageid == LESSON_UNSEENBRANCHPAGE) { // this only happens when a student leaves in the middle of an unseen question within a branch series
|
|
$pageid = $seenpages[0]; // just change the pageid to the last page viewed inside the branch table
|
|
}
|
|
|
|
// go up the pages till branch table
|
|
while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
|
|
if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
|
|
break;
|
|
}
|
|
$pageid = $lessonpages[$pageid]->prevpageid;
|
|
}
|
|
|
|
$pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
|
|
|
|
// this foreach loop stores all the pages that are within the branch table but are not in the $seenpages array
|
|
$unseen = array();
|
|
foreach($pagesinbranch as $page) {
|
|
if (!in_array($page->id, $seenpages)) {
|
|
$unseen[] = $page->id;
|
|
}
|
|
}
|
|
|
|
if(count($unseen) == 0) {
|
|
if(isset($pagesinbranch)) {
|
|
$temp = end($pagesinbranch);
|
|
$nextpage = $temp->nextpageid; // they have seen all the pages in the branch, so go to EOB/next branch table/EOL
|
|
} else {
|
|
// there are no pages inside the branch, so return the next page
|
|
$nextpage = $lessonpages[$pageid]->nextpageid;
|
|
}
|
|
if ($nextpage == 0) {
|
|
return LESSON_EOL;
|
|
} else {
|
|
return $nextpage;
|
|
}
|
|
} else {
|
|
return $unseen[rand(0, count($unseen)-1)]; // returns a random page id for the next page
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles the unseen branch table jump.
|
|
*
|
|
* @param int $lessonid Lesson id.
|
|
* @param int $userid User id.
|
|
* @return int Will return the page id of a branch table or end of lesson
|
|
**/
|
|
function lesson_unseen_branch_jump($lessonid, $userid) {
|
|
if (!$retakes = count_records("lesson_grades", "lessonid", $lessonid, "userid", $userid)) {
|
|
$retakes = 0;
|
|
}
|
|
|
|
if (!$seenbranches = get_records_select("lesson_branch", "lessonid = $lessonid AND userid = $userid AND retry = $retakes",
|
|
"timeseen DESC")) {
|
|
print_error("Error: could not find records in lesson_branch table");
|
|
}
|
|
|
|
// get the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
|
|
print_error("Error: could not find records in lesson_pages table");
|
|
}
|
|
|
|
// this loads all the viewed branch tables into $seen untill it finds the branch table with the flag
|
|
// which is the branch table that starts the unseenbranch function
|
|
$seen = array();
|
|
foreach ($seenbranches as $seenbranch) {
|
|
if (!$seenbranch->flag) {
|
|
$seen[$seenbranch->pageid] = $seenbranch->pageid;
|
|
} else {
|
|
$start = $seenbranch->pageid;
|
|
break;
|
|
}
|
|
}
|
|
// this function searches through the lesson pages to find all the branch tables
|
|
// that follow the flagged branch table
|
|
$pageid = $lessonpages[$start]->nextpageid; // move down from the flagged branch table
|
|
while ($pageid != 0) { // grab all of the branch table till eol
|
|
if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
|
|
$branchtables[] = $lessonpages[$pageid]->id;
|
|
}
|
|
$pageid = $lessonpages[$pageid]->nextpageid;
|
|
}
|
|
$unseen = array();
|
|
foreach ($branchtables as $branchtable) {
|
|
// load all of the unseen branch tables into unseen
|
|
if (!array_key_exists($branchtable, $seen)) {
|
|
$unseen[] = $branchtable;
|
|
}
|
|
}
|
|
if (count($unseen) > 0) {
|
|
return $unseen[rand(0, count($unseen)-1)]; // returns a random page id for the next page
|
|
} else {
|
|
return LESSON_EOL; // has viewed all of the branch tables
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handles the random jump between a branch table and end of branch or end of lesson (LESSON_RANDOMPAGE).
|
|
*
|
|
* @param int $lessonid Lesson id.
|
|
* @param int $pageid The id of the page that we are jumping from (?)
|
|
* @return int The pageid of a random page that is within a branch table
|
|
**/
|
|
function lesson_random_question_jump($lessonid, $pageid) {
|
|
// get the lesson pages
|
|
if (!$lessonpages = get_records_select("lesson_pages", "lessonid = $lessonid")) {
|
|
print_error("Error: could not find records in lesson_pages table");
|
|
}
|
|
|
|
// go up the pages till branch table
|
|
while ($pageid != 0) { // this condition should never be satisfied... only happens if there are no branch tables above this page
|
|
|
|
if ($lessonpages[$pageid]->qtype == LESSON_BRANCHTABLE) {
|
|
break;
|
|
}
|
|
$pageid = $lessonpages[$pageid]->prevpageid;
|
|
}
|
|
|
|
// get the pages within the branch
|
|
$pagesinbranch = lesson_pages_in_branch($lessonpages, $pageid);
|
|
|
|
if(count($pagesinbranch) == 0) {
|
|
// there are no pages inside the branch, so return the next page
|
|
return $lessonpages[$pageid]->nextpageid;
|
|
} else {
|
|
return $pagesinbranch[rand(0, count($pagesinbranch)-1)]->id; // returns a random page id for the next page
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check to see if a page is below a branch table (logically).
|
|
*
|
|
* Will return true if a branch table is found logically above the page.
|
|
* Will return false if an end of branch, cluster or the beginning
|
|
* of the lesson is found before a branch table.
|
|
*
|
|
* @param array $pages An array of lesson page objects.
|
|
* @param int $pageid Id of the page for testing.
|
|
* @return boolean
|
|
*/
|
|
function lesson_is_page_in_branch($pages, $pageid) {
|
|
$pageid = $pages[$pageid]->prevpageid; // move up one
|
|
|
|
// go up the pages till branch table
|
|
while (true) {
|
|
if ($pageid == 0) { // ran into the beginning of the lesson
|
|
return false;
|
|
} elseif ($pages[$pageid]->qtype == LESSON_ENDOFBRANCH) { // ran into the end of another branch table
|
|
return false;
|
|
} elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // do not look beyond a cluster
|
|
return false;
|
|
} elseif ($pages[$pageid]->qtype == LESSON_BRANCHTABLE) { // hit a branch table
|
|
return true;
|
|
}
|
|
$pageid = $pages[$pageid]->prevpageid;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Check to see if a page is below a cluster page (logically).
|
|
*
|
|
* Will return true if a cluster is found logically above the page.
|
|
* Will return false if an end of cluster or the beginning
|
|
* of the lesson is found before a cluster page.
|
|
*
|
|
* @param array $pages An array of lesson page objects.
|
|
* @param int $pageid Id of the page for testing.
|
|
* @return boolean
|
|
*/
|
|
function lesson_is_page_in_cluster($pages, $pageid) {
|
|
$pageid = $pages[$pageid]->prevpageid; // move up one
|
|
|
|
// go up the pages till branch table
|
|
while (true) {
|
|
if ($pageid == 0) { // ran into the beginning of the lesson
|
|
return false;
|
|
} elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER) { // ran into the end of another branch table
|
|
return false;
|
|
} elseif ($pages[$pageid]->qtype == LESSON_CLUSTER) { // hit a branch table
|
|
return true;
|
|
}
|
|
$pageid = $pages[$pageid]->prevpageid;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates a user's grade for a lesson.
|
|
*
|
|
* @param object $lesson The lesson that the user is taking.
|
|
* @param int $retries The attempt number.
|
|
* @param int $userid Id of the user (optinal, default current user).
|
|
* @return object { nquestions => number of questions answered
|
|
attempts => number of question attempts
|
|
total => max points possible
|
|
earned => points earned by student
|
|
grade => calculated percentage grade
|
|
nmanual => number of manually graded questions
|
|
manualpoints => point value for manually graded questions }
|
|
*/
|
|
function lesson_grade($lesson, $ntries, $userid = 0) {
|
|
global $USER;
|
|
|
|
if (empty($userid)) {
|
|
$userid = $USER->id;
|
|
}
|
|
|
|
// Zero out everything
|
|
$ncorrect = 0;
|
|
$nviewed = 0;
|
|
$score = 0;
|
|
$nmanual = 0;
|
|
$manualpoints = 0;
|
|
$thegrade = 0;
|
|
$nquestions = 0;
|
|
$total = 0;
|
|
$earned = 0;
|
|
|
|
if ($useranswers = get_records_select("lesson_attempts", "lessonid = $lesson->id AND
|
|
userid = $userid AND retry = $ntries", "timeseen")) {
|
|
// group each try with its page
|
|
$attemptset = array();
|
|
foreach ($useranswers as $useranswer) {
|
|
$attemptset[$useranswer->pageid][] = $useranswer;
|
|
}
|
|
|
|
// Drop all attempts that go beyond max attempts for the lesson
|
|
foreach ($attemptset as $key => $set) {
|
|
$attemptset[$key] = array_slice($set, 0, $lesson->maxattempts);
|
|
}
|
|
|
|
$pageids = implode(",", array_keys($attemptset));
|
|
|
|
// get only the pages and their answers that the user answered
|
|
$pages = get_records_select("lesson_pages", "lessonid = $lesson->id AND id IN($pageids)");
|
|
$answers = get_records_select("lesson_answers", "lessonid = $lesson->id AND pageid IN($pageids)");
|
|
|
|
// Number of pages answered
|
|
$nquestions = count($pages);
|
|
|
|
foreach ($attemptset as $attempts) {
|
|
if ($lesson->custom) {
|
|
$attempt = end($attempts);
|
|
// If essay question, handle it, otherwise add to score
|
|
if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
|
|
$essayinfo = unserialize($attempt->useranswer);
|
|
$earned += $essayinfo->score;
|
|
$nmanual++;
|
|
$manualpoints += $answers[$attempt->answerid]->score;
|
|
} else {
|
|
$earned += $answers[$attempt->answerid]->score;
|
|
}
|
|
} else {
|
|
foreach ($attempts as $attempt) {
|
|
$earned += $attempt->correct;
|
|
}
|
|
$attempt = end($attempts); // doesn't matter which one
|
|
// If essay question, increase numbers
|
|
if ($pages[$attempt->pageid]->qtype == LESSON_ESSAY) {
|
|
$nmanual++;
|
|
$manualpoints++;
|
|
}
|
|
}
|
|
// Number of times answered
|
|
$nviewed += count($attempts);
|
|
}
|
|
|
|
if ($lesson->custom) {
|
|
$bestscores = array();
|
|
// Find the highest possible score per page to get our total
|
|
foreach ($answers as $answer) {
|
|
if(!isset($bestscores[$answer->pageid])) {
|
|
$bestscores[$answer->pageid] = $answer->score;
|
|
} else if ($bestscores[$answer->pageid] < $answer->score) {
|
|
$bestscores[$answer->pageid] = $answer->score;
|
|
}
|
|
}
|
|
$total = array_sum($bestscores);
|
|
} else {
|
|
// Check to make sure the student has answered the minimum questions
|
|
if ($lesson->minquestions and $nquestions < $lesson->minquestions) {
|
|
// Nope, increase number viewed by the amount of unanswered questions
|
|
$total = $nviewed + ($lesson->minquestions - $nquestions);
|
|
} else {
|
|
$total = $nviewed;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($total) { // not zero
|
|
$thegrade = round(100 * $earned / $total, 5);
|
|
}
|
|
|
|
// Build the grade information object
|
|
$gradeinfo = new stdClass;
|
|
$gradeinfo->nquestions = $nquestions;
|
|
$gradeinfo->attempts = $nviewed;
|
|
$gradeinfo->total = $total;
|
|
$gradeinfo->earned = $earned;
|
|
$gradeinfo->grade = $thegrade;
|
|
$gradeinfo->nmanual = $nmanual;
|
|
$gradeinfo->manualpoints = $manualpoints;
|
|
|
|
return $gradeinfo;
|
|
}
|
|
|
|
/**
|
|
* Prints the on going message to the user.
|
|
*
|
|
* With custom grading On, displays points
|
|
* earned out of total points possible thus far.
|
|
* With custom grading Off, displays number of correct
|
|
* answers out of total attempted.
|
|
*
|
|
* @param object $lesson The lesson that the user is taking.
|
|
* @return void
|
|
**/
|
|
function lesson_print_ongoing_score($lesson) {
|
|
global $USER;
|
|
$cm = get_coursemodule_from_instance('lesson', $lesson->id);
|
|
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
|
|
|
if (has_capability('mod/lesson:manage', $context)) {
|
|
echo "<p align=\"center\">".get_string('teacherongoingwarning', 'lesson').'</p>';
|
|
} else {
|
|
$ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id);
|
|
if (isset($USER->modattempts[$lesson->id])) {
|
|
$ntries--;
|
|
}
|
|
$gradeinfo = lesson_grade($lesson, $ntries);
|
|
|
|
$a = new stdClass;
|
|
if ($lesson->custom) {
|
|
$a->score = $gradeinfo->earned;
|
|
$a->currenthigh = $gradeinfo->total;
|
|
print_simple_box(get_string("ongoingcustom", "lesson", $a), "center");
|
|
} else {
|
|
$a->correct = $gradeinfo->earned;
|
|
$a->viewed = $gradeinfo->attempts;
|
|
print_simple_box(get_string("ongoingnormal", "lesson", $a), "center");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prints tabs for the editing and adding pages. Each tab is a question type.
|
|
*
|
|
* @param array $qtypes The question types array (may not need to pass this because it is defined in this file)
|
|
* @param string $selected Current selected tab
|
|
* @param string $link The base href value of the link for the tab
|
|
* @param string $onclick Javascript for the tab link
|
|
* @return void
|
|
*/
|
|
function lesson_qtype_menu($qtypes, $selected="", $link="", $onclick="") {
|
|
$tabs = array();
|
|
$tabrows = array();
|
|
|
|
foreach ($qtypes as $qtype => $qtypename) {
|
|
$tabrows[] = new tabobject($qtype, "$link&qtype=$qtype\" onclick=\"$onclick", $qtypename);
|
|
}
|
|
$tabs[] = $tabrows;
|
|
print_tabs($tabs, $selected);
|
|
echo "<input type=\"hidden\" name=\"qtype\" value=\"$selected\" /> \n";
|
|
|
|
}
|
|
|
|
/**
|
|
* Prints out a Progress Bar which depicts a user's progress within a lesson.
|
|
*
|
|
* Currently works best with a linear lesson. Clusters are counted as a single page.
|
|
* Also, only viewed branch tables and questions that have been answered correctly count
|
|
* toward lesson completion (or progress). Only Students can see the Progress bar as well.
|
|
*
|
|
* @param object $lesson The lesson that the user is currently taking.
|
|
* @param object $course The course that the to which the lesson belongs.
|
|
* @return boolean The return is not significant as of yet. Will return true/false.
|
|
**/
|
|
function lesson_print_progress_bar($lesson, $course) {
|
|
global $CFG, $USER;
|
|
$cm = get_coursemodule_from_instance('lesson', $lesson->id);
|
|
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
|
|
|
// lesson setting to turn progress bar on or off
|
|
if (!$lesson->progressbar) {
|
|
return false;
|
|
}
|
|
|
|
// catch teachers
|
|
if (has_capability('mod/lesson:manage', $context)) {
|
|
notify(get_string('progressbarteacherwarning', 'lesson', $course->teachers));
|
|
return false;
|
|
}
|
|
if (!isset($USER->modattempts[$lesson->id])) {
|
|
// all of the lesson pages
|
|
if (!$pages = get_records('lesson_pages', 'lessonid', $lesson->id)) {
|
|
return false;
|
|
} else {
|
|
foreach ($pages as $page) {
|
|
if ($page->prevpageid == 0) {
|
|
$pageid = $page->id; // find the first page id
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// current attempt number
|
|
if (!$ntries = count_records("lesson_grades", "lessonid", $lesson->id, "userid", $USER->id)) {
|
|
$ntries = 0; // may not be necessary
|
|
}
|
|
|
|
$viewedpageids = array();
|
|
|
|
// collect all of the correctly answered questions
|
|
if ($viewedpages = get_records_select("lesson_attempts", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries AND correct = 1", 'timeseen DESC', 'pageid, id')) {
|
|
$viewedpageids = array_keys($viewedpages);
|
|
}
|
|
// collect all of the branch tables viewed
|
|
if ($viewedbranches = get_records_select("lesson_branch", "lessonid = $lesson->id AND userid = $USER->id AND retry = $ntries", 'timeseen DESC', 'pageid, id')) {
|
|
$viewedpageids = array_merge($viewedpageids, array_keys($viewedbranches));
|
|
}
|
|
|
|
// Filter out the following pages:
|
|
// End of Cluster
|
|
// End of Branch
|
|
// Pages found inside of Clusters
|
|
// Do not filter out Cluster Page(s) because we count a cluster as one.
|
|
// By keeping the cluster page, we get our 1
|
|
$validpages = array();
|
|
while ($pageid != 0) {
|
|
if ($pages[$pageid]->qtype == LESSON_CLUSTER) {
|
|
$clusterpageid = $pageid; // copy it
|
|
$validpages[$clusterpageid] = 1; // add the cluster page as a valid page
|
|
$pageid = $pages[$pageid]->nextpageid; // get next page
|
|
|
|
// now, remove all necessary viewed paged ids from the viewedpageids array.
|
|
while ($pages[$pageid]->qtype != LESSON_ENDOFCLUSTER and $pageid != 0) {
|
|
if (in_array($pageid, $viewedpageids)) {
|
|
unset($viewedpageids[array_search($pageid, $viewedpageids)]); // remove it
|
|
// since the user did see one page in the cluster, add the cluster pageid to the viewedpageids
|
|
if (!in_array($clusterpageid, $viewedpageids)) {
|
|
$viewedpageids[] = $clusterpageid;
|
|
}
|
|
}
|
|
$pageid = $pages[$pageid]->nextpageid;
|
|
}
|
|
} elseif ($pages[$pageid]->qtype == LESSON_ENDOFCLUSTER or $pages[$pageid]->qtype == LESSON_ENDOFBRANCH) {
|
|
// dont count these, just go to next
|
|
$pageid = $pages[$pageid]->nextpageid;
|
|
} else {
|
|
// a counted page
|
|
$validpages[$pageid] = 1;
|
|
$pageid = $pages[$pageid]->nextpageid;
|
|
}
|
|
}
|
|
|
|
// progress calculation as a percent
|
|
$progress = round(count($viewedpageids)/count($validpages), 2) * 100;
|
|
} else {
|
|
$progress = 100;
|
|
}
|
|
|
|
// print out the Progress Bar. Attempted to put as much as possible in the style sheets.
|
|
echo '<div class="progress_bar" align="center">';
|
|
echo '<table class="progress_bar_table"><tr>';
|
|
if ($progress != 0) { // some browsers do not repsect the 0 width.
|
|
echo '<td style="width:'.$progress.'%;" class="progress_bar_completed">';
|
|
echo '</td>';
|
|
}
|
|
echo '<td class="progress_bar_todo">';
|
|
echo '<div class="progress_bar_token"></div>';
|
|
echo '</td>';
|
|
echo '</tr></table>';
|
|
echo '</div>';
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Determines if a user can view the left menu. The determining factor
|
|
* is whether a user has a grade greater than or equal to the lesson setting
|
|
* of displayleftif
|
|
*
|
|
* @param object $lesson Lesson object of the current lesson
|
|
* @return boolean 0 if the user cannot see, or $lesson->displayleft to keep displayleft unchanged
|
|
**/
|
|
function lesson_displayleftif($lesson) {
|
|
global $CFG, $USER;
|
|
|
|
if (!empty($lesson->displayleftif)) {
|
|
// get the current user's max grade for this lesson
|
|
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')) {
|
|
if ($maxgrade->maxgrade < $lesson->displayleftif) {
|
|
return 0; // turn off the displayleft
|
|
}
|
|
} else {
|
|
return 0; // no grades
|
|
}
|
|
}
|
|
|
|
// if we get to here, keep the original state of displayleft lesson setting
|
|
return $lesson->displayleft;
|
|
}
|
|
|
|
/**
|
|
* If there is a media file associated with this
|
|
* lesson, then print it in a block.
|
|
*
|
|
* @param int $cmid Course Module ID for this lesson
|
|
* @param object $lesson Full lesson record object
|
|
* @return void
|
|
**/
|
|
function lesson_print_mediafile_block($cmid, $lesson) {
|
|
if (!empty($lesson->mediafile)) {
|
|
$url = '/mod/lesson/mediafile.php?id='.$cmid;
|
|
$options = 'menubar=0,location=0,left=5,top=5,scrollbars,resizable,width='. $lesson->mediawidth .',height='. $lesson->mediaheight;
|
|
$name = 'lessonmediafile';
|
|
|
|
$content = link_to_popup_window ($url, $name, get_string('mediafilepopup', 'lesson'), '', '', get_string('mediafilepopup', 'lesson'), $options, true);
|
|
$content .= helpbutton("mediafilestudent", get_string("mediafile", "lesson"), "lesson", true, false, '', true);
|
|
|
|
print_side_block(get_string('linkedmedia', 'lesson'), $content, NULL, NULL, '', array('class' => 'mediafile'), get_string('linkedmedia', 'lesson'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If a timed lesson and not a teacher, then
|
|
* print the clock
|
|
*
|
|
* @param int $cmid Course Module ID for this lesson
|
|
* @param object $lesson Full lesson record object
|
|
* @param object $timer Full timer record object
|
|
* @return void
|
|
**/
|
|
function lesson_print_clock_block($cmid, $lesson, $timer) {
|
|
global $CFG;
|
|
|
|
$context = get_context_instance(CONTEXT_MODULE, $cmid);
|
|
|
|
// Display for timed lessons and for students only
|
|
if($lesson->timed and !has_capability('mod/lesson:manage', $context) and !empty($timer)) {
|
|
$content = '<script type="text/javascript" charset="utf-8">'."\n";
|
|
$content .= "<!--\n";
|
|
$content .= ' var starttime = '.$timer->starttime.";\n";
|
|
$content .= ' var servertime = '.time().";\n";
|
|
$content .= ' var testlength = '.($lesson->maxtime * 60).";\n";
|
|
$content .= ' document.write(\'<script type="text/javascript" src="'.$CFG->wwwroot.'/mod/lesson/timer.js" charset="utf-8"><\/script>\');'."\n";
|
|
$content .= " window.onload = function () { show_clock(); };\n";
|
|
$content .= "// -->\n";
|
|
$content .= "</script>\n";
|
|
$content .= "<noscript>\n";
|
|
$content .= lesson_print_time_remaining($timer->starttime, $lesson->maxtime, true)."\n";
|
|
$content .= "</noscript>\n";
|
|
|
|
print_side_block(get_string('timeremaining', 'lesson'), $content, NULL, NULL, '', array('class' => 'clock'), get_string('timeremaining', 'lesson'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If left menu is turned on, then this will
|
|
* print the menu in a block
|
|
*
|
|
* @param int $cmid Course Module ID for this lesson
|
|
* @param object $lesson Full lesson record object
|
|
* @return void
|
|
**/
|
|
function lesson_print_menu_block($cmid, $lesson) {
|
|
global $CFG;
|
|
|
|
if ($lesson->displayleft) {
|
|
$pageid = get_field('lesson_pages', 'id', 'lessonid', $lesson->id, 'prevpageid', 0);
|
|
$pages = get_records_select('lesson_pages', "lessonid = $lesson->id");
|
|
$currentpageid = optional_param('pageid', $pageid, PARAM_INT);
|
|
|
|
if ($pageid and $pages) {
|
|
$content = '<a href="#maincontent" class="skip">'.get_string('skip', 'lesson')."</a>\n<div class=\"menuwrapper\">\n<ul>\n";
|
|
|
|
while ($pageid != 0) {
|
|
$page = $pages[$pageid];
|
|
|
|
// Only process branch tables with display turned on
|
|
if ($page->qtype == LESSON_BRANCHTABLE and $page->display) {
|
|
if ($page->id == $currentpageid) {
|
|
$content .= '<li class="selected">'.format_string($page->title,true)."</a></li>\n";
|
|
} else {
|
|
$content .= "<li class=\"notselected\"><a href=\"$CFG->wwwroot/mod/lesson/view.php?id=$cmid&pageid=$page->id\">".format_string($page->title,true)."</a></li>\n";
|
|
}
|
|
|
|
}
|
|
$pageid = $page->nextpageid;
|
|
}
|
|
$content .= "</ul>\n</div>\n";
|
|
print_side_block(get_string('lessonmenu', 'lesson'), $content, NULL, NULL, '', array('class' => 'menu'), get_string('lessonmenu', 'lesson'));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This is not ideal, but checks to see if a
|
|
* column has "block" content.
|
|
*
|
|
* In the future, it would be nice if the lesson
|
|
* media file, timer and navigation were blocks
|
|
* then this would be unnecessary.
|
|
*
|
|
* @uses $CFG
|
|
* @uses $PAGE
|
|
* @param object $lesson Full lesson record object
|
|
* @param array $pageblocks An array of block instances organized by left and right columns
|
|
* @param string $column Pass either BLOCK_POS_RIGHT or BLOCK_POS_LEFT constants
|
|
* @return boolean
|
|
**/
|
|
function lesson_blocks_have_content($lesson, $pageblocks, $column) {
|
|
global $CFG, $PAGE;
|
|
|
|
// First check lesson conditions
|
|
if ($column == BLOCK_POS_RIGHT) {
|
|
$managecap = false;
|
|
if ($cm = get_coursemodule_from_instance('lesson', $lesson->id, $lesson->course)) {
|
|
$managecap = has_capability('mod/lesson:manage', get_context_instance(CONTEXT_MODULE, $cm->id));
|
|
}
|
|
if (($lesson->timed and !$managecap) or !empty($lesson->mediafile)) {
|
|
return true;
|
|
}
|
|
} else if ($column == BLOCK_POS_LEFT) {
|
|
if ($lesson->displayleft) {
|
|
return true;
|
|
}
|
|
}
|
|
if (!empty($CFG->showblocksonmodpages)) {
|
|
if ((blocks_have_content($pageblocks, $column) || $PAGE->user_is_editing())) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
?>
|