From: moodler Date: Wed, 9 Aug 2006 13:45:49 +0000 (+0000) Subject: Removed tabs X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=dabfd0ed851e25907430a6e8eee90b8865ca28f7;p=moodle.git Removed tabs --- diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index b8bd546502..6d3e4e0831 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -107,10 +107,10 @@ class assignment_base { */ function view() { - $context = get_context_instance(CONTEXT_MODULE,$this->cm->id); + $context = get_context_instance(CONTEXT_MODULE,$this->cm->id); has_capability('mod/assignment:view', $context->id, true); - add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}", + add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}", $this->assignment->id, $this->cm->id); $this->view_header(); @@ -281,7 +281,7 @@ class assignment_base { // if this user can mark and is put in a group // then he can only see/mark submission in his own groups - if (user_group($this->course->id, $USER->id)) { + if (user_group($this->course->id, $USER->id)) { $count = $this->count_real_submissions($this->currentgroup); // Only their groups } else { $count = $this->count_real_submissions(); // Everyone diff --git a/mod/assignment/mod.html b/mod/assignment/mod.html index 891f57aa4a..0d5e4dc9ae 100644 --- a/mod/assignment/mod.html +++ b/mod/assignment/mod.html @@ -35,7 +35,7 @@ var availableitems = ['availableday','availablemonth','availableyear','availablehour', 'availableminute']; -
+ diff --git a/mod/chat/gui_header_js/index.php b/mod/chat/gui_header_js/index.php index ddd1d74991..6c35be3ee2 100644 --- a/mod/chat/gui_header_js/index.php +++ b/mod/chat/gui_header_js/index.php @@ -17,17 +17,17 @@ if (!$cm = get_coursemodule_from_instance('chat', $chat->id, $course->id)) { error('Course Module ID was incorrect'); } - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - require_login($course->id, false, $cm); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + + require_login($course->id, false, $cm); - has_capability('mod/chat:chat',$context->id, true); - /* + has_capability('mod/chat:chat',$context->id, true); + /* if (isguest()) { error('Guest does not have access to chat rooms'); } - */ + */ if (!$cm->visible and !isteacher($course->id)) { print_header(); notice(get_string("activityiscurrentlyhidden")); diff --git a/mod/chat/lib.php b/mod/chat/lib.php index d963d5caa2..0052d558e5 100644 --- a/mod/chat/lib.php +++ b/mod/chat/lib.php @@ -200,17 +200,17 @@ function chat_print_recent_activity($course, $isteacher, $timestart) { } if ($chat = get_record('chat', 'id', $chatuser->chatid)) { - // we find the course module id - $chatmod = get_record('modules', 'name', 'chat'); - $SQL = "select * from {$CFG->prefix}course_modules where - course = $course->id - and module = $chatmod->id - and instance = $chat->id"; - $cm = get_records_sql($SQL); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + // we find the course module id + $chatmod = get_record('modules', 'name', 'chat'); + $SQL = "select * from {$CFG->prefix}course_modules where + course = $course->id + and module = $chatmod->id + and instance = $chat->id"; + $cm = get_records_sql($SQL); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); - // needs to be fixed - if (!(has_capability('mod/chat:readlog', $context->id) or instance_is_visible('chat', $chat))) { // Chat hidden to students + // needs to be fixed + if (!(has_capability('mod/chat:readlog', $context->id) or instance_is_visible('chat', $chat))) { // Chat hidden to students //if (!($isteacher or instance_is_visible('chat', $chat))) { // Chat hidden to students continue; } diff --git a/mod/chat/report.php b/mod/chat/report.php index 5bcf6a6116..8f9ec6a370 100644 --- a/mod/chat/report.php +++ b/mod/chat/report.php @@ -21,16 +21,16 @@ error('Course is misconfigured'); } - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_login($course->id, false, $cm); $isteacher = isteacher($course->id); $isteacheredit = isteacheredit($course->id); //if (isguest() or (!$isteacher and !$chat->studentlogs)) { - //error('You can not view these chat reports'); + //error('You can not view these chat reports'); //} - has_capability('mod/chat:readlog', $context->id, true); // if can't even read, kill + has_capability('mod/chat:readlog', $context->id, true); // if can't even read, kill add_to_log($course->id, 'chat', 'report', "report.php?id=$cm->id", $chat->id, $cm->id); @@ -89,7 +89,7 @@ print_simple_box_end('center'); } - if (!$deletesession or !has_capability('mod/chat:deletelog', $context->id)) { + if (!$deletesession or !has_capability('mod/chat:deletelog', $context->id)) { //if (!$deletesession or !$isteacheredit) { print_continue("report.php?id=$cm->id"); } @@ -124,7 +124,7 @@ /// Delete a session if one has been specified - if ($deletesession and has_capability('mod/chat:deletelog', $context->id) and $confirmdelete and $start and $end and confirm_sesskey()) { + if ($deletesession and has_capability('mod/chat:deletelog', $context->id) and $confirmdelete and $start and $end and confirm_sesskey()) { //if ($deletesession and $isteacheredit and $confirmdelete and $start and $end and confirm_sesskey()) { delete_records_select('chat_messages', "chatid = $chat->id AND timestamp >= '$start' AND @@ -194,7 +194,7 @@ echo '

'; echo "id&start=$sessionstart&end=$sessionend\">$strseesession"; //if ($isteacheredit) - if (has_capability('mod/chat:deletelog', $context->id)) { + if (has_capability('mod/chat:deletelog', $context->id)) { echo "
id&start=$sessionstart&end=$sessionend&deletesession=1\">$strdeletesession"; } echo '

'; diff --git a/mod/chat/view.php b/mod/chat/view.php index 5a125ed3b7..5d96bd9543 100644 --- a/mod/chat/view.php +++ b/mod/chat/view.php @@ -43,9 +43,9 @@ require_course_login($course, true, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); - add_to_log($course->id, 'chat', 'view', "view.php?id=$cm->id", $chat->id, $cm->id); + add_to_log($course->id, 'chat', 'view', "view.php?id=$cm->id", $chat->id, $cm->id); // Initialize $PAGE, compute blocks @@ -76,7 +76,7 @@ echo '
:'; - if ($chat->studentlogs or has_capability('mod/chat:readlog',$context->id)) { + if ($chat->studentlogs or has_capability('mod/chat:readlog',$context->id)) { //if (($chat->studentlogs or isteacher($course->id)) and !isguest()) { echo '"; - } + echo ""; + } break; @@ -572,13 +572,13 @@ function choice_show_results($choice, $course, $cm, $forcepublish='') { echo "
"; break; - } + } } function choice_delete_responses($attemptids) { - - if(!is_array($attemptids) || empty($attemptids)) { + + if(!is_array($attemptids) || empty($attemptids)) { return false; } diff --git a/mod/choice/report.php b/mod/choice/report.php index c813d58e0e..bb56faa63f 100644 --- a/mod/choice/report.php +++ b/mod/choice/report.php @@ -18,11 +18,11 @@ require_login($course->id, false, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); has_capability('mod/choice:readresponses', $context->id, true); - //if (!isteacher($course->id)) { + //if (!isteacher($course->id)) { // error("Only teachers can look at this page"); //} @@ -40,7 +40,7 @@ //if ($action == 'delete') { //some responses need to be deleted $attemptids = isset($_POST['attemptid']) ? $_POST['attemptid'] : array(); //get array of repsonses to delete. choice_delete_responses($attemptids); //delete responses. - redirect("report.php?id=$cm->id"); + redirect("report.php?id=$cm->id"); } if ($download <> "xls" and $download <> "txt" ) { @@ -123,9 +123,9 @@ $ug2 = ''; if ($usergrps = user_group($course->id, $user->id)) { foreach ($usergrps as $ug) { - $ug2 = $ug2. $ug->name; - } - } + $ug2 = $ug2. $ug->name; + } + } $myxls->write_string($row,3,$ug2); $useroption = choice_get_option_text($choice, $answers[$user->id]->optionid); @@ -144,7 +144,7 @@ exit; } // print text file - //if ($download == "txt") { + //if ($download == "txt") { if ($download == "txt" && has_capability('mod/choice:downloadresponses', $context->id, true)) { $filename = clean_filename("$course->shortname ".strip_tags(format_string($choice->name,true))).'.txt'; @@ -172,15 +172,15 @@ echo "\t".$user->firstname; $studentid = " "; if (!empty($user->idnumber)) { - $studentid = $user->idnumber; - } + $studentid = $user->idnumber; + } echo "\t". $studentid."\t"; $ug2 = ''; if ($usergrps = user_group($course->id, $user->id)) { foreach ($usergrps as $ug) { - $ug2 = $ug2. $ug->name; - } - } + $ug2 = $ug2. $ug->name; + } + } echo $ug2. "\t"; echo format_string(choice_get_option_text($choice, $answers[$user->id]->optionid),true). "\n"; } diff --git a/mod/choice/view.php b/mod/choice/view.php index ff052f7ec3..fa6849ab40 100644 --- a/mod/choice/view.php +++ b/mod/choice/view.php @@ -33,7 +33,7 @@ if ($form = data_submitted()) { $timenow = time(); - if (has_capability('mod/choice:deleteresponses', $context->id)) { + if (has_capability('mod/choice:deleteresponses', $context->id)) { //if (isteacher($course->id, $USER->id)) { if ($action == 'delete') { //some responses need to be deleted choice_delete_responses($attemptids); //delete responses. @@ -59,7 +59,7 @@ "id\">$strchoices -> ".format_string($choice->name), "", "", true, update_module_button($cm->id, $course->id, $strchoice), navmenu($course, $cm)); - if (has_capability('mod/choice:readresponses', $context->id)) { + if (has_capability('mod/choice:readresponses', $context->id)) { //if (isteacher($course->id)) { choice_show_reportlink($choice, $course->id, $cm->id); } else if (!$cm->visible) { @@ -102,7 +102,7 @@ ( $choice->showresults == CHOICE_SHOWRESULTS_AFTER_ANSWER and $current ) or ( $choice->showresults == CHOICE_SHOWRESULTS_AFTER_CLOSE and $choice->timeclose <= time() ) ) { - choice_show_results($choice, $course, $cm); + choice_show_results($choice, $course, $cm); } print_footer($course); diff --git a/mod/data/comment.php b/mod/data/comment.php index 2a79131121..34a883759d 100755 --- a/mod/data/comment.php +++ b/mod/data/comment.php @@ -26,11 +26,11 @@ } require_login($course->id); - - $cm = data_get_cm($data); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - if ($commentid) { + $cm = data_get_cm($data); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + + if ($commentid) { if (! $comment = get_record('data_comments', 'id', $commentid)) { error('Comment ID is misconfigured'); } diff --git a/mod/data/field.php b/mod/data/field.php index 4cd279c868..b129a749a2 100755 --- a/mod/data/field.php +++ b/mod/data/field.php @@ -65,8 +65,8 @@ require_course_login($course, true, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/data:managetemplates', $context->id, true); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/data:managetemplates', $context->id, true); if (!isteacheredit($course->id)){ diff --git a/mod/data/import.php b/mod/data/import.php index d29911500b..2c7e922fa7 100755 --- a/mod/data/import.php +++ b/mod/data/import.php @@ -57,8 +57,8 @@ } } - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/data:uploadentries', $context->id, true); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/data:uploadentries', $context->id, true); if (has_capability('mod/data:managetemplates', $context->id)) { if (!count_records('data_fields','dataid',$data->id)) { // Brand new database! diff --git a/mod/data/lib.php b/mod/data/lib.php index 17fc862ea5..b0b827a94e 100755 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -557,7 +557,7 @@ function data_add_record($data, $groupid=0){ $record->groupid = $groupid; $record->timecreated = $record->timemodified = time(); if (has_capability('mod/data:approve', $context->id)) { - //if (isteacher($data->course)) { + //if (isteacher($data->course)) { $record->approved = 1; } else { $record->approved = 0; @@ -839,8 +839,8 @@ function data_get_coursemodule_info($coursemodule) { function data_print_template($template, $records, $data, $search='',$page=0, $return=false) { global $CFG; - $cm = data_get_cm($data); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $cm = data_get_cm($data); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); static $fields = NULL; static $isteacher; @@ -991,9 +991,9 @@ function data_print_preference_form($data, $perpage, $search, $sort='', $order=' function data_print_ratings($data, $record) { global $USER; - $cm = data_get_cm($data); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - + $cm = data_get_cm($data); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $ratingsmenuused = false; if ($data->ratings and !empty($USER->id)) { if ($ratings->scale = make_grades_menu($data->scale)) { @@ -1165,10 +1165,10 @@ function data_print_comment($data, $comment, $page=0) { global $USER, $CFG; - $cm = data_get_cm($data); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $cm = data_get_cm($data); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); - $stredit = get_string('edit'); + $stredit = get_string('edit'); $strdelete = get_string('delete'); $user = get_record('user','id',$comment->userid); @@ -1254,13 +1254,13 @@ function data_convert_arrays_to_strings(&$fieldinput) { // returns the $cm given $data function data_get_cm($data) { - global $CFG, $course; - $datamod = get_record('modules', 'name', 'data'); - $SQL = "select * from {$CFG->prefix}course_modules - where course = $course->id and - module = $datamod->id and - instance = $data->id"; - return get_record_sql($SQL); + global $CFG, $course; + $datamod = get_record('modules', 'name', 'data'); + $SQL = "select * from {$CFG->prefix}course_modules + where course = $course->id and + module = $datamod->id and + instance = $data->id"; + return get_record_sql($SQL); } ?> diff --git a/mod/data/restorelib.php b/mod/data/restorelib.php index 1adf4d45f5..80b149cb6c 100644 --- a/mod/data/restorelib.php +++ b/mod/data/restorelib.php @@ -92,11 +92,11 @@ function data_restore_mods($mod,$restore) { $mod->id, $newid); //Now check if want to restore user data and do it. if (function_exists('restore_userdata_selected')) { - // Moodle 1.6 - $restore_userdata_selected = restore_userdata_selected($restore, 'data', $mod->id); + // Moodle 1.6 + $restore_userdata_selected = restore_userdata_selected($restore, 'data', $mod->id); } else { // Moodle 1.5 - $restore_userdata_selected = $restore->mods['data']->userinfo; + $restore_userdata_selected = $restore->mods['data']->userinfo; } if ($restore_userdata_selected) { //Restore data_fields first!!! need to hold an array of [oldid]=>newid due to double dependencies diff --git a/mod/data/tabs.php b/mod/data/tabs.php index b35cf31675..82e5e8c02c 100755 --- a/mod/data/tabs.php +++ b/mod/data/tabs.php @@ -30,7 +30,7 @@ } $cm = data_get_cm($data); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); $inactive = NULL; $row = array(); @@ -46,7 +46,7 @@ //if (isloggedin() and !isguest()) { if (isloggedin()) { if (has_capability('mod/data:writeentry', $context->id)) { // took out participation list here! - $addstring = empty($editentry) ? get_string('add', 'data') : get_string('editentry', 'data'); + $addstring = empty($editentry) ? get_string('add', 'data') : get_string('editentry', 'data'); $row[] = new tabobject('add', $CFG->wwwroot.'/mod/data/edit.php?d='.$data->id, $addstring, '', true); } if (has_capability('mod/data:managetemplates', $context->id)) { diff --git a/mod/data/templates.php b/mod/data/templates.php index 9c6c92f068..4931b7e1a3 100755 --- a/mod/data/templates.php +++ b/mod/data/templates.php @@ -56,9 +56,9 @@ } require_course_login($course, true, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/data:managetemplates', $context->id, true); -/* + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/data:managetemplates', $context->id, true); +/* if (!isteacheredit($course->id)){ error(get_string('noaccess','data')); } diff --git a/mod/data/view.php b/mod/data/view.php index 9621ba24f7..10dd24cf26 100755 --- a/mod/data/view.php +++ b/mod/data/view.php @@ -82,9 +82,9 @@ } require_course_login($course, true, $cm); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/data:readentry', $context->id, true); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/data:readentry', $context->id, true); /// If it's hidden then it's don't show anything. :) if (empty($cm->visible) and !has_capability('mod/data:managetemplates', $context->id)) { diff --git a/mod/exercise/assessments.php b/mod/exercise/assessments.php index 4ebeab3140..27fae00618 100644 --- a/mod/exercise/assessments.php +++ b/mod/exercise/assessments.php @@ -55,7 +55,7 @@ require_login($course->id, false, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); $strexercises = get_string("modulenameplural", "exercise"); $strexercise = get_string("modulename", "exercise"); diff --git a/mod/exercise/view.php b/mod/exercise/view.php index aa7a0afb3d..e10dbbab92 100644 --- a/mod/exercise/view.php +++ b/mod/exercise/view.php @@ -38,7 +38,7 @@ require_login($course->id, false, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); // ...log activity... add_to_log($course->id, "exercise", "view", "view.php?id=$cm->id", $exercise->id, $cm->id); diff --git a/mod/glossary/approve.php b/mod/glossary/approve.php index 5448d92447..364886f796 100644 --- a/mod/glossary/approve.php +++ b/mod/glossary/approve.php @@ -22,9 +22,9 @@ } require_login($course->id, false, $cm); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:approve', $context->id, true); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:approve', $context->id, true); $newentry->id = $eid; $newentry->approved = 1; diff --git a/mod/glossary/comment.php b/mod/glossary/comment.php index 316143197c..365f65820d 100644 --- a/mod/glossary/comment.php +++ b/mod/glossary/comment.php @@ -38,9 +38,9 @@ require_login($course->id, false, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); - if (isguest()) { + if (isguest()) { error('Guests are not allowed to post comments', $_SERVER['HTTP_REFERER']); } add_to_log($course->id, 'glossary', 'view', "view.php?id=$cm->id", "$glossary->id",$cm->id); diff --git a/mod/glossary/comments.php b/mod/glossary/comments.php index 38a54638d5..176fced3bf 100644 --- a/mod/glossary/comments.php +++ b/mod/glossary/comments.php @@ -25,7 +25,7 @@ error("Entry is incorrect"); } - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_login($course->id, false, $cm); diff --git a/mod/glossary/deleteentry.php b/mod/glossary/deleteentry.php index 3d20b8124f..b66d84168b 100644 --- a/mod/glossary/deleteentry.php +++ b/mod/glossary/deleteentry.php @@ -29,8 +29,8 @@ } require_login($course->id, false, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + if (isguest()) { error("Guests are not allowed to edit or delete entries", $_SERVER["HTTP_REFERER"]); } diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index 95e6623acc..5e07395456 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -166,7 +166,7 @@ if ( $confirm ) { error("Could not update this glossary entry because this concept already exist."); } } else { - + $newentry->userid = $USER->id; $newentry->timecreated = $timenow; $newentry->sourceglossaryid = 0; @@ -332,7 +332,7 @@ $tab = GLOSSARY_ADDENTRY_VIEW; include("tabs.html"); if (!$e) { - has_capability('glossary_write', $context->id, true); + has_capability('glossary_write', $context->id, true); } include("edit.html"); diff --git a/mod/glossary/editcategories.php b/mod/glossary/editcategories.php index 83d6dd55b8..94d3f478f3 100644 --- a/mod/glossary/editcategories.php +++ b/mod/glossary/editcategories.php @@ -44,7 +44,7 @@ require_login($course->id, false); $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:managecategories', $context->id, true); + has_capability('mod/glossary:managecategories', $context->id, true); $strglossaries = get_string("modulenameplural", "glossary"); $strglossary = get_string("modulename", "glossary"); diff --git a/mod/glossary/export.php b/mod/glossary/export.php index 712cf758cb..cbe03fe5c7 100644 --- a/mod/glossary/export.php +++ b/mod/glossary/export.php @@ -22,10 +22,10 @@ error("Course module is incorrect"); } - require_login($course->id, false); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:export', $context->id, true); + require_login($course->id, false); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:export', $context->id, true); $strglossaries = get_string("modulenameplural", "glossary"); $strglossary = get_string("modulename", "glossary"); diff --git a/mod/glossary/exportentry.php b/mod/glossary/exportentry.php index 8619cc684f..735eec4cae 100644 --- a/mod/glossary/exportentry.php +++ b/mod/glossary/exportentry.php @@ -29,8 +29,8 @@ $lcase = 'lcase'; } - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:export', $context->id, true); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:export', $context->id, true); if (! $course = get_record('course', 'id', $cm->course)) { error('Course is misconfigured'); diff --git a/mod/glossary/exportfile.php b/mod/glossary/exportfile.php index e4f163de5b..ca3338cf6b 100644 --- a/mod/glossary/exportfile.php +++ b/mod/glossary/exportfile.php @@ -21,10 +21,10 @@ } require_login($course->id, false); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:export', $context->id, true); - + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:export', $context->id, true); + $filename = clean_filename(strip_tags(format_string($glossary->name,true)).'.xml'); $content = glossary_generate_export_file($glossary,$l,$cat); diff --git a/mod/glossary/import.php b/mod/glossary/import.php index 0f1c029af5..ad2f018ca6 100644 --- a/mod/glossary/import.php +++ b/mod/glossary/import.php @@ -18,7 +18,7 @@ if (! $cm = get_coursemodule_from_id('glossary', $id)) { error("Course Module ID was incorrect"); } - + if (! $course = get_record("course", "id", $cm->course)) { error("Course is misconfigured"); } @@ -27,10 +27,10 @@ error("Course module is incorrect"); } - require_login($course->id, false); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:import', $context->id, true); + require_login($course->id, false); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:import', $context->id, true); if ($dest != 'new' and $dest != 'current') { $dest = 'current'; diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index 5df9c68df9..0185ab0ee1 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -738,8 +738,8 @@ function glossary_print_entry_aliases($course, $cm, $glossary, $entry,$mode='', function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$hook='', $type = 'print') { global $USER, $CFG; - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); $output = false; //To decide if we must really return text in "return". Activate when needed only! $importedentry = ($entry->sourceglossaryid == $glossary->id); @@ -754,15 +754,15 @@ function glossary_print_entry_icons($course, $cm, $glossary, $entry, $mode='',$h $return .= glossary_print_entry_commentslink($course, $cm, $glossary, $entry,$mode,$hook,'html'); if (has_capability('mod/glossary:comment', $context->id)) { - $output = true; + $output = true; $return .= ' '.get_string('addcomment','glossary').''; } if (has_capability('mod/glossary:write', $context->id) or (!empty($USER->id) and $glossary->studentcanpost and $entry->userid == $USER->id)) { // only teachers can export entries so check it out - if (has_capability('mod/glossary:export', $context->id) and !$ismainglossary and !$importedentry) { - $mainglossary = get_record('glossary','mainglossary',1,'course',$course->id); + if (has_capability('mod/glossary:export', $context->id) and !$ismainglossary and !$importedentry) { + $mainglossary = get_record('glossary','mainglossary',1,'course',$course->id); if ( $mainglossary ) { // if there is a main glossary defined, allow to export the current entry $output = true; $return .= ' '.get_string('exporttomainglossary','glossary').''; @@ -1303,9 +1303,9 @@ function glossary_print_author_menu($cm, $glossary,$mode, $hook, $sortkey = '', function glossary_print_categories_menu($cm, $glossary, $hook, $category) { - global $CFG; - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); + global $CFG; + + $context = get_context_instance(CONTEXT_MODULE, $cm->id); echo ''; echo ''; @@ -1563,8 +1563,8 @@ function glossary_print_entry_ratings($course, $entry, $ratings = NULL) { $glossary = get_record('glossary', 'id', $entry->glossaryid); $glossarymod = get_record('modules','name','glossary'); $cm = get_record_sql("select * from {$CFG->prefix}course_modules where course = $course->id - and module = $glossarymod->id and instance = $glossary->id"); - + and module = $glossarymod->id and instance = $glossary->id"); + $context = get_context_instance(CONTEXT_MODULE, $cm->id); $ratingsmenuused = false; diff --git a/mod/glossary/report.php b/mod/glossary/report.php index 2492525b01..8ac786f6e2 100644 --- a/mod/glossary/report.php +++ b/mod/glossary/report.php @@ -21,8 +21,8 @@ $module = get_record("modules","name","glossary"); $cm = get_record("course_modules","module",$module->id,"instance",$entry->glossaryid); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + if (!has_capability('mod/glossary:manageentries', $context->id) and $USER->id != $entry->userid) { error("You can only look at results for your own entries"); } diff --git a/mod/glossary/tabs.html b/mod/glossary/tabs.html index ad1ed7323c..6ada25b189 100644 --- a/mod/glossary/tabs.html +++ b/mod/glossary/tabs.html @@ -23,8 +23,8 @@ } if (has_capability('mod/glossary:import', $context->id)) { $data[GLOSSARY_IMPORT_VIEW]->caption = get_string("importentries", "glossary"); - $data[GLOSSARY_IMPORT_VIEW]->link = "import.php?id=$cm->id"; - } + $data[GLOSSARY_IMPORT_VIEW]->link = "import.php?id=$cm->id"; + } if (has_capability('mod/glossary:export', $context->id)) { $data[GLOSSARY_EXPORT_VIEW]->caption = get_string("exportentries", "glossary"); @@ -39,8 +39,8 @@ $data[GLOSSARY_CATEGORY_VIEW]->link = "view.php?id=$id&mode=cat"; $data[GLOSSARY_AUTHOR_VIEW]->link = "view.php?id=$id&mode=author"; - if (has_capability('mod/glossary:approve', $context->id)) { - $data[GLOSSARY_APPROVAL_VIEW]->caption = get_string("waitingapproval", "glossary"); + if (has_capability('mod/glossary:approve', $context->id)) { + $data[GLOSSARY_APPROVAL_VIEW]->caption = get_string("waitingapproval", "glossary"); $data[GLOSSARY_APPROVAL_VIEW]->link = ""; $hiddenentries = get_records_select("glossary_entries","glossaryid = $glossary->id and approved = 0"); diff --git a/mod/glossary/view.php b/mod/glossary/view.php index d013974033..71f27968e0 100644 --- a/mod/glossary/view.php +++ b/mod/glossary/view.php @@ -44,8 +44,8 @@ error("Must specify glossary ID or course module ID"); } - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - has_capability('mod/glossary:view', $context->id, true); // kill the page if user can't even read + $context = get_context_instance(CONTEXT_MODULE, $cm->id); + has_capability('mod/glossary:view', $context->id, true); // kill the page if user can't even read if ($CFG->forcelogin) { require_login(); diff --git a/mod/hotpot/attempt.php b/mod/hotpot/attempt.php index b7d5e55a34..68c612c8f0 100644 --- a/mod/hotpot/attempt.php +++ b/mod/hotpot/attempt.php @@ -1,583 +1,583 @@ ErrorMsg()); - } - if ($attempt->userid != $USER->id) { - error("User ID is incorrect"); - } - if (! $hotpot = get_record("hotpot", "id", $attempt->hotpot)) { - error("Hot Potatoes ID is incorrect (attempt id = $attempt->id)"); - } - if (! $course = get_record("course", "id", $hotpot->course)) { - error("Course ID is incorrect (hotpot id = $hotpot->id)"); - } - if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { - error("Course Module ID is incorrect"); - } - - // make sure this user is enrolled in this course - require_login($course->id); - - $next_url = "$CFG->wwwroot/course/view.php?id=$course->id"; - $time = time(); - - // update attempt record fields using incoming data - $attempt->score = optional_param('mark', NULL, PARAM_INT); - $attempt->status = optional_param('status', NULL, PARAM_INT); - $attempt->details = optional_param('detail', NULL, PARAM_RAW); - $attempt->endtime = optional_param('endtime', NULL, PARAM_ALPHA); - $attempt->starttime = optional_param('starttime', NULL, PARAM_ALPHA); - $attempt->timefinish = $time; - - // convert times, if necessary - if (empty($attempt->starttime)) { - $attempt->starttime = 0; - } else { - $attempt->starttime = strtotime($attempt->starttime); - } - if (empty($attempt->endtime)) { - $attempt->endtime = 0; - } else { - $attempt->endtime = strtotime($attempt->endtime); - } - - // set clickreportid, (for click reporting) - $attempt->clickreportid = $attempt->id; - - $quiztype = optional_param('quiztype', 0, PARAM_INT); - - if (empty($attempt->details)) { - hotpot_set_attempt_details($attempt); - $javascript_is_off = true; - } else { - $javascript_is_off = false; - } - - if (empty($attempt->status)) { - if (empty($attempt->endtime)) { - $attempt->status = HOTPOT_STATUS_INPROGRESS; - } else { - $attempt->status = HOTPOT_STATUS_COMPLETED; - } - } - - // check if this is the second (or subsequent) click - if (get_field("hotpot_attempts", "timefinish", "id", $attempt->id)) { - - if ($hotpot->clickreporting==HOTPOT_YES) { - // add attempt record for each form submission - // records are linked via the "clickreportid" field - - // update status in previous records in this group - set_field("hotpot_attempts", "status", $attempt->status, "clickreportid", $attempt->clickreportid); - - // add new attempt record - unset ($attempt->id); - $attempt->id = insert_record("hotpot_attempts", $attempt); - - if (empty($attempt->id)) { - error("Could not insert attempt record: ".$db->ErrorMsg(), $next_url); - } - - // add attempt details record, if necessary - if (!empty($attempt->details)) { - unset($details); - $details->attempt = $attempt->id; - $details->details = $attempt->details; - if (! insert_record("hotpot_details", $details, false)) { - error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url); - } - } - } else { - // remove previous responses for this attempt, if required - // (N.B. this does NOT remove the attempt record, just the responses) - delete_records("hotpot_responses", "attempt", $attempt->id); - } - } - - // remove slashes added by lib/setup.php - $attempt->details = stripslashes($attempt->details); - - // add details of this attempt - hotpot_add_attempt_details($attempt); - - // add slashes again, so the details can be added to the database - $attempt->details = addslashes($attempt->details); - - // update the attempt record - if (! update_record("hotpot_attempts", $attempt)) { - error("Could not update attempt record: ".$db->ErrorMsg(), $next_url); - } - - // get previous attempt details record, if any - $details_exist = record_exists("hotpot_details", "attempt", $attempt->id); - - // delete/update/add the attempt details record - if (empty($attempt->details)) { - if ($details_exist) { - delete_records("hotpot_details", "attempt", $attempt->id); - } - } else { - if ($details_exist) { - set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id); - } else { - unset($details); - $details->attempt = $attempt->id; - $details->details = $attempt->details; - if (! insert_record("hotpot_details", $details)) { - error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url); - } - } - } - - if ($attempt->status==HOTPOT_STATUS_INPROGRESS) { - if ($javascript_is_off) { - // regenerate HTML page - define('HOTPOT_FIRST_ATTEMPT', false); - include ("$CFG->hotpotroot/view.php"); - } else { - // continue without reloading the page - header("Status: 204"); - header("HTTP/1.0 204 No Response"); - } - - } else { // quiz is finished - - add_to_log($course->id, "hotpot", "submit", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id"); - - if ($hotpot->shownextquiz==HOTPOT_YES) { - if (is_numeric($next_cm = hotpot_get_next_cm($cm))) { - $next_url = "$CFG->wwwroot/mod/hotpot/view.php?id=$next_cm"; - } - } - - // redirect to the next quiz or the course page - redirect($next_url, get_string('resultssaved', 'hotpot')); - } + require_once("../../config.php"); + require_once("lib.php"); + + $attemptid = required_param("attemptid"); + + // get attempt, hotpot, course and course_module records + if (! $attempt = get_record("hotpot_attempts", "id", $attemptid)) { + error("Hot Potatoes attempt record $attemptid could not be accessed: ".$db->ErrorMsg()); + } + if ($attempt->userid != $USER->id) { + error("User ID is incorrect"); + } + if (! $hotpot = get_record("hotpot", "id", $attempt->hotpot)) { + error("Hot Potatoes ID is incorrect (attempt id = $attempt->id)"); + } + if (! $course = get_record("course", "id", $hotpot->course)) { + error("Course ID is incorrect (hotpot id = $hotpot->id)"); + } + if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { + error("Course Module ID is incorrect"); + } + + // make sure this user is enrolled in this course + require_login($course->id); + + $next_url = "$CFG->wwwroot/course/view.php?id=$course->id"; + $time = time(); + + // update attempt record fields using incoming data + $attempt->score = optional_param('mark', NULL, PARAM_INT); + $attempt->status = optional_param('status', NULL, PARAM_INT); + $attempt->details = optional_param('detail', NULL, PARAM_RAW); + $attempt->endtime = optional_param('endtime', NULL, PARAM_ALPHA); + $attempt->starttime = optional_param('starttime', NULL, PARAM_ALPHA); + $attempt->timefinish = $time; + + // convert times, if necessary + if (empty($attempt->starttime)) { + $attempt->starttime = 0; + } else { + $attempt->starttime = strtotime($attempt->starttime); + } + if (empty($attempt->endtime)) { + $attempt->endtime = 0; + } else { + $attempt->endtime = strtotime($attempt->endtime); + } + + // set clickreportid, (for click reporting) + $attempt->clickreportid = $attempt->id; + + $quiztype = optional_param('quiztype', 0, PARAM_INT); + + if (empty($attempt->details)) { + hotpot_set_attempt_details($attempt); + $javascript_is_off = true; + } else { + $javascript_is_off = false; + } + + if (empty($attempt->status)) { + if (empty($attempt->endtime)) { + $attempt->status = HOTPOT_STATUS_INPROGRESS; + } else { + $attempt->status = HOTPOT_STATUS_COMPLETED; + } + } + + // check if this is the second (or subsequent) click + if (get_field("hotpot_attempts", "timefinish", "id", $attempt->id)) { + + if ($hotpot->clickreporting==HOTPOT_YES) { + // add attempt record for each form submission + // records are linked via the "clickreportid" field + + // update status in previous records in this group + set_field("hotpot_attempts", "status", $attempt->status, "clickreportid", $attempt->clickreportid); + + // add new attempt record + unset ($attempt->id); + $attempt->id = insert_record("hotpot_attempts", $attempt); + + if (empty($attempt->id)) { + error("Could not insert attempt record: ".$db->ErrorMsg(), $next_url); + } + + // add attempt details record, if necessary + if (!empty($attempt->details)) { + unset($details); + $details->attempt = $attempt->id; + $details->details = $attempt->details; + if (! insert_record("hotpot_details", $details, false)) { + error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url); + } + } + } else { + // remove previous responses for this attempt, if required + // (N.B. this does NOT remove the attempt record, just the responses) + delete_records("hotpot_responses", "attempt", $attempt->id); + } + } + + // remove slashes added by lib/setup.php + $attempt->details = stripslashes($attempt->details); + + // add details of this attempt + hotpot_add_attempt_details($attempt); + + // add slashes again, so the details can be added to the database + $attempt->details = addslashes($attempt->details); + + // update the attempt record + if (! update_record("hotpot_attempts", $attempt)) { + error("Could not update attempt record: ".$db->ErrorMsg(), $next_url); + } + + // get previous attempt details record, if any + $details_exist = record_exists("hotpot_details", "attempt", $attempt->id); + + // delete/update/add the attempt details record + if (empty($attempt->details)) { + if ($details_exist) { + delete_records("hotpot_details", "attempt", $attempt->id); + } + } else { + if ($details_exist) { + set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id); + } else { + unset($details); + $details->attempt = $attempt->id; + $details->details = $attempt->details; + if (! insert_record("hotpot_details", $details)) { + error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url); + } + } + } + + if ($attempt->status==HOTPOT_STATUS_INPROGRESS) { + if ($javascript_is_off) { + // regenerate HTML page + define('HOTPOT_FIRST_ATTEMPT', false); + include ("$CFG->hotpotroot/view.php"); + } else { + // continue without reloading the page + header("Status: 204"); + header("HTTP/1.0 204 No Response"); + } + + } else { // quiz is finished + + add_to_log($course->id, "hotpot", "submit", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id"); + + if ($hotpot->shownextquiz==HOTPOT_YES) { + if (is_numeric($next_cm = hotpot_get_next_cm($cm))) { + $next_url = "$CFG->wwwroot/mod/hotpot/view.php?id=$next_cm"; + } + } + + // redirect to the next quiz or the course page + redirect($next_url, get_string('resultssaved', 'hotpot')); + } // ================= -// functions +// functions // ================= function hotpot_get_next_cm(&$cm) { - // gets the next module in this section of the course - // that is the same type of module as the current module - - $next_mod = false; - - // get a list of $ids of modules in this section - if ($ids = get_field('course_sections', 'sequence', 'id', $cm->section)) { - - $found = false; - $ids = explode(',', $ids); - foreach ($ids as $id) { - if ($found && ($cm->module==get_field('course_modules', 'module', 'id', $id))) { - $next_mod = $id; - break; - } else if ($cm->id==$id) { - $found = true; - } - } - } - return $next_mod; + // gets the next module in this section of the course + // that is the same type of module as the current module + + $next_mod = false; + + // get a list of $ids of modules in this section + if ($ids = get_field('course_sections', 'sequence', 'id', $cm->section)) { + + $found = false; + $ids = explode(',', $ids); + foreach ($ids as $id) { + if ($found && ($cm->module==get_field('course_modules', 'module', 'id', $id))) { + $next_mod = $id; + break; + } else if ($cm->id==$id) { + $found = true; + } + } + } + return $next_mod; } function hotpot_set_attempt_details(&$attempt) { - global $CFG, $HOTPOT_QUIZTYPE; - - // optional_param('showallquestions', 0, PARAM_INT); - - $attempt->details = ''; - $attempt->score = 0; - $attempt->status = HOTPOT_STATUS_COMPLETED; - - $buttons = array('clues', 'hints', 'checks'); - $textfields = array('correct', 'wrong', 'ignored'); - - $ok = false; - $quiztype = optional_param('quiztype', 0, PARAM_ALPHANUM); - if ($quiztype) { - if (is_numeric($quiztype)) { - $ok = array_key_exists($quiztype, $HOTPOT_QUIZTYPE); - } else { - $quiztype = array_search($quiztype, $HOTPOT_QUIZTYPE); - $ok = is_numeric($quiztype); - } - } - if (!$ok) { - return; - // error('Quiz type is missing or invalid'); - // error(get_string('error_invalidquiztype', 'hotpot')); - // - // script finishes here if quiztype is invalid - // - } - - // special flag to detect jquiz multiselect - $is_jquiz_multiselect = false; - - // set maximum question number - $q_max = 0;; - do { - switch ($quiztype) { - case HOTPOT_JCLOZE: - case HOTPOT_JQUIZ: - $field="q{$q_max}_a0_text"; - break; - case HOTPOT_JCB: - case HOTPOT_JCROSS: - case HOTPOT_JMATCH: - case HOTPOT_JMIX: - default: - $field = ''; - } - } while ($field && isset($_POST[$field]) && ($q_max = $q_max+1)); - - // check JQuiz navigation buttons - switch (true) { - case isset($_POST['ShowAllQuestionsButton']): - $_POST['ShowAllQuestions'] = 1; - break; - case isset($_POST['ShowOneByOneButton']): - $_POST['ShowAllQuestions'] = 0; - break; - case isset($_POST['PrevQButton']): - $_POST['ThisQuestion']--; - break; - case isset($_POST['NextQButton']): - $_POST['ThisQuestion']++; - break; - } - - $q = 0; - while ($q<$q_max) { - $responsefield="q{$q}"; - - $questiontype = optional_param("{$responsefield}_questiontype", 0, PARAM_INT); - $is_jquiz_multiselect = ($quiztype==HOTPOT_JQUIZ && $questiontype==HOTPOT_JQUIZ_MULTISELECT); - - if (isset($_POST[$responsefield]) && is_array($_POST[$responsefield])) { - $responsevalue = array(); - foreach ($_POST[$responsefield] as $key=>$value) { - $responsevalue[$key] = clean_param($value, PARAM_CLEAN); - } - } else { - $responsevalue = optional_param($responsefield, ''); - } - if (is_array($responsevalue)) { - // incomplete jquiz multi-select - $responsevalues = $responsevalue; - $responsevalue = implode('+', $responsevalue); - } else { - $responsevalues = explode('+', $responsevalue); - } - - // initialize $response object - $response = new stdClass(); - $response->correct = array(); - $response->wrong = array(); - $response->ignored = array(); - $response->clues = 0; - $response->hints = 0; - $response->checks = 0; - $response->score = 0; - $response->weighting = 0; - - // create another empty object to hold all previous responses (from database) - $oldresponse = new stdClass(); - $vars = get_object_vars($response); - foreach($vars as $name=>$value) { - $oldresponse->$name = $value; - } - - foreach ($buttons as $button) { - if (($field = "q{$q}_{$button}_button") && isset($_POST[$field])) { - $value = optional_param($field, '', PARAM_RAW); - if (!empty($value)) { - $response->$button++; - } - } - } - - // loop through possible answers to this question - $firstcorrectvalue = ''; - $percents = array(); - $a = 0; - while (($valuefield="q{$q}_a{$a}_text") && isset($_POST[$valuefield])) { - $value = optional_param($valuefield, '', PARAM_RAW); - - if (($percentfield="q{$q}_a{$a}_percent") && isset($_POST[$percentfield])) { - $percent = optional_param($percentfield, 0, PARAM_INT); - if ($percent) { - $percents[$value] = $percent; - } - } - - if (($correctfield="q{$q}_a{$a}_correct") && isset($_POST[$correctfield])) { - $correct = optional_param($correctfield, 0, PARAM_INT); - } else { - $correct = false; - } - - if ($correct && empty($firstcorrectvalue)) { - $firstcorrectvalue = $value; - } - - if ($is_jquiz_multiselect) { - $selected = in_array($value, $responsevalues); - if ($correct) { - $response->correct[] = $value; - if (empty($selected)) { - $response->wrong[] = true; - } - } else { - if ($selected) { - $response->wrong[] = true; - } - } - } else { - // single answer only required - if ($responsevalue==$value) { - if ($correct) { - $response->correct[] = $value; - } else { - $response->wrong[] = $value; - } - } else { - $response->ignored[] = $value; - } - } - $a++; - } - - // number of answers for this question - $a_max = $a; - - if ($is_jquiz_multiselect) { - if (empty($response->wrong) && count($responsevalues)==count($response->correct)) { - $response->wrong = array(); - $response->correct = array($responsevalue); - } else { - $response->correct = array(); - $response->wrong = array($responsevalue); - } - } else { - // if response did not match any answer, then this response is wrong - if (empty($response->correct) && empty($response->wrong)) { - $response->wrong[] = $responsevalue; - } - } - - // if this question has not been answered correctly, quiz is still in progress - if (empty($response->correct)) { - - if (isset($_POST["q{$q}_ShowAnswers_button"])) { - $_POST[$responsefield] = $firstcorrectvalue; - } else { - $attempt->status = HOTPOT_STATUS_INPROGRESS; - - if (isset($_POST["q{$q}_Hint_button"])) { - // a particular hint button in JQuiz shortanswer - $_POST['HintButton'] = true; - } - - // give a hint, if necessary - if (isset($_POST['HintButton']) && $firstcorrectvalue) { - - // make sure we only come through here once - unset($_POST['HintButton']); - - $correctlen = strlen($firstcorrectvalue); - $responselen = strlen($responsevalue); - - // check how many letters are the same - $i = 0; - while ($i<$responselen && $i<$correctlen && $responsevalue{$i}==$firstcorrectvalue{$i}) { - $i++; - } - - if ($i<$responselen) { - // remove incorrect characters on the end of the response - $responsevalue = substr($responsevalue, 0, $i); - } - if ($i<$correctlen) { - // append next correct letter - $responsevalue .= $firstcorrectvalue{$i}; - } - $_POST[$responsefield] = $responsevalue; - $response->hints++; - } // end if hint - } - } // end if not correct - - // get clue text, if any - if (($field="q{$q}_clue") && isset($_POST[$field])) { - $response->clue_text = optional_param($field, '', PARAM_RAW); - } - - // get question name - $qq = sprintf('%02d', $q); // (a padded, two-digit version of $q) - if (($field="q{$q}_name") && isset($_POST[$field])) { - $questionname = optional_param($field, '', PARAM_RAW); - $questionname = strip_tags($questionname); - } else { - $questionname = $qq; - } - - // get previous responses to this question (if any) - $records = get_records_sql(" - SELECT - r.* - FROM - {$CFG->prefix}hotpot_attempts AS a, - {$CFG->prefix}hotpot_questions AS q, - {$CFG->prefix}hotpot_responses AS r - WHERE - a.clickreportid = $attempt->clickreportid AND - a.id = r.attempt AND - r.question = q.id AND - q.name = '$questionname' AND - q.hotpot = $attempt->hotpot - ORDER BY - a.timefinish - "); - - if ($records) { - foreach ($records as $record) { - foreach ($buttons as $button) { - $oldresponse->$button = max($oldresponse->$button, $record->$button); - } - foreach ($textfields as $field) { - if ($record->$field && ($field=='correct' || $field=='wrong')) { - $values = explode(',', hotpot_strings($record->$field)); - $oldresponse->$field = array_merge($oldresponse->$field, $values); - } - } - } - } - - // remove "correct" and "wrong" values from "ignored" values - $response->ignored = array_diff($response->ignored, - $response->correct, $response->wrong, $oldresponse->correct, $oldresponse->wrong - ); - - foreach ($buttons as $button) { - $response->$button += $oldresponse->$button; - } - - $value_has_changed = false; - foreach ($textfields as $field) { - $response->$field = array_merge($oldresponse->$field, $response->$field); - $response->$field = array_unique($response->$field); - $response->$field = implode(',', $response->$field); - - if ($field=='correct' || $field=='wrong') { - $array = $oldresponse->$field; - $array = array_unique($array); - $oldresponse->$field = implode(',', $array); - if ($response->$field<>$oldresponse->$field) { - $value_has_changed = true; - } - } - } - if ($value_has_changed) { - $response->checks++; - } - - // $response now holds amalgamation of all responses so far to this question - - // set question score and weighting - if ($response->correct) { - switch ($quiztype) { - case HOTPOT_JCB: - break; - case HOTPOT_JCLOZE: - $strlen = strlen($response->correct); - $response->score = 100*($strlen-($response->checks-1))/$strlen; - $attempt->score += $response->score; - break; - case HOTPOT_JCROSS: - break; - case HOTPOT_JMATCH: - break; - case HOTPOT_JMIX: - break; - case HOTPOT_JQUIZ: - switch ($questiontype) { - case HOTPOT_JQUIZ_MULTICHOICE: - $wrong = explode(',', $response->wrong); - foreach ($wrong as $value) { - if (isset($percents[$value])) { - $percent = $percents[$value]; - } else { - $percent = 0; - } - } - case HOTPOT_JQUIZ_SHORTANSWER: - $strlen = strlen($response->correct); - $response->score = 100*($strlen-($response->checks-1))/$strlen; - break; - case HOTPOT_JQUIZ_MULTISELECT: - if (isset($percents[$response->correct])) { - $percent = $percents[$response->correct]; - } else { - $percent = 0; - } - if ($a_max>0 && $response->checks>0 && $a_max>$response->checks) { - $response->score = $percent*($a_max-($response->checks-1))/$a_max; - } - break; - } - $attempt->score += $response->score; - break; - } - } - - $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_name"; - $attempt->details .= "$fieldname$questionname"; - - // encode $response fields as XML - $vars = get_object_vars($response); - foreach($vars as $name=>$value) { - if (!empty($value)) { - $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_{$name}"; - $attempt->details .= "$fieldname$value"; - } - } - - $q++; - } // end main loop through $q(uestions) - - // set attempt score - if ($q>0) { - switch ($quiztype) { - case HOTPOT_JCB: - break; - case HOTPOT_JCLOZE: - $attempt->score = floor($attempt->score / $q); - break; - case HOTPOT_JCROSS: - break; - case HOTPOT_JMATCH: - break; - case HOTPOT_JMIX: - break; - case HOTPOT_JQUIZ: - break; - } - } - - if ($attempt->details) { - $attempt->details = ''.$attempt->details.''; - } - -// print "forcing status to in progress ..
\n"; -// $attempt->status = HOTPOT_STATUS_INPROGRESS; + global $CFG, $HOTPOT_QUIZTYPE; + + // optional_param('showallquestions', 0, PARAM_INT); + + $attempt->details = ''; + $attempt->score = 0; + $attempt->status = HOTPOT_STATUS_COMPLETED; + + $buttons = array('clues', 'hints', 'checks'); + $textfields = array('correct', 'wrong', 'ignored'); + + $ok = false; + $quiztype = optional_param('quiztype', 0, PARAM_ALPHANUM); + if ($quiztype) { + if (is_numeric($quiztype)) { + $ok = array_key_exists($quiztype, $HOTPOT_QUIZTYPE); + } else { + $quiztype = array_search($quiztype, $HOTPOT_QUIZTYPE); + $ok = is_numeric($quiztype); + } + } + if (!$ok) { + return; + // error('Quiz type is missing or invalid'); + // error(get_string('error_invalidquiztype', 'hotpot')); + // + // script finishes here if quiztype is invalid + // + } + + // special flag to detect jquiz multiselect + $is_jquiz_multiselect = false; + + // set maximum question number + $q_max = 0;; + do { + switch ($quiztype) { + case HOTPOT_JCLOZE: + case HOTPOT_JQUIZ: + $field="q{$q_max}_a0_text"; + break; + case HOTPOT_JCB: + case HOTPOT_JCROSS: + case HOTPOT_JMATCH: + case HOTPOT_JMIX: + default: + $field = ''; + } + } while ($field && isset($_POST[$field]) && ($q_max = $q_max+1)); + + // check JQuiz navigation buttons + switch (true) { + case isset($_POST['ShowAllQuestionsButton']): + $_POST['ShowAllQuestions'] = 1; + break; + case isset($_POST['ShowOneByOneButton']): + $_POST['ShowAllQuestions'] = 0; + break; + case isset($_POST['PrevQButton']): + $_POST['ThisQuestion']--; + break; + case isset($_POST['NextQButton']): + $_POST['ThisQuestion']++; + break; + } + + $q = 0; + while ($q<$q_max) { + $responsefield="q{$q}"; + + $questiontype = optional_param("{$responsefield}_questiontype", 0, PARAM_INT); + $is_jquiz_multiselect = ($quiztype==HOTPOT_JQUIZ && $questiontype==HOTPOT_JQUIZ_MULTISELECT); + + if (isset($_POST[$responsefield]) && is_array($_POST[$responsefield])) { + $responsevalue = array(); + foreach ($_POST[$responsefield] as $key=>$value) { + $responsevalue[$key] = clean_param($value, PARAM_CLEAN); + } + } else { + $responsevalue = optional_param($responsefield, ''); + } + if (is_array($responsevalue)) { + // incomplete jquiz multi-select + $responsevalues = $responsevalue; + $responsevalue = implode('+', $responsevalue); + } else { + $responsevalues = explode('+', $responsevalue); + } + + // initialize $response object + $response = new stdClass(); + $response->correct = array(); + $response->wrong = array(); + $response->ignored = array(); + $response->clues = 0; + $response->hints = 0; + $response->checks = 0; + $response->score = 0; + $response->weighting = 0; + + // create another empty object to hold all previous responses (from database) + $oldresponse = new stdClass(); + $vars = get_object_vars($response); + foreach($vars as $name=>$value) { + $oldresponse->$name = $value; + } + + foreach ($buttons as $button) { + if (($field = "q{$q}_{$button}_button") && isset($_POST[$field])) { + $value = optional_param($field, '', PARAM_RAW); + if (!empty($value)) { + $response->$button++; + } + } + } + + // loop through possible answers to this question + $firstcorrectvalue = ''; + $percents = array(); + $a = 0; + while (($valuefield="q{$q}_a{$a}_text") && isset($_POST[$valuefield])) { + $value = optional_param($valuefield, '', PARAM_RAW); + + if (($percentfield="q{$q}_a{$a}_percent") && isset($_POST[$percentfield])) { + $percent = optional_param($percentfield, 0, PARAM_INT); + if ($percent) { + $percents[$value] = $percent; + } + } + + if (($correctfield="q{$q}_a{$a}_correct") && isset($_POST[$correctfield])) { + $correct = optional_param($correctfield, 0, PARAM_INT); + } else { + $correct = false; + } + + if ($correct && empty($firstcorrectvalue)) { + $firstcorrectvalue = $value; + } + + if ($is_jquiz_multiselect) { + $selected = in_array($value, $responsevalues); + if ($correct) { + $response->correct[] = $value; + if (empty($selected)) { + $response->wrong[] = true; + } + } else { + if ($selected) { + $response->wrong[] = true; + } + } + } else { + // single answer only required + if ($responsevalue==$value) { + if ($correct) { + $response->correct[] = $value; + } else { + $response->wrong[] = $value; + } + } else { + $response->ignored[] = $value; + } + } + $a++; + } + + // number of answers for this question + $a_max = $a; + + if ($is_jquiz_multiselect) { + if (empty($response->wrong) && count($responsevalues)==count($response->correct)) { + $response->wrong = array(); + $response->correct = array($responsevalue); + } else { + $response->correct = array(); + $response->wrong = array($responsevalue); + } + } else { + // if response did not match any answer, then this response is wrong + if (empty($response->correct) && empty($response->wrong)) { + $response->wrong[] = $responsevalue; + } + } + + // if this question has not been answered correctly, quiz is still in progress + if (empty($response->correct)) { + + if (isset($_POST["q{$q}_ShowAnswers_button"])) { + $_POST[$responsefield] = $firstcorrectvalue; + } else { + $attempt->status = HOTPOT_STATUS_INPROGRESS; + + if (isset($_POST["q{$q}_Hint_button"])) { + // a particular hint button in JQuiz shortanswer + $_POST['HintButton'] = true; + } + + // give a hint, if necessary + if (isset($_POST['HintButton']) && $firstcorrectvalue) { + + // make sure we only come through here once + unset($_POST['HintButton']); + + $correctlen = strlen($firstcorrectvalue); + $responselen = strlen($responsevalue); + + // check how many letters are the same + $i = 0; + while ($i<$responselen && $i<$correctlen && $responsevalue{$i}==$firstcorrectvalue{$i}) { + $i++; + } + + if ($i<$responselen) { + // remove incorrect characters on the end of the response + $responsevalue = substr($responsevalue, 0, $i); + } + if ($i<$correctlen) { + // append next correct letter + $responsevalue .= $firstcorrectvalue{$i}; + } + $_POST[$responsefield] = $responsevalue; + $response->hints++; + } // end if hint + } + } // end if not correct + + // get clue text, if any + if (($field="q{$q}_clue") && isset($_POST[$field])) { + $response->clue_text = optional_param($field, '', PARAM_RAW); + } + + // get question name + $qq = sprintf('%02d', $q); // (a padded, two-digit version of $q) + if (($field="q{$q}_name") && isset($_POST[$field])) { + $questionname = optional_param($field, '', PARAM_RAW); + $questionname = strip_tags($questionname); + } else { + $questionname = $qq; + } + + // get previous responses to this question (if any) + $records = get_records_sql(" + SELECT + r.* + FROM + {$CFG->prefix}hotpot_attempts AS a, + {$CFG->prefix}hotpot_questions AS q, + {$CFG->prefix}hotpot_responses AS r + WHERE + a.clickreportid = $attempt->clickreportid AND + a.id = r.attempt AND + r.question = q.id AND + q.name = '$questionname' AND + q.hotpot = $attempt->hotpot + ORDER BY + a.timefinish + "); + + if ($records) { + foreach ($records as $record) { + foreach ($buttons as $button) { + $oldresponse->$button = max($oldresponse->$button, $record->$button); + } + foreach ($textfields as $field) { + if ($record->$field && ($field=='correct' || $field=='wrong')) { + $values = explode(',', hotpot_strings($record->$field)); + $oldresponse->$field = array_merge($oldresponse->$field, $values); + } + } + } + } + + // remove "correct" and "wrong" values from "ignored" values + $response->ignored = array_diff($response->ignored, + $response->correct, $response->wrong, $oldresponse->correct, $oldresponse->wrong + ); + + foreach ($buttons as $button) { + $response->$button += $oldresponse->$button; + } + + $value_has_changed = false; + foreach ($textfields as $field) { + $response->$field = array_merge($oldresponse->$field, $response->$field); + $response->$field = array_unique($response->$field); + $response->$field = implode(',', $response->$field); + + if ($field=='correct' || $field=='wrong') { + $array = $oldresponse->$field; + $array = array_unique($array); + $oldresponse->$field = implode(',', $array); + if ($response->$field<>$oldresponse->$field) { + $value_has_changed = true; + } + } + } + if ($value_has_changed) { + $response->checks++; + } + + // $response now holds amalgamation of all responses so far to this question + + // set question score and weighting + if ($response->correct) { + switch ($quiztype) { + case HOTPOT_JCB: + break; + case HOTPOT_JCLOZE: + $strlen = strlen($response->correct); + $response->score = 100*($strlen-($response->checks-1))/$strlen; + $attempt->score += $response->score; + break; + case HOTPOT_JCROSS: + break; + case HOTPOT_JMATCH: + break; + case HOTPOT_JMIX: + break; + case HOTPOT_JQUIZ: + switch ($questiontype) { + case HOTPOT_JQUIZ_MULTICHOICE: + $wrong = explode(',', $response->wrong); + foreach ($wrong as $value) { + if (isset($percents[$value])) { + $percent = $percents[$value]; + } else { + $percent = 0; + } + } + case HOTPOT_JQUIZ_SHORTANSWER: + $strlen = strlen($response->correct); + $response->score = 100*($strlen-($response->checks-1))/$strlen; + break; + case HOTPOT_JQUIZ_MULTISELECT: + if (isset($percents[$response->correct])) { + $percent = $percents[$response->correct]; + } else { + $percent = 0; + } + if ($a_max>0 && $response->checks>0 && $a_max>$response->checks) { + $response->score = $percent*($a_max-($response->checks-1))/$a_max; + } + break; + } + $attempt->score += $response->score; + break; + } + } + + $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_name"; + $attempt->details .= "$fieldname$questionname"; + + // encode $response fields as XML + $vars = get_object_vars($response); + foreach($vars as $name=>$value) { + if (!empty($value)) { + $fieldname = $HOTPOT_QUIZTYPE[$quiztype]."_q{$qq}_{$name}"; + $attempt->details .= "$fieldname$value"; + } + } + + $q++; + } // end main loop through $q(uestions) + + // set attempt score + if ($q>0) { + switch ($quiztype) { + case HOTPOT_JCB: + break; + case HOTPOT_JCLOZE: + $attempt->score = floor($attempt->score / $q); + break; + case HOTPOT_JCROSS: + break; + case HOTPOT_JMATCH: + break; + case HOTPOT_JMIX: + break; + case HOTPOT_JQUIZ: + break; + } + } + + if ($attempt->details) { + $attempt->details = ''.$attempt->details.''; + } + +// print "forcing status to in progress ..
\n"; +// $attempt->status = HOTPOT_STATUS_INPROGRESS; } ?> diff --git a/mod/hotpot/config.html b/mod/hotpot/config.html index 48585a7157..a783402612 100644 --- a/mod/hotpot/config.html +++ b/mod/hotpot/config.html @@ -2,24 +2,24 @@
- - - - - - - - - - - - - + + + + + + + + + + + + +

hotpot_showtimes:

hotpot_showtimes, ""); - ?>

hotpot_excelencodings:

">

hotpot_showtimes:

hotpot_showtimes, ""); + ?>

hotpot_excelencodings:

">
diff --git a/mod/hotpot/db/mysql.php b/mod/hotpot/db/mysql.php index 561f6260c5..ab75b1e84f 100644 --- a/mod/hotpot/db/mysql.php +++ b/mod/hotpot/db/mysql.php @@ -1,43 +1,43 @@ prefix}hotpot_events` ADD `starttime` INT(10) unsigned NOT NULL DEFAULT '0' AFTER `time`"); - execute_sql(" ALTER TABLE `{$CFG->prefix}hotpot_events` ADD `endtime` INT(10) unsigned NOT NULL DEFAULT '0' AFTER `time`"); - } + if ($oldversion < 2004021400) { + execute_sql(" ALTER TABLE `{$CFG->prefix}hotpot_events` ADD `starttime` INT(10) unsigned NOT NULL DEFAULT '0' AFTER `time`"); + execute_sql(" ALTER TABLE `{$CFG->prefix}hotpot_events` ADD `endtime` INT(10) unsigned NOT NULL DEFAULT '0' AFTER `time`"); + } - // set path to update functions - $update_to_v2 = "$CFG->dirroot/mod/hotpot/db/update_to_v2.php"; + // set path to update functions + $update_to_v2 = "$CFG->dirroot/mod/hotpot/db/update_to_v2.php"; - // update from HotPot v1 to HotPot v2 - if ($oldversion < 2005031400) { - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_from_v1(); - } - if ($oldversion < 2005090700) { - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_1(); - } - if ($oldversion > 2005031419 && $oldversion < 2005090702) { - // update to from HotPot v2.1.0 or v2.1.1 - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_1_2(); - } - if ($oldversion < 2006042103) { - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_1_16(); - } - if ($oldversion < 2006042601) { - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_1_17(); - } - if ($oldversion < 2006042803) { - require_once $update_to_v2; - $ok = $ok && hotpot_update_to_v2_1_18(); - } + // update from HotPot v1 to HotPot v2 + if ($oldversion < 2005031400) { + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_from_v1(); + } + if ($oldversion < 2005090700) { + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_1(); + } + if ($oldversion > 2005031419 && $oldversion < 2005090702) { + // update to from HotPot v2.1.0 or v2.1.1 + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_1_2(); + } + if ($oldversion < 2006042103) { + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_1_16(); + } + if ($oldversion < 2006042601) { + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_1_17(); + } + if ($oldversion < 2006042803) { + require_once $update_to_v2; + $ok = $ok && hotpot_update_to_v2_1_18(); + } - return $ok; + return $ok; } ?> diff --git a/mod/hotpot/db/update_to_v2.php b/mod/hotpot/db/update_to_v2.php index 9c8eb457b7..b8eb14a854 100644 --- a/mod/hotpot/db/update_to_v2.php +++ b/mod/hotpot/db/update_to_v2.php @@ -3,7 +3,7 @@ function hotpot_update_to_v2_1_21() { global $CFG; $ok = true; - if (strtolower($CFG->dbtype)=='postgres7') { + if (strtolower($CFG->dbtype)=='postgres7') { // ensure setting of default values on certain fields // this was originally done in postgres7.php, but was found to be incompatible with PG7 :-( $table="hotpot"; @@ -36,1293 +36,1293 @@ function hotpot_update_to_v2_1_21() { return $ok; } function hotpot_update_to_v2_1_18() { - $ok = true; + $ok = true; - // remove all orphan records (there shouldn't be any, but if there are they can mess up the utfdbmigrate) + // remove all orphan records (there shouldn't be any, but if there are they can mess up the utfdbmigrate) - $ok = $ok && hotpot_remove_orphans('hotpot_attempts', 'hotpot', 'hotpot'); - $ok = $ok && hotpot_remove_orphans('hotpot_questions', 'hotpot', 'hotpot'); - $ok = $ok && hotpot_remove_orphans('hotpot_responses', 'attempt', 'hotpot_attempts'); - $ok = $ok && hotpot_remove_orphans('hotpot_responses', 'question', 'hotpot_questions'); - $ok = $ok && hotpot_remove_orphans('hotpot_details', 'attempt', 'hotpot_attempts'); + $ok = $ok && hotpot_remove_orphans('hotpot_attempts', 'hotpot', 'hotpot'); + $ok = $ok && hotpot_remove_orphans('hotpot_questions', 'hotpot', 'hotpot'); + $ok = $ok && hotpot_remove_orphans('hotpot_responses', 'attempt', 'hotpot_attempts'); + $ok = $ok && hotpot_remove_orphans('hotpot_responses', 'question', 'hotpot_questions'); + $ok = $ok && hotpot_remove_orphans('hotpot_details', 'attempt', 'hotpot_attempts'); - // allow negative weighting and scores + // allow negative weighting and scores - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'weighting', '6', false); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'score', '6', false); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'weighting', '6', false); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'score', '6', false); - return $ok; + return $ok; } function hotpot_remove_orphans($secondarytable, $secondarykeyfield, $primarytable, $primarykeyfield='id') { - global $CFG,$db; - $ok = true; + global $CFG,$db; + $ok = true; - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = false; + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = false; - $records = get_records_sql(" - SELECT - t2.$secondarykeyfield, t2.$secondarykeyfield - FROM - {$CFG->prefix}$secondarytable AS t2 LEFT JOIN {$CFG->prefix}$primarytable AS t1 - ON (t2.$secondarykeyfield = t1.id) - WHERE - t1.$primarykeyfield IS NULL - "); + $records = get_records_sql(" + SELECT + t2.$secondarykeyfield, t2.$secondarykeyfield + FROM + {$CFG->prefix}$secondarytable AS t2 LEFT JOIN {$CFG->prefix}$primarytable AS t1 + ON (t2.$secondarykeyfield = t1.id) + WHERE + t1.$primarykeyfield IS NULL + "); - // restore SQL message echo setting - $db->debug = $debug; + // restore SQL message echo setting + $db->debug = $debug; - if ($records) { - $keys = implode(',', array_keys($records)); - print "removing orphan record(s) from {$CFG->prefix}$secondarytable
"; - $ok = $ok && execute_sql("DELETE FROM {$CFG->prefix}$secondarytable WHERE $secondarykeyfield IN ($keys)"); - } + if ($records) { + $keys = implode(',', array_keys($records)); + print "removing orphan record(s) from {$CFG->prefix}$secondarytable
"; + $ok = $ok && execute_sql("DELETE FROM {$CFG->prefix}$secondarytable WHERE $secondarykeyfield IN ($keys)"); + } - return $ok; + return $ok; } function hotpot_update_to_v2_1_17() { - global $CFG; - $ok = true; + global $CFG; + $ok = true; - // convert and disable null values on certain numeric fields + // convert and disable null values on certain numeric fields - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'starttime', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'endtime', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'score', '6'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'penalties', '6'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'timestart', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'timefinish', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'clickreportid', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'starttime', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'endtime', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'score', '6'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'penalties', '6'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'timestart', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'timefinish', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_attempts', 'clickreportid', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_questions', 'type', '4'); - $ok = $ok && hotpot_denull_int_field('hotpot_questions', 'text', '10'); + $ok = $ok && hotpot_denull_int_field('hotpot_questions', 'type', '4'); + $ok = $ok && hotpot_denull_int_field('hotpot_questions', 'text', '10'); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'weighting', '6', false); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'score', '6', false); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'hints', '6'); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'clues', '6'); - $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'checks', '6'); - return $ok; + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'weighting', '6', false); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'score', '6', false); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'hints', '6'); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'clues', '6'); + $ok = $ok && hotpot_denull_int_field('hotpot_responses', 'checks', '6'); + return $ok; } function hotpot_denull_int_field($table, $field, $size, $unsigned=true) { - global $CFG; - $ok = true; + global $CFG; + $ok = true; - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}$table SET $field=0 WHERE $field IS NULL", false); - if ($unsigned) { - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}$table SET $field=0 WHERE $field<0", false); - } - $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'INTEGER', $size, $unsigned, 'NOT NULL', 0); + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}$table SET $field=0 WHERE $field IS NULL", false); + if ($unsigned) { + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}$table SET $field=0 WHERE $field<0", false); + } + $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'INTEGER', $size, $unsigned, 'NOT NULL', 0); - return $ok; + return $ok; } function hotpot_update_to_v2_1_16() { - global $CFG; - $ok = true; + global $CFG; + $ok = true; - // settings for the "hotpot_questions_name_idx" index - $length = 20; - $field = 'name'; - $table = 'hotpot_questions'; - $index = "{$table}_{$field}_idx"; + // settings for the "hotpot_questions_name_idx" index + $length = 20; + $field = 'name'; + $table = 'hotpot_questions'; + $index = "{$table}_{$field}_idx"; - // remove the index - hotpot_db_delete_index("{$CFG->prefix}$table", $index); - hotpot_db_delete_index("{$CFG->prefix}$table", "{$CFG->prefix}$index"); + // remove the index + hotpot_db_delete_index("{$CFG->prefix}$table", $index); + hotpot_db_delete_index("{$CFG->prefix}$table", "{$CFG->prefix}$index"); - // make sure type of 'name' is a text field (not varchar 255) - $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'TEXT', '', '', 'NOT NULL', ''); + // make sure type of 'name' is a text field (not varchar 255) + $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'TEXT', '', '', 'NOT NULL', ''); - // restore the index - $ok = $ok && hotpot_db_add_index($table, $field, $length); + // restore the index + $ok = $ok && hotpot_db_add_index($table, $field, $length); - if (strtolower($CFG->dbtype)=='mysql') { + if (strtolower($CFG->dbtype)=='mysql') { - // set default values on certain VARCHAR(255) fields - $varchar_fields = array( - 'hotpot.studentfeedbackurl', - 'hotpot_responses.correct', - 'hotpot_responses.wrong', - 'hotpot_responses.ignored' - ); - foreach ($varchar_fields as $varchar_field) { - list ($table, $field) = explode('.', $varchar_field); - execute_sql("UPDATE {$CFG->prefix}$table SET $field='' WHERE $field IS NULL"); - $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'VARCHAR', 255, '', 'NOT NULL', ''); - } + // set default values on certain VARCHAR(255) fields + $varchar_fields = array( + 'hotpot.studentfeedbackurl', + 'hotpot_responses.correct', + 'hotpot_responses.wrong', + 'hotpot_responses.ignored' + ); + foreach ($varchar_fields as $varchar_field) { + list ($table, $field) = explode('.', $varchar_field); + execute_sql("UPDATE {$CFG->prefix}$table SET $field='' WHERE $field IS NULL"); + $ok = $ok && hotpot_db_update_field_type($table, $field, $field, 'VARCHAR', 255, '', 'NOT NULL', ''); + } - // remove $CFG->prefix from all index names - $ok = $ok && hotpot_index_remove_prefix('hotpot_attempts', 'hotpot'); - $ok = $ok && hotpot_index_remove_prefix('hotpot_attempts', 'userid'); - $ok = $ok && hotpot_index_remove_prefix('hotpot_details', 'attempt'); - $ok = $ok && hotpot_index_remove_prefix('hotpot_questions', 'hotpot'); - //$ok = $ok && hotpot_index_remove_prefix('hotpot_questions', 'name', 20); - $ok = $ok && hotpot_index_remove_prefix('hotpot_responses', 'attempt'); - $ok = $ok && hotpot_index_remove_prefix('hotpot_responses', 'question'); - $ok = $ok && hotpot_index_remove_prefix('hotpot_strings', 'string', 20); - } - return $ok; + // remove $CFG->prefix from all index names + $ok = $ok && hotpot_index_remove_prefix('hotpot_attempts', 'hotpot'); + $ok = $ok && hotpot_index_remove_prefix('hotpot_attempts', 'userid'); + $ok = $ok && hotpot_index_remove_prefix('hotpot_details', 'attempt'); + $ok = $ok && hotpot_index_remove_prefix('hotpot_questions', 'hotpot'); + //$ok = $ok && hotpot_index_remove_prefix('hotpot_questions', 'name', 20); + $ok = $ok && hotpot_index_remove_prefix('hotpot_responses', 'attempt'); + $ok = $ok && hotpot_index_remove_prefix('hotpot_responses', 'question'); + $ok = $ok && hotpot_index_remove_prefix('hotpot_strings', 'string', 20); + } + return $ok; } function hotpot_index_remove_prefix($table, $field, $length=0) { - global $CFG; - $index = "{$table}_{$field}_idx"; - hotpot_db_delete_index("{$CFG->prefix}$table", "{$CFG->prefix}$index"); - hotpot_db_delete_index("{$CFG->prefix}$table", $index); - return hotpot_db_add_index($table, $field, $length); + global $CFG; + $index = "{$table}_{$field}_idx"; + hotpot_db_delete_index("{$CFG->prefix}$table", "{$CFG->prefix}$index"); + hotpot_db_delete_index("{$CFG->prefix}$table", $index); + return hotpot_db_add_index($table, $field, $length); } function hotpot_update_to_v2_1_8() { - global $CFG; - $ok = true; - if (strtolower($CFG->dbtype)=='postgres7') { - // add, delete and rename certain fields and indexes - // that were not correctly setup by postgres7.sql + global $CFG; + $ok = true; + if (strtolower($CFG->dbtype)=='postgres7') { + // add, delete and rename certain fields and indexes + // that were not correctly setup by postgres7.sql - // hotpot - $table = 'hotpot'; - if (hotpot_db_field_exists($table, 'microreporting')) { - $ok = $ok && hotpot_db_update_field_type($table, 'microreporting', 'clickreporting', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); - } - } - return $ok; + // hotpot + $table = 'hotpot'; + if (hotpot_db_field_exists($table, 'microreporting')) { + $ok = $ok && hotpot_db_update_field_type($table, 'microreporting', 'clickreporting', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); + } + } + return $ok; } function hotpot_update_to_v2_1_6() { - global $CFG; - $ok = true; + global $CFG; + $ok = true; - if (strtolower($CFG->dbtype)=='postgres7') { - // add, delete and rename certain fields and indexes - // that were not correctly setup by postgres7.sql + if (strtolower($CFG->dbtype)=='postgres7') { + // add, delete and rename certain fields and indexes + // that were not correctly setup by postgres7.sql - // hotpot - $table = 'hotpot'; - if (hotpot_db_field_exists($table, 'studentfeedback') && !hotpot_db_field_exists($table, 'studentfeedbackurl')) { - $ok = $ok && hotpot_db_update_field_type($table, 'studentfeedback', 'studentfeedbackurl', 'VARCHAR', 255, '', 'NULL'); - $ok = $ok && hotpot_db_update_field_type($table, '', 'studentfeedback', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); - } + // hotpot + $table = 'hotpot'; + if (hotpot_db_field_exists($table, 'studentfeedback') && !hotpot_db_field_exists($table, 'studentfeedbackurl')) { + $ok = $ok && hotpot_db_update_field_type($table, 'studentfeedback', 'studentfeedbackurl', 'VARCHAR', 255, '', 'NULL'); + $ok = $ok && hotpot_db_update_field_type($table, '', 'studentfeedback', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); + } - // hotpot_attempts - $table = 'hotpot_attempts'; - $ok = $ok && hotpot_db_remove_field($table, 'groupid'); - if (hotpot_db_field_exists($table, 'microreportid') && !hotpot_db_field_exists($table, 'clickreportid')) { - $ok = $ok && hotpot_db_update_field_type($table, 'microreportid', 'clickreportid', 'INTEGER', 10, 'UNSIGNED', 'NULL'); - } + // hotpot_attempts + $table = 'hotpot_attempts'; + $ok = $ok && hotpot_db_remove_field($table, 'groupid'); + if (hotpot_db_field_exists($table, 'microreportid') && !hotpot_db_field_exists($table, 'clickreportid')) { + $ok = $ok && hotpot_db_update_field_type($table, 'microreportid', 'clickreportid', 'INTEGER', 10, 'UNSIGNED', 'NULL'); + } - // hotpot_questions (add index on question "name") - $table = 'hotpot_questions'; - $field = 'name'; - $index = "{$table}_{$field}_idx"; - if (!hotpot_db_index_exists("{$CFG->prefix}$table", "{$CFG->prefix}$index")) { - hotpot_db_add_index($table, $field, '20'); - } + // hotpot_questions (add index on question "name") + $table = 'hotpot_questions'; + $field = 'name'; + $index = "{$table}_{$field}_idx"; + if (!hotpot_db_index_exists("{$CFG->prefix}$table", "{$CFG->prefix}$index")) { + hotpot_db_add_index($table, $field, '20'); + } - // hotpot_strings (add index on "string") - $table = "hotpot_strings"; - $field = 'string'; - $index = "{$table}_{$field}_idx"; - if (!hotpot_db_index_exists("{$CFG->prefix}$table", "{$CFG->prefix}$index")) { - hotpot_db_add_index($table, $field, '20'); - } - } + // hotpot_strings (add index on "string") + $table = "hotpot_strings"; + $field = 'string'; + $index = "{$table}_{$field}_idx"; + if (!hotpot_db_index_exists("{$CFG->prefix}$table", "{$CFG->prefix}$index")) { + hotpot_db_add_index($table, $field, '20'); + } + } - return $ok; + return $ok; } function hotpot_update_to_v2_1_2() { - global $CFG, $db; - $ok = true; + global $CFG, $db; + $ok = true; - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = false; + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = false; - // extract info about attempts by each user on each hotpot (cases where - // the user has only one attempt, or no "in progess" attempt are ignored) - $rs = $db->Execute(" - SELECT userid, hotpot, COUNT(*), MIN(status) - FROM {$CFG->prefix}hotpot_attempts - GROUP BY userid, hotpot - HAVING COUNT(*)>1 AND MIN(status)=1 - "); - if ($rs && $rs->RecordCount()) { - $records = $rs->GetArray(); + // extract info about attempts by each user on each hotpot (cases where + // the user has only one attempt, or no "in progess" attempt are ignored) + $rs = $db->Execute(" + SELECT userid, hotpot, COUNT(*), MIN(status) + FROM {$CFG->prefix}hotpot_attempts + GROUP BY userid, hotpot + HAVING COUNT(*)>1 AND MIN(status)=1 + "); + if ($rs && $rs->RecordCount()) { + $records = $rs->GetArray(); - // start message to browser - print "adjusting status of ".count($records)." "in progress" attempts ... "; + // start message to browser + print "adjusting status of ".count($records)." "in progress" attempts ... "; - // loop through records - foreach ($records as $record) { + // loop through records + foreach ($records as $record) { - // get all attempts by this user at this hotpot - $attempts = get_records_sql(" - SELECT id, userid, hotpot, score, timestart, timefinish, status - FROM {$CFG->prefix}hotpot_attempts - WHERE userid = ".$record['userid']." AND hotpot=".$record['hotpot']." - ORDER BY timestart DESC, id DESC - "); + // get all attempts by this user at this hotpot + $attempts = get_records_sql(" + SELECT id, userid, hotpot, score, timestart, timefinish, status + FROM {$CFG->prefix}hotpot_attempts + WHERE userid = ".$record['userid']." AND hotpot=".$record['hotpot']." + ORDER BY timestart DESC, id DESC + "); - unset($previous_timestart); + unset($previous_timestart); - foreach ($attempts as $attempt) { - // if this attempt has a status of "in progress" and is not - // the most recent one in the group, set the status to "abandoned" - if ($attempt->status==1 && isset($previous_timestart)) { - $values = 'status=3'; - if (empty($attempt->score)) { - $values .= ',score=0'; - } - if (empty($attempt->timefinish)) { - $values .= ",timefinish=$previous_timestart"; - } - execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET $values WHERE id=$attempt->id", false); - print "."; - hotpot_flush(300); - } - $previous_timestart = $attempt->timestart; - } // end foreach $attempts - } // end foreach $records + foreach ($attempts as $attempt) { + // if this attempt has a status of "in progress" and is not + // the most recent one in the group, set the status to "abandoned" + if ($attempt->status==1 && isset($previous_timestart)) { + $values = 'status=3'; + if (empty($attempt->score)) { + $values .= ',score=0'; + } + if (empty($attempt->timefinish)) { + $values .= ",timefinish=$previous_timestart"; + } + execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET $values WHERE id=$attempt->id", false); + print "."; + hotpot_flush(300); + } + $previous_timestart = $attempt->timestart; + } // end foreach $attempts + } // end foreach $records - // finish message to browser - print $ok ? get_string('success') : 'failed'; - print "
\n"; - } + // finish message to browser + print $ok ? get_string('success') : 'failed'; + print "
\n"; + } - // restore SQL message echo setting - $db->debug = $debug; + // restore SQL message echo setting + $db->debug = $debug; - return $ok; + return $ok; } function hotpot_update_to_v2_1() { - global $CFG, $db; - $ok = true; - // hotpot_questions: reduce size of "type" field to "4" - $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'type', 'type', 'INTEGER', 4, 'UNSIGNED', 'NULL'); - // hotpot_questions: change type of "name" field to "text" - $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'name', 'name', 'TEXT', '', '', 'NOT NULL', ''); - // hotpot_questions: nullify empty and non-numeric (shouldn't be any) values in "text" field - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $NOT_REGEXP = 'NOT REGEXP'; - break; - case 'postgres7' : - $NOT_REGEXP = '!~'; - break; - default: - $NOT_REGEXP = ''; - break; - } - if ($NOT_REGEXP) { - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_questions SET text=NULL WHERE text $NOT_REGEXP '^[0-9]+$'"); - } - // hotpot_questions: change type of "text" field to "INT(10)" - $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'text', 'text', 'INTEGER', 10, 'UNSIGNED', 'NULL'); - // hotpot_attempts - // hotpot_attempts: move "details" to separate table - $table = 'hotpot_details'; - if (hotpot_db_table_exists($table)) { - // do nothing - } else { - $ok = $ok && hotpot_create_table($table); - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - case 'postgres7' : - $sql = " - INSERT INTO {$CFG->prefix}$table (attempt, details) - SELECT a.id AS attempt, a.details AS details - FROM {$CFG->prefix}hotpot_attempts AS a - WHERE - a.details IS NOT NULL AND a.details <> '' - AND a.details LIKE '' - "; - break; - default: - $sql = ''; - break; - } - if ($sql) { - $ok = $ok && execute_sql($sql); - } - } - // hotpot_attempts: remove the "details" field - $ok = $ok && hotpot_db_remove_field('hotpot_attempts', 'details'); - // hotpot_attempts: create and set status field (1=in-progress, 2=timed-out, 3=abandoned, 4=completed) - $ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'status', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=1 WHERE timefinish=0 AND SCORE IS NULL"); - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=3 WHERE timefinish>0 AND SCORE IS NULL"); - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=4 WHERE timefinish>0 AND SCORE IS NOT NULL"); - // hotpot_attempts: create and set clickreport fields - $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'clickreporting', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); - $ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'clickreportid', 'INTEGER', 10, 'UNSIGNED', 'NULL'); - $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET clickreportid=id WHERE clickreportid IS NULL"); - // hotpot_attempts: create and set studentfeedback field (0=none, 1=formmail, 2=moodleforum, 3=moodlemessaging) - $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedback', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); - $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedbackurl', 'VARCHAR', 255, '', 'NULL'); - // add indexes - $ok = $ok && hotpot_db_add_index('hotpot_attempts', 'hotpot'); - $ok = $ok && hotpot_db_add_index('hotpot_attempts', 'userid'); - $ok = $ok && hotpot_db_add_index('hotpot_details', 'attempt'); - $ok = $ok && hotpot_db_add_index('hotpot_questions', 'name', 20); - $ok = $ok && hotpot_db_add_index('hotpot_questions', 'hotpot'); - $ok = $ok && hotpot_db_add_index('hotpot_responses', 'attempt'); - $ok = $ok && hotpot_db_add_index('hotpot_responses', 'question'); - $ok = $ok && hotpot_db_add_index('hotpot_strings', 'string', 20); - // hotpot_string: correct double-encoded HTML entities - $ok = $ok && execute_sql(" - UPDATE {$CFG->prefix}hotpot_strings - SET string = REPLACE(string, '&','&') - WHERE string LIKE '%&#%' - AND (string LIKE '<' OR string LIKE '>') - "); - // hotpot_question: remove questions which refer to deleted hotpots - if ($ok) { - // try and get all hotpot records - if ($records = get_records('hotpot')) { - $ids = implode(',', array_keys($records)); - $sql = "DELETE FROM {$CFG->prefix}hotpot_questions WHERE hotpot NOT IN ($ids)"; - } else { - // remove all question records (because there are no valid hotpot ids) - $sql = "TRUNCATE {$CFG->prefix}hotpot_questions"; - } - print "Removing unused question records ..."; - execute_sql($sql); - } - if ($ok) { - // remove old 'v6' templates folder (replaced by 'template' folder) - $ds = DIRECTORY_SEPARATOR; - $dir = "mod{$ds}hotpot{$ds}v6"; - print "removing old templates ($dir) ... "; - if (hotpot_rm("$CFG->dirroot{$ds}$dir", false)) { - print get_string('success'); - } else { - print "failed
Please remove '$CFG->dirroot{$ds}$dir' manually"; - } - print "
\n"; - } - return $ok; + global $CFG, $db; + $ok = true; + // hotpot_questions: reduce size of "type" field to "4" + $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'type', 'type', 'INTEGER', 4, 'UNSIGNED', 'NULL'); + // hotpot_questions: change type of "name" field to "text" + $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'name', 'name', 'TEXT', '', '', 'NOT NULL', ''); + // hotpot_questions: nullify empty and non-numeric (shouldn't be any) values in "text" field + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $NOT_REGEXP = 'NOT REGEXP'; + break; + case 'postgres7' : + $NOT_REGEXP = '!~'; + break; + default: + $NOT_REGEXP = ''; + break; + } + if ($NOT_REGEXP) { + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_questions SET text=NULL WHERE text $NOT_REGEXP '^[0-9]+$'"); + } + // hotpot_questions: change type of "text" field to "INT(10)" + $ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'text', 'text', 'INTEGER', 10, 'UNSIGNED', 'NULL'); + // hotpot_attempts + // hotpot_attempts: move "details" to separate table + $table = 'hotpot_details'; + if (hotpot_db_table_exists($table)) { + // do nothing + } else { + $ok = $ok && hotpot_create_table($table); + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + case 'postgres7' : + $sql = " + INSERT INTO {$CFG->prefix}$table (attempt, details) + SELECT a.id AS attempt, a.details AS details + FROM {$CFG->prefix}hotpot_attempts AS a + WHERE + a.details IS NOT NULL AND a.details <> '' + AND a.details LIKE '' + "; + break; + default: + $sql = ''; + break; + } + if ($sql) { + $ok = $ok && execute_sql($sql); + } + } + // hotpot_attempts: remove the "details" field + $ok = $ok && hotpot_db_remove_field('hotpot_attempts', 'details'); + // hotpot_attempts: create and set status field (1=in-progress, 2=timed-out, 3=abandoned, 4=completed) + $ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'status', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=1 WHERE timefinish=0 AND SCORE IS NULL"); + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=3 WHERE timefinish>0 AND SCORE IS NULL"); + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=4 WHERE timefinish>0 AND SCORE IS NOT NULL"); + // hotpot_attempts: create and set clickreport fields + $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'clickreporting', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); + $ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'clickreportid', 'INTEGER', 10, 'UNSIGNED', 'NULL'); + $ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET clickreportid=id WHERE clickreportid IS NULL"); + // hotpot_attempts: create and set studentfeedback field (0=none, 1=formmail, 2=moodleforum, 3=moodlemessaging) + $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedback', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0'); + $ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedbackurl', 'VARCHAR', 255, '', 'NULL'); + // add indexes + $ok = $ok && hotpot_db_add_index('hotpot_attempts', 'hotpot'); + $ok = $ok && hotpot_db_add_index('hotpot_attempts', 'userid'); + $ok = $ok && hotpot_db_add_index('hotpot_details', 'attempt'); + $ok = $ok && hotpot_db_add_index('hotpot_questions', 'name', 20); + $ok = $ok && hotpot_db_add_index('hotpot_questions', 'hotpot'); + $ok = $ok && hotpot_db_add_index('hotpot_responses', 'attempt'); + $ok = $ok && hotpot_db_add_index('hotpot_responses', 'question'); + $ok = $ok && hotpot_db_add_index('hotpot_strings', 'string', 20); + // hotpot_string: correct double-encoded HTML entities + $ok = $ok && execute_sql(" + UPDATE {$CFG->prefix}hotpot_strings + SET string = REPLACE(string, '&','&') + WHERE string LIKE '%&#%' + AND (string LIKE '<' OR string LIKE '>') + "); + // hotpot_question: remove questions which refer to deleted hotpots + if ($ok) { + // try and get all hotpot records + if ($records = get_records('hotpot')) { + $ids = implode(',', array_keys($records)); + $sql = "DELETE FROM {$CFG->prefix}hotpot_questions WHERE hotpot NOT IN ($ids)"; + } else { + // remove all question records (because there are no valid hotpot ids) + $sql = "TRUNCATE {$CFG->prefix}hotpot_questions"; + } + print "Removing unused question records ..."; + execute_sql($sql); + } + if ($ok) { + // remove old 'v6' templates folder (replaced by 'template' folder) + $ds = DIRECTORY_SEPARATOR; + $dir = "mod{$ds}hotpot{$ds}v6"; + print "removing old templates ($dir) ... "; + if (hotpot_rm("$CFG->dirroot{$ds}$dir", false)) { + print get_string('success'); + } else { + print "failed
Please remove '$CFG->dirroot{$ds}$dir' manually"; + } + print "
\n"; + } + return $ok; } function hotpot_update_to_v2_from_v1() { - global $CFG; - $ok = true; - // remove, alter and add fields in database - $table = 'hotpot'; - if (hotpot_db_table_exists($table)) { - $ok = $ok && hotpot_update_fields($table); - } else { - $ok = $ok && hotpot_create_table($table); - } - $table = 'hotpot_attempts'; - $oldtable = 'hotpot_events'; - if (hotpot_db_table_exists($oldtable)) { - $ok = $ok && hotpot_update_fields($oldtable); - $ok = $ok && hotpot_db_append_table($oldtable, $table); - } else { - $ok = $ok && hotpot_create_table($table); - } - // create new tables (from mysql.sql) - $ok = $ok && hotpot_create_table('hotpot_questions'); - $ok = $ok && hotpot_create_table('hotpot_responses'); - $ok = $ok && hotpot_create_table('hotpot_strings'); - // remove redundant scripts - $files = array('coursefiles.php', 'details.php', 'dummy.html', 'hotpot.php', 'hotpot2db.php'); - foreach ($files as $file) { - $filepath = "$CFG->dirroot/mod/hotpot/$file"; - if (file_exists($filepath)) { - @unlink($filepath); // don't worry about errors - } - } - return $ok; + global $CFG; + $ok = true; + // remove, alter and add fields in database + $table = 'hotpot'; + if (hotpot_db_table_exists($table)) { + $ok = $ok && hotpot_update_fields($table); + } else { + $ok = $ok && hotpot_create_table($table); + } + $table = 'hotpot_attempts'; + $oldtable = 'hotpot_events'; + if (hotpot_db_table_exists($oldtable)) { + $ok = $ok && hotpot_update_fields($oldtable); + $ok = $ok && hotpot_db_append_table($oldtable, $table); + } else { + $ok = $ok && hotpot_create_table($table); + } + // create new tables (from mysql.sql) + $ok = $ok && hotpot_create_table('hotpot_questions'); + $ok = $ok && hotpot_create_table('hotpot_responses'); + $ok = $ok && hotpot_create_table('hotpot_strings'); + // remove redundant scripts + $files = array('coursefiles.php', 'details.php', 'dummy.html', 'hotpot.php', 'hotpot2db.php'); + foreach ($files as $file) { + $filepath = "$CFG->dirroot/mod/hotpot/$file"; + if (file_exists($filepath)) { + @unlink($filepath); // don't worry about errors + } + } + return $ok; } function hotpot_update_to_v2_from_hotpotatoes() { - global $CFG; - $ok = true; // hope for the best! - // check we have the minimum required hotpot module - $minimum = 2005031400; - $module = get_record("modules", "name", "hotpot"); - if (empty($module) || $module->version<$minimum) { - if ($module) { - print ("

The update to the HotPotatoes module requires at least version $minimum of the HotPot module.

"); - print ("

The current version of the HotPot module on this site is $module->version.

"); - } - print ("

Please install the latest version of the HotPot module and then try the update again.

"); - $ok = false; - } else { - // arrays to map foreign keys - $new = array(); - $new['hotpot'] = array(); - $new['attempt'] = array(); - $new['question'] = array(); - $new['string'] = array(); - // save and switch off SQL message echo - global $db; - $debug = $db->debug; - $db->debug = false; - // import hotpotatoes (and save old ids) - $ok = $ok && hotpot_update_fields('hotpotatoes'); - $ok = $ok && hotpot_transfer_records('hotpotatoes', 'hotpot', array(), 'hotpot', $new); - // update course modules and logs - $ok = $ok && hotpot_update_course_modules('hotpotatoes', 'hotpot', $new); - // import hotpotatoes_strings (and save old ids) - $ok = $ok && hotpot_transfer_records('hotpotatoes_strings', 'hotpot_strings', array(), 'string', $new); - // import hotpotatoes_attempts (and save old ids) - $ok = $ok && hotpot_transfer_records('hotpotatoes_attempts', 'hotpot_attempts', array('hotpotatoes'=>'hotpot'), 'attempt', $new); - // import hotpotatoes_questions (and save old ids) - $ok = $ok && hotpot_transfer_records('hotpotatoes_questions', 'hotpot_questions', array('hotpotatoes'=>'hotpot'), 'question', $new); - // import hotpotatoes_responses - $ok = $ok && hotpot_transfer_records('hotpotatoes_responses', 'hotpot_responses', array('attempt'=>'attempt', 'question'=>'question'), 'response', $new); - // restore SQL message echo setting - $db->debug = $debug; - // remove the hotpotatoes tables, if the update went ok - if ($ok) { - // hotpot_db_remove_table('hotpotatoes'); - // hotpot_db_remove_table('hotpotatoes_attempts'); - // hotpot_db_remove_table('hotpotatoes_questions'); - // hotpot_db_remove_table('hotpotatoes_responses'); - // hotpot_db_remove_table('hotpotatoes_strings'); - } - // hide the hotpotatoes module (see admin/modules.php)) - if ($ok && ($module = get_record("modules", "name", "hotpotatoes"))) { - set_field("modules", "visible", "0", "id", $module->id); - print '

All HotPotatoes activities have been imported to the HotPot module.
'."\n"; - print 'The HotPotatoes module has been hidden and can safely be deleted from this Moodle site.
'."\n"; - print '     Configuration -> Modules, then click "Delete" for "Hot Potatoes XML Quiz"

'."\n"; - } - } - if ($ok) { - print '

Thank you for using the HotPotatoes module.
'; - print 'The HotPotatoes module has been replaced by
version 2 of the HotPot module. Enjoy!

'; - } - return $ok; + global $CFG; + $ok = true; // hope for the best! + // check we have the minimum required hotpot module + $minimum = 2005031400; + $module = get_record("modules", "name", "hotpot"); + if (empty($module) || $module->version<$minimum) { + if ($module) { + print ("

The update to the HotPotatoes module requires at least version $minimum of the HotPot module.

"); + print ("

The current version of the HotPot module on this site is $module->version.

"); + } + print ("

Please install the latest version of the HotPot module and then try the update again.

"); + $ok = false; + } else { + // arrays to map foreign keys + $new = array(); + $new['hotpot'] = array(); + $new['attempt'] = array(); + $new['question'] = array(); + $new['string'] = array(); + // save and switch off SQL message echo + global $db; + $debug = $db->debug; + $db->debug = false; + // import hotpotatoes (and save old ids) + $ok = $ok && hotpot_update_fields('hotpotatoes'); + $ok = $ok && hotpot_transfer_records('hotpotatoes', 'hotpot', array(), 'hotpot', $new); + // update course modules and logs + $ok = $ok && hotpot_update_course_modules('hotpotatoes', 'hotpot', $new); + // import hotpotatoes_strings (and save old ids) + $ok = $ok && hotpot_transfer_records('hotpotatoes_strings', 'hotpot_strings', array(), 'string', $new); + // import hotpotatoes_attempts (and save old ids) + $ok = $ok && hotpot_transfer_records('hotpotatoes_attempts', 'hotpot_attempts', array('hotpotatoes'=>'hotpot'), 'attempt', $new); + // import hotpotatoes_questions (and save old ids) + $ok = $ok && hotpot_transfer_records('hotpotatoes_questions', 'hotpot_questions', array('hotpotatoes'=>'hotpot'), 'question', $new); + // import hotpotatoes_responses + $ok = $ok && hotpot_transfer_records('hotpotatoes_responses', 'hotpot_responses', array('attempt'=>'attempt', 'question'=>'question'), 'response', $new); + // restore SQL message echo setting + $db->debug = $debug; + // remove the hotpotatoes tables, if the update went ok + if ($ok) { + // hotpot_db_remove_table('hotpotatoes'); + // hotpot_db_remove_table('hotpotatoes_attempts'); + // hotpot_db_remove_table('hotpotatoes_questions'); + // hotpot_db_remove_table('hotpotatoes_responses'); + // hotpot_db_remove_table('hotpotatoes_strings'); + } + // hide the hotpotatoes module (see admin/modules.php)) + if ($ok && ($module = get_record("modules", "name", "hotpotatoes"))) { + set_field("modules", "visible", "0", "id", $module->id); + print '

All HotPotatoes activities have been imported to the HotPot module.
'."\n"; + print 'The HotPotatoes module has been hidden and can safely be deleted from this Moodle site.
'."\n"; + print '     Configuration -> Modules, then click "Delete" for "Hot Potatoes XML Quiz"

'."\n"; + } + } + if ($ok) { + print '

Thank you for using the HotPotatoes module.
'; + print 'The HotPotatoes module has been replaced by
version 2 of the HotPot module. Enjoy!

'; + } + return $ok; } function hotpot_create_table($table) { - global $CFG; - $ok = true; - static $sql; - if (empty($sql)) { // first time only - $filepath = "$CFG->dirroot/mod/hotpot/db/$CFG->dbtype.sql"; - if (function_exists('file_get_contents')) { - $sql = file_get_contents($filepath); - } else { // PHP < 4.3 - $sql = file($filepath); - if (is_array($sql)) { - $sql = implode('', $sql); - } - } - if(empty($sql)) { // $sql==false - $sql = ''; - } - } - // check table does not already exist - if (!hotpot_db_table_exists($table)) { - // extract and execute all CREATE statements relating to this table - if (preg_match_all("/CREATE (TABLE|INDEX)(\s[^;]*)? prefix_{$table}(\s[^;]*)?;/s", $sql, $strings)) { - foreach ($strings[0] as $string) { - $ok = $ok && modify_database('', $string); - } - } else { - // no CREATE statements found for this $table - $ok = false; - } - } - return $ok; + global $CFG; + $ok = true; + static $sql; + if (empty($sql)) { // first time only + $filepath = "$CFG->dirroot/mod/hotpot/db/$CFG->dbtype.sql"; + if (function_exists('file_get_contents')) { + $sql = file_get_contents($filepath); + } else { // PHP < 4.3 + $sql = file($filepath); + if (is_array($sql)) { + $sql = implode('', $sql); + } + } + if(empty($sql)) { // $sql==false + $sql = ''; + } + } + // check table does not already exist + if (!hotpot_db_table_exists($table)) { + // extract and execute all CREATE statements relating to this table + if (preg_match_all("/CREATE (TABLE|INDEX)(\s[^;]*)? prefix_{$table}(\s[^;]*)?;/s", $sql, $strings)) { + foreach ($strings[0] as $string) { + $ok = $ok && modify_database('', $string); + } + } else { + // no CREATE statements found for this $table + $ok = false; + } + } + return $ok; } function hotpot_transfer_records($oldtable, $table, $foreignkeys, $primarykey, &$new) { - global $db; - $ok = true; - // get the records, if any - if (hotpot_db_table_exists($oldtable) && ($records = get_records($oldtable))) { - // start progress report - $i = 0; - $count = count($records); - hotpot_update_print("Transferring $count records from "$oldtable" to "$table" ... "); - // transfer all $records - foreach ($records as $record) { - switch ($table) { - case 'hotpot' : - $record->summary = addslashes($record->summary); - break; - case 'hotpot_attempts' : - $record->details = addslashes($record->details); - break; - case 'hotpot_questions' : - $record->name = addslashes($record->name); - hotpot_update_string_id_list($table, $record, 'TEXT', $new); - break; - case 'hotpot_responses' : - hotpot_update_string_id_list($table, $record, 'correct', $new); - hotpot_update_string_id_list($table, $record, 'ignored', $new); - hotpot_update_string_id_list($table, $record, 'wrong', $new); - break; - case 'hotpot_strings' : - $record->string = addslashes($record->string); - break; - } - // update foreign keys, if any - foreach ($foreignkeys as $oldkey=>$key) { - // transfer (and update) key - $value = $record->$oldkey; - if (isset($new[$key][$value])) { - $record->$key = $new[$key][$value]; - } else { - // foreign key could not be updated - $ok = hotpot_update_print_warning($key, $value, $oldtable, $record->id) && $ok; - unset($record->id); - } - } - if ($ok && isset($record->id)) { - // store and remove old primary key - $id = $record->id; - unset($record->id); - // add the updated record and store the new id - $new[$primarykey][$id] = insert_record($table, $record, true); - // check id is numeric - if (!is_numeric($new[$primarykey][$id])) { - hotpot_update_print("
  • Record could not added to $table table ($oldtable id=$id)
  • \n"); - //$ok = false; - } - } - $i++; - hotpot_update_print_progress($i); - } - // finish progress report - hotpot_update_print_ok($ok); - } - return $ok; + global $db; + $ok = true; + // get the records, if any + if (hotpot_db_table_exists($oldtable) && ($records = get_records($oldtable))) { + // start progress report + $i = 0; + $count = count($records); + hotpot_update_print("Transferring $count records from "$oldtable" to "$table" ... "); + // transfer all $records + foreach ($records as $record) { + switch ($table) { + case 'hotpot' : + $record->summary = addslashes($record->summary); + break; + case 'hotpot_attempts' : + $record->details = addslashes($record->details); + break; + case 'hotpot_questions' : + $record->name = addslashes($record->name); + hotpot_update_string_id_list($table, $record, 'TEXT', $new); + break; + case 'hotpot_responses' : + hotpot_update_string_id_list($table, $record, 'correct', $new); + hotpot_update_string_id_list($table, $record, 'ignored', $new); + hotpot_update_string_id_list($table, $record, 'wrong', $new); + break; + case 'hotpot_strings' : + $record->string = addslashes($record->string); + break; + } + // update foreign keys, if any + foreach ($foreignkeys as $oldkey=>$key) { + // transfer (and update) key + $value = $record->$oldkey; + if (isset($new[$key][$value])) { + $record->$key = $new[$key][$value]; + } else { + // foreign key could not be updated + $ok = hotpot_update_print_warning($key, $value, $oldtable, $record->id) && $ok; + unset($record->id); + } + } + if ($ok && isset($record->id)) { + // store and remove old primary key + $id = $record->id; + unset($record->id); + // add the updated record and store the new id + $new[$primarykey][$id] = insert_record($table, $record, true); + // check id is numeric + if (!is_numeric($new[$primarykey][$id])) { + hotpot_update_print("
  • Record could not added to $table table ($oldtable id=$id)
  • \n"); + //$ok = false; + } + } + $i++; + hotpot_update_print_progress($i); + } + // finish progress report + hotpot_update_print_ok($ok); + } + return $ok; } function hotpot_update_course_modules($oldmodulename, $modulename, &$new) { - $ok = true; - $oldmoduleid = get_field('modules', 'id', 'name', $oldmodulename); - $moduleid = get_field('modules', 'id', 'name', $modulename); - if (is_numeric($oldmoduleid) && is_numeric($moduleid)) { - // get module records - if ($records = get_records('course_modules', 'module', $oldmoduleid)) { - // start progress report - $count = count($records); - hotpot_update_print("Updating $count course modules from "$oldmodulename" to "$modulename" ... "); - // update foreign keys in all $records - foreach ($records as $record) { - // update instance - $instance = $record->instance; - if (isset($new[$modulename][$instance])) { - $record->instance = $new[$modulename][$instance]; - } else if ($record->deleted) { - unset($record->id); - } else { - // could not find new id of course module - $ok = hotpot_update_print_warning("$modulename instance", $instance, 'course_modules', $record->id) && $ok; - unset($record->id); - } - // update module id - if ($ok && isset($record->id)) { - $record->module = $moduleid; - $ok = update_record('course_modules', $record); - } - } - // finish progress report - hotpot_update_print_ok($ok); - } - // update logs - $ok = $ok && hotpot_update_logs($oldmodulename, $modulename, $moduleid, $new); - } - return $ok; + $ok = true; + $oldmoduleid = get_field('modules', 'id', 'name', $oldmodulename); + $moduleid = get_field('modules', 'id', 'name', $modulename); + if (is_numeric($oldmoduleid) && is_numeric($moduleid)) { + // get module records + if ($records = get_records('course_modules', 'module', $oldmoduleid)) { + // start progress report + $count = count($records); + hotpot_update_print("Updating $count course modules from "$oldmodulename" to "$modulename" ... "); + // update foreign keys in all $records + foreach ($records as $record) { + // update instance + $instance = $record->instance; + if (isset($new[$modulename][$instance])) { + $record->instance = $new[$modulename][$instance]; + } else if ($record->deleted) { + unset($record->id); + } else { + // could not find new id of course module + $ok = hotpot_update_print_warning("$modulename instance", $instance, 'course_modules', $record->id) && $ok; + unset($record->id); + } + // update module id + if ($ok && isset($record->id)) { + $record->module = $moduleid; + $ok = update_record('course_modules', $record); + } + } + // finish progress report + hotpot_update_print_ok($ok); + } + // update logs + $ok = $ok && hotpot_update_logs($oldmodulename, $modulename, $moduleid, $new); + } + return $ok; } function hotpot_update_logs($oldmodulename, $modulename, $moduleid, &$new) { - $table = 'log'; - $ok = true; - // get log records for the oldmodule - if ($records = get_records($table, 'module', $oldmodulename)) { - // start progress report - $i = 0; - $count = count($records); - hotpot_update_print("Updating $count log records ... "); - // update foreign keys in all $records - foreach ($records as $record) { - // update course module name - $record->module = $modulename; - // check if module id was given (usually it is) - if ($record->cmid) { - // update course module id, if necessary - if (isset($new[$modulename][$record->cmid])) { - $record->cmid = $new[$modulename][$record->cmid]; - } else { - // could not update course module id - $ok = hotpot_update_print_warning('cmid', $record->cmid, 'log', $record->id) && $ok; - unset($record->id); - } - // update url and info - switch ($record->action) { - case "add": - case "update": - case "view": - $record->url = "view.php?id=".$record->cmid; - $record->info = $moduleid; - break; - case "view all": - // do nothing - break; - case "report": - $record->url = "report.php?id=".$record->cmid; - $record->info = $moduleid; - break; - case "attempt": - case "submit": - case "review": - $id = substr(strrchr($record->url,"="),1); - if (isset($new->attempt[$id])) { - $id = $new->attempt[$id]; - } - $record->url = "review.php?id=".$record->cmid."&attempt=$id"; - $record->info = $moduleid; - break; - default: - // unknown log action - $ok = hotpot_update_print_warning('action', $record->action, 'log', $record->id) && $ok; - unset($record->id); - } // end switch - } - if (isset($record->id)) { - $ok = $ok && update_record($table, $record); - } - $i++; - hotpot_update_print_progress($i); - } // end foreach - // finish progress report - hotpot_update_print_ok($ok); - } - return $ok; + $table = 'log'; + $ok = true; + // get log records for the oldmodule + if ($records = get_records($table, 'module', $oldmodulename)) { + // start progress report + $i = 0; + $count = count($records); + hotpot_update_print("Updating $count log records ... "); + // update foreign keys in all $records + foreach ($records as $record) { + // update course module name + $record->module = $modulename; + // check if module id was given (usually it is) + if ($record->cmid) { + // update course module id, if necessary + if (isset($new[$modulename][$record->cmid])) { + $record->cmid = $new[$modulename][$record->cmid]; + } else { + // could not update course module id + $ok = hotpot_update_print_warning('cmid', $record->cmid, 'log', $record->id) && $ok; + unset($record->id); + } + // update url and info + switch ($record->action) { + case "add": + case "update": + case "view": + $record->url = "view.php?id=".$record->cmid; + $record->info = $moduleid; + break; + case "view all": + // do nothing + break; + case "report": + $record->url = "report.php?id=".$record->cmid; + $record->info = $moduleid; + break; + case "attempt": + case "submit": + case "review": + $id = substr(strrchr($record->url,"="),1); + if (isset($new->attempt[$id])) { + $id = $new->attempt[$id]; + } + $record->url = "review.php?id=".$record->cmid."&attempt=$id"; + $record->info = $moduleid; + break; + default: + // unknown log action + $ok = hotpot_update_print_warning('action', $record->action, 'log', $record->id) && $ok; + unset($record->id); + } // end switch + } + if (isset($record->id)) { + $ok = $ok && update_record($table, $record); + } + $i++; + hotpot_update_print_progress($i); + } // end foreach + // finish progress report + hotpot_update_print_ok($ok); + } + return $ok; } function hotpot_update_fields($table, $feedback=false) { - global $CFG, $db; - $ok = true; - // check the table exists - if (hotpot_db_table_exists($table)) { - switch ($table) { - case 'hotpot' : - // == ADD == - hotpot_db_update_field_type($table, '', 'location', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); - hotpot_db_update_field_type($table, '', 'navigation', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); - hotpot_db_update_field_type($table, '', 'outputformat', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); - hotpot_db_update_field_type($table, '', 'shownextquiz', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); - hotpot_db_update_field_type($table, '', 'forceplugins', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); - hotpot_db_update_field_type($table, '', 'password', 'VARCHAR', 255, '', 'NOT NULL', ''); - hotpot_db_update_field_type($table, '', 'subnet', 'VARCHAR', 255, '', 'NOT NULL', ''); - // == ALTER == - hotpot_db_update_field_type($table, 'summary', 'summary', 'TEXT', '', '', 'NOT NULL', ''); - hotpot_db_update_field_type($table, 'reference', 'reference', 'VARCHAR', 255, '', 'NOT NULL', ''); - // == REMOVE == - hotpot_db_remove_field($table, 'intro'); - hotpot_db_remove_field($table, 'attemptonlast'); - hotpot_db_remove_field($table, 'sumgrades'); - hotpot_db_set_table_comment($table, 'details about Hot Potatoes quizzes'); - break; - case 'hotpot_events' : - // == ADD == - hotpot_db_update_field_type($table, '', 'hotpot', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL'); - hotpot_db_update_field_type($table, '', 'attempt', 'INTEGER', 6, 'UNSIGNED', 'NOT NULL'); - hotpot_db_update_field_type($table, '', 'details', 'TEXT', '', '', '', ''); - hotpot_db_update_field_type($table, '', 'timestart', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL', 0); - hotpot_db_update_field_type($table, '', 'timefinish', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL', 0); - // == ALTER == - hotpot_db_update_field_type($table, 'score', 'score', 'INTEGER', 6, 'UNSIGNED', 'NULL'); - hotpot_db_update_field_type($table, 'wrong', 'penalties', 'INTEGER', 6, 'UNSIGNED', 'NULL'); - hotpot_db_update_field_type($table, 'starttime', 'starttime', 'INTEGER', 10, 'UNSIGNED', 'NULL'); - hotpot_db_update_field_type($table, 'endtime', 'endtime', 'INTEGER', 10, 'UNSIGNED', 'NULL'); - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = $feedback; - // get array mapping course module ids to hotpot ids - $hotpotmoduleid = get_field('modules', 'id', 'name', 'hotpot'); - $coursemodules = get_records('course_modules', 'module', $hotpotmoduleid, 'id', 'id, instance'); - // get all event records - if (hotpot_db_field_exists($table, 'hotpotid')) { - $records = get_records($table, '', '', 'userid,hotpotid,time'); - } else { - $records = false; // table has already been updated - } - if ($records) { - $count = count($records); - hotpot_update_print("Updating $count records in $table ... "); - $ids = array_keys($records); - foreach ($ids as $i=>$id) { - // reference to current record - $record = &$records[$id]; - // set timestart and timefinish (the times recorded by Moodle) - if (empty($record->timestart) && $record->time) { - $record->timestart = $record->time; - } - if (empty($record->timefinish) && $record->timestart) { - if ($record->starttime && $record->endtime) { - $duration = ($record->endtime - $record->starttime); - } else { - if (($i+1)>=$count) { - $nextrecord = NULL; - } else { - $nextrecord = &$records[$ids[$i+1]]; - } - if (isset($nextrecord) && $nextrecord->userid==$record->userid && $nextrecord->hotpotid==$record->hotpotid) { - $duration = $nextrecord->time - $record->time; - } else { - $duration = NULL; - } - } - if (isset($duration)) { - $record->timefinish = $record->timestart + $duration; - } - } - // unset score and penalties, if quiz was abandoned - if (empty($record->endtime) || (empty($record->penalties) && empty($record->score))) { - unset($record->score); - unset($record->penalties); - } - // get last (=previous) record - if ($i==0) { - $lastrecord = NULL; - } else { - $lastrecord = &$records[$ids[$i-1]]; - } - // increment or reset $attempt number - if (isset($lastrecord) && $lastrecord->userid==$record->userid && $lastrecord->hotpotid==$record->hotpotid) { - $attempt++; - } else { - $attempt = 1; - } - // set $record->$attempt, if necessary - if (empty($record->attempt) || $record->attempt<$attempt) { - $record->attempt = $attempt; - } else { - $attempt = $record->attempt; - } - // set hotpot id and update record - if (isset($record->hotpotid) && isset($record->id)) { - if (isset($coursemodules[$record->hotpotid])) { - $record->hotpot = $coursemodules[$record->hotpotid]->instance; - hotpot_db_update_record($table, $record, true); - } else { - // hotpotid is invalid (shouldn't happen) - $ok = hotpot_update_print_warning('hotpotid', $record->hotpotid, $table, $record->id) && $ok; - delete_records($table, 'id', $record->id); - } - } else { - // empty record (shouldn't happen) - } - hotpot_update_print_progress($i); - } - // finish progress report - hotpot_update_print_ok($ok); - } - // restore SQL message echo setting - $db->debug = $debug; - // == REMOVE == - hotpot_db_remove_field($table, 'hotpotid'); - hotpot_db_remove_field($table, 'course'); - hotpot_db_remove_field($table, 'time'); - hotpot_db_remove_field($table, 'event'); - hotpot_db_set_table_comment($table, 'details about Hot Potatoes quiz attempts'); - break; - case 'hotpotatoes' : - // == ALTER == - hotpot_db_update_field_type($table, 'intro', 'summary', 'TEXT', '', '', '', 'NULL'); - break; - } - } - return $ok; + global $CFG, $db; + $ok = true; + // check the table exists + if (hotpot_db_table_exists($table)) { + switch ($table) { + case 'hotpot' : + // == ADD == + hotpot_db_update_field_type($table, '', 'location', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); + hotpot_db_update_field_type($table, '', 'navigation', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); + hotpot_db_update_field_type($table, '', 'outputformat', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1); + hotpot_db_update_field_type($table, '', 'shownextquiz', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); + hotpot_db_update_field_type($table, '', 'forceplugins', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0); + hotpot_db_update_field_type($table, '', 'password', 'VARCHAR', 255, '', 'NOT NULL', ''); + hotpot_db_update_field_type($table, '', 'subnet', 'VARCHAR', 255, '', 'NOT NULL', ''); + // == ALTER == + hotpot_db_update_field_type($table, 'summary', 'summary', 'TEXT', '', '', 'NOT NULL', ''); + hotpot_db_update_field_type($table, 'reference', 'reference', 'VARCHAR', 255, '', 'NOT NULL', ''); + // == REMOVE == + hotpot_db_remove_field($table, 'intro'); + hotpot_db_remove_field($table, 'attemptonlast'); + hotpot_db_remove_field($table, 'sumgrades'); + hotpot_db_set_table_comment($table, 'details about Hot Potatoes quizzes'); + break; + case 'hotpot_events' : + // == ADD == + hotpot_db_update_field_type($table, '', 'hotpot', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL'); + hotpot_db_update_field_type($table, '', 'attempt', 'INTEGER', 6, 'UNSIGNED', 'NOT NULL'); + hotpot_db_update_field_type($table, '', 'details', 'TEXT', '', '', '', ''); + hotpot_db_update_field_type($table, '', 'timestart', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL', 0); + hotpot_db_update_field_type($table, '', 'timefinish', 'INTEGER', 10, 'UNSIGNED', 'NOT NULL', 0); + // == ALTER == + hotpot_db_update_field_type($table, 'score', 'score', 'INTEGER', 6, 'UNSIGNED', 'NULL'); + hotpot_db_update_field_type($table, 'wrong', 'penalties', 'INTEGER', 6, 'UNSIGNED', 'NULL'); + hotpot_db_update_field_type($table, 'starttime', 'starttime', 'INTEGER', 10, 'UNSIGNED', 'NULL'); + hotpot_db_update_field_type($table, 'endtime', 'endtime', 'INTEGER', 10, 'UNSIGNED', 'NULL'); + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = $feedback; + // get array mapping course module ids to hotpot ids + $hotpotmoduleid = get_field('modules', 'id', 'name', 'hotpot'); + $coursemodules = get_records('course_modules', 'module', $hotpotmoduleid, 'id', 'id, instance'); + // get all event records + if (hotpot_db_field_exists($table, 'hotpotid')) { + $records = get_records($table, '', '', 'userid,hotpotid,time'); + } else { + $records = false; // table has already been updated + } + if ($records) { + $count = count($records); + hotpot_update_print("Updating $count records in $table ... "); + $ids = array_keys($records); + foreach ($ids as $i=>$id) { + // reference to current record + $record = &$records[$id]; + // set timestart and timefinish (the times recorded by Moodle) + if (empty($record->timestart) && $record->time) { + $record->timestart = $record->time; + } + if (empty($record->timefinish) && $record->timestart) { + if ($record->starttime && $record->endtime) { + $duration = ($record->endtime - $record->starttime); + } else { + if (($i+1)>=$count) { + $nextrecord = NULL; + } else { + $nextrecord = &$records[$ids[$i+1]]; + } + if (isset($nextrecord) && $nextrecord->userid==$record->userid && $nextrecord->hotpotid==$record->hotpotid) { + $duration = $nextrecord->time - $record->time; + } else { + $duration = NULL; + } + } + if (isset($duration)) { + $record->timefinish = $record->timestart + $duration; + } + } + // unset score and penalties, if quiz was abandoned + if (empty($record->endtime) || (empty($record->penalties) && empty($record->score))) { + unset($record->score); + unset($record->penalties); + } + // get last (=previous) record + if ($i==0) { + $lastrecord = NULL; + } else { + $lastrecord = &$records[$ids[$i-1]]; + } + // increment or reset $attempt number + if (isset($lastrecord) && $lastrecord->userid==$record->userid && $lastrecord->hotpotid==$record->hotpotid) { + $attempt++; + } else { + $attempt = 1; + } + // set $record->$attempt, if necessary + if (empty($record->attempt) || $record->attempt<$attempt) { + $record->attempt = $attempt; + } else { + $attempt = $record->attempt; + } + // set hotpot id and update record + if (isset($record->hotpotid) && isset($record->id)) { + if (isset($coursemodules[$record->hotpotid])) { + $record->hotpot = $coursemodules[$record->hotpotid]->instance; + hotpot_db_update_record($table, $record, true); + } else { + // hotpotid is invalid (shouldn't happen) + $ok = hotpot_update_print_warning('hotpotid', $record->hotpotid, $table, $record->id) && $ok; + delete_records($table, 'id', $record->id); + } + } else { + // empty record (shouldn't happen) + } + hotpot_update_print_progress($i); + } + // finish progress report + hotpot_update_print_ok($ok); + } + // restore SQL message echo setting + $db->debug = $debug; + // == REMOVE == + hotpot_db_remove_field($table, 'hotpotid'); + hotpot_db_remove_field($table, 'course'); + hotpot_db_remove_field($table, 'time'); + hotpot_db_remove_field($table, 'event'); + hotpot_db_set_table_comment($table, 'details about Hot Potatoes quiz attempts'); + break; + case 'hotpotatoes' : + // == ALTER == + hotpot_db_update_field_type($table, 'intro', 'summary', 'TEXT', '', '', '', 'NULL'); + break; + } + } + return $ok; } function hotpot_update_string_id_list($table, &$record, $field, &$new) { - $ok = true; - if (isset($record->$field)) { - $oldids = explode(',', $record->$field); - $newids = array(); - foreach ($oldids as $id) { - if (isset($new['string'][$id])) { - $newids[] = $new['string'][$id]; - } else if (is_numeric($id)) { - // string id could not be updated - $ok = hotpot_update_print_warning("string id in $field", $id, $table, $record->id) && $ok; - } else { - // ignore non-numeric ids (e.g. blanks) - } - } - if ($ok) { - $record->$field = implode(',', $newids); - } - } - return $ok; + $ok = true; + if (isset($record->$field)) { + $oldids = explode(',', $record->$field); + $newids = array(); + foreach ($oldids as $id) { + if (isset($new['string'][$id])) { + $newids[] = $new['string'][$id]; + } else if (is_numeric($id)) { + // string id could not be updated + $ok = hotpot_update_print_warning("string id in $field", $id, $table, $record->id) && $ok; + } else { + // ignore non-numeric ids (e.g. blanks) + } + } + if ($ok) { + $record->$field = implode(',', $newids); + } + } + return $ok; } /////////////////////////// // print functions /////////////////////////// function hotpot_update_print($msg=false, $n=300) { - // this function prints $msg and flush output buffer - if ($msg) { - if (is_string($msg)) { - print $msg; - } else { - print strftime("%X", time()); - } - } - // fill output buffer - if ($n) { - print str_repeat(" ", $n); - } - // some browser's require newline to flush - print "\n"; - // flush PHP's output buffer - flush(); + // this function prints $msg and flush output buffer + if ($msg) { + if (is_string($msg)) { + print $msg; + } else { + print strftime("%X", time()); + } + } + // fill output buffer + if ($n) { + print str_repeat(" ", $n); + } + // some browser's require newline to flush + print "\n"; + // flush PHP's output buffer + flush(); } function hotpot_update_print_progress($i) { - if ($i%10==0) { - $msg = '.'; - hotpot_update_print($msg); - } + if ($i%10==0) { + $msg = '.'; + hotpot_update_print($msg); + } } function hotpot_update_print_ok($ok) { - if ($ok) { - hotpot_update_print(''.get_string('success')."
    \n"); - } else { - hotpot_update_print(''.get_string('error')."
    \n"); - } + if ($ok) { + hotpot_update_print(''.get_string('success')."
    \n"); + } else { + hotpot_update_print(''.get_string('error')."
    \n"); + } } function hotpot_update_print_warning($field, $value, $table, $id) { - hotpot_update_print("
  • Warning: invalid $field field (value=$value) in $table (id=$id)
  • \n"); - return true; + hotpot_update_print("
  • Warning: invalid $field field (value=$value) in $table (id=$id)
  • \n"); + return true; } /////////////////////////// // database functions /////////////////////////// function hotpot_db_index_exists($table, $index, $feedback=false) { - global $CFG, $db; - $exists = false; - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = $feedback; - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $rs = $db->Execute("SHOW INDEX FROM `$table`"); - if ($rs && $rs->RecordCount()>0) { - $records = $rs->GetArray(); - foreach ($records as $record) { - if (isset($record['Key_name']) && $record['Key_name']==$index) { - $exists = true; - break; - } - } - } - break; - case 'postgres7' : - $rs = $db->Execute("SELECT relname FROM pg_class WHERE relname = '$index' AND relkind='i'"); - if ($rs && $rs->RecordCount()>0) { - $exists = true; - } - break; - } - // restore SQL message echo - $db->debug = $debug; - return $exists; + global $CFG, $db; + $exists = false; + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = $feedback; + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $rs = $db->Execute("SHOW INDEX FROM `$table`"); + if ($rs && $rs->RecordCount()>0) { + $records = $rs->GetArray(); + foreach ($records as $record) { + if (isset($record['Key_name']) && $record['Key_name']==$index) { + $exists = true; + break; + } + } + } + break; + case 'postgres7' : + $rs = $db->Execute("SELECT relname FROM pg_class WHERE relname = '$index' AND relkind='i'"); + if ($rs && $rs->RecordCount()>0) { + $exists = true; + } + break; + } + // restore SQL message echo + $db->debug = $debug; + return $exists; } function hotpot_db_delete_index($table, $index, $feedback=false) { - global $CFG, $db; - $ok = true; - // check index exists - if (hotpot_db_index_exists($table, $index)) { - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $sql = "ALTER TABLE `$table` DROP INDEX `$index`"; - break; - case 'postgres7' : - $sql = "DROP INDEX $index"; - break; - default: // unknown database type - $sql = ''; - break; - } - if ($sql) { - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = $feedback; - $ok = $db->Execute($sql) ? true : false; - // restore SQL message echo - $db->debug = $debug; - } else { // unknown database type - $ok = false; - } - } - return $ok; + global $CFG, $db; + $ok = true; + // check index exists + if (hotpot_db_index_exists($table, $index)) { + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $sql = "ALTER TABLE `$table` DROP INDEX `$index`"; + break; + case 'postgres7' : + $sql = "DROP INDEX $index"; + break; + default: // unknown database type + $sql = ''; + break; + } + if ($sql) { + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = $feedback; + $ok = $db->Execute($sql) ? true : false; + // restore SQL message echo + $db->debug = $debug; + } else { // unknown database type + $ok = false; + } + } + return $ok; } function hotpot_db_add_index($table, $field, $length='') { - global $CFG, $db; + global $CFG, $db; - if (strtolower($CFG->dbtype)=='postgres7') { - $index = "{$CFG->prefix}{$table}_{$field}_idx"; - } else { - // mysql (and others) - $index = "{$table}_{$field}_idx"; - } - $table = "{$CFG->prefix}$table"; + if (strtolower($CFG->dbtype)=='postgres7') { + $index = "{$CFG->prefix}{$table}_{$field}_idx"; + } else { + // mysql (and others) + $index = "{$table}_{$field}_idx"; + } + $table = "{$CFG->prefix}$table"; - // delete $index if it already exists - $ok = hotpot_db_delete_index($table, $index); + // delete $index if it already exists + $ok = hotpot_db_delete_index($table, $index); - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $length = empty($length) ? '' : " ($length)"; - $ok = $ok && $db->Execute("ALTER TABLE `$table` ADD INDEX `$index` (`$field`$length)"); - break; - case 'postgres7' : - if ($length) { - $field = "SUBSTR(\"$field\",$length)"; - } - $ok = $ok && $db->Execute("CREATE INDEX $index ON $table ($field)"); - break; - default: // unknown database type - $ok = false; - break; - } - return $ok; + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $length = empty($length) ? '' : " ($length)"; + $ok = $ok && $db->Execute("ALTER TABLE `$table` ADD INDEX `$index` (`$field`$length)"); + break; + case 'postgres7' : + if ($length) { + $field = "SUBSTR(\"$field\",$length)"; + } + $ok = $ok && $db->Execute("CREATE INDEX $index ON $table ($field)"); + break; + default: // unknown database type + $ok = false; + break; + } + return $ok; } function hotpot_db_table_exists($table, $feedback=false) { - return hotpot_db_object_exists($table, '', $feedback); + return hotpot_db_object_exists($table, '', $feedback); } function hotpot_db_field_exists($table, $field, $feedback=false) { - return - hotpot_db_object_exists($table, '', $feedback) && - hotpot_db_object_exists($table, $field, $feedback) - ; + return + hotpot_db_object_exists($table, '', $feedback) && + hotpot_db_object_exists($table, $field, $feedback) + ; } function hotpot_db_object_exists($table, $field='', $feedback=false) { - global $CFG,$db; - // expand table name - $table = "{$CFG->prefix}$table"; - // set $sql - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - if (empty($field)) { - $sql = "SHOW TABLES LIKE '$table'"; - } else { - $sql = "SHOW COLUMNS FROM `$table` LIKE '$field'"; - } - break; - case 'postgres7' : - if (empty($field)) { - $sql = "SELECT relname FROM pg_class WHERE relname = '$table' AND relkind='r'"; - } else { - $sql = " - SELECT attname FROM pg_attribute WHERE attname = '$field' - AND attrelid = (SELECT oid FROM pg_class WHERE relname = '$table') - "; - } - break; - } - // save and switch off SQL message echo - $debug = $db->debug; - $db->debug = $feedback; - // execute sql - $rs = $db->Execute($sql); - // restore SQL message echo setting - $db->debug = $debug; - // report error if required - if (empty($rs) && isset($CFG->debug) and $CFG->debug > 7) { - notify($db->ErrorMsg()."

    $sql"); - } - return ($rs && $rs->RecordCount()>0); + global $CFG,$db; + // expand table name + $table = "{$CFG->prefix}$table"; + // set $sql + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + if (empty($field)) { + $sql = "SHOW TABLES LIKE '$table'"; + } else { + $sql = "SHOW COLUMNS FROM `$table` LIKE '$field'"; + } + break; + case 'postgres7' : + if (empty($field)) { + $sql = "SELECT relname FROM pg_class WHERE relname = '$table' AND relkind='r'"; + } else { + $sql = " + SELECT attname FROM pg_attribute WHERE attname = '$field' + AND attrelid = (SELECT oid FROM pg_class WHERE relname = '$table') + "; + } + break; + } + // save and switch off SQL message echo + $debug = $db->debug; + $db->debug = $feedback; + // execute sql + $rs = $db->Execute($sql); + // restore SQL message echo setting + $db->debug = $debug; + // report error if required + if (empty($rs) && isset($CFG->debug) and $CFG->debug > 7) { + notify($db->ErrorMsg()."

    $sql"); + } + return ($rs && $rs->RecordCount()>0); } function hotpot_db_remove_table($table, $feedback=true) { - global $CFG; - if (hotpot_db_table_exists($table)) { - $ok = execute_sql("DROP TABLE {$CFG->prefix}$table", $feedback); - } else { - $ok = true; - } - return $ok; + global $CFG; + if (hotpot_db_table_exists($table)) { + $ok = execute_sql("DROP TABLE {$CFG->prefix}$table", $feedback); + } else { + $ok = true; + } + return $ok; } function hotpot_db_rename_table($oldtable, $table, $feedback=true) { - global $CFG; - if (hotpot_db_table_exists($oldtable)) { - $ok = execute_sql("ALTER TABLE {$CFG->prefix}$oldtable RENAME TO {$CFG->prefix}$table", $feedback); - } else { - $ok = true; - } - return $ok; + global $CFG; + if (hotpot_db_table_exists($oldtable)) { + $ok = execute_sql("ALTER TABLE {$CFG->prefix}$oldtable RENAME TO {$CFG->prefix}$table", $feedback); + } else { + $ok = true; + } + return $ok; } function hotpot_db_append_table($oldtable, $table, $feedback=true) { - global $CFG, $db; - if (hotpot_db_table_exists($oldtable)) { - if (hotpot_db_table_exists($table)) { - // expand table names - $table = "{$CFG->prefix}$table"; - $oldtable = "{$CFG->prefix}$oldtable"; - // get field info - $fields = $db->MetaColumns($table); - $oldfields = $db->MetaColumns($oldtable); - $fieldnames = array(); - if (!empty($fields) || !empty($oldfields)) { - foreach ($fields as $field) { - if ($field->name!='id' && isset($oldfields[strtoupper($field->name)])) { - $fieldnames[] = $field->name; - } - } - } - $fieldnames = implode(',', $fieldnames); - if (empty($fieldnames)) { - $ok = false; - } else { - switch (strtolower($CFG->dbtype)) { - case 'mysql': - $ok = execute_sql("INSERT INTO `$table` ($fieldnames) SELECT $fieldnames FROM `$oldtable` WHERE 1"); - break; - case 'postgres7': - $ok = execute_sql("INSERT INTO $table ($fieldnames) SELECT $fieldnames FROM $oldtable"); - break; - default: - $ok = false; - break; - } - } - } else { // $table does not exist - $ok = hotpot_db_rename_table($oldtable, $table, $feedback); - } - } else { // $oldtable does not exist - $ok = hotpot_db_table_exists($table, $feedback); - } - return $ok; + global $CFG, $db; + if (hotpot_db_table_exists($oldtable)) { + if (hotpot_db_table_exists($table)) { + // expand table names + $table = "{$CFG->prefix}$table"; + $oldtable = "{$CFG->prefix}$oldtable"; + // get field info + $fields = $db->MetaColumns($table); + $oldfields = $db->MetaColumns($oldtable); + $fieldnames = array(); + if (!empty($fields) || !empty($oldfields)) { + foreach ($fields as $field) { + if ($field->name!='id' && isset($oldfields[strtoupper($field->name)])) { + $fieldnames[] = $field->name; + } + } + } + $fieldnames = implode(',', $fieldnames); + if (empty($fieldnames)) { + $ok = false; + } else { + switch (strtolower($CFG->dbtype)) { + case 'mysql': + $ok = execute_sql("INSERT INTO `$table` ($fieldnames) SELECT $fieldnames FROM `$oldtable` WHERE 1"); + break; + case 'postgres7': + $ok = execute_sql("INSERT INTO $table ($fieldnames) SELECT $fieldnames FROM $oldtable"); + break; + default: + $ok = false; + break; + } + } + } else { // $table does not exist + $ok = hotpot_db_rename_table($oldtable, $table, $feedback); + } + } else { // $oldtable does not exist + $ok = hotpot_db_table_exists($table, $feedback); + } + return $ok; } function hotpot_db_set_table_comment($table, $comment, $feedback=true) { - global $CFG; - $ok = true; - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $ok = execute_sql("ALTER TABLE {$CFG->prefix}$table COMMENT='$comment'"); - break; - case 'postgres7' : - $ok = execute_sql("COMMENT ON TABLE {$CFG->prefix}$table IS '$comment'"); - break; - } - return $ok; + global $CFG; + $ok = true; + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $ok = execute_sql("ALTER TABLE {$CFG->prefix}$table COMMENT='$comment'"); + break; + case 'postgres7' : + $ok = execute_sql("COMMENT ON TABLE {$CFG->prefix}$table IS '$comment'"); + break; + } + return $ok; } function hotpot_db_remove_field($table, $field, $feedback=true) { - global $CFG; - if (hotpot_db_field_exists($table, $field)) { - $ok = execute_sql("ALTER TABLE {$CFG->prefix}$table DROP COLUMN $field", $feedback); - } else { - $ok = true; - } - return $ok; + global $CFG; + if (hotpot_db_field_exists($table, $field)) { + $ok = execute_sql("ALTER TABLE {$CFG->prefix}$table DROP COLUMN $field", $feedback); + } else { + $ok = true; + } + return $ok; } function hotpot_db_update_field_type($table, $oldfield, $field, $type, $size, $unsigned, $notnull, $default=NULL, $after=NULL) { - $ok = true; - global $CFG,$db; - // check validity of arguments, and adjust if necessary - if ($oldfield && !hotpot_db_field_exists($table, $oldfield)) { - $oldfield = ''; - } - if (empty($oldfield) && hotpot_db_field_exists($table, $field)) { - $oldfield = $field; - } - if (is_string($unsigned)) { - $unsigned = (strtoupper($unsigned)=='UNSIGNED'); - } - if (is_string($notnull)) { - $notnull = (strtoupper($notnull)=='NOT NULL'); - } - if (isset($default)) { - if (!is_numeric($default) && strtoupper($default)!='NULL' && !preg_match("|^'.*'$|", $default)) { - $default = "'$default'"; - } - } - // set full table name - $table = "{$CFG->prefix}$table"; - // update the field in the database - switch (strtolower($CFG->dbtype)) { - case 'mysql': - // optimize integer types - switch (strtoupper($type)) { - case 'TEXT': - $size = ''; - $unsigned = false; - break; - case 'INTEGER' : - if (!is_numeric($size)) { - $size = ''; - } else if ($size <= 4) { - $type = "TINYINT"; // 1 byte - } else if ($size <= 6) { - $type = "SMALLINT"; // 2 bytes - } else if ($size <= 8) { - $type = "MEDIUMINT"; // 3 bytes - } else if ($size <= 10) { - $type = "INTEGER"; // 4 bytes (=INT) - } else if ($size > 10) { - $type = "BIGINT"; // 8 bytes - } - break; - case 'VARCHAR': - $unsigned = false; - break; - } - // set action - if (empty($oldfield)) { - $action = "ADD"; - } else { - $action = "CHANGE `$oldfield`"; - } - // set fieldtype - $fieldtype = $type; - if ($size) { - $fieldtype .= "($size)"; - } - if ($unsigned) { - $fieldtype .= ' UNSIGNED'; - } - if ($notnull) { - $fieldtype .= ' NOT NULL'; - } - if (isset($default)) { - $fieldtype .= " DEFAULT $default"; - } - if (!empty($after)) { - $fieldtype .= " AFTER `$after`"; - } - $ok = $ok && execute_sql("ALTER TABLE `$table` $action `$field` $fieldtype"); - break; - case 'postgres7': - // get db version - $dbinfo = $db->ServerInfo(); - $dbversion = substr($dbinfo['version'],0,3); - // prevent conflicts with reserved words - $tmpfield = "\"temporary_{$field}_".time()."\""; - $oldfield = "\"$oldfield\""; - $field = "\"$field\""; - switch (strtoupper($type)) { - case "INTEGER": - if (!is_numeric($size)) { - $fieldtype = "INTEGER"; - } else if ($size <= 4) { - $fieldtype = "INT2"; // 2 bytes - } else if ($size <= 10) { - $fieldtype = "INT4"; // 4 bytes (=INTEGER) - } else if ($size > 10) { - $fieldtype = "INT8"; // 8 bytes - } - break; - case "VARCHAR": - $fieldtype = "VARCHAR($size)"; - break; - default: - $fieldtype = $type; - } - // start transaction - execute_sql("BEGIN"); - // create temporary field - execute_sql("ALTER TABLE $table ADD COLUMN $tmpfield $fieldtype"); - // set default - if (isset($default)) { - execute_sql("UPDATE $table SET $tmpfield = $default"); - execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield SET DEFAULT $default"); - } else { - execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield DROP DEFAULT"); - } - // set not null - if ($dbversion >= "7.3") { - $notnull = ($notnull ? "SET NOT NULL" : "DROP NOT NULL"); - execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield $notnull"); - } else { - execute_sql(" - UPDATE pg_attribute SET attnotnull=".($notnull ? 'TRUE' : 'FALSE')." - WHERE attname = $tmpfield - AND attrelid = (SELECT oid FROM pg_class WHERE relname = '$table') - "); - } - // transfer $oldfield values, if necessary - if ( $oldfield != '""' ) { - execute_sql("UPDATE $table SET $tmpfield = CAST ($oldfield AS $fieldtype)"); - execute_sql("ALTER TABLE $table DROP COLUMN $oldfield"); - } - // rename $tmpfield to $field - execute_sql("ALTER TABLE $table RENAME COLUMN $tmpfield TO $field"); - // do the transaction - execute_sql("COMMIT"); - // reclaim disk space (must be done outside transaction) - if ($oldfield != '""' && $dbversion >= "7.3") { - execute_sql("UPDATE $table SET $field = $field"); - execute_sql("VACUUM FULL $table"); - } - break; - } // end switch $CGF->dbtype - return $ok; + $ok = true; + global $CFG,$db; + // check validity of arguments, and adjust if necessary + if ($oldfield && !hotpot_db_field_exists($table, $oldfield)) { + $oldfield = ''; + } + if (empty($oldfield) && hotpot_db_field_exists($table, $field)) { + $oldfield = $field; + } + if (is_string($unsigned)) { + $unsigned = (strtoupper($unsigned)=='UNSIGNED'); + } + if (is_string($notnull)) { + $notnull = (strtoupper($notnull)=='NOT NULL'); + } + if (isset($default)) { + if (!is_numeric($default) && strtoupper($default)!='NULL' && !preg_match("|^'.*'$|", $default)) { + $default = "'$default'"; + } + } + // set full table name + $table = "{$CFG->prefix}$table"; + // update the field in the database + switch (strtolower($CFG->dbtype)) { + case 'mysql': + // optimize integer types + switch (strtoupper($type)) { + case 'TEXT': + $size = ''; + $unsigned = false; + break; + case 'INTEGER' : + if (!is_numeric($size)) { + $size = ''; + } else if ($size <= 4) { + $type = "TINYINT"; // 1 byte + } else if ($size <= 6) { + $type = "SMALLINT"; // 2 bytes + } else if ($size <= 8) { + $type = "MEDIUMINT"; // 3 bytes + } else if ($size <= 10) { + $type = "INTEGER"; // 4 bytes (=INT) + } else if ($size > 10) { + $type = "BIGINT"; // 8 bytes + } + break; + case 'VARCHAR': + $unsigned = false; + break; + } + // set action + if (empty($oldfield)) { + $action = "ADD"; + } else { + $action = "CHANGE `$oldfield`"; + } + // set fieldtype + $fieldtype = $type; + if ($size) { + $fieldtype .= "($size)"; + } + if ($unsigned) { + $fieldtype .= ' UNSIGNED'; + } + if ($notnull) { + $fieldtype .= ' NOT NULL'; + } + if (isset($default)) { + $fieldtype .= " DEFAULT $default"; + } + if (!empty($after)) { + $fieldtype .= " AFTER `$after`"; + } + $ok = $ok && execute_sql("ALTER TABLE `$table` $action `$field` $fieldtype"); + break; + case 'postgres7': + // get db version + $dbinfo = $db->ServerInfo(); + $dbversion = substr($dbinfo['version'],0,3); + // prevent conflicts with reserved words + $tmpfield = "\"temporary_{$field}_".time()."\""; + $oldfield = "\"$oldfield\""; + $field = "\"$field\""; + switch (strtoupper($type)) { + case "INTEGER": + if (!is_numeric($size)) { + $fieldtype = "INTEGER"; + } else if ($size <= 4) { + $fieldtype = "INT2"; // 2 bytes + } else if ($size <= 10) { + $fieldtype = "INT4"; // 4 bytes (=INTEGER) + } else if ($size > 10) { + $fieldtype = "INT8"; // 8 bytes + } + break; + case "VARCHAR": + $fieldtype = "VARCHAR($size)"; + break; + default: + $fieldtype = $type; + } + // start transaction + execute_sql("BEGIN"); + // create temporary field + execute_sql("ALTER TABLE $table ADD COLUMN $tmpfield $fieldtype"); + // set default + if (isset($default)) { + execute_sql("UPDATE $table SET $tmpfield = $default"); + execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield SET DEFAULT $default"); + } else { + execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield DROP DEFAULT"); + } + // set not null + if ($dbversion >= "7.3") { + $notnull = ($notnull ? "SET NOT NULL" : "DROP NOT NULL"); + execute_sql("ALTER TABLE $table ALTER COLUMN $tmpfield $notnull"); + } else { + execute_sql(" + UPDATE pg_attribute SET attnotnull=".($notnull ? 'TRUE' : 'FALSE')." + WHERE attname = $tmpfield + AND attrelid = (SELECT oid FROM pg_class WHERE relname = '$table') + "); + } + // transfer $oldfield values, if necessary + if ( $oldfield != '""' ) { + execute_sql("UPDATE $table SET $tmpfield = CAST ($oldfield AS $fieldtype)"); + execute_sql("ALTER TABLE $table DROP COLUMN $oldfield"); + } + // rename $tmpfield to $field + execute_sql("ALTER TABLE $table RENAME COLUMN $tmpfield TO $field"); + // do the transaction + execute_sql("COMMIT"); + // reclaim disk space (must be done outside transaction) + if ($oldfield != '""' && $dbversion >= "7.3") { + execute_sql("UPDATE $table SET $field = $field"); + execute_sql("VACUUM FULL $table"); + } + break; + } // end switch $CGF->dbtype + return $ok; } function hotpot_db_update_record($table, $record, $forcenull=false) { - global $CFG, $db; - $ok = true; - // set full table name - $table = "{$CFG->prefix}$table"; - // get field names - $fields = $db->MetaColumns($table); - if (empty($fields)) { - $ok = false; - } else { - // get values - $values = array(); - foreach ($fields as $field) { - $fieldname = $field->name; - if ($fieldname!='id' && ($forcenull || isset($record->$fieldname))) { - $value = isset($record->$fieldname) ? "'".$record->$fieldname."'" : 'NULL'; - $values[] = "$fieldname = $value"; - } - } - $values = implode(',', $values); - // update values (if there are any) - if ($values) { - $sql = "UPDATE $table SET $values WHERE id='$record->id'"; - $rs = $db->Execute($sql); - if (empty($rs)) { - $ok = false; - if (isset($CFG->debug) and $CFG->debug > 7) { - notify($db->ErrorMsg()."

    $sql"); - } - } - } - } - return $ok; + global $CFG, $db; + $ok = true; + // set full table name + $table = "{$CFG->prefix}$table"; + // get field names + $fields = $db->MetaColumns($table); + if (empty($fields)) { + $ok = false; + } else { + // get values + $values = array(); + foreach ($fields as $field) { + $fieldname = $field->name; + if ($fieldname!='id' && ($forcenull || isset($record->$fieldname))) { + $value = isset($record->$fieldname) ? "'".$record->$fieldname."'" : 'NULL'; + $values[] = "$fieldname = $value"; + } + } + $values = implode(',', $values); + // update values (if there are any) + if ($values) { + $sql = "UPDATE $table SET $values WHERE id='$record->id'"; + $rs = $db->Execute($sql); + if (empty($rs)) { + $ok = false; + if (isset($CFG->debug) and $CFG->debug > 7) { + notify($db->ErrorMsg()."

    $sql"); + } + } + } + } + return $ok; } function hotpot_rm($target, $output=true) { - $ok = true; - if (!empty($target)) { - if (is_file($target)) { - if ($output) { - print "removing file: $target ... "; - } - $ok = @unlink($target); - } else if (is_dir($target)) { - $dir = dir($target); - while(false !== ($entry = $dir->read())) { - if ($entry!='.' && $entry!='..') { - $ok = $ok && hotpot_rm($target.DIRECTORY_SEPARATOR.$entry, $output); - } - } - $dir->close(); - if ($output) { - print "removing folder: $target ... "; - } - $ok = $ok && @rmdir($target); - } else { // not a file or directory (probably doesn't exist) - $output = false; - } - if ($output) { - if ($ok) { - print 'OK
    '; - } else { - print 'Failed
    '; - } - } - } - return $ok; + $ok = true; + if (!empty($target)) { + if (is_file($target)) { + if ($output) { + print "removing file: $target ... "; + } + $ok = @unlink($target); + } else if (is_dir($target)) { + $dir = dir($target); + while(false !== ($entry = $dir->read())) { + if ($entry!='.' && $entry!='..') { + $ok = $ok && hotpot_rm($target.DIRECTORY_SEPARATOR.$entry, $output); + } + } + $dir->close(); + if ($output) { + print "removing folder: $target ... "; + } + $ok = $ok && @rmdir($target); + } else { // not a file or directory (probably doesn't exist) + $output = false; + } + if ($output) { + if ($ok) { + print 'OK
    '; + } else { + print 'Failed
    '; + } + } + } + return $ok; } function hotpot_flush($n=0, $time=false) { - if ($time) { - $t = strftime("%X",time()); - } else { - $t = ""; - } - echo str_repeat(" ", $n) . $t . "\n"; - flush(); + if ($time) { + $t = strftime("%X",time()); + } else { + $t = ""; + } + echo str_repeat(" ", $n) . $t . "\n"; + flush(); } ?> diff --git a/mod/hotpot/index.php b/mod/hotpot/index.php index 3aceb5e80e..e7226ac5a5 100644 --- a/mod/hotpot/index.php +++ b/mod/hotpot/index.php @@ -2,420 +2,420 @@ // This page lists all the instances of hotpot in a particular course - require_once("../../config.php"); - require_once("../../course/lib.php"); - require_once("lib.php"); - - $id = required_param("id"); // course - - if (! $course = get_record("course", "id", $id)) { - error("Course ID is incorrect"); - } - - require_login($course->id); - - add_to_log($course->id, "hotpot", "view all", "index.php?id=$course->id", ""); - - // Moodle 1.4+ requires sesskey to be passed in forms - if (isset($USER->sesskey)) { - $sesskey = ''; - } else { - $sesskey = ''; - } - - // get message strings for titles - $strmodulenameplural = get_string("modulenameplural", "hotpot"); - $strmodulename = get_string("modulename", "hotpot"); - - // string translation array for single and double quotes - $quotes = array("'"=>"\'", '"'=>'"'); - - // Print the header - - $title = "$course->shortname: $strmodulenameplural"; - $heading = "$course->fullname"; - $navigation = "$strmodulenameplural"; - if ($course->category) { - $navigation = "id\">$course->shortname -> $navigation"; - } - print_header($title, $heading, $navigation, "", "", true, "", navmenu($course)); - - $next_url = "$CFG->wwwroot/course/view.php?id=$course->id"; - - // get display section, if any - $section = optional_param('section', 0); - if ($section) { - $displaysection = course_set_display($course->id, $section); - } else { - if (isset($USER->display[$course->id])) { - $displaysection = $USER->display[$course->id]; - } else { - $displaysection = 0; - } - } - - // Get all instances of this module - if (!$hotpots = hotpot_get_all_instances_in_course("hotpot", $course)) { - $hotpots = array(); - } - - // if necessary, remove hotpots that are not in section0 or this $USER's display section - if ($displaysection) { - foreach ($hotpots as $coursemodule=>$hotpot) { - if ($hotpot->section!=0 && $hotpot->section!=$displaysection) { - unset($hotpots[$coursemodule]); - } - } - } - - if (empty($hotpots)) { - notice("There are no $strmodulenameplural", $next_url); - exit; - } - - // get list of hotpot ids - $hotpotids = array(); - foreach ($hotpots as $cmid=>$hotpot) { - $hotpotids[] = $hotpot->id; - } - $hotpotids = implode(',', $hotpotids); - - if (isadmin()) { - - // get regrade settings, if any - $regrade = optional_param("regrade"); - $confirm = optional_param("confirm"); - - // check regrade is valid - unset($regrade_cmid); - if (isset($regrade)) { - foreach ($hotpots as $cmid=>$hotpot) { - $found = false; - if ($hotpot->id==$regrade) { - $regrade_cmid = $cmid; - } - } - } - - // regrade, if necessary - if (isset($regrade_cmid)) { - - if (empty($confirm)) { - - $strregradecheck = get_string('regradecheck', 'hotpot', $hotpots[$regrade_cmid]->name); - - print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox"); - print_heading($strregradecheck); - print '' - . '
    ' - . '
    ' - . '' - . '' - . '' - . $sesskey - . '' - . '
    ' - . '
      ' - . '
    ' - . '' - . $sesskey - . '' - . '
    ' - . '
    ' - ; - print_simple_box_end(); - print_footer($course); - exit; - - } else { // regrade has been confirmed, so proceed - - if ($regrade=='all') { - $select = "hotpot IN ($hotpotids)"; - } else { - $select = "hotpot=$regrade"; - } - - $questionids = array(); - if ($questions = get_records_select("hotpot_questions", $select)) { - $questionids = array_keys($questions); - } - $questionids = implode(',', $questionids); - - if ($questionids) { - hotpot_delete_and_notify('hotpot_questions', "id IN ($questionids)", get_string('question', 'quiz')); - hotpot_delete_and_notify('hotpot_responses', "question IN ($questionids)", get_string('answer', 'quiz')); - } - - if ($attempts = get_records_select('hotpot_attempts', $select)) { - - // start counter and timer - $start = microtime(); - $count = 0; - - // use while loop instead of foreach loop - // to allow the possibility of splitting a regrade - // and so avoid "maximum script time exceeded" errors - $attemptids = array_keys($attempts); - $i_max = count($attemptids); - $i = 0; - while ($i<$i_max) { - - $attemptid = $attemptids[$i]; - $attempt =&$attempts[$attemptid]; - - $attempt->details = get_field('hotpot_details', 'details', 'attempt', $attemptid); - if ($attempt->details) { - - hotpot_add_attempt_details($attempt); - if (! update_record('hotpot_attempts', $attempt)) { - error("Could not update attempt record: ".$db->ErrorMsg(), $next_url); - } - } - $count++; - $i++; - } - if ($count) { - notify(get_string('added', 'moodle', "$count x ".get_string('attempts', 'quiz'))); - } - $msg = get_string('regradecomplete', 'quiz'); - if (!empty($CFG->hotpot_showtimes)) { - $duration = format_time(sprintf("%0.2f", microtime_diff($start, microtime()))); - $msg .= " ($duration)"; - } - notify($msg); - } - } - } // end regrade - - //print '
    '; - //print ''; - //print ''; - //print '
    '."\n"; - - - // get duplicate hotpot-name questions - // - JMatch LHS is longer than 255 bytes - // - JQuiz question text is longer than 255 bytes - // - other unidentified situations ?!? - - $field = ''; - $questions = false; - $regradehotpots = array(); - - switch (strtolower($CFG->dbtype)) { - case 'mysql' : - $field = "CONCAT(hotpot, '_', name)"; - break; - case 'postgres7' : - $field = "hotpot||'_'||name"; - break; - } - if ($field) { - $questions = get_records_sql(" - SELECT $field, COUNT(*), hotpot, name - FROM {$CFG->prefix}hotpot_questions - WHERE hotpot IN ($hotpotids) - GROUP BY hotpot, name - HAVING COUNT(*) >1 - "); - } - if ($questions) { - foreach ($questions as $question) { - $regradehotpots[] = $question->hotpot; - } - $regradehotpots = array_unique($regradehotpots); - sort($regradehotpots); - } - } - - // start timer - $start = microtime(); - - // get total number of attempts, users and details for these hotpots - $tables = "{$CFG->prefix}hotpot_attempts AS a"; - $fields = " - a.hotpot AS hotpot, - COUNT(DISTINCT a.clickreportid) AS attemptcount, - COUNT(DISTINCT a.userid) AS usercount, - MAX(a.score) AS maxscore - "; - $select = "a.hotpot IN ($hotpotids)"; - if (isteacher($course->id)) { - // do nothing (=get all users) - } else { - // restrict results to this user only - $select .= " AND a.userid='$USER->id'"; - } - $usejoin = 1; - if (isadmin() && $usejoin) { - // join attempts table and details table - $tables .= ",{$CFG->prefix}hotpot_details AS d"; - $fields .= ',COUNT(DISTINCT d.id) AS detailcount'; - $select .= " AND a.id=d.attempt"; - - // this may take about twice as long as getting the gradecounts separately :-( - // so this operation could be done after getting the $totals from the attempts table - } - $totals = get_records_sql("SELECT $fields FROM $tables WHERE $select GROUP BY a.hotpot"); - - if (isadmin() && empty($usejoin)) { - foreach ($hotpots as $hotpot) { - $totals[$hotpot->id]->detailcount = 0; - if ($ids = get_records('hotpot_attempts', 'hotpot', $hotpot->id)) { - $ids = join(',', array_keys($ids)); - $totals[$hotpot->id]->detailcount = count_records_select('hotpot_details', "attempt IN ($ids)"); - } - } - } - - // message strings for main table - $strusers = get_string('users'); - $strupdate = get_string('update'); - $strregrade = get_string('regrade', 'hotpot'); - $strneverclosed = get_string('neverclosed', 'hotpot'); - $strregraderequired = get_string('regraderequired', 'hotpot'); - - // column headings and attributes - $table->head = array(); - $table->align = array(); - - if (!empty($CFG->hotpot_showtimes)) { - print '

    '.sprintf("%0.3f", microtime_diff($start, microtime())).' secs'."

    \n"; - } - - switch ($course->format) { - case 'weeks' : - $title = get_string("week"); - break; - case 'topics' : - $title = get_string("topic"); - break; - default : - $title = ''; - break; - } - if ($title) { - array_push($table->head, $title); - array_push($table->align, "center"); - } - if (isteacheredit($course->id)) { - array_push($table->head, $strupdate); - array_push($table->align, "center"); - } - array_push($table->head, - get_string("name"), - get_string("quizcloses", "quiz"), - get_string("bestgrade", "quiz"), - get_string("attempts", "quiz") - ); - array_push($table->align, - "left", "left", "center", "left" - ); - if (isadmin()) { - array_push($table->head, $strregrade); - array_push($table->align, "center"); - } - - $currentsection = -1; - foreach ($hotpots as $hotpot) { - - $printsection = ""; - if ($hotpot->section != $currentsection) { - if ($hotpot->section) { - $printsection = $hotpot->section; - if ($course->format=='weeks' || $course->format=='topics') { - // Show the zoom boxes - if ($displaysection==$hotpot->section) { - $strshowall = get_string('showall'.$course->format); - $printsection .= '

    '; - } else { - $strshowone = get_string('showonly'.preg_replace('|s$|', '', $course->format, 1), '', $hotpot->section); - $printsection .= '

    '; - } - } - } - if ($currentsection>=0) { - $table->data[] = 'hr'; - } - $currentsection = $hotpot->section; - } - - $class = ($hotpot->visible) ? '' : 'class="dimmed" '; - $quizname = ''.$hotpot->name.''; - $quizclose = empty($hotpot->timeclose) ? $strneverclosed : userdate($hotpot->timeclose); - - // are there any totals for this hotpot? - if (empty($totals[$hotpot->id]->attemptcount)) { - $report = " "; - $bestscore = " "; - - } else { - // report number of attempts and users - $report = get_string("viewallreports","quiz", $totals[$hotpot->id]->attemptcount); - if (isteacher($course->id)) { - $report .= " (".$totals[$hotpot->id]->usercount." $strusers)"; - } - $report = ''.$report.''; - - // get best score - if (is_numeric($totals[$hotpot->id]->maxscore)) { - $bestscore = $totals[$hotpot->id]->maxscore." / $hotpot->grade"; - } else { - $bestscore = " "; - } - } - - if (isadmin()) { - if (in_array($hotpot->id, $regradehotpots)) { - $report .= ' '.$strregraderequired.''; - } - } - - $data = array (); - - if ($course->format=="weeks" || $course->format=="topics") { - array_push($data, $printsection); - } - - if (isteacheredit($course->id)) { - $updatebutton = '' - . '
    ' - . '' - . $sesskey - . '' - . '
    ' - ; - array_push($data, $updatebutton); - } - - array_push($data, $quizname, $quizclose, $bestscore, $report); - - if (isadmin()) { - if (empty($totals[$hotpot->id]->detailcount)) { - // no details records for this hotpot, so disable regrade - $regradebutton = ' '; - } else { - $strregradecheck = get_string('regradecheck', 'hotpot', strtr($hotpot->name, $quotes)); - $regradebutton = '' - . '
    ' - . '' - . '' - . '' - . $sesskey - . '' - . '
    ' - ; - } - array_push($data, $regradebutton); - } - - $table->data[] = $data; - } - - echo "
    "; - - print_table($table); - - // Finish the page - print_footer($course); + require_once("../../config.php"); + require_once("../../course/lib.php"); + require_once("lib.php"); + + $id = required_param("id"); // course + + if (! $course = get_record("course", "id", $id)) { + error("Course ID is incorrect"); + } + + require_login($course->id); + + add_to_log($course->id, "hotpot", "view all", "index.php?id=$course->id", ""); + + // Moodle 1.4+ requires sesskey to be passed in forms + if (isset($USER->sesskey)) { + $sesskey = ''; + } else { + $sesskey = ''; + } + + // get message strings for titles + $strmodulenameplural = get_string("modulenameplural", "hotpot"); + $strmodulename = get_string("modulename", "hotpot"); + + // string translation array for single and double quotes + $quotes = array("'"=>"\'", '"'=>'"'); + + // Print the header + + $title = "$course->shortname: $strmodulenameplural"; + $heading = "$course->fullname"; + $navigation = "$strmodulenameplural"; + if ($course->category) { + $navigation = "id\">$course->shortname -> $navigation"; + } + print_header($title, $heading, $navigation, "", "", true, "", navmenu($course)); + + $next_url = "$CFG->wwwroot/course/view.php?id=$course->id"; + + // get display section, if any + $section = optional_param('section', 0); + if ($section) { + $displaysection = course_set_display($course->id, $section); + } else { + if (isset($USER->display[$course->id])) { + $displaysection = $USER->display[$course->id]; + } else { + $displaysection = 0; + } + } + + // Get all instances of this module + if (!$hotpots = hotpot_get_all_instances_in_course("hotpot", $course)) { + $hotpots = array(); + } + + // if necessary, remove hotpots that are not in section0 or this $USER's display section + if ($displaysection) { + foreach ($hotpots as $coursemodule=>$hotpot) { + if ($hotpot->section!=0 && $hotpot->section!=$displaysection) { + unset($hotpots[$coursemodule]); + } + } + } + + if (empty($hotpots)) { + notice("There are no $strmodulenameplural", $next_url); + exit; + } + + // get list of hotpot ids + $hotpotids = array(); + foreach ($hotpots as $cmid=>$hotpot) { + $hotpotids[] = $hotpot->id; + } + $hotpotids = implode(',', $hotpotids); + + if (isadmin()) { + + // get regrade settings, if any + $regrade = optional_param("regrade"); + $confirm = optional_param("confirm"); + + // check regrade is valid + unset($regrade_cmid); + if (isset($regrade)) { + foreach ($hotpots as $cmid=>$hotpot) { + $found = false; + if ($hotpot->id==$regrade) { + $regrade_cmid = $cmid; + } + } + } + + // regrade, if necessary + if (isset($regrade_cmid)) { + + if (empty($confirm)) { + + $strregradecheck = get_string('regradecheck', 'hotpot', $hotpots[$regrade_cmid]->name); + + print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox"); + print_heading($strregradecheck); + print '' + . '
    ' + . '
    ' + . '' + . '' + . '' + . $sesskey + . '' + . '
    ' + . '
      ' + . '
    ' + . '' + . $sesskey + . '' + . '
    ' + . '
    ' + ; + print_simple_box_end(); + print_footer($course); + exit; + + } else { // regrade has been confirmed, so proceed + + if ($regrade=='all') { + $select = "hotpot IN ($hotpotids)"; + } else { + $select = "hotpot=$regrade"; + } + + $questionids = array(); + if ($questions = get_records_select("hotpot_questions", $select)) { + $questionids = array_keys($questions); + } + $questionids = implode(',', $questionids); + + if ($questionids) { + hotpot_delete_and_notify('hotpot_questions', "id IN ($questionids)", get_string('question', 'quiz')); + hotpot_delete_and_notify('hotpot_responses', "question IN ($questionids)", get_string('answer', 'quiz')); + } + + if ($attempts = get_records_select('hotpot_attempts', $select)) { + + // start counter and timer + $start = microtime(); + $count = 0; + + // use while loop instead of foreach loop + // to allow the possibility of splitting a regrade + // and so avoid "maximum script time exceeded" errors + $attemptids = array_keys($attempts); + $i_max = count($attemptids); + $i = 0; + while ($i<$i_max) { + + $attemptid = $attemptids[$i]; + $attempt =&$attempts[$attemptid]; + + $attempt->details = get_field('hotpot_details', 'details', 'attempt', $attemptid); + if ($attempt->details) { + + hotpot_add_attempt_details($attempt); + if (! update_record('hotpot_attempts', $attempt)) { + error("Could not update attempt record: ".$db->ErrorMsg(), $next_url); + } + } + $count++; + $i++; + } + if ($count) { + notify(get_string('added', 'moodle', "$count x ".get_string('attempts', 'quiz'))); + } + $msg = get_string('regradecomplete', 'quiz'); + if (!empty($CFG->hotpot_showtimes)) { + $duration = format_time(sprintf("%0.2f", microtime_diff($start, microtime()))); + $msg .= " ($duration)"; + } + notify($msg); + } + } + } // end regrade + + //print '
    '; + //print ''; + //print ''; + //print '
    '."\n"; + + + // get duplicate hotpot-name questions + // - JMatch LHS is longer than 255 bytes + // - JQuiz question text is longer than 255 bytes + // - other unidentified situations ?!? + + $field = ''; + $questions = false; + $regradehotpots = array(); + + switch (strtolower($CFG->dbtype)) { + case 'mysql' : + $field = "CONCAT(hotpot, '_', name)"; + break; + case 'postgres7' : + $field = "hotpot||'_'||name"; + break; + } + if ($field) { + $questions = get_records_sql(" + SELECT $field, COUNT(*), hotpot, name + FROM {$CFG->prefix}hotpot_questions + WHERE hotpot IN ($hotpotids) + GROUP BY hotpot, name + HAVING COUNT(*) >1 + "); + } + if ($questions) { + foreach ($questions as $question) { + $regradehotpots[] = $question->hotpot; + } + $regradehotpots = array_unique($regradehotpots); + sort($regradehotpots); + } + } + + // start timer + $start = microtime(); + + // get total number of attempts, users and details for these hotpots + $tables = "{$CFG->prefix}hotpot_attempts AS a"; + $fields = " + a.hotpot AS hotpot, + COUNT(DISTINCT a.clickreportid) AS attemptcount, + COUNT(DISTINCT a.userid) AS usercount, + MAX(a.score) AS maxscore + "; + $select = "a.hotpot IN ($hotpotids)"; + if (isteacher($course->id)) { + // do nothing (=get all users) + } else { + // restrict results to this user only + $select .= " AND a.userid='$USER->id'"; + } + $usejoin = 1; + if (isadmin() && $usejoin) { + // join attempts table and details table + $tables .= ",{$CFG->prefix}hotpot_details AS d"; + $fields .= ',COUNT(DISTINCT d.id) AS detailcount'; + $select .= " AND a.id=d.attempt"; + + // this may take about twice as long as getting the gradecounts separately :-( + // so this operation could be done after getting the $totals from the attempts table + } + $totals = get_records_sql("SELECT $fields FROM $tables WHERE $select GROUP BY a.hotpot"); + + if (isadmin() && empty($usejoin)) { + foreach ($hotpots as $hotpot) { + $totals[$hotpot->id]->detailcount = 0; + if ($ids = get_records('hotpot_attempts', 'hotpot', $hotpot->id)) { + $ids = join(',', array_keys($ids)); + $totals[$hotpot->id]->detailcount = count_records_select('hotpot_details', "attempt IN ($ids)"); + } + } + } + + // message strings for main table + $strusers = get_string('users'); + $strupdate = get_string('update'); + $strregrade = get_string('regrade', 'hotpot'); + $strneverclosed = get_string('neverclosed', 'hotpot'); + $strregraderequired = get_string('regraderequired', 'hotpot'); + + // column headings and attributes + $table->head = array(); + $table->align = array(); + + if (!empty($CFG->hotpot_showtimes)) { + print '

    '.sprintf("%0.3f", microtime_diff($start, microtime())).' secs'."

    \n"; + } + + switch ($course->format) { + case 'weeks' : + $title = get_string("week"); + break; + case 'topics' : + $title = get_string("topic"); + break; + default : + $title = ''; + break; + } + if ($title) { + array_push($table->head, $title); + array_push($table->align, "center"); + } + if (isteacheredit($course->id)) { + array_push($table->head, $strupdate); + array_push($table->align, "center"); + } + array_push($table->head, + get_string("name"), + get_string("quizcloses", "quiz"), + get_string("bestgrade", "quiz"), + get_string("attempts", "quiz") + ); + array_push($table->align, + "left", "left", "center", "left" + ); + if (isadmin()) { + array_push($table->head, $strregrade); + array_push($table->align, "center"); + } + + $currentsection = -1; + foreach ($hotpots as $hotpot) { + + $printsection = ""; + if ($hotpot->section != $currentsection) { + if ($hotpot->section) { + $printsection = $hotpot->section; + if ($course->format=='weeks' || $course->format=='topics') { + // Show the zoom boxes + if ($displaysection==$hotpot->section) { + $strshowall = get_string('showall'.$course->format); + $printsection .= '

    '; + } else { + $strshowone = get_string('showonly'.preg_replace('|s$|', '', $course->format, 1), '', $hotpot->section); + $printsection .= '

    '; + } + } + } + if ($currentsection>=0) { + $table->data[] = 'hr'; + } + $currentsection = $hotpot->section; + } + + $class = ($hotpot->visible) ? '' : 'class="dimmed" '; + $quizname = ''.$hotpot->name.''; + $quizclose = empty($hotpot->timeclose) ? $strneverclosed : userdate($hotpot->timeclose); + + // are there any totals for this hotpot? + if (empty($totals[$hotpot->id]->attemptcount)) { + $report = " "; + $bestscore = " "; + + } else { + // report number of attempts and users + $report = get_string("viewallreports","quiz", $totals[$hotpot->id]->attemptcount); + if (isteacher($course->id)) { + $report .= " (".$totals[$hotpot->id]->usercount." $strusers)"; + } + $report = ''.$report.''; + + // get best score + if (is_numeric($totals[$hotpot->id]->maxscore)) { + $bestscore = $totals[$hotpot->id]->maxscore." / $hotpot->grade"; + } else { + $bestscore = " "; + } + } + + if (isadmin()) { + if (in_array($hotpot->id, $regradehotpots)) { + $report .= ' '.$strregraderequired.''; + } + } + + $data = array (); + + if ($course->format=="weeks" || $course->format=="topics") { + array_push($data, $printsection); + } + + if (isteacheredit($course->id)) { + $updatebutton = '' + . '
    ' + . '' + . $sesskey + . '' + . '
    ' + ; + array_push($data, $updatebutton); + } + + array_push($data, $quizname, $quizclose, $bestscore, $report); + + if (isadmin()) { + if (empty($totals[$hotpot->id]->detailcount)) { + // no details records for this hotpot, so disable regrade + $regradebutton = ' '; + } else { + $strregradecheck = get_string('regradecheck', 'hotpot', strtr($hotpot->name, $quotes)); + $regradebutton = '' + . '
    ' + . '' + . '' + . '' + . $sesskey + . '' + . '
    ' + ; + } + array_push($data, $regradebutton); + } + + $table->data[] = $data; + } + + echo "
    "; + + print_table($table); + + // Finish the page + print_footer($course); ?> diff --git a/mod/hotpot/lib.php b/mod/hotpot/lib.php index a14ddc72d2..a7d2b4582b 100644 --- a/mod/hotpot/lib.php +++ b/mod/hotpot/lib.php @@ -4,10 +4,10 @@ /// CONFIGURATION settings if (!isset($CFG->hotpot_showtimes)) { - set_config("hotpot_showtimes", 0); + set_config("hotpot_showtimes", 0); } if (!isset($CFG->hotpot_excelencodings)) { - set_config("hotpot_excelencodings", ""); + set_config("hotpot_excelencodings", ""); } ////////////////////////////////// @@ -31,8 +31,8 @@ define("HOTPOT_LOCATION_COURSEFILES", "0"); define("HOTPOT_LOCATION_SITEFILES", "1"); $HOTPOT_LOCATION = array ( - HOTPOT_LOCATION_COURSEFILES => get_string("coursefiles"), - HOTPOT_LOCATION_SITEFILES => get_string("sitefiles"), + HOTPOT_LOCATION_COURSEFILES => get_string("coursefiles"), + HOTPOT_LOCATION_SITEFILES => get_string("sitefiles"), ); define("HOTPOT_OUTPUTFORMAT_BEST", "1"); @@ -46,34 +46,34 @@ define("HOTPOT_OUTPUTFORMAT_FLASH", "20"); define("HOTPOT_OUTPUTFORMAT_MOBILE", "30"); $HOTPOT_OUTPUTFORMAT = array ( - HOTPOT_OUTPUTFORMAT_BEST => get_string("outputformat_best", "hotpot"), - HOTPOT_OUTPUTFORMAT_V6_PLUS => get_string("outputformat_v6_plus", "hotpot"), - HOTPOT_OUTPUTFORMAT_V6 => get_string("outputformat_v6", "hotpot"), - HOTPOT_OUTPUTFORMAT_V5_PLUS => get_string("outputformat_v5_plus", "hotpot"), - HOTPOT_OUTPUTFORMAT_V5 => get_string("outputformat_v5", "hotpot"), - HOTPOT_OUTPUTFORMAT_V4 => get_string("outputformat_v4", "hotpot"), - HOTPOT_OUTPUTFORMAT_V3 => get_string("outputformat_v3", "hotpot"), - HOTPOT_OUTPUTFORMAT_FLASH => get_string("outputformat_flash", "hotpot"), - HOTPOT_OUTPUTFORMAT_MOBILE => get_string("outputformat_mobile", "hotpot"), + HOTPOT_OUTPUTFORMAT_BEST => get_string("outputformat_best", "hotpot"), + HOTPOT_OUTPUTFORMAT_V6_PLUS => get_string("outputformat_v6_plus", "hotpot"), + HOTPOT_OUTPUTFORMAT_V6 => get_string("outputformat_v6", "hotpot"), + HOTPOT_OUTPUTFORMAT_V5_PLUS => get_string("outputformat_v5_plus", "hotpot"), + HOTPOT_OUTPUTFORMAT_V5 => get_string("outputformat_v5", "hotpot"), + HOTPOT_OUTPUTFORMAT_V4 => get_string("outputformat_v4", "hotpot"), + HOTPOT_OUTPUTFORMAT_V3 => get_string("outputformat_v3", "hotpot"), + HOTPOT_OUTPUTFORMAT_FLASH => get_string("outputformat_flash", "hotpot"), + HOTPOT_OUTPUTFORMAT_MOBILE => get_string("outputformat_mobile", "hotpot"), ); $HOTPOT_OUTPUTFORMAT_DIR = array ( - HOTPOT_OUTPUTFORMAT_V6_PLUS => 'v6', - HOTPOT_OUTPUTFORMAT_V6 => 'v6', - HOTPOT_OUTPUTFORMAT_V5_PLUS => 'v5', - HOTPOT_OUTPUTFORMAT_V5 => 'v5', - HOTPOT_OUTPUTFORMAT_V4 => 'v4', - HOTPOT_OUTPUTFORMAT_V3 => 'v3', - HOTPOT_OUTPUTFORMAT_FLASH => 'flash', - HOTPOT_OUTPUTFORMAT_MOBILE => 'mobile', + HOTPOT_OUTPUTFORMAT_V6_PLUS => 'v6', + HOTPOT_OUTPUTFORMAT_V6 => 'v6', + HOTPOT_OUTPUTFORMAT_V5_PLUS => 'v5', + HOTPOT_OUTPUTFORMAT_V5 => 'v5', + HOTPOT_OUTPUTFORMAT_V4 => 'v4', + HOTPOT_OUTPUTFORMAT_V3 => 'v3', + HOTPOT_OUTPUTFORMAT_FLASH => 'flash', + HOTPOT_OUTPUTFORMAT_MOBILE => 'mobile', ); foreach ($HOTPOT_OUTPUTFORMAT_DIR as $format=>$dir) { - if (is_file("$CFG->hotpottemplate/$dir.php") && is_dir("$CFG->hotpottemplate/$dir")) { - // do nothing ($format is available) - } else { - // $format is not available, so remove it - unset($HOTPOT_OUTPUTFORMAT[$format]); - unset($HOTPOT_OUTPUTFORMAT_DIR[$format]); - } + if (is_file("$CFG->hotpottemplate/$dir.php") && is_dir("$CFG->hotpottemplate/$dir")) { + // do nothing ($format is available) + } else { + // $format is not available, so remove it + unset($HOTPOT_OUTPUTFORMAT[$format]); + unset($HOTPOT_OUTPUTFORMAT_DIR[$format]); + } } define("HOTPOT_NAVIGATION_BAR", "1"); define("HOTPOT_NAVIGATION_FRAME", "2"); @@ -83,12 +83,12 @@ define("HOTPOT_NAVIGATION_GIVEUP", "5"); define("HOTPOT_NAVIGATION_NONE", "6"); $HOTPOT_NAVIGATION = array ( - HOTPOT_NAVIGATION_BAR => get_string("navigation_bar", "hotpot"), - HOTPOT_NAVIGATION_FRAME => get_string("navigation_frame", "hotpot"), - HOTPOT_NAVIGATION_IFRAME => get_string("navigation_iframe", "hotpot"), - HOTPOT_NAVIGATION_BUTTONS => get_string("navigation_buttons", "hotpot"), - HOTPOT_NAVIGATION_GIVEUP => get_string("navigation_give_up", "hotpot"), - HOTPOT_NAVIGATION_NONE => get_string("navigation_none", "hotpot"), + HOTPOT_NAVIGATION_BAR => get_string("navigation_bar", "hotpot"), + HOTPOT_NAVIGATION_FRAME => get_string("navigation_frame", "hotpot"), + HOTPOT_NAVIGATION_IFRAME => get_string("navigation_iframe", "hotpot"), + HOTPOT_NAVIGATION_BUTTONS => get_string("navigation_buttons", "hotpot"), + HOTPOT_NAVIGATION_GIVEUP => get_string("navigation_give_up", "hotpot"), + HOTPOT_NAVIGATION_NONE => get_string("navigation_none", "hotpot"), ); define("HOTPOT_JCB", "1"); @@ -101,14 +101,14 @@ define("HOTPOT_TEXTOYS_RHUBARB", "7"); define("HOTPOT_TEXTOYS_SEQUITUR", "8"); $HOTPOT_QUIZTYPE = array( - HOTPOT_JCB => 'JCB', - HOTPOT_JCLOZE => 'JCloze', - HOTPOT_JCROSS => 'JCross', - HOTPOT_JMATCH => 'JMatch', - HOTPOT_JMIX => 'JMix', - HOTPOT_JQUIZ => 'JQuiz', - HOTPOT_TEXTOYS_RHUBARB => 'Rhubarb', - HOTPOT_TEXTOYS_SEQUITUR => 'Sequitur' + HOTPOT_JCB => 'JCB', + HOTPOT_JCLOZE => 'JCloze', + HOTPOT_JCROSS => 'JCross', + HOTPOT_JMATCH => 'JMatch', + HOTPOT_JMIX => 'JMix', + HOTPOT_JQUIZ => 'JQuiz', + HOTPOT_TEXTOYS_RHUBARB => 'Rhubarb', + HOTPOT_TEXTOYS_SEQUITUR => 'Sequitur' ); define("HOTPOT_JQUIZ_MULTICHOICE", "1"); @@ -122,10 +122,10 @@ define("HOTPOT_GRADEMETHOD_FIRST", "3"); define("HOTPOT_GRADEMETHOD_LAST", "4"); $HOTPOT_GRADEMETHOD = array ( - HOTPOT_GRADEMETHOD_HIGHEST => get_string("gradehighest", "quiz"), - HOTPOT_GRADEMETHOD_AVERAGE => get_string("gradeaverage", "quiz"), - HOTPOT_GRADEMETHOD_FIRST => get_string("attemptfirst", "quiz"), - HOTPOT_GRADEMETHOD_LAST => get_string("attemptlast", "quiz"), + HOTPOT_GRADEMETHOD_HIGHEST => get_string("gradehighest", "quiz"), + HOTPOT_GRADEMETHOD_AVERAGE => get_string("gradeaverage", "quiz"), + HOTPOT_GRADEMETHOD_FIRST => get_string("attemptfirst", "quiz"), + HOTPOT_GRADEMETHOD_LAST => get_string("attemptlast", "quiz"), ); define("HOTPOT_STATUS_INPROGRESS", "1"); @@ -134,10 +134,10 @@ define("HOTPOT_STATUS_ABANDONED", "3"); define("HOTPOT_STATUS_COMPLETED", "4"); $HOTPOT_STATUS = array ( - HOTPOT_STATUS_INPROGRESS => get_string("inprogress", "hotpot"), - HOTPOT_STATUS_TIMEDOUT => get_string("timedout", "hotpot"), - HOTPOT_STATUS_ABANDONED => get_string("abandoned", "hotpot"), - HOTPOT_STATUS_COMPLETED => get_string("completed", "hotpot"), + HOTPOT_STATUS_INPROGRESS => get_string("inprogress", "hotpot"), + HOTPOT_STATUS_TIMEDOUT => get_string("timedout", "hotpot"), + HOTPOT_STATUS_ABANDONED => get_string("abandoned", "hotpot"), + HOTPOT_STATUS_COMPLETED => get_string("completed", "hotpot"), ); define("HOTPOT_FEEDBACK_NONE", "0"); @@ -147,14 +147,14 @@ define("HOTPOT_FEEDBACK_MOODLEFORUM", "3"); define("HOTPOT_FEEDBACK_MOODLEMESSAGING", "4"); $HOTPOT_FEEDBACK = array ( - HOTPOT_FEEDBACK_NONE => get_string("feedbacknone", "hotpot"), - HOTPOT_FEEDBACK_WEBPAGE => get_string("feedbackwebpage", "hotpot"), - HOTPOT_FEEDBACK_FORMMAIL => get_string("feedbackformmail", "hotpot"), - HOTPOT_FEEDBACK_MOODLEFORUM => get_string("feedbackmoodleforum", "hotpot"), - HOTPOT_FEEDBACK_MOODLEMESSAGING => get_string("feedbackmoodlemessaging", "hotpot"), + HOTPOT_FEEDBACK_NONE => get_string("feedbacknone", "hotpot"), + HOTPOT_FEEDBACK_WEBPAGE => get_string("feedbackwebpage", "hotpot"), + HOTPOT_FEEDBACK_FORMMAIL => get_string("feedbackformmail", "hotpot"), + HOTPOT_FEEDBACK_MOODLEFORUM => get_string("feedbackmoodleforum", "hotpot"), + HOTPOT_FEEDBACK_MOODLEMESSAGING => get_string("feedbackmoodlemessaging", "hotpot"), ); if (empty($CFG->messaging)) { // Moodle 1.4 (and less) - unset($HOTPOT_FEEDBACK[HOTPOT_FEEDBACK_MOODLEMESSAGING]); + unset($HOTPOT_FEEDBACK[HOTPOT_FEEDBACK_MOODLEMESSAGING]); } define("HOTPOT_DISPLAYNEXT_QUIZ", "0"); @@ -175,662 +175,662 @@ define("HOTPOT_DISPLAYNEXT_INDEX", "2"); // $hp is an object containing the values of the form in mod.html // i.e. all the fields in the 'hotpot' table, plus the following: -// $hp->course : an id in the 'course' table -// $hp->coursemodule : an id in the 'course_modules' table -// $hp->section : an id in the 'course_sections' table -// $hp->module : an id in the 'modules' table -// $hp->modulename : always 'hotpot' -// $hp->instance : an id in the 'hotpot' table -// $hp->mode : 'add' or 'update' -// $hp->sesskey : unique string required for Moodle's session management +// $hp->course : an id in the 'course' table +// $hp->coursemodule : an id in the 'course_modules' table +// $hp->section : an id in the 'course_sections' table +// $hp->module : an id in the 'modules' table +// $hp->modulename : always 'hotpot' +// $hp->instance : an id in the 'hotpot' table +// $hp->mode : 'add' or 'update' +// $hp->sesskey : unique string required for Moodle's session management function hotpot_add_instance(&$hp) { - if (hotpot_set_form_values($hp)) { - $result = insert_record("hotpot", $hp); - } else { - $result= false; - } - return $result; + if (hotpot_set_form_values($hp)) { + $result = insert_record("hotpot", $hp); + } else { + $result= false; + } + return $result; } function hotpot_update_instance(&$hp) { - if (hotpot_set_form_values($hp)) { - $hp->id = $hp->instance; - $result = update_record("hotpot", $hp); - } else { - $result= false; - } - return $result; + if (hotpot_set_form_values($hp)) { + $hp->id = $hp->instance; + $result = update_record("hotpot", $hp); + } else { + $result= false; + } + return $result; } function hotpot_set_form_values(&$hp) { - $ok = true; - $hp->errors = array(); // these will be reported by moderr.html - - if (empty($hp->reference)) { - $ok = false; - $hp->errors['reference']= get_string('error_nofilename', 'hotpot'); - } - - if ($hp->studentfeedbackurl=='http://') { - $hp->studentfeedbackurl = ''; - } - - if (empty($hp->studentfeedbackurl)) { - switch ($hp->studentfeedback) { - case HOTPOT_FEEDBACK_WEBPAGE: - $ok = false; - $hp->errors['studentfeedbackurl']= get_string('error_nofeedbackurlwebpage', 'hotpot'); - break; - case HOTPOT_FEEDBACK_FORMMAIL: - $ok = false; - $hp->errors['studentfeedbackurl']= get_string('error_nofeedbackurlformmail', 'hotpot'); - break; - } - } - - $time = time(); - $hp->timecreated = $time; - $hp->timemodified = $time; - - if (empty($hp->enabletimeopen)) { - $hp->timeopen = 0; - } else { - $hp->timeopen = make_timestamp( - $hp->openyear, $hp->openmonth, $hp->openday, - $hp->openhour, $hp->openminute, 0 - ); - } - - if (empty($hp->enabletimeclose)) { - $hp->timeclose = 0; - } else { - $hp->timeclose = make_timestamp( - $hp->closeyear, $hp->closemonth, $hp->closeday, - $hp->closehour, $hp->closeminute, 0 - ); - } - - if ($hp->quizchain==HOTPOT_YES) { - switch ($hp->mode) { - case 'add': - $ok = hotpot_add_chain($hp); - break; - case 'update': - $ok = hotpot_update_chain($hp); - break; - } - } else { // $hp->quizchain==HOTPOT_NO - hotpot_set_name_summary_reference($hp); - } - - switch ($hp->displaynext) { - // N.B. redirection only works for Moodle 1.5+ - case HOTPOT_DISPLAYNEXT_COURSE: - $hp->redirect = true; - $hp->redirecturl = "view.php?id=$hp->course"; - break; - case HOTPOT_DISPLAYNEXT_INDEX: - $hp->redirect = true; - $hp->redirecturl = "../mod/hotpot/index.php?id=$hp->course"; - break; - default: - // use Moodle default action (i.e. go on to display the hotpot quiz) - } - - // if ($ok && $hp->setdefaults) { - if ($ok) { - set_user_preference('hotpot_timeopen', $hp->timeopen); - set_user_preference('hotpot_timeclose', $hp->timeclose); - set_user_preference('hotpot_navigation', $hp->navigation); - set_user_preference('hotpot_outputformat', $hp->outputformat); - set_user_preference('hotpot_studentfeedback', $hp->studentfeedback); - set_user_preference('hotpot_studentfeedbackurl', $hp->studentfeedbackurl); - set_user_preference('hotpot_forceplugins', $hp->forceplugins); - set_user_preference('hotpot_shownextquiz', $hp->shownextquiz); - set_user_preference('hotpot_review', $hp->review); - set_user_preference('hotpot_grade', $hp->grade); - set_user_preference('hotpot_grademethod', $hp->grademethod); - set_user_preference('hotpot_attempts', $hp->attempts); - set_user_preference('hotpot_subnet', $hp->subnet); - set_user_preference('hotpot_displaynext', $hp->displaynext); - if ($hp->mode=='add') { - set_user_preference('hotpot_quizchain', $hp->quizchain); - set_user_preference('hotpot_namesource', $hp->namesource); - set_user_preference('hotpot_summarysource', $hp->summarysource); - } - } - return $ok; + $ok = true; + $hp->errors = array(); // these will be reported by moderr.html + + if (empty($hp->reference)) { + $ok = false; + $hp->errors['reference']= get_string('error_nofilename', 'hotpot'); + } + + if ($hp->studentfeedbackurl=='http://') { + $hp->studentfeedbackurl = ''; + } + + if (empty($hp->studentfeedbackurl)) { + switch ($hp->studentfeedback) { + case HOTPOT_FEEDBACK_WEBPAGE: + $ok = false; + $hp->errors['studentfeedbackurl']= get_string('error_nofeedbackurlwebpage', 'hotpot'); + break; + case HOTPOT_FEEDBACK_FORMMAIL: + $ok = false; + $hp->errors['studentfeedbackurl']= get_string('error_nofeedbackurlformmail', 'hotpot'); + break; + } + } + + $time = time(); + $hp->timecreated = $time; + $hp->timemodified = $time; + + if (empty($hp->enabletimeopen)) { + $hp->timeopen = 0; + } else { + $hp->timeopen = make_timestamp( + $hp->openyear, $hp->openmonth, $hp->openday, + $hp->openhour, $hp->openminute, 0 + ); + } + + if (empty($hp->enabletimeclose)) { + $hp->timeclose = 0; + } else { + $hp->timeclose = make_timestamp( + $hp->closeyear, $hp->closemonth, $hp->closeday, + $hp->closehour, $hp->closeminute, 0 + ); + } + + if ($hp->quizchain==HOTPOT_YES) { + switch ($hp->mode) { + case 'add': + $ok = hotpot_add_chain($hp); + break; + case 'update': + $ok = hotpot_update_chain($hp); + break; + } + } else { // $hp->quizchain==HOTPOT_NO + hotpot_set_name_summary_reference($hp); + } + + switch ($hp->displaynext) { + // N.B. redirection only works for Moodle 1.5+ + case HOTPOT_DISPLAYNEXT_COURSE: + $hp->redirect = true; + $hp->redirecturl = "view.php?id=$hp->course"; + break; + case HOTPOT_DISPLAYNEXT_INDEX: + $hp->redirect = true; + $hp->redirecturl = "../mod/hotpot/index.php?id=$hp->course"; + break; + default: + // use Moodle default action (i.e. go on to display the hotpot quiz) + } + + // if ($ok && $hp->setdefaults) { + if ($ok) { + set_user_preference('hotpot_timeopen', $hp->timeopen); + set_user_preference('hotpot_timeclose', $hp->timeclose); + set_user_preference('hotpot_navigation', $hp->navigation); + set_user_preference('hotpot_outputformat', $hp->outputformat); + set_user_preference('hotpot_studentfeedback', $hp->studentfeedback); + set_user_preference('hotpot_studentfeedbackurl', $hp->studentfeedbackurl); + set_user_preference('hotpot_forceplugins', $hp->forceplugins); + set_user_preference('hotpot_shownextquiz', $hp->shownextquiz); + set_user_preference('hotpot_review', $hp->review); + set_user_preference('hotpot_grade', $hp->grade); + set_user_preference('hotpot_grademethod', $hp->grademethod); + set_user_preference('hotpot_attempts', $hp->attempts); + set_user_preference('hotpot_subnet', $hp->subnet); + set_user_preference('hotpot_displaynext', $hp->displaynext); + if ($hp->mode=='add') { + set_user_preference('hotpot_quizchain', $hp->quizchain); + set_user_preference('hotpot_namesource', $hp->namesource); + set_user_preference('hotpot_summarysource', $hp->summarysource); + } + } + return $ok; } function hotpot_get_chain(&$cm) { - // get details of course_modules in this section - $course_module_ids = get_field('course_sections', 'sequence', 'id', $cm->section); - if (empty($course_module_ids)) { - $hotpot_modules = array(); - } else { - $hotpot_modules = get_records_select('course_modules', "id IN ($course_module_ids) AND module=$cm->module"); - if (empty($hotpot_modules)) { - $hotpot_modules = array(); - } - } - - // get ids of hotpot modules in this section - $ids = array(); - foreach ($hotpot_modules as $hotpot_module) { - $ids[] = $hotpot_module->instance; - } - - // get details of hotpots in this section - if (empty($ids)) { - $hotpots = array(); - } else { - $hotpots = get_records_list('hotpot', 'id', implode(',', $ids)); - } - - $found = false; - $chain = array(); - - // loop through course_modules in this section - $ids = explode(',', $course_module_ids); - foreach ($ids as $id) { - - // check this course_module is a hotpot activity - if (isset($hotpot_modules[$id])) { - - // store details of this course module and hotpot activity - $hotpot_id = $hotpot_modules[$id]->instance; - $chain[$id] = &$hotpot_modules[$id]; - $chain[$id]->hotpot = &$hotpots[$hotpot_id]; - - // set $found, if this is the course module we're looking for - if (isset($cm->coursemodule)) { - if ($id==$cm->coursemodule) { - $found = true; - } - } else { - if ($id==$cm->id) { - $found = true; - } - } - - // is this the end of a chain - if (empty($hotpots[$hotpot_id]->shownextquiz)) { - if ($found) { - break; // out of loop - } else { - // restart chain (target cm has not been found yet) - $chain = array(); - } - } - } - } // end foreach $ids - - return $found ? $chain : false; + // get details of course_modules in this section + $course_module_ids = get_field('course_sections', 'sequence', 'id', $cm->section); + if (empty($course_module_ids)) { + $hotpot_modules = array(); + } else { + $hotpot_modules = get_records_select('course_modules', "id IN ($course_module_ids) AND module=$cm->module"); + if (empty($hotpot_modules)) { + $hotpot_modules = array(); + } + } + + // get ids of hotpot modules in this section + $ids = array(); + foreach ($hotpot_modules as $hotpot_module) { + $ids[] = $hotpot_module->instance; + } + + // get details of hotpots in this section + if (empty($ids)) { + $hotpots = array(); + } else { + $hotpots = get_records_list('hotpot', 'id', implode(',', $ids)); + } + + $found = false; + $chain = array(); + + // loop through course_modules in this section + $ids = explode(',', $course_module_ids); + foreach ($ids as $id) { + + // check this course_module is a hotpot activity + if (isset($hotpot_modules[$id])) { + + // store details of this course module and hotpot activity + $hotpot_id = $hotpot_modules[$id]->instance; + $chain[$id] = &$hotpot_modules[$id]; + $chain[$id]->hotpot = &$hotpots[$hotpot_id]; + + // set $found, if this is the course module we're looking for + if (isset($cm->coursemodule)) { + if ($id==$cm->coursemodule) { + $found = true; + } + } else { + if ($id==$cm->id) { + $found = true; + } + } + + // is this the end of a chain + if (empty($hotpots[$hotpot_id]->shownextquiz)) { + if ($found) { + break; // out of loop + } else { + // restart chain (target cm has not been found yet) + $chain = array(); + } + } + } + } // end foreach $ids + + return $found ? $chain : false; } function hotpot_is_visible(&$cm) { - if (!isset($cm->sectionvisible)) { - if ($section = get_record('course_sections', 'id', $cm->section)) { - $cm->sectionvisible = $section->visible; - } else { - error('Course module record contains invalid section'); - } - } - - if (empty($cm->sectionvisible)) { - $visible = HOTPOT_NO; - } else { - $visible = HOTPOT_YES; - if (empty($cm->visible)) { - if ($chain = hotpot_get_chain($cm)) { - $startofchain = array_shift($chain); - $visible = $startofchain->visible; - } - } - } - return $visible; + if (!isset($cm->sectionvisible)) { + if ($section = get_record('course_sections', 'id', $cm->section)) { + $cm->sectionvisible = $section->visible; + } else { + error('Course module record contains invalid section'); + } + } + + if (empty($cm->sectionvisible)) { + $visible = HOTPOT_NO; + } else { + $visible = HOTPOT_YES; + if (empty($cm->visible)) { + if ($chain = hotpot_get_chain($cm)) { + $startofchain = array_shift($chain); + $visible = $startofchain->visible; + } + } + } + return $visible; } function hotpot_add_chain(&$hp) { /// add a chain of hotpot actiivities - global $CFG, $course; - - $ok = true; - $hp->names = array(); - $hp->summaries = array(); - $hp->references = array(); - - $xml_quiz = new hotpot_xml_quiz($hp, false, false, false, false, false); - - if (isset($xml_quiz->error)) { - $hp->errors['reference'] = $xml_quiz->error; - $ok = false; - - } else if (is_dir($xml_quiz->filepath)) { - - // get list of hotpot files in this folder - if ($dh = @opendir($xml_quiz->filepath)) { - while ($file = @readdir($dh)) { - if (preg_match('/\.(jbc|jcl|jcw|jmt|jmx|jqz|htm|html)$/', $file)) { - $hp->references[] = "$xml_quiz->reference/$file"; - } - } - closedir($dh); - - // get titles - foreach ($hp->references as $i=>$reference) { - $filepath = $xml_quiz->fileroot.'/'.$reference; - hotpot_get_titles_and_next_ex($hp, $filepath); - $hp->names[$i] = $hp->exercisetitle; - $hp->summaries[$i] = $hp->exercisesubtitle; - } - - } else { - $ok = false; - $hp->errors['reference'] = get_string('error_couldnotopenfolder', 'hotpot', $hp->reference); - } - - } else if (is_file($xml_quiz->filepath)) { - - $filerootlength = strlen($xml_quiz->fileroot) + 1; - - while ($xml_quiz->filepath) { - hotpot_get_titles_and_next_ex($hp, $xml_quiz->filepath, true); - $hp->names[] = $hp->exercisetitle; - $hp->summaries[] = $hp->exercisesubtitle; - $hp->references[] = substr($xml_quiz->filepath, $filerootlength); - - if ($hp->nextexercise) { - $filepath = $xml_quiz->fileroot.'/'.$xml_quiz->filesubdir.$hp->nextexercise; - - // check file is not already in chain - $reference = substr($filepath, $filerootlength); - if (in_array($reference, $hp->references)) { - $filepath = ''; - } - } else { - $filepath = ''; - } - if ($filepath && file_exists($filepath) && is_file($filepath) && is_readable($filepath)) { - $xml_quiz->filepath = $filepath; - } else { - $xml_quiz->filepath = false; // finish while loop - } - } // end while - - } else { - $ok = false; - $hp->errors['reference'] = get_string('error_notfileorfolder', 'hotpot', $hp->reference); - } - - if (empty($hp->references) && empty($hp->errors['reference'])) { - $ok = false; - $hp->errors['reference'] = get_string('error_noquizzesfound', 'hotpot', $hp->reference); - } - - if ($ok) { - $hp->visible = HOTPOT_YES; - - if (trim($hp->name)=='') { - $hp->name = get_string("modulename", $hp->modulename); - } - $hp->specificname = $hp->name; - $hp->specificsummary = $hp->summary; - - // add all except last activity in chain - - $i_max = count($hp->references)-1; - for ($i=0; $i<$i_max; $i++) { - - hotpot_set_name_summary_reference($hp, $i); - $hp->reference = addslashes($hp->reference); - - if (!$hp->instance = insert_record("hotpot", $hp)) { - error("Could not add a new instance of $hp->modulename", "view.php?id=$hp->course"); - } - - // store (hotpot table) id of start of chain - if ($i==0) { - $hp->startofchain = $hp->instance; - } - - if (isset($course->groupmode)) { - $hp->groupmode = $course->groupmode; - } - - if (! $hp->coursemodule = add_course_module($hp)) { - error("Could not add a new course module"); - } - if (! $sectionid = add_mod_to_section($hp) ) { - error("Could not add the new course module to that section"); - } - - if (! set_field("course_modules", "section", $sectionid, "id", $hp->coursemodule)) { - error("Could not update the course module with the correct section"); - } - - add_to_log($hp->course, "course", "add mod", - "../mod/$hp->modulename/view.php?id=$hp->coursemodule", - "$hp->modulename $hp->instance" - ); - add_to_log($hp->course, $hp->modulename, "add", - "view.php?id=$hp->coursemodule", - "$hp->instance", $hp->coursemodule - ); - - // hide tail of chain - if ($hp->shownextquiz==HOTPOT_YES) { - $hp->visible = HOTPOT_NO; - } - } // end for ($hp->references) - - // settings for final activity in chain - hotpot_set_name_summary_reference($hp, $i); - $hp->reference = addslashes($hp->references[$i]); - $hp->shownextquiz = HOTPOT_NO; - - if (isset($hp->startofchain)) { - // redirection only works for Moodle 1.5+ - $hp->redirect = true; - $hp->redirecturl = "$CFG->wwwroot/mod/hotpot/view.php?hp=$hp->startofchain"; - } - } // end if $ok - - return $ok; + global $CFG, $course; + + $ok = true; + $hp->names = array(); + $hp->summaries = array(); + $hp->references = array(); + + $xml_quiz = new hotpot_xml_quiz($hp, false, false, false, false, false); + + if (isset($xml_quiz->error)) { + $hp->errors['reference'] = $xml_quiz->error; + $ok = false; + + } else if (is_dir($xml_quiz->filepath)) { + + // get list of hotpot files in this folder + if ($dh = @opendir($xml_quiz->filepath)) { + while ($file = @readdir($dh)) { + if (preg_match('/\.(jbc|jcl|jcw|jmt|jmx|jqz|htm|html)$/', $file)) { + $hp->references[] = "$xml_quiz->reference/$file"; + } + } + closedir($dh); + + // get titles + foreach ($hp->references as $i=>$reference) { + $filepath = $xml_quiz->fileroot.'/'.$reference; + hotpot_get_titles_and_next_ex($hp, $filepath); + $hp->names[$i] = $hp->exercisetitle; + $hp->summaries[$i] = $hp->exercisesubtitle; + } + + } else { + $ok = false; + $hp->errors['reference'] = get_string('error_couldnotopenfolder', 'hotpot', $hp->reference); + } + + } else if (is_file($xml_quiz->filepath)) { + + $filerootlength = strlen($xml_quiz->fileroot) + 1; + + while ($xml_quiz->filepath) { + hotpot_get_titles_and_next_ex($hp, $xml_quiz->filepath, true); + $hp->names[] = $hp->exercisetitle; + $hp->summaries[] = $hp->exercisesubtitle; + $hp->references[] = substr($xml_quiz->filepath, $filerootlength); + + if ($hp->nextexercise) { + $filepath = $xml_quiz->fileroot.'/'.$xml_quiz->filesubdir.$hp->nextexercise; + + // check file is not already in chain + $reference = substr($filepath, $filerootlength); + if (in_array($reference, $hp->references)) { + $filepath = ''; + } + } else { + $filepath = ''; + } + if ($filepath && file_exists($filepath) && is_file($filepath) && is_readable($filepath)) { + $xml_quiz->filepath = $filepath; + } else { + $xml_quiz->filepath = false; // finish while loop + } + } // end while + + } else { + $ok = false; + $hp->errors['reference'] = get_string('error_notfileorfolder', 'hotpot', $hp->reference); + } + + if (empty($hp->references) && empty($hp->errors['reference'])) { + $ok = false; + $hp->errors['reference'] = get_string('error_noquizzesfound', 'hotpot', $hp->reference); + } + + if ($ok) { + $hp->visible = HOTPOT_YES; + + if (trim($hp->name)=='') { + $hp->name = get_string("modulename", $hp->modulename); + } + $hp->specificname = $hp->name; + $hp->specificsummary = $hp->summary; + + // add all except last activity in chain + + $i_max = count($hp->references)-1; + for ($i=0; $i<$i_max; $i++) { + + hotpot_set_name_summary_reference($hp, $i); + $hp->reference = addslashes($hp->reference); + + if (!$hp->instance = insert_record("hotpot", $hp)) { + error("Could not add a new instance of $hp->modulename", "view.php?id=$hp->course"); + } + + // store (hotpot table) id of start of chain + if ($i==0) { + $hp->startofchain = $hp->instance; + } + + if (isset($course->groupmode)) { + $hp->groupmode = $course->groupmode; + } + + if (! $hp->coursemodule = add_course_module($hp)) { + error("Could not add a new course module"); + } + if (! $sectionid = add_mod_to_section($hp) ) { + error("Could not add the new course module to that section"); + } + + if (! set_field("course_modules", "section", $sectionid, "id", $hp->coursemodule)) { + error("Could not update the course module with the correct section"); + } + + add_to_log($hp->course, "course", "add mod", + "../mod/$hp->modulename/view.php?id=$hp->coursemodule", + "$hp->modulename $hp->instance" + ); + add_to_log($hp->course, $hp->modulename, "add", + "view.php?id=$hp->coursemodule", + "$hp->instance", $hp->coursemodule + ); + + // hide tail of chain + if ($hp->shownextquiz==HOTPOT_YES) { + $hp->visible = HOTPOT_NO; + } + } // end for ($hp->references) + + // settings for final activity in chain + hotpot_set_name_summary_reference($hp, $i); + $hp->reference = addslashes($hp->references[$i]); + $hp->shownextquiz = HOTPOT_NO; + + if (isset($hp->startofchain)) { + // redirection only works for Moodle 1.5+ + $hp->redirect = true; + $hp->redirecturl = "$CFG->wwwroot/mod/hotpot/view.php?hp=$hp->startofchain"; + } + } // end if $ok + + return $ok; } function hotpot_set_name_summary_reference(&$hp, $chain_index=NULL) { - $xml_quiz = NULL; - - $textfields = array('name', 'summary'); - foreach ($textfields as $textfield) { - - $textsource = $textfield.'source'; - - // are we adding a chain? - if (isset($chain_index)) { - - switch ($hp->$textsource) { - case HOTPOT_TEXTSOURCE_QUIZ: - if ($textfield=='name') { - $hp->exercisetitle = $hp->names[$chain_index]; - } else if ($textfield=='summary') { - $hp->exercisesubtitle = $hp->summaries[$chain_index]; - } - break; - case HOTPOT_TEXTSOURCE_SPECIFIC: - $specifictext = 'specific'.$textfield; - if (empty($hp->$specifictext) && trim($hp->$specifictext)=='') { - $hp->$textfield = ''; - } else { - $hp->$textfield = $hp->$specifictext.' ('.($chain_index+1).')'; - } - break; - } - $hp->reference = $hp->references[$chain_index]; - } - - if ($hp->$textsource==HOTPOT_TEXTSOURCE_QUIZ) { - if (empty($xml_quiz) && !isset($chain_index)) { - $xml_quiz = new hotpot_xml_quiz($hp, false, false, false, false, false); - hotpot_get_titles_and_next_ex($hp, $xml_quiz->filepath); - } - if ($textfield=='name') { - $hp->$textfield = addslashes($hp->exercisetitle); - } else if ($textfield=='summary') { - $hp->$textfield = addslashes($hp->exercisesubtitle); - } - } - switch ($hp->$textsource) { - case HOTPOT_TEXTSOURCE_FILENAME: - $hp->$textfield = basename($hp->reference); - break; - case HOTPOT_TEXTSOURCE_FILEPATH: - $hp->$textfield = ''; - // continue to next lines - default: - if (empty($hp->$textfield)) { - $hp->$textfield = str_replace('/', ' ', $hp->reference); - } - } // end switch - } // end foreach + $xml_quiz = NULL; + + $textfields = array('name', 'summary'); + foreach ($textfields as $textfield) { + + $textsource = $textfield.'source'; + + // are we adding a chain? + if (isset($chain_index)) { + + switch ($hp->$textsource) { + case HOTPOT_TEXTSOURCE_QUIZ: + if ($textfield=='name') { + $hp->exercisetitle = $hp->names[$chain_index]; + } else if ($textfield=='summary') { + $hp->exercisesubtitle = $hp->summaries[$chain_index]; + } + break; + case HOTPOT_TEXTSOURCE_SPECIFIC: + $specifictext = 'specific'.$textfield; + if (empty($hp->$specifictext) && trim($hp->$specifictext)=='') { + $hp->$textfield = ''; + } else { + $hp->$textfield = $hp->$specifictext.' ('.($chain_index+1).')'; + } + break; + } + $hp->reference = $hp->references[$chain_index]; + } + + if ($hp->$textsource==HOTPOT_TEXTSOURCE_QUIZ) { + if (empty($xml_quiz) && !isset($chain_index)) { + $xml_quiz = new hotpot_xml_quiz($hp, false, false, false, false, false); + hotpot_get_titles_and_next_ex($hp, $xml_quiz->filepath); + } + if ($textfield=='name') { + $hp->$textfield = addslashes($hp->exercisetitle); + } else if ($textfield=='summary') { + $hp->$textfield = addslashes($hp->exercisesubtitle); + } + } + switch ($hp->$textsource) { + case HOTPOT_TEXTSOURCE_FILENAME: + $hp->$textfield = basename($hp->reference); + break; + case HOTPOT_TEXTSOURCE_FILEPATH: + $hp->$textfield = ''; + // continue to next lines + default: + if (empty($hp->$textfield)) { + $hp->$textfield = str_replace('/', ' ', $hp->reference); + } + } // end switch + } // end foreach } function hotpot_get_titles_and_next_ex(&$hp, $filepath, $get_next=false) { - $hp->exercisetitle = ''; - $hp->exercisesubtitle = ''; - $hp->nextexercise = ''; - - // read the quiz file source - if ($source = file_get_contents($filepath)) { - - $next = ''; - $title = ''; - $subtitle = ''; - - if (preg_match('|\.html?$|', $filepath)) { - // html file - if (preg_match('|]*class="ExerciseTitle"[^>]*>(.*?)|is', $source, $matches)) { - $title = trim(strip_tags($matches[1])); - } - if (empty($title)) { - if (preg_match('|]*>(.*?)|is', $source, $matches)) { - $title = trim(strip_tags($matches[1])); - } - } - if (preg_match('|]*class="ExerciseSubtitle"[^>]*>(.*?)|is', $source, $matches)) { - $subtitle = trim(strip_tags($matches[1])); - } - if ($get_next) { - if (preg_match('|]*class="NavButtonBar"[^>]*>(.*?)|is', $source, $matches)) { - $navbuttonbar = $matches[1]; - if (preg_match_all('|]*class="NavButton"[^>]*onclick="'."location='([^']*)'".'[^"]*"[^>]*>|is', $navbuttonbar, $matches)) { - $lastbutton = count($matches[0])-1; - $next = $matches[1][$lastbutton]; - } - } - } - - } else { - // xml file (...maybe) - $xml_tree = new hotpot_xml_tree($source); - $xml_tree->filetype = ''; - - $keys = array_keys($xml_tree->xml); - foreach ($keys as $key) { - if (preg_match('/^(hotpot|textoys)-(\w+)-file$/i', $key, $matches)) { - $xml_tree->filetype = 'xml'; - $xml_tree->xml_root = "['$key']['#']"; - $xml_tree->quiztype = strtolower($matches[2]); - break; - } - } - if ($xml_tree->filetype=='xml') { - - $title = strip_tags($xml_tree->xml_value('data,title')); - $subtitle = $xml_tree->xml_value('hotpot-config-file,'.$xml_tree->quiztype.',exercise-subtitle'); - - if ($get_next) { - $include = $xml_tree->xml_value('hotpot-config-file,global,include-next-ex'); - if (!empty($include)) { - $next = $xml_tree->xml_value("hotpot-config-file,$xml_tree->quiztype,next-ex-url"); - if (is_array($next)) { - $next = $next[0]; // in case "next-ex-url" was repeated in the xml file - } - } - } - } - } - - $hp->nextexercise = $next; - $hp->exercisetitle = (empty($title) || is_array($title)) ? basename($filepath) : $title; - $hp->exercisesubtitle = (empty($subtitle) || is_array($subtitle)) ? $hp->exercisetitle : $subtitle; - } + $hp->exercisetitle = ''; + $hp->exercisesubtitle = ''; + $hp->nextexercise = ''; + + // read the quiz file source + if ($source = file_get_contents($filepath)) { + + $next = ''; + $title = ''; + $subtitle = ''; + + if (preg_match('|\.html?$|', $filepath)) { + // html file + if (preg_match('|]*class="ExerciseTitle"[^>]*>(.*?)|is', $source, $matches)) { + $title = trim(strip_tags($matches[1])); + } + if (empty($title)) { + if (preg_match('|]*>(.*?)|is', $source, $matches)) { + $title = trim(strip_tags($matches[1])); + } + } + if (preg_match('|]*class="ExerciseSubtitle"[^>]*>(.*?)|is', $source, $matches)) { + $subtitle = trim(strip_tags($matches[1])); + } + if ($get_next) { + if (preg_match('|]*class="NavButtonBar"[^>]*>(.*?)|is', $source, $matches)) { + $navbuttonbar = $matches[1]; + if (preg_match_all('|]*class="NavButton"[^>]*onclick="'."location='([^']*)'".'[^"]*"[^>]*>|is', $navbuttonbar, $matches)) { + $lastbutton = count($matches[0])-1; + $next = $matches[1][$lastbutton]; + } + } + } + + } else { + // xml file (...maybe) + $xml_tree = new hotpot_xml_tree($source); + $xml_tree->filetype = ''; + + $keys = array_keys($xml_tree->xml); + foreach ($keys as $key) { + if (preg_match('/^(hotpot|textoys)-(\w+)-file$/i', $key, $matches)) { + $xml_tree->filetype = 'xml'; + $xml_tree->xml_root = "['$key']['#']"; + $xml_tree->quiztype = strtolower($matches[2]); + break; + } + } + if ($xml_tree->filetype=='xml') { + + $title = strip_tags($xml_tree->xml_value('data,title')); + $subtitle = $xml_tree->xml_value('hotpot-config-file,'.$xml_tree->quiztype.',exercise-subtitle'); + + if ($get_next) { + $include = $xml_tree->xml_value('hotpot-config-file,global,include-next-ex'); + if (!empty($include)) { + $next = $xml_tree->xml_value("hotpot-config-file,$xml_tree->quiztype,next-ex-url"); + if (is_array($next)) { + $next = $next[0]; // in case "next-ex-url" was repeated in the xml file + } + } + } + } + } + + $hp->nextexercise = $next; + $hp->exercisetitle = (empty($title) || is_array($title)) ? basename($filepath) : $title; + $hp->exercisesubtitle = (empty($subtitle) || is_array($subtitle)) ? $hp->exercisetitle : $subtitle; + } } function hotpot_get_all_instances_in_course($modulename, $course) { /// called from index.php - global $CFG; - $instances = array(); - - if (isset($CFG->release) && substr($CFG->release, 0, 3)>=1.2) { - $groupmode = 'cm.groupmode,'; - } else { - $groupmode = ''; - } - - $query = " - SELECT - cm.id AS coursemodule, - cm.course AS course, - cm.module AS module, - cm.instance AS instance, - -- cm.section AS section, - cm.visible AS visible, - $groupmode - -- cs.section AS sectionnumber, - cs.section AS section, - cs.sequence AS sequence, - cs.visible AS sectionvisible, - thismodule.* - FROM - {$CFG->prefix}course_modules AS cm, - {$CFG->prefix}course_sections AS cs, - {$CFG->prefix}modules AS m, - {$CFG->prefix}$modulename AS thismodule - WHERE - m.name = '$modulename' AND - m.id = cm.module AND - cm.course = '$course->id' AND - cm.section = cs.id AND - cm.instance = thismodule.id - "; - if ($rawmods = get_records_sql($query)) { - - // cache $isteacher setting - $isteacher = isteacher($course->id); - - $explodesection = array(); - $order = array(); - - foreach ($rawmods as $rawmod) { - - if (empty($explodesection[$rawmod->section])) { - $explodesection[$rawmod->section] = true; - - $coursemodules = explode(',', $rawmod->sequence); - foreach ($coursemodules as $i=>$coursemodule) { - $order[$coursemodule] = sprintf('%d.%04d', $rawmod->section, $i); - } - } - - if ($isteacher) { - $visible = true; - } else if ($modulename=='hotpot') { - $visible = hotpot_is_visible($rawmod); - } else { - $visible = $rawmod->visible; - } - - if ($visible) { - $instances[$order[$rawmod->coursemodule]] = $rawmod; - } - - } // end foreach $modinfo - - ksort($instances); - $instances = array_values($instances); - } - - return $instances; + global $CFG; + $instances = array(); + + if (isset($CFG->release) && substr($CFG->release, 0, 3)>=1.2) { + $groupmode = 'cm.groupmode,'; + } else { + $groupmode = ''; + } + + $query = " + SELECT + cm.id AS coursemodule, + cm.course AS course, + cm.module AS module, + cm.instance AS instance, + -- cm.section AS section, + cm.visible AS visible, + $groupmode + -- cs.section AS sectionnumber, + cs.section AS section, + cs.sequence AS sequence, + cs.visible AS sectionvisible, + thismodule.* + FROM + {$CFG->prefix}course_modules AS cm, + {$CFG->prefix}course_sections AS cs, + {$CFG->prefix}modules AS m, + {$CFG->prefix}$modulename AS thismodule + WHERE + m.name = '$modulename' AND + m.id = cm.module AND + cm.course = '$course->id' AND + cm.section = cs.id AND + cm.instance = thismodule.id + "; + if ($rawmods = get_records_sql($query)) { + + // cache $isteacher setting + $isteacher = isteacher($course->id); + + $explodesection = array(); + $order = array(); + + foreach ($rawmods as $rawmod) { + + if (empty($explodesection[$rawmod->section])) { + $explodesection[$rawmod->section] = true; + + $coursemodules = explode(',', $rawmod->sequence); + foreach ($coursemodules as $i=>$coursemodule) { + $order[$coursemodule] = sprintf('%d.%04d', $rawmod->section, $i); + } + } + + if ($isteacher) { + $visible = true; + } else if ($modulename=='hotpot') { + $visible = hotpot_is_visible($rawmod); + } else { + $visible = $rawmod->visible; + } + + if ($visible) { + $instances[$order[$rawmod->coursemodule]] = $rawmod; + } + + } // end foreach $modinfo + + ksort($instances); + $instances = array_values($instances); + } + + return $instances; } function hotpot_update_chain(&$hp) { /// update a chain of hotpot actiivities - $ok = true; - if ($hotpot_modules = hotpot_get_chain($hp)) { - - // skip updating of these fields - $skipfields = array('id', 'course', 'name', 'reference', 'summary', 'shownextquiz'); - $fields = array(); - - foreach ($hotpot_modules as $hotpot_module) { - - if ($hp->instance==$hotpot_module->id) { - // don't need to update this hotpot - - } else { - // shortcut to hotpot record - $hotpot = &$hotpot_module->hotpot; - - // get a list of fields to update (first time only) - if (empty($fields)) { - $fields = array_keys(get_object_vars($hotpot)); - } - - // assume update is NOT required - $require_update = false; - - // update field values (except $skipfields) - foreach($fields as $field) { - if (in_array($field, $skipfields) || $hotpot->$field==$hp->$field) { - // update not required for this field - } else { - $require_update = true; - $hotpot->$field = $hp->$field; - } - } - - // update this $hotpot, if required - if ($require_update && !update_record("hotpot", $hotpot)) { - error("Could not update the $hp->modulename", "view.php?id=$hp->course"); - } - } - } // end foreach $ids - } - return $ok; + $ok = true; + if ($hotpot_modules = hotpot_get_chain($hp)) { + + // skip updating of these fields + $skipfields = array('id', 'course', 'name', 'reference', 'summary', 'shownextquiz'); + $fields = array(); + + foreach ($hotpot_modules as $hotpot_module) { + + if ($hp->instance==$hotpot_module->id) { + // don't need to update this hotpot + + } else { + // shortcut to hotpot record + $hotpot = &$hotpot_module->hotpot; + + // get a list of fields to update (first time only) + if (empty($fields)) { + $fields = array_keys(get_object_vars($hotpot)); + } + + // assume update is NOT required + $require_update = false; + + // update field values (except $skipfields) + foreach($fields as $field) { + if (in_array($field, $skipfields) || $hotpot->$field==$hp->$field) { + // update not required for this field + } else { + $require_update = true; + $hotpot->$field = $hp->$field; + } + } + + // update this $hotpot, if required + if ($require_update && !update_record("hotpot", $hotpot)) { + error("Could not update the $hp->modulename", "view.php?id=$hp->course"); + } + } + } // end foreach $ids + } + return $ok; } function hotpot_delete_instance($id) { /// Given an ID of an instance of this module, /// this function will permanently delete the instance /// and any data that depends on it. - $result = false; - if (delete_records("hotpot", "id", "$id")) { - $result = true; - delete_records("hotpot_questions", "hotpot", "$id"); - if ($attempts = get_records_select("hotpot_attempts", "hotpot='$id'")) { - $ids = implode(',', array_keys($attempts)); - delete_records_select("hotpot_attempts", "id IN ($ids)"); - delete_records_select("hotpot_details", "attempt IN ($ids)"); - delete_records_select("hotpot_responses", "attempt IN ($ids)"); - } - } - return $result; + $result = false; + if (delete_records("hotpot", "id", "$id")) { + $result = true; + delete_records("hotpot_questions", "hotpot", "$id"); + if ($attempts = get_records_select("hotpot_attempts", "hotpot='$id'")) { + $ids = implode(',', array_keys($attempts)); + delete_records_select("hotpot_attempts", "id IN ($ids)"); + delete_records_select("hotpot_details", "attempt IN ($ids)"); + delete_records_select("hotpot_responses", "attempt IN ($ids)"); + } + } + return $result; } function hotpot_delete_and_notify($table, $select, $strtable) { - $count = max(0, count_records_select($table, $select)); - if ($count) { - delete_records_select($table, $select); - $count -= max(0, count_records_select($table, $select)); - if ($count) { - notify(get_string('deleted')." $count x $strtable"); - } - } + $count = max(0, count_records_select($table, $select)); + if ($count) { + delete_records_select($table, $select); + $count -= max(0, count_records_select($table, $select)); + if ($count) { + notify(get_string('deleted')." $count x $strtable"); + } + } } function hotpot_user_complete($course, $user, $mod, $hp) { /// Print a detailed representation of what a user has done with /// a given particular instance of this module, for user activity reports. - $report = hotpot_user_outline($course, $user, $mod, $hp); - if (empty($report)) { - print get_string("noactivity", "hotpot"); - } else { - $date = userdate($report->time, get_string('strftimerecentfull')); - print $report->info.' '.get_string('mostrecently').': '.$date; - } - return true; + $report = hotpot_user_outline($course, $user, $mod, $hp); + if (empty($report)) { + print get_string("noactivity", "hotpot"); + } else { + $date = userdate($report->time, get_string('strftimerecentfull')); + print $report->info.' '.get_string('mostrecently').': '.$date; + } + return true; } function hotpot_user_outline($course, $user, $mod, $hp) { @@ -840,43 +840,43 @@ function hotpot_user_outline($course, $user, $mod, $hp) { /// $report->time = the time they did it /// $report->info = a short text description - $report = NULL; - if ($records = get_records_select("hotpot_attempts", "hotpot='$hp->id' AND userid='$user->id'", "timestart ASC", "*")) { - $scores = array(); - foreach ($records as $record){ - if (empty($report->time)) { - $report->time = $record->timestart; - } - $scores[] = hotpot_format_score($record); - } - if (empty($scores)) { - $report->time = 0; - $report->info = get_string('noactivity', 'hotpot'); - } else { - $report->info = get_string('score', 'quiz').': '.implode(', ', $scores); - } - } - return $report; + $report = NULL; + if ($records = get_records_select("hotpot_attempts", "hotpot='$hp->id' AND userid='$user->id'", "timestart ASC", "*")) { + $scores = array(); + foreach ($records as $record){ + if (empty($report->time)) { + $report->time = $record->timestart; + } + $scores[] = hotpot_format_score($record); + } + if (empty($scores)) { + $report->time = 0; + $report->info = get_string('noactivity', 'hotpot'); + } else { + $report->info = get_string('score', 'quiz').': '.implode(', ', $scores); + } + } + return $report; } function hotpot_format_score($record, $undefined=' ') { - if (isset($record->score)) { - $score = $record->score; - } else { - $score = $undefined; - } - return $score; + if (isset($record->score)) { + $score = $record->score; + } else { + $score = $undefined; + } + return $score; } function hotpot_format_status($record, $undefined=' ') { - global $HOTPOT_STATUS; - - if (isset($record->status) || isset($HOTPOT_STATUS[$record->status])) { - $status = $HOTPOT_STATUS[$record->status]; - } else { - $status = $undefined; - } - return $status; + global $HOTPOT_STATUS; + + if (isset($record->status) || isset($HOTPOT_STATUS[$record->status])) { + $status = $HOTPOT_STATUS[$record->status]; + } else { + $status = $undefined; + } + return $status; } function hotpot_print_recent_activity($course, $isteacher, $timestart) { @@ -884,162 +884,162 @@ function hotpot_print_recent_activity($course, $isteacher, $timestart) { /// that has occurred in hotpot activities and print it out. /// Return true if there was output, or false is there was none. - global $CFG; - - $result = false; - if($isteacher){ - - $records = get_records_sql(" - SELECT - h.id AS id, - h.name AS name, - COUNT(*) AS count_attempts - FROM - {$CFG->prefix}hotpot AS h, - {$CFG->prefix}hotpot_attempts AS a - WHERE - h.course = $course->id - AND h.id = a.hotpot - AND a.id = a.clickreportid - AND a.starttime > $timestart - GROUP BY - h.id, h.name - "); - // note that PostGreSQL requires h.name in the GROUP BY clause - - if($records) { - - $names = array(); - foreach ($records as $id => $record){ - $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$id"; - $name = ' '.$record->name.''; - if ($record->count_attempts > 1) { - $name .= " ($record->count_attempts)"; - } - $names[] = $name; - } - - print_headline(get_string('modulenameplural', 'hotpot').':'); - - if ($CFG->version >= 2005050500) { // Moodle 1.5+ - echo '
    '.implode('
    ', $names).'
    '; - } else { // Moodle 1.4.x (or less) - echo ''.implode('
    ', $names).'
    '; - } - - $result = true; - } - } - return $result; // True if anything was printed, otherwise false + global $CFG; + + $result = false; + if($isteacher){ + + $records = get_records_sql(" + SELECT + h.id AS id, + h.name AS name, + COUNT(*) AS count_attempts + FROM + {$CFG->prefix}hotpot AS h, + {$CFG->prefix}hotpot_attempts AS a + WHERE + h.course = $course->id + AND h.id = a.hotpot + AND a.id = a.clickreportid + AND a.starttime > $timestart + GROUP BY + h.id, h.name + "); + // note that PostGreSQL requires h.name in the GROUP BY clause + + if($records) { + + $names = array(); + foreach ($records as $id => $record){ + $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$id"; + $name = ' '.$record->name.''; + if ($record->count_attempts > 1) { + $name .= " ($record->count_attempts)"; + } + $names[] = $name; + } + + print_headline(get_string('modulenameplural', 'hotpot').':'); + + if ($CFG->version >= 2005050500) { // Moodle 1.5+ + echo '
    '.implode('
    ', $names).'
    '; + } else { // Moodle 1.4.x (or less) + echo ''.implode('
    ', $names).'
    '; + } + + $result = true; + } + } + return $result; // True if anything was printed, otherwise false } function hotpot_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $cmid="", $userid="", $groupid="") { // Returns all quizzes since a given time. - global $CFG; - - // If $cmid or $userid are specified, then this restricts the results - $cm_select = empty($cmid) ? "" : " AND cm.id = '$cmid'"; - $user_select = empty($userid) ? "" : " AND u.id = '$userid'"; - - $records = get_records_sql(" - SELECT - a.*, - h.name, h.course, - cm.instance, cm.section, - u.firstname, u.lastname, u.picture - FROM - {$CFG->prefix}hotpot_attempts AS a, - {$CFG->prefix}hotpot AS h, - {$CFG->prefix}course_modules AS cm, - {$CFG->prefix}user AS u - WHERE - a.timefinish > '$sincetime' - AND a.id = a.clickreportid - AND a.userid = u.id $user_select - AND a.hotpot = h.id $cm_select - AND cm.instance = h.id - AND cm.course = '$courseid' - AND h.course = cm.course - ORDER BY - a.timefinish ASC - "); - - if (!empty($records)) { - foreach ($records as $record) { - if (empty($groupid) || ismember($groupid, $record->userid)) { - - unset($activity); - - $activity->type = "hotpot"; - $activity->defaultindex = $index; - $activity->instance = $record->hotpot; - - $activity->name = $record->name; - $activity->section = $record->section; - - $activity->content->attemptid = $record->id; - $activity->content->attempt = $record->attempt; - $activity->content->score = $record->score; - $activity->content->timestart = $record->timestart; - $activity->content->timefinish = $record->timefinish; - - $activity->user->userid = $record->userid; - $activity->user->fullname = fullname($record); - $activity->user->picture = $record->picture; - - $activity->timestamp = $record->timefinish; - - $activities[] = $activity; - - $index++; - } - } // end foreach - } + global $CFG; + + // If $cmid or $userid are specified, then this restricts the results + $cm_select = empty($cmid) ? "" : " AND cm.id = '$cmid'"; + $user_select = empty($userid) ? "" : " AND u.id = '$userid'"; + + $records = get_records_sql(" + SELECT + a.*, + h.name, h.course, + cm.instance, cm.section, + u.firstname, u.lastname, u.picture + FROM + {$CFG->prefix}hotpot_attempts AS a, + {$CFG->prefix}hotpot AS h, + {$CFG->prefix}course_modules AS cm, + {$CFG->prefix}user AS u + WHERE + a.timefinish > '$sincetime' + AND a.id = a.clickreportid + AND a.userid = u.id $user_select + AND a.hotpot = h.id $cm_select + AND cm.instance = h.id + AND cm.course = '$courseid' + AND h.course = cm.course + ORDER BY + a.timefinish ASC + "); + + if (!empty($records)) { + foreach ($records as $record) { + if (empty($groupid) || ismember($groupid, $record->userid)) { + + unset($activity); + + $activity->type = "hotpot"; + $activity->defaultindex = $index; + $activity->instance = $record->hotpot; + + $activity->name = $record->name; + $activity->section = $record->section; + + $activity->content->attemptid = $record->id; + $activity->content->attempt = $record->attempt; + $activity->content->score = $record->score; + $activity->content->timestart = $record->timestart; + $activity->content->timefinish = $record->timefinish; + + $activity->user->userid = $record->userid; + $activity->user->fullname = fullname($record); + $activity->user->picture = $record->picture; + + $activity->timestamp = $record->timefinish; + + $activities[] = $activity; + + $index++; + } + } // end foreach + } } function hotpot_print_recent_mod_activity($activity, $course, $detail=false) { /// Basically, this function prints the results of "hotpot_get_recent_activity" - global $CFG, $THEME, $USER; + global $CFG, $THEME, $USER; - print ''; + print '
    '; - print '"; - print "
    '; - print_user_picture($activity->user->userid, $course, $activity->user->picture); - print ''; + print '
    '; + print_user_picture($activity->user->userid, $course, $activity->user->picture); + print ''; - if ($detail) { - // activity icon - $src = "$CFG->modpixpath/$activity->type/icon.gif"; - print ''.$activity->type.' '; + if ($detail) { + // activity icon + $src = "$CFG->modpixpath/$activity->type/icon.gif"; + print ''.$activity->type.' '; - // link to activity - $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$activity->instance"; - print ''.$activity->name.' - '; - } - if (isteacher($course)) { - // score (with link to attempt details) - $href = "$CFG->wwwroot/mod/hotpot/review.php?hp=$activity->instance&attempt=".$activity->content->attemptid; - print '('.hotpot_format_score($activity->content).') '; + // link to activity + $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$activity->instance"; + print ''.$activity->name.' - '; + } + if (isteacher($course)) { + // score (with link to attempt details) + $href = "$CFG->wwwroot/mod/hotpot/review.php?hp=$activity->instance&attempt=".$activity->content->attemptid; + print '('.hotpot_format_score($activity->content).') '; - // attempt number - print get_string('attempt', 'quiz').' - '.$activity->content->attempt.'
    '; - } + // attempt number + print get_string('attempt', 'quiz').' - '.$activity->content->attempt.'
    '; + } - // link to user - $href = "$CFG->wwwroot/user/view.php?id=$activity->user->userid&course=$course"; - print ''.$activity->user->fullname.' '; + // link to user + $href = "$CFG->wwwroot/user/view.php?id=$activity->user->userid&course=$course"; + print ''.$activity->user->fullname.' '; - // time and date - print ' - ' . userdate($activity->timestamp); + // time and date + print ' - ' . userdate($activity->timestamp); - // duration - $duration = format_time($activity->content->timestart - $activity->content->timefinish); - print "   ($duration)"; + // duration + $duration = format_time($activity->content->timestart - $activity->content->timefinish); + print "   ($duration)"; - print "
    "; + print ""; + print ""; } function hotpot_cron () { @@ -1047,77 +1047,77 @@ function hotpot_cron () { /// This function searches for things that need to be done, such /// as sending out mail, toggling flags etc ... - global $CFG; + global $CFG; - return true; + return true; } function hotpot_grades($hotpotid) { /// Must return an array of grades for a given instance of this module, /// indexed by user. It also returns a maximum allowed grade. - $hotpot = get_record('hotpot', 'id', $hotpotid); - $return->grades = hotpot_get_grades($hotpot); - $return->maxgrade = $hotpot->grade; + $hotpot = get_record('hotpot', 'id', $hotpotid); + $return->grades = hotpot_get_grades($hotpot); + $return->maxgrade = $hotpot->grade; - return $return; + return $return; } function hotpot_get_grades($hotpot, $user_ids='') { - global $CFG; - - $grades = array(); - - $weighting = $hotpot->grade / 100; - $precision = hotpot_get_precision($hotpot); - - // set the SQL string to determine the $grade - $grade = ""; - switch ($hotpot->grademethod) { - case HOTPOT_GRADEMETHOD_HIGHEST: - $grade = "ROUND(MAX(score) * $weighting, $precision) AS grade"; - break; - case HOTPOT_GRADEMETHOD_AVERAGE: - // the 'AVG' function skips abandoned quizzes, so use SUM(score)/COUNT(id) - $grade = "ROUND(SUM(score)/COUNT(id) * $weighting, $precision) AS grade"; - break; - case HOTPOT_GRADEMETHOD_FIRST: - if ($CFG->dbtype=='postgres7') { - $grade = "MIN(timestart||'_'||(CASE WHEN (score IS NULL) THEN '' ELSE TRIM(ROUND(score * $weighting, $precision)) END)) AS grade"; - } else { - $grade = "MIN(CONCAT(timestart, '_', IF(score IS NULL, '', ROUND(score * $weighting, $precision)))) AS grade"; - } - break; - case HOTPOT_GRADEMETHOD_LAST: - if ($CFG->dbtype=='postgres7') { - $grade = "MAX(timestart||'_'||(CASE WHEN (score IS NULL) THEN '' ELSE TRIM(ROUND(score * $weighting, $precision)) END)) AS grade"; - } else { - $grade = "MAX(CONCAT(timestart, '_', IF(score IS NULL, '', ROUND(score * $weighting, $precision)))) AS grade"; - } - break; - } - - if ($grade) { - $userid_condition = empty($user_ids) ? '' : "AND userid IN ($user_ids) "; - $grades = get_records_sql_menu(" - SELECT userid, $grade - FROM {$CFG->prefix}hotpot_attempts - WHERE timefinish>0 AND hotpot='$hotpot->id' $userid_condition - GROUP BY userid - "); - if ($grades) { - if ($hotpot->grademethod==HOTPOT_GRADEMETHOD_FIRST || $hotpot->grademethod==HOTPOT_GRADEMETHOD_LAST) { - // remove left hand characters in $grade (up to and including the underscore) - foreach ($grades as $userid=>$grade) { - $grades[$userid] = substr($grades[$userid], strpos($grades[$userid], '_')+1); - } - } - } - } - - return $grades; + global $CFG; + + $grades = array(); + + $weighting = $hotpot->grade / 100; + $precision = hotpot_get_precision($hotpot); + + // set the SQL string to determine the $grade + $grade = ""; + switch ($hotpot->grademethod) { + case HOTPOT_GRADEMETHOD_HIGHEST: + $grade = "ROUND(MAX(score) * $weighting, $precision) AS grade"; + break; + case HOTPOT_GRADEMETHOD_AVERAGE: + // the 'AVG' function skips abandoned quizzes, so use SUM(score)/COUNT(id) + $grade = "ROUND(SUM(score)/COUNT(id) * $weighting, $precision) AS grade"; + break; + case HOTPOT_GRADEMETHOD_FIRST: + if ($CFG->dbtype=='postgres7') { + $grade = "MIN(timestart||'_'||(CASE WHEN (score IS NULL) THEN '' ELSE TRIM(ROUND(score * $weighting, $precision)) END)) AS grade"; + } else { + $grade = "MIN(CONCAT(timestart, '_', IF(score IS NULL, '', ROUND(score * $weighting, $precision)))) AS grade"; + } + break; + case HOTPOT_GRADEMETHOD_LAST: + if ($CFG->dbtype=='postgres7') { + $grade = "MAX(timestart||'_'||(CASE WHEN (score IS NULL) THEN '' ELSE TRIM(ROUND(score * $weighting, $precision)) END)) AS grade"; + } else { + $grade = "MAX(CONCAT(timestart, '_', IF(score IS NULL, '', ROUND(score * $weighting, $precision)))) AS grade"; + } + break; + } + + if ($grade) { + $userid_condition = empty($user_ids) ? '' : "AND userid IN ($user_ids) "; + $grades = get_records_sql_menu(" + SELECT userid, $grade + FROM {$CFG->prefix}hotpot_attempts + WHERE timefinish>0 AND hotpot='$hotpot->id' $userid_condition + GROUP BY userid + "); + if ($grades) { + if ($hotpot->grademethod==HOTPOT_GRADEMETHOD_FIRST || $hotpot->grademethod==HOTPOT_GRADEMETHOD_LAST) { + // remove left hand characters in $grade (up to and including the underscore) + foreach ($grades as $userid=>$grade) { + $grades[$userid] = substr($grades[$userid], strpos($grades[$userid], '_')+1); + } + } + } + } + + return $grades; } function hotpot_get_precision(&$hotpot) { - return ($hotpot->grademethod==HOTPOT_GRADEMETHOD_AVERAGE || $hotpot->grade<100) ? 1 : 0; + return ($hotpot->grademethod==HOTPOT_GRADEMETHOD_AVERAGE || $hotpot->grade<100) ? 1 : 0; } function hotpot_get_participants($hotpotid) { @@ -1125,18 +1125,18 @@ function hotpot_get_participants($hotpotid) { //for a given instance of hotpot. Must include every user involved //in the instance, independient of his role (student, teacher, admin...) //See other modules as example. - global $CFG; - - return get_records_sql(" - SELECT DISTINCT - u.id, u.id - FROM - {$CFG->prefix}user u, - {$CFG->prefix}hotpot_attempts a - WHERE - u.id = a.userid - AND a.hotpot = '$hotpotid' - "); + global $CFG; + + return get_records_sql(" + SELECT DISTINCT + u.id, u.id + FROM + {$CFG->prefix}user u, + {$CFG->prefix}hotpot_attempts a + WHERE + u.id = a.userid + AND a.hotpot = '$hotpotid' + "); } function hotpot_scale_used ($hotpotid, $scaleid) { @@ -1145,15 +1145,15 @@ function hotpot_scale_used ($hotpotid, $scaleid) { //modified if necessary. See forum, glossary or journal modules //as reference. - $report = false; + $report = false; - //$rec = get_record("hotpot","id","$hotpotid","scale","-$scaleid"); - // - //if (!empty($rec) && !empty($scaleid)) { - // $report = true; - //} + //$rec = get_record("hotpot","id","$hotpotid","scale","-$scaleid"); + // + //if (!empty($rec) && !empty($scaleid)) { + // $report = true; + //} - return $report; + return $report; } ////////////////////////////////////////////////////////// @@ -1162,83 +1162,83 @@ function hotpot_scale_used ($hotpotid, $scaleid) { function hotpot_add_attempt($hotpotid) { - global $db, $CFG, $USER; - $time = time(); - switch (strtolower($CFG->dbtype)) { - case 'mysql': - $timefinish = "IF(a.timefinish IS NULL, '$time', a.timefinish)"; - $clickreportid = "IF(a.clickreportid IS NULL, a.id, a.clickreportid)"; - break; - case 'postgres7': - $timefinish = "WHEN(a.timefinish IS NULL) THEN '$time' ELSE a.timefinish"; - $clickreportid = "WHEN(a.clickreportid IS NULL) THEN a.id ELSE a.clickreportid"; - break; - } - - // set all previous "in progress" attempts at this quiz to "abandoned" - $db->Execute(" - UPDATE - {$CFG->prefix}hotpot_attempts as a - SET - a.timefinish = $timefinish, - a.status = '".HOTPOT_STATUS_ABANDONED."', - a.clickreportid = $clickreportid - WHERE - a.hotpot='$hotpotid' - AND a.userid='$USER->id' - AND a.status='".HOTPOT_STATUS_INPROGRESS."' - "); - - // create and add new attempt record - $attempt->hotpot = $hotpotid; - $attempt->userid = $USER->id; - $attempt->attempt = hotpot_get_next_attempt($hotpotid); - $attempt->timestart = time(); - - return insert_record("hotpot_attempts", $attempt); + global $db, $CFG, $USER; + $time = time(); + switch (strtolower($CFG->dbtype)) { + case 'mysql': + $timefinish = "IF(a.timefinish IS NULL, '$time', a.timefinish)"; + $clickreportid = "IF(a.clickreportid IS NULL, a.id, a.clickreportid)"; + break; + case 'postgres7': + $timefinish = "WHEN(a.timefinish IS NULL) THEN '$time' ELSE a.timefinish"; + $clickreportid = "WHEN(a.clickreportid IS NULL) THEN a.id ELSE a.clickreportid"; + break; + } + + // set all previous "in progress" attempts at this quiz to "abandoned" + $db->Execute(" + UPDATE + {$CFG->prefix}hotpot_attempts as a + SET + a.timefinish = $timefinish, + a.status = '".HOTPOT_STATUS_ABANDONED."', + a.clickreportid = $clickreportid + WHERE + a.hotpot='$hotpotid' + AND a.userid='$USER->id' + AND a.status='".HOTPOT_STATUS_INPROGRESS."' + "); + + // create and add new attempt record + $attempt->hotpot = $hotpotid; + $attempt->userid = $USER->id; + $attempt->attempt = hotpot_get_next_attempt($hotpotid); + $attempt->timestart = time(); + + return insert_record("hotpot_attempts", $attempt); } function hotpot_get_next_attempt($hotpotid) { - global $USER; + global $USER; - // get max attempt so far - $i = count_records_select('hotpot_attempts', "hotpot='$hotpotid' AND userid='$USER->id'", 'MAX(attempt)'); + // get max attempt so far + $i = count_records_select('hotpot_attempts', "hotpot='$hotpotid' AND userid='$USER->id'", 'MAX(attempt)'); - return empty($i) ? 1 : ($i+1); + return empty($i) ? 1 : ($i+1); } function hotpot_get_question_name($question) { - $name = ''; - if (isset($question->text)) { - $name = hotpot_strings($question->text); - } - if (empty($name)) { - $name = $question->name; - } - return $name; + $name = ''; + if (isset($question->text)) { + $name = hotpot_strings($question->text); + } + if (empty($name)) { + $name = $question->name; + } + return $name; } function hotpot_strings($ids) { - // array of ids of empty strings - static $HOTPOT_EMPTYSTRINGS; - - if (!isset($HOTPOT_EMPTYSTRINGS)) { // first time only - // get ids of empty strings - $emptystrings = get_records_select('hotpot_strings', 'LENGTH(TRIM(string))=0'); - $HOTPOT_EMPTYSTRINGS = empty($emptystrings) ? array() : array_keys($emptystrings); - } - - $strings = array(); - if (!empty($ids)) { - $ids = explode(',', $ids); - foreach ($ids as $id) { - if (!in_array($id, $HOTPOT_EMPTYSTRINGS)) { - $strings[] = hotpot_string($id); - } - } - } - return implode(',', $strings); + // array of ids of empty strings + static $HOTPOT_EMPTYSTRINGS; + + if (!isset($HOTPOT_EMPTYSTRINGS)) { // first time only + // get ids of empty strings + $emptystrings = get_records_select('hotpot_strings', 'LENGTH(TRIM(string))=0'); + $HOTPOT_EMPTYSTRINGS = empty($emptystrings) ? array() : array_keys($emptystrings); + } + + $strings = array(); + if (!empty($ids)) { + $ids = explode(',', $ids); + foreach ($ids as $id) { + if (!in_array($id, $HOTPOT_EMPTYSTRINGS)) { + $strings[] = hotpot_string($id); + } + } + } + return implode(',', $strings); } function hotpot_string($id) { - return get_field('hotpot_strings', 'string', 'id', $id); + return get_field('hotpot_strings', 'string', 'id', $id); } ////////////////////////////////////////////////////////////////////////////////////// @@ -1251,575 +1251,575 @@ require_once("$CFG->libdir/xmlize.php"); require_once("$CFG->hotpottemplate/default.php"); class hotpot_xml_tree { - function hotpot_xml_tree($str, $xml_root='') { - if (empty($str)) { - $this->xml = array(); - } else { - if (empty($CFG->unicodedb)) { - $str = utf8_encode($str); - } - $this->xml = xmlize($str, 0); - } - $this->xml_root = $xml_root; - } - function xml_value($tags, $more_tags="[0]['#']") { - - $tags = empty($tags) ? '' : "['".str_replace(",", "'][0]['#']['", $tags)."']"; - eval('$value = &$this->xml'.$this->xml_root.$tags.$more_tags.';'); - - if (is_string($value)) { - if (empty($CFG->unicodedb)) { - $value = utf8_decode($value); - } - - // decode angle brackets - $value = strtr($value, array('<'=>'<', '>'=>'>', '&'=>'&')); - - // remove white space between , and parts - // (so it doesn't get converted to
    ) - $htmltags = '(' - . 'TABLE|/?CAPTION|/?COL|/?COLGROUP|/?TBODY|/?TFOOT|/?THEAD|/?TD|/?TH|/?TR' - . '|OL|UL|/?LI' - . '|DL|/?DT|/?DD' - . '|EMBED|OBJECT|APPLET|/?PARAM' - //. '|SELECT|/?OPTION' - //. '|FIELDSET|/?LEGEND' - //. '|FRAMESET|/?FRAME' - . ')' - ; - - $space = '(\s|(]*>))+'; - $search = '#(<'.$htmltags.'[^>]*'.'>)'.$space.'(?='.'<)#is'; - $value = preg_replace($search, '\\1', $value); - - // replace remaining newlines with
    - $value = str_replace("\n", '
    ', $value); - - // encode unicode characters as HTML entities - // (in particular, accented charaters that have not been encoded by HP) - - // unicode characters can be detected by checking the hex value of a character - // 00 - 7F : ascii char (roman alphabet + punctuation) - // 80 - BF : byte 2, 3 or 4 of a unicode char - // C0 - DF : 1st byte of 2-byte char - // E0 - EF : 1st byte of 3-byte char - // F0 - FF : 1st byte of 4-byte char - // if the string doesn't match the above, it might be - // 80 - FF : single-byte, non-ascii char - $search = '#('.'[\xc0-\xdf][\x80-\xbf]'.'|'.'[\xe0-\xef][\x80-\xbf]{2}'.'|'.'[\xf0-\xff][\x80-\xbf]{3}'.'|'.'[\x80-\xff]'.')#se'; - $value = preg_replace($search, "hotpot_utf8_to_html_entity('\\1')", $value); - } - return $value; - } - function xml_values($tags) { - $i = 0; - $values = array(); - while ($value = $this->xml_value($tags, "[$i]['#']")) { - $values[$i++] = $value; - } - return $values; - } - function obj_value(&$obj, $name) { - return is_object($obj) ? @$obj->$name : (is_array($obj) ? @$obj[$name] : NULL); - } - function encode_cdata(&$str, $tag) { - - // conversion tables - static $HTML_ENTITIES = array( - ''' => "'", - '"' => '"', - '<' => '<', - '>' => '>', - '&' => '&', - ); - static $ILLEGAL_STRINGS = array( - "\r\n" => '<br />', - "\r" => '<br />', - "\n" => '<br />', - '[' => '[', - ']' => ']' - ); - - // extract the $tag from the $str(ing), if possible - $pattern = '|(^.*<'.$tag.'[^>]*)(>.*<)(/'.$tag.'>.*$)|is'; - if (preg_match($pattern, $str, $matches)) { - - // encode problematic CDATA chars and strings - $matches[2] = strtr($matches[2], $ILLEGAL_STRINGS); - - // if there are any ampersands in "open text" - // surround them by CDATA start and end markers - // (and convert HTML entities to plain text) - $search = '/>([^<]*&[^<]*)xml = array(); + } else { + if (empty($CFG->unicodedb)) { + $str = utf8_encode($str); + } + $this->xml = xmlize($str, 0); + } + $this->xml_root = $xml_root; + } + function xml_value($tags, $more_tags="[0]['#']") { + + $tags = empty($tags) ? '' : "['".str_replace(",", "'][0]['#']['", $tags)."']"; + eval('$value = &$this->xml'.$this->xml_root.$tags.$more_tags.';'); + + if (is_string($value)) { + if (empty($CFG->unicodedb)) { + $value = utf8_decode($value); + } + + // decode angle brackets + $value = strtr($value, array('<'=>'<', '>'=>'>', '&'=>'&')); + + // remove white space between
    , and parts + // (so it doesn't get converted to
    ) + $htmltags = '(' + . 'TABLE|/?CAPTION|/?COL|/?COLGROUP|/?TBODY|/?TFOOT|/?THEAD|/?TD|/?TH|/?TR' + . '|OL|UL|/?LI' + . '|DL|/?DT|/?DD' + . '|EMBED|OBJECT|APPLET|/?PARAM' + //. '|SELECT|/?OPTION' + //. '|FIELDSET|/?LEGEND' + //. '|FRAMESET|/?FRAME' + . ')' + ; + + $space = '(\s|(]*>))+'; + $search = '#(<'.$htmltags.'[^>]*'.'>)'.$space.'(?='.'<)#is'; + $value = preg_replace($search, '\\1', $value); + + // replace remaining newlines with
    + $value = str_replace("\n", '
    ', $value); + + // encode unicode characters as HTML entities + // (in particular, accented charaters that have not been encoded by HP) + + // unicode characters can be detected by checking the hex value of a character + // 00 - 7F : ascii char (roman alphabet + punctuation) + // 80 - BF : byte 2, 3 or 4 of a unicode char + // C0 - DF : 1st byte of 2-byte char + // E0 - EF : 1st byte of 3-byte char + // F0 - FF : 1st byte of 4-byte char + // if the string doesn't match the above, it might be + // 80 - FF : single-byte, non-ascii char + $search = '#('.'[\xc0-\xdf][\x80-\xbf]'.'|'.'[\xe0-\xef][\x80-\xbf]{2}'.'|'.'[\xf0-\xff][\x80-\xbf]{3}'.'|'.'[\x80-\xff]'.')#se'; + $value = preg_replace($search, "hotpot_utf8_to_html_entity('\\1')", $value); + } + return $value; + } + function xml_values($tags) { + $i = 0; + $values = array(); + while ($value = $this->xml_value($tags, "[$i]['#']")) { + $values[$i++] = $value; + } + return $values; + } + function obj_value(&$obj, $name) { + return is_object($obj) ? @$obj->$name : (is_array($obj) ? @$obj[$name] : NULL); + } + function encode_cdata(&$str, $tag) { + + // conversion tables + static $HTML_ENTITIES = array( + ''' => "'", + '"' => '"', + '<' => '<', + '>' => '>', + '&' => '&', + ); + static $ILLEGAL_STRINGS = array( + "\r\n" => '<br />', + "\r" => '<br />', + "\n" => '<br />', + '[' => '[', + ']' => ']' + ); + + // extract the $tag from the $str(ing), if possible + $pattern = '|(^.*<'.$tag.'[^>]*)(>.*<)(/'.$tag.'>.*$)|is'; + if (preg_match($pattern, $str, $matches)) { + + // encode problematic CDATA chars and strings + $matches[2] = strtr($matches[2], $ILLEGAL_STRINGS); + + // if there are any ampersands in "open text" + // surround them by CDATA start and end markers + // (and convert HTML entities to plain text) + $search = '/>([^<]*&[^<]*)read_file = $read_file; - $this->parse_xml = $parse_xml; - $this->convert_urls = $convert_urls; - $this->report_errors = $report_errors; - $this->create_html = $create_html; - - // extract fields from $obj - // course : the course id - // reference : the filename within the files folder - // location : "site" files folder or "course" files folder - // navigation : type of navigation required in quiz - // forceplugins : force Moodle compatible media players - $this->course = $this->obj_value($obj, 'course'); - $this->reference = $this->obj_value($obj, 'reference'); - $this->location = $this->obj_value($obj, 'location'); - $this->navigation = $this->obj_value($obj, 'navigation'); - $this->forceplugins = $this->obj_value($obj, 'forceplugins'); - - // can't continue if there is no course or reference - if (empty($this->course) || empty($this->reference)) { - $this->error = get_string('error_nocourseorfilename', 'hotpot'); - if ($this->report_errors) { - error($this->error); - } - return; - } - - $this->course_homeurl = "$CFG->wwwroot/course/view.php?id=$this->course"; - - // set filedir, filename and filepath - switch ($this->location) { - case HOTPOT_LOCATION_SITEFILES: - $site = get_site(); - $this->filedir = $site->id; - break; - - case HOTPOT_LOCATION_COURSEFILES: - default: - $this->filedir = $this->course; - break; - } - $this->filesubdir = dirname($this->reference); - if ($this->filesubdir=='.') { - $this->filesubdir = ''; - } - if ($this->filesubdir) { - $this->filesubdir .= '/'; - } - $this->filename = basename($this->reference); - $this->fileroot = "$CFG->dataroot/$this->filedir"; - $this->filepath = "$this->fileroot/$this->reference"; - - // read the file, if required - if ($this->read_file) { - - if (!file_exists($this->filepath) || !is_readable($this->filepath)) { - $this->error = get_string('error_couldnotopensourcefile', 'hotpot', $this->filepath); - if ($this->report_errors) { - error($this->error, $this->course_homeurl); - } - return; - } - - // read in the XML source - $this->source = file_get_contents($this->filepath); - - // convert relative URLs to absolute URLs - if ($this->convert_urls) { - $this->hotpot_convert_relative_urls($this->source); - } - - $this->html = ''; - $this->quiztype = ''; - $this->outputformat = 0; - - // is this an html file? - if (preg_match('|\.html?$|', $this->filename)) { - - $this->filetype = 'html'; - $this->html = &$this->source; - - // relative URLs in stylesheets - $search = '|'.'(]*>)'.'(.*?)'.'()'.'|ise'; - $replace = "stripslashes('\\1').hotpot_convert_stylesheets_urls('".$this->get_baseurl()."','".$this->reference."','\\2'.'\\3')"; - $this->source = preg_replace($search, $replace, $this->source); - - // relative URLs in "PreloadImages(...);" - $search = '|'.'(?<='.'PreloadImages'.'\('.')'."([^)]+?)".'(?='.'\);'.')'.'|se'; - $replace = "hotpot_convert_preloadimages_urls('".$this->get_baseurl()."','".$this->reference."','\\1')"; - $this->source = preg_replace($search, $replace, $this->source); - - // relative URLs in ' - ; - $this->insert_form($startblock, $endblock, $form_name, $form_fields, $keep_contents, true); - } - function insert_form($startblock, $endblock, $form_name, $form_fields, $keep_contents, $center=false) { - global $CFG; - $search = '#('.preg_quote($startblock).')(.*?)('.preg_quote($endblock).')#s'; - $replace = $form_fields; - if ($keep_contents) { - $replace .= '\\2'; - } - if ($form_name) { - $replace = ''.$replace.''; - } - if ($center) { - $replace = '
    '.$replace.'
    '; - } - $replace = '\\1'.$replace.'\\3'; - $this->html = preg_replace($search, $replace, $this->html, 1); - } - function insert_message($start_str, $message, $color='red', $align='center') { - $message = '

    '.$message."

    \n"; - $this->html = preg_replace('|'.preg_quote($start_str).'|', $start_str.$message, $this->html, 1); - } - - function adjust_media_urls() { - - if ($this->forceplugins) { - - // make sure the Moodle media plugin is available - global $CFG; - include_once "$CFG->dirroot/filter/mediaplugin/filter.php"; - - // exclude swf files from the filter - //$CFG->filter_mediaplugin_ignore_swf = true; - - $space = '\s(?:.+\s)?'; - $quote = '["'."']?"; // single, double, or no quote - - // patterns to media files types and paths - $filetype = "avi|mpeg|mpg|mp3|mov|wmv"; - $filepath = ".*?\.($filetype)"; - - $tagopen = '(?:(<)|(\\\\u003C))'; // left angle-bracket (uses two parenthese) - $tagclose = '(?(1)>|(?(2)\\\\u003E))'; // right angle-bracket (to match the left one) - $tagreopen = '(?(1)<|(?(2)\\\\u003C))'; // another left angle-bracket (to match the first one) - - // pattern to match tags which contain the file path - // wmp : url - // quicktime : src - // realplayer : src - // flash : movie (doesn't need replacing) - $param_url = "/{$tagopen}param{$space}name=$quote(?:movie|src|url)$quote{$space}value=$quote($filepath)$quote.*?$tagclose/is"; - - // pattern to match tags which link to multimedia files - $link_url = "/{$tagopen}a{$space}href=$quote($filepath)$quote.*?$tagclose.*?$tagreopen\/A$tagclose/is"; - - // extract tags - preg_match_all("/{$tagopen}object\s.*?{$tagclose}(.*?){$tagreopen}\/object{$tagclose}/is", $this->html, $objects); - - $i_max = count($objects[0]); - for ($i=0; $i<$i_max; $i++) { - - // extract URL from or - $url = ''; - if (preg_match($param_url, $objects[3][$i], $matches) || preg_match($link_url, $objects[3][$i], $matches)) { - $url = $matches[3]; - } - - if ($url) { - // strip inner tags (e.g. ) - $txt = preg_replace("/$tagopen.*?$tagclose/", '', $objects[3][$i]); - - // if url is in the query string, remove the leading characters - $url = preg_replace('/^[^?]*\?([^=]+=[^&]*&)*[^=]+=([^&]*)$/', '$2', $url, 1); - $link = ''.$txt.''; - - $new_object = mediaplugin_filter($this->filedir, $link); - $new_object = str_replace($link, '', $new_object); - $new_object = str_replace('&', '&', $new_object); - - $this->html = str_replace($objects[0][$i], $new_object, $this->html); - } - } - } - } + // constructor function + function hotpot_xml_quiz(&$obj, $read_file=true, $parse_xml=true, $convert_urls=true, $report_errors=true, $create_html=true) { + // obj can be the $_GET array or a form object/array + + global $CFG, $HOTPOT_OUTPUTFORMAT, $HOTPOT_OUTPUTFORMAT_DIR; + + // check xmlize functions are available + if (! function_exists("xmlize")) { + error('xmlize functions are not available'); + } + + $this->read_file = $read_file; + $this->parse_xml = $parse_xml; + $this->convert_urls = $convert_urls; + $this->report_errors = $report_errors; + $this->create_html = $create_html; + + // extract fields from $obj + // course : the course id + // reference : the filename within the files folder + // location : "site" files folder or "course" files folder + // navigation : type of navigation required in quiz + // forceplugins : force Moodle compatible media players + $this->course = $this->obj_value($obj, 'course'); + $this->reference = $this->obj_value($obj, 'reference'); + $this->location = $this->obj_value($obj, 'location'); + $this->navigation = $this->obj_value($obj, 'navigation'); + $this->forceplugins = $this->obj_value($obj, 'forceplugins'); + + // can't continue if there is no course or reference + if (empty($this->course) || empty($this->reference)) { + $this->error = get_string('error_nocourseorfilename', 'hotpot'); + if ($this->report_errors) { + error($this->error); + } + return; + } + + $this->course_homeurl = "$CFG->wwwroot/course/view.php?id=$this->course"; + + // set filedir, filename and filepath + switch ($this->location) { + case HOTPOT_LOCATION_SITEFILES: + $site = get_site(); + $this->filedir = $site->id; + break; + + case HOTPOT_LOCATION_COURSEFILES: + default: + $this->filedir = $this->course; + break; + } + $this->filesubdir = dirname($this->reference); + if ($this->filesubdir=='.') { + $this->filesubdir = ''; + } + if ($this->filesubdir) { + $this->filesubdir .= '/'; + } + $this->filename = basename($this->reference); + $this->fileroot = "$CFG->dataroot/$this->filedir"; + $this->filepath = "$this->fileroot/$this->reference"; + + // read the file, if required + if ($this->read_file) { + + if (!file_exists($this->filepath) || !is_readable($this->filepath)) { + $this->error = get_string('error_couldnotopensourcefile', 'hotpot', $this->filepath); + if ($this->report_errors) { + error($this->error, $this->course_homeurl); + } + return; + } + + // read in the XML source + $this->source = file_get_contents($this->filepath); + + // convert relative URLs to absolute URLs + if ($this->convert_urls) { + $this->hotpot_convert_relative_urls($this->source); + } + + $this->html = ''; + $this->quiztype = ''; + $this->outputformat = 0; + + // is this an html file? + if (preg_match('|\.html?$|', $this->filename)) { + + $this->filetype = 'html'; + $this->html = &$this->source; + + // relative URLs in stylesheets + $search = '|'.'(]*>)'.'(.*?)'.'()'.'|ise'; + $replace = "stripslashes('\\1').hotpot_convert_stylesheets_urls('".$this->get_baseurl()."','".$this->reference."','\\2'.'\\3')"; + $this->source = preg_replace($search, $replace, $this->source); + + // relative URLs in "PreloadImages(...);" + $search = '|'.'(?<='.'PreloadImages'.'\('.')'."([^)]+?)".'(?='.'\);'.')'.'|se'; + $replace = "hotpot_convert_preloadimages_urls('".$this->get_baseurl()."','".$this->reference."','\\1')"; + $this->source = preg_replace($search, $replace, $this->source); + + // relative URLs in ' + ; + $this->insert_form($startblock, $endblock, $form_name, $form_fields, $keep_contents, true); + } + function insert_form($startblock, $endblock, $form_name, $form_fields, $keep_contents, $center=false) { + global $CFG; + $search = '#('.preg_quote($startblock).')(.*?)('.preg_quote($endblock).')#s'; + $replace = $form_fields; + if ($keep_contents) { + $replace .= '\\2'; + } + if ($form_name) { + $replace = ''.$replace.''; + } + if ($center) { + $replace = '
    '.$replace.'
    '; + } + $replace = '\\1'.$replace.'\\3'; + $this->html = preg_replace($search, $replace, $this->html, 1); + } + function insert_message($start_str, $message, $color='red', $align='center') { + $message = '

    '.$message."

    \n"; + $this->html = preg_replace('|'.preg_quote($start_str).'|', $start_str.$message, $this->html, 1); + } + + function adjust_media_urls() { + + if ($this->forceplugins) { + + // make sure the Moodle media plugin is available + global $CFG; + include_once "$CFG->dirroot/filter/mediaplugin/filter.php"; + + // exclude swf files from the filter + //$CFG->filter_mediaplugin_ignore_swf = true; + + $space = '\s(?:.+\s)?'; + $quote = '["'."']?"; // single, double, or no quote + + // patterns to media files types and paths + $filetype = "avi|mpeg|mpg|mp3|mov|wmv"; + $filepath = ".*?\.($filetype)"; + + $tagopen = '(?:(<)|(\\\\u003C))'; // left angle-bracket (uses two parenthese) + $tagclose = '(?(1)>|(?(2)\\\\u003E))'; // right angle-bracket (to match the left one) + $tagreopen = '(?(1)<|(?(2)\\\\u003C))'; // another left angle-bracket (to match the first one) + + // pattern to match tags which contain the file path + // wmp : url + // quicktime : src + // realplayer : src + // flash : movie (doesn't need replacing) + $param_url = "/{$tagopen}param{$space}name=$quote(?:movie|src|url)$quote{$space}value=$quote($filepath)$quote.*?$tagclose/is"; + + // pattern to match tags which link to multimedia files + $link_url = "/{$tagopen}a{$space}href=$quote($filepath)$quote.*?$tagclose.*?$tagreopen\/A$tagclose/is"; + + // extract tags + preg_match_all("/{$tagopen}object\s.*?{$tagclose}(.*?){$tagreopen}\/object{$tagclose}/is", $this->html, $objects); + + $i_max = count($objects[0]); + for ($i=0; $i<$i_max; $i++) { + + // extract URL from or + $url = ''; + if (preg_match($param_url, $objects[3][$i], $matches) || preg_match($link_url, $objects[3][$i], $matches)) { + $url = $matches[3]; + } + + if ($url) { + // strip inner tags (e.g. ) + $txt = preg_replace("/$tagopen.*?$tagclose/", '', $objects[3][$i]); + + // if url is in the query string, remove the leading characters + $url = preg_replace('/^[^?]*\?([^=]+=[^&]*&)*[^=]+=([^&]*)$/', '$2', $url, 1); + $link = ''.$txt.''; + + $new_object = mediaplugin_filter($this->filedir, $link); + $new_object = str_replace($link, '', $new_object); + $new_object = str_replace('&', '&', $new_object); + + $this->html = str_replace($objects[0][$i], $new_object, $this->html); + } + } + } + } } // end class function hotpot_convert_stylesheets_urls($baseurl, $reference, $css, $stripslashes=true) { - if ($stripslashes) { - $css = stripslashes($css); - } - $search = '|'.'(?<='.'url'.'\('.')'."(.+?)".'(?='.'\)'.')'.'|ise'; - $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; - return preg_replace($search, $replace, $css); + if ($stripslashes) { + $css = stripslashes($css); + } + $search = '|'.'(?<='.'url'.'\('.')'."(.+?)".'(?='.'\)'.')'.'|ise'; + $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; + return preg_replace($search, $replace, $css); } function hotpot_convert_preloadimages_urls($baseurl, $reference, $urls, $stripslashes=true) { - if ($stripslashes) { - $urls = stripslashes($urls); - } - $search = '|(?<=["'."'])([^,'".'"]*?)(?=["'."'])|ise"; - $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; - return preg_replace($search, $replace, $urls); + if ($stripslashes) { + $urls = stripslashes($urls); + } + $search = '|(?<=["'."'])([^,'".'"]*?)(?=["'."'])|ise"; + $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; + return preg_replace($search, $replace, $urls); } function hotpot_convert_navbutton_url($baseurl, $reference, $url, $course, $stripslashes=true) { - global $CFG; - - if ($stripslashes) { - $url = stripslashes($url); - } - $url = hotpot_convert_url($baseurl, $reference, $url, false); - - // is this a $url for another hotpot in this course ? - if (preg_match("|^$baseurl(.*)$|", $url, $matches)) { - if ($records = get_records_select('hotpot', "course='$course' AND reference='".$matches[1]."'")) { - $ids = array_keys($records); - $url = "$CFG->wwwroot/mod/hotpot/view.php?hp=".$ids[0]; - } - } - - return $url; + global $CFG; + + if ($stripslashes) { + $url = stripslashes($url); + } + $url = hotpot_convert_url($baseurl, $reference, $url, false); + + // is this a $url for another hotpot in this course ? + if (preg_match("|^$baseurl(.*)$|", $url, $matches)) { + if ($records = get_records_select('hotpot', "course='$course' AND reference='".$matches[1]."'")) { + $ids = array_keys($records); + $url = "$CFG->wwwroot/mod/hotpot/view.php?hp=".$ids[0]; + } + } + + return $url; } function hotpot_convert_relative_url($baseurl, $reference, $opentag, $url, $closetag, $stripslashes=true) { - if ($stripslashes) { - $opentag = stripslashes($opentag); - $url = stripslashes($url); - $closetag = stripslashes($closetag); - } - - // catch - // ampersands can appear as "&", "&" or "&#x0026;amp;" - if (preg_match('|^'.'\w+=[^&]+'.'('.'&((amp;#x0026;)?amp;)?'.'\w+=[^&]+)*'.'$|', $url)) { - $query = $url; - $url = ''; - $fragment = ''; - - // parse the $url into $matches - // [1] path - // [2] query string, if any - // [3] anchor fragment, if any - } else if (preg_match('|^'.'([^?]*)'.'((?:\\?[^#]*)?)'.'((?:#.*)?)'.'$|', $url, $matches)) { - $url = $matches[1]; - $query = $matches[2]; - $fragment = $matches[3]; - - // these appears to be no query or fragment in this url - } else { - $query = ''; - $fragment = ''; - } - - if ($url) { - $url = hotpot_convert_url($baseurl, $reference, $url, false); - } - - if ($query) { - $search = '#'.'(file|src|thesound)='."([^&]+)".'#ise'; - $replace = "'\\1='.hotpot_convert_url('".$baseurl."','".$reference."','\\2')"; - $query = preg_replace($search, $replace, $query); - } - - $url = $opentag.$url.$query.$fragment.$closetag; - - return $url; + if ($stripslashes) { + $opentag = stripslashes($opentag); + $url = stripslashes($url); + $closetag = stripslashes($closetag); + } + + // catch + // ampersands can appear as "&", "&" or "&#x0026;amp;" + if (preg_match('|^'.'\w+=[^&]+'.'('.'&((amp;#x0026;)?amp;)?'.'\w+=[^&]+)*'.'$|', $url)) { + $query = $url; + $url = ''; + $fragment = ''; + + // parse the $url into $matches + // [1] path + // [2] query string, if any + // [3] anchor fragment, if any + } else if (preg_match('|^'.'([^?]*)'.'((?:\\?[^#]*)?)'.'((?:#.*)?)'.'$|', $url, $matches)) { + $url = $matches[1]; + $query = $matches[2]; + $fragment = $matches[3]; + + // these appears to be no query or fragment in this url + } else { + $query = ''; + $fragment = ''; + } + + if ($url) { + $url = hotpot_convert_url($baseurl, $reference, $url, false); + } + + if ($query) { + $search = '#'.'(file|src|thesound)='."([^&]+)".'#ise'; + $replace = "'\\1='.hotpot_convert_url('".$baseurl."','".$reference."','\\2')"; + $query = preg_replace($search, $replace, $query); + } + + $url = $opentag.$url.$query.$fragment.$closetag; + + return $url; } function hotpot_convert_url($baseurl, $reference, $url, $stripslashes=true) { - // maintain a cache of converted urls - static $HOTPOT_RELATIVE_URLS = array(); - - if ($stripslashes) { - $url = stripslashes($url); - } - - // is this an absolute url? (or javascript pseudo url) - if (preg_match('%^(http://|/|javascript:)%i', $url)) { - // do nothing - - // has this relative url already been converted? - } else if (isset($HOTPOT_RELATIVE_URLS[$url])) { - $url = $HOTPOT_RELATIVE_URLS[$url]; - - } else { - $relativeurl = $url; - - // get the subdirectory, $dir, of the quiz $reference - $dir = dirname($reference); - - // allow for leading "./" and "../" - while (preg_match('|^(\.{1,2})/(.*)$|', $url, $matches)) { - if ($matches[1]=='..') { - $dir = dirname($dir); - } - $url = $matches[2]; - } - - // add subdirectory, $dir, to $baseurl, if necessary - if ($dir && $dir<>'.') { - $baseurl .= "$dir/"; - } - - // prefix $url with $baseurl - $url = "$baseurl$url"; - - // add url to cache - $HOTPOT_RELATIVE_URLS[$relativeurl] = $url; - } - return $url; + // maintain a cache of converted urls + static $HOTPOT_RELATIVE_URLS = array(); + + if ($stripslashes) { + $url = stripslashes($url); + } + + // is this an absolute url? (or javascript pseudo url) + if (preg_match('%^(http://|/|javascript:)%i', $url)) { + // do nothing + + // has this relative url already been converted? + } else if (isset($HOTPOT_RELATIVE_URLS[$url])) { + $url = $HOTPOT_RELATIVE_URLS[$url]; + + } else { + $relativeurl = $url; + + // get the subdirectory, $dir, of the quiz $reference + $dir = dirname($reference); + + // allow for leading "./" and "../" + while (preg_match('|^(\.{1,2})/(.*)$|', $url, $matches)) { + if ($matches[1]=='..') { + $dir = dirname($dir); + } + $url = $matches[2]; + } + + // add subdirectory, $dir, to $baseurl, if necessary + if ($dir && $dir<>'.') { + $baseurl .= "$dir/"; + } + + // prefix $url with $baseurl + $url = "$baseurl$url"; + + // add url to cache + $HOTPOT_RELATIVE_URLS[$relativeurl] = $url; + } + return $url; } // =================================================== @@ -1828,481 +1828,481 @@ function hotpot_convert_url($baseurl, $reference, $url, $stripslashes=true) { function hotpot_add_attempt_details(&$attempt) { - // encode ampersands so that HTML entities are preserved in the XML parser - // N.B. ampersands inside blocks do NOT need to be encoded - - $old = &$attempt->details; // shortcut to "old" details - $new = ''; - $str_start = 0; - while (($cdata_start = strpos($old, '', $cdata_start))) { - $cdata_end += 3; - $new .= str_replace('&', '&', substr($old, $str_start, $cdata_start-$str_start)).substr($old, $cdata_start, $cdata_end-$cdata_start); - $str_start = $cdata_end; - } - $new .= str_replace('&', '&', substr($old, $str_start)); - unset($old); - - // parse the attempt details as xml - $details = new hotpot_xml_tree($new, "['hpjsresult']['#']"); - - $num = -1; - $q_num = -1; - $question = NULL; - $reponse = NULL; - - $i = 0; - $tags = 'fields,field'; - - while (($field="[$i]['#']") && $details->xml_value($tags, $field)) { - - $name = $details->xml_value($tags, $field."['fieldname'][0]['#']"); - $data = $details->xml_value($tags, $field."['fielddata'][0]['#']"); - - // parse the field name into $matches - // [1] quiz type - // [2] attempt detail name - if (preg_match('/^(\w+?)_(\w+)$/', $name, $matches)) { - $quiztype = strtolower($matches[1]); - $name = strtolower($matches[2]); - - // parse the attempt detail $name into $matches - // [1] question number - // [2] question detail name - if (preg_match('/^q(\d+)_(\w+)$/', $name, $matches)) { - $num = $matches[1]; - $name = strtolower($matches[2]); - $data = addslashes($data); - - // adjust JCross question numbers - if (preg_match('/^(across|down)(.*)$/', $name, $matches)) { - $num .= '_'.$matches[1]; // e.g. 01_across, 02_down - $name = $matches[2]; - if (substr($name, 0, 1)=='_') { - $name = substr($name, 1); // remove leading '_' - } - } - - // is this a new question (or the first one)? - if ($q_num<>$num) { - - // add previous question and response, if any - hotpot_add_response($attempt, $question, $response); - - // initialize question object - $question = NULL; - $question->name = ''; - $question->text = ''; - $question->hotpot = $attempt->hotpot; - - // initialize response object - $response = NULL; - $response->attempt = $attempt->id; - - // update question number - $q_num = $num; - } - - // adjust field name and value, and set question type - // (may not be necessary one day) - hotpot_adjust_response_field($quiztype, $question, $num, $name, $data); - - // add $data to the question/response details - switch ($name) { - case 'name': - case 'type': - $question->$name = $data; - break; - case 'text': - $question->$name = hotpot_string_id($data); - break; - - case 'correct': - case 'ignored': - case 'wrong': - $response->$name = hotpot_string_ids($data); - break; - - case 'score': - case 'weighting': - case 'hints': - case 'clues': - case 'checks': - $response->$name = intval($data); - break; - } - - } else { // attempt details - - // adjust field name and value - hotpot_adjust_response_field($quiztype, $question, $num='', $name, $data); - - // add $data to the attempt details - if ($name=='penalties') { - $attempt->$name = intval($data); - } - } - } - - $i++; - } // end while - - // add the final question and response, if any - hotpot_add_response($attempt, $question, $response); + // encode ampersands so that HTML entities are preserved in the XML parser + // N.B. ampersands inside blocks do NOT need to be encoded + + $old = &$attempt->details; // shortcut to "old" details + $new = ''; + $str_start = 0; + while (($cdata_start = strpos($old, '', $cdata_start))) { + $cdata_end += 3; + $new .= str_replace('&', '&', substr($old, $str_start, $cdata_start-$str_start)).substr($old, $cdata_start, $cdata_end-$cdata_start); + $str_start = $cdata_end; + } + $new .= str_replace('&', '&', substr($old, $str_start)); + unset($old); + + // parse the attempt details as xml + $details = new hotpot_xml_tree($new, "['hpjsresult']['#']"); + + $num = -1; + $q_num = -1; + $question = NULL; + $reponse = NULL; + + $i = 0; + $tags = 'fields,field'; + + while (($field="[$i]['#']") && $details->xml_value($tags, $field)) { + + $name = $details->xml_value($tags, $field."['fieldname'][0]['#']"); + $data = $details->xml_value($tags, $field."['fielddata'][0]['#']"); + + // parse the field name into $matches + // [1] quiz type + // [2] attempt detail name + if (preg_match('/^(\w+?)_(\w+)$/', $name, $matches)) { + $quiztype = strtolower($matches[1]); + $name = strtolower($matches[2]); + + // parse the attempt detail $name into $matches + // [1] question number + // [2] question detail name + if (preg_match('/^q(\d+)_(\w+)$/', $name, $matches)) { + $num = $matches[1]; + $name = strtolower($matches[2]); + $data = addslashes($data); + + // adjust JCross question numbers + if (preg_match('/^(across|down)(.*)$/', $name, $matches)) { + $num .= '_'.$matches[1]; // e.g. 01_across, 02_down + $name = $matches[2]; + if (substr($name, 0, 1)=='_') { + $name = substr($name, 1); // remove leading '_' + } + } + + // is this a new question (or the first one)? + if ($q_num<>$num) { + + // add previous question and response, if any + hotpot_add_response($attempt, $question, $response); + + // initialize question object + $question = NULL; + $question->name = ''; + $question->text = ''; + $question->hotpot = $attempt->hotpot; + + // initialize response object + $response = NULL; + $response->attempt = $attempt->id; + + // update question number + $q_num = $num; + } + + // adjust field name and value, and set question type + // (may not be necessary one day) + hotpot_adjust_response_field($quiztype, $question, $num, $name, $data); + + // add $data to the question/response details + switch ($name) { + case 'name': + case 'type': + $question->$name = $data; + break; + case 'text': + $question->$name = hotpot_string_id($data); + break; + + case 'correct': + case 'ignored': + case 'wrong': + $response->$name = hotpot_string_ids($data); + break; + + case 'score': + case 'weighting': + case 'hints': + case 'clues': + case 'checks': + $response->$name = intval($data); + break; + } + + } else { // attempt details + + // adjust field name and value + hotpot_adjust_response_field($quiztype, $question, $num='', $name, $data); + + // add $data to the attempt details + if ($name=='penalties') { + $attempt->$name = intval($data); + } + } + } + + $i++; + } // end while + + // add the final question and response, if any + hotpot_add_response($attempt, $question, $response); } function hotpot_add_response(&$attempt, &$question, &$response) { - global $db, $next_url; + global $db, $next_url; - $loopcount = 1; + $loopcount = 1; - $looping = isset($question) && isset($question->name) && isset($response); - while ($looping) { + $looping = isset($question) && isset($question->name) && isset($response); + while ($looping) { - if ($loopcount==1) { - $questionname = $question->name; - } + if ($loopcount==1) { + $questionname = $question->name; + } - if (!$question->id = get_field('hotpot_questions', 'id', 'name', $question->name, 'hotpot', $attempt->hotpot)) { - // add question record - if (!$question->id = insert_record('hotpot_questions', $question)) { - error("Could not add question record (attempt_id=$attempt->id): ".$db->ErrorMsg(), $next_url); - } - } + if (!$question->id = get_field('hotpot_questions', 'id', 'name', $question->name, 'hotpot', $attempt->hotpot)) { + // add question record + if (!$question->id = insert_record('hotpot_questions', $question)) { + error("Could not add question record (attempt_id=$attempt->id): ".$db->ErrorMsg(), $next_url); + } + } - if (record_exists('hotpot_responses', 'attempt', $attempt->id, 'question', $question->id)) { - // there is already a response to this question for this attempt - // probably because this quiz has two questions with the same text - // e.g. Which one of these answers is correct? + if (record_exists('hotpot_responses', 'attempt', $attempt->id, 'question', $question->id)) { + // there is already a response to this question for this attempt + // probably because this quiz has two questions with the same text + // e.g. Which one of these answers is correct? - // To workaround this, we create new question names - // e.g. Which one of these answers is correct? (2) - // until we get a question name for which there is no response yet on this attempt + // To workaround this, we create new question names + // e.g. Which one of these answers is correct? (2) + // until we get a question name for which there is no response yet on this attempt - $loopcount++; - $question->name = "$questionname ($loopcount)"; + $loopcount++; + $question->name = "$questionname ($loopcount)"; - // This method fails to correctly identify questions in - // quizzes which allow questions to be shuffled or omitted. - // As yet, there is no workaround for such cases. + // This method fails to correctly identify questions in + // quizzes which allow questions to be shuffled or omitted. + // As yet, there is no workaround for such cases. - } else { - $response->question = $question->id; + } else { + $response->question = $question->id; - // add response record - if(!$response->id = insert_record('hotpot_responses', $response)) { - error("Could not add response record (attempt_id=$attempt->id, question_id=$question->id): ".$db->ErrorMsg(), $next_url); - } + // add response record + if(!$response->id = insert_record('hotpot_responses', $response)) { + error("Could not add response record (attempt_id=$attempt->id, question_id=$question->id): ".$db->ErrorMsg(), $next_url); + } - // we can stop looping now - $looping = false; - } - } // end while + // we can stop looping now + $looping = false; + } + } // end while } function hotpot_adjust_response_field($quiztype, &$question, &$num, &$name, &$data) { - switch ($quiztype) { - case 'jbc': - $question->type = HOTPOT_JCB; - switch ($name) { - case 'right': - $name = 'correct'; - break; - } - break; - case 'jcloze': - $question->type = HOTPOT_JCLOZE; - if (is_numeric($num)) { - $question->name = $num; - } - switch ($name) { - case 'penalties': - if (is_numeric($num)) { - $name = 'checks'; - if (is_numeric($data)) { - $data++; - } - } - break; - case 'clue_shown': - $name = 'clues'; - $data = ($data=='YES' ? 1 : 0); - break; - case 'clue_text': - $name = 'text'; - break; - } - break; - case 'jcross': - $question->type = HOTPOT_JCROSS; - $question->name = $num; - switch ($name) { - case '': // HotPot v2.0.x - $name = 'correct'; - break; - case 'clue': - $name = 'text'; - break; - } - break; - case 'jmatch': - $question->type = HOTPOT_JMATCH; - switch ($name) { - case 'attempts': - $name = 'penalties'; - if (is_numeric($data) && $data>0) { - $data--; - } - break; - case 'lhs': - $name = 'name'; - break; - case 'rhs': - $name = 'correct'; - break; - } - break; - case 'jmix': - $question->type = HOTPOT_JMIX; - $question->name = $num; - switch ($name) { - // keep these in for "restore" of courses - // which were backed up with HotPot v2.0.x - case 'wrongguesses': - $name = 'checks'; - if (is_numeric($data)) { - $data++; - } - break; - case 'right': - $name = 'correct'; - break; - } - break; - break; - case 'jquiz': - switch ($name) { - case 'type': - $data = HOTPOT_JQUIZ; - switch ($data) { - case 'multiple-choice': - $data .= '.'.HOTPOT_JQUIZ_MULTICHOICE; - break; - case 'short-answer': - $data .= '.'.HOTPOT_JQUIZ_SHORTANSWER; - break; - case 'hybrid': - $data .= '.'.HOTPOT_JQUIZ_HYBRID; - break; - case 'multi-select': - $data .= '.'.HOTPOT_JQUIZ_MULTISELECT; - case 'n/a': - default: - // do nothing more - break; - } - break; - case 'question': - $name = 'name'; - break; - } - break; - - case 'rhubarb': - $question->type = HOTPOT_TEXTOYS_RHUBARB; - if (empty($question->name)) { - $question->name = $num; - } - break; - - case 'sequitur': - $question->type = HOTPOT_TEXTOYS_SEQUITUR; - break; - } + switch ($quiztype) { + case 'jbc': + $question->type = HOTPOT_JCB; + switch ($name) { + case 'right': + $name = 'correct'; + break; + } + break; + case 'jcloze': + $question->type = HOTPOT_JCLOZE; + if (is_numeric($num)) { + $question->name = $num; + } + switch ($name) { + case 'penalties': + if (is_numeric($num)) { + $name = 'checks'; + if (is_numeric($data)) { + $data++; + } + } + break; + case 'clue_shown': + $name = 'clues'; + $data = ($data=='YES' ? 1 : 0); + break; + case 'clue_text': + $name = 'text'; + break; + } + break; + case 'jcross': + $question->type = HOTPOT_JCROSS; + $question->name = $num; + switch ($name) { + case '': // HotPot v2.0.x + $name = 'correct'; + break; + case 'clue': + $name = 'text'; + break; + } + break; + case 'jmatch': + $question->type = HOTPOT_JMATCH; + switch ($name) { + case 'attempts': + $name = 'penalties'; + if (is_numeric($data) && $data>0) { + $data--; + } + break; + case 'lhs': + $name = 'name'; + break; + case 'rhs': + $name = 'correct'; + break; + } + break; + case 'jmix': + $question->type = HOTPOT_JMIX; + $question->name = $num; + switch ($name) { + // keep these in for "restore" of courses + // which were backed up with HotPot v2.0.x + case 'wrongguesses': + $name = 'checks'; + if (is_numeric($data)) { + $data++; + } + break; + case 'right': + $name = 'correct'; + break; + } + break; + break; + case 'jquiz': + switch ($name) { + case 'type': + $data = HOTPOT_JQUIZ; + switch ($data) { + case 'multiple-choice': + $data .= '.'.HOTPOT_JQUIZ_MULTICHOICE; + break; + case 'short-answer': + $data .= '.'.HOTPOT_JQUIZ_SHORTANSWER; + break; + case 'hybrid': + $data .= '.'.HOTPOT_JQUIZ_HYBRID; + break; + case 'multi-select': + $data .= '.'.HOTPOT_JQUIZ_MULTISELECT; + case 'n/a': + default: + // do nothing more + break; + } + break; + case 'question': + $name = 'name'; + break; + } + break; + + case 'rhubarb': + $question->type = HOTPOT_TEXTOYS_RHUBARB; + if (empty($question->name)) { + $question->name = $num; + } + break; + + case 'sequitur': + $question->type = HOTPOT_TEXTOYS_SEQUITUR; + break; + } } function hotpot_string_ids($field_value) { - $ids = array(); - $strings = explode(',', $field_value); - foreach($strings as $str) { - if ($id = hotpot_string_id($str)) { - $ids[] = $id; - } - } - return implode(',', $ids); + $ids = array(); + $strings = explode(',', $field_value); + foreach($strings as $str) { + if ($id = hotpot_string_id($str)) { + $ids[] = $id; + } + } + return implode(',', $ids); } function hotpot_string_id($str) { - $id = ''; - if (isset($str) && $str<>'') { - - // get the id from the table if it is already there - if (!$id = get_field('hotpot_strings', 'id', 'string', $str)) { - - // create a string record - $record = NULL; - $record->string = $str; - - // try and add the new string record - if (!$id = insert_record('hotpot_strings', $record)) { - global $db; - error("Could not add string record for '".htmlspecialchars($str)."': ".$db->ErrorMsg()); - } - } - } - return $id; + $id = ''; + if (isset($str) && $str<>'') { + + // get the id from the table if it is already there + if (!$id = get_field('hotpot_strings', 'id', 'string', $str)) { + + // create a string record + $record = NULL; + $record->string = $str; + + // try and add the new string record + if (!$id = insert_record('hotpot_strings', $record)) { + global $db; + error("Could not add string record for '".htmlspecialchars($str)."': ".$db->ErrorMsg()); + } + } + } + return $id; } if (!function_exists('file_get_contents')) { - // add this function for php version<4.3 - function file_get_contents($filepath) { - $contents = file($filepath); - if (is_array($contents)) { - $contents = implode('', $contents); - } - return $contents; - } + // add this function for php version<4.3 + function file_get_contents($filepath) { + $contents = file($filepath); + if (is_array($contents)) { + $contents = implode('', $contents); + } + return $contents; + } } if (!function_exists('html_entity_decode')) { - // add this function for php version<4.3 - function html_entity_decode($str) { - $t = get_html_translation_table(HTML_ENTITIES); - $t = array_flip($t); - return strtr($str, $t); - } + // add this function for php version<4.3 + function html_entity_decode($str) { + $t = get_html_translation_table(HTML_ENTITIES); + $t = array_flip($t); + return strtr($str, $t); + } } // required for Moodle 1.x if (!isset($CFG->pixpath)) { - $CFG->pixpath = "$CFG->wwwroot/pix"; + $CFG->pixpath = "$CFG->wwwroot/pix"; } if (!function_exists('fullname')) { - // add this function for Moodle 1.x - function fullname($user) { - return "$user->firstname $user->lastname"; - } + // add this function for Moodle 1.x + function fullname($user) { + return "$user->firstname $user->lastname"; + } } if (!function_exists('get_user_preferences')) { - // add this function for Moodle 1.x - function get_user_preferences($name=NULL, $default=NULL, $userid=NULL) { - return $default; - } + // add this function for Moodle 1.x + function get_user_preferences($name=NULL, $default=NULL, $userid=NULL) { + return $default; + } } if (!function_exists('set_user_preference')) { - // add this function for Moodle 1.x - function set_user_preference($name, $value, $otheruser=NULL) { - return false; - } + // add this function for Moodle 1.x + function set_user_preference($name, $value, $otheruser=NULL) { + return false; + } } function hotpot_utf8_to_html_entity($char) { - // http://www.zend.com/codex.php?id=835&single=1 - - // array used to figure what number to decrement from character order value - // according to number of characters used to map unicode to ascii by utf-8 - static $HOTPOT_UTF8_DECREMENT = array( - 1=>0, 2=>192, 3=>224, 4=>240 - ); - - // the number of bits to shift each character by - static $HOTPOT_UTF8_SHIFT = array( - 1=>array(0=>0), - 2=>array(0=>6, 1=>0), - 3=>array(0=>12, 1=>6, 2=>0), - 4=>array(0=>18, 1=>12, 2=>6, 3=>0) - ); - - $dec = 0; - $len = strlen($char); - for ($pos=0; $pos<$len; $pos++) { - $ord = ord ($char{$pos}); - $ord -= ($pos ? 128 : $HOTPOT_UTF8_DECREMENT[$len]); - $dec += ($ord << $HOTPOT_UTF8_SHIFT[$len][$pos]); - } - return '&#x'.sprintf('%04X', $dec).';'; + // http://www.zend.com/codex.php?id=835&single=1 + + // array used to figure what number to decrement from character order value + // according to number of characters used to map unicode to ascii by utf-8 + static $HOTPOT_UTF8_DECREMENT = array( + 1=>0, 2=>192, 3=>224, 4=>240 + ); + + // the number of bits to shift each character by + static $HOTPOT_UTF8_SHIFT = array( + 1=>array(0=>0), + 2=>array(0=>6, 1=>0), + 3=>array(0=>12, 1=>6, 2=>0), + 4=>array(0=>18, 1=>12, 2=>6, 3=>0) + ); + + $dec = 0; + $len = strlen($char); + for ($pos=0; $pos<$len; $pos++) { + $ord = ord ($char{$pos}); + $ord -= ($pos ? 128 : $HOTPOT_UTF8_DECREMENT[$len]); + $dec += ($ord << $HOTPOT_UTF8_SHIFT[$len][$pos]); + } + return '&#x'.sprintf('%04X', $dec).';'; } function hotpot_print_show_links($course, $location, $reference, $actions='', $spacer='   ', $new_window=false) { - global $CFG; - if (is_string($actions)) { - if (empty($actions)) { - $actions = 'showxmlsource,showxmltree,showhtmlsource'; - } - $actions = explode(',', $actions); - } - $strenterafilename = get_string('enterafilename', 'hotpot'); - $html = << END_OF_SCRIPT; - foreach ($actions as $action) { - $html .= $spacer - . ''.get_string($action, 'hotpot').'' - ; - } - print ''.$html.''; + foreach ($actions as $action) { + $html .= $spacer + . ''.get_string($action, 'hotpot').'' + ; + } + print ''.$html.''; } ?> diff --git a/mod/hotpot/mod.html b/mod/hotpot/mod.html index 7941e23459..a296bdf0d1 100644 --- a/mod/hotpot/mod.html +++ b/mod/hotpot/mod.html @@ -11,309 +11,309 @@ set_form_fields($form); // commonly used array of
    - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
    :mode=='add') { - choose_from_menu($text_source_options, "namesource", "$form->namesource", ""); - } else { - print ''; - } - print ''; - print ''; - print ''; - ?>
    - :
    - '; - helpbutton("writing", get_string("helpwriting"), "moodle", true, true); - print '
    '; - if (isset($usehtmleditor) && $usehtmleditor) { - helpbutton("richtext", get_string("helprichtext"), "moodle", true, true); - print '
    '; - } else { - helpbutton("text", get_string("helptext"), "moodle", true, true); - print '
    '; - emoticonhelpbutton("form", "description"); - print '
    '; - } - ?>
    -
    mode=='add') { - choose_from_menu($text_source_options, "summarysource", "$form->summarysource", ""); - } else { - print ''; - } - print ''; - if (function_exists("print_textarea") && isset($usehtmleditor)) { - print_textarea($usehtmleditor, 10, 65, 680, 400, "summary", $form->summary); - } else { - // Moodle 1.1.1 (original size was rows="5" cols="50") - print ''; - } - print ''; - ?>
    : get_string("alwaysopen", "hotpot"), - HOTPOT_YES => get_string("specifictime", "hotpot") - ); - choose_from_menu($options, "enabletimeopen", "$form->enabletimeopen", ""); - print ''; - print '   '; - if (!$form->timeopen && $course->format == "weeks") { - $form->timeopen= $course->startdate + (($form->section - 1) * 608400); - } - print_date_selector("openday", "openmonth", "openyear", $form->timeopen); - print ' - '; - print_time_selector("openhour", "openminute", $form->timeopen); - helpbutton("timeopen", get_string("quizopen","quiz"), "quiz"); - print ''; - ?>
    : get_string("neverclosed", "hotpot"), - HOTPOT_YES => get_string("specifictime", "hotpot") - ); - choose_from_menu($options, "enabletimeclose", "$form->enabletimeclose", ""); - print ''; - print '   '; - if (!$form->timeclose && $course->format == "weeks") { - $form->timeclose= $course->startdate + (($form->section) * 608400); - } - print_date_selector("closeday", "closemonth", "closeyear", $form->timeclose); - print ' - '; - print_time_selector("closehour", "closeminute", $form->timeclose); - helpbutton("timeopen", get_string("quizclose","quiz"), "quiz"); - print ''; - ?>
    - : - + :mode=='add') { + choose_from_menu($text_source_options, "namesource", "$form->namesource", ""); + } else { + print ''; + } + print ''; + print ''; + print ''; + ?>
    + :
    + '; + helpbutton("writing", get_string("helpwriting"), "moodle", true, true); + print '
    '; + if (isset($usehtmleditor) && $usehtmleditor) { + helpbutton("richtext", get_string("helprichtext"), "moodle", true, true); + print '
    '; + } else { + helpbutton("text", get_string("helptext"), "moodle", true, true); + print '
    '; + emoticonhelpbutton("form", "description"); + print '
    '; + } + ?>
    +
    mode=='add') { + choose_from_menu($text_source_options, "summarysource", "$form->summarysource", ""); + } else { + print ''; + } + print ''; + if (function_exists("print_textarea") && isset($usehtmleditor)) { + print_textarea($usehtmleditor, 10, 65, 680, 400, "summary", $form->summary); + } else { + // Moodle 1.1.1 (original size was rows="5" cols="50") + print ''; + } + print ''; + ?>
    : get_string("alwaysopen", "hotpot"), + HOTPOT_YES => get_string("specifictime", "hotpot") + ); + choose_from_menu($options, "enabletimeopen", "$form->enabletimeopen", ""); + print ''; + print '   '; + if (!$form->timeopen && $course->format == "weeks") { + $form->timeopen= $course->startdate + (($form->section - 1) * 608400); + } + print_date_selector("openday", "openmonth", "openyear", $form->timeopen); + print ' - '; + print_time_selector("openhour", "openminute", $form->timeopen); + helpbutton("timeopen", get_string("quizopen","quiz"), "quiz"); + print ''; + ?>
    : get_string("neverclosed", "hotpot"), + HOTPOT_YES => get_string("specifictime", "hotpot") + ); + choose_from_menu($options, "enabletimeclose", "$form->enabletimeclose", ""); + print ''; + print '   '; + if (!$form->timeclose && $course->format == "weeks") { + $form->timeclose= $course->startdate + (($form->section) * 608400); + } + print_date_selector("closeday", "closemonth", "closeyear", $form->timeclose); + print ' - '; + print_time_selector("closehour", "closeminute", $form->timeclose); + helpbutton("timeopen", get_string("quizclose","quiz"), "quiz"); + print ''; + ?>
    + : + id==$site->id) { - $id = $site->id; - $location = HOTPOT_LOCATION_SITEFILES; - } else { - $id = "'+(getObjValue(this.form.location)==".HOTPOT_LOCATION_SITEFILES."?".$site->id.":".$course->id.")+'"; - $location = ''; - } - } else { // ordinary teacher or content creator - $id = $course->id; - $location = HOTPOT_LOCATION_COURSEFILES; - } + if (isadmin()) { + $site = get_site(); + if ($course->id==$site->id) { + $id = $site->id; + $location = HOTPOT_LOCATION_SITEFILES; + } else { + $id = "'+(getObjValue(this.form.location)==".HOTPOT_LOCATION_SITEFILES."?".$site->id.":".$course->id.")+'"; + $location = ''; + } + } else { // ordinary teacher or content creator + $id = $course->id; + $location = HOTPOT_LOCATION_COURSEFILES; + } - if (array_key_exists($location, $HOTPOT_LOCATION)) { - print ''; - print ''.$HOTPOT_LOCATION[$location].'   '; + if (array_key_exists($location, $HOTPOT_LOCATION)) { + print ''; + print ''.$HOTPOT_LOCATION[$location].'   '; - } else { // admin can select from "site" or "course" files - choose_from_menu($HOTPOT_LOCATION, "location", "$form->location", ""); - } + } else { // admin can select from "site" or "course" files + choose_from_menu($HOTPOT_LOCATION, "location", "$form->location", ""); + } - if (function_exists("button_to_popup_window")) { + if (function_exists("button_to_popup_window")) { - // use javascript to extract wdir from the reference field - $wdir = "'+getDir(getObjValue(this.form.reference))+'"; + // use javascript to extract wdir from the reference field + $wdir = "'+getDir(getObjValue(this.form.reference))+'"; - // set button url depending on Moodle version - if ($CFG->version < 2004083125) { // version may need refining - // up to and including Moodle 1.4.1 - $url = "/mod/resource/coursefiles.php?id=$id&wdir=$wdir"; - } else { - // Moodle 1.4.2 and beyond - $url = "/files/index.php?id=$id&wdir=$wdir&choose=form.reference"; - } + // set button url depending on Moodle version + if ($CFG->version < 2004083125) { // version may need refining + // up to and including Moodle 1.4.1 + $url = "/mod/resource/coursefiles.php?id=$id&wdir=$wdir"; + } else { + // Moodle 1.4.2 and beyond + $url = "/files/index.php?id=$id&wdir=$wdir&choose=form.reference"; + } - $strchooseafile = get_string("chooseafile", "resource"); - button_to_popup_window ($url, 'coursefiles', $strchooseafile, 500, 750, $strchooseafile); - } - ?>
    - : - reference.'"> '; + $strchooseafile = get_string("chooseafile", "resource"); + button_to_popup_window ($url, 'coursefiles', $strchooseafile, 500, 750, $strchooseafile); + } + ?>
    + : + reference.'"> '; - } else if (function_exists("get_directory_list")) { - // Moodle 1.1 (and perhaps some others) - $dirs = get_directory_list("$CFG->dataroot/$course->id"); - $options = array(); - foreach ($dirs as $dir) { - $options["$dir"] = $dir; - } - choose_from_menu ($options, "reference", $form->reference); + } else if (function_exists("get_directory_list")) { + // Moodle 1.1 (and perhaps some others) + $dirs = get_directory_list("$CFG->dataroot/$course->id"); + $options = array(); + foreach ($dirs as $dir) { + $options["$dir"] = $dir; + } + choose_from_menu ($options, "reference", $form->reference); - } else { - // a very old Moodle (may be none left :-) - print ' '; - } - print '
    '; - hotpot_print_show_links($form->course, $form->location, $form->reference, '', '   ', true); - ?>
    mode}quizchain"; - print_string($quizchain, "hotpot"); - ?>:quizchain, ""); - helpbutton($quizchain, get_string($quizchain,"hotpot"), "hotpot"); - ?>
    :outputformat", ""); - helpbutton("outputformat", get_string("outputformat","hotpot"), "hotpot"); - ?>
    :navigation", ""); - helpbutton("navigation", get_string("navigation","hotpot"), "hotpot"); - ?>
    :studentfeedback", ""); - print "studentfeedbackurl\">"; - helpbutton("studentfeedback", get_string("studentfeedback","hotpot"), "hotpot"); - ?>
    :forceplugins", ""); - helpbutton("forceplugins", get_string("forceplugins","hotpot"), "hotpot"); - ?>
    :shownextquiz", ""); - helpbutton("shownextquiz", get_string("shownextquiz","hotpot"), "hotpot"); - ?>
    :review", ""); - helpbutton("review", get_string("allowreview","quiz"), "quiz"); - ?>
    :=1; $i--) { - $options[$i] = $i; - } - $options[0] = get_string("nograde"); + } else { + // a very old Moodle (may be none left :-) + print ' '; + } + print '
    '; + hotpot_print_show_links($form->course, $form->location, $form->reference, '', '   ', true); + ?>
    mode}quizchain"; + print_string($quizchain, "hotpot"); + ?>:quizchain, ""); + helpbutton($quizchain, get_string($quizchain,"hotpot"), "hotpot"); + ?>
    :outputformat", ""); + helpbutton("outputformat", get_string("outputformat","hotpot"), "hotpot"); + ?>
    :navigation", ""); + helpbutton("navigation", get_string("navigation","hotpot"), "hotpot"); + ?>
    :studentfeedback", ""); + print "studentfeedbackurl\">"; + helpbutton("studentfeedback", get_string("studentfeedback","hotpot"), "hotpot"); + ?>
    :forceplugins", ""); + helpbutton("forceplugins", get_string("forceplugins","hotpot"), "hotpot"); + ?>
    :shownextquiz", ""); + helpbutton("shownextquiz", get_string("shownextquiz","hotpot"), "hotpot"); + ?>
    :review", ""); + helpbutton("review", get_string("allowreview","quiz"), "quiz"); + ?>
    :=1; $i--) { + $options[$i] = $i; + } + $options[0] = get_string("nograde"); - choose_from_menu($options, "grade", "$form->grade", ""); - helpbutton("maxgrade", get_string("maximumgrade"), "quiz"); - ?>
    :grademethod", ""); - helpbutton("grademethod", get_string("grademethod","quiz"), "quiz"); - ?>
    : get_string("attemptsunlimited", "quiz"), - 1 => '1 '.strtolower(get_string("attempt", "quiz")) - ); - for ($i=2; $i<=10; $i++) { - $options[$i] = "$i ".strtolower(get_string("attempts", "quiz")); - } - choose_from_menu($options, "attempts", "$form->attempts", ""); - helpbutton("attempts", get_string("attemptsallowed","quiz"), "quiz"); - ?>
    : - - -
    : - - -
    :clickreporting", ""); - helpbutton("clickreporting", get_string("clickreporting","hotpot"), "hotpot"); - ?>
      - - ">     - " />
    - release) && substr($CFG->release, 0, 3)>=1.5) { - $options = array( - HOTPOT_DISPLAYNEXT_QUIZ => get_string("displayhotpotnext", "hotpot"), - HOTPOT_DISPLAYNEXT_COURSE => get_string("displaycoursenext", "hotpot"), - HOTPOT_DISPLAYNEXT_INDEX => get_string("displayindexnext", "hotpot") - ); - choose_from_menu($options, "displaynext", "$form->displaynext", ""); - } else { - print ''."\n"; - } - ?> + choose_from_menu($options, "grade", "$form->grade", ""); + helpbutton("maxgrade", get_string("maximumgrade"), "quiz"); + ?>
    :grademethod", ""); + helpbutton("grademethod", get_string("grademethod","quiz"), "quiz"); + ?>
    : get_string("attemptsunlimited", "quiz"), + 1 => '1 '.strtolower(get_string("attempt", "quiz")) + ); + for ($i=2; $i<=10; $i++) { + $options[$i] = "$i ".strtolower(get_string("attempts", "quiz")); + } + choose_from_menu($options, "attempts", "$form->attempts", ""); + helpbutton("attempts", get_string("attemptsallowed","quiz"), "quiz"); + ?>
    : + + +
    : + + +
    :clickreporting", ""); + helpbutton("clickreporting", get_string("clickreporting","hotpot"), "hotpot"); + ?>
      + + ">     + " />
    + release) && substr($CFG->release, 0, 3)>=1.5) { + $options = array( + HOTPOT_DISPLAYNEXT_QUIZ => get_string("displayhotpotnext", "hotpot"), + HOTPOT_DISPLAYNEXT_COURSE => get_string("displaycoursenext", "hotpot"), + HOTPOT_DISPLAYNEXT_INDEX => get_string("displayindexnext", "hotpot") + ); + choose_from_menu($options, "displaynext", "$form->displaynext", ""); + } else { + print ''."\n"; + } + ?>
    @@ -333,121 +333,121 @@ $text_source_options = array( timeopen) ? HOTPOT_NO : HOTPOT_YES); - set_form_field($form, 'timeclose', get_user_preferences('hotpot_timeclose', 0)); - set_form_field($form, 'enabletimeclose', empty($form->timeclose) ? HOTPOT_NO : HOTPOT_YES); - set_form_field($form, 'location', HOTPOT_LOCATION_COURSEFILES); - set_form_field($form, 'reference'); - set_form_field($form, 'navigation', get_user_preferences('hotpot_navigation', HOTPOT_NAVIGATION_BAR)); - set_form_field($form, 'outputformat', get_user_preferences('hotpot_outputformat', HOTPOT_OUTPUTFORMAT_BEST)); - set_form_field($form, 'studentfeedback', get_user_preferences('hotpot_studentfeedback', HOTPOT_FEEDBACK_NONE)); - set_form_field($form, 'studentfeedbackurl', get_user_preferences('hotpot_studentfeedbackurl', 'http://')); - set_form_field($form, 'forceplugins', get_user_preferences('hotpot_forceplugins', HOTPOT_NO)); - if ($form->mode=='add') { - set_form_field($form, 'namesource', get_user_preferences('hotpot_namesource', HOTPOT_TEXTSOURCE_QUIZ)); - set_form_field($form, 'summarysource', get_user_preferences('hotpot_summarysource', HOTPOT_TEXTSOURCE_QUIZ)); - $quizchain = get_user_preferences('hotpot_quizchain', HOTPOT_NO); - } else { - $quizchain = empty($form->quizchain) ? HOTPOT_NO : HOTPOT_YES; - } - set_form_field($form, 'quizchain', $quizchain); - set_form_field($form, 'shownextquiz', get_user_preferences('hotpot_shownextquiz', HOTPOT_NO)); - set_form_field($form, 'review', get_user_preferences('hotpot_review', HOTPOT_YES)); - set_form_field($form, 'grade', get_user_preferences('hotpot_grade', 100)); - set_form_field($form, 'grademethod', get_user_preferences('hotpot_grademethod', HOTPOT_GRADEMETHOD_HIGHEST)); - set_form_field($form, 'attempts', get_user_preferences('hotpot_attempts', 0)); // 0=unlimited - set_form_field($form, 'password'); - set_form_field($form, 'subnet', get_user_preferences('hotpot_subnet')); - set_form_field($form, 'clickreporting', HOTPOT_NO); - set_form_field($form, 'displaynext', get_user_preferences('hotpot_displaynext', HOTPOT_DISPLAYNEXT_QUIZ)); + set_form_field($form, 'name'); + set_form_field($form, 'summary'); + set_form_field($form, 'timeopen', get_user_preferences('hotpot_timeopen', 0)); + set_form_field($form, 'enabletimeopen', empty($form->timeopen) ? HOTPOT_NO : HOTPOT_YES); + set_form_field($form, 'timeclose', get_user_preferences('hotpot_timeclose', 0)); + set_form_field($form, 'enabletimeclose', empty($form->timeclose) ? HOTPOT_NO : HOTPOT_YES); + set_form_field($form, 'location', HOTPOT_LOCATION_COURSEFILES); + set_form_field($form, 'reference'); + set_form_field($form, 'navigation', get_user_preferences('hotpot_navigation', HOTPOT_NAVIGATION_BAR)); + set_form_field($form, 'outputformat', get_user_preferences('hotpot_outputformat', HOTPOT_OUTPUTFORMAT_BEST)); + set_form_field($form, 'studentfeedback', get_user_preferences('hotpot_studentfeedback', HOTPOT_FEEDBACK_NONE)); + set_form_field($form, 'studentfeedbackurl', get_user_preferences('hotpot_studentfeedbackurl', 'http://')); + set_form_field($form, 'forceplugins', get_user_preferences('hotpot_forceplugins', HOTPOT_NO)); + if ($form->mode=='add') { + set_form_field($form, 'namesource', get_user_preferences('hotpot_namesource', HOTPOT_TEXTSOURCE_QUIZ)); + set_form_field($form, 'summarysource', get_user_preferences('hotpot_summarysource', HOTPOT_TEXTSOURCE_QUIZ)); + $quizchain = get_user_preferences('hotpot_quizchain', HOTPOT_NO); + } else { + $quizchain = empty($form->quizchain) ? HOTPOT_NO : HOTPOT_YES; + } + set_form_field($form, 'quizchain', $quizchain); + set_form_field($form, 'shownextquiz', get_user_preferences('hotpot_shownextquiz', HOTPOT_NO)); + set_form_field($form, 'review', get_user_preferences('hotpot_review', HOTPOT_YES)); + set_form_field($form, 'grade', get_user_preferences('hotpot_grade', 100)); + set_form_field($form, 'grademethod', get_user_preferences('hotpot_grademethod', HOTPOT_GRADEMETHOD_HIGHEST)); + set_form_field($form, 'attempts', get_user_preferences('hotpot_attempts', 0)); // 0=unlimited + set_form_field($form, 'password'); + set_form_field($form, 'subnet', get_user_preferences('hotpot_subnet')); + set_form_field($form, 'clickreporting', HOTPOT_NO); + set_form_field($form, 'displaynext', get_user_preferences('hotpot_displaynext', HOTPOT_DISPLAYNEXT_QUIZ)); } function set_form_field(&$form, $fieldname, $defaultvalue='') { - if (!isset($form->$fieldname)) { - $form->$fieldname = $defaultvalue; - } + if (!isset($form->$fieldname)) { + $form->$fieldname = $defaultvalue; + } } ?> diff --git a/mod/hotpot/report.php b/mod/hotpot/report.php index b800561879..7ad0b12d92 100644 --- a/mod/hotpot/report.php +++ b/mod/hotpot/report.php @@ -31,343 +31,343 @@ } } - // set homeurl of couse (for error messages) - $course_homeurl = "$CFG->wwwroot/course/view.php?id=$course->id"; - - require_login($course->id); - - // get report mode - if (isteacher($course->id)) { - $mode = optional_param("mode", "overview"); - } else { - // students have no choice - $mode = 'overview'; - } - - // assemble array of form data - $formdata = array( - 'mode' => $mode, - 'reportcourse' => isadmin() ? optional_param('reportcourse', get_user_preferences('hotpot_reportcourse', 'this')) : 'this', - 'reportusers' => isteacher($course->id) ? optional_param('reportusers', get_user_preferences('hotpot_reportusers', 'all')) : 'this', - 'reportattempts' => optional_param('reportattempts', get_user_preferences('hotpot_reportattempts', 'all')), - 'reportformat' => optional_param('reportformat', 'htm'), - 'reportshowlegend' => optional_param('reportshowlegend', get_user_preferences('hotpot_reportshowlegend', '0')), - 'reportencoding' => optional_param('reportencoding', get_user_preferences('hotpot_reportencoding', '')), - 'reportwrapdata' => optional_param('reportwrapdata', get_user_preferences('hotpot_reportwrapdata', '1')), - ); - - foreach ($formdata as $name=>$value) { - set_user_preference("hotpot_$name", $value); - } + // set homeurl of couse (for error messages) + $course_homeurl = "$CFG->wwwroot/course/view.php?id=$course->id"; + + require_login($course->id); + + // get report mode + if (isteacher($course->id)) { + $mode = optional_param("mode", "overview"); + } else { + // students have no choice + $mode = 'overview'; + } + + // assemble array of form data + $formdata = array( + 'mode' => $mode, + 'reportcourse' => isadmin() ? optional_param('reportcourse', get_user_preferences('hotpot_reportcourse', 'this')) : 'this', + 'reportusers' => isteacher($course->id) ? optional_param('reportusers', get_user_preferences('hotpot_reportusers', 'all')) : 'this', + 'reportattempts' => optional_param('reportattempts', get_user_preferences('hotpot_reportattempts', 'all')), + 'reportformat' => optional_param('reportformat', 'htm'), + 'reportshowlegend' => optional_param('reportshowlegend', get_user_preferences('hotpot_reportshowlegend', '0')), + 'reportencoding' => optional_param('reportencoding', get_user_preferences('hotpot_reportencoding', '')), + 'reportwrapdata' => optional_param('reportwrapdata', get_user_preferences('hotpot_reportwrapdata', '1')), + ); + + foreach ($formdata as $name=>$value) { + set_user_preference("hotpot_$name", $value); + } /// Start the report - add_to_log($course->id, "hotpot", "report", "report.php?id=$cm->id&mode=$mode", "$hotpot->id", "$cm->id"); - - // print page header. if required - if ($formdata['reportformat']=='htm') { - hotpot_print_report_heading($course, $cm, $hotpot, $mode); - if (isteacher($course->id)) { - hotpot_print_report_selector($course, $hotpot, $formdata); - } - } - - // delete selected attempts, if any - if (isteacher($course->id)) { - $del = optional_param("del", ""); - hotpot_delete_selected_attempts($hotpot, $del); - } - - $hotpot_ids = ''; - $course_ids = ''; - switch ($formdata['reportcourse']) { - case 'this': - $course_ids = $course->id; - $hotpot_ids = $hotpot->id; - break; - case 'all' : - $records = get_records_select_menu('user_teachers', "userid='$USER->id'", 'course', 'id, course'); - $course_ids = join(',', array_values($records)); - - $records = get_records_select_menu('hotpot', "reference='$hotpot->reference'", 'reference', 'id, reference'); - $hotpot_ids = join(',', array_keys($records)); - break; - } - - $user_ids = ''; - $users = array(); - switch ($formdata['reportusers']) { - case 'all': - $admin_ids = get_records_select_menu('user_admins'); - if (is_array($admin_ids)) { - $users = array_merge($users, $admin_ids); - } - $creator_ids = get_records_select_menu('user_coursecreators'); - if (is_array($creator_ids)) { - $users = array_merge($users, $creator_ids); - } - $teacher_ids = get_records_select_menu('user_teachers', "course IN ($course_ids)", 'course', 'id, userid'); - if (is_array($teacher_ids)) { - $users = array_merge($users, $teacher_ids); - } - $guest_id = get_records_select_menu('user', "username='guest'", '', 'id,id'); - if (is_array($guest_id)) { - $users = array_merge($users, $guest_id); - } - // add students next - - case 'students': - $student_ids = get_records_select_menu('user_students', "course IN ($course_ids)", 'course', 'id, userid'); - if (is_array($student_ids)) { - $users = array_merge($users, $student_ids); - } - $user_ids = array_values($users); - sort($user_ids); - $user_ids = join(',', array_unique($user_ids)); - break; - - case 'this': // current user only - $user_ids = $USER->id; - break; - - default: // specific user selected by teacher - if (is_numeric($formdata['reportusers'])) { - $user_ids = $formdata['reportusers']; - } - } - - if (empty($user_ids)) { - print_heading(get_string('nousersyet')); - exit; - } - - // database table and selection conditions - $table = "{$CFG->prefix}hotpot_attempts AS a"; - $select = "a.hotpot IN ($hotpot_ids) AND a.userid IN ($user_ids)"; - if ($mode!='overview') { - $select .= ' AND a.status<>'.HOTPOT_STATUS_INPROGRESS; - } - - // confine attempts if necessary - switch ($formdata['reportattempts']) { - case 'best': - $function = 'MAX'; - $fieldnames = array('score', 'id', 'clickreportid'); - $defaultvalue = 0; - break; - case 'first': - $function = 'MIN'; - $fieldnames = array('timefinish', 'id', 'clickreportid'); - $default_value = time(); - break; - case 'last': - $function = 'MAX'; - $fieldnames = array('timefinish', 'id', 'clickreportid'); - $defaultvalue = time(); - break; - default: // 'all' and any others - $function = ''; - $fieldnames = array(); - $defaultvalue = ''; - break; - } - if (empty($function) || empty($fieldnames)) { - // do nothing (i.e. get ALL attempts) - } else { - $groupby = 'userid'; - $records = hotpot_get_records_groupby($function, $fieldnames, $table, $select, $groupby); - - $ids = array(); - foreach ($records as $record) { - $ids[] = $record->clickreportid; - } - $select = "a.clickreportid IN (".join(',', $ids).")"; - } - - // pick out last attempt in each clickreport series - $cr_attempts = hotpot_get_records_groupby('MAX', array('timefinish', 'id'), $table, $select, 'clickreportid'); - - $fields = 'a.*, u.firstname, u.lastname, u.picture'; - if ($mode=='click') { - $fields .= ', u.idnumber'; - } else { - // overview, simple and detailed reports - // get last attempt record in clickreport series - $ids = array(); - foreach ($cr_attempts as $cr_attempt) { - $ids[] = $cr_attempt->id; - } - if (empty($ids)) { - $select = ""; - } else { - $ids = array_unique($ids); - sort($ids); - $select = "a.id IN (".join(',', $ids).")"; - } - } - - $attempts = array(); - - if ($select) { - // add user information to SQL query - $select .= ' AND a.userid = u.id'; - $table .= ", {$CFG->prefix}user AS u"; - $order = "u.lastname, a.attempt, a.timefinish"; - // get the attempts (at last!) - $attempts = get_records_sql("SELECT $fields FROM $table WHERE $select ORDER BY $order"); - } - - // stop now if no attempts were found - if (empty($attempts)) { - print_heading(get_string('noattempts','quiz')); - exit; - } - - // get the questions - if (!$questions = get_records_select('hotpot_questions', "hotpot='$hotpot->id'")) { - $questions = array(); - } - - // get grades - $grades = hotpot_get_grades($hotpot, $user_ids); - - // get list of attempts by user and set reference to last attempt in clickreport series - $users = array(); - foreach ($attempts as $id=>$attempt) { - - $userid = $attempt->userid; - - if (!isset($users[$userid])) { - $users[$userid]->grade = isset($grades[$userid]) ? $grades[$userid] : ' '; - $users[$userid]->attempts = array(); - } - - $users[$userid]->attempts[] = &$attempts[$id]; - - if ($mode=='click' && isset($cr_attempts[$id])) { - $attempts[$id]->cr_lastclick = $cr_attempts[$id]->id; - $attempts[$id]->cr_timefinish = $cr_attempts[$id]->timefinish; - } - } - - if ($mode!='overview') { - - // initialise details of responses to questions in these attempts - foreach ($attempts as $a=>$attempt) { - $attempts[$a]->responses = array(); - } - foreach ($questions as $q=>$question) { - $questions[$q]->attempts = array(); - } - - // get reponses to these attempts - $attempt_ids = join(',',array_keys($attempts)); - if (!$responses = get_records_sql("SELECT * FROM {$CFG->prefix}hotpot_responses WHERE attempt IN ($attempt_ids)")) { - $responses = array(); - } - - // ids of questions used in these responses - $questionids = array(); - - foreach ($responses as $response) { - // shortcuts to the attempt and question ids - $a = $response->attempt; - $q = $response->question; - - // check the attempt and question objects exist - // (if they don't exist, something is very wrong!) - if (isset($attempts[$a]) || isset($questions[$q])) { - - // add the response for this attempt - $attempts[$a]->responses[$q] = $response; - - // add a reference from the question to the attempt which includes this question - $questions[$q]->attempts[] = &$attempts[$a]; - - // flag this id as being used - $questionids[$q] = true; - } - } - - // remove unused questions - $questionids = array_keys($questionids); - foreach ($questions as $id=>$question) { - if (!in_array($id, $questionids)) { - unset($questions[$id]); - } - } - } + add_to_log($course->id, "hotpot", "report", "report.php?id=$cm->id&mode=$mode", "$hotpot->id", "$cm->id"); + + // print page header. if required + if ($formdata['reportformat']=='htm') { + hotpot_print_report_heading($course, $cm, $hotpot, $mode); + if (isteacher($course->id)) { + hotpot_print_report_selector($course, $hotpot, $formdata); + } + } + + // delete selected attempts, if any + if (isteacher($course->id)) { + $del = optional_param("del", ""); + hotpot_delete_selected_attempts($hotpot, $del); + } + + $hotpot_ids = ''; + $course_ids = ''; + switch ($formdata['reportcourse']) { + case 'this': + $course_ids = $course->id; + $hotpot_ids = $hotpot->id; + break; + case 'all' : + $records = get_records_select_menu('user_teachers', "userid='$USER->id'", 'course', 'id, course'); + $course_ids = join(',', array_values($records)); + + $records = get_records_select_menu('hotpot', "reference='$hotpot->reference'", 'reference', 'id, reference'); + $hotpot_ids = join(',', array_keys($records)); + break; + } + + $user_ids = ''; + $users = array(); + switch ($formdata['reportusers']) { + case 'all': + $admin_ids = get_records_select_menu('user_admins'); + if (is_array($admin_ids)) { + $users = array_merge($users, $admin_ids); + } + $creator_ids = get_records_select_menu('user_coursecreators'); + if (is_array($creator_ids)) { + $users = array_merge($users, $creator_ids); + } + $teacher_ids = get_records_select_menu('user_teachers', "course IN ($course_ids)", 'course', 'id, userid'); + if (is_array($teacher_ids)) { + $users = array_merge($users, $teacher_ids); + } + $guest_id = get_records_select_menu('user', "username='guest'", '', 'id,id'); + if (is_array($guest_id)) { + $users = array_merge($users, $guest_id); + } + // add students next + + case 'students': + $student_ids = get_records_select_menu('user_students', "course IN ($course_ids)", 'course', 'id, userid'); + if (is_array($student_ids)) { + $users = array_merge($users, $student_ids); + } + $user_ids = array_values($users); + sort($user_ids); + $user_ids = join(',', array_unique($user_ids)); + break; + + case 'this': // current user only + $user_ids = $USER->id; + break; + + default: // specific user selected by teacher + if (is_numeric($formdata['reportusers'])) { + $user_ids = $formdata['reportusers']; + } + } + + if (empty($user_ids)) { + print_heading(get_string('nousersyet')); + exit; + } + + // database table and selection conditions + $table = "{$CFG->prefix}hotpot_attempts AS a"; + $select = "a.hotpot IN ($hotpot_ids) AND a.userid IN ($user_ids)"; + if ($mode!='overview') { + $select .= ' AND a.status<>'.HOTPOT_STATUS_INPROGRESS; + } + + // confine attempts if necessary + switch ($formdata['reportattempts']) { + case 'best': + $function = 'MAX'; + $fieldnames = array('score', 'id', 'clickreportid'); + $defaultvalue = 0; + break; + case 'first': + $function = 'MIN'; + $fieldnames = array('timefinish', 'id', 'clickreportid'); + $default_value = time(); + break; + case 'last': + $function = 'MAX'; + $fieldnames = array('timefinish', 'id', 'clickreportid'); + $defaultvalue = time(); + break; + default: // 'all' and any others + $function = ''; + $fieldnames = array(); + $defaultvalue = ''; + break; + } + if (empty($function) || empty($fieldnames)) { + // do nothing (i.e. get ALL attempts) + } else { + $groupby = 'userid'; + $records = hotpot_get_records_groupby($function, $fieldnames, $table, $select, $groupby); + + $ids = array(); + foreach ($records as $record) { + $ids[] = $record->clickreportid; + } + $select = "a.clickreportid IN (".join(',', $ids).")"; + } + + // pick out last attempt in each clickreport series + $cr_attempts = hotpot_get_records_groupby('MAX', array('timefinish', 'id'), $table, $select, 'clickreportid'); + + $fields = 'a.*, u.firstname, u.lastname, u.picture'; + if ($mode=='click') { + $fields .= ', u.idnumber'; + } else { + // overview, simple and detailed reports + // get last attempt record in clickreport series + $ids = array(); + foreach ($cr_attempts as $cr_attempt) { + $ids[] = $cr_attempt->id; + } + if (empty($ids)) { + $select = ""; + } else { + $ids = array_unique($ids); + sort($ids); + $select = "a.id IN (".join(',', $ids).")"; + } + } + + $attempts = array(); + + if ($select) { + // add user information to SQL query + $select .= ' AND a.userid = u.id'; + $table .= ", {$CFG->prefix}user AS u"; + $order = "u.lastname, a.attempt, a.timefinish"; + // get the attempts (at last!) + $attempts = get_records_sql("SELECT $fields FROM $table WHERE $select ORDER BY $order"); + } + + // stop now if no attempts were found + if (empty($attempts)) { + print_heading(get_string('noattempts','quiz')); + exit; + } + + // get the questions + if (!$questions = get_records_select('hotpot_questions', "hotpot='$hotpot->id'")) { + $questions = array(); + } + + // get grades + $grades = hotpot_get_grades($hotpot, $user_ids); + + // get list of attempts by user and set reference to last attempt in clickreport series + $users = array(); + foreach ($attempts as $id=>$attempt) { + + $userid = $attempt->userid; + + if (!isset($users[$userid])) { + $users[$userid]->grade = isset($grades[$userid]) ? $grades[$userid] : ' '; + $users[$userid]->attempts = array(); + } + + $users[$userid]->attempts[] = &$attempts[$id]; + + if ($mode=='click' && isset($cr_attempts[$id])) { + $attempts[$id]->cr_lastclick = $cr_attempts[$id]->id; + $attempts[$id]->cr_timefinish = $cr_attempts[$id]->timefinish; + } + } + + if ($mode!='overview') { + + // initialise details of responses to questions in these attempts + foreach ($attempts as $a=>$attempt) { + $attempts[$a]->responses = array(); + } + foreach ($questions as $q=>$question) { + $questions[$q]->attempts = array(); + } + + // get reponses to these attempts + $attempt_ids = join(',',array_keys($attempts)); + if (!$responses = get_records_sql("SELECT * FROM {$CFG->prefix}hotpot_responses WHERE attempt IN ($attempt_ids)")) { + $responses = array(); + } + + // ids of questions used in these responses + $questionids = array(); + + foreach ($responses as $response) { + // shortcuts to the attempt and question ids + $a = $response->attempt; + $q = $response->question; + + // check the attempt and question objects exist + // (if they don't exist, something is very wrong!) + if (isset($attempts[$a]) || isset($questions[$q])) { + + // add the response for this attempt + $attempts[$a]->responses[$q] = $response; + + // add a reference from the question to the attempt which includes this question + $questions[$q]->attempts[] = &$attempts[$a]; + + // flag this id as being used + $questionids[$q] = true; + } + } + + // remove unused questions + $questionids = array_keys($questionids); + foreach ($questions as $id=>$question) { + if (!in_array($id, $questionids)) { + unset($questions[$id]); + } + } + } /// Open the selected hotpot report and display it - $mode = clean_param($mode, PARAM_SAFEDIR); + $mode = clean_param($mode, PARAM_SAFEDIR); - if (! is_readable("report/$mode/report.php")) { - error("Report not known (".clean_text($mode).")", $course_homeurl); - } + if (! is_readable("report/$mode/report.php")) { + error("Report not known (".clean_text($mode).")", $course_homeurl); + } - include("report/default.php"); // Parent class - include("report/$mode/report.php"); + include("report/default.php"); // Parent class + include("report/$mode/report.php"); - $report = new hotpot_report(); + $report = new hotpot_report(); - if (! $report->display($hotpot, $cm, $course, $users, $attempts, $questions, $formdata)) { - error("Error occurred during report processing!", $course_homeurl); - } + if (! $report->display($hotpot, $cm, $course, $users, $attempts, $questions, $formdata)) { + error("Error occurred during report processing!", $course_homeurl); + } - if ($formdata['reportformat']=='htm') { - print_footer($course); - } + if ($formdata['reportformat']=='htm') { + print_footer($course); + } ////////////////////////////////////////////// /// functions to delete attempts and responses function hotpot_grade_heading($hotpot, $formdata) { - global $HOTPOT_GRADEMETHOD; - $grademethod = $HOTPOT_GRADEMETHOD[$hotpot->grademethod]; - - if ($hotpot->grade!=100) { - $grademethod = "$hotpot->grade x $grademethod/100"; - } - if ($formdata['reportformat']=='htm') { - $grademethod = ''.$grademethod.''; - } - $nl = $formdata['reportformat']=='htm' ? '
    ' : "\n"; - return get_string('grade')."$nl($grademethod)"; + global $HOTPOT_GRADEMETHOD; + $grademethod = $HOTPOT_GRADEMETHOD[$hotpot->grademethod]; + + if ($hotpot->grade!=100) { + $grademethod = "$hotpot->grade x $grademethod/100"; + } + if ($formdata['reportformat']=='htm') { + $grademethod = ''.$grademethod.''; + } + $nl = $formdata['reportformat']=='htm' ? '
    ' : "\n"; + return get_string('grade')."$nl($grademethod)"; } function hotpot_delete_selected_attempts(&$hotpot, $del) { - $select = ''; - switch ($del) { - case 'all' : - $select = "hotpot='$hotpot->id'"; - break; - case 'abandoned': - $select = "hotpot='$hotpot->id' AND status=".HOTPOT_STATUS_ABANDONED; - break; - case 'selection': - $ids = (array)data_submitted(); - unset($ids['del']); - unset($ids['id']); - if (!empty($ids)) { - $select = "hotpot='$hotpot->id' AND clickreportid IN (".implode(',', $ids).")"; - } - break; - } - - // delete attempts using $select, if it is set - if ($select) { - - $table = 'hotpot_attempts'; - if ($attempts = get_records_select($table, $select)) { - - hotpot_delete_and_notify($table, $select, get_string('attempts', 'quiz')); - - $select = 'attempt IN ('.implode(',', array_keys($attempts)).')'; - hotpot_delete_and_notify('hotpot_details', $select, get_string('rawdetails', 'hotpot')); - hotpot_delete_and_notify('hotpot_responses', $select, get_string('answer', 'quiz')); - } - } + $select = ''; + switch ($del) { + case 'all' : + $select = "hotpot='$hotpot->id'"; + break; + case 'abandoned': + $select = "hotpot='$hotpot->id' AND status=".HOTPOT_STATUS_ABANDONED; + break; + case 'selection': + $ids = (array)data_submitted(); + unset($ids['del']); + unset($ids['id']); + if (!empty($ids)) { + $select = "hotpot='$hotpot->id' AND clickreportid IN (".implode(',', $ids).")"; + } + break; + } + + // delete attempts using $select, if it is set + if ($select) { + + $table = 'hotpot_attempts'; + if ($attempts = get_records_select($table, $select)) { + + hotpot_delete_and_notify($table, $select, get_string('attempts', 'quiz')); + + $select = 'attempt IN ('.implode(',', array_keys($attempts)).')'; + hotpot_delete_and_notify('hotpot_details', $select, get_string('rawdetails', 'hotpot')); + hotpot_delete_and_notify('hotpot_responses', $select, get_string('answer', 'quiz')); + } + } } @@ -376,239 +376,239 @@ function hotpot_delete_selected_attempts(&$hotpot, $del) { /// report selector menus function hotpot_print_report_heading(&$course, &$cm, &$hotpot, &$mode) { - $strmodulenameplural = get_string("modulenameplural", "hotpot"); - $strmodulename = get_string("modulename", "hotpot"); - - $title = "$course->shortname: $hotpot->name"; - $heading = "$course->fullname"; - - $navigation = "id>$strmodulenameplural -> "; - $navigation .= "id\">$hotpot->name -> "; - if (isteacher($course->id)) { - if ($mode=='overview' || $mode=='simplestat' || $mode=='fullstat') { - $module = "quiz"; - } else { - $module = "hotpot"; - } - $navigation .= get_string("report$mode", $module); - - } else { - $navigation .= get_string("report", "quiz"); - } - if ($course->category) { - $navigation = "id\">$course->shortname -> $navigation"; - } - $button = update_module_button($cm->id, $course->id, $strmodulename); - - print_header($title, $heading, $navigation, "", "", true, $button, navmenu($course, $cm)); - - print_heading($hotpot->name); + $strmodulenameplural = get_string("modulenameplural", "hotpot"); + $strmodulename = get_string("modulename", "hotpot"); + + $title = "$course->shortname: $hotpot->name"; + $heading = "$course->fullname"; + + $navigation = "id>$strmodulenameplural -> "; + $navigation .= "id\">$hotpot->name -> "; + if (isteacher($course->id)) { + if ($mode=='overview' || $mode=='simplestat' || $mode=='fullstat') { + $module = "quiz"; + } else { + $module = "hotpot"; + } + $navigation .= get_string("report$mode", $module); + + } else { + $navigation .= get_string("report", "quiz"); + } + if ($course->category) { + $navigation = "id\">$course->shortname -> $navigation"; + } + $button = update_module_button($cm->id, $course->id, $strmodulename); + + print_header($title, $heading, $navigation, "", "", true, $button, navmenu($course, $cm)); + + print_heading($hotpot->name); } function hotpot_print_report_selector(&$course, &$hotpot, &$formdata) { - global $CFG; - - $reports = hotpot_get_report_names('overview,simplestat,fullstat'); - - print '
    wwwroot/mod/hotpot/report.php?hp=$hotpot->id".'">'; - print ''; - - $menus = array(); - - $menus['mode'] = array(); - foreach ($reports as $name) { - if ($name=='overview' || $name=='simplestat' || $name=='fullstat') { - $module = "quiz"; // standard reports - } else if ($name=='click' && empty($hotpot->clickreporting)) { - $module = ""; // clickreporting is disabled - } else { - $module = "hotpot"; // custom reports - } - if ($module) { - $menus['mode'][$name] = get_string("report$name", $module); - } - } - if (isadmin()) { - $menus['reportcourse'] = array( - 'this' => get_string('thiscourse', 'hotpot'), // $course->shortname, - 'all' => get_string('allmycourses', 'hotpot') - ); - } - $menus['reportusers'] = array( - 'all' => get_string('allparticipants'), - 'students' => get_string('students') - ); - $users = get_records_sql(" - SELECT - u.* - FROM - {$CFG->prefix}user AS u, - {$CFG->prefix}user_students AS us - WHERE - u.id = us.userid AND us.course=$course->id - ORDER BY - u.lastname - "); - if ($users) { - $menus['reportusers'][''] = '------'; // separator - foreach ($users as $id=>$user) { - $menus['reportusers']["$id"] = fullname($user); - } - } - $menus['reportattempts'] = array( - 'all' => get_string('attemptsall', 'hotpot'), - 'best' => get_string('attemptsbest', 'hotpot'), - 'first' => get_string('attemptsfirst', 'hotpot'), - 'last' => get_string('attemptslast', 'hotpot') - ); - - print ''; - - $menus = array(); - - $menus['reportformat'] = array(); - $menus['reportformat']['htm'] = get_string('reportformathtml', 'hotpot'); - if (file_exists("$CFG->libdir/excel") || file_exists("$CFG->libdir/excellib.class.php")) { - $menus['reportformat']['xls'] = get_string('reportformatexcel', 'hotpot'); - } - $menus['reportformat']['txt'] = get_string('reportformattext', 'hotpot'); - - if (trim($CFG->hotpot_excelencodings)) { - $menus['reportencoding'] = array(get_string('none')=>''); - - $encodings = explode(',', $CFG->hotpot_excelencodings); - foreach ($encodings as $encoding) { - - $encoding = trim($encoding); - if ($encoding) { - $menus['reportencoding'][$encoding] = $encoding; - } - } - } - $menus['reportwrapdata'] = array( - '1' => get_string('yes'), - '0' => get_string('no'), - ); - $menus['reportshowlegend'] = array( - '1' => get_string('yes'), - '0' => get_string('no'), - ); - - print ''; - foreach ($menus as $name => $options) { - $value = $formdata[$name]; - print ''; - } - print ''; - - print '
    '; - helpbutton('reportcontent', get_string('reportcontent', 'hotpot'), 'hotpot'); - print ''.get_string('reportcontent', 'hotpot').':'; - foreach ($menus as $name => $options) { - $value = $formdata[$name]; - print choose_from_menu($options, $name, $value, "", "", 0, true); - }; - print '
    '; - helpbutton('reportformat', get_string('reportformat', 'hotpot'), 'hotpot'); - print ''.get_string($name, 'hotpot').':'.choose_from_menu($options, $name, $value, "", "", 0, true).'
    '; - - print '
    '; - print '
    '."\n"; + global $CFG; + + $reports = hotpot_get_report_names('overview,simplestat,fullstat'); + + print '
    wwwroot/mod/hotpot/report.php?hp=$hotpot->id".'">'; + print ''; + + $menus = array(); + + $menus['mode'] = array(); + foreach ($reports as $name) { + if ($name=='overview' || $name=='simplestat' || $name=='fullstat') { + $module = "quiz"; // standard reports + } else if ($name=='click' && empty($hotpot->clickreporting)) { + $module = ""; // clickreporting is disabled + } else { + $module = "hotpot"; // custom reports + } + if ($module) { + $menus['mode'][$name] = get_string("report$name", $module); + } + } + if (isadmin()) { + $menus['reportcourse'] = array( + 'this' => get_string('thiscourse', 'hotpot'), // $course->shortname, + 'all' => get_string('allmycourses', 'hotpot') + ); + } + $menus['reportusers'] = array( + 'all' => get_string('allparticipants'), + 'students' => get_string('students') + ); + $users = get_records_sql(" + SELECT + u.* + FROM + {$CFG->prefix}user AS u, + {$CFG->prefix}user_students AS us + WHERE + u.id = us.userid AND us.course=$course->id + ORDER BY + u.lastname + "); + if ($users) { + $menus['reportusers'][''] = '------'; // separator + foreach ($users as $id=>$user) { + $menus['reportusers']["$id"] = fullname($user); + } + } + $menus['reportattempts'] = array( + 'all' => get_string('attemptsall', 'hotpot'), + 'best' => get_string('attemptsbest', 'hotpot'), + 'first' => get_string('attemptsfirst', 'hotpot'), + 'last' => get_string('attemptslast', 'hotpot') + ); + + print ''; + + $menus = array(); + + $menus['reportformat'] = array(); + $menus['reportformat']['htm'] = get_string('reportformathtml', 'hotpot'); + if (file_exists("$CFG->libdir/excel") || file_exists("$CFG->libdir/excellib.class.php")) { + $menus['reportformat']['xls'] = get_string('reportformatexcel', 'hotpot'); + } + $menus['reportformat']['txt'] = get_string('reportformattext', 'hotpot'); + + if (trim($CFG->hotpot_excelencodings)) { + $menus['reportencoding'] = array(get_string('none')=>''); + + $encodings = explode(',', $CFG->hotpot_excelencodings); + foreach ($encodings as $encoding) { + + $encoding = trim($encoding); + if ($encoding) { + $menus['reportencoding'][$encoding] = $encoding; + } + } + } + $menus['reportwrapdata'] = array( + '1' => get_string('yes'), + '0' => get_string('no'), + ); + $menus['reportshowlegend'] = array( + '1' => get_string('yes'), + '0' => get_string('no'), + ); + + print ''; + foreach ($menus as $name => $options) { + $value = $formdata[$name]; + print ''; + } + print ''; + + print '
    '; + helpbutton('reportcontent', get_string('reportcontent', 'hotpot'), 'hotpot'); + print ''.get_string('reportcontent', 'hotpot').':'; + foreach ($menus as $name => $options) { + $value = $formdata[$name]; + print choose_from_menu($options, $name, $value, "", "", 0, true); + }; + print '
    '; + helpbutton('reportformat', get_string('reportformat', 'hotpot'), 'hotpot'); + print ''.get_string($name, 'hotpot').':'.choose_from_menu($options, $name, $value, "", "", 0, true).'
    '; + + print '
    '; + print '
    '."\n"; } function hotpot_get_report_names($names='') { - // $names : optional list showing required order reports names + // $names : optional list showing required order reports names - $reports = array(); + $reports = array(); - // convert $names to an array, if necessary (usually is) - if (!is_array($names)) { - $names = explode(',', $names); - } + // convert $names to an array, if necessary (usually is) + if (!is_array($names)) { + $names = explode(',', $names); + } - $plugins = get_list_of_plugins('mod/hotpot/report'); - foreach($names as $name) { - if (is_numeric($i = array_search($name, $plugins))) { - $reports[] = $name; - unset($plugins[$i]); - } - } + $plugins = get_list_of_plugins('mod/hotpot/report'); + foreach($names as $name) { + if (is_numeric($i = array_search($name, $plugins))) { + $reports[] = $name; + unset($plugins[$i]); + } + } - // append remaining plugins - $reports = array_merge($reports, $plugins); + // append remaining plugins + $reports = array_merge($reports, $plugins); - return $reports; + return $reports; } function hotpot_get_report_users($course_ids, $formdata) { - $users = array(); - - /// Check to see if groups are being used in this module - $currentgroup = false; - if ($groupmode = groupmode($course, $cm)) { // Groups are being used - $currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id=$cm->id&mode=simple"); - } - - $sort = "u.lastname ASC"; - - switch ($formdata['reportusers']) { - case 'students': - if ($currentgroup) { - $users = get_group_students($currentgroup, $sort); - } else { - $users = get_course_students($course->id, $sort); - } - break; - case 'all': - if ($currentgroup) { - $users = get_group_users($currentgroup, $sort); - } else { - $users = get_course_users($course->id, $sort); - } - break; - } - - return $users; + $users = array(); + + /// Check to see if groups are being used in this module + $currentgroup = false; + if ($groupmode = groupmode($course, $cm)) { // Groups are being used + $currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id=$cm->id&mode=simple"); + } + + $sort = "u.lastname ASC"; + + switch ($formdata['reportusers']) { + case 'students': + if ($currentgroup) { + $users = get_group_students($currentgroup, $sort); + } else { + $users = get_course_students($course->id, $sort); + } + break; + case 'all': + if ($currentgroup) { + $users = get_group_users($currentgroup, $sort); + } else { + $users = get_course_users($course->id, $sort); + } + break; + } + + return $users; } function hotpot_get_records_groupby($function, $fieldnames, $table, $select, $groupby) { - // $function is an SQL aggregate function (MAX or MIN) - - global $CFG; - - switch (strtolower($CFG->dbtype)) { - case 'mysql': - $fields = "$groupby, $function(CONCAT(".join(",'_',", $fieldnames).")) AS joinedvalues"; - break; - case 'postgres7': - $fields = "$groupby, $function(".join("||'_'||", $fieldnames).") AS joinedvalues"; - break; - default: - $fields = ""; - break; - } - - if ($fields) { - $records = get_records_sql("SELECT $fields FROM $table WHERE $select GROUP BY $groupby"); - } - - if (empty($fields) || empty($records)) { - $records = array(); - } - - $fieldcount = count($fieldnames); - - foreach ($records as $id=>$record) { - if (empty($record->joinedvalues)) { - unset($records[$id]); - } else { - $formdata = explode('_', $record->joinedvalues); - - for ($i=0; $i<$fieldcount; $i++) { - $fieldname = $fieldnames[$i]; - $records[$id]->$fieldname = $formdata[$i]; - } - } - unset($record->joinedvalues); - } - - return $records; + // $function is an SQL aggregate function (MAX or MIN) + + global $CFG; + + switch (strtolower($CFG->dbtype)) { + case 'mysql': + $fields = "$groupby, $function(CONCAT(".join(",'_',", $fieldnames).")) AS joinedvalues"; + break; + case 'postgres7': + $fields = "$groupby, $function(".join("||'_'||", $fieldnames).") AS joinedvalues"; + break; + default: + $fields = ""; + break; + } + + if ($fields) { + $records = get_records_sql("SELECT $fields FROM $table WHERE $select GROUP BY $groupby"); + } + + if (empty($fields) || empty($records)) { + $records = array(); + } + + $fieldcount = count($fieldnames); + + foreach ($records as $id=>$record) { + if (empty($record->joinedvalues)) { + unset($records[$id]); + } else { + $formdata = explode('_', $record->joinedvalues); + + for ($i=0; $i<$fieldcount; $i++) { + $fieldname = $fieldnames[$i]; + $records[$id]->$fieldname = $formdata[$i]; + } + } + unset($record->joinedvalues); + } + + return $records; } ?> diff --git a/mod/hotpot/report/default.php b/mod/hotpot/report/default.php index 998362d3f0..c89423e2c5 100644 --- a/mod/hotpot/report/default.php +++ b/mod/hotpot/report/default.php @@ -2,7 +2,7 @@ //////////////////////////////////////////////////////////////////// /// Default class for report plugins -/// +/// /// Doesn't do anything on it's own -- it needs to be extended. /// This class displays quiz reports. Because it is called from /// within /mod/quiz/report.php you can assume that the page header @@ -17,227 +17,227 @@ class hotpot_default_report { - function display($hotpot, $cm, $course, $users, $attempts, $questions, $options) { - /// This function just displays the report - // it is replaced by the "display" functions in the scripts in the "report" folder - return true; - } - - function add_question_headings(&$questions, &$table, $align='center', $size=50, $wrap=false, $fontsize=0) { - $count = count($questions); - for ($i=0; $i<$count; $i++) { - $table->head[] = get_string('questionshort', 'hotpot', $i+1); - if (isset($table->align)) { - $table->align[] = $align; - } - if (isset($table->size)) { - $table->size[] = $size; - } - if (isset($table->wrap)) { - $table->wrap[] = $wrap; - } - if (isset($table->fontsize)) { - $table->fontsize[] = $fontsize; - } - } - - } - - function set_legend(&$table, &$q, &$value, &$question) { - // $q is the question number - // $value is the value (=text) of the answer - - // check the legend is required - if (isset($table->legend) && isset($value)) { - - // create question details array, if necessary - if (empty($table->legend[$q])) { - $table->legend[$q] = array( - 'name' => hotpot_get_question_name($question), - 'answers' => array() - ); - } - - // search for this $value in answers array for this $q(uestion) - $i_max = count($table->legend[$q]['answers']); - for ($i=0; $i<$i_max; $i++) { - if ($table->legend[$q]['answers'][$i]==$value) { - break; - } - } - - // add $value to answers array, if it was not there - if ($i==$i_max) { - $table->legend[$q]['answers'][$i] = $value; - } - - // convert $value to alphabetic index (A, B ... AA, AB ...) - $value = $this->dec_to_ALPHA($i); - } - } - function create_legend_table(&$tables, &$table) { - - if (isset($table->legend)) { - - $legend->width = '*'; - $legend->tablealign = '*'; - $legend->border = isset($table->border) ? $table->border : NULL; - $legend->cellpadding = isset($table->cellpadding) ? $table->cellpadding : NULL; - $legend->cellspacing = isset($table->cellspacing) ? $table->cellspacing : NULL; - $legend->tableclass = isset($table->tableclass) ? $table->tableclass : NULL; - - $legend->caption = get_string('reportlegend', 'hotpot'); - $legend->align = array('right', 'left'); - $legend->statheadercols = array(0); - - $legend->stat = array(); - - // put the questions in order - sort($table->legend); - - foreach($table->legend as $q=>$question) { - - $legend->stat[] = array( - get_string('questionshort', 'hotpot', $q+1), - $question['name'] - ); - foreach($question['answers'] as $a=>$answer) { - $legend->stat[] = array( - $this->dec_to_ALPHA($a), - $answer - ); - } - } - - unset($table->legend); - $tables[] = $legend; - } - } - function dec_to_ALPHA($dec) { - if ($dec < 26) { - return chr(ord('A') + $dec); - } else { - return $this->dec_to_ALPHA(intval($dec/26)-1).$this->dec_to_ALPHA($dec % 26); - } - } - function remove_column(&$table, $target_col) { - - if (is_array($table)) { - unset($table[$target_col]); - $table = array_values($table); - - } else if (is_object($table)) { - $vars = get_object_vars($table); - foreach ($vars as $name=>$value) { - switch ($name) { - case 'data' : - case 'stat' : - case 'foot' : - $skipcol = array(); - $cells = &$table->$name; - - $row_max = count($cells); - for ($row=0; $row<$row_max; $row++) { - - $col = 0; - $col_max = count($cells[$row]); - - $current_col = 0; - while ($current_col<$target_col && $col<$col_max) { - - if (empty($skipcol[$current_col])) { - - $cell = $cells[$row][$col++]; - if (is_object($cell)) { - if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) { - // skip cells below this one - $skipcol[$current_col] = $cell->rowspan-1; - } - if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) { - // skip cells to the right of this one - for ($c=1; $c<$cell->colspan; $c++) { - if (empty($skipcol[$current_col+$c])) { - $skipcol[$current_col+$c] = 1; - } else { - $skipcol[$current_col+$c] ++; - } - } - } - } - } else { - $skipcol[$current_col]--; - } - $current_col++; - } - if ($current_col==$target_col && $col<$col_max) { - $this->remove_column($cells[$row], $col); - } - } // end for $row - break; - case 'head' : - case 'align' : - case 'class' : - case 'fontsize' : - case 'size' : - case 'wrap' : - $this->remove_column($table->$name, $target_col); - break; - case 'statheadercols' : - $array = &$table->$name; - $count = count($array); - for ($i=0; $i<$count; $i++) { - if ($array[$i]>=$target_col) { - $array[$i] --; - } - } - break; - } // end switch - } // end foreach - } // end if - } // end function - - - function expand_spans(&$table, $zone) { - // expand multi-column and multi-row cells in a specified $zone of a $table - - // do nothing if this $zone is empty - if (empty($table->$zone)) return; - - // shortcut to rows in this $table $zone - $rows = &$table->{$zone}; - - // loop through the rows - foreach ($rows as $row=>$cells) { - - // check this is an array - if (is_array($cells)) { - - // loop through the cells in this row - foreach ($cells as $col=>$cell) { - - if (is_object($cell)) { - if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>1)) { - // fill in cells below this one - $new_cell = array($cell->text); - for ($r=1; $r<$cell->rowspan; $r++) { - array_splice($rows[$row+$r], $col, 0, $new_cell); - } - } - if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>1)) { - // fill in cells to the right of this one - $new_cells = array(); - for ($c=1; $c<$cell->colspan; $c++) { - $new_cells[] = $cell->text; - } - array_splice($rows[$row], $col, 0, $new_cells); - } - // replace $cell object with plain text - $rows[$row][$col] = $cell->text; - } - } - } - } - } + function display($hotpot, $cm, $course, $users, $attempts, $questions, $options) { + /// This function just displays the report + // it is replaced by the "display" functions in the scripts in the "report" folder + return true; + } + + function add_question_headings(&$questions, &$table, $align='center', $size=50, $wrap=false, $fontsize=0) { + $count = count($questions); + for ($i=0; $i<$count; $i++) { + $table->head[] = get_string('questionshort', 'hotpot', $i+1); + if (isset($table->align)) { + $table->align[] = $align; + } + if (isset($table->size)) { + $table->size[] = $size; + } + if (isset($table->wrap)) { + $table->wrap[] = $wrap; + } + if (isset($table->fontsize)) { + $table->fontsize[] = $fontsize; + } + } + + } + + function set_legend(&$table, &$q, &$value, &$question) { + // $q is the question number + // $value is the value (=text) of the answer + + // check the legend is required + if (isset($table->legend) && isset($value)) { + + // create question details array, if necessary + if (empty($table->legend[$q])) { + $table->legend[$q] = array( + 'name' => hotpot_get_question_name($question), + 'answers' => array() + ); + } + + // search for this $value in answers array for this $q(uestion) + $i_max = count($table->legend[$q]['answers']); + for ($i=0; $i<$i_max; $i++) { + if ($table->legend[$q]['answers'][$i]==$value) { + break; + } + } + + // add $value to answers array, if it was not there + if ($i==$i_max) { + $table->legend[$q]['answers'][$i] = $value; + } + + // convert $value to alphabetic index (A, B ... AA, AB ...) + $value = $this->dec_to_ALPHA($i); + } + } + function create_legend_table(&$tables, &$table) { + + if (isset($table->legend)) { + + $legend->width = '*'; + $legend->tablealign = '*'; + $legend->border = isset($table->border) ? $table->border : NULL; + $legend->cellpadding = isset($table->cellpadding) ? $table->cellpadding : NULL; + $legend->cellspacing = isset($table->cellspacing) ? $table->cellspacing : NULL; + $legend->tableclass = isset($table->tableclass) ? $table->tableclass : NULL; + + $legend->caption = get_string('reportlegend', 'hotpot'); + $legend->align = array('right', 'left'); + $legend->statheadercols = array(0); + + $legend->stat = array(); + + // put the questions in order + sort($table->legend); + + foreach($table->legend as $q=>$question) { + + $legend->stat[] = array( + get_string('questionshort', 'hotpot', $q+1), + $question['name'] + ); + foreach($question['answers'] as $a=>$answer) { + $legend->stat[] = array( + $this->dec_to_ALPHA($a), + $answer + ); + } + } + + unset($table->legend); + $tables[] = $legend; + } + } + function dec_to_ALPHA($dec) { + if ($dec < 26) { + return chr(ord('A') + $dec); + } else { + return $this->dec_to_ALPHA(intval($dec/26)-1).$this->dec_to_ALPHA($dec % 26); + } + } + function remove_column(&$table, $target_col) { + + if (is_array($table)) { + unset($table[$target_col]); + $table = array_values($table); + + } else if (is_object($table)) { + $vars = get_object_vars($table); + foreach ($vars as $name=>$value) { + switch ($name) { + case 'data' : + case 'stat' : + case 'foot' : + $skipcol = array(); + $cells = &$table->$name; + + $row_max = count($cells); + for ($row=0; $row<$row_max; $row++) { + + $col = 0; + $col_max = count($cells[$row]); + + $current_col = 0; + while ($current_col<$target_col && $col<$col_max) { + + if (empty($skipcol[$current_col])) { + + $cell = $cells[$row][$col++]; + if (is_object($cell)) { + if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) { + // skip cells below this one + $skipcol[$current_col] = $cell->rowspan-1; + } + if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) { + // skip cells to the right of this one + for ($c=1; $c<$cell->colspan; $c++) { + if (empty($skipcol[$current_col+$c])) { + $skipcol[$current_col+$c] = 1; + } else { + $skipcol[$current_col+$c] ++; + } + } + } + } + } else { + $skipcol[$current_col]--; + } + $current_col++; + } + if ($current_col==$target_col && $col<$col_max) { + $this->remove_column($cells[$row], $col); + } + } // end for $row + break; + case 'head' : + case 'align' : + case 'class' : + case 'fontsize' : + case 'size' : + case 'wrap' : + $this->remove_column($table->$name, $target_col); + break; + case 'statheadercols' : + $array = &$table->$name; + $count = count($array); + for ($i=0; $i<$count; $i++) { + if ($array[$i]>=$target_col) { + $array[$i] --; + } + } + break; + } // end switch + } // end foreach + } // end if + } // end function + + + function expand_spans(&$table, $zone) { + // expand multi-column and multi-row cells in a specified $zone of a $table + + // do nothing if this $zone is empty + if (empty($table->$zone)) return; + + // shortcut to rows in this $table $zone + $rows = &$table->{$zone}; + + // loop through the rows + foreach ($rows as $row=>$cells) { + + // check this is an array + if (is_array($cells)) { + + // loop through the cells in this row + foreach ($cells as $col=>$cell) { + + if (is_object($cell)) { + if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>1)) { + // fill in cells below this one + $new_cell = array($cell->text); + for ($r=1; $r<$cell->rowspan; $r++) { + array_splice($rows[$row+$r], $col, 0, $new_cell); + } + } + if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>1)) { + // fill in cells to the right of this one + $new_cells = array(); + for ($c=1; $c<$cell->colspan; $c++) { + $new_cells[] = $cell->text; + } + array_splice($rows[$row], $col, 0, $new_cells); + } + // replace $cell object with plain text + $rows[$row][$col] = $cell->text; + } + } + } + } + } ///////////////////////////////////////////////// /// print a report in html, text or Excel format @@ -246,592 +246,592 @@ class hotpot_default_report { // the stuff to print is contained in $table // which has the following properties: -// $table->border border width for the table -// $table->cellpadding padding on each cell -// $table->cellspacing spacing between cells -// $table->tableclass class for table -// $table->width table width - -// $table->align is an array of column alignments -// $table->class is an array of column classes -// $table->size is an array of column sizes -// $table->wrap is an array of column wrap/nowrap switches -// $table->fontsize is an array of fontsizes - -// $table->caption is a caption (=title) for the report -// $table->head is an array of headings (all TH cells) -// $table->data[] is an array of arrays containing the data (all TD cells) -// if a row is given as "hr", a "tabledivider" is inserted -// if a cell is a string, it is assumed to be the cell content -// a cell can also be an object, thus: -// $cell->text : the content of the cell -// $cell->rowspan : the row span of this cell -// $cell->colspan : the column span of this cell -// if rowspan or colspan are specified, neighboring cells are shifted accordingly -// $table->stat[] is an array of arrays containing the statistics rows (TD and TH cells) -// $table->foot[] is an array of arrays containing the footer rows (all TH cells) - -// $table->statheadercols is an array of column numbers which are headers +// $table->border border width for the table +// $table->cellpadding padding on each cell +// $table->cellspacing spacing between cells +// $table->tableclass class for table +// $table->width table width + +// $table->align is an array of column alignments +// $table->class is an array of column classes +// $table->size is an array of column sizes +// $table->wrap is an array of column wrap/nowrap switches +// $table->fontsize is an array of fontsizes + +// $table->caption is a caption (=title) for the report +// $table->head is an array of headings (all TH cells) +// $table->data[] is an array of arrays containing the data (all TD cells) +// if a row is given as "hr", a "tabledivider" is inserted +// if a cell is a string, it is assumed to be the cell content +// a cell can also be an object, thus: +// $cell->text : the content of the cell +// $cell->rowspan : the row span of this cell +// $cell->colspan : the column span of this cell +// if rowspan or colspan are specified, neighboring cells are shifted accordingly +// $table->stat[] is an array of arrays containing the statistics rows (TD and TH cells) +// $table->foot[] is an array of arrays containing the footer rows (all TH cells) + +// $table->statheadercols is an array of column numbers which are headers ////////////////////////////////////////// /// print a report - function print_report(&$course, &$hotpot, &$tables, &$options) { - switch ($options['reportformat']) { - case 'txt': - $this->print_text_report($course, $hotpot, $tables, $options); - break; - case 'xls': - $this->print_excel_report($course, $hotpot, $tables, $options); - break; - default: // 'htm' (and anything else) - $this->print_html_report($tables); - break; - } - } - - function print_report_start(&$course, &$hotpot, &$options, &$table) { - switch ($options['reportformat']) { - case 'txt': - $this->print_text_start($course, $hotpot, $options); - break; - case 'xls': - $this->print_excel_start($course, $hotpot, $options); - break; - - case 'htm': - $this->print_html_start($course, $hotpot, $options); - break; - } - } - - function print_report_cells(&$table, &$options, $zone) { - switch ($options['reportformat']) { - case 'txt': - $fmt = 'text'; - break; - case 'xls': - $fmt = 'excel'; - break; - default: // 'htm' (and anything else) - $fmt = 'html'; - break; - } - $fn = "print_{$fmt}_{$zone}"; - $this->$fn($table, $options); - } - - function print_report_finish(&$course, &$hotpot, &$options) { - switch ($options['reportformat']) { - case 'txt' : - // do nothing - break; - case 'xls': - $this->print_excel_finish($course, $hotpot, $options); - break; - case 'htm': - $this->print_html_finish($course, $hotpot, $options); - break; - } - } + function print_report(&$course, &$hotpot, &$tables, &$options) { + switch ($options['reportformat']) { + case 'txt': + $this->print_text_report($course, $hotpot, $tables, $options); + break; + case 'xls': + $this->print_excel_report($course, $hotpot, $tables, $options); + break; + default: // 'htm' (and anything else) + $this->print_html_report($tables); + break; + } + } + + function print_report_start(&$course, &$hotpot, &$options, &$table) { + switch ($options['reportformat']) { + case 'txt': + $this->print_text_start($course, $hotpot, $options); + break; + case 'xls': + $this->print_excel_start($course, $hotpot, $options); + break; + + case 'htm': + $this->print_html_start($course, $hotpot, $options); + break; + } + } + + function print_report_cells(&$table, &$options, $zone) { + switch ($options['reportformat']) { + case 'txt': + $fmt = 'text'; + break; + case 'xls': + $fmt = 'excel'; + break; + default: // 'htm' (and anything else) + $fmt = 'html'; + break; + } + $fn = "print_{$fmt}_{$zone}"; + $this->$fn($table, $options); + } + + function print_report_finish(&$course, &$hotpot, &$options) { + switch ($options['reportformat']) { + case 'txt' : + // do nothing + break; + case 'xls': + $this->print_excel_finish($course, $hotpot, $options); + break; + case 'htm': + $this->print_html_finish($course, $hotpot, $options); + break; + } + } ////////////////////////////////////////// /// print an html report - function print_html_report(&$tables) { - $count = count($tables); - foreach($tables as $i=>$table) { - - $this->print_html_start($table); - $this->print_html_head($table); - $this->print_html_data($table); - $this->print_html_stat($table); - $this->print_html_foot($table); - $this->print_html_finish($table); - - if (($i+1)<$count) { - print_spacer(30, 10, true); - } - } - } - function print_html_start(&$table) { - - // default class for the table - if (empty($table->tableclass)) { - $table->tableclass = 'generaltable'; - } - - // default classes for TD and TH - $d = $table->tableclass.'cell'; - $h = $table->tableclass.'header'; - - $table->th_side = ''; - - $table->td = array(); - $table->th_top = array(); - - if (empty($table->colspan)) { - if (isset($table->head)) { - $table->colspan = count($table->head); - } else if (isset($table->data)) { - $table->colspan = count($table->data[0]); - } else if (isset($table->stat)) { - $table->colspan = count($table->stat); - } else if (isset($table->foot)) { - $table->colspan = count($table->foot); - } else { - $table->colspan = 0; - } - } - - for ($i=0; $i<$table->colspan; $i++) { - - $align = empty($table->align[$i]) ? '' : ' align="'.$table->align[$i].'"'; - $class = empty($table->class[$i]) ? $d : ' class="'.$table->class[$i].'"'; - $size = empty($table->size[$i]) ? '' : ' width="'.$table->size[$i].'"'; - $wrap = empty($table->wrap[$i]) ? '' : ' nowrap="nowrap"'; - - $table->th_top[$i] = ''; - - $table->td[$i] = ''; - - if (!empty($table->fontsize[$i])) { - $table->td[$i] .= ''; - } - } - - if (empty($table->border)) { - $table->border = 0; - } - if (empty($table->cellpadding)) { - $table->cellpadding = 5; - } - if (empty($table->cellspacing)) { - $table->cellspacing = 1; - } - if (empty($table->width)) { - $table->width = "80%"; // actually the width of the "simple box" - } - if (empty($table->tablealign)) { - $table->tablealign = "center"; - } - - if (isset($table->start)) { - print $table->start."\n"; - } - - print_simple_box_start("$table->tablealign", "$table->width", "#ffffff", 0); - print ''."\n"; - - if (isset($table->caption)) { - print ''."\n"; - } - - } - function print_html_head(&$table) { - if (isset($table->head)) { - print "\n"; - foreach ($table->head as $i=>$cell) { - $th = $table->th_top[$i]; - print $th.$cell."\n"; - } - print "\n"; - } - } - function print_html_data(&$table) { - if (isset($table->data)) { - $skipcol = array(); - foreach ($table->data as $cells) { - print "\n"; - if (is_array($cells)) { - $i = 0; // index on $cells - $col = 0; // column index - while ($col<$table->colspan && isset($cells[$i])) { - if (empty($skipcol[$col])) { - $cell = &$cells[$i++]; - $td = $table->td[$col]; - if (is_object($cell)) { - $text = $cell->text; - if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) { - $td = '\n"; - } else { - $skipcol[$col]--; - } - $col++; - } // end while - } else if ($cells=='hr') { - print ''."\n"; - } - print "\n"; - } - } - } - function print_html_stat(&$table) { - if (isset($table->stat)) { - if (empty($table->statheadercols)) { - $table->statheadercols = array(); - } - foreach ($table->stat as $cells) { - print ''; - foreach ($cells as $i => $cell) { - if (in_array($i, $table->statheadercols)) { - $th = $table->th_side; - print $th.$cell."\n"; - } else { - $td = $table->td[$i]; - print $td.$cell."\n"; - } - } - print "\n"; - } - } - } - function print_html_foot(&$table) { - if (isset($table->foot)) { - foreach ($table->foot as $cells) { - print "\n"; - foreach ($cells as $i => $cell) { - if ($i==0) { - $th = $table->th_side; - print $th.$cell."\n"; - } else { - $th = $table->th_top[$i]; - print $th.$cell."\n"; - } - } - print "\n"; - } - } - } - function print_html_finish(&$table) { - print "
    '.$table->caption.'
    rowspan-1; - } - if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) { - $td = 'colspan; $c++) { - if (empty($skipcol[$col+$c])) { - $skipcol[$col+$c] = 1; - } else { - $skipcol[$col+$c] ++; - } - } - } - } else { // $cell is a string - $text = $cell; - } - print $td.$text."
    \n"; - print_simple_box_end(); - - if (isset($table->finish)) { - print $table->finish."\n"; - } - } + function print_html_report(&$tables) { + $count = count($tables); + foreach($tables as $i=>$table) { + + $this->print_html_start($table); + $this->print_html_head($table); + $this->print_html_data($table); + $this->print_html_stat($table); + $this->print_html_foot($table); + $this->print_html_finish($table); + + if (($i+1)<$count) { + print_spacer(30, 10, true); + } + } + } + function print_html_start(&$table) { + + // default class for the table + if (empty($table->tableclass)) { + $table->tableclass = 'generaltable'; + } + + // default classes for TD and TH + $d = $table->tableclass.'cell'; + $h = $table->tableclass.'header'; + + $table->th_side = ''; + + $table->td = array(); + $table->th_top = array(); + + if (empty($table->colspan)) { + if (isset($table->head)) { + $table->colspan = count($table->head); + } else if (isset($table->data)) { + $table->colspan = count($table->data[0]); + } else if (isset($table->stat)) { + $table->colspan = count($table->stat); + } else if (isset($table->foot)) { + $table->colspan = count($table->foot); + } else { + $table->colspan = 0; + } + } + + for ($i=0; $i<$table->colspan; $i++) { + + $align = empty($table->align[$i]) ? '' : ' align="'.$table->align[$i].'"'; + $class = empty($table->class[$i]) ? $d : ' class="'.$table->class[$i].'"'; + $size = empty($table->size[$i]) ? '' : ' width="'.$table->size[$i].'"'; + $wrap = empty($table->wrap[$i]) ? '' : ' nowrap="nowrap"'; + + $table->th_top[$i] = ''; + + $table->td[$i] = ''; + + if (!empty($table->fontsize[$i])) { + $table->td[$i] .= ''; + } + } + + if (empty($table->border)) { + $table->border = 0; + } + if (empty($table->cellpadding)) { + $table->cellpadding = 5; + } + if (empty($table->cellspacing)) { + $table->cellspacing = 1; + } + if (empty($table->width)) { + $table->width = "80%"; // actually the width of the "simple box" + } + if (empty($table->tablealign)) { + $table->tablealign = "center"; + } + + if (isset($table->start)) { + print $table->start."\n"; + } + + print_simple_box_start("$table->tablealign", "$table->width", "#ffffff", 0); + print ''."\n"; + + if (isset($table->caption)) { + print ''."\n"; + } + + } + function print_html_head(&$table) { + if (isset($table->head)) { + print "\n"; + foreach ($table->head as $i=>$cell) { + $th = $table->th_top[$i]; + print $th.$cell."\n"; + } + print "\n"; + } + } + function print_html_data(&$table) { + if (isset($table->data)) { + $skipcol = array(); + foreach ($table->data as $cells) { + print "\n"; + if (is_array($cells)) { + $i = 0; // index on $cells + $col = 0; // column index + while ($col<$table->colspan && isset($cells[$i])) { + if (empty($skipcol[$col])) { + $cell = &$cells[$i++]; + $td = $table->td[$col]; + if (is_object($cell)) { + $text = $cell->text; + if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) { + $td = '\n"; + } else { + $skipcol[$col]--; + } + $col++; + } // end while + } else if ($cells=='hr') { + print ''."\n"; + } + print "\n"; + } + } + } + function print_html_stat(&$table) { + if (isset($table->stat)) { + if (empty($table->statheadercols)) { + $table->statheadercols = array(); + } + foreach ($table->stat as $cells) { + print ''; + foreach ($cells as $i => $cell) { + if (in_array($i, $table->statheadercols)) { + $th = $table->th_side; + print $th.$cell."\n"; + } else { + $td = $table->td[$i]; + print $td.$cell."\n"; + } + } + print "\n"; + } + } + } + function print_html_foot(&$table) { + if (isset($table->foot)) { + foreach ($table->foot as $cells) { + print "\n"; + foreach ($cells as $i => $cell) { + if ($i==0) { + $th = $table->th_side; + print $th.$cell."\n"; + } else { + $th = $table->th_top[$i]; + print $th.$cell."\n"; + } + } + print "\n"; + } + } + } + function print_html_finish(&$table) { + print "
    '.$table->caption.'
    rowspan-1; + } + if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) { + $td = 'colspan; $c++) { + if (empty($skipcol[$col+$c])) { + $skipcol[$col+$c] = 1; + } else { + $skipcol[$col+$c] ++; + } + } + } + } else { // $cell is a string + $text = $cell; + } + print $td.$text."
    \n"; + print_simple_box_end(); + + if (isset($table->finish)) { + print $table->finish."\n"; + } + } ////////////////////////////////////////// /// print a text report - function print_text_report(&$course, &$hotpot, &$tables, &$options) { - $this->print_text_start($course, $hotpot, $options); - foreach ($tables as $table) { - $this->print_text_head($table, $options); - $this->print_text_data($table, $options); - $this->print_text_stat($table, $options); - $this->print_text_foot($table, $options); - } - } - function print_text_start(&$course, &$hotpot, &$options) { - $downloadfilename = clean_filename("$course->shortname $hotpot->name.txt"); - header("Content-Type: application/download\n"); - header("Content-Disposition: attachment; filename=$downloadfilename"); - header("Expires: 0"); - header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); - header("Pragma: public"); - } - function print_text_head(&$table, &$options) { - if (isset($table->caption)) { - $i = strlen($table->caption); - $data = array( - array(str_repeat('=', $i)), - array($table->caption), - array(str_repeat('=', $i)), - ); - foreach($data as $cells) { - $this->print_text_cells($cells, $options); - } - } - if (isset($table->head)) { - $this->expand_spans($table, 'head'); - $this->print_text_cells($table->head, $options); - } - } - function print_text_data(&$table, &$options) { - if (isset($table->data)) { - $this->expand_spans($table, 'data'); - foreach ($table->data as $cells) { - $this->print_text_cells($cells, $options); - } - } - } - function print_text_stat(&$table, &$options) { - if (isset($table->stat)) { - $this->expand_spans($table, 'stat'); - foreach ($table->stat as $cells) { - $this->print_text_cells($cells, $options); - } - } - } - function print_text_foot(&$table, &$options) { - if (isset($table->foot)) { - $this->expand_spans($table, 'foot'); - foreach ($table->foot as $cells) { - $this->print_text_cells($cells, $options); - } - } - } - function print_text_cells(&$cells, &$options) { - - // do nothing if there are no cells - if (empty($cells) || is_string($cells)) return; - - // convert to tab-delimted string - $str = implode("\t", $cells); - - // replace newlines in string - $str = preg_replace("/\n/", ",", $str); - - // set best newline for this browser (if it hasn't been done already) - if (empty($this->nl)) { - $s = &$_SERVER['HTTP_USER_AGENT']; - $win = is_numeric(strpos($s, 'Win')); - $mac = is_numeric(strpos($s, 'Mac')) && !is_numeric(strpos($s, 'OS X')); - $this->nl = $win ? "\r\n" : ($mac ? "\r" : "\n"); - } - - print $str.$this->nl; - } + function print_text_report(&$course, &$hotpot, &$tables, &$options) { + $this->print_text_start($course, $hotpot, $options); + foreach ($tables as $table) { + $this->print_text_head($table, $options); + $this->print_text_data($table, $options); + $this->print_text_stat($table, $options); + $this->print_text_foot($table, $options); + } + } + function print_text_start(&$course, &$hotpot, &$options) { + $downloadfilename = clean_filename("$course->shortname $hotpot->name.txt"); + header("Content-Type: application/download\n"); + header("Content-Disposition: attachment; filename=$downloadfilename"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); + header("Pragma: public"); + } + function print_text_head(&$table, &$options) { + if (isset($table->caption)) { + $i = strlen($table->caption); + $data = array( + array(str_repeat('=', $i)), + array($table->caption), + array(str_repeat('=', $i)), + ); + foreach($data as $cells) { + $this->print_text_cells($cells, $options); + } + } + if (isset($table->head)) { + $this->expand_spans($table, 'head'); + $this->print_text_cells($table->head, $options); + } + } + function print_text_data(&$table, &$options) { + if (isset($table->data)) { + $this->expand_spans($table, 'data'); + foreach ($table->data as $cells) { + $this->print_text_cells($cells, $options); + } + } + } + function print_text_stat(&$table, &$options) { + if (isset($table->stat)) { + $this->expand_spans($table, 'stat'); + foreach ($table->stat as $cells) { + $this->print_text_cells($cells, $options); + } + } + } + function print_text_foot(&$table, &$options) { + if (isset($table->foot)) { + $this->expand_spans($table, 'foot'); + foreach ($table->foot as $cells) { + $this->print_text_cells($cells, $options); + } + } + } + function print_text_cells(&$cells, &$options) { + + // do nothing if there are no cells + if (empty($cells) || is_string($cells)) return; + + // convert to tab-delimted string + $str = implode("\t", $cells); + + // replace newlines in string + $str = preg_replace("/\n/", ",", $str); + + // set best newline for this browser (if it hasn't been done already) + if (empty($this->nl)) { + $s = &$_SERVER['HTTP_USER_AGENT']; + $win = is_numeric(strpos($s, 'Win')); + $mac = is_numeric(strpos($s, 'Mac')) && !is_numeric(strpos($s, 'OS X')); + $this->nl = $win ? "\r\n" : ($mac ? "\r" : "\n"); + } + + print $str.$this->nl; + } ////////////////////////////////////////// /// print an Excel report - function print_excel_report(&$course, &$hotpot, &$tables, &$options) { - global $CFG; - - // create Excel workbook - if (file_exists("$CFG->libdir/excellib.class.php")) { - // Moodle >= 1.6 - require_once("$CFG->libdir/excellib.class.php"); - $wb = new MoodleExcelWorkbook("-"); - } else { - // Moodle <= 1.5 - require_once("$CFG->libdir/excel/Worksheet.php"); - require_once("$CFG->libdir/excel/Workbook.php"); - $wb = new Workbook("-"); - } - - // send HTTP headers - $this->print_excel_headers($wb, $course, $hotpot); - - // create one worksheet for each table - foreach($tables as $table) { - unset($ws); - $ws = &$wb->add_worksheet(empty($table->caption) ? '' : strip_tags($table->caption)); - - $row = 0; - $this->print_excel_head($wb, $ws, $table, $row, $options); - $this->print_excel_data($wb, $ws, $table, $row, $options); - $this->print_excel_stat($wb, $ws, $table, $row, $options); - $this->print_excel_foot($wb, $ws, $table, $row, $options); - } - - // close the workbook (and send it to the browser) - $wb->close(); - } - function print_excel_headers(&$wb, &$course, &$hotpot) { - $downloadfilename = clean_filename("$course->shortname $hotpot->name.xls"); - if (method_exists($wb, 'send')) { - // Moodle >=1.6 - $wb->send($downloadfilename); - } else { - // Moodle <=1.5 - header("Content-type: application/vnd.ms-excel"); - header("Content-Disposition: attachment; filename=$downloadfilename" ); - header("Expires: 0"); - header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); - header("Pragma: public"); - } - } - function print_excel_head(&$wb, &$ws, &$table, &$row, &$options) { - // define format properties - $properties = array( - 'bold'=>1, - 'align'=>'center', - 'v_align'=>'bottom', - 'text_wrap'=>1 - ); - - // expand multi-column and multi-row cells - $this->expand_spans($table, 'head'); - - // print the headings - $this->print_excel_cells($wb, $ws, $table, $row, $properties, $table->head, $options); - } - function print_excel_data(&$wb, &$ws, &$table, &$row, &$options) { - // do nothing if there are no cells - if (empty($table->data)) return; - - // define format properties - $properties = array('text_wrap' => (empty($options['reportwrapdata']) ? 0 : 1)); - - // expand multi-column and multi-row cells - $this->expand_spans($table, 'data'); - - // print rows - foreach ($table->data as $cells) { - $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options); - } - } - function print_excel_stat(&$wb, &$ws, &$table, &$row, &$options) { - // do nothing if there are no cells - if (empty($table->stat)) return; - - // define format properties - $properties = array('align'=>'right'); - - // expand multi-column and multi-row cells - $this->expand_spans($table, 'stat'); - - // print rows - $i_count = count($table->stat); - foreach ($table->stat as $i => $cells) { - - // set border on top and bottom row - $properties['top'] = ($i==0) ? 1 : 0; - $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0; - - // print this row - $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options, $table->statheadercols); - } - } - function print_excel_foot(&$wb, &$ws, &$table, &$row, &$options) { - // do nothing if there are no cells - if (empty($table->foot)) return; - - // define format properties - $properties = array('bold'=>1, 'align'=>'center'); - - // expand multi-column and multi-row cells - $this->expand_spans($table, 'foot'); - - // print rows - $i_count = count($table->foot); - foreach ($table->foot as $i => $cells) { - - // set border on top and bottom row - $properties['top'] = ($i==0) ? 1 : 0; - $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0; - - // print this footer row - $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options); - } - } - - function print_excel_cells(&$wb, &$ws, &$table, &$row, &$properties, &$cells, &$options, $statheadercols=NULL) { - // do nothing if there are no cells - if (empty($cells) || is_string($cells)) return; - - // print cells - foreach($cells as $col => $cell) { - - unset($fmt_properties); - $fmt_properties = $properties; - - if (empty($fmt_properties['text_wrap'])) { - if (strlen("$cell")>=9) { - // long cell value - $fmt_properties['align'] = 'left'; - } - } else { - if (strlen("$cell")<9 && strpos("$cell", "\n")===false) { - // short cell value (wrapping not required) - $fmt_properties['text_wrap'] = 0; - } - } - - // set bold, if required (for stat) - if (isset($statheadercols)) { - $fmt_properties['bold'] = in_array($col, $statheadercols) ? 1 : 0; - $fmt_properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col]; - } - - // set align, if required - if (isset($table->align[$col]) && empty($fmt_properties['align'])) { - $fmt_properties['align'] = $table->align[$col]; - } - - // check to see that an identical format object has not already been created - unset($fmt); - - if (isset($wb->pear_excel_workbook)) { - // Moodle >=1.6 - $fmt_properties_obj = (object)$fmt_properties; - foreach ($wb->pear_excel_workbook->_formats as $id=>$format) { - if ($format==$fmt_properties_obj) { - $fmt = &$wb->pear_excel_workbook->_formats[$id]; - break; - } - } - } else { - // Moodle <=1.5 - foreach ($wb->formats as $id=>$format) { - if (isset($format->properties) && $format->properties==$fmt_properties) { - $fmt = &$wb->formats[$id]; - break; - } - } - if (is_numeric($cell) || empty($options['reportencoding'])) { - // do nothing - } else { - $in_charset = ''; - if (function_exists('mb_convert_encoding')) { - $in_charset = mb_detect_encoding($cell, 'auto'); - } - if (empty($in_charset)) { - $in_charset = get_string('thischarset'); - } - if ($in_charset != 'ASCII' && function_exists('mb_convert_encoding')) { - $cell = mb_convert_encoding($cell, $options['reportencoding'], $in_charset); - } - } - } - - // create new format object, if necessary (to avoid "too many cell formats" error) - if (!isset($fmt)) { - $fmt = &$wb->add_format($fmt_properties); - $fmt->properties = &$fmt_properties; - - // set vertical alignment - if (isset($fmt->properties['v_align'])) { - $fmt->set_align($fmt->properties['v_align']); - } else { - $fmt->set_align('top'); // default - } - } - - // write cell - if (is_numeric($cell) && !preg_match("/^0./", $cell)) { - $ws->write_number($row, $col, $cell, $fmt); - } else { - $ws->write_string($row, $col, $cell, $fmt); - } - } // end foreach $col - - // increment $row - $row++; - } + function print_excel_report(&$course, &$hotpot, &$tables, &$options) { + global $CFG; + + // create Excel workbook + if (file_exists("$CFG->libdir/excellib.class.php")) { + // Moodle >= 1.6 + require_once("$CFG->libdir/excellib.class.php"); + $wb = new MoodleExcelWorkbook("-"); + } else { + // Moodle <= 1.5 + require_once("$CFG->libdir/excel/Worksheet.php"); + require_once("$CFG->libdir/excel/Workbook.php"); + $wb = new Workbook("-"); + } + + // send HTTP headers + $this->print_excel_headers($wb, $course, $hotpot); + + // create one worksheet for each table + foreach($tables as $table) { + unset($ws); + $ws = &$wb->add_worksheet(empty($table->caption) ? '' : strip_tags($table->caption)); + + $row = 0; + $this->print_excel_head($wb, $ws, $table, $row, $options); + $this->print_excel_data($wb, $ws, $table, $row, $options); + $this->print_excel_stat($wb, $ws, $table, $row, $options); + $this->print_excel_foot($wb, $ws, $table, $row, $options); + } + + // close the workbook (and send it to the browser) + $wb->close(); + } + function print_excel_headers(&$wb, &$course, &$hotpot) { + $downloadfilename = clean_filename("$course->shortname $hotpot->name.xls"); + if (method_exists($wb, 'send')) { + // Moodle >=1.6 + $wb->send($downloadfilename); + } else { + // Moodle <=1.5 + header("Content-type: application/vnd.ms-excel"); + header("Content-Disposition: attachment; filename=$downloadfilename" ); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0,pre-check=0"); + header("Pragma: public"); + } + } + function print_excel_head(&$wb, &$ws, &$table, &$row, &$options) { + // define format properties + $properties = array( + 'bold'=>1, + 'align'=>'center', + 'v_align'=>'bottom', + 'text_wrap'=>1 + ); + + // expand multi-column and multi-row cells + $this->expand_spans($table, 'head'); + + // print the headings + $this->print_excel_cells($wb, $ws, $table, $row, $properties, $table->head, $options); + } + function print_excel_data(&$wb, &$ws, &$table, &$row, &$options) { + // do nothing if there are no cells + if (empty($table->data)) return; + + // define format properties + $properties = array('text_wrap' => (empty($options['reportwrapdata']) ? 0 : 1)); + + // expand multi-column and multi-row cells + $this->expand_spans($table, 'data'); + + // print rows + foreach ($table->data as $cells) { + $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options); + } + } + function print_excel_stat(&$wb, &$ws, &$table, &$row, &$options) { + // do nothing if there are no cells + if (empty($table->stat)) return; + + // define format properties + $properties = array('align'=>'right'); + + // expand multi-column and multi-row cells + $this->expand_spans($table, 'stat'); + + // print rows + $i_count = count($table->stat); + foreach ($table->stat as $i => $cells) { + + // set border on top and bottom row + $properties['top'] = ($i==0) ? 1 : 0; + $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0; + + // print this row + $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options, $table->statheadercols); + } + } + function print_excel_foot(&$wb, &$ws, &$table, &$row, &$options) { + // do nothing if there are no cells + if (empty($table->foot)) return; + + // define format properties + $properties = array('bold'=>1, 'align'=>'center'); + + // expand multi-column and multi-row cells + $this->expand_spans($table, 'foot'); + + // print rows + $i_count = count($table->foot); + foreach ($table->foot as $i => $cells) { + + // set border on top and bottom row + $properties['top'] = ($i==0) ? 1 : 0; + $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0; + + // print this footer row + $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options); + } + } + + function print_excel_cells(&$wb, &$ws, &$table, &$row, &$properties, &$cells, &$options, $statheadercols=NULL) { + // do nothing if there are no cells + if (empty($cells) || is_string($cells)) return; + + // print cells + foreach($cells as $col => $cell) { + + unset($fmt_properties); + $fmt_properties = $properties; + + if (empty($fmt_properties['text_wrap'])) { + if (strlen("$cell")>=9) { + // long cell value + $fmt_properties['align'] = 'left'; + } + } else { + if (strlen("$cell")<9 && strpos("$cell", "\n")===false) { + // short cell value (wrapping not required) + $fmt_properties['text_wrap'] = 0; + } + } + + // set bold, if required (for stat) + if (isset($statheadercols)) { + $fmt_properties['bold'] = in_array($col, $statheadercols) ? 1 : 0; + $fmt_properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col]; + } + + // set align, if required + if (isset($table->align[$col]) && empty($fmt_properties['align'])) { + $fmt_properties['align'] = $table->align[$col]; + } + + // check to see that an identical format object has not already been created + unset($fmt); + + if (isset($wb->pear_excel_workbook)) { + // Moodle >=1.6 + $fmt_properties_obj = (object)$fmt_properties; + foreach ($wb->pear_excel_workbook->_formats as $id=>$format) { + if ($format==$fmt_properties_obj) { + $fmt = &$wb->pear_excel_workbook->_formats[$id]; + break; + } + } + } else { + // Moodle <=1.5 + foreach ($wb->formats as $id=>$format) { + if (isset($format->properties) && $format->properties==$fmt_properties) { + $fmt = &$wb->formats[$id]; + break; + } + } + if (is_numeric($cell) || empty($options['reportencoding'])) { + // do nothing + } else { + $in_charset = ''; + if (function_exists('mb_convert_encoding')) { + $in_charset = mb_detect_encoding($cell, 'auto'); + } + if (empty($in_charset)) { + $in_charset = get_string('thischarset'); + } + if ($in_charset != 'ASCII' && function_exists('mb_convert_encoding')) { + $cell = mb_convert_encoding($cell, $options['reportencoding'], $in_charset); + } + } + } + + // create new format object, if necessary (to avoid "too many cell formats" error) + if (!isset($fmt)) { + $fmt = &$wb->add_format($fmt_properties); + $fmt->properties = &$fmt_properties; + + // set vertical alignment + if (isset($fmt->properties['v_align'])) { + $fmt->set_align($fmt->properties['v_align']); + } else { + $fmt->set_align('top'); // default + } + } + + // write cell + if (is_numeric($cell) && !preg_match("/^0./", $cell)) { + $ws->write_number($row, $col, $cell, $fmt); + } else { + $ws->write_string($row, $col, $cell, $fmt); + } + } // end foreach $col + + // increment $row + $row++; + } } ?> diff --git a/mod/hotpot/review.php b/mod/hotpot/review.php index 8d2b8fcad8..06f1169654 100644 --- a/mod/hotpot/review.php +++ b/mod/hotpot/review.php @@ -1,240 +1,240 @@ course)) { - error("Course is misconfigured"); - } - if (! $hotpot = get_record("hotpot", "id", $cm->instance)) { - error("Course module is incorrect"); - } - } else { - if (! $hotpot = get_record("hotpot", "id", $hp)) { - error("Course module is incorrect"); - } - if (! $course = get_record("course", "id", $hotpot->course)) { - error("Course is misconfigured"); - } - if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { - error("Course Module ID was incorrect"); - } - } - if (! $attempt = get_record("hotpot_attempts", "id", $attempt)) { - error("Attempt ID was incorrect"); - } - require_login($course->id); - if (!isteacher($course->id)) { - if (!$hotpot->review) { - error(get_string("noreview", "quiz")); - } - //if (time() < $hotpot->timeclose) { - // error(get_string("noreviewuntil", "quiz", userdate($hotpot->timeclose))); - //} - if ($attempt->userid != $USER->id) { - error("This is not your attempt!"); - } - } - add_to_log($course->id, "hotpot", "review", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id"); + require_once("../../config.php"); + require_once("lib.php"); + $id = optional_param("id"); // Course Module ID, or + $hp = optional_param("hp"); // hotpot ID + $attempt = required_param("attempt"); // A particular attempt ID for review + if ($id) { + if (! $cm = get_coursemodule_from_id('hotpot', $id)) { + error("Course Module ID was incorrect"); + } + if (! $course = get_record("course", "id", $cm->course)) { + error("Course is misconfigured"); + } + if (! $hotpot = get_record("hotpot", "id", $cm->instance)) { + error("Course module is incorrect"); + } + } else { + if (! $hotpot = get_record("hotpot", "id", $hp)) { + error("Course module is incorrect"); + } + if (! $course = get_record("course", "id", $hotpot->course)) { + error("Course is misconfigured"); + } + if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { + error("Course Module ID was incorrect"); + } + } + if (! $attempt = get_record("hotpot_attempts", "id", $attempt)) { + error("Attempt ID was incorrect"); + } + require_login($course->id); + if (!isteacher($course->id)) { + if (!$hotpot->review) { + error(get_string("noreview", "quiz")); + } + //if (time() < $hotpot->timeclose) { + // error(get_string("noreviewuntil", "quiz", userdate($hotpot->timeclose))); + //} + if ($attempt->userid != $USER->id) { + error("This is not your attempt!"); + } + } + add_to_log($course->id, "hotpot", "review", "review.php?id=$cm->id&attempt=$attempt->id", "$hotpot->id", "$cm->id"); // Print the page header - $strmodulenameplural = get_string("modulenameplural", "hotpot"); - $strmodulename = get_string("modulename", "hotpot"); - // print header - $title = "$course->shortname: $hotpot->name"; - $heading = "$course->fullname"; - $navigation = "id\">$strmodulenameplural -> ".get_string("review", "quiz"); - if ($course->category) { - $navigation = "id\">$course->shortname -> $navigation"; - } - $button = update_module_button($cm->id, $course->id, $strmodulename); - print_header($title, $heading, $navigation, "", "", true, $button, navmenu($course, $cm)); - print ''; // for overlib - print_heading($hotpot->name); - hotpot_print_attempt_summary($hotpot, $attempt); - hotpot_print_review_buttons($course, $hotpot, $attempt); - $action = isteacher($course->id) ? optional_param('action') : ''; - if ($action) { - $xml = get_field('hotpot_details', 'details', 'attempt', $attempt->id); - print '
    '; - switch ($action) { - case 'showxmltree': - print '
    ';
    -				$xml_tree = new hotpot_xml_tree($xml, "['hpjsresult']['#']");
    -				print_r ($xml_tree->xml_value('fields'));
    -				print '
    '; - break; - case 'showxmlsource': - print htmlspecialchars($xml); - break; - default: - print "Action '$action' not recognized"; - } - print '
    '; - } else { - hotpot_print_attempt_details($hotpot, $attempt); - } - hotpot_print_review_buttons($course, $hotpot, $attempt); - print_footer($course); + $strmodulenameplural = get_string("modulenameplural", "hotpot"); + $strmodulename = get_string("modulename", "hotpot"); + // print header + $title = "$course->shortname: $hotpot->name"; + $heading = "$course->fullname"; + $navigation = "id\">$strmodulenameplural -> ".get_string("review", "quiz"); + if ($course->category) { + $navigation = "id\">$course->shortname -> $navigation"; + } + $button = update_module_button($cm->id, $course->id, $strmodulename); + print_header($title, $heading, $navigation, "", "", true, $button, navmenu($course, $cm)); + print ''; // for overlib + print_heading($hotpot->name); + hotpot_print_attempt_summary($hotpot, $attempt); + hotpot_print_review_buttons($course, $hotpot, $attempt); + $action = isteacher($course->id) ? optional_param('action') : ''; + if ($action) { + $xml = get_field('hotpot_details', 'details', 'attempt', $attempt->id); + print '
    '; + switch ($action) { + case 'showxmltree': + print '
    ';
    +                $xml_tree = new hotpot_xml_tree($xml, "['hpjsresult']['#']");
    +                print_r ($xml_tree->xml_value('fields'));
    +                print '
    '; + break; + case 'showxmlsource': + print htmlspecialchars($xml); + break; + default: + print "Action '$action' not recognized"; + } + print '
    '; + } else { + hotpot_print_attempt_details($hotpot, $attempt); + } + hotpot_print_review_buttons($course, $hotpot, $attempt); + print_footer($course); /////////////////////////// // functions /////////////////////////// function hotpot_print_attempt_summary(&$hotpot, &$attempt) { - // start table - print_simple_box_start("center", "80%", "#ffffff", 0); - print ''."\n"; - // add attempt properties - $fields = array('attempt', 'score', 'penalties', 'status', 'timetaken', 'timerecorded'); - foreach ($fields as $field) { - switch ($field) { - case 'score': - $value = hotpot_format_score($attempt); - break; - case 'status': - $value = hotpot_format_status($attempt); - break; - case 'timerecorded': - $value = empty($attempt->timefinish) ? '-' : userdate($attempt->timefinish); - break; - case 'timetaken': - $value = empty($attempt->timefinish) ? '-' : format_time($attempt->timefinish - $attempt->timestart); - break; - default: - $value = isset($attempt->$field) ? $attempt->$field : NULL; - } - if (isset($value)) { - switch ($field) { - case 'status': - case 'timerecorded': - $name = get_string('report'.$field, 'hotpot'); - break; - case 'penalties': - $name = get_string('penalties', 'hotpot'); - break; - default: - $name = get_string($field, 'quiz'); - } - print ''; - } - } - // finish table - print '
    '.$name.':'.$value.'
    '; - print_simple_box_end(); + // start table + print_simple_box_start("center", "80%", "#ffffff", 0); + print ''."\n"; + // add attempt properties + $fields = array('attempt', 'score', 'penalties', 'status', 'timetaken', 'timerecorded'); + foreach ($fields as $field) { + switch ($field) { + case 'score': + $value = hotpot_format_score($attempt); + break; + case 'status': + $value = hotpot_format_status($attempt); + break; + case 'timerecorded': + $value = empty($attempt->timefinish) ? '-' : userdate($attempt->timefinish); + break; + case 'timetaken': + $value = empty($attempt->timefinish) ? '-' : format_time($attempt->timefinish - $attempt->timestart); + break; + default: + $value = isset($attempt->$field) ? $attempt->$field : NULL; + } + if (isset($value)) { + switch ($field) { + case 'status': + case 'timerecorded': + $name = get_string('report'.$field, 'hotpot'); + break; + case 'penalties': + $name = get_string('penalties', 'hotpot'); + break; + default: + $name = get_string($field, 'quiz'); + } + print ''; + } + } + // finish table + print '
    '.$name.':'.$value.'
    '; + print_simple_box_end(); } function hotpot_print_review_buttons(&$course, &$hotpot, &$attempt) { - print "\n".''; - print "\n\n".'\n".'\n".'\n\n"; - print '\n"; - print "
    '; - print_single_button("report.php?hp=$hotpot->id", NULL, get_string('continue'), 'post'); - if (isteacher($course->id) && record_exists('hotpot_details', 'attempt', $attempt->id)) { - print "'; - print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmlsource", NULL, get_string('showxmlsource', 'hotpot'), 'post'); - print "'; - print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmltree", NULL, get_string('showxmltree', 'hotpot'), 'post'); - $colspan = 3; - } else { - $colspan = 1; - } - print "
    '; - print_spacer(4, 1, false); // height=4, width=1, no
    - print "
    \n"; + print "\n".''; + print "\n\n".'\n".'\n".'\n\n"; + print '\n"; + print "
    '; + print_single_button("report.php?hp=$hotpot->id", NULL, get_string('continue'), 'post'); + if (isteacher($course->id) && record_exists('hotpot_details', 'attempt', $attempt->id)) { + print "'; + print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmlsource", NULL, get_string('showxmlsource', 'hotpot'), 'post'); + print "'; + print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmltree", NULL, get_string('showxmltree', 'hotpot'), 'post'); + $colspan = 3; + } else { + $colspan = 1; + } + print "
    '; + print_spacer(4, 1, false); // height=4, width=1, no
    + print "
    \n"; } function hotpot_print_attempt_details(&$hotpot, &$attempt) { - // define fields to print - $textfields = array('correct', 'ignored', 'wrong'); - $numfields = array('score', 'weighting', 'hints', 'clues', 'checks'); - $fields = array_merge($textfields, $numfields); - $q = array(); // questions - $f = array(); // fields - foreach ($fields as $field) { - $name = get_string($field, 'hotpot'); - $f[$field] = array('count'=>0, 'name'=>$name); - } - // get questions and responses for this attempt - $questions = get_records_select('hotpot_questions', "hotpot='$hotpot->id'", 'id'); - $responses = get_records_select('hotpot_responses', "attempt='$attempt->id'", 'id'); - if ($questions && $responses) { - foreach ($responses as $response) { - $id = $response->question; - foreach ($fields as $field) { - if (!isset($f[$field])) { - $name = get_string($field, 'hotpot'); - $f[$field] = array('count'=>0, 'name'=>$name); - } - if (isset($response->$field)) { - $f[$field]['count']++; - if (!isset($q[$id])) { - $name = hotpot_get_question_name($questions[$id]); - $q[$id] = array('name'=>$name); - } - $q[$id][$field] = $response->$field; - } - } - } - } - // count the number of columns required in the table - $colspan = 0; - foreach ($numfields as $field) { - if ($f[$field]['count']) { - $colspan += 2; - } - } - $colspan = max(2, $colspan); - // start table of questions and responses - print_simple_box_start("center", "80%", "#ffffff", 0); - print ''."\n"; - if (empty($q)) { - print '\n"; - } else { - // flag to ensure separators are only printed before the 2nd and subsequent questions - $printseparator = false; - foreach ($q as $i=>$question) { - // flag to ensure questions are only printed when there is at least one response - $printedquestion = false; - // add rows of text fields - foreach ($textfields as $field) { - if (isset($question[$field])) { - $text = hotpot_strings($question[$field]); - if (trim($text)) { - // print question if necessary - if (!$printedquestion) { - if ($printseparator) { - print ''."\n"; - } - $printseparator = true; - print ''."\n"; - $printedquestion = true; - } - // print response - print ''."\n"; - } - } - } - // add row of numeric fields - print ''; - foreach ($numfields as $field) { - if ($f[$field]['count']) { - // print question if necessary - if (!$printedquestion) { - print '\n"; - $printedquestion = true; - } - // print numeric response - $value = isset($question[$field]) ? $question[$field] : '-'; - print ''; - } - } - print "\n"; - } // foreach $q - } - // finish table - print "
    '.get_string("noresponses", "hotpot")."
    '.$question['name'].'
    '.$f[$field]['name'].':'.$text.'
    '.$question['name']."
    '.$f[$field]['name'].':'.$value.'
    \n"; - print_simple_box_end(); + // define fields to print + $textfields = array('correct', 'ignored', 'wrong'); + $numfields = array('score', 'weighting', 'hints', 'clues', 'checks'); + $fields = array_merge($textfields, $numfields); + $q = array(); // questions + $f = array(); // fields + foreach ($fields as $field) { + $name = get_string($field, 'hotpot'); + $f[$field] = array('count'=>0, 'name'=>$name); + } + // get questions and responses for this attempt + $questions = get_records_select('hotpot_questions', "hotpot='$hotpot->id'", 'id'); + $responses = get_records_select('hotpot_responses', "attempt='$attempt->id'", 'id'); + if ($questions && $responses) { + foreach ($responses as $response) { + $id = $response->question; + foreach ($fields as $field) { + if (!isset($f[$field])) { + $name = get_string($field, 'hotpot'); + $f[$field] = array('count'=>0, 'name'=>$name); + } + if (isset($response->$field)) { + $f[$field]['count']++; + if (!isset($q[$id])) { + $name = hotpot_get_question_name($questions[$id]); + $q[$id] = array('name'=>$name); + } + $q[$id][$field] = $response->$field; + } + } + } + } + // count the number of columns required in the table + $colspan = 0; + foreach ($numfields as $field) { + if ($f[$field]['count']) { + $colspan += 2; + } + } + $colspan = max(2, $colspan); + // start table of questions and responses + print_simple_box_start("center", "80%", "#ffffff", 0); + print ''."\n"; + if (empty($q)) { + print '\n"; + } else { + // flag to ensure separators are only printed before the 2nd and subsequent questions + $printseparator = false; + foreach ($q as $i=>$question) { + // flag to ensure questions are only printed when there is at least one response + $printedquestion = false; + // add rows of text fields + foreach ($textfields as $field) { + if (isset($question[$field])) { + $text = hotpot_strings($question[$field]); + if (trim($text)) { + // print question if necessary + if (!$printedquestion) { + if ($printseparator) { + print ''."\n"; + } + $printseparator = true; + print ''."\n"; + $printedquestion = true; + } + // print response + print ''."\n"; + } + } + } + // add row of numeric fields + print ''; + foreach ($numfields as $field) { + if ($f[$field]['count']) { + // print question if necessary + if (!$printedquestion) { + print '\n"; + $printedquestion = true; + } + // print numeric response + $value = isset($question[$field]) ? $question[$field] : '-'; + print ''; + } + } + print "\n"; + } // foreach $q + } + // finish table + print "
    '.get_string("noresponses", "hotpot")."
    '.$question['name'].'
    '.$f[$field]['name'].':'.$text.'
    '.$question['name']."
    '.$f[$field]['name'].':'.$value.'
    \n"; + print_simple_box_end(); } ?> diff --git a/mod/hotpot/show.php b/mod/hotpot/show.php index 923780f038..2905ec256f 100644 --- a/mod/hotpot/show.php +++ b/mod/hotpot/show.php @@ -1,68 +1,68 @@ action = required_param('action'); - $params->course = required_param('course'); - $params->reference = required_param('reference'); - require_login($params->course); - if (!isteacher($params->course)) { - error("You are not allowed to view this page!"); - } - if (isadmin()) { - $params->location = optional_param('location', HOTPOT_LOCATION_COURSEFILES); - } else { - $params->location = HOTPOT_LOCATION_COURSEFILES; - } - $title = get_string($params->action, 'hotpot').': '.$params->reference; - print_header($title, $title); - hotpot_print_show_links($params->course, $params->location, $params->reference); + require_once("../../config.php"); + require_once("lib.php"); + require_login(); + // fetch and clean the required $_GET parameters + // (script stops here if any parameters are missing) + unset($params); + $params->action = required_param('action'); + $params->course = required_param('course'); + $params->reference = required_param('reference'); + require_login($params->course); + if (!isteacher($params->course)) { + error("You are not allowed to view this page!"); + } + if (isadmin()) { + $params->location = optional_param('location', HOTPOT_LOCATION_COURSEFILES); + } else { + $params->location = HOTPOT_LOCATION_COURSEFILES; + } + $title = get_string($params->action, 'hotpot').': '.$params->reference; + print_header($title, $title); + hotpot_print_show_links($params->course, $params->location, $params->reference); ?> '; - switch ($params->action) { - case 'showxmlsource': - print htmlspecialchars($hp->source); - break; - case 'showxmltree': - print_r($hp->xml); - break; - case 'showhtmlsource': - print htmlspecialchars($hp->html); - break; - case 'showhtmlquiz': - print $hp->html; - break; - } - print ''; - } else { - print_simple_box("Could not open Hot Potatoes XML file", "center", "", "#FFBBBB"); - } - print_simple_box_end(); - print '
    '; - close_window_button(); + print_simple_box_start("center", "96%"); + if($hp = new hotpot_xml_quiz($params)) { + print '
    ';
    +        switch ($params->action) {
    +            case 'showxmlsource':
    +                print htmlspecialchars($hp->source);
    +                break;
    +            case 'showxmltree':
    +                print_r($hp->xml);
    +                break;
    +            case 'showhtmlsource':
    +                print htmlspecialchars($hp->html);
    +                break;
    +            case 'showhtmlquiz':
    +                print $hp->html;
    +                break;
    +        }
    +        print '
    '; + } else { + print_simple_box("Could not open Hot Potatoes XML file", "center", "", "#FFBBBB"); + } + print_simple_box_end(); + print '
    '; + close_window_button(); ?> diff --git a/mod/hotpot/template/default.php b/mod/hotpot/template/default.php index da38d63eb0..4f35b28e3f 100644 --- a/mod/hotpot/template/default.php +++ b/mod/hotpot/template/default.php @@ -1,110 +1,110 @@ parent->template_dirpath.DIRECTORY_SEPARATOR.$filename; - // try and open the template file - if (!file_exists($filepath) || !is_readable($filepath)) { - $msg = 'Could not open the '.$this->parent->template_dir.' template file "'.$filepath.'"'; - error($msg, $this->parent->course_homeurl); - } - // read in the template and close the file - $this->$tag = file_get_contents($filepath); - // expand the blocks and strings in the template - $this->expand_blocks($tag); - $this->expand_strings($tag); - if ($tag=='temporary') { - $template = $this->$tag; - $this->$tag = ''; - return $template; - } - } - function expand_blocks($tag) { - // get block $names - // [1] the full block name (including optional leading 'str' or 'incl') - // [2] leading 'incl' or 'str', if any - // [3] the real block name ([1] without [2]) - $search = '/\[\/((incl|str)?(\w+))\]/'; - preg_match_all($search, $this->$tag, $names); - $i_max = count($names[0]); - for ($i=0; $i<$i_max; $i++) { - $method = $this->parent->template_dir.'_expand_'.$names[3][$i]; - if (method_exists($this, $method)) { - eval('$value=$this->'.$method.'();'); - $search = '/\['.$names[1][$i].'\](.*?)\[\/'.$names[1][$i].'\]/s'; - preg_match_all($search, $this->$tag, $blocks); - $ii_max = count($blocks[0]); - for ($ii=0; $ii<$ii_max; $ii++) { - $replace = empty($value) ? '' : $blocks[1][$ii]; - $this->$tag = str_replace($blocks[0][$ii], $replace, $this->$tag); - } - } else { - $msg = 'Template block expand method not found: "'.$method.'"'; - error($msg, $this->parent->course_homeurl); - } - } - } - function expand_strings($tag, $search='') { - if (empty($search)) { - // default $search $pattern - $search = '/\[(?:bool|int|str)(\\w+)\]/'; - } - preg_match_all($search, $this->$tag, $matches); - $i_max = count($matches[0]); - for ($i=0; $i<$i_max; $i++) { - $method = $this->parent->template_dir.'_expand_'.$matches[1][$i]; - if (method_exists($this, $method)) { - eval('$replace=$this->'.$method.'();'); - $this->$tag = str_replace($matches[0][$i], $replace, $this->$tag); - } - } - } - function bool_value($tags, $more_tags="[0]['#']") { - $value = $this->parent->xml_value($tags, $more_tags); - return empty($value) ? 'false' : 'true'; - } - function int_value($tags, $more_tags="[0]['#']") { - return intval($this->parent->xml_value($tags, $more_tags)); - } - function js_value($tags, $more_tags="[0]['#']", $convert_to_unicode=false) { - return $this->js_safe($this->parent->xml_value($tags, $more_tags), $convert_to_unicode); - } - function js_safe($str, $convert_to_unicode=false) { - // encode a string for javascript - // decode "<" and ">" - not necesary as it was done by xml_value() - // $str = strtr($str, array('<' => '<', '>' => '>')); - // escape single quotes and backslashes - $str = strtr($str, array("'"=>"\\'", '\\'=>'\\\\')); - // convert newlines (win = "\r\n", mac="\r", linix/unix="\n") - $nl = '\\n'; // javascript newline - $str = strtr($str, array("\r\n"=>$nl, "\r"=>$nl, "\n"=>$nl)); - // convert (hex and decimal) html entities to unicode, if required - if ($convert_to_unicode) { - $str = preg_replace('|&#x([0-9A-F]+);|i', '\\u\\1', $str); - $str = preg_replace('|&#(\d+);|e', "'\\u'.sprintf('%04X', '\\1')", $str); - } - return $str; - } - function get_halfway_color($x, $y) { - // returns the $color that is half way between $x and $y - $color = $x; // default - $rgb = '/^\#?([0-9a-f])([0-9a-f])([0-9a-f])$/i'; - $rrggbb = '/^\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i'; - if (( - preg_match($rgb, $x, $x_matches) || - preg_match($rrggbb, $x, $x_matches) - ) && ( - preg_match($rgb, $y, $y_matches) || - preg_match($rrggbb, $y, $y_matches) - )) { - $color = '#'; - for ($i=1; $i<=3; $i++) { - $x_dec = hexdec($x_matches[$i]); - $y_dec = hexdec($y_matches[$i]); - $color .= sprintf('%02x', min($x_dec, $y_dec) + abs($x_dec-$y_dec)/2); - } - } - return $color; - } + function read_template($filename, $tag='temporary') { + // create the file path to the template + $filepath = $this->parent->template_dirpath.DIRECTORY_SEPARATOR.$filename; + // try and open the template file + if (!file_exists($filepath) || !is_readable($filepath)) { + $msg = 'Could not open the '.$this->parent->template_dir.' template file "'.$filepath.'"'; + error($msg, $this->parent->course_homeurl); + } + // read in the template and close the file + $this->$tag = file_get_contents($filepath); + // expand the blocks and strings in the template + $this->expand_blocks($tag); + $this->expand_strings($tag); + if ($tag=='temporary') { + $template = $this->$tag; + $this->$tag = ''; + return $template; + } + } + function expand_blocks($tag) { + // get block $names + // [1] the full block name (including optional leading 'str' or 'incl') + // [2] leading 'incl' or 'str', if any + // [3] the real block name ([1] without [2]) + $search = '/\[\/((incl|str)?(\w+))\]/'; + preg_match_all($search, $this->$tag, $names); + $i_max = count($names[0]); + for ($i=0; $i<$i_max; $i++) { + $method = $this->parent->template_dir.'_expand_'.$names[3][$i]; + if (method_exists($this, $method)) { + eval('$value=$this->'.$method.'();'); + $search = '/\['.$names[1][$i].'\](.*?)\[\/'.$names[1][$i].'\]/s'; + preg_match_all($search, $this->$tag, $blocks); + $ii_max = count($blocks[0]); + for ($ii=0; $ii<$ii_max; $ii++) { + $replace = empty($value) ? '' : $blocks[1][$ii]; + $this->$tag = str_replace($blocks[0][$ii], $replace, $this->$tag); + } + } else { + $msg = 'Template block expand method not found: "'.$method.'"'; + error($msg, $this->parent->course_homeurl); + } + } + } + function expand_strings($tag, $search='') { + if (empty($search)) { + // default $search $pattern + $search = '/\[(?:bool|int|str)(\\w+)\]/'; + } + preg_match_all($search, $this->$tag, $matches); + $i_max = count($matches[0]); + for ($i=0; $i<$i_max; $i++) { + $method = $this->parent->template_dir.'_expand_'.$matches[1][$i]; + if (method_exists($this, $method)) { + eval('$replace=$this->'.$method.'();'); + $this->$tag = str_replace($matches[0][$i], $replace, $this->$tag); + } + } + } + function bool_value($tags, $more_tags="[0]['#']") { + $value = $this->parent->xml_value($tags, $more_tags); + return empty($value) ? 'false' : 'true'; + } + function int_value($tags, $more_tags="[0]['#']") { + return intval($this->parent->xml_value($tags, $more_tags)); + } + function js_value($tags, $more_tags="[0]['#']", $convert_to_unicode=false) { + return $this->js_safe($this->parent->xml_value($tags, $more_tags), $convert_to_unicode); + } + function js_safe($str, $convert_to_unicode=false) { + // encode a string for javascript + // decode "<" and ">" - not necesary as it was done by xml_value() + // $str = strtr($str, array('<' => '<', '>' => '>')); + // escape single quotes and backslashes + $str = strtr($str, array("'"=>"\\'", '\\'=>'\\\\')); + // convert newlines (win = "\r\n", mac="\r", linix/unix="\n") + $nl = '\\n'; // javascript newline + $str = strtr($str, array("\r\n"=>$nl, "\r"=>$nl, "\n"=>$nl)); + // convert (hex and decimal) html entities to unicode, if required + if ($convert_to_unicode) { + $str = preg_replace('|&#x([0-9A-F]+);|i', '\\u\\1', $str); + $str = preg_replace('|&#(\d+);|e', "'\\u'.sprintf('%04X', '\\1')", $str); + } + return $str; + } + function get_halfway_color($x, $y) { + // returns the $color that is half way between $x and $y + $color = $x; // default + $rgb = '/^\#?([0-9a-f])([0-9a-f])([0-9a-f])$/i'; + $rrggbb = '/^\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i'; + if (( + preg_match($rgb, $x, $x_matches) || + preg_match($rrggbb, $x, $x_matches) + ) && ( + preg_match($rgb, $y, $y_matches) || + preg_match($rrggbb, $y, $y_matches) + )) { + $color = '#'; + for ($i=1; $i<=3; $i++) { + $x_dec = hexdec($x_matches[$i]); + $y_dec = hexdec($y_matches[$i]); + $color .= sprintf('%02x', min($x_dec, $y_dec) + abs($x_dec-$y_dec)/2); + } + } + return $color; + } } ?> diff --git a/mod/hotpot/template/v6.php b/mod/hotpot/template/v6.php index 02a0346ee1..4389b59da2 100644 --- a/mod/hotpot/template/v6.php +++ b/mod/hotpot/template/v6.php @@ -2,1444 +2,1444 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default { - // constructor function for this class - function hotpot_xml_quiz_template(&$parent) { - - $this->parent = &$parent; - - $get_js = optional_param('js', false); - $get_css = optional_param('css', false); - - if (!empty($get_css)) { - // set $this->css - $this->v6_expand_StyleSheet(); - - } else if (!empty($get_js)) { - // set $this->js - $this->read_template($this->parent->draganddrop.$this->parent->quiztype.'6.js_', 'js'); - - } else { - // set $this->html - $this->read_template($this->parent->draganddrop.$this->parent->quiztype.'6.ht_', 'html'); - } - - // expand special strings, if any - $pattern = ''; - switch ($this->parent->quiztype) { - case 'jcloze': - $pattern = '/\[(PreloadImageList)\]/'; - break; - case 'jcross': - $pattern = '/\[(PreloadImageList|ShowHideClueList)\]/'; - break; - case 'jmatch': - $pattern = '/\[(PreloadImageList|QsToShow|FixedArray|DragArray)\]/'; - break; - case 'jmix': - $pattern = '/\[(PreloadImageList|SegmentArray|AnswerArray)\]/'; - break; - case 'jquiz': - $pattern = '/\[(PreloadImageList|QsToShow)\]/'; - break; - } - if (!empty($pattern)) { - $this->expand_strings('html', $pattern); - } - } - - // captions and messages - - function v6_expand_AlsoCorrect() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',also-correct'); - } - function v6_expand_CapitalizeFirst() { - return $this->bool_value('hotpot-config-file,'.$this->parent->quiztype.',capitalize-first-letter'); - } - function v6_expand_CheckCaption() { - return $this->parent->xml_value('hotpot-config-file,global,check-caption'); - } - function v6_expand_CorrectIndicator() { - return $this->js_value('hotpot-config-file,global,correct-indicator'); - } - function v6_expand_Back() { - return $this->int_value('hotpot-config-file,global,include-back'); - } - function v6_expand_BackCaption() { - return $this->parent->xml_value('hotpot-config-file,global,back-caption'); - } - function v6_expand_ClickToAdd() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',click-to-add'); - } - function v6_expand_ClueCaption() { - return $this->parent->xml_value('hotpot-config-file,global,clue-caption'); - } - function v6_expand_Clues() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-clues'); - } - function v6_expand_Contents() { - return $this->int_value('hotpot-config-file,global,include-contents'); - } - function v6_expand_ContentsCaption() { - return $this->parent->xml_value('hotpot-config-file,global,contents-caption'); - } - function v6_expand_GuessCorrect() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guess-correct'); - } - function v6_expand_GuessIncorrect() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guess-incorrect'); - } - function v6_expand_Hint() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-hint'); - } - function v6_expand_HintCaption() { - return $this->parent->xml_value('hotpot-config-file,global,hint-caption'); - } - function v6_expand_IncorrectIndicator() { - return $this->js_value('hotpot-config-file,global,incorrect-indicator'); - } - function v6_expand_LastQCaption() { - return $this->parent->xml_value('hotpot-config-file,global,last-q-caption'); - } - function v6_expand_NextCorrect() { - $value = $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',next-correct-part'); - if (empty($value)) { // jquiz - $value = $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',next-correct-letter'); - } - return $value; - } - function v6_expand_NextEx() { - return $this->int_value('hotpot-config-file,global,include-next-ex'); - } - function v6_expand_NextExCaption() { - return $this->parent->xml_value('hotpot-config-file,global,next-ex-caption'); - } - function v6_expand_NextQCaption() { - return $this->parent->xml_value('hotpot-config-file,global,next-q-caption'); - } - function v6_expand_OKCaption() { - return $this->parent->xml_value('hotpot-config-file,global,ok-caption'); - } - function v6_expand_Restart() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-restart'); - } - function v6_expand_RestartCaption() { - return $this->parent->xml_value('hotpot-config-file,global,restart-caption'); - } - function v6_expand_ShowAllQuestionsCaption() { - return $this->js_value('hotpot-config-file,global,show-all-questions-caption'); - } - function v6_expand_ShowOneByOneCaption() { - return $this->js_value('hotpot-config-file,global,show-one-by-one-caption'); - } - function v6_expand_TheseAnswersToo() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',also-correct'); - } - function v6_expand_ThisMuch() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',this-much-correct'); - } - function v6_expand_Undo() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-undo'); - } - function v6_expand_UndoCaption() { - return $this->parent->xml_value('hotpot-config-file,global,undo-caption'); - } - function v6_expand_YourScoreIs() { - return $this->js_value('hotpot-config-file,global,your-score-is'); - } - - // reading - - function v6_expand_Reading() { - return $this->int_value('data,reading,include-reading'); - } - function v6_expand_ReadingText() { - $title = $this->v6_expand_ReadingTitle(); - $value = $this->parent->xml_value('data,reading,reading-text'); - $value = empty($value) ? '' : ('
    '.$value.'
    '); - return $title.$value; - } - function v6_expand_ReadingTitle() { - $value = $this->parent->xml_value('data,reading,reading-title'); - return empty($value) ? '' : ('

    '.$value.'

    '); - } - - // timer - - function v6_expand_Timer() { - return $this->int_value('data,timer,include-timer'); - } - function v6_expand_JSTimer() { - return $this->read_template('hp6timer.js_'); - } - function v6_expand_Seconds() { - return $this->parent->xml_value('data,timer,seconds'); - } - - // send results - - function v6_expand_SendResults() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',send-email'); - } - function v6_expand_JSSendResults() { - return $this->read_template('hp6sendresults.js_'); - } - function v6_expand_FormMailURL() { - return $this->parent->xml_value('hotpot-config-file,global,formmail-url'); - } - function v6_expand_EMail() { - return $this->parent->xml_value('hotpot-config-file,global,email'); - } - function v6_expand_NamePlease() { - return $this->js_value('hotpot-config-file,global,name-please'); - } - - // preload images - - function v6_expand_PreloadImages() { - $value = $this->v6_expand_PreloadImageList(); - return empty($value) ? false : true; - } - function v6_expand_PreloadImageList() { - - // check it has not been set already - if (!isset($this->PreloadImageList)) { - - // the list of image urls - $list = array(); - - // extract tags - $img_tag = htmlspecialchars('|<img.*?src="(.*?)".*?>|is'); - if (preg_match_all($img_tag, $this->parent->source, $matches)) { - $list = $matches[1]; - - // remove duplicates - $list = array_unique($list); - } - - // convert to comma delimited string - $this->PreloadImageList = empty($list) ? '' : "'".implode(',', $list)."'"; - } - return $this->PreloadImageList; - } - - // html files (all quiz types) - - function v6_expand_PlainTitle() { - return $this->parent->xml_value('data,title'); - } - function v6_expand_ExerciseSubtitle() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',exercise-subtitle'); - } - function v6_expand_Instructions() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',instructions'); - } - function v6_expand_DublinCoreMetadata() { - $dc = ''."\n"; - if (is_string($this->parent->xml_value('rdf:RDF,rdf:Description'))) { - // do nothing (there is no more dc info) - } else { - $dc .= ''."\n"; - $dc .= ''."\n"; - } - return $dc; - } - function v6_expand_FullVersionInfo() { - global $CFG; - require_once($CFG->hotpotroot.DIRECTORY_SEPARATOR.'version.php'); // set $module - return $this->parent->xml_value('version').'.x (Moodle '.$CFG->release.', hotpot-module '.$this->parent->obj_value($module, 'release').')'; - } - function v6_expand_HeaderCode() { - return $this->parent->xml_value('hotpot-config-file,global,header-code'); - } - function v6_expand_StyleSheet() { - $this->read_template('hp6.cs_', 'css'); - $this->css = hotpot_convert_stylesheets_urls($this->parent->get_baseurl(), $this->parent->reference, $this->css); - return $this->css; - } - - // stylesheet (hp6.cs_) - - function v6_expand_PageBGColor() { - return $this->parent->xml_value('hotpot-config-file,global,page-bg-color'); - } - function v6_expand_GraphicURL() { - return $this->parent->xml_value('hotpot-config-file,global,graphic-url'); - } - function v6_expand_ExBGColor() { - return $this->parent->xml_value('hotpot-config-file,global,ex-bg-color'); - } - - function v6_expand_FontFace() { - return $this->parent->xml_value('hotpot-config-file,global,font-face'); - } - function v6_expand_FontSize() { - return $this->parent->xml_value('hotpot-config-file,global,font-size'); - } - function v6_expand_TextColor() { - return $this->parent->xml_value('hotpot-config-file,global,text-color'); - } - function v6_expand_TitleColor() { - return $this->parent->xml_value('hotpot-config-file,global,title-color'); - } - function v6_expand_LinkColor() { - return $this->parent->xml_value('hotpot-config-file,global,link-color'); - } - function v6_expand_VLinkColor() { - return $this->parent->xml_value('hotpot-config-file,global,vlink-color'); - } - - function v6_expand_NavTextColor() { - return $this->parent->xml_value('hotpot-config-file,global,page-bg-color'); - } - function v6_expand_NavBarColor() { - return $this->parent->xml_value('hotpot-config-file,global,nav-bar-color'); - } - function v6_expand_NavLightColor() { - $color = $this->parent->xml_value('hotpot-config-file,global,nav-bar-color'); - return $this->get_halfway_color($color, '#ffffff'); - } - function v6_expand_NavShadeColor() { - $color = $this->parent->xml_value('hotpot-config-file,global,nav-bar-color'); - return $this->get_halfway_color($color, '#000000'); - } - - function v6_expand_FuncLightColor() { // top-left of buttons - $color = $this->parent->xml_value('hotpot-config-file,global,ex-bg-color'); - return $this->get_halfway_color($color, '#ffffff'); - } - function v6_expand_FuncShadeColor() { // bottom right of buttons - $color = $this->parent->xml_value('hotpot-config-file,global,ex-bg-color'); - return $this->get_halfway_color($color, '#000000'); - } - - // navigation buttons - - function v6_expand_NavButtons() { - $back = $this->v6_expand_Back(); - $next_ex = $this->v6_expand_NextEx(); - $contents = $this->v6_expand_Contents(); - return (empty($back) && empty($next_ex) && empty($contents) ? false : true); - } - function v6_expand_NavBarJS() { - return $this->v6_expand_NavButtons(); - } - - // js files (all quiz types) - - function v6_expand_JSBrowserCheck() { - return $this->read_template('hp6browsercheck.js_'); - } - function v6_expand_JSButtons() { - return $this->read_template('hp6buttons.js_'); - } - function v6_expand_JSCard() { - return $this->read_template('hp6card.js_'); - } - function v6_expand_JSCheckShortAnswer() { - return $this->read_template('hp6checkshortanswer.js_'); - } - function v6_expand_JSHotPotNet() { - return $this->read_template('hp6hotpotnet.js_'); - } - function v6_expand_JSShowMessage() { - return $this->read_template('hp6showmessage.js_'); - } - function v6_expand_JSUtilities() { - return $this->read_template('hp6utilities.js_'); - } - - // js files - - function v6_expand_JSJCloze6() { - return $this->read_template('jcloze6.js_'); - } - function v6_expand_JSJCross6() { - return $this->read_template('jcross6.js_'); - } - function v6_expand_JSJMatch6() { - return $this->read_template('jmatch6.js_'); - } - function v6_expand_JSJMix6() { - return $this->read_template('jmix6.js_'); - } - function v6_expand_JSJQuiz6() { - return $this->read_template('jquiz6.js_'); - } - - // drag and drop - - function v6_expand_JSDJMatch6() { - return $this->read_template('djmatch6.js_'); - } - function v6_expand_JSDJMix6() { - return $this->read_template('djmix6.js_'); - } - - // what are these for? - - function v6_expand_JSFJMatch6() { - return $this->read_template('fjmatch6.js_'); - } - function v6_expand_JSFJMix6() { - return $this->read_template('fjmix6.js_'); - } - - // jmatch6.js_ - - function v6_expand_ShuffleQs() { - return $this->bool_value('hotpot-config-file,'.$this->parent->quiztype.',shuffle-questions'); - } - function v6_expand_QsToShow() { - $i = $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',show-limited-questions'); - if ($i) { - $i = $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',questions-to-show'); - } - if (empty($i)) { - $i = 0; - switch ($this->parent->quiztype) { - case 'jmatch': - $values = $this->parent->xml_values('data,matching-exercise,pair'); - $i = count($values); - break; - case 'jquiz': - while ($this->parent->xml_value('data,questions,question-record', "[$i]['#']['question'][0]['#']")) { - $i++; - } - break; - } // end switch - } - return $i; - } - function v6_expand_MatchDivItems() { - $l_items = array(); - $r_items = array(); - $this->get_jmatch_items($l_items, $r_items); - - $l_keys = $this->shuffle_jmatch_items($l_items); - $r_keys = $this->shuffle_jmatch_items($r_items); - - $options = ''; - foreach ($r_keys as $key) { - $options .= ''."\n"; - } - - $str = ''; - foreach ($l_keys as $key) { - $str .= ''.$l_items[$key]['text'][0]['#'].''; - $str .= ''; - $str .= ''; - } - return $str; - } - - // jmix6.js_ - - function v6_expand_Punctuation() { - $tags = 'data,jumbled-order-exercise'; - $chars = array_merge( - $this->jmix_Punctuation("$tags,main-order,segment"), - $this->jmix_Punctuation("$tags,alternate") - ); - $chars = array_unique($chars); - $chars = implode('', $chars); - $chars = $this->js_safe($chars, true); - return $chars; - } - function jmix_Punctuation($tags) { - $chars = array(); - - // all punctutation except '&#;' (because they are used in html entities) - $ENTITIES = $this->jmix_encode_punctuation('!"$%'."'".'()*+,-./:<=>?@[\]^_`{|}~'); - $pattern = "/&#x([0-9A-F]+);/i"; - $i = 0; - - // get next segment (or alternate answer) - while ($value = $this->parent->xml_value($tags, "[$i]['#']")) { - - // convert low-ascii punctuation to entities - $value = strtr($value, $ENTITIES); - - // extract all hex HTML entities - if (preg_match_all($pattern, $value, $matches)) { - - // loop through hex entities - $m_max = count($matches[0]); - for ($m=0; $m<$m_max; $m++) { - - // convert to hex number - eval('$hex=0x'.$matches[1][$m].';'); - - // is this a punctuation character? - if ( - ($hex>=0x0020 && $hex<=0x00BF) || // ascii punctuation - ($hex>=0x2000 && $hex<=0x206F) || // general punctuation - ($hex>=0x3000 && $hex<=0x303F) || // CJK punctuation - ($hex>=0xFE30 && $hex<=0xFE4F) || // CJK compatability - ($hex>=0xFE50 && $hex<=0xFE6F) || // small form variants - ($hex>=0xFF00 && $hex<=0xFF40) || // halfwidth and fullwidth forms (1) - ($hex>=0xFF5B && $hex<=0xFF65) || // halfwidth and fullwidth forms (2) - ($hex>=0xFFE0 && $hex<=0xFFEE) // halfwidth and fullwidth forms (3) - ) { - // add this character - $chars[] = $matches[0][$m]; - } - } - } - $i++; - } - - return $chars; - } - function v6_expand_OpenPunctuation() { - $tags = 'data,jumbled-order-exercise'; - $chars = array_merge( - $this->jmix_OpenPunctuation("$tags,main-order,segment"), - $this->jmix_OpenPunctuation("$tags,alternate") - ); - $chars = array_unique($chars); - $chars = implode('', $chars); - $chars = $this->js_safe($chars, true); - return $chars; - } - function jmix_OpenPunctuation($tags) { - $chars = array(); - - // unicode punctuation designations (pi="initial quote", ps="open") - // http://www.sql-und-xml.de/unicode-database/pi.html - // http://www.sql-und-xml.de/unicode-database/ps.html - $pi = '0022|0027|00AB|2018|201B|201C|201F|2039'; - $ps = '0028|005B|007B|0F3A|0F3C|169B|201A|201E|2045|207D|208D|2329|23B4|2768|276A|276C|276E|2770|2772|2774|27E6|27E8|27EA|2983|2985|2987|2989|298B|298D|298F|2991|2993|2995|2997|29D8|29DA|29FC|3008|300A|300C|300E|3010|3014|3016|3018|301A|301D|FD3E|FE35|FE37|FE39|FE3B|FE3D|FE3F|FE41|FE43|FE47|FE59|FE5B|FE5D|FF08|FF3B|FF5B|FF5F|FF62'; - $pattern = "/(&#x($pi|$ps);)/i"; - - $ENTITIES = $this->jmix_encode_punctuation('"'."'".'(<[{'); - - $i = 0; - while ($value = $this->parent->xml_value($tags, "[$i]['#']")) { - $value = strtr($value, $ENTITIES); - if (preg_match_all($pattern, $value, $matches)) { - $chars = array_merge($chars, $matches[0]); - } - $i++; - } - - return $chars; - } - function jmix_encode_punctuation($str) { - $ENTITIES = array(); - $i_max = strlen($str); - for ($i=0; $i<$i_max; $i++) { - $ENTITIES[$str{$i}] = '&#x'.sprintf('%04X', ord($str{$i})).';'; - } - return $ENTITIES; - } - function v6_expand_ExerciseTitle() { - return $this->parent->xml_value('data,title'); - } - - // Jmix specials - - function v6_expand_SegmentArray() { - - $segments = array(); - $values = array(); - $VALUES = array(); - - // XML tags to the start of a segment - $tags = 'data,jumbled-order-exercise,main-order,segment'; - - $i = 0; - while ($value = $this->parent->xml_value($tags, "[$i]['#']")) { - $VALUE = strtoupper($value); - $key = array_search($VALUE, $VALUES); - if (is_numeric($key)) { - $segments[] = $key; - } else { - $segments[] = $i; - $values[$i] = $value; - $VALUES[$i] = $VALUE; - } - $i++; - } - - $this->seed_random_number_generator(); - $keys = array_keys($segments); - shuffle($keys); - - $str = ''; - for($i=0; $ijs_safe($values[$key], true)."';\n"; - $str .= "Segments[$i][1] = ".($key+1).";\n"; - $str .= "Segments[$i][2] = 0;\n"; - } - return $str; - } - function v6_expand_AnswerArray() { - - $segments = array(); - $values = array(); - $VALUES = array(); - $escapedvalues = array(); - - // XML tags to the start of a segment - $tags = 'data,jumbled-order-exercise,main-order,segment'; - - $i = 0; - while ($value = $this->parent->xml_value($tags, "[$i]['#']")) { - $VALUE = strtoupper($value); - $key = array_search($VALUE, $VALUES); - if (is_numeric($key)) { - $segments[] = $key+1; - } else { - $segments[] = $i+1; - $values[$i] = $value; - $VALUES[$i] = $VALUE; - $escapedvalues[] = preg_quote($value, '/'); - } - $i++; - } - - // start the answers array - $a = 0; - $str = 'Answers['.($a++).'] = new Array('.implode(',', $segments).");\n"; - - // pattern to match the next part of an alternate answer - $pattern = '/^('.implode('|', $escapedvalues).')\\s*/i'; - - // XML tags to the start of an alternate answer - $tags = 'data,jumbled-order-exercise,alternate'; - - $i = 0; - while ($value = $this->parent->xml_value($tags, "[$i]['#']")) { - $segments = array(); - while (strlen($value) && preg_match($pattern, $value, $matches)) { - $key = array_search($matches[1], $values); - if (is_numeric($key)) { - $segments[] = $key+1; - $value = substr($value, strlen($matches[0])); - } else { - // invalid alternate sequence - $segments = array(); - break; - } - } - if (count($segments)) { - $str .= 'Answers['.($a++).'] = new Array('.implode(',', $segments).");\n"; - } - $i++; - } - return $str; - } - - // =============================================================== - - // JMix (jmix6.js_) - - function v6_expand_RemainingWords() { - return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',remaining-words'); - } - function v6_expand_TimesUp() { - return $this->parent->xml_value('hotpot-config-file,global,times-up'); - } - - // nav bar - - function v6_expand_NavBar($navbarid='') { - $this->navbarid = $navbarid; - - $tag = 'navbar'; - $this->read_template('hp6navbar.ht_', $tag); - - unset($this->navbarid); - - return $this->$tag; - } - function v6_expand_TopNavBar() { - return $this->v6_expand_NavBar('TopNavBar'); - } - function v6_expand_BottomNavBar() { - return $this->v6_expand_NavBar('BottomNavBar'); - } - - // hp6navbar.ht_ - - function v6_expand_NavBarID() { - // $this->navbarid is set in "$this->v6_expand_NavBar" - return empty($this->navbarid) ? '' : $this->navbarid; - } - function v6_expand_ContentsURL() { - $url = $this->parent->xml_value('hotpot-config-file,global,contents-url'); - if ($url) { - $url = hotpot_convert_navbutton_url($this->parent->get_baseurl(), $this->parent->reference, $url, $this->parent->course); - } - return $url; - } - function v6_expand_NextExURL() { - $url = $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',next-ex-url'); - if ($url) { - $url = hotpot_convert_navbutton_url($this->parent->get_baseurl(), $this->parent->reference, $url, $this->parent->course); - } - return $url; - } - - // conditional blocks - - function v6_expand_ShowAnswer() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-show-answer'); - } - function v6_expand_Slide() { - return true; // whats's this (JMatch drag and drop) - } - - // specials (JMatch) - - function v6_expand_FixedArray() { - $l_items = array(); - $r_items = array(); - $this->get_jmatch_items($l_items, $r_items); - - $str = ''; - foreach ($l_items as $i=>$item) { - $str .= "F[$i] = new Array();\n"; - $str .= "F[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n"; - $str .= "F[$i][1] = ".($i+1).";\n"; - } - return $str; - } - function v6_expand_DragArray() { - $l_items = array(); - $r_items = array(); - $this->get_jmatch_items($l_items, $r_items); - - $str = ''; - foreach ($r_items as $i=>$item) { - $str .= "D[$i] = new Array();\n"; - $str .= "D[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n"; - $str .= "D[$i][1] = ".($i+1).";\n"; - $str .= "D[$i][2] = 0;\n"; - } - return $str; - } - - function get_jmatch_items(&$l_items, &$r_items) { - $tags = 'data,matching-exercise,pair'; - $i = 0; - while($item = $this->parent->xml_value($tags,"[$i]['#']['left-item'][0]['#']")) { - if (!empty($item['text'][0]['#'])) { - $l_items[] = $item; - } - $i++; - } - $i = 0; - while($item = $this->parent->xml_value($tags,"[$i]['#']['right-item'][0]['#']")) { - if (!empty($item['text'][0]['#'])) { - $r_items[] = $item; - } - $i++; - } - } - function shuffle_jmatch_items(&$items) { - // get moveable items - $moveable_keys = array(); - for($i=0; $iseed_random_number_generator(); - shuffle($moveable_keys); - - $keys = array(); - for($i=0, $ii=0; $iparent->quiztype) { - case 'jcloze': - $tags = 'data,gap-fill,question-record'; - while (($question="[$q]['#']") && $this->parent->xml_value($tags, $question)) { - $a = 0; - $aa = 0; - while (($answer=$question."['answer'][$a]['#']") && $this->parent->xml_value($tags, $answer)) { - $text = $this->js_value($tags, $answer."['text'][0]['#']", true); - if (strlen($text)) { - if ($aa==0) { // first time only - $str .= "\n"; - $str .= "I[$q] = new Array();\n"; - $str .= "I[$q][1] = new Array();\n"; - } - $str .= "I[$q][1][$aa] = new Array();\n"; - $str .= "I[$q][1][$aa][0] = '$text';\n"; - $aa++; - } - $a++; - } - // add clue, if any answers were found - if ($aa) { - $clue = $this->js_value($tags, $question."['clue'][0]['#']", true); - $str .= "I[$q][2] = '$clue';\n"; - } - $q++; - } - break; - case 'jquiz': - $str .= "I=new Array();\n"; - $tags = 'data,questions,question-record'; - while (($question="[$q]['#']") && $this->parent->xml_value($tags, $question)) { - - $question_type = $this->int_value($tags, $question."['question-type'][0]['#']"); - $weighting = $this->int_value($tags, $question."['weighting'][0]['#']"); - $clue = $this->js_value($tags, $question."['clue'][0]['#']", true); - - $answers = $question."['answers'][0]['#']"; - - $a = 0; - $aa = 0; - while (($answer = $answers."['answer'][$a]['#']") && $this->parent->xml_value($tags, $answer)) { - $text = $this->js_value($tags, $answer."['text'][0]['#']", true); - $feedback = $this->js_value($tags, $answer."['feedback'][0]['#']", true); - $correct = $this->int_value($tags, $answer."['correct'][0]['#']"); - $percent = $this->int_value($tags, $answer."['percent-correct'][0]['#']"); - $include = $this->int_value($tags, $answer."['include-in-mc-options'][0]['#']"); - if (strlen($text)) { - if ($aa==0) { // first time only - $str .= "\n"; - $str .= "I[$q] = new Array();\n"; - $str .= "I[$q][0] = $weighting;\n"; - $str .= "I[$q][1] = '$clue';\n"; - $str .= "I[$q][2] = '".($question_type-1)."';\n"; - $str .= "I[$q][3] = new Array();\n"; - } - $str .= "I[$q][3][$aa] = new Array('$text','$feedback',$correct,$percent,$include);\n"; - $aa++; - } - $a++; - } - $q++; - } - break; - } - return $str; - } - - function v6_expand_ClozeBody() { - $str = ''; - - // get drop down list of words, if required - $dropdownlist = ''; - if ($this->v6_use_DropDownList()) { - $this->v6_set_WordList(); - foreach ($this->wordlist as $word) { - $dropdownlist .= ''; - } - } - - // cache clues flag and caption - $includeclues = $this->v6_expand_Clues(); - $cluecaption = $this->v6_expand_ClueCaption(); - - // detect if cloze starts with gap - $strpos = strpos($this->parent->source, ''); - if (is_numeric($strpos)) { - $startwithgap = true; - } else { - $startwithgap = false; - } - - // initialize loop values - $q = 0; - $tags = 'data,gap-fill'; - $question_record = "$tags,question-record"; - - // loop through text and gaps - do { - $text = $this->parent->xml_value($tags, "[0]['#'][$q]"); - $gap = ''; - if (($question="[$q]['#']") && $this->parent->xml_value($question_record, $question)) { - $gap .= ''; - if ($this->v6_use_DropDownList()) { - $gap .= ''; - } else { - // minimum gap size - $gapsize = 6; - - // increase gap size to length of longest answer for this gap - $a = 0; - while (($answer=$question."['answer'][$a]['#']") && $this->parent->xml_value($question_record, $answer)) { - $answertext = $this->parent->xml_value($question_record, $answer."['text'][0]['#']"); - $answertext = preg_replace('|&[#a-zA-Z0-9]+;|', 'x', $answertext); - $gapsize = max($gapsize, strlen($answertext)); - $a++; - } - - $gap .= ''; - } - if ($includeclues) { - $clue = $this->parent->xml_value($question_record, $question."['clue'][0]['#']"); - if (strlen($clue)) { - $gap .= ''; - } - } - $gap .= ''; - } - if ($startwithgap) { - $str .= "$gap$text"; - } else { - $str .= "$text$gap"; - } - $q++; - } while (strlen($text) || strlen($gap)); - - return $str; - } - - // JCloze quiztype - - function v6_expand_WordList() { - $str = ''; - if ($this->v6_include_WordList()) { - $this->v6_set_WordList(); - $str = implode('    ', $this->wordlist); - } - return $str; - } - function v6_include_WordList() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-word-list'); - } - function v6_use_DropDownList() { - return $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',use-drop-down-list'); - } - function v6_set_WordList() { - - if (isset($this->wordlist)) { - // do nothing - } else { - $this->wordlist = array(); - - // is the wordlist required - if ($this->v6_include_WordList() || $this->v6_use_DropDownList()) { - - $q = 0; - $tags = 'data,gap-fill,question-record'; - while (($question="[$q]['#']") && $this->parent->xml_value($tags, $question)) { - $a = 0; - $aa = 0; - while (($answer=$question."['answer'][$a]['#']") && $this->parent->xml_value($tags, $answer)) { - $text = $this->parent->xml_value($tags, $answer."['text'][0]['#']"); - $correct = $this->int_value($tags, $answer."['correct'][0]['#']"); - if ($text && $correct) { // $correct is always true - $this->wordlist[] = $text; - $aa++; - } - $a++; - } - $q++; - } - $this->wordlist = array_unique($this->wordlist); - sort($this->wordlist); - } - } - } - function v6_expand_Keypad() { - $str = ''; - if ($this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-keypad')) { - - // these characters must always be in the keypad - $chars = array(); - $this->add_keypad_chars($chars, $this->parent->xml_value('hotpot-config-file,global,keypad-characters')); - - // append other characters used in the answers - $tags = ''; - switch ($this->parent->quiztype) { - case 'jcloze': - $tags = 'data,gap-fill,question-record'; - break; - case 'jquiz': - $tags = 'data,questions,question-record'; - break; - } - if ($tags) { - $q = 0; - while (($question="[$q]['#']") && $this->parent->xml_value($tags, $question)) { - - if ($this->parent->quiztype=='jquiz') { - $answers = $question."['answers'][0]['#']"; - } else { - $answers = $question; - } - - $a = 0; - while (($answer=$answers."['answer'][$a]['#']") && $this->parent->xml_value($tags, $answer)) { - $this->add_keypad_chars($chars, $this->parent->xml_value($tags, $answer."['text'][0]['#']")); - $a++; - } - $q++; - } - } - - // remove duplicate characters and sort - $chars = array_unique($chars); - usort($chars, "hotpot_sort_keypad_chars"); - - // create keypad buttons for each character - $str .= '
    '; - foreach ($chars as $char) { - $str .= ""; - } - $str .= '
    '; - } - return $str; - } - function add_keypad_chars(&$chars, $text) { - if (preg_match_all('|&[^;]+;|i', $text, $more_chars)) { - $chars = array_merge($chars, $more_chars[0]); - } - } - function v6_expand_Correct() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guesses-correct'); - } - function v6_expand_Incorrect() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guesses-incorrect'); - } - function v6_expand_GiveHint() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',next-correct-letter'); - } - function v6_expand_CaseSensitive() { - return $this->bool_value('hotpot-config-file,'.$this->parent->quiztype.',case-sensitive'); - } - - // JCross quiztype - - function v6_expand_CluesAcrossLabel() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',clues-across'); - } - function v6_expand_CluesDownLabel() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',clues-down'); - } - function v6_expand_EnterCaption() { - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',enter-caption'); - } - function v6_expand_ShowHideClueList() { - $value = $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',include-clue-list'); - return empty($value) ? ' style="display: none;"' : ''; - } - - // JCross specials - - function v6_expand_CluesDown() { - return $this->v6_expand_jcross_clues('D'); - } - function v6_expand_CluesAcross() { - return $this->v6_expand_jcross_clues('A'); - } - function v6_expand_jcross_clues($direction) { - // $direction: A(cross) or D(own) - $row = NULL; - $r_max = 0; - $c_max = 0; - $this->v6_get_jcross_grid($row, $r_max, $c_max); - - $i = 0; // clue index; - $str = ''; - for($r=0; $r<=$r_max; $r++) { - for($c=0; $c<=$c_max; $c++) { - $aword = $this->get_jcross_aword($row, $r, $r_max, $c, $c_max); - $dword = $this->get_jcross_dword($row, $r, $r_max, $c, $c_max); - if ($aword || $dword) { - $i++; // increment clue index - - // get the definition for this word - $def = ''; - $word = ($direction=='A') ? $aword : $dword; - $clues = $this->parent->xml_values('data,crossword,clues,item'); - foreach ($clues as $clue) { - if ($clue['word'][0]['#']==$word) { - $def = $clue['def'][0]['#']; - $def = strtr($def, array('<'=>'<', '>'=>'>', "\n"=>'
    ')); - break; - } - } - - if (!empty($def)) { - $str .= ''.$i.'. '.$def.''; - } - } - } - } - return $str; - } - - // jcross6.js_ - - function v6_expand_LetterArray() { - $row = NULL; - $r_max = 0; - $c_max = 0; - $this->v6_get_jcross_grid($row, $r_max, $c_max); - - $str = ''; - for($r=0; $r<=$r_max; $r++) { - $str .= "L[$r] = new Array("; - for($c=0; $c<=$c_max; $c++) { - $str .= ($c>0 ? ',' : '')."'".$this->js_safe($row[$r]['cell'][$c]['#'], true)."'"; - } - $str .= ");\n"; - } - return $str; - } - function v6_expand_GuessArray() { - $row = NULL; - $r_max = 0; - $c_max = 0; - $this->v6_get_jcross_grid($row, $r_max, $c_max); - - $str = ''; - for($r=0; $r<=$r_max; $r++) { - $str .= "G[$r] = new Array('".str_repeat("','", $c_max)."');\n"; - } - return $str; - } - function v6_expand_ClueNumArray() { - $row = NULL; - $r_max = 0; - $c_max = 0; - $this->v6_get_jcross_grid($row, $r_max, $c_max); - - $i = 0; // clue index - $str = ''; - for($r=0; $r<=$r_max; $r++) { - $str .= "CL[$r] = new Array("; - for($c=0; $c<=$c_max; $c++) { - if ($c>0) { - $str .= ','; - } - $aword = $this->get_jcross_aword($row, $r, $r_max, $c, $c_max); - $dword = $this->get_jcross_dword($row, $r, $r_max, $c, $c_max); - if (empty($aword) && empty($dword)) { - $str .= 0; - } else { - $i++; // increment the clue index - $str .= $i; - } - } - $str .= ");\n"; - } - return $str; - } - function v6_expand_GridBody() { - $row = NULL; - $r_max = 0; - $c_max = 0; - $this->v6_get_jcross_grid($row, $r_max, $c_max); - - $i = 0; // clue index; - $str = ''; - for($r=0; $r<=$r_max; $r++) { - $str .= ''; - for($c=0; $c<=$c_max; $c++) { - if (empty($row[$r]['cell'][$c]['#'])) { - $str .= ' '; - } else { - $aword = $this->get_jcross_aword($row, $r, $r_max, $c, $c_max); - $dword = $this->get_jcross_dword($row, $r, $r_max, $c, $c_max); - if (empty($aword) && empty($dword)) { - $str .= ' '; - } else { - $i++; // increment clue index - $str .= ''.$i.'   '; - } - } - } - $str .= ''; - } - return $str; - } - function v6_get_jcross_grid(&$row, &$r_max, &$c_max) { - $row = $this->parent->xml_values('data,crossword,grid,row'); - $r_max = 0; - $c_max = 0; - if (isset($row) && is_array($row)) { - for($r=0; $rget_jcross_word($row, $r, $r_max, $c, $c_max, true); - } - return $str; - } - function get_jcross_aword(&$row, $r, $r_max, $c, $c_max) { - $str = ''; - if (($c==0 || empty($row[$r]['cell'][$c-1]['#'])) && $c<$c_max && !empty($row[$r]['cell'][$c+1]['#'])) { - $str = $this->get_jcross_word($row, $r, $r_max, $c, $c_max, false); - } - return $str; - } - function get_jcross_word(&$row, $r, $r_max, $c, $c_max, $go_down=false) { - $str = ''; - while ($r<=$r_max && $c<=$c_max && !empty($row[$r]['cell'][$c]['#'])) { - $str .= $row[$r]['cell'][$c]['#']; - if ($go_down) { - $r++; - } else { - $c++; - } - } - return $str; - } - - // specials (JQuiz) - - function v6_expand_QuestionOutput() { - $str = ''; - $str .= '
      '."\n"; - - $q = 0; - $tags = 'data,questions,question-record'; - while (($question="[$q]['#']") && $this->parent->xml_value($tags, $question)) { - - // get question - $question_text = $this->parent->xml_value($tags, $question."['question'][0]['#']"); - $question_type = $this->parent->xml_value($tags, $question."['question-type'][0]['#']"); - - // check we have a question - if ($question_text && $question_type) { - - $str .= '