From 91b9560bd63e5582781e910573ee0887b558ca12 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sat, 24 Jul 2010 17:15:54 +0000 Subject: [PATCH] MDL-23450 moving mod/hotpot to contrib for now, because it is not ready for Moodle 2.0 yet --- mod/hotpot/README.TXT | 87 - mod/hotpot/attempt.php | 582 ---- mod/hotpot/backuplib.php | 347 -- mod/hotpot/db/access.php | 79 - mod/hotpot/db/install.php | 17 - mod/hotpot/db/install.xml | 122 - mod/hotpot/db/upgrade.php | 30 - mod/hotpot/grade.php | 29 - mod/hotpot/hotpot-full.js | 3012 ----------------- mod/hotpot/icon.gif | Bin 415 -> 0 bytes mod/hotpot/iframe.js | 76 - mod/hotpot/index.php | 402 --- mod/hotpot/lang/en/hotpot.php | 224 -- mod/hotpot/lib.php | 2996 ---------------- mod/hotpot/mediaplayers/moodle/filter.php | 251 -- mod/hotpot/mod_form.js | 48 - mod/hotpot/mod_form.php | 338 -- mod/hotpot/pix/icon.gif | Bin 415 -> 0 bytes mod/hotpot/report.php | 667 ---- mod/hotpot/report/click/report.php | 542 --- mod/hotpot/report/default.php | 851 ----- mod/hotpot/report/fullstat/report.php | 449 --- mod/hotpot/report/overview/report.php | 172 - mod/hotpot/report/simplestat/report.php | 203 -- mod/hotpot/restorelib.php | 537 --- mod/hotpot/review.php | 251 -- mod/hotpot/settings.php | 11 - mod/hotpot/show.php | 75 - mod/hotpot/template/default.php | 111 - mod/hotpot/template/v6.php | 1515 --------- mod/hotpot/template/v6/djmatch6.ht_ | 128 - mod/hotpot/template/v6/djmatch6.js_ | 369 -- mod/hotpot/template/v6/djmix6.ht_ | 136 - mod/hotpot/template/v6/djmix6.js_ | 576 ---- mod/hotpot/template/v6/fjmatch6.ht_ | 105 - mod/hotpot/template/v6/fjmatch6.js_ | 131 - mod/hotpot/template/v6/hotpot6r.ht_ | 8 - mod/hotpot/template/v6/hp6.cs_ | 605 ---- mod/hotpot/template/v6/hp6browsercheck.js_ | 55 - mod/hotpot/template/v6/hp6buttons.js_ | 42 - mod/hotpot/template/v6/hp6card.js_ | 152 - .../template/v6/hp6checkshortanswer.js_ | 405 --- mod/hotpot/template/v6/hp6hotpotnet.js_ | 18 - mod/hotpot/template/v6/hp6navbar.ht_ | 15 - mod/hotpot/template/v6/hp6objecttags.ht_ | 18 - mod/hotpot/template/v6/hp6plainpage.ht_ | 42 - mod/hotpot/template/v6/hp6sendresults.js_ | 53 - mod/hotpot/template/v6/hp6showmessage.js_ | 85 - mod/hotpot/template/v6/hp6timer.js_ | 33 - mod/hotpot/template/v6/hp6utilities.js_ | 248 -- mod/hotpot/template/v6/jcloze6.ht_ | 169 - mod/hotpot/template/v6/jcloze6.js_ | 390 --- mod/hotpot/template/v6/jcross6.ht_ | 191 -- mod/hotpot/template/v6/jcross6.js_ | 373 -- mod/hotpot/template/v6/jcross6print.ht_ | 182 - mod/hotpot/template/v6/jmatch6.ht_ | 148 - mod/hotpot/template/v6/jmatch6.js_ | 310 -- mod/hotpot/template/v6/jmix6.ht_ | 155 - mod/hotpot/template/v6/jmix6.js_ | 409 --- mod/hotpot/template/v6/jquiz6.ht_ | 163 - mod/hotpot/template/v6/jquiz6.js_ | 668 ---- mod/hotpot/template/v6/masher.ht_ | 94 - mod/hotpot/template/v6/mashernav.ht_ | 29 - mod/hotpot/template/v6/testbrowsercheck.htm | 35 - mod/hotpot/version.php | 16 - mod/hotpot/view.php | 528 --- 66 files changed, 21108 deletions(-) delete mode 100644 mod/hotpot/README.TXT delete mode 100644 mod/hotpot/attempt.php delete mode 100644 mod/hotpot/backuplib.php delete mode 100644 mod/hotpot/db/access.php delete mode 100644 mod/hotpot/db/install.php delete mode 100644 mod/hotpot/db/install.xml delete mode 100644 mod/hotpot/db/upgrade.php delete mode 100644 mod/hotpot/grade.php delete mode 100644 mod/hotpot/hotpot-full.js delete mode 100644 mod/hotpot/icon.gif delete mode 100644 mod/hotpot/iframe.js delete mode 100644 mod/hotpot/index.php delete mode 100644 mod/hotpot/lang/en/hotpot.php delete mode 100644 mod/hotpot/lib.php delete mode 100644 mod/hotpot/mediaplayers/moodle/filter.php delete mode 100644 mod/hotpot/mod_form.js delete mode 100644 mod/hotpot/mod_form.php delete mode 100644 mod/hotpot/pix/icon.gif delete mode 100644 mod/hotpot/report.php delete mode 100644 mod/hotpot/report/click/report.php delete mode 100644 mod/hotpot/report/default.php delete mode 100644 mod/hotpot/report/fullstat/report.php delete mode 100644 mod/hotpot/report/overview/report.php delete mode 100644 mod/hotpot/report/simplestat/report.php delete mode 100644 mod/hotpot/restorelib.php delete mode 100644 mod/hotpot/review.php delete mode 100644 mod/hotpot/settings.php delete mode 100644 mod/hotpot/show.php delete mode 100644 mod/hotpot/template/default.php delete mode 100644 mod/hotpot/template/v6.php delete mode 100644 mod/hotpot/template/v6/djmatch6.ht_ delete mode 100644 mod/hotpot/template/v6/djmatch6.js_ delete mode 100644 mod/hotpot/template/v6/djmix6.ht_ delete mode 100644 mod/hotpot/template/v6/djmix6.js_ delete mode 100644 mod/hotpot/template/v6/fjmatch6.ht_ delete mode 100644 mod/hotpot/template/v6/fjmatch6.js_ delete mode 100644 mod/hotpot/template/v6/hotpot6r.ht_ delete mode 100644 mod/hotpot/template/v6/hp6.cs_ delete mode 100644 mod/hotpot/template/v6/hp6browsercheck.js_ delete mode 100644 mod/hotpot/template/v6/hp6buttons.js_ delete mode 100644 mod/hotpot/template/v6/hp6card.js_ delete mode 100644 mod/hotpot/template/v6/hp6checkshortanswer.js_ delete mode 100644 mod/hotpot/template/v6/hp6hotpotnet.js_ delete mode 100644 mod/hotpot/template/v6/hp6navbar.ht_ delete mode 100644 mod/hotpot/template/v6/hp6objecttags.ht_ delete mode 100644 mod/hotpot/template/v6/hp6plainpage.ht_ delete mode 100644 mod/hotpot/template/v6/hp6sendresults.js_ delete mode 100644 mod/hotpot/template/v6/hp6showmessage.js_ delete mode 100644 mod/hotpot/template/v6/hp6timer.js_ delete mode 100644 mod/hotpot/template/v6/hp6utilities.js_ delete mode 100644 mod/hotpot/template/v6/jcloze6.ht_ delete mode 100644 mod/hotpot/template/v6/jcloze6.js_ delete mode 100644 mod/hotpot/template/v6/jcross6.ht_ delete mode 100644 mod/hotpot/template/v6/jcross6.js_ delete mode 100644 mod/hotpot/template/v6/jcross6print.ht_ delete mode 100644 mod/hotpot/template/v6/jmatch6.ht_ delete mode 100644 mod/hotpot/template/v6/jmatch6.js_ delete mode 100644 mod/hotpot/template/v6/jmix6.ht_ delete mode 100644 mod/hotpot/template/v6/jmix6.js_ delete mode 100644 mod/hotpot/template/v6/jquiz6.ht_ delete mode 100644 mod/hotpot/template/v6/jquiz6.js_ delete mode 100644 mod/hotpot/template/v6/masher.ht_ delete mode 100644 mod/hotpot/template/v6/mashernav.ht_ delete mode 100644 mod/hotpot/template/v6/testbrowsercheck.htm delete mode 100644 mod/hotpot/version.php delete mode 100644 mod/hotpot/view.php diff --git a/mod/hotpot/README.TXT b/mod/hotpot/README.TXT deleted file mode 100644 index 8c8d2abf4a8..00000000000 --- a/mod/hotpot/README.TXT +++ /dev/null @@ -1,87 +0,0 @@ -================================================== -This is v2.4.2 of the HotPot module for Moodle 1.9 -================================================== - - This module allows teachers to administer Hot Potatoes and TexToys quizzes via Moodle. - It has been tested on: - - Hot Potatoes 6 - - Moodle 1.9 - - PHP 4.1 thru 5.2 - - MySQL 4.x thru 5.0 - - PostgreSQL 7.3 thru 8.2 - - This module may be distributed under the terms of the General Public License - (see http://www.gnu.org/licenses/gpl.txt for details) - - This software is provided "AS IS" without a warranty of any kind. - - Sponsors who have generously contributed to the development of this software: - - Agencia de Gestio d'Ajuts Universitaris i de Recerca (AGAUR), - Autonomous Government of Catalonia, Spain - (via Josep M. Fontana, Universitat Pompeu Fabra) - - Rikkyo Univeristy, Japan (via Paul Allum) - - Universite de Franche-Comte, France (via Glenys Hanson) - - -================ -IMPORTANT NOTICE -================ -* Please be sure to use Hot Potatoes according to the conditions of use which are listed at the end of this file. If you restrict use via a required Moodle login, you most likely can still meet the 'freely available' condition if you make the same material on a separate URL that permits free access. Otherwise, please purchase a license. - - -====================================== -TO INSTALL OR UPDATE THE HOTPOT MODULE -====================================== - - You should install only this module by installing a complete Moodle 1.9 package. - - Similarly, the recommended way to upgrade this module is to upgrade to a complete Moodle 1.8 package. - - However, it is possible to download and unzip a complete Moodle 1.9 package and extract the "mod/hotpot" folder for use on your live Moodle 1.8 site. - -======================== -TO USE THE HOTPOT MODULE -======================== - -1. If you haven't already done so, download and install the Hot Potatoes software from http://www.halfbakedsoftware.com onto your PC - -2. Create any type of Hot Potatoes quiz on your PC using the Hot Potatoes software - -3. Upload the quiz's source file (".jcl", ".jcw", ".jmt", ".jmx", ".jqz") or ".html" file from your PC to the "Files" area of a course on your Moodle site. - -4. Also upload any graphics, sound files, stylesheets or javascripts that the quiz uses - -5. On the main page for the Moodle course, confirm editing is turned on (click the "Turn editing on" button), then, in the section where you want to add the HotPot activity, select "Hot Potatoes Quiz" on the "Add an activity" drop-down menu . - - If "Hot Potatoes Quiz" does not appear on the "Add an activity" menu, you may need to enable the HotPot module as follows: - - a) from the site's front page select "Admin" then "Modules" - b) click the "closed eye" icon for the "Hot Potatoes Quiz" module - - If there is no "Hot Potatoes Quiz" on the "Modules" page, you probably have not put the hotpot.php messages file in the right place. Please refer to step 2, "Install the messages and help files", of the installation procedure (see previous section) - -6. The "Adding a new Hot Potatoes Quiz" page appears. Click the "Choose or Upload a file ..." button and select the desired Hot Potaotes quiz file. - -7. Review the other settings for the quiz and click "Save Changes" when you are ready - -8. You can view reports of the results via the "Hot Potatoes Quizzes" link on the "Activities menu". Students will see links to all the quizzes. Administrators and teachers will additionally see links to the statistical reports for each quiz. - -9. You can also import the questions from the Hot Potatoes source file to the Moodle Quiz database, if you completed step 4, "enable import from Hot Potatoes XML files", of the installation procedure (see previous section) - - -============================== -HOT POTATOES CONDITIONS OF USE -============================== -** Reproduced from the Hot Potatoes site ** - -Hot Potatoes is offered free to the educational community by the University of Victoria Humanities Computing and Media Centre (formerly the Language Centre), under certain conditions. Hot Potatoes is free for use by state educational institutions which are non-profit making, on the condition that the material produced using the program is freely available to anyone via the WWW. However, you need to purchase a licence under any of the following conditions: -* You do not work for a public sector educational establishment. -* You charge money for access to the material you make with Hot Potatoes. -* You restrict access to the material in some way. (The only exception here is if you have an account on www.hotpot.net, where you ARE allowed to use password restrictions.) -* You want to use the Masher program included with the Hot Potatoes suite. - -For more information on licences, and details on how to purchase one, check out our Website at: - http://www.halfbakedsoftware.com/hotpot/ - -If you intend using the programs to generate more than a handful of exercises, please make sure you register. This costs you nothing -- see How to register for details. -Martin Holmes, Half-Baked Software and the University of Victoria HCMC, 1998-2004. \ No newline at end of file diff --git a/mod/hotpot/attempt.php b/mod/hotpot/attempt.php deleted file mode 100644 index b7ed9f9c4de..00000000000 --- a/mod/hotpot/attempt.php +++ /dev/null @@ -1,582 +0,0 @@ -set_url('/mod/hotpot/attempt.php', array('attemptid'=>$attemptid)); - - // get attempt, hotpot, course and course_module records - if (! $attempt = $DB->get_record("hotpot_attempts", array("id"=>$attemptid))) { - print_error('invalidattemptid', 'hotpot'); - } - if ($attempt->userid != $USER->id) { - print_error("invaliduserid"); - } - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$attempt->hotpot))) { - print_error('invalidhotpotid', 'hotpot'); - } - if (! $course = $DB->get_record("course", array("id"=>$hotpot->course))) { - print_error('invalidcourseid'); - } - if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { - print_error("invalidcoursemodule"); - } - - // make sure this user is enrolled in this course - require_login($course, true, $cm); - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - require_capability('mod/hotpot:attempt', $context, $USER->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 ($DB->get_field("hotpot_attempts", "timefinish", array("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 - $DB->set_field("hotpot_attempts", "status", $attempt->status, array("clickreportid"=>$attempt->clickreportid)); - - // add new attempt record - unset ($attempt->id); - $attempt->id = $DB->insert_record("hotpot_attempts", $attempt); - - // add attempt details record, if necessary - if (!empty($attempt->details)) { - $details = new object(); - $details->attempt = $attempt->id; - $details->details = $attempt->details; - $DB->insert_record("hotpot_details", $details, false); - } - } else { - // remove previous responses for this attempt, if required - // (N.B. this does NOT remove the attempt record, just the responses) - $DB->delete_records("hotpot_responses", array("attempt"=>$attempt->id)); - } - } - - // remove slashes added by lib/setup.php - $attempt->details = $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 = $attempt->details; - - // update the attempt record - $DB->update_record("hotpot_attempts", $attempt); - - // update grades for this user - hotpot_update_grades($hotpot, $attempt->userid); - - // get previous attempt details record, if any - $details_exist = $DB->record_exists("hotpot_details", array("attempt"=>$attempt->id)); - - // delete/update/add the attempt details record - if (empty($attempt->details)) { - if ($details_exist) { - $DB->delete_records("hotpot_details", array("attempt"=>$attempt->id)); - } - } else { - if ($details_exist) { - $DB->set_field("hotpot_details", "details", $attempt->details, array("attempt"=>$attempt->id)); - } else { - $details = new object(); - $details->attempt = $attempt->id; - $details->details = $attempt->details; - $DB->insert_record("hotpot_details", $details); - } - } - - 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 -// ================= - -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 - global $DB; - - $next_mod = false; - - // get a list of $ids of modules in this section - if ($ids = $DB->get_field('course_sections', 'sequence', array('id'=>$cm->section))) { - - $found = false; - $ids = explode(',', $ids); - foreach ($ids as $id) { - if ($found && ($cm->module==$DB->get_field('course_modules', 'module', array('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, $DB; - - // 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; - // print_error('QuizTypeIsMissingOrInvalid'); - // print_error('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, '', PARAM_CLEAN); - } - 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 = $DB->get_records_sql(" - SELECT - r.* - FROM - {hotpot_attempts} a, - {hotpot_questions} q, - {hotpot_responses} r - WHERE - a.clickreportid = ? AND - a.id = r.attempt AND - r.question = q.id AND - q.name = ? AND - q.hotpot = ? - ORDER BY - a.timefinish - ", array($attempt->clickreportid, $questionname, $attempt->hotpot)); - - 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/backuplib.php b/mod/hotpot/backuplib.php deleted file mode 100644 index 9cb54ebb4af..00000000000 --- a/mod/hotpot/backuplib.php +++ /dev/null @@ -1,347 +0,0 @@ -id, - // fk->course, files) - // | - // +--------------+---------------+ - // | | - // hotpot_attempts hotpot_questions - // (UL, pk->id, (UL, pk->id, - // fk->hotpot) fk->hotpot, text) - // | | | - // +-------------------+----------+ | - // | | | - // hotpot_details hotpot_responses | - // (UL, pk->id, (UL, pk->id, | - // fk->attempt) fk->attempt, question, | - // correct, wrong, ignored) | - // | | - // +-------+-------+ - // | - // hotpot_strings - // (UL, pk->id) - // - // Meaning: pk->primary key field of the table - // fk->foreign key to link with parent - // nt->nested field (recursive data) - // CL->course level info - // UL->user level info - // files->table may have files - // - //----------------------------------------------------------- - function hotpot_backup_mods($bf, $preferences) { - global $DB; - - $status = true; - - //Iterate over hotpot table - $hotpots = $DB->get_records ("hotpot", array("course"=>$preferences->backup_course), "id"); - if ($hotpots) { - foreach ($hotpots as $hotpot) { - if (function_exists('backup_mod_selected')) { - // Moodle >= 1.6 - $backup_mod_selected = backup_mod_selected($preferences, 'hotpot', $hotpot->id); - } else { - // Moodle <= 1.5 - $backup_mod_selected = true; - } - if ($backup_mod_selected) { - $status = hotpot_backup_one_mod($bf, $preferences, $hotpot->id); - } - } - } - return $status; - } - - function hotpot_backup_one_mod($bf, $preferences, $instance=0) { - // $bf : resource id for b(ackup) f(ile) - // $preferences : object containing switches and settings for this backup - $level = 3; - $status = true; - $table = 'hotpot'; - $select = "course=? AND id=?"; - $params = array($preferences->backup_course, $instance); - $records_tag = ''; - $records_tags = array(); - $record_tag = 'MOD'; - $record_tags = array('MODTYPE'=>'hotpot'); - $excluded_tags = array(); - $more_backup = ''; - if (function_exists('backup_userdata_selected')) { - // Moodle >= 1.6 - $backup_userdata_selected = backup_userdata_selected($preferences, 'hotpot', $instance); - } else { - // Moodle <= 1.5 - $backup_userdata_selected = $preferences->mods['hotpot']->userinfo; - } - if ($backup_userdata_selected) { - $more_backup .= '$GLOBALS["hotpot_backup_string_ids"] = array();'; - $more_backup .= '$status = hotpot_backup_attempts($bf, $record, $level, $status);'; - $more_backup .= '$status = hotpot_backup_questions($bf, $record, $level, $status);'; - $more_backup .= '$status = hotpot_backup_strings($bf, $record, $level, $status);'; - $more_backup .= 'unset($GLOBALS["hotpot_backup_string_ids"]);'; // tidy up - } - return hotpot_backup_records( - $bf, $status, $level, - $table, $select, $params, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - function hotpot_backup_attempts($bf, &$parent, $level, $status) { - // $parent is a reference to a hotpot record - $table = 'hotpot_attempts'; - $select = "hotpot=?"; - $params = array($parent->id); - $records_tag = 'ATTEMPT_DATA'; - $records_tags = array(); - $record_tag = 'ATTEMPT'; - $record_tags = array(); - $more_backup = ''; - $more_backup .= 'hotpot_backup_details($bf, $record, $level, $status);'; - $more_backup .= 'hotpot_backup_responses($bf, $record, $level, $status);'; - $excluded_tags = array('hotpot'); - return hotpot_backup_records( - $bf, $status, $level, - $table, $select, $params, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - function hotpot_backup_details($bf, &$parent, $level, $status) { - // $parent is a reference to an attempt record - $table = 'hotpot_details'; - $select = "attempt=?"; - $params = array($parent->id); - $records_tag = ''; - $records_tags = array(); - $record_tag = ''; - $record_tags = array(); - $more_backup = ''; - $excluded_tags = array('id','attempt'); - return hotpot_backup_records( - $bf, $status, $level, - $table, $select, $params, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - function hotpot_backup_responses($bf, &$parent, $level, $status) { - // $parent is a reference to an attempt record - $table = 'hotpot_responses'; - $select = "attempt=?"; - $params = array($parent->id); - $records_tag = 'RESPONSE_DATA'; - $records_tags = array(); - $record_tag = 'RESPONSE'; - $record_tags = array(); - $more_backup = 'hotpot_backup_string_ids($record, array("correct","wrong","ignored"));'; - $excluded_tags = array('id','attempt'); - return hotpot_backup_records( - $bf, $status, $level, - $table, $select, $params, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - function hotpot_backup_questions($bf, &$parent, $level, $status) { - // $parent is a reference to an hotpot record - $table = 'hotpot_questions'; - $select = "hotpot=?"; - $params = array($parent->id); - $records_tag = 'QUESTION_DATA'; - $records_tags = array(); - $record_tag = 'QUESTION'; - $record_tags = array(); - $more_backup = 'hotpot_backup_string_ids($record, array("text"));'; - $excluded_tags = array('hotpot'); - return hotpot_backup_records( - $bf, $status, $level, - $table, $select, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - function hotpot_backup_string_ids(&$record, $fields) { - // as the questions and responses tables are backed up - // this function is called to store the ids of strings. - // The string ids are used later by "hotpot_backup_strings" - // $GLOBALS['hotpot_backup_string_ids'] was initialized in "hotpot_backup_mods" - // store the ids of strings used in this $record's $fields - foreach ($fields as $field) { - if (empty($record->$field)) { - // do nothing - } else { - $value = $record->$field; - $ids = explode(',', "$value"); - foreach ($ids as $id) { - if (empty($id)) { - // do nothing - } else { - $GLOBALS['hotpot_backup_string_ids'][$id] = true; - } - } - } - } - } - function hotpot_backup_strings($bf, $record, $level, $status) { - // This functions backups the strings used - // in the question and responses for a single hotpot activity - // The ids of the strings were stored by "hotpot_backup_string_ids" - // $GLOBALS['hotpot_backup_string_ids'] was initialized in "hotpot_backup_mods" - // retrieve $ids of strings to be backed up - $ids = array_keys($GLOBALS['hotpot_backup_string_ids']); - if (empty($ids)) { - // no strings to backup - } else { - sort($ids); - $ids = implode(',', $ids); - $table = 'hotpot_strings'; - $select = "id IN ($ids)"; - $params = array(); - $records_tag = 'STRING_DATA'; - $records_tags = array(); - $record_tag = 'STRING'; - $record_tags = array(); - $more_backup = ''; - $excluded_tags = array(''); - $status = hotpot_backup_records( - $bf, $status, $level, - $table, $select, $params, - $records_tag, $records_tags, - $record_tag, $record_tags, - $excluded_tags, $more_backup - ); - } - return $status; - } - function hotpot_backup_records(&$bf, $status, $level, $table, $select, $params, $records_tag, $records_tags, $record_tag, $record_tags, $excluded_tags, $more_backup) { - // general purpose backup function - // $bf : resource id of backup file - // $status : current status of backup (true or false) - // $level : current depth level in the backup XML tree - // $table : table from which records will be selected and backed up - // $select : SQL selection string - // $records_tag : optional XML tag which starts a group of records (and descends a level) - // $records_tags : optional XML tags to be inserted at the start of a group of records - // $record_tag : optional XML tag which starts a record (and descends a level) - // $record_tags : optional XML tags to be inserted at the start of a record - // $excluded_tags : fields which will NOT be backed up from the records - // $more_backup : optional PHP code to be eval(uated) for each record - // If any of the "fwrite" statements fail, - // no further "fwrite"s will be attempted - // and the function returns "false". - // Otherwise, the function returns "true". - global $DB; - - if ($status && ($records = $DB->get_records_select($table, $select, $params, 'id'))) { - // start a group of records - if ($records_tag) { - $status = $status && fwrite($bf, start_tag($records_tag, $level, true)); - $level++; - foreach ($records_tags as $tag) { - $status = $status && fwrite($bf, full_tag($tag, $level, false, $value)); - } - } - foreach ($records as $record) { - // start a single record - if ($record_tag) { - $status = $status && fwrite($bf, start_tag($record_tag, $level, true)); - $level++; - foreach ($record_tags as $tag=>$value) { - $status = $status && fwrite($bf, full_tag($tag, $level, false, $value)); - } - } - // backup fields in this record - $tags = get_object_vars($record); - foreach ($tags as $tag=>$value) { - if (!is_numeric($tag) && !in_array($tag, $excluded_tags)) { - $status = $status && fwrite($bf, full_tag($tag, $level, false, $value)); - } - } - // backup related records, if required - if ($more_backup) { - eval($more_backup); - } - // end a single record - if ($record_tag) { - $level--; - $status = $status && fwrite($bf, end_tag($record_tag, $level, true)); - } - } - // end a group of records - if ($records_tag) { - $level--; - $status = $status && fwrite($bf, end_tag($records_tag, $level, true)); - } - } - return $status; - } - ////Return an array of info (name, value) - function hotpot_check_backup_mods($course, $user_data=false, $backup_unique_code, $instances=null) { - global $CFG, $DB; - $info = array(); - if (isset($instances) && is_array($instances) && count($instances)) { - foreach ($instances as $id => $instance) { - $info += hotpot_check_backup_mods_instances($instance,$backup_unique_code); - } - } else { - // the course data - $info[0][0] = get_string('modulenameplural','hotpot'); - $info[0][1] = $DB->count_records('hotpot', array('course'=>$course)); - - // the user_data, if requested - if ($user_data) { - $table = "{hotpot} h, {hotpot_attempts} a"; - $select = "h.course = ? AND h.id = a.hotpot"; - $params = array($course); - - $info[1][0] = get_string('attempts', 'quiz'); - $info[1][1] = $DB->count_records_sql("SELECT COUNT(*) FROM $table WHERE $select", $params); - } - } - return $info; - } - - ////Return an array of info (name, value) - function hotpot_check_backup_mods_instances($instance,$backup_unique_code) { - global $CFG, $DB; - $info = array(); - - // the course data - $info[$instance->id.'0'][0] = ''.$instance->name.''; - $info[$instance->id.'0'][1] = ''; - - // the user_data, if requested - if (!empty($instance->userdata)) { - $table = "{hotpot_attempts} a"; - $select = "a.hotpot = ?"; - $params = array($instance->id); - - $info[$instance->id.'1'][0] = get_string('attempts', 'quiz'); - $info[$instance->id.'1'][1] = $DB->count_records_sql("SELECT COUNT(*) FROM $table WHERE $select", $params); - } - return $info; - } - - // Return content encoded to support interactivities linking. - // Called by "backup_encode_absolute_links()" in backup/backuplib.php - // Content will be decoded by "hotpot_decode_content_links()" - function hotpot_encode_content_links ($content, $preferences) { - global $CFG; - $base = preg_quote("$CFG->wwwroot/mod/hotpot/", '/'); - $search = "/($base)([a-z]+).php\?([a-z]+)\=([0-9]+)/"; - return preg_replace($search, '$@HOTPOT*$2*$3*$4@$', $content); - } - diff --git a/mod/hotpot/db/access.php b/mod/hotpot/db/access.php deleted file mode 100644 index a4867ca69d3..00000000000 --- a/mod/hotpot/db/access.php +++ /dev/null @@ -1,79 +0,0 @@ -: -// -// component_name should be the same as the directory name of the mod or block. -// -// Core moodle capabilities are defined thus: -// moodle/: -// -// Examples: mod/forum:viewpost -// block/recent_activity:view -// moodle/site:deleteuser -// -// The variable name for the capability definitions array is $capabilities - - -$capabilities = array( - - 'mod/hotpot:attempt' => array( - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'student' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/hotpot:viewreport' => array( - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/hotpot:grade' => array( - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - - 'mod/hotpot:deleteattempt' => array( - - 'captype' => 'read', - 'contextlevel' => CONTEXT_MODULE, - 'archetypes' => array( - 'editingteacher' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ) - -); - - diff --git a/mod/hotpot/db/install.php b/mod/hotpot/db/install.php deleted file mode 100644 index 17742a47161..00000000000 --- a/mod/hotpot/db/install.php +++ /dev/null @@ -1,17 +0,0 @@ -set_field('modules', 'visible', 0, array('name'=>'hotpot')); - -/// Install logging support here - - -} diff --git a/mod/hotpot/db/install.xml b/mod/hotpot/db/install.xml deleted file mode 100644 index ce1b457d93f..00000000000 --- a/mod/hotpot/db/install.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - -
-
-
diff --git a/mod/hotpot/db/upgrade.php b/mod/hotpot/db/upgrade.php deleted file mode 100644 index defc6d95bf7..00000000000 --- a/mod/hotpot/db/upgrade.php +++ /dev/null @@ -1,30 +0,0 @@ -get_manager(); - -//===== 1.9.0 upgrade line ======// - - // update hotpot grades from sites earlier than Moodle 1.9, 27th March 2008 - if ($oldversion < 2007101511) { - // ensure "hotpot_upgrade_grades" function is available - require_once $CFG->dirroot.'/mod/hotpot/lib.php'; - hotpot_upgrade_grades(); - upgrade_mod_savepoint(true, 2007101511, 'hotpot'); - } - - if ($oldversion < 2008011200) { - // remove not used setting - unset_config('hotpot_initialdisable'); - upgrade_mod_savepoint(true, 2008011200, 'hotpot'); - } - - return true; -} diff --git a/mod/hotpot/grade.php b/mod/hotpot/grade.php deleted file mode 100644 index b3f6dd92afd..00000000000 --- a/mod/hotpot/grade.php +++ /dev/null @@ -1,29 +0,0 @@ -set_url('/mod/hotpot/grade.php', array('id'=>$id)); - - if (! $cm = get_coursemodule_from_id('hotpot', $id)) { - print_error('invalidcoursemodule'); - } - - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$cm->instance))) { - print_error('invalidhotpotid', 'hotpot'); - } - - if (! $course = $DB->get_record("course", array("id"=>$hotpot->course))) { - print_error("invalidcourse"); - } - - require_login($course->id, false, $cm); - - if (has_capability('mod/hotpot:grade', get_context_instance(CONTEXT_MODULE, $cm->id))) { - redirect('report.php?id='.$cm->id); - } else { - redirect('view.php?id='.$cm->id); - } - - diff --git a/mod/hotpot/hotpot-full.js b/mod/hotpot/hotpot-full.js deleted file mode 100644 index f3bcc734fd1..00000000000 --- a/mod/hotpot/hotpot-full.js +++ /dev/null @@ -1,3012 +0,0 @@ - \ No newline at end of file diff --git a/mod/hotpot/icon.gif b/mod/hotpot/icon.gif deleted file mode 100644 index 463c06585ca8f5a6c9c2a9b9f7ee9075282a051d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415 zcmZ?wbh9u|6krfw_{zZW|IEyPhx$J5@BO~M=HZssa~qqluBC1wT1+y#yPY z84on5sij?>!WgoPkCWjDPp1{9!y+bz3I-X!%*-YYDXxyAhx{Z}q`ibB1;j=9Mfk-T zv>AoHR9Qtu1VpBZh{~!nXe!C8v9ZgEONuXBCMhSWA+N>2Z78>C<;qRUy8diz+cK28R;2n>YbJ3llBkH<&ZQoGBH-?U{_O;)?&-e73Aq;W?)m3exxe) h?DI1%zj^X1OkZ-@4CEiRWMnip$Tf=0) this.mac = t; - if (s.indexOf("Opera") >=0) this.opera = t; - var d = document; - if (d.layers) this.n4 = t; - if (d.childNodes) this.dom = t; - if (d.all && d.plugins) this.ie = t; -} -function getContentH(lyr) { - return (is.n4) ? lyr.document.height : (is.ie) ? (is.mac ? lyr.offsetHeight : lyr.scrollHeight) : (is.opera) ? lyr.style.pixelHeight : (is.dom) ? lyr.offsetHeight : 0; -} -function px(i) { - return i + "px"; -} -function setSize(obj, w, h) { - if (is.n4) { - if (w) obj.width = w; - if (h) obj.height = h; - } else if (is.opera) { - // opera 5 needs pixelWidth/Height - if (w) obj.style.pixelWidth = w; - if (h) obj.style.pixelHeight = h; - } else { - if (w) obj.style.width = px(w); - if (h) obj.style.height = px(h); - } -} -function getElement(id, lyr) { - var d = (document.layers && lyr) ? lyr.document : document; - var obj = (document.layers) ? eval("d."+id) : (d.all) ? d.all[id] : (d.getElementById) ? d.getElementById(id) : null; - return obj; -} -function set_embed_object_height(evt, embed_object) { - if (typeof(embed_object)=='undefined') { - if (evt) { - // we are being called by the onload event handler - if (evt.target) { // most browsers - embed_object = evt.target; - } else if (evt.srcElement) { // IE - embed_object = evt.srcElement; - } - } - } - var obj = null; - if (embed_object) { - if (document.frames) { // IE - switch (embed_object.tagName) { - case 'IFRAME': - obj = document.frames[embed_object.name].document; - break; - case 'OBJECT': - obj = embed_object; // already an HTML document element - break; - } - } else { // Firefox, Safari, Opera, Chrome - obj = embed_object.document || embed_object.contentDocument || null; - } - } - if (obj) { - if (obj.body) { - obj = obj.body; - } - var h = getContentH(obj); - if (h) { - setSize(embed_object, 0, h + 65); - } - // at some point the next two lines were important, but now it doesn't seeme to matter ?! - // if (document.all) { - // embed_object.allowTransparency = true; - // obj.style.backgroundColor = 'transparent'; - // } - } -} -is = new domSniffer(); \ No newline at end of file diff --git a/mod/hotpot/index.php b/mod/hotpot/index.php deleted file mode 100644 index ed471d0aa6f..00000000000 --- a/mod/hotpot/index.php +++ /dev/null @@ -1,402 +0,0 @@ -set_url('/mod/hotpot/index.php', array('id'=>$id)); - - if (!$course = $DB->get_record('course', array('id'=>$id))) { - print_error('invalidcourseid'); - } - - require_login($course->id); - $PAGE->set_pagelayout('incourse'); - - $coursecontext = get_context_instance(CONTEXT_COURSE, $id); - $sitecontext = get_context_instance(CONTEXT_SYSTEM); - - add_to_log($course->id, "hotpot", "view all", "index.php?id=$course->id", ""); - - $sesskey = ''; - - // get message strings for titles - $strmodulenameplural = get_string("modulenameplural", "hotpot"); - $strmodulename = get_string("modulename", "hotpot"); - $strsectionname = get_string('sectionname', 'format_'.$course->format); - - // string translation array for single and double quotes - $quotes = array("'"=>"\'", '"'=>'"'); - - // Print the header - $PAGE->navbar->add($strmodulenameplural); - $PAGE->set_title(format_string($course->shortname) . ": $strmodulenameplural"); - $PAGE->set_heading($course->fullname); - echo $OUTPUT->header(); - - $next_url = "$CFG->wwwroot/course/view.php?id=$course->id"; - - // get display section, if any - $section = optional_param('section', 0, PARAM_ALPHANUM); - if ($section=='all') { - // do nothing - } else { - $section = intval($section); - } - 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 hotpot instances in this course - $hotpots = array(); - if ($hotpot_instances = hotpot_get_all_instances_in_course('hotpot', $course)) { - foreach ($hotpot_instances as $hotpot_instance) { - if ($displaysection>0 && $hotpot_instance->section>0 && $displaysection<>$hotpot_instance->section) { - // do nothing (user is not diplaying this section) - } else { - $hotpots[$hotpot_instance->id] = $hotpot_instance; - } - } - } - if (empty($hotpots)) { - notice(get_string('thereareno', 'moodle', $strmodulenameplural), $next_url); - exit; - } - $hotpotids = implode(',', array_keys($hotpots)); - - $usesections = course_format_uses_sections($course->format); - if ($usesections) { - $sections = get_all_sections($course->id); - } - - if (has_capability('mod/hotpot:grade', $sitecontext)) { - - // array of hotpots to be regraded - $regrade_hotpots = array(); - - // do we need to regrade any or all of the hotpots? - $regrade = optional_param('regrade', 0, PARAM_SEQUENCE); - if ($regrade) { - // add valid hotpot ids to the regrade array - $regrade = explode(',', $regrade); - foreach ($regrade as $id) { - if (isset($hotpots[$id])) { - $regrade_hotpots[$id] = &$hotpots[$id]; - } - } - $regrade = implode(',', array_keys($regrade_hotpots)); - } - if ($regrade) { - - $confirm = optional_param('confirm', 0, PARAM_BOOL); - if (!$confirm) { - - echo $OUTPUT->box_start("generalbox boxaligncenter boxwidthnormal errorboxcontent"); - - if (count($regrade_hotpots)==1) { - echo $OUTPUT->heading(get_string('regradecheck', 'hotpot', $regrade_hotpots[$regrade]->name)); - } else { - echo $OUTPUT->heading(get_string('regradecheck', 'hotpot', '')); - print '
    '; - foreach ($regrade_hotpots as $hotpot) { - print "
  • $hotpot->name
  • "; - } - print '
'; - } - print '' - . '
' - . '
' - . '' - . '' - . '' - . $sesskey - . '' - . '
' - . '
  ' - . '
' - . '' - . $sesskey - . '' - . '
' - . '
' - ; - - echo $OUTPUT->box_end(); - echo $OUTPUT->footer(); - exit; - - } else { // regrade has been confirmed, so proceed - - // start hotpot counter and timer - $hotpotstart = microtime(); - $hotpotcount = 0; - - // regrade attempts for these hotpots - foreach ($regrade_hotpots as $hotpot) { - echo $OUTPUT->notification("$hotpot->name"); - - // delete questions and responses for this hotpot - if ($records = $DB->get_records('hotpot_questions', array('hotpot'=>$hotpot->id), '', 'id,hotpot')) { - $questionids = implode(',', array_keys($records)); - hotpot_delete_and_notify('hotpot_questions', "id IN ($questionids)", array(), get_string('question', 'quiz')); - hotpot_delete_and_notify('hotpot_responses', "question IN ($questionids)", array(), get_string('answer', 'quiz')); - } - - // start attempt counter and timer - $attemptstart = microtime(); - $attemptcount = 0; - - // regrade attempts, if any, for this hotpot - if ($attempts = $DB->get_records('hotpot_attempts', array('hotpot'=>$hotpot->id))) { - foreach ($attempts as $attempt) { - $attempt->details = $DB->get_field('hotpot_details', 'details', array('attempt'=>$attempt->id)); - if ($attempt->details) { - hotpot_add_attempt_details($attempt); - $DB->update_record('hotpot_attempts', $attempt); - } - $attemptcount++; - } - } - if ($attemptcount) { - $msg = get_string('added', 'moodle', "$attemptcount x ".get_string('attempts', 'quiz')); - if (!empty($CFG->hotpot_showtimes)) { - $msg .= ' ('.format_time(sprintf("%0.2f", microtime_diff($attemptstart, microtime()))).')'; - } - echo $OUTPUT->notification($msg); - } - $hotpotcount++; - } // end foreach $hotpots - if ($hotpotcount) { - $msg = get_string('regrade', 'quiz').": $hotpotcount x ".get_string('modulenameplural', 'hotpot'); - if (!empty($CFG->hotpot_showtimes)) { - $msg .= ' ('.format_time(sprintf("%0.2f", microtime_diff($hotpotstart, microtime()))).')'; - } - echo $OUTPUT->notification($msg); - } - echo $OUTPUT->notification(get_string('regradecomplete', 'quiz')); - } // end if $confirm - } // end regrade - - // get duplicate hotpot-name questions - // - JMatch LHS is longer than 255 bytes - // - JQuiz question text is longer than 255 bytes - // - other unidentified situations ?! - - $regrade_hotpots = array(); - $concat_field = $DB->sql_concat('hotpot', "'_'", 'name'); - if ($concat_field) { - $records = $DB->get_records_sql(" - SELECT $concat_field, COUNT(*), hotpot, name - FROM {hotpot_questions} - WHERE hotpot IN ($hotpotids) - GROUP BY hotpot, name - HAVING COUNT(*) >1 - "); - if ($records) { - foreach ($records as $record) { - $regrade_hotpots[$record->hotpot] = 1; - } - ksort($regrade_hotpots); - $regrade_hotpots = array_keys($regrade_hotpots); - } - } - } - - // start timer - $start = microtime(); - - // get total number of attempts, users and details for these hotpots - $params = array(); - $tables = "{hotpot_attempts} 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 (has_capability('mod/hotpot:viewreport', $coursecontext)) { - // do nothing (=get all users) - } else { - // restrict results to this user only - $select .= " AND a.userid=:userid"; - $params['userid'] = $USER->id; - } - $usejoin = 0; - if (has_capability('mod/hotpot:grade', get_context_instance(CONTEXT_SYSTEM)) && $usejoin) { - // join attempts table and details table - $tables .= ",{hotpot_details} 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 = $DB->get_records_sql("SELECT $fields FROM $tables WHERE $select GROUP BY a.hotpot", $params); - - if (has_capability('mod/hotpot:grade', get_context_instance(CONTEXT_SYSTEM)) && empty($usejoin)) { - foreach ($hotpots as $hotpot) { - $totals[$hotpot->id]->detailcount = 0; - if ($ids = $DB->get_records('hotpot_attempts', array('hotpot'=>$hotpot->id))) { - $ids = join(',', array_keys($ids)); - $totals[$hotpot->id]->detailcount = $DB->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 = new html_table(); - $table->head = array(); - $table->align = array(); - - if (!empty($CFG->hotpot_showtimes)) { - print '

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

\n"; - } - - $title = $strsectionname; - if ($title) { - array_push($table->head, $title); - array_push($table->align, "center"); - } - if (has_capability('moodle/course:manageactivities', $coursecontext)) { - 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 (has_capability('mod/hotpot:grade', $coursecontext)) { - array_push($table->head, $strregrade); - array_push($table->align, "center"); - } - - $currentsection = -1; - foreach ($hotpots as $hotpot) { - - $printsection = ""; - if ($hotpot->section != $currentsection) { - if ($hotpot->section) { - if ($usesections) { - $printsection = get_section_name($course, $sections[$hotpot->section]); - // Show the zoom boxes - if ($displaysection==$hotpot->section) { - $strshowall = get_string('showall'.$course->format); - $printsection .= '
'.$strshowall.'
'; - } else { - $strshowone = get_string('showonly'.preg_replace('|s$|', '', $course->format, 1), '', $hotpot->section); - $printsection .= '
'.$strshowone.'
'; - } - } - } - 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 { - - $cm = get_coursemodule_from_instance('hotpot', $hotpot->id); - // report number of attempts and users - $report = get_string("viewallreports","quiz", $totals[$hotpot->id]->attemptcount); - if (has_capability('mod/hotpot:viewreport', get_context_instance(CONTEXT_MODULE, $cm->id))) { - $report .= " (".$totals[$hotpot->id]->usercount." $strusers)"; - } - $report = ''.$report.''; - - // get best score - if (is_numeric($totals[$hotpot->id]->maxscore)) { - $weighting = $hotpot->grade / 100; - $precision = hotpot_get_precision($hotpot); - $bestscore = round($totals[$hotpot->id]->maxscore * $weighting, $precision)." / $hotpot->grade"; - } else { - $bestscore = " "; - } - } - - if (has_capability('mod/hotpot:grade', $sitecontext)) { - if (in_array($hotpot->id, $regrade_hotpots)) { - $report .= ' '.$strregraderequired.''; - } - } - - $data = array (); - - if ($usesections) { - array_push($data, $printsection); - } - - if (has_capability('moodle/course:manageactivities', $coursecontext)) { - $updatebutton = '' - . '
' - . '' - . $sesskey - . '' - . '
' - ; - array_push($data, $updatebutton); - } - - array_push($data, $quizname, $quizclose, $bestscore, $report); - - if (has_capability('mod/hotpot:grade', $sitecontext)) { - 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 "
"; - - echo html_writer::table($table); - - // Finish the page - echo $OUTPUT->footer(); - diff --git a/mod/hotpot/lang/en/hotpot.php b/mod/hotpot/lang/en/hotpot.php deleted file mode 100644 index 6db34f8e0fd..00000000000 --- a/mod/hotpot/lang/en/hotpot.php +++ /dev/null @@ -1,224 +0,0 @@ -. - -/** - * Strings for component 'hotpot', language 'en', branch 'MOODLE_20_STABLE' - * - * @package hotpot - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['abandoned'] = 'Abandoned'; -$string['addquizchain'] = 'Add quiz chain'; -$string['allmycourses'] = 'All my courses'; -$string['allowreview'] = 'Allow review'; -$string['allowreview_help'] = 'If enabled, students may review their quiz attempts after the quiz is closed.'; -$string['allusers'] = 'All users'; -$string['alwaysopen'] = 'Always open'; -$string['attemptsall'] = 'All attempts'; -$string['attemptsbest'] = 'Best attempt'; -$string['attemptsfirst'] = 'First attempt'; -$string['attemptslast'] = 'Last attempt'; -$string['average'] = 'Average'; -$string['cannotfindmethod'] = 'Template block expand method not found: ({$a})'; -$string['clickreporting'] = 'Enable click reporting'; -$string['clickreporting_help'] = 'If enabled, a separate record is kept each time a "hint", "clue" or "check" button is clicked. This allows the teacher to see a very detailed report showing the state of the quiz at each click. Otherwise, only one record per attempt at a quiz is kept.'; -$string['clues'] = 'Clues'; -$string['completed'] = 'Completed'; -$string['configexcelencodings'] = 'A list of encodings, separated by commas, that can be used to force report values into a specific encoding for spreadsheet programs. For example, Microsoft Excel requires the "SJIS" encoding for Japanese'; -$string['configshowtimes'] = 'Should the time taken to process records be displayed in listings and reports? This is only really necessary if you are trying to find out why your server is running slowly.'; -$string['copiedtoclipboard'] = 'The contents of this page have been copied to the clipboard'; -$string['copytoclipboard'] = 'Copy to Clipboard'; -$string['correct'] = 'Correct'; -$string['deleteabandoned'] = 'Delete abandoned'; -$string['deleteabandonedcheck'] = 'Do you really want to delete all {$a} abandoned attempts?'; -$string['deleteallattempts'] = 'Delete all attempts'; -$string['displaycoursenext'] = 'Display Course page next'; -$string['displayhotpotnext'] = 'Display Hot Potatoes quiz next'; -$string['displayindexnext'] = 'Display HotPot index next'; -$string['enterafilename'] = 'Please enter a file name'; -$string['error_couldnotopenfolder'] = 'Could not access the folder "{$a}"'; -$string['error_couldnotopensourcefile'] = 'Could not open the source file "{$a}"'; -$string['error_couldnotopentemplate'] = 'Could not open template for "{$a}" format'; -$string['error_invalidquiztype'] = 'Quiz type is missing or invalid'; -$string['error_nocourseorfilename'] = 'Could not create XML tree: missing course or file name'; -$string['error_nofeedbackurlformmail'] = 'Please enter a URL for the form processing script'; -$string['error_nofeedbackurlwebpage'] = 'Please enter a URL for the webpage'; -$string['error_nofilename'] = 'Please enter a file name'; -$string['error_noquizzesfound'] = 'No Hot Potatoes quizzes found'; -$string['error_notfileorfolder'] = '"{$a}" is not file or folder'; -$string['excelencodings'] = 'Excel encodings'; -$string['feedbackformmail'] = 'Feedback form'; -$string['feedbackmoodleforum'] = 'Moodle forum'; -$string['feedbackmoodlemessaging'] = 'Moodle messaging'; -$string['feedbacknone'] = 'None'; -$string['feedbackwebpage'] = 'Web page'; -$string['filetype'] = 'File type'; -$string['forceplugins'] = 'Force media plugins'; -$string['forceplugins_help'] = 'If enabled, Moodle-compatible media players will play files such as avi, mpeg, mpg, mp3, mov and wmv. Otherwise, Moodle will not change the settings of any media players in the quiz.'; -$string['forceplugins_link'] = 'mod/hotpot/mod'; -$string['giveup'] = 'Give Up'; -$string['hints'] = 'Hints'; -$string['hotpotadministration'] = 'Hot Potatoes quiz administration'; -$string['hotpot:attempt'] = 'Attempt a quiz'; -$string['hotpotcloses'] = 'Hot Potatoes quiz closes'; -$string['hotpot:deleteattempt'] = 'Delete quiz attempts'; -$string['hotpot:grade'] = 'Modify grades'; -$string['hotpotopens'] = 'Hot Potatoes quiz opens'; -$string['hotpot:view'] = 'Use quiz'; -$string['hotpot:viewreport'] = 'View reports'; -$string['checks'] = 'Checks'; -$string['ignored'] = 'Ignored'; -$string['inprogress'] = 'In progress'; -$string['invalidattemptid'] = 'Attempt ID was incorrect'; -$string['invalidhotpotid'] = 'hotpot ID was incorrect'; -$string['location'] = 'File location'; -$string['maxgrade'] = 'Maximum grade'; -$string['maxgrade_help'] = 'This setting specifies the grade that all scores are scaled to. For example, if the quiz is worth 20% of the whole course, the maximum grade would be set to 20.'; -$string['modulename'] = 'Hot Potatoes Quiz'; -$string['modulename_help'] = 'The HotPot module enables the teacher to include Hot Potatoes quizzes in the course. Each attempt is automatically marked, and reports are available which show how individual questions were answered and some statistical trends in the scores.'; -$string['modulename_link'] = 'hotpot'; -$string['modulenameplural'] = 'Hot Potatoes Quizzes'; -$string['navigation'] = 'Navigation'; -$string['navigation_help'] = 'This setting determines the navigation used in the quiz: - -* Moodle navigation bar - The Moodle navigation bar will be displayed in the same window as the quiz at the top of the page -* Moodle navigation frame - The Moodle navigation bar will be displayed in a separate frame at the top of the quiz -* Embedded IFRAME - The Moodle navigation bar will be displayed in the same window as the quiz and the quiz will be embedded in an IFRAME -* Hot Potatoes quiz buttons - The quiz will be displayed with the navigation buttons, if any, defined in the quiz -* A single "Give Up" button - The quiz will be displayed with a single "Give Up" button at the top of the page -* None - The quiz will be displayed with no navigation aids, so when all questions have been answered correctly, depending on the "Show next quiz?" setting, Moodle will either return to the course page or display the next quiz'; -$string['navigation_bar'] = 'Moodle navigation bar'; -$string['navigation_buttons'] = 'Hot Potatoes quiz buttons'; -$string['navigation_frame'] = 'Moodle navigation frame'; -$string['navigation_give_up'] = 'A single "Give Up" button'; -$string['navigation_iframe'] = 'Embedded IFRAME'; -$string['navigation_none'] = 'None'; -$string['neverclosed'] = 'Never closed'; -$string['noactivity'] = 'No activity'; -$string['noresponses'] = 'No information about individual questions and responses was found.'; -$string['notyourattempt'] = 'This is not your attempt!'; -$string['outputformat'] = 'Output format'; -$string['outputformat_help'] = 'This setting specifies the format to display the quiz. - -* Best - The best format for the browser -* v6+ - Drag and drop format for v6+ browsers -* v6 - Format for v6 browsers'; -$string['outputformat_best'] = 'best'; -$string['outputformat_flash'] = 'Flash'; -$string['outputformat_mobile'] = 'mobile'; -$string['outputformat_v3'] = 'v3'; -$string['outputformat_v4'] = 'v4'; -$string['outputformat_v5'] = 'v5'; -$string['outputformat_v5_plus'] = 'v5+'; -$string['outputformat_v6'] = 'v6'; -$string['outputformat_v6_plus'] = 'v6+'; -$string['penalties'] = 'Penalties'; -$string['pluginname'] = 'Hot Potatoes Quiz'; -$string['questionshort'] = 'Q-{$a}'; -$string['quiztype'] = 'Quiz type'; -$string['quizunavailable'] = 'Quiz is unavailable at the moment'; -$string['rawdetails'] = 'Raw attempt details'; -$string['regrade'] = 'Regrade'; -$string['regradecheck'] = 'Do you really want to regrade "{$a}"?'; -$string['regraderequired'] = 'Regrade required'; -$string['removegradeitem'] = 'Remove grade item'; -$string['reportanswers'] = 'Answers'; -$string['reportattemptfinish'] = 'Att. finish'; -$string['reportattemptnumber'] = 'Attempt'; -$string['reportattemptstart'] = 'Att. start'; -$string['reportbutton'] = 'Generate report'; -$string['reportclick'] = 'Click trail report'; -$string['reportclicknumber'] = 'Click'; -$string['reportclicktime'] = 'Click time'; -$string['reportclicktype'] = 'Click type'; -$string['reportclues'] = 'Clues'; -$string['reportcontent'] = 'Content'; -$string['reportcontent_help'] = 'There are 4 report types: - -* Overview - A list of all attempts -* Simple statistics - A list of all attempts with average scores for individual questions and for the complete quiz -* Detailed statistics - Full details of all attempts together with a responses table and an item analysis table -* Click trail report (only available if click reporting is enabled) - Full details of every click by every student in all attempts'; -$string['reportcontent_link'] = 'mod/hotpot/report'; -$string['reportcorrectsymbol'] = 'O'; -$string['reportcoursename'] = 'Course name'; -$string['reportencoding'] = 'Encoding'; -$string['reportevents'] = 'Events'; -$string['reportexercisename'] = 'Ex. name'; -$string['reportexercisenumber'] = 'Exercise'; -$string['reportexercisetype'] = 'Ex. type'; -$string['reportformat'] = 'Format'; -$string['reportformat_help'] = 'Reports are available in HTML, Excel or text formats with the option to wrap data (to fit into table cells) and to have questions and answers represented by letters together with a legend showing which letters represent which questions or answers.'; -$string['reportformatexcel'] = 'Excel'; -$string['reportformathtml'] = 'HTML'; -$string['reportformattext'] = 'Text'; -$string['reporthints'] = 'Hints'; -$string['reporthotpotscore'] = 'Hotpot score'; -$string['reportchanges'] = 'Changes'; -$string['reportchecks'] = 'Checks'; -$string['reportlegend'] = 'Legend'; -$string['reportlogindate'] = 'Login date'; -$string['reportlogintime'] = 'Login time'; -$string['reportlogofftime'] = 'Logoff time'; -$string['reportmaxscore'] = 'Max score'; -$string['reportnottried'] = 'Not tried'; -$string['reportnottriedsymbol'] = '-'; -$string['reportnumberofquestions'] = 'No. of q\'s'; -$string['reportpercentscore'] = '% Score'; -$string['reportquestionstried'] = 'Q\'s tried'; -$string['reportrawscore'] = 'Raw score'; -$string['reportright'] = 'Right'; -$string['reportsectionnumber'] = 'Section'; -$string['reportshowanswer'] = 'Show answers'; -$string['reportshowlegend'] = 'Show legend'; -$string['reportsofar'] = '{$a} so far'; -$string['reportstatus'] = 'Status'; -$string['reportstudentid'] = 'Student id'; -$string['reportthisclick'] = '{$a} this click'; -$string['reporttimerecorded'] = 'Responses recorded'; -$string['reportwrapdata'] = 'Wrap data'; -$string['reportwrong'] = 'Wrong'; -$string['reportwrongsymbol'] = 'X'; -$string['resultssaved'] = 'Quiz results were saved'; -$string['score'] = 'Score'; -$string['showhtmlsource'] = 'Show HTML source'; -$string['shownextquiz'] = 'Show next quiz'; -$string['shownextquiz_help'] = 'This setting determines whether, on finishing a quiz, Moodle will return to the course page or display the next quiz (if there is one).'; -$string['showtimes'] = 'Show processing times'; -$string['showxmlsource'] = 'Show XML source'; -$string['showxmltree'] = 'Show XML tree'; -$string['specifictime'] = 'Specific time'; -$string['studentfeedback'] = 'Student feedback'; -$string['studentfeedback_help'] = 'If enabled, a link to a pop-up feedback window will be displayed whenever the student clicks on the "Check" button. The feedback window allows students to send feedback to the teacher in 4 possible ways: - -* Web page (requires URL of the web page, for example http://myserver.com/feedbackform.html) -* Feedback form (requires URL of the form script, for example http://myserver.com/cgi-bin/formmail.pl) -* Moodle forum - The forum index for the course will be displayed -* Moodle messaging - The Moodle instant messaging window will be displayed. If the course has several teachers, the student will be prompted to select a teacher before the messaging window appears.'; -$string['textsourcefilename'] = 'Use file name'; -$string['textsourcefilepath'] = 'Use file path'; -$string['textsourcequiz'] = 'Get from quiz'; -$string['textsourcespecific'] = 'Specific text'; -$string['thiscourse'] = 'This course'; -$string['timedout'] = 'Timed out'; -$string['unknownreport'] = 'Report not known ({$a})'; -$string['updatequizchain'] = 'Update quiz chain'; -$string['updatequizchain_help'] = 'If enabled, if this quiz is part of a chain of Hot Potatoes quizzes, then all quizzes in the chain will be assigned identical settings to the current quiz. Otherwise, only the current quiz will be updated.'; -$string['weighting'] = 'Weighting'; -$string['wrong'] = 'Wrong'; diff --git a/mod/hotpot/lib.php b/mod/hotpot/lib.php deleted file mode 100644 index 919737cb5b1..00000000000 --- a/mod/hotpot/lib.php +++ /dev/null @@ -1,2996 +0,0 @@ -. - -/** - * @package mod-hotpot - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** CONSTANTS and GLOBAL VARIABLES */ - -$CFG->hotpotroot = "$CFG->dirroot/mod/hotpot"; -$CFG->hotpottemplate = "$CFG->hotpotroot/template"; -if (!empty($_SERVER['HTTP_USER_AGENT'])) { - $CFG->hotpotismobile = preg_match('/Alcatel|ATTWS|DoCoMo|Doris|Hutc3G|J-PHONE|Java|KDDI|KGT|LGE|MOT|Nokia|portalmmm|ReqwirelessWeb|SAGEM|SHARP|SIE-|SonyEricsson|Teleport|UP\.Browser|UPG1|Wapagsim/', $_SERVER['HTTP_USER_AGENT']); -} else { - $CFG->hotpotismobile = false; -} - -define("HOTPOT_JS", "$CFG->wwwroot/mod/hotpot/hotpot-full.js"); - -define("HOTPOT_NO", "0"); -define("HOTPOT_YES", "1"); - -define ("HOTPOT_TEXTSOURCE_QUIZ", "0"); -define ("HOTPOT_TEXTSOURCE_FILENAME", "1"); -define ("HOTPOT_TEXTSOURCE_FILEPATH", "2"); -define ("HOTPOT_TEXTSOURCE_SPECIFIC", "3"); - -define("HOTPOT_LOCATION_COURSEFILES", "0"); -define("HOTPOT_LOCATION_SITEFILES", "1"); - -global $HOTPOT_LOCATION; -$HOTPOT_LOCATION = array ( - HOTPOT_LOCATION_COURSEFILES => get_string("coursefiles"), - HOTPOT_LOCATION_SITEFILES => get_string("sitefiles"), -); - -define("HOTPOT_OUTPUTFORMAT_BEST", "1"); -define("HOTPOT_OUTPUTFORMAT_V3", "10"); -define("HOTPOT_OUTPUTFORMAT_V4", "11"); -define("HOTPOT_OUTPUTFORMAT_V5", "12"); -define("HOTPOT_OUTPUTFORMAT_V5_PLUS", "13"); -define("HOTPOT_OUTPUTFORMAT_V6", "14"); -define("HOTPOT_OUTPUTFORMAT_V6_PLUS", "15"); -define("HOTPOT_OUTPUTFORMAT_FLASH", "20"); -define("HOTPOT_OUTPUTFORMAT_MOBILE", "30"); - -global $HOTPOT_OUTPUTFORMAT; -$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"), -); -global $HOTPOT_OUTPUTFORMAT_DIR; -$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', -); -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]); - } -} -define("HOTPOT_NAVIGATION_BAR", "1"); -define("HOTPOT_NAVIGATION_FRAME", "2"); -define("HOTPOT_NAVIGATION_IFRAME", "3"); -define("HOTPOT_NAVIGATION_BUTTONS", "4"); -define("HOTPOT_NAVIGATION_GIVEUP", "5"); -define("HOTPOT_NAVIGATION_NONE", "6"); - -global $HOTPOT_NAVIGATION; -$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"), -); - -define("HOTPOT_JCB", "1"); -define("HOTPOT_JCLOZE", "2"); -define("HOTPOT_JCROSS", "3"); -define("HOTPOT_JMATCH", "4"); -define("HOTPOT_JMIX", "5"); -define("HOTPOT_JQUIZ", "6"); -define("HOTPOT_TEXTOYS_RHUBARB", "7"); -define("HOTPOT_TEXTOYS_SEQUITUR", "8"); - -global $HOTPOT_QUIZTYPE; -$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' -); - -define("HOTPOT_JQUIZ_MULTICHOICE", "1"); -define("HOTPOT_JQUIZ_SHORTANSWER", "2"); -define("HOTPOT_JQUIZ_HYBRID", "3"); -define("HOTPOT_JQUIZ_MULTISELECT", "4"); - -define("HOTPOT_GRADEMETHOD_HIGHEST", "1"); -define("HOTPOT_GRADEMETHOD_AVERAGE", "2"); -define("HOTPOT_GRADEMETHOD_FIRST", "3"); -define("HOTPOT_GRADEMETHOD_LAST", "4"); - -global $HOTPOT_GRADEMETHOD; -$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"), -); - -define("HOTPOT_STATUS_INPROGRESS", "1"); -define("HOTPOT_STATUS_TIMEDOUT", "2"); -define("HOTPOT_STATUS_ABANDONED", "3"); -define("HOTPOT_STATUS_COMPLETED", "4"); - -global $HOTPOT_STATUS; -$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"), -); - -define("HOTPOT_FEEDBACK_NONE", "0"); -define("HOTPOT_FEEDBACK_WEBPAGE", "1"); -define("HOTPOT_FEEDBACK_FORMMAIL", "2"); -define("HOTPOT_FEEDBACK_MOODLEFORUM", "3"); -define("HOTPOT_FEEDBACK_MOODLEMESSAGING", "4"); - -global $HOTPOT_FEEDBACK; -$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"), -); -if (empty($CFG->messaging)) { // Moodle 1.4 (and less) - unset($HOTPOT_FEEDBACK[HOTPOT_FEEDBACK_MOODLEMESSAGING]); -} - -define("HOTPOT_DISPLAYNEXT_QUIZ", "0"); -define("HOTPOT_DISPLAYNEXT_COURSE", "1"); -define("HOTPOT_DISPLAYNEXT_INDEX", "2"); - -/** - * If start and end date for the quiz are more than this many seconds apart - * they will be represented by two separate events in the calendar - */ -define("HOTPOT_MAX_EVENT_LENGTH", "432000"); // 5 days maximum - -////////////////////////////////// -/// CORE FUNCTIONS - - -// possible return values: -// false: -// display moderr.html (if exists) OR "Could not update" and return to couse view -// string: -// display as error message and return to course view -// true (or non-zero number): -// continue to $hotpot->redirect (if set) OR hotpot/view.php (to displsay quiz) - -// $hotpot is an object containing the values of the form in mod_form.php -// i.e. all the fields in the 'hotpot' table, plus the following: -// $hotpot->course : an id in the 'course' table -// $hotpot->coursemodule : an id in the 'course_modules' table -// $hotpot->section : an id in the 'course_sections' table -// $hotpot->module : an id in the 'modules' table -// $hotpot->modulename : always 'hotpot' -// $hotpot->instance : an id in the 'hotpot' table -// $hotpot->mode : 'add' or 'update' -// $hotpot->sesskey : unique string required for Moodle's session management - -/** - * @global object - * @param object $hotpot - * @return bool - */ -function hotpot_add_instance($hotpot) { - global $DB; - - if (hotpot_set_form_values($hotpot)) { - if ($result = $DB->insert_record('hotpot', $hotpot)) { - $hotpot->id = $result; - hotpot_update_events($hotpot); - hotpot_grade_item_update($hotpot); - } - } else { - $result= false; - } - return $result; -} - -/** - * @global object - * @param object $hotpot - * @return bool - */ -function hotpot_update_instance($hotpot) { - global $DB; - - if (hotpot_set_form_values($hotpot)) { - $hotpot->id = $hotpot->instance; - if ($result = $DB->update_record('hotpot', $hotpot)) { - hotpot_update_events($hotpot); - hotpot_update_grades($hotpot); - } - } else { - $result= false; - } - return $result; -} - -/** - * @global object - * @param object $hotpot - */ -function hotpot_update_events($hotpot) { - global $DB; - - // remove any previous calendar events for this hotpot - $DB->delete_records('event', array('modulename'=>'hotpot', 'instance'=>$hotpot->id)); - - $event = new stdClass(); - $event->description = $hotpot->summary; - $event->courseid = $hotpot->course; - $event->groupid = 0; - $event->userid = 0; - $event->modulename = 'hotpot'; - $event->instance = $hotpot->id; - $event->timestart = $hotpot->timeopen; - if ($cm = get_coursemodule_from_id('hotpot', $hotpot->id)) { - $event->visible = hotpot_is_visible($cm); - } else { - $event->visible = 1; - } - - if ($hotpot->timeclose && $hotpot->timeopen) { - // we have both a start and an end date - $event->eventtype = 'open'; - $event->timeduration = ($hotpot->timeclose - $hotpot->timeopen); - - if ($event->timeduration > HOTPOT_MAX_EVENT_LENGTH) { /// Long durations create two events - - $event->name = $hotpot->name.' ('.get_string('hotpotopens', 'hotpot').')'; - $event->timeduration = 0; - add_event($event); - - $event->timestart = $hotpot->timeclose; - $event->eventtype = 'close'; - $event->name = $hotpot->name.' ('.get_string('hotpotcloses', 'hotpot').')'; - unset($event->id); - add_event($event); - } else { // single event with duration - $event->name = $hotpot->name; - add_event($event); - } - } elseif ($hotpot->timeopen) { // only an open date - $event->name = $hotpot->name.' ('.get_string('hotpotopens', 'hotpot').')'; - $event->eventtype = 'open'; - $event->timeduration = 0; - add_event($event); - } elseif ($hotpot->timeclose) { // only a closing date - $event->name = $hotpot->name.' ('.get_string('hotpotcloses', 'hotpot').')'; - $event->timestart = $hotpot->timeclose; - $event->eventtype = 'close'; - $event->timeduration = 0; - add_event($event); - } -} - -/** - * @global object - * @param object $hotpot By Reference - * @return bool - */ -function hotpot_set_form_values(&$hotpot) { - $ok = true; - $hotpot->errors = array(); // these will be reported by moderr.html - - if (empty($hotpot->reference)) { - $ok = false; - $hotpot->errors['reference']= get_string('error_nofilename', 'hotpot'); - } - - if (empty($hotpot->studentfeedbackurl) || $hotpot->studentfeedbackurl=='http://') { - $hotpot->studentfeedbackurl = ''; - switch ($hotpot->studentfeedback) { - case HOTPOT_FEEDBACK_WEBPAGE: - $ok = false; - $hotpot->errors['studentfeedbackurl']= get_string('error_nofeedbackurlwebpage', 'hotpot'); - break; - case HOTPOT_FEEDBACK_FORMMAIL: - $ok = false; - $hotpot->errors['studentfeedbackurl']= get_string('error_nofeedbackurlformmail', 'hotpot'); - break; - } - } - - $time = time(); - $hotpot->timecreated = $time; - $hotpot->timemodified = $time; - - if (empty($hotpot->mode)) { - // moodle 1.9 (from mod_form.lib) - if ($hotpot->add) { - $hotpot->mode = 'add'; - } else if ($hotpot->update) { - $hotpot->mode = 'update'; - } else { - $hotpot->mode = ''; - } - } - if ($hotpot->quizchain==HOTPOT_YES) { - switch ($hotpot->mode) { - case 'add': - $ok = hotpot_add_chain($hotpot); - break; - case 'update': - $ok = hotpot_update_chain($hotpot); - break; - } - } else { // $hotpot->quizchain==HOTPOT_NO - hotpot_set_name_summary_reference($hotpot); - } - - if (isset($hotpot->displaynext)) { - switch ($hotpot->displaynext) { - // N.B. redirection only works for Moodle 1.5+ - case HOTPOT_DISPLAYNEXT_COURSE: - $hotpot->redirect = true; - $hotpot->redirecturl = "view.php?id=$hotpot->course"; - break; - case HOTPOT_DISPLAYNEXT_INDEX: - $hotpot->redirect = true; - $hotpot->redirecturl = "../mod/hotpot/index.php?id=$hotpot->course"; - break; - default: - // use Moodle default action (i.e. go on to display the hotpot quiz) - } - } else { - $hotpot->displaynext = HOTPOT_DISPLAYNEXT_QUIZ; - } - - // if ($ok && $hotpot->setdefaults) { - if ($ok) { - set_user_preference('hotpot_timeopen', $hotpot->timeopen); - set_user_preference('hotpot_timeclose', $hotpot->timeclose); - set_user_preference('hotpot_navigation', $hotpot->navigation); - set_user_preference('hotpot_outputformat', $hotpot->outputformat); - set_user_preference('hotpot_studentfeedback', $hotpot->studentfeedback); - set_user_preference('hotpot_studentfeedbackurl', $hotpot->studentfeedbackurl); - set_user_preference('hotpot_forceplugins', $hotpot->forceplugins); - set_user_preference('hotpot_shownextquiz', $hotpot->shownextquiz); - set_user_preference('hotpot_review', $hotpot->review); - set_user_preference('hotpot_grade', $hotpot->grade); - set_user_preference('hotpot_grademethod', $hotpot->grademethod); - set_user_preference('hotpot_attempts', $hotpot->attempts); - set_user_preference('hotpot_subnet', $hotpot->subnet); - set_user_preference('hotpot_displaynext', $hotpot->displaynext); - if ($hotpot->mode=='add') { - set_user_preference('hotpot_quizchain', $hotpot->quizchain); - set_user_preference('hotpot_namesource', $hotpot->namesource); - set_user_preference('hotpot_summarysource', $hotpot->summarysource); - } - } - return $ok; -} - -/** - * @global object - * @param object $cm By Reference - * @return bool|array - */ -function hotpot_get_chain(&$cm) { - global $DB; - // get details of course_modules in this section - $course_module_ids = $DB->get_field('course_sections', 'sequence', array('id'=>$cm->section)); - if (empty($course_module_ids)) { - $hotpot_modules = array(); - } else { - $hotpot_modules = $DB->get_records_select('course_modules', "id IN ($course_module_ids) AND module=?", array($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 = $DB->get_records_list('hotpot', 'id', $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; -} - -/** - * @global object - * @global object - * @global object - * @param object $cm By Reference - * @return bool - */ -function hotpot_is_visible(&$cm) { - global $CFG, $COURSE, $DB; - - // check grouping - $modulecontext = get_context_instance(CONTEXT_MODULE, $cm->id); - if (empty($CFG->enablegroupmembersonly) || empty($cm->groupmembersonly) || has_capability('moodle/site:accessallgroups', $modulecontext)) { - // groupings not applicable - } else if (!isguestuser() && groups_has_membership($cm)) { - // user is in one of the groups in the allowed grouping - } else { - // user is not in the required grouping and does not have sufficiently privileges to view this hotpot activity - return false; - } - - // check if user can view hidden activities - $coursecontext = get_context_instance(CONTEXT_COURSE, $cm->course); - if (has_capability('moodle/course:viewhiddenactivities', $coursecontext)) { - return true; // user can view hidden activities - } - - if (!isset($cm->sectionvisible)) { - if (! $section = $DB->get_record('course_sections', array('id'=>$cm->section))) { - print_error('invalidsection'); - } - $cm->sectionvisible = $section->visible; - } - - 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; -} - -/** - * @global object - * @global object - * @global object - * @param object $hotpot By Reference - * @return bool|array - */ -function hotpot_add_chain(&$hotpot) { -/// add a chain of hotpot actiivities - - global $CFG, $course, $DB; - - $ok = true; - $hotpot->names = array(); - $hotpot->summaries = array(); - $hotpot->references = array(); - - $xml_quiz = new hotpot_xml_quiz($hotpot, false, false, false, false, false); - - if (isset($xml_quiz->error)) { - $hotpot->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 (false !== ($file = @readdir($dh))) { - if (preg_match('/\.(jbc|jcl|jcw|jmt|jmx|jqz|htm|html)$/', $file)) { - $hotpot->references[] = "$xml_quiz->reference/$file"; - } - } - closedir($dh); - - // get titles - foreach ($hotpot->references as $i=>$reference) { - $filepath = $xml_quiz->fileroot.'/'.$reference; - hotpot_get_titles_and_next_ex($hotpot, $filepath); - $hotpot->names[$i] = $hotpot->exercisetitle; - $hotpot->summaries[$i] = $hotpot->exercisesubtitle; - } - - } else { - $ok = false; - $hotpot->errors['reference'] = get_string('error_couldnotopenfolder', 'hotpot', $hotpot->reference); - } - - } else if (is_file($xml_quiz->filepath)) { - - $filerootlength = strlen($xml_quiz->fileroot) + 1; - - while ($xml_quiz->filepath) { - hotpot_get_titles_and_next_ex($hotpot, $xml_quiz->filepath, true); - $hotpot->names[] = $hotpot->exercisetitle; - $hotpot->summaries[] = $hotpot->exercisesubtitle; - $hotpot->references[] = substr($xml_quiz->filepath, $filerootlength); - - if ($hotpot->nextexercise) { - $filepath = $xml_quiz->fileroot.'/'.$xml_quiz->filesubdir.$hotpot->nextexercise; - - // check file is not already in chain - $reference = substr($filepath, $filerootlength); - if (in_array($reference, $hotpot->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; - $hotpot->errors['reference'] = get_string('error_notfileorfolder', 'hotpot', $hotpot->reference); - } - - if (empty($hotpot->references) && empty($hotpot->errors['reference'])) { - $ok = false; - $hotpot->errors['reference'] = get_string('error_noquizzesfound', 'hotpot', $hotpot->reference); - } - - if ($ok) { - $hotpot->visible = HOTPOT_YES; - - if (trim($hotpot->name)=='') { - $hotpot->name = get_string("modulename", $hotpot->modulename); - } - $hotpot->specificname = $hotpot->name; - $hotpot->specificsummary = $hotpot->summary; - - // add all except last activity in chain - - $i_max = count($hotpot->references)-1; - for ($i=0; $i<$i_max; $i++) { - - hotpot_set_name_summary_reference($hotpot, $i); - $hotpot->reference = $hotpot->reference; - - $hotpot->instance = $DB->insert_record("hotpot", $hotpot); - - // store (hotpot table) id of start of chain - if ($i==0) { - $hotpot->startofchain = $hotpot->instance; - } - - if (isset($course->groupmode)) { - $hotpot->groupmode = $course->groupmode; - } - - if (! $hotpot->coursemodule = add_course_module($hotpot)) { - print_error('cannotaddcoursemodule'); - } - if (! $sectionid = add_mod_to_section($hotpot) ) { - print_error('cannotaddcoursemoduletosection'); - } - - $DB->set_field('course_modules', 'section', $sectionid, array("id"=>$hotpot->coursemodule)); - - add_to_log($hotpot->course, "course", "add mod", - "../mod/$hotpot->modulename/view.php?id=$hotpot->coursemodule", - "$hotpot->modulename $hotpot->instance" - ); - add_to_log($hotpot->course, $hotpot->modulename, "add", - "view.php?id=$hotpot->coursemodule", - "$hotpot->instance", $hotpot->coursemodule - ); - - // hide tail of chain - if ($hotpot->shownextquiz==HOTPOT_YES) { - $hotpot->visible = HOTPOT_NO; - } - } // end for ($hotpot->references) - - // settings for final activity in chain - hotpot_set_name_summary_reference($hotpot, $i); - $hotpot->reference = $hotpot->references[$i]; - $hotpot->shownextquiz = HOTPOT_NO; - - if (isset($hotpot->startofchain)) { - // redirection only works for Moodle 1.5+ - $hotpot->redirect = true; - $hotpot->redirecturl = "$CFG->wwwroot/mod/hotpot/view.php?hp=$hotpot->startofchain"; - } - } // end if $ok - - return $ok; -} - -/** - * @param object $hotpot By Reference - * @param int $chain_index - */ -function hotpot_set_name_summary_reference(&$hotpot, $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 ($hotpot->$textsource) { - case HOTPOT_TEXTSOURCE_QUIZ: - if ($textfield=='name') { - $hotpot->exercisetitle = $hotpot->names[$chain_index]; - } else if ($textfield=='summary') { - $hotpot->exercisesubtitle = $hotpot->summaries[$chain_index]; - } - break; - case HOTPOT_TEXTSOURCE_SPECIFIC: - $specifictext = 'specific'.$textfield; - if (empty($hotpot->$specifictext) && trim($hotpot->$specifictext)=='') { - $hotpot->$textfield = ''; - } else { - $hotpot->$textfield = $hotpot->$specifictext.' ('.($chain_index+1).')'; - } - break; - } - $hotpot->reference = $hotpot->references[$chain_index]; - } - - if ($hotpot->$textsource==HOTPOT_TEXTSOURCE_QUIZ) { - if (empty($xml_quiz) && !isset($chain_index)) { - $xml_quiz = new hotpot_xml_quiz($hotpot, false, false, false, false, false); - hotpot_get_titles_and_next_ex($hotpot, $xml_quiz->filepath); - } - if ($textfield=='name') { - $hotpot->$textfield = $hotpot->exercisetitle; - } else if ($textfield=='summary') { - $hotpot->$textfield = $hotpot->exercisesubtitle; - } - } - switch ($hotpot->$textsource) { - case HOTPOT_TEXTSOURCE_FILENAME: - $hotpot->$textfield = basename($hotpot->reference); - break; - case HOTPOT_TEXTSOURCE_FILEPATH: - $hotpot->$textfield = ''; - // continue to next lines - default: - if (empty($hotpot->$textfield)) { - $hotpot->$textfield = str_replace('/', ' ', $hotpot->reference); - } - } // end switch - } // end foreach -} -/** - * @param object $hotpot By Reference - * @param string $filepath - * @param bool $get_next - */ -function hotpot_get_titles_and_next_ex(&$hotpot, $filepath, $get_next=false) { - - $hotpot->exercisetitle = ''; - $hotpot->exercisesubtitle = ''; - $hotpot->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('|]*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 - } - } - } - } - } - - $hotpot->nextexercise = $next; - $hotpot->exercisetitle = (empty($title) || is_array($title)) ? basename($filepath) : $title; - $hotpot->exercisesubtitle = (empty($subtitle) || is_array($subtitle)) ? $hotpot->exercisetitle : $subtitle; - } -} -/** - * @global object - * @global object - * @param string $modulename - * @param object $course - * @return array - */ -function hotpot_get_all_instances_in_course($modulename, $course) { -/// called from index.php - global $CFG, $DB; - - $instances = array(); - - $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, - cm.groupmode, - -- cs.section AS sectionnumber, - cs.section AS section, - cs.sequence AS sequence, - cs.visible AS sectionvisible, - thismodule.* - FROM - {course_modules} cm, - {course_sections} cs, - {modules} m, - {".$modulename."} thismodule - WHERE - m.name = :modulename AND - m.id = cm.module AND - cm.course = :courseid AND - cm.section = cs.id AND - cm.instance = thismodule.id - "; - $params = array('modulename'=>$modulename, 'courseid'=>$course->id); - - if ($rawmods = $DB->get_records_sql($query, $params)) { - - // cache $isteacher setting - - $isteacher = has_capability('mod/hotpot:viewreport', get_context_instance(CONTEXT_COURSE, $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 object - * @param object $hotpot By Reference - * @return bool - */ -function hotpot_update_chain(&$hotpot) { -/// update a chain of hotpot actiivities - global $DB; - - $ok = true; - if ($hotpot_modules = hotpot_get_chain($hotpot)) { - - // skip updating of these fields - $skipfields = array('id', 'course', 'name', 'reference', 'summary', 'shownextquiz'); - $fields = array(); - - foreach ($hotpot_modules as $hotpot_module) { - - if ($hotpot->instance==$hotpot_module->id) { - // don't need to update this hotpot - - } else { - // shortcut to hotpot record - $thishotpot = &$hotpot_module->hotpot; - - // get a list of fields to update (first time only) - if (empty($fields)) { - $fields = array_keys(get_object_vars($thishotpot)); - } - - // assume update is NOT required - $require_update = false; - - // update field values (except $skipfields) - foreach($fields as $field) { - if (in_array($field, $skipfields) || $thishotpot->$field==$hotpot->$field) { - // update not required for this field - } else { - $require_update = true; - $thishotpot->$field = $hotpot->$field; - } - } - - // update $thishotpot, if required - if ($require_update) { - $DB->update_record("hotpot", $thishotpot); - } - } - } // end foreach $ids - } - return $ok; -} -/** - * @global object - * @param int $id - * @return bool - */ -function hotpot_delete_instance($id) { - global $DB; -/// Given an ID of an instance of this module, -/// this function will permanently delete the instance -/// and any data that depends on it. - - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$id))) { - return false; - } - - if (! $DB->delete_records("hotpot", array("id"=>$id))) { - return false; - } - - $DB->delete_records("hotpot_questions", array("hotpot"=>$id)); - if ($attempts = $DB->get_records("hotpot_attempts", array("hotpot"=>$id))) { - $ids = implode(',', array_keys($attempts)); - $DB->delete_records_select("hotpot_attempts", "id IN ($ids)"); - $DB->delete_records_select("hotpot_details", "attempt IN ($ids)"); - $DB->delete_records_select("hotpot_responses", "attempt IN ($ids)"); - } - - // remove calendar events for this hotpot - $DB->delete_records('event', array('modulename'=>'hotpot', 'instance'=>$id)); - - // remove grade item for this hotpot - hotpot_grade_item_delete($hotpot); - - return true; -} -/** - * @global object - * @param string $table - * @param string $select - * @param array $params - * @param string $strtable - */ -function hotpot_delete_and_notify($table, $select, $params, $strtable) { - global $DB, $OUTPUT; - - $count = max(0, $DB->count_records_select($table, $select, $params)); - if ($count) { - $DB->delete_records_select($table, $select, $params); - $count -= max(0, $DB->count_records_select($table, $select, $params)); - if ($count) { - echo $OUTPUT->notification(get_string('deleted')." $count x $strtable"); - } - } -} - -/** - * Print a detailed representation of what a user has done with - * a given particular instance of this module, for user activity reports. - * - * @param object $course - * @param object $user - * @param object $mod - * @param object $hotpot - */ -function hotpot_user_complete($course, $user, $mod, $hotpot) { - $report = hotpot_user_outline($course, $user, $mod, $hotpot); - 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; -} - -/** - * Return a small object with summary information about what a - * user has done with a given particular instance of this module - * Used for user activity reports. - * $report->time = the time they did it - * $report->info = a short text description - * - * @global object - * @param object $course - * @param object $user - * @param object $mod - * @param object $hotpot - */ -function hotpot_user_outline($course, $user, $mod, $hotpot) { - global $DB; - - $report = NULL; - if ($records = $DB->get_records("hotpot_attempts", array('hotpot'=>$hotpot->id, 'userid'=>$user->id), "timestart ASC", "*")) { - $report = new stdClass(); - $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; -} - -/** - * @param object $record - * @param string $undefined - * @return string - */ -function hotpot_format_score($record, $undefined=' ') { - if (isset($record->score)) { - $score = $record->score; - } else { - $score = $undefined; - } - return $score; -} - -/** - * @global array - * @param object $record - * @param string $undefined - * @return string - */ -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; -} - -/** - * Given a course and a time, this module should find recent activity - * that has occurred in hotpot activities and print it out. - * Return true if there was output, or false is there was none. - * - * @global object - * @global object - * @param object $course - * @param bool $isteacher - * @param int $timestart - * @return bool - */ -function hotpot_print_recent_activity($course, $isteacher, $timestart) { - global $CFG, $DB, $OUTPUT; - - $result = false; - - $records = $DB->get_records_sql(" - SELECT - h.id AS id, - h.name AS name, - COUNT(*) AS count_attempts - FROM - {hotpot} h, - {hotpot_attempts} a - WHERE - h.course = ? - AND h.id = a.hotpot - AND a.id = a.clickreportid - AND a.starttime > ? - GROUP BY - h.id, h.name - ", array($course->id, $timestart)); - // note that PostGreSQL requires h.name in the GROUP BY clause - - if($records) { - $names = array(); - foreach ($records as $id => $record){ - if ($cm = get_coursemodule_from_instance('hotpot', $record->id, $course->id)) { - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - - if (has_capability('mod/hotpot:viewreport', $context)) { - $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$id"; - $name = ' '.$record->name.''; - if ($record->count_attempts > 1) { - $name .= " ($record->count_attempts)"; - } - $names[] = $name; - } - } - } - if (count($names) > 0) { - echo $OUTPUT->heading(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 -} - -/** - * Returns all quizzes since a given time. - * @global object - * @global object - * @param array $activities - * @param int $index - * @param int $sincetime - * @param int $courseid - * @param int $cmid - * @param int $userid - * @param int $groupid - */ -function hotpot_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $cmid="", $userid="", $groupid="") { - global $CFG, $DB; - - // 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"; - - $params = array('cmid'=>$cmid, 'userid'=>$userid, 'sincetime'=>$sincetime, 'courseid'=>$courseid); - - $records = $DB->get_records_sql(" - SELECT - a.*, - h.name, h.course, - cm.instance, cm.section, - u.firstname, u.lastname, u.picture - FROM - {hotpot_attempts} a, - {hotpot} h, - {course_modules} cm, - {user} 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 - ", $params); - - if (!empty($records)) { - foreach ($records as $record) { - if (empty($groupid) || groups_is_member($groupid, $record->userid)) { - - $activity = new object(); - - $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 - } -} - -/** - * Basically, this function prints the results of "hotpot_get_recent_activity" - * - * @global object - * @global object - * @global object - * @param object $activity - * @param object $course - * @param bool $detail - */ -function hotpot_print_recent_mod_activity($activity, $course, $detail=false) { - - global $CFG, $USER, $OUTPUT; - - $bgcolor = ''; - - print ''; - - print ''; - echo $OUTPUT->user_picture($activity->user, array('courseid'=>$course)); - print '"; - print "
'; - - if ($detail) { - // activity icon - $src = "" . $OUTPUT->pix_url('icon', $activity->type) . ""; - print ''.$activity->type.' '; - - // link to activity - $href = "$CFG->wwwroot/mod/hotpot/view.php?hp=$activity->instance"; - print ''.$activity->name.' - '; - } - if (has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $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.'
'; - } - - // 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); - - // duration - $duration = format_time($activity->content->timestart - $activity->content->timefinish); - print "   ($duration)"; - - print "
"; -} - -/** - * Function to be run periodically according to the moodle cron - * This function searches for things that need to be done, such - * as sending out mail, toggling flags etc ... - * - * @return true - */ -function hotpot_cron () { - return true; -} - -/** - * Must return an array of grades for a given instance of this module, - * indexed by user. It also returns a maximum allowed grade. - * - * @global object - * @param itn $hotpotid - * @return object - */ -function hotpot_grades($hotpotid) { - global $DB; - - $hotpot = $DB->get_record('hotpot', array('id'=>$hotpotid)); - - $return = new object(); - $return->grades = hotpot_get_grades($hotpot); - $return->maxgrade = $hotpot->grade; - - return $return; -} -/** - * @global object - * @global object - * @param object $hotpot - * @param arry $user_ids - * @return array - */ -function hotpot_get_grades($hotpot, $user_ids='') { - global $CFG, $DB; - - $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: - $grade = "ROUND(score * $weighting, $precision)"; - $grade = $DB->sql_concat('timestart', "'_'", $grade); - $grade = "MIN($grade) AS grade"; - break; - case HOTPOT_GRADEMETHOD_LAST: - $grade = "ROUND(score * $weighting, $precision)"; - $grade = $DB->sql_concat('timestart', "'_'", $grade); - $grade = "MAX($grade) AS grade"; - break; - } - - if ($grade) { - $userid_condition = empty($user_ids) ? '' : "AND userid IN ($user_ids) "; - $grades = $DB->get_records_sql_menu(" - SELECT userid, $grade - FROM {hotpot_attempts} - WHERE timefinish>0 AND hotpot=:hid $userid_condition - GROUP BY userid - ", array('hid'=>$hotpot->id)); - 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; -} -/** - * @return int - */ -function hotpot_get_precision(&$hotpot) { - return ($hotpot->grademethod==HOTPOT_GRADEMETHOD_AVERAGE || $hotpot->grade<100) ? 1 : 0; -} - -/** - * Return grade for given user or all users. - * - * @param object $hotpot - * @param int $userid optional user id, 0 means all users - * @return array array of grades, false if none - */ -function hotpot_get_user_grades($hotpot, $userid=0) { - $grades = array(); - if ($hotpotgrades = hotpot_get_grades($hotpot, $userid)) { - foreach ($hotpotgrades as $hotpotuserid => $hotpotgrade) { - $grades[$hotpotuserid] = new stdClass(); - $grades[$hotpotuserid]->id = $hotpotuserid; - $grades[$hotpotuserid]->userid = $hotpotuserid; - $grades[$hotpotuserid]->rawgrade = $hotpotgrade; - } - } - if (count($grades)) { - return $grades; - } else { - return false; - } -} - -/** - * Update grades in central gradebook - * @global object - * @global object - * @param object $hotpot - * @param int $userid specific user only, 0 means all users - * @param bool $nullifnone - */ -function hotpot_update_grades($hotpot, $userid=0, $nullifnone=true) { - global $CFG, $DB; - require_once($CFG->libdir.'/gradelib.php'); - - // update (=create) grade for a single hotpot - if ($grades = hotpot_get_user_grades($hotpot, $userid)) { - hotpot_grade_item_update($hotpot, $grades); - - } else if ($userid && $nullifnone) { - // no grades for this user, but we must force the creation of a "null" grade record - $grade = new object(); - $grade->userid = $userid; - $grade->rawgrade = null; - hotpot_grade_item_update($hotpot, $grade); - - } else { - // no grades and no userid - hotpot_grade_item_update($hotpot); - } -} - -/** - * Update all grades in gradebook. - * this function is called from db/upgrade.php - * it iterates through the hotpots, calling hotpot_update_grades() to create a grade record for each hotpot - * @global object - */ -function hotpot_upgrade_grades() { - global $DB; - - // upgrade (=create) grades for all hotpots - $sql = " - SELECT COUNT('x') - FROM {hotpot} h, {course_modules} cm, {modules} m - WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=h.id"; - $count = $DB->count_records_sql($sql); - - $sql = " - SELECT h.*, cm.idnumber AS cmidnumber - FROM {hotpot} h, {course_modules} cm, {modules} m - WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=h.id"; - if ($rs = $DB->get_recordset_sql($sql)) { - // too much debug output - $pbar = new progress_bar('hotpotupgradegrades', 500, true); - $i=0; - foreach ($rs as $hotpot) { - $i++; - upgrade_set_timeout(60*5); // set up timeout, may also abort execution - hotpot_update_grades($hotpot, 0, false); - $pbar->update($i, $count, "Updating Hotpot grades ($i/$count)."); - } - $rs->close(); - } -} - -/** - * Update/create grade item for given hotpot - * - * @global object - * @param object $hotpot object with extra cmidnumber - * @param mixed optional array/object of grade(s); 'reset' means reset grades in gradebook - * @return object grade_item - */ -function hotpot_grade_item_update($hotpot, $grades=null) { - global $CFG; - require_once($CFG->libdir.'/gradelib.php'); - - $params = array('itemname' => $hotpot->name); - if (array_key_exists('cmidnumber', $hotpot)) { - //cmidnumber may not be always present - $params['idnumber'] = $hotpot->cmidnumber; - } - if ($hotpot->grade > 0) { - $params['gradetype'] = GRADE_TYPE_VALUE; - $params['grademax'] = $hotpot->grade; - $params['grademin'] = 0; - - } else { - $params['gradetype'] = GRADE_TYPE_NONE; - } - return grade_update('mod/hotpot', $hotpot->course, 'mod', 'hotpot', $hotpot->id, 0, $grades, $params); -} - -/** - * Delete grade item for given hotpot - * - * @global object - * @param object $hotpot object - * @return object grade_item - */ -function hotpot_grade_item_delete($hotpot) { - global $CFG; - require_once($CFG->libdir.'/gradelib.php'); - return grade_update('mod/hotpot', $hotpot->course, 'mod', 'hotpot', $hotpot->id, 0, null, array('deleted'=>1)); -} - -/** - * Must return an array of user ids who are participants - * 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 object - * @param int $hotpotid - */ -function hotpot_get_participants($hotpotid) { - global $DB; - - return $DB->get_records_sql(" - SELECT DISTINCT - u.id, u.id - FROM - {user} u, - {hotpot_attempts} a - WHERE - u.id = a.userid - AND a.hotpot = ? - ", array($hotpotid)); -} - -/** - * This function returns if a scale is being used by one hotpot - * it it has support for grading and scales. Commented code should be - * modified if necessary. See forum, glossary or journal modules - * as reference. - * - * @param int $hotpotid - * @param int $scaleid - * @return bool - */ - -function hotpot_scale_used ($hotpotid, $scaleid) { - $report = false; - - //$rec = $DB->get_record("hotpot", array("id"=>"$hotpotid","scale"=>-$scaleid)); - // - //if (!empty($rec) && !empty($scaleid)) { - // $report = true; - //} - - return $report; -} - -/** - * Checks if scale is being used by any instance of hotpot - * - * This is used to find out if scale used anywhere - * @param int $scaleid - * @return boolean True if the scale is used by any hotpot - */ -function hotpot_scale_used_anywhere($scaleid) { - return false; -} - -////////////////////////////////////////////////////////// -/// Any other hotpot functions go here. -/// Each of them must have a name that starts with hotpot - -/** - * @global object - * @global stdClass - * @global object - * @uses HOTPOT_STATUS_INPROGRESS - * @uses HOTPOT_STATUS_ABANDONED - * @param int @hotpotid - * @return bool - */ -function hotpot_add_attempt($hotpotid) { - global $DB, $CFG, $USER; - - // get start time of this attempt - $time = time(); - - // set all previous "in progress" attempts at this quiz to "abandoned" - if ($attempts = $DB->get_records('hotpot_attempts', array('hotpot'=>$hotpotid, 'userid'=>$USER->id, 'status'=>HOTPOT_STATUS_INPROGRESS))) { - foreach ($attempts as $attempt) { - if ($attempt->timefinish==0) { - $attempt->timefinish = $time; - } - if ($attempt->clickreportid==0) { - $attempt->clickreportid = $attempt->id; - } - $attempt->status = HOTPOT_STATUS_ABANDONED; - $DB->update_record('hotpot_attempts', $attempt); - } - } - - // create and add new attempt record - $attempt = new stdClass(); - $attempt->hotpot = $hotpotid; - $attempt->userid = $USER->id; - $attempt->attempt = hotpot_get_next_attempt($hotpotid); - $attempt->timestart = $time; - - return $DB->insert_record("hotpot_attempts", $attempt); -} -/** - * @global object - * @global object - * @param int $hotpotid - * @return int - */ -function hotpot_get_next_attempt($hotpotid) { - global $USER, $DB; - - // get max attempt so far - $i = $DB->count_records_select('hotpot_attempts', "hotpot=? AND userid=?", array($hotpotid, $USER->id), 'MAX(attempt)'); - - return empty($i) ? 1 : ($i+1); -} -/** - * @param object $question - * @return string - */ -function hotpot_get_question_name($question) { - $name = ''; - if (isset($question->text)) { - $name = hotpot_strings($question->text); - } - if (empty($name)) { - $name = $question->name; - } - return $name; -} -/** - * @global object - * @param array $ids - * @return string - */ -function hotpot_strings($ids) { - global $DB; - - // array of ids of empty strings - static $HOTPOT_EMPTYSTRINGS; - - if (!isset($HOTPOT_EMPTYSTRINGS)) { // first time only - // get ids of empty strings - $emptystrings = $DB->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); -} -/** - * @global object - * @param int $id - * @return object - */ -function hotpot_string($id) { - global $DB; - return $DB->get_field('hotpot_strings', 'string', array('id'=>$id)); -} - -////////////////////////////////////////////////////////////////////////////////////// -/// the class definitions to handle XML trees - -// get the standard XML parser supplied with Moodle -require_once("$CFG->libdir/xmlize.php"); - -// get the default class for hotpot quiz templates -require_once("$CFG->hotpottemplate/default.php"); - -/** - * @package mod-hotpot - * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class hotpot_xml_tree { - /** - * @param string $str - * @param string $xml_root - */ - function hotpot_xml_tree($str, $xml_root='') { - if (empty($str)) { - $this->xml = array(); - } else { - $this->xml = xmlize($str, 0); - } - $this->xml_root = $xml_root; - } - /** - * @param string $tags - * @param string $more_tags - * @return string - */ - 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)) { - - // 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; - } - /** - * @param string $tags - * @return array - */ - function xml_values($tags) { - $i = 0; - $values = array(); - while ($value = $this->xml_value($tags, "[$i]['#']")) { - $values[$i++] = $value; - } - return $values; - } - /** - * @param object $obj - * @param string $name - * @return mixed - */ - function obj_value(&$obj, $name) { - return is_object($obj) ? @$obj->$name : (is_array($obj) ? @$obj[$name] : NULL); - } - /** - * @param string $str - * @param string $tag - */ - 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)) { - if ($this->report_errors) { - print_error('error_nocourseorfilename', 'hotpot'); - } - 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)) { - if ($this->report_errors) { - print_error('error_couldnotopensourcefile', 'hotpot'); - } - 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 = "hotpot_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_id, $form_fields, $keep_contents, true); - } - /** - * @global stdClass - * @param string $startblock - * @param string $endblock - * @param string $form_id - * @param mixed $form_fields - * @param bool $keep_contents - * @param bool $center - * @param string $targetframe - */ - function insert_form($startblock, $endblock, $form_id, $form_fields, $keep_contents, $center=false, $targetframe='') { - global $CFG; - $search = '#('.preg_quote($startblock).')(.*?)('.preg_quote($endblock).')#s'; - $replace = $form_fields; - if ($keep_contents) { - $replace .= '\\2'; - } - if ($targetframe) { - $frametarget = ' onsubmit="'."this.target='$targetframe';".'"'; - } else if (! empty($CFG->framename)) { - $frametarget = ' onsubmit="'."this.target='$CFG->framename';".'"'; - } else { - $frametarget = ''; - } - if ($form_id) { - $replace = ''.$replace.''; - } - if ($center) { - $replace = '
'.$replace.'
'; - } - $replace = '\\1'.$replace.'\\3'; - $this->html = preg_replace($search, $replace, $this->html, 1); - } - /** - * @param string $start_str - * @param string $message - * @param string $color - * @param string $align - */ - 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); - } - /** - * @global stdClass - */ - 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"; - include_once "$CFG->dirroot/mod/hotpot/mediaplayers/moodle/filter.php"; - - $space = '\s(?:.+\s)?'; - $quote = '["'."']?"; // single, double, or no quote - - // patterns to media files types and paths - $filetypes = "avi|mpeg|mpg|mp3|mov|wmv|flv"; - if ($CFG->filter_mediaplugin_enable_swf) { - $filetypes .= '|swf'; - } - $filepath = '[^"'."']*".'\\.(?:'.$filetypes.')[^"'."']*"; - - $tagopen = '(?:(<)|(\\\\u003C))'; // left angle-bracket (uses two parenthese) - $tagchars = '(?(1)[^>]|(?(2).(?!\\\\u003E)))*?'; // string of chars inside the tag - $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 - $param_names = 'movie|src|url|flashvars'; - // wmp : url - // quicktime : src - // realplayer : src - // flash : movie, flashvars - $param_url = '/'.$tagopen.'param'.'\s'.$tagchars.'name="(?:'.$param_names.')"'.$tagchars.'value="('.$filepath.')"'.$tagchars.$tagclose.'/is'; - - // pattern to match tags which link to multimedia files - $link_url = '/'.$tagopen.'a'.'\s'.$tagchars.'href="('.$filepath.')"'.$tagchars.$tagclose.'.*?'.$tagreopen.'\/a'.$tagclose.'/is'; - - // extract tags - $object_tag = '/'.$tagopen.'object'.'\s'.$tagchars.$tagclose.'(.*?)'.'(?:'.$tagreopen.'\/object'.$tagclose.')+/is'; - preg_match_all($object_tag, $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('/^([^=]+=[^&]*&)*[^=]+=(http:[^&]*)$/', '$2', $url, 1); - $link = ''.$txt.''; - - $new_object = hotpot_mediaplayer_moodle($this, $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 -/** - * strip slashes from double quotes, single quotes and back slashes - * the slashes were added by preg_replace() when using the "e" modifier - * - * @staticvar array $escapedchars - * @staticvar array $escapedchars - * @param string - */ -function hotpot_stripslashes($str) { - static $escapedchars = array('\\\\', '\\"', "\\'"); - static $unescapedchars = array('\\', '"', "'"); - return str_replace($escapedchars, $unescapedchars, $str); -} -/** - * @param string $baseurl - * @param string $reference - * @param string $css - * @param bool $stripslashes - * @return string - */ -function hotpot_convert_stylesheets_urls($baseurl, $reference, $css, $stripslashes=true) { - if ($stripslashes) { - $css = hotpot_stripslashes($css); - } - $search = '|'.'(?<='.'url'.'\('.')'."(.+?)".'(?='.'\)'.')'.'|ise'; - $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; - return preg_replace($search, $replace, $css); -} -/** - * @param string $baseurl - * @param string $reference - * @param array|string $urls - * @param bool $stripslashes - * @return string - */ -function hotpot_convert_preloadimages_urls($baseurl, $reference, $urls, $stripslashes=true) { - if ($stripslashes) { - $urls = hotpot_stripslashes($urls); - } - $search = '|(?<=["'."'])([^,'".'"]*?)(?=["'."'])|ise"; - $replace = "hotpot_convert_url('".$baseurl."','".$reference."','\\1')"; - return preg_replace($search, $replace, $urls); -} -/** - * @global stdClass - * @global object - * @param string $baseurl - * @param string $reference - * @param string $url - * @param object $course - * @param bool $stripslashes - * @return string - */ -function hotpot_convert_navbutton_url($baseurl, $reference, $url, $course, $stripslashes=true) { - global $CFG, $DB; - - if ($stripslashes) { - $url = hotpot_stripslashes($url); - } - $url = hotpot_convert_url($baseurl, $reference, $url, false); - - // is this a $url for another hotpot in this course ? - if (preg_match("|^".preg_quote($baseurl)."(.*)$|", $url, $matches)) { - if ($records = $DB->get_records('hotpot', array('course'=>$course, 'reference'=>$matches[1]))) { - $ids = array_keys($records); - $url = "$CFG->wwwroot/mod/hotpot/view.php?hp=".$ids[0]; - } - } - - return $url; -} -/** - * @param string $baseurl - * @param string $reference - * @param string $opentage - * @param string $url - * @param string $closetage - * @param bool $stripslashes - * @return string - */ -function hotpot_convert_relative_url($baseurl, $reference, $opentag, $url, $closetag, $stripslashes=true) { - if ($stripslashes) { - $opentag = hotpot_stripslashes($opentag); - $url = hotpot_stripslashes($url); - $closetag = hotpot_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|mp3)='."([^&]+)".'#ise'; - $replace = "'\\1='.hotpot_convert_url('".$baseurl."','".$reference."','\\2')"; - $query = preg_replace($search, $replace, $query); - } - - $url = $opentag.$url.$query.$fragment.$closetag; - - return $url; -} -/** - * @staticvar array $HOTPOT_RELATIVE_URLS - * @param string $baseurl - * @param string $reference - * @param string $url - * @param bool $stripslashes - */ -function hotpot_convert_url($baseurl, $reference, $url, $stripslashes=true) { - // maintain a cache of converted urls - static $HOTPOT_RELATIVE_URLS = array(); - - if ($stripslashes) { - $url = hotpot_stripslashes($url); - } - - // is this an absolute url? (or javascript pseudo url) - if (preg_match('%^(http://|https://|/|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; -} - -/** - * function for adding attempt questions and responses - * - * @param object $attempt - */ -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); -} -/** - * @global object - * @global string - * @param object $attempt - * @param object $question - * @param object $response - */ -function hotpot_add_response(&$attempt, &$question, &$response) { - global $DB, $next_url; - - $loopcount = 1; - - $looping = isset($question) && isset($question->name) && isset($response); - while ($looping) { - - if ($loopcount==1) { - $questionname = $question->name; - } - - $question->md5key = md5($question->name); - if (!$question->id = $DB->get_field('hotpot_questions', 'id', array('hotpot'=>$attempt->hotpot, 'md5key'=>$question->md5key, 'name'=>$question->name))) { - // add question record - $question->id = $DB->insert_record('hotpot_questions', $question); - } - - if ($DB->record_exists('hotpot_responses', array('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 - - $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. - - } else { - $response->question = $question->id; - - // add response record - $response->id = $DB->insert_record('hotpot_responses', $response); - - // we can stop looping now - $looping = false; - } - } // end while -} -/** - * @param string $quiztype - * @param object $question - * @param string $num - * @param string $name - * @param int|string $data - */ -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; - } -} -/** - * @param string $field_value - * @return string - */ -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); -} -/** - * @global object - * @param string $str - * @return int|string - */ -function hotpot_string_id($str) { - global $DB; - - $id = ''; - if (isset($str) && $str<>'') { - - // get the id from the table if it is already there - $md5key = md5($str); - if (!$id = $DB->get_field('hotpot_strings', 'id', array('md5key'=>$md5key, 'string'=>$str))) { - - // create a string record - $record = new stdClass(); - $record->string = $str; - $record->md5key = $md5key; - - // try and add the new string record - $id = $DB->insert_record('hotpot_strings', $record); - } - } - return $id; -} -/** - * @return array - */ -function hotpot_get_view_actions() { - return array('view','view all','report'); -} -/** - * @return array - */ -function hotpot_get_post_actions() { - return array('attempt','review','submit'); -} - -/** - * @staticvar array $HOTPOT_UTF8_DECREMENT - * @staticvar array $HOTPOT_UTF8_SHIFT - * @param string $char - * @return string - */ -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).';'; -} -/** - * @global object - * @param string $course - * @param string $location - * @param string $reference - * @param string $actions - * @param string $spacer - * @param bool $new_window - * @param bool $return - * @return string|void - */ -function hotpot_print_show_links($course, $location, $reference, $actions='', $spacer='   ', $new_window=false, $return=false) { - global $CFG; - if (is_string($actions)) { - if (empty($actions)) { - $actions = 'showxmlsource,showxmltree,showhtmlsource'; - } - $actions = explode(',', $actions); - } - $strenterafilename = get_string('enterafilename', 'hotpot'); - $html = << -//=0) { - i = s.indexOf(name+'=', i+1); - if (i>=0) { - i += name.length+1; - var ii = s.indexOf('&', i); - if (ii<0) { - ii = s.length; - } - lnk.href = s.substring(0, i) + v + s.substring(ii); - r = true; - } - } - } - } - return r; - } - function getObjValue(obj) { - var v = ''; // the value - var t = (obj && obj.type) ? obj.type : ""; - if (t=="text" || t=="textarea" || t=="hidden") { - v = obj.value; - } else if (t=="select-one" || t=="select-multiple") { - var l = obj.options.length; - for (var i=0; i - -END_OF_SCRIPT; - - foreach ($actions as $action) { - $html .= $spacer - . ''.get_string($action, 'hotpot').'' - ; - } - $html = ''.$html.''; - if ($return) { - return $html; - } else { - print $html; - } -} - -/** - * Returns all other caps used in module - * @return array - */ -function hotpot_get_extra_capabilities() { - return array('moodle/site:accessallgroups'); -} - -/** - * This function is used by the reset_course_userdata function in moodlelib. - * This function will remove all attempts from hotpot quizzes in the specified course. - * - * @global stdClass - * @global object - * @param object $data the data submitted from the reset course. - * @return array status array - */ -function hotpot_reset_userdata($data) { - global $CFG, $DB; - require_once($CFG->libdir.'/filelib.php'); - - $status = array(); - - if (!empty($data->reset_hotpot_deleteallattempts)) { - - $hotpotids = 'SELECT h.id FROM {hotpot} h WHERE h.course='.$data->courseid; - $attemptids = 'SELECT a.id FROM {hotpot_attempts} a WHERE a.hotpot in ('.$hotpotids.')'; - - $DB->delete_records_select('hotpot_responses', "attempt in ($attemptids)"); - $DB->delete_records_select('hotpot_details', "attempt in ($attemptids)"); - $DB->delete_records_select('hotpot_attempts', "hotpot IN ($hotpotids)"); - - $status[] = array('component' => get_string('modulenameplural', 'hotpot'), - 'item' => get_string('deleteallattempts', 'hotpot'), - 'error' => false); - } - - return $status; -} - -/** - * Called by course/reset.php - * - * @param $mform form passed by reference - */ -function hotpot_reset_course_form_definition(&$mform) { - $mform->addElement('header', 'hotpotheader', get_string('modulenameplural', 'hotpot')); - $mform->addElement('checkbox', 'reset_hotpot_deleteallattempts', get_string('deleteallattempts', 'hotpot')); -} - -/** - * Course reset form defaults. - * - * @return array - */ -function hotpot_reset_course_form_defaults($course) { - return array('reset_hotpot_deleteallattempts' => 1); -} - -/** - * This function extends the global navigation for the site. - * It is important to note that you should not rely on PAGE objects within this - * body of code as there is no guarantee that during an AJAX request they are - * available - * - * @param navigation_node $navigation The hotpot node within the global navigation - * @param stdClass $course The course object returned from the DB - * @param stdClass $module The module object returned from the DB - * @param stdClass $cm The course module instance returned from the DB - */ -function hotpot_extend_navigation($navigation, $course, $module, $cm) { - /** - * This is currently just a stub so that it can be easily expanded upon. - * When expanding just remove this comment and the line below and then add - * you content. - */ - $navigation->nodetype = navigation_node::NODETYPE_LEAF; -} \ No newline at end of file diff --git a/mod/hotpot/mediaplayers/moodle/filter.php b/mod/hotpot/mediaplayers/moodle/filter.php deleted file mode 100644 index 1cf80355385..00000000000 --- a/mod/hotpot/mediaplayers/moodle/filter.php +++ /dev/null @@ -1,251 +0,0 @@ -filter_mediaplugin_enable_mp3) { - static $c; - - if (empty($c)) { - $c = $OUTPUT->filter_mediaplugin_colors(); // You can set this up in your theme/xxx/config.php - } - // $c = htmlentities($c); // Commented out pending bug 5223 - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0 wwwroot/filter/mediaplugin/mp3player.swf?src=\\2.mp3\" />"; - $replace .= ' '; - $replace .= ' '; - $replace .= ' '; - $replace .= " wwwroot/filter/mediaplugin/mp3player.swf?src=\\2.mp3\" "; - $replace .= " quality=\"high\" bgcolor=\"#333333\" width=\"90\" height=\"15\" name=\"mp3player\" "; - $replace .= ' type="application/x-shockwave-flash" '; - $replace .= ' flashvars="'.$c.'" '; - $replace .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">'; - $replace .= ''; - $replace .= ' '; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_swf) { - $search = array( - '/]*)>(.*?)<\/a>/is', - '/]*)>(.*?)<\/a>/is' - ); - - $replace = array(); - - $replace[0] = '\\0

"; - $replace[0] .= ' '; - $replace[0] .= ' '; - $replace[0] .= " "; - $replace[1] .= ' '; - $replace[1] .= ' '; - $replace[1] .= " filter_mediaplugin_enable_flv) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0 wwwroot/filter/mediaplugin/flvplayer.swf?file=\\2.flv\" />"; - $replace .= ' '; - $replace .= ' '; - $replace .= " wwwroot/filter/mediaplugin/flvplayer.swf?file=\\2.flv\" "; - $replace .= " quality=\"high\" bgcolor=\"#FFFFFF\" width=\"480\" height=\"360\" name=\"flvplayer\" "; - $replace .= ' type="application/x-shockwave-flash" '; - $replace .= ' pluginspage="http://www.macromedia.com/go/getflashplayer">'; - $replace .= ''; - $replace .= ' '; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_mov) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

"; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= "\nfilter_mediaplugin_enable_wmv) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

"; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= "\nfilter_mediaplugin_enable_mpg) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

'; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ' '; - $replace .= '

'; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_avi) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

'; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ' '; - $replace .= '

'; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_ram) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

'; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '
'; - - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '

'; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_rpm) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

'; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '
'; - - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '

'; - - $text = preg_replace($search, $replace, $text); - } - - if ($CFG->filter_mediaplugin_enable_rm) { - $search = '/]*)>(.*?)<\/a>/is'; - - $replace = '\\0

'; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '
'; - - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= ''; - $replace .= '

'; - - $text = preg_replace($search, $replace, $text); - } - - return $text; -} diff --git a/mod/hotpot/mod_form.js b/mod/hotpot/mod_form.js deleted file mode 100644 index c6c185496ec..00000000000 --- a/mod/hotpot/mod_form.js +++ /dev/null @@ -1,48 +0,0 @@ -// \ No newline at end of file diff --git a/mod/hotpot/mod_form.php b/mod/hotpot/mod_form.php deleted file mode 100644 index 2d7424bee83..00000000000 --- a/mod/hotpot/mod_form.php +++ /dev/null @@ -1,338 +0,0 @@ -dirroot.'/course/moodleform_mod.php'); -require_once ($CFG->dirroot.'/mod/hotpot/lib.php'); - -$HOTPOT_TEXTSOURCE = array( - HOTPOT_TEXTSOURCE_QUIZ => get_string('textsourcequiz', 'hotpot'), - HOTPOT_TEXTSOURCE_FILENAME => get_string('textsourcefilename', 'hotpot'), - HOTPOT_TEXTSOURCE_FILEPATH => get_string('textsourcefilepath', 'hotpot'), - HOTPOT_TEXTSOURCE_SPECIFIC => get_string('textsourcespecific', 'hotpot') -); - -class mod_hotpot_mod_form extends moodleform_mod { - // documentation on formslib.php here: - // http://docs.moodle.org/en/Development:lib/formslib.php_Form_Definition - - function definition() { - // TO DO - // ===== - // $mform->setType('name', PARAM_xxx); - // $mform->setDefault('name', array('elementhelpfilename', get_string('helpicontitlestring', 'hotpot'), 'hotpot')); - - global $CFG, $COURSE, $OUTPUT; - global $HOTPOT_FEEDBACK, $HOTPOT_GRADEMETHOD, $HOTPOT_LOCATION; - global $HOTPOT_NAVIGATION, $HOTPOT_OUTPUTFORMAT, $HOTPOT_TEXTSOURCE; - - $mform =&$this->_form; - - // initialize values for $hours, $minutes and $seconds - $hours = array(); - $minutes = array(); - $seconds = array(); - for ($i=0; $i<60; $i++) { - $str = sprintf('%02d', $i); - if ($i<24) { - $hours[$i] = $str; - } - $minutes[$i] = $str; - $seconds[$i] = $str; - } - -//----------------------------------------------------------------------------------------------- - $mform->addElement('header', 'general', get_string('general', 'form')); -//----------------------------------------------------------------------------------------------- - -// Name - global $form; - if (isset($form->add)) { - // new HotPot - $elements = array(); - $elements[] = &$mform->createElement('select', 'namesource', '', $HOTPOT_TEXTSOURCE); - $elements[] = &$mform->createElement('text', 'name', '', array('size' => '40')); - $mform->addGroup($elements, 'name_elements', get_string('name'), array(' '), false); - $mform->disabledIf('name_elements', 'namesource', 'ne', HOTPOT_TEXTSOURCE_SPECIFIC); - // $mform->setAdvanced('name_elements'); - } else { - // existing HotPot - $mform->addElement('hidden', 'namesource', HOTPOT_TEXTSOURCE_SPECIFIC); - $mform->setType('namesource', PARAM_RAW); - $mform->addElement('text', 'name', get_string('name'), array('size' => '40')); - } - $mform->setType('namesource', PARAM_INT); - if (!empty($CFG->formatstringstriptags)) { - $mform->setType('name', PARAM_TEXT); - } else { - $mform->setType('name', PARAM_CLEAN); - } - -// Location - $sitecontext = get_context_instance(CONTEXT_SYSTEM); - if (has_capability('moodle/course:managefiles', $sitecontext)) { - $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)) { - $mform->addElement('hidden', 'location', $location); - $mform->setType('location', PARAM_RAW); - } else { // admin can select from "site" or "course" files - $mform->addElement('select', 'location', get_string('location', 'hotpot'), $HOTPOT_LOCATION); - } - $mform->setType('location', PARAM_INT); - -// Reference - // create "Choose file" button - $choosefile_button = $mform->createElement('button', 'popup', get_string('chooseafile', 'resource') .' ...'); - - // create a 'reference' group of form elements, comprising text box + buttons - $elements = array(); - $elements[] = $mform->createElement('text', 'reference', '', array('size'=>'60')); - $elements[] = &$choosefile_button; - $mform->addGroup($elements, 'reference_elements', get_string('filename', 'resource'), ' ' , false); - - // set attributes on the button - if ($choosefile_button) { - $wdir = "'+getDir(this.form.reference.value)+'"; - $url="/files/index.php?id=$id&wdir=$wdir&choose=id_reference"; - $attributes = array( - 'title'=>get_string('chooseafile', 'resource') - ); - $choosefile_button->updateAttributes($attributes); - - //attach the onclick event - $action = new popup_action('click', $url, $choosefile_button->getName(), array('title'=>$choosefile_button->getName(),'width'=>750,'height'=>500)); - $OUTPUT->add_action_handler($action, $choosefile_button->id); - } - $mform->setType('reference', PARAM_TEXT); - -// Summary - if (isset($form->add)) { - // new HotPot - $elements = array(); - $elements[] = &$mform->createElement('select', 'summarysource', '', $HOTPOT_TEXTSOURCE); - $elements[] = &$mform->createElement('htmleditor', 'summary', ''); - $mform->addGroup($elements, 'summary_elements', get_string('summary'), array(' '), false); - $mform->setAdvanced('summary_elements'); - } else { - // existing HotPot - $mform->addElement('hidden', 'summarysource', HOTPOT_TEXTSOURCE_SPECIFIC); - $mform->setType('summarysource', PARAM_RAW); - $mform->addElement('htmleditor', 'summary', get_string('summary')); - $mform->setType('summary', PARAM_RAW); - $mform->setAdvanced('summary'); - } - $mform->setType('summarysource', PARAM_INT); - $mform->setType('summary', PARAM_RAW); - -// Add/Update quiz chain? - if (isset($form->add)) { - $quizchain = 'addquizchain'; - } else { - $quizchain = 'updatequizchain'; - } - $mform->addElement('selectyesno', 'quizchain', get_string($quizchain, 'hotpot')); - $mform->setDefault('quizchain', get_user_preferences("hotpot_$quizchain", HOTPOT_NO)); - $mform->setHelpButton('quizchain', array($quizchain, get_string($quizchain, 'hotpot'), 'hotpot')); - // $mform->setAdvanced('quizchain'); - -//----------------------------------------------------------------------------------------------- - $mform->addElement('header', 'displayhdr', get_string('display', 'form')); -//----------------------------------------------------------------------------------------------- - -// Output format - $mform->addElement('select', 'outputformat', get_string('outputformat', 'hotpot'), $HOTPOT_OUTPUTFORMAT); - $mform->setDefault('outputformat', get_user_preferences('hotpot_outputformat', HOTPOT_OUTPUTFORMAT_BEST)); - $mform->setHelpButton('outputformat', array('outputformat', get_string('outputformat', 'hotpot'), 'hotpot')); - -// Navigation - $mform->addElement('select', 'navigation', get_string('navigation', 'hotpot'), $HOTPOT_NAVIGATION); - $mform->setDefault('navigation', get_user_preferences('hotpot_navigation', HOTPOT_NAVIGATION_BAR)); - $mform->setHelpButton('navigation', array('navigation', get_string('navigation', 'hotpot'), 'hotpot')); - -// Use Moode player ? - $mform->addElement('selectyesno', 'forceplugins', get_string('forceplugins', 'hotpot')); - $mform->setDefault('forceplugins', get_user_preferences('hotpot_forceplugins', HOTPOT_NO)); - $mform->setHelpButton('forceplugins', array('forceplugins', get_string('forceplugins', 'hotpot'), 'hotpot')); - // $mform->setAdvanced('forceplugins'); - -// Student feedback - $elements = array(); - $elements[] = &$mform->createElement('select', 'studentfeedback', '', $HOTPOT_FEEDBACK); - $elements[] = &$mform->createElement('text', 'studentfeedbackurl', '', array('size'=>'50')); - $mform->addGroup($elements, 'studentfeedback_elements', get_string('studentfeedback', 'hotpot'), array(' '), false); - $mform->setHelpButton('studentfeedback_elements', array('studentfeedback', get_string('studentfeedback', 'hotpot'), 'hotpot')); - $mform->disabledIf('studentfeedback_elements', 'studentfeedback', 'eq', HOTPOT_FEEDBACK_NONE); - $mform->disabledIf('studentfeedback_elements', 'studentfeedback', 'eq', HOTPOT_FEEDBACK_MOODLEFORUM); - $mform->disabledIf('studentfeedback_elements', 'studentfeedback', 'eq', HOTPOT_FEEDBACK_MOODLEMESSAGING); - // $mform->setAdvanced('studentfeedback_elements'); - $mform->setType('studentfeedbackurl', PARAM_URL); - -// Show next quiz ? - $mform->addElement('selectyesno', 'shownextquiz', get_string('shownextquiz', 'hotpot')); - $mform->setDefault('shownextquiz', get_user_preferences('hotpot_shownextquiz', HOTPOT_NO)); - $mform->setHelpButton('shownextquiz', array('shownextquiz', get_string('shownextquiz', 'hotpot'), 'hotpot')); - // $mform->setAdvanced('forceplugins'); - -//----------------------------------------------------------------------------------------------- - $mform->addElement('header', 'accesscontrolhdr', get_string('accesscontrol', 'lesson')); -//----------------------------------------------------------------------------------------------- - -// Open time - $mform->addElement('date_time_selector', 'timeopen', get_string('quizopen', 'quiz'), array('optional'=>true)); - $mform->setHelpButton('timeopen', array('timeopen', get_string('quizopen', 'quiz'), 'quiz')); - -// Close time - $mform->addElement('date_time_selector', 'timeclose', get_string('quizclose', 'quiz'), array('optional'=>true)); - $mform->setHelpButton('timeclose', array('timeopen', get_string('quizclose', 'quiz'), 'quiz')); - -// Password - $mform->addElement('text', 'password', get_string('requirepassword', 'quiz')); - $mform->setType('password', PARAM_TEXT); - $mform->setHelpButton('password', array('requirepassword', get_string('requirepassword', 'quiz'), 'quiz')); - // $mform->setAdvanced('password'); - -// Subnet - $mform->addElement('text', 'subnet', get_string('requiresubnet', 'quiz')); - $mform->setType('subnet', PARAM_TEXT); - $mform->setHelpButton('subnet', array('requiresubnet', get_string('requiresubnet', 'quiz'), 'quiz')); - $mform->setDefault('subnet', get_user_preferences('hotpot_subnet')); - // $mform->setAdvanced('subnet'); - -// Allow review? - $mform->addElement('selectyesno', 'review', get_string('allowreview', 'quiz')); - $mform->setDefault('review', get_user_preferences('hotpot_review', HOTPOT_YES)); - $mform->setHelpButton('review', array('review', get_string('allowreview', 'quiz'), 'quiz')); - // $mform->setAdvanced('forceplugins'); - -// Maximum number of attempts - $options = array( - 0 => 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")); - } - $mform->addElement('select', 'attempts', get_string('attemptsallowed', 'quiz'), $options); - $mform->setDefault('attempts', get_user_preferences('hotpot_attempts', 0)); // 0=unlimited - $mform->setHelpButton('attempts', array('attempts', get_string('attemptsallowed', 'quiz'), 'quiz')); - // $mform->setAdvanced('forceplugins'); - -//----------------------------------------------------------------------------------------------- - $mform->addElement('header', 'gradeshdr', get_string('grades', 'grades')); -//----------------------------------------------------------------------------------------------- - -// Maximum grade - $options = array(); - for ($i=100; $i>=1; $i--) { - $options[$i] = $i; - } - $options[0] = get_string("nograde"); - $mform->addElement('select', 'grade', get_string('maximumgrade'), $options); - $mform->setDefault('grade', get_user_preferences('hotpot_grade', 100)); - $mform->setHelpButton('grade', array('maxgrade', get_string('maximumgrade'), 'quiz')); - // $mform->setAdvanced('forceplugins'); - -// Maximum grading method - $mform->addElement('select', 'grademethod', get_string('grademethod', 'quiz'), $HOTPOT_GRADEMETHOD); - $mform->setDefault('grademethod', get_user_preferences('hotpot_grademethod', HOTPOT_GRADEMETHOD_HIGHEST)); - $mform->setHelpButton('grademethod', array('grademethod', get_string('grademethod', 'quiz'), 'quiz')); - // $mform->setAdvanced('forceplugins'); - -//----------------------------------------------------------------------------------------------- - $mform->addElement('header', 'reportshdr', get_string('reports')); -//----------------------------------------------------------------------------------------------- - -// Enable click reporting? - $mform->addElement('selectyesno', 'clickreporting', get_string('clickreporting', 'hotpot')); - $mform->setDefault('clickreporting', get_user_preferences('hotpot_clickreporting', HOTPOT_NO)); - $mform->setHelpButton('clickreporting', array('clickreporting', get_string('clickreporting', 'hotpot'), 'hotpot')); - // $mform->setAdvanced('forceplugins'); - -//---------------------------------------------- - $features = new stdClass; - $features->groups = true; - $features->groupings = true; - $features->groupmembersonly = true; - $this->standard_coursemodule_elements($features); -//---------------------------------------------- - - $this->add_action_buttons(); - - $js = ''; - $mform->addElement('static', 'hotpot_mod_form_js', '', $js); - } - - function data_preprocessing(&$defaults){ - } - - function validation($data, $files) { - global $CFG, $USER, $DB, $COURSE; - - $errors = parent::validation($data, $files); - -// location - if (empty($data['location'])) { - // this shouldn't happen - $data['location'] = $COURSE->id; - } else { - if ($data['location']==$COURSE->id) { - // this is normal - } else if ($data['location']==SITEID && has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_SYSTEM))) { - // admin can access site files - } else { - // location is invalid or missing, so set to default - $data['location'] = $COURSE->id; - } - } - -// reference - if (isset($data['reference'])) { - $data['reference'] = trim($data['reference']); - } - if (empty($data['reference'])) { - $errors['reference_elements'] = get_string('error_nofilename', 'hotpot'); - } else { - if (preg_match('|^https?://|', $data['reference'])) { - // URL - $errors['reference_elements'] = 'Sorry, handling of URLs is not implemented yet'; - } else { - // course files - $filepath = $CFG->dataroot.'/'.$data['location'].'/'.$data['reference']; - if (! file_exists($filepath)) { - $errors['reference_elements'] = get_string('error_pathdoesnotexist', 'hotpot', $filepath); - } else if (! $data['quizchain'] && ! is_file($filepath)) { - $errors['reference_elements'] = get_string('error_folderwithoutquizchain', 'hotpot'); - } - } - } - -// studentfeedbackurl - if (empty($data['studentfeedbackurl']) || $data['studentfeedbackurl']=='http://') { - $data['studentfeedbackurl'] = ''; - $error = false; - if ($data['studentfeedback']==HOTPOT_FEEDBACK_WEBPAGE) { - $error = true; - } - if ($data['studentfeedback']==HOTPOT_FEEDBACK_FORMMAIL) { - $error = true; - } - if ($error) { - $errors['studentfeedback_elements']= get_string('error_nofeedbackurlformmail', 'hotpot'); - } - } - - return $errors; - } -} diff --git a/mod/hotpot/pix/icon.gif b/mod/hotpot/pix/icon.gif deleted file mode 100644 index 463c06585ca8f5a6c9c2a9b9f7ee9075282a051d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 415 zcmZ?wbh9u|6krfw_{zZW|IEyPhx$J5@BO~M=HZssa~qqluBC1wT1+y#yPY z84on5sij?>!WgoPkCWjDPp1{9!y+bz3I-X!%*-YYDXxyAhx{Z}q`ibB1;j=9Mfk-T zv>AoHR9Qtu1VpBZh{~!nXe!C8v9ZgEONuXBCMhSWA+N>2Z78>C<;qRUy8diz+cK28R;2n>YbJ3llBkH<&ZQoGBH-?U{_O;)?&-e73Aq;W?)m3exxe) h?DI1%zj^X1OkZ-@4CEiRWMnip$Tfset_url('/mod/hotpot/report.php', array('id'=>$id)); - if (! $cm = get_coursemodule_from_id('hotpot', $id)) { - print_error('invalidcoursemodule'); - } - if (! $course = $DB->get_record("course", array("id"=>$cm->course))) { - print_error('coursemisconf'); - } - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$cm->instance))) { - print_error('invalidhotpotid', 'hotpot'); - } - - } else { - $PAGE->set_url('/mod/hotpot/report.php', array('hp'=>$hp)); - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$hp))) { - print_error('invalidhotpotid', 'hotpot'); - } - if (! $course = $DB->get_record("course", array("id"=>$hotpot->course))) { - print_error('coursemisconf'); - } - if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { - print_error('invalidcoursemodule'); - } - } - - // get the roles context for this course - $sitecontext = get_context_instance(CONTEXT_SYSTEM); - $modulecontext = get_context_instance(CONTEXT_MODULE, $cm->id); - - // set homeurl of couse (for error messages) - $course_homeurl = "$CFG->wwwroot/course/view.php?id=$course->id"; - - require_login($course, true, $cm); - - // get report mode - if (has_capability('mod/hotpot:viewreport',$modulecontext)) { - $mode = optional_param('mode', 'overview', PARAM_ALPHA); - } else { - // ordinary students have no choice - $mode = 'overview'; - } - - // assemble array of form data - $formdata = array( - 'mode' => $mode, - 'reportusers' => has_capability('mod/hotpot:viewreport',$modulecontext) ? optional_param('reportusers', get_user_preferences('hotpot_reportusers', 'allusers'), PARAM_ALPHANUM) : 'this', - 'reportattempts' => optional_param('reportattempts', get_user_preferences('hotpot_reportattempts', 'all'), PARAM_ALPHA), - 'reportformat' => optional_param('reportformat', 'htm', PARAM_ALPHA), - 'reportshowlegend' => optional_param('reportshowlegend', get_user_preferences('hotpot_reportshowlegend', '0'), PARAM_INT), - 'reportencoding' => optional_param('reportencoding', get_user_preferences('hotpot_reportencoding', ''), PARAM_ALPHANUM), - 'reportwrapdata' => optional_param('reportwrapdata', get_user_preferences('hotpot_reportwrapdata', '1'), PARAM_INT), - ); - - 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 (has_capability('mod/hotpot:viewreport',$modulecontext)) { - hotpot_print_report_selector($course, $hotpot, $formdata); - } - } - - // delete selected attempts, if any - if (has_capability('mod/hotpot:deleteattempt',$modulecontext)) { - $del = optional_param('del', '', PARAM_ALPHA); - hotpot_delete_selected_attempts($hotpot, $del); - } - - // check for groups - if (preg_match('/^group(\d*)$/', $formdata['reportusers'], $matches)) { - $formdata['reportusers'] = 'group'; - $formdata['reportgroupid'] = 0; - // validate groupid - if ($groups = groups_get_all_groups($course->id)) { - if (isset($groups[$matches[1]])) { - $formdata['reportgroupid'] = $matches[1]; - } - } - } - - $user_ids = ''; - $users = array(); - - switch ($formdata['reportusers']) { - - case 'allusers': - // anyone who has ever attempted this hotpot - if ($records = $DB->get_records('hotpot_attempts', array('hotpot'=>$hotpot->id), '', 'id,userid')) { - foreach ($records as $record) { - $users[$record->userid] = 0; // "0" means user is NOT currently allowed to attempt this HotPot - } - unset($records); - } - break; - - case 'group': - // group members - if ($members = groups_get_members($formdata['reportgroupid'])) { - foreach ($members as $memberid=>$unused) { - $users[$memberid] = 1; // "1" signifies currently recognized participant - } - } - break; - - case 'allparticipants': - // anyone currently allowed to attempt this HotPot - if ($records = hotpot_get_users_by_capability($modulecontext, 'mod/hotpot:attempt')) { - foreach ($records as $record) { - $users[$record->id] = 1; // "1" means user is allowed to do this HotPot - } - unset($records); - } - break; - - case 'existingstudents': - // anyone currently allowed to attempt this HotPot who is not a teacher - $teachers = hotpot_get_users_by_capability($modulecontext, 'mod/hotpot:viewreport'); - if ($records = hotpot_get_users_by_capability($modulecontext, 'mod/hotpot:attempt')) { - foreach ($records as $record) { - if (empty($teachers[$record->id])) { - $users[$record->id] = 1; - } - } - unset($records); - } - 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) && count($users)) { - ksort($users); - $user_ids = join(',', array_keys($users)); - } - if (empty($user_ids)) { - echo $OUTPUT->heading(get_string('nousersyet')); - echo $OUTPUT->footer(); - exit; - } - - // database table and selection conditions - $table = "{hotpot_attempts} a"; - $select = "a.hotpot=:hotpotid AND a.userid IN ($user_ids)"; - if ($mode!='overview') { - $select .= ' AND a.status<>'.HOTPOT_STATUS_INPROGRESS; - } - $params = array('hotpotid'=>$hotpot->id); - - // 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, $params, $groupby); - - $select = ''; - $params = array(); - if ($records) { - $ids = array(); - foreach ($records as $record) { - $ids[] = $record->clickreportid; - } - if (count($ids)) { - $select = "a.clickreportid IN (".join(',', $ids).")"; - } - } - } - - // pick out last attempt in each clickreport series - if ($select) { - $cr_attempts = hotpot_get_records_groupby('MAX', array('timefinish', 'id'), $table, $select, $params, 'clickreportid'); - } else { - $cr_attempts = array(); - } - - $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).")"; - } - $params = array(); - } - - $attempts = array(); - - if ($select) { - // add user information to SQL query - $select .= ' AND a.userid = u.id'; - $table .= ", {user} u"; - $order = "u.lastname, a.attempt, a.timefinish"; - // get the attempts (at last!) - $attempts = $DB->get_records_sql("SELECT $fields FROM $table WHERE $select ORDER BY $order", $params); - } - - // stop now if no attempts were found - if (empty($attempts)) { - echo $OUTPUT->heading(get_string('noattemptstoshow','quiz')); - echo $OUTPUT->footer(); - exit; - } - - // get the questions - if (!$questions = $DB->get_records('hotpot_questions', array('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') { - // shortcut to clickreportid (=the id of the FIRST attempt in this clickreport series) - $clickreportid = $attempt->clickreportid; - if (isset($cr_attempts[$clickreportid])) { - // store id and finish time of LAST attempt in this clickreport series - $attempts[$id]->cr_lastclick = $cr_attempts[$clickreportid]->id; - $attempts[$id]->cr_timefinish = $cr_attempts[$clickreportid]->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 = $DB->get_records_sql("SELECT * FROM {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 - - if (! is_readable("report/$mode/report.php")) { - print_error('unknownreport', 'hotpot', $course_homeurl, clean_text($mode)); - } - - include("report/default.php"); // Parent class - include("report/$mode/report.php"); - - $report = new hotpot_report(); - - if (! $report->display($hotpot, $cm, $course, $users, $attempts, $questions, $formdata)) { - print_error('error_processreport', 'hotpot', $course_homeurl); - } - - if ($formdata['reportformat']=='htm') { - echo $OUTPUT->footer(); - } - -////////////////////////////////////////////// -/// 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)"; -} -function hotpot_delete_selected_attempts(&$hotpot, $del) { - global $DB; - - $select = ''; - $params = array('hotpotid'=>$hotpot->id); - switch ($del) { - case 'all' : - $select = "hotpot=:hotpotid"; - break; - case 'abandoned': - $select = "hotpot=:hotpotid AND status=".HOTPOT_STATUS_ABANDONED; - break; - case 'selection': - $ids = array(); - $data = (array)data_submitted(); - foreach ($data as $name => $value) { - if (preg_match('/^box\d+$/', $name)) { - $ids[] = intval($value); - } - } - if (count($ids)) { - list($ids, $idparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED, 'crid0'); - $params = array_merge($params, $idparams); - $select = "hotpot=:hotpotid AND clickreportid $ids"; - } - break; - } - - // delete attempts using $select, if it is set - if ($select) { - - $table = 'hotpot_attempts'; - if ($attempts = $DB->get_records_select($table, $select, $params)) { - - hotpot_delete_and_notify($table, $select, $params, get_string('attempts', 'quiz')); - - $select = 'attempt IN ('.implode(',', array_keys($attempts)).')'; - $params = array(); - hotpot_delete_and_notify('hotpot_details', $select, $params, get_string('rawdetails', 'hotpot')); - hotpot_delete_and_notify('hotpot_responses', $select, $params, get_string('answer', 'quiz')); - - // update grades for all users for this hotpot - hotpot_update_grades($hotpot); - } - } - -} - -////////////////////////////////////////////// -/// functions to print the report headings and -/// report selector menus - -function hotpot_print_report_heading(&$course, &$cm, &$hotpot, &$mode) { - global $OUTPUT; - $strmodulenameplural = get_string("modulenameplural", "hotpot"); - $strmodulename = get_string("modulename", "hotpot"); - - $modulecontext = get_context_instance(CONTEXT_MODULE, $cm->id); - if (has_capability('mod/hotpot:viewreport',$modulecontext)) { - if ($mode=='overview' || $mode=='simplestat' || $mode=='fullstat') { - $module = "quiz"; - } else { - $module = "hotpot"; - } - - $PAGE->navbar->add(get_string("report$mode", $module)); - } else { - $PAGE->navbar->add(get_string("report", "quiz")); - } - - $PAGE->set_title(format_string($course->shortname) . ": $hotpot->name"); - $PAGE->set_heading($course->fullname); - echo $OUTPUT->header(); - - $course_context = get_context_instance(CONTEXT_COURSE, $course->id); - if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) { - echo ''; - } - echo $OUTPUT->heading($hotpot->name); -} -function hotpot_print_report_selector(&$course, &$hotpot, &$formdata) { - global $CFG, $DB, $OUTPUT; - - $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); - } - } - - $menus['reportusers'] = array( - 'allusers' => get_string('allusers', 'hotpot'), - 'allparticipants' => get_string('allparticipants') - ); - - // groups - if ($groups = groups_get_all_groups($course->id)) { - foreach ($groups as $gid => $group) { - $menus['reportusers']["group$gid"] = get_string('group').': '.format_string($group->name); - } - } - - // get users who have ever atetmpted this HotPot - $users = $DB->get_records_sql(" - SELECT - u.id, u.firstname, u.lastname - FROM - {user} u, - {hotpot_attempts} ha - WHERE - u.id = ha.userid AND ha.hotpot=? - ORDER BY - u.lastname - ", array($hotpot->id)); - - if (!empty($users)) { - // get context - $cm = get_coursemodule_from_instance('hotpot', $hotpot->id); - $modulecontext = get_context_instance(CONTEXT_MODULE, $cm->id); - - $teachers = hotpot_get_users_by_capability($modulecontext, 'mod/hotpot:viewreport'); - $students = hotpot_get_users_by_capability($modulecontext, 'mod/hotpot:attempt'); - - // current students - if (!empty($students)) { - $firsttime = true; - foreach ($users as $user) { - if (array_key_exists($user->id, $teachers)) { - continue; // skip teachers - } - if (array_key_exists($user->id, $students)) { - if ($firsttime) { - $firsttime = false; // so we only do this once - $menus['reportusers']['existingstudents'] = get_string('existingstudents'); - $menus['reportusers'][] = '------'; - } - $menus['reportusers']["$user->id"] = fullname($user); - unset($users[$user->id]); - } - } - unset($students); - } - // others (former students, teachers, admins, course creators) - $firsttime = true; - foreach ($users as $user) { - if ($firsttime) { - $firsttime = false; // so we only do this once - $menus['reportusers'][] = '======'; - } - $menus['reportusers']["$user->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 '
'; - echo $OUTPUT->old_help_icon('reportcontent', get_string('reportcontent', 'hotpot'), 'hotpot'); - print ''.get_string('reportcontent', 'hotpot').':'; - foreach ($menus as $name => $options) { - $value = $formdata[$name]; - print html_writer::select($options, $name, $value, false); - }; - print '
'; - echo $OUTPUT->old_help_icon('reportformat', get_string('reportformat', 'hotpot'), 'hotpot'); - print ''.get_string($name, 'hotpot').':'.html_writer::select($options, $name, $value, false).'
'; - - print '
'; - print ''."\n"; -} -function hotpot_get_report_names($names='') { - // $names : optional list showing required order reports names - - $reports = array(); - - // 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]); - } - } - - // append remaining plugins - $reports = array_merge($reports, $plugins); - - return $reports; -} - -function hotpot_get_records_groupby($function, $fieldnames, $table, $select, $params, $groupby) { - // $function is an SQL aggregate function (MAX or MIN) - global $DB; - - $fields = $DB->sql_concat_join("'_'", $fieldnames); - $fields = "$groupby, $function($fields) AS joinedvalues"; - - if ($fields) { - $records = $DB->get_records_sql("SELECT $fields FROM $table WHERE $select GROUP BY $groupby", $params); - } - - if (empty($fields) || empty($records)) { - $records = array(); - } - - $fieldcount = count($fieldnames); - - foreach ($records as $id=>$record) { - if (empty($record->joinedvalues)) { - unset($records[$id]); - } else { - $values = explode('_', $record->joinedvalues); - - for ($i=0; $i<$fieldcount; $i++) { - $fieldname = $fieldnames[$i]; - $records[$id]->$fieldname = $values[$i]; - } - } - unset($record->joinedvalues); - } - - return $records; -} -function hotpot_get_users_by_capability(&$modulecontext, $capability) { - static $users = array(); - if (! array_key_exists($capability, $users)) { - $users[$capability] = get_users_by_capability($modulecontext, $capability, 'u.id,u.id', 'u.id'); - } - return $users[$capability]; -} - diff --git a/mod/hotpot/report/click/report.php b/mod/hotpot/report/click/report.php deleted file mode 100644 index 33e13202b89..00000000000 --- a/mod/hotpot/report/click/report.php +++ /dev/null @@ -1,542 +0,0 @@ -create_clickreport_table($hotpot, $cm, $course, $users, $attempts, $questions, $options, $tables); - // print the tables - $this->print_report($course, $hotpot, $tables, $options); - return true; - } - function create_clickreport_table(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { - global $CFG; - $is_html = ($options['reportformat']=='htm'); - // time and date format strings // date format strings - $strftimetime = '%H:%M:%S'; - $strftimedate = get_string('strftimedate'); - // get the current time and max execution time - $start_report_time = microtime(); - $max_execution_time = ini_get('max_execution_time'); - $correct = get_string('reportcorrectsymbol', 'hotpot'); - $wrong = get_string('reportwrongsymbol', 'hotpot'); - $nottried = get_string('reportnottriedsymbol', 'hotpot'); - // shortcuts for font tags - $blank = $is_html ? ' ' : ""; - // store question count - $questioncount = count($questions); - // array to map columns onto question ids ($col => $id) - $questionids = array_keys($questions); - // store exercise type - $exercisetype = $this->get_exercisetype($questions, $questionids, $blank); - // initialize details ('events' must go last) - $details = array('checks', 'status', 'answers', 'changes', 'hints', 'clues', 'events'); - // initialize $table - unset($table); - $table->border = 1; - $table->width = '100%'; - // initialize legend, if necessary - if (!empty($options['reportshowlegend'])) { - $table->legend = array(); - } - // start $table headings - $this->set_head($options, $table, 'exercise'); - $this->set_head($options, $table, 'user'); - $this->set_head($options, $table, 'attempt'); - $this->set_head($options, $table, 'click'); - // store clicktype column number - $clicktype_col = count($table->head)-1; - // finish $table headings - $this->set_head($options, $table, 'details', $exercisetype, $details, $questioncount); - $this->set_head($options, $table, 'totals', $exercisetype); - // set align and wrap - $this->set_align_and_wrap($table); - // is link to review allowed? - $allow_review = ($is_html && (has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review)); - // initialize array of data values - $this->data = array(); - // set exercise data values - $this->set_data_exercise($cm, $course, $hotpot, $questions, $questionids, $questioncount, $blank); - // add details of users' responses - foreach ($users as $user) { - $this->set_data_user($options, $course, $user); - unset($clickreportid); - foreach ($user->attempts as $attempt) { - // initialize totals for - $click = array( - 'qnumber' => array(), - 'correct' => array(), - 'wrong' => array(), - 'answers' => array(), - 'hints' => array(), - 'clues' => array(), - 'changes' => array(), - 'checks' => array(), - 'events' => array(), - 'score' => array(), - 'weighting' => array() - ); - $clicktypes = array(); - // is the start of a new attempt? - // (clicks in the same attempt have the same clickreportid) - if (!isset($clickreportid) || $clickreportid != $attempt->clickreportid) { - $clickcount = 1; - $clickreportid = $attempt->clickreportid; - // initialize totals for all clicks in this attempt - $clicks = $click; // $click has just been initialized - $this->set_data_attempt($attempt, $strftimedate, $strftimetime, $blank); - } - $cells = array(); - $this->set_data($cells, 'exercise'); - $this->set_data($cells, 'user'); - $this->set_data($cells, 'attempt'); - // get responses to questions in this attempt - foreach ($attempt->responses as $response) { - // set $q(uestion number) - $q = array_search($response->question, $questionids); - $click['qnumber'][$q] = true; - // was this question answered correctly? - if ($answer = hotpot_strings($response->correct)) { - // mark the question as correctly answered - if (empty($clicks['correct'][$q])) { - $click['correct'][$q] = true; - $clicks['correct'][$q] = true; - } - // unset 'wrong' flags, if necessary - if (isset($click['wrong'][$q])) { - unset($click['wrong'][$q]); - } - if (isset($clicks['wrong'][$q])) { - unset($clicks['wrong'][$q]); - } - // otherwise, was the question answered wrongly? - } else if ($answer = hotpot_strings($response->wrong)) { - // mark the question as wrongly answered - $click['wrong'][$q] = true; - $clicks['wrong'][$q] = true; - } else { // not correct or wrong (curious?!) - unset($answer); - } - if (!empty($click['correct'][$q]) || !empty($click['wrong'][$q])) { - $click['score'][$q] = $response->score; - $clicks['score'][$q] = $response->score; - $weighting = isset($response->weighting) ? $response->weighting : 100; - $click['weighting'][$q] = $weighting; - $clicks['weighting'][$q] =$weighting; - } - foreach($details as $detail) { - switch ($detail) { - case 'answers': - if (isset($answer) && is_string($answer) && !empty($answer)) { - $click[$detail][$q] = $answer; - } - break; - case 'hints': - case 'clues': - case 'checks': - if (isset($response->$detail) && is_numeric($response->$detail) && $response->$detail>0) { - if (!isset($click[$detail][$q]) || $click[$detail][$q] < $response->$detail) { - $click[$detail][$q] = $response->$detail; - } - } - break; - } - } // end foreach $detail - } // end foreach $response - $click['types'] = array(); - $this->data['details'] = array(); - foreach($details as $detail) { - for ($q=0; $q<$questioncount; $q++) { - switch ($detail) { - case 'status': - if (isset($clicks['correct'][$q])) { - $this->data['details'][] = $correct; - } else if (isset($clicks['wrong'][$q])) { - $this->data['details'][] = $wrong; - } else if (isset($click['qnumber'][$q])) { - $this->data['details'][] = $nottried; - } else { // this question did not appear in this attempt - $this->data['details'][] = $blank; - } - break; - case 'answers': - case 'hints': - case 'clues': - case 'checks': - if (!isset($clicks[$detail][$q])) { - if (!isset($click[$detail][$q])) { - $this->data['details'][] = $blank; - } else { - $clicks[$detail][$q] = $click[$detail][$q]; - if ($detail=='answers') { - $this->set_legend($table, $q, $click[$detail][$q], $questions[$questionids[$q]]); - } - $this->data['details'][] = $click[$detail][$q]; - $this->update_event_count($click, $detail, $q); - } - } else { - if (!isset($click[$detail][$q])) { - $this->data['details'][] = $blank; - } else { - $difference = ''; - if ($detail=='answers') { - if ($click[$detail][$q] != $clicks[$detail][$q]) { - $pattern = '/^'.preg_quote($clicks[$detail][$q], '/').',/'; - $difference = preg_replace($pattern, '', $click[$detail][$q], 1); - } - } else { // hints, clues, checks - if ($click[$detail][$q] > $clicks[$detail][$q]) { - $difference = $click[$detail][$q] - $clicks[$detail][$q]; - } - } - if ($difference) { - $clicks[$detail][$q] = $click[$detail][$q]; - $click[$detail][$q] = $difference; - if ($detail=='answers') { - $this->set_legend($table, $q, $difference, $questions[$questionids[$q]]); - } - $this->data['details'][] = $difference; - $this->update_event_count($click, $detail, $q); - } else { - unset($click[$detail][$q]); - $this->data['details'][] = $blank; - } - } - } - break; - case 'changes': - case 'events': - if (empty($click[$detail][$q])) { - $this->data['details'][] = $blank; - } else { - $this->data['details'][] = $click[$detail][$q]; - } - break; - default: - // do nothing - break; - } // end switch - } // for $q - } // foreach $detail - // set data cell values for - $this->set_data_click( - $allow_review ? ''.$clickcount.'' : $clickcount, - trim(userdate($attempt->timefinish, $strftimetime)), - $exercisetype, - $click - ); - $this->set_data($cells, 'click'); - $this->set_data($cells, 'details'); - $this->set_data_totals($click, $clicks, $questioncount, $blank, $attempt); - $this->set_data($cells, 'totals'); - $table->data[] = $cells; - $clickcount++; - } // end foreach $attempt - // insert 'tabledivider' between users - $table->data[] = 'hr'; - } // end foreach $user - // remove final 'hr' from data rows - array_pop($table->data); - if ($is_html && $CFG->hotpot_showtimes) { - $count = count($users); - $duration = sprintf("%0.3f", microtime_diff($start_report_time, microtime())); - print "$count users processed in $duration seconds (".sprintf("%0.3f", $duration/$count).' secs/user)
'."\n"; - } - $tables[] = &$table; - $this->create_legend_table($tables, $table); - } // end function - function get_exercisetype(&$questions, &$questionids, &$blank) { - if (empty($questions)) { - $type = $blank; - } else { - switch ($questions[$questionids[0]]->type) { - case HOTPOT_JCB: - $type = "JCB"; - break; - case HOTPOT_JCLOZE : - $type = "JCloze"; - break; - case HOTPOT_JCROSS : - $type = "JCross"; - break; - case HOTPOT_JMATCH : - $type = "JMatch"; - break; - case HOTPOT_JMIX : - $type = "JMix"; - break; - case HOTPOT_JQUIZ : - $type = "JQuiz"; - break; - case HOTPOT_TEXTOYS_RHUBARB : - $type = "Rhubarb"; - break; - case HOTPOT_TEXTOYS_SEQUITUR : - $type = "Sequitur"; - break; - default: - $type = $blank; - } - } - return $type; - } - function set_head(&$options, &$table, $zone, $exercisetype='', $details=array(), $questioncount=0) { - if (empty($table->head)) { - $table->head = array(); - } - switch ($zone) { - case 'exercise': - array_push($table->head, - get_string('reportcoursename', 'hotpot'), - get_string('reportsectionnumber', 'hotpot'), - get_string('reportexercisenumber', 'hotpot'), - get_string('reportexercisename', 'hotpot'), - get_string('reportexercisetype', 'hotpot'), - get_string('reportnumberofquestions', 'hotpot') - ); - break; - case 'user': - array_push($table->head, - get_string('reportstudentid', 'hotpot'), - get_string('reportlogindate', 'hotpot'), - get_string('reportlogintime', 'hotpot'), - get_string('reportlogofftime', 'hotpot') - ); - break; - case 'attempt': - array_push($table->head, - get_string('reportattemptnumber', 'hotpot'), - get_string('reportattemptstart', 'hotpot'), - get_string('reportattemptfinish', 'hotpot') - ); - break; - case 'click': - array_push($table->head, - get_string('reportclicknumber', 'hotpot'), - get_string('reportclicktime', 'hotpot'), - get_string('reportclicktype', 'hotpot') - ); - break; - case 'details': - foreach($details as $detail) { - if ($exercisetype=='JQuiz' && $detail=='clues') { - $detail = 'showanswer'; - } - $detail = get_string("report$detail", 'hotpot'); - for ($i=0; $i<$questioncount; $i++) { - $str = get_string('questionshort', 'hotpot', $i+1); - if ($i==0 || $options['reportformat']!='htm') { - $str = "$detail $str"; - } - $table->head[] = $str; - } - } - break; - case 'totals': - $reportpercentscore =get_string('reportpercentscore', 'hotpot'); - if (!function_exists('clean_getstring_data')) { // Moodle 1.4 (and less) - $reportpercentscore = str_replace('%', '%%', $reportpercentscore); - } - array_push($table->head, - get_string('reportthisclick', 'hotpot', get_string('reportquestionstried', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reportquestionstried', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportright', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportwrong', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportnottried', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reportright', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reportwrong', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reportnottried', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportanswers', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reporthints', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string($exercisetype=='JQuiz' ? 'reportshowanswer' : 'reportclues', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportevents', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reporthints', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string($exercisetype=='JQuiz' ? 'reportshowanswer' : 'reportclues', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportrawscore', 'hotpot')), - get_string('reportthisclick', 'hotpot', get_string('reportmaxscore', 'hotpot')), - get_string('reportthisclick', 'hotpot', $reportpercentscore), - get_string('reportsofar', 'hotpot', get_string('reportrawscore', 'hotpot')), - get_string('reportsofar', 'hotpot', get_string('reportmaxscore', 'hotpot')), - get_string('reportsofar', 'hotpot', $reportpercentscore), - get_string('reporthotpotscore', 'hotpot') - ); - break; - } // end switch - } - function set_align_and_wrap(&$table) { - $count = count($table->head); - for ($i=0; $i<$count; $i++) { - if ($i==0 || $i==1 || $i==2 || $i==4 || $i==5 || $i>=7) { - // numeric (and short text) columns - $table->align[] = 'center'; - $table->wrap[] = ''; - } else { - // text columns - $table->align[] = 'left'; - $table->wrap[] = 'nowrap'; - } - } - } - function set_data_exercise(&$cm, &$course, &$hotpot, &$questions, &$questionids, &$questioncount, &$blank) { - global $DB; - - // get exercise details (course name, section number, activity number, quiztype and question count) - $record = $DB->get_record("course_sections", array("id"=>$cm->section)); - $this->data['exercise'] = array( - 'course' => $course->shortname, - 'section' => empty($record) ? $blank : $record->section+1, - 'number' => empty($record) ? $blank : array_search($cm->id, explode(',', $record->sequence))+1, - 'name' => $hotpot->name, - 'type' => $this->get_exercisetype($questions, $questionids, $blank), - 'questioncount' => $questioncount - ); - } - function set_data_user(&$options, &$course, &$user) { - global $CFG; - // shortcut to first attempt record (which also hold user info) - $attempt = &$user->attempts[0]; - $idnumber = $attempt->idnumber; - if (empty($idnumber)) { - $idnumber = fullname($attempt); - } - if ($options['reportformat']=='htm') { - $idnumber = ''.$idnumber.''; - } - $this->data['user'] = array( - 'idnumber' => $idnumber, - ); - } - function set_data_attempt(&$attempt, &$strftimedate, &$strftimetime, &$blank) { - global $CFG, $DB; - $records = $DB->get_records_sql_menu(" - SELECT userid, MAX(time) AS logintime - FROM {log} - WHERE userid=? AND action='login' AND timeuserid, $attempt->timestart)); - if (empty($records)) { - $logindate = $blank; - $logintime = $blank; - } else { - $logintime = $records[$attempt->userid]; - $logindate = trim(userdate($logintime, $strftimedate)); - $logintime = trim(userdate($logintime, $strftimetime)); - } - $records = $DB->get_records_sql_menu(" - SELECT userid, MIN(time) AS logouttime - FROM {log} - WHERE userid=? AND action='logout' AND time>? - GROUP BY userid - ", array($attempt->userid, $attempt->cr_timefinish)); - if (empty($records)) { - $logouttime = $blank; - } else { - $logouttime = $records[$attempt->userid]; - $logouttime = trim(userdate($logouttime, $strftimetime)); - } - $this->data['attempt'] = array( - 'logindate' => $logindate, - 'logintime' => $logintime, - 'logouttime' => $logouttime, - 'number' => $attempt->attempt, - 'start' => trim(userdate($attempt->timestart, $strftimetime)), - 'finish' => trim(userdate($attempt->cr_timefinish, $strftimetime)), - ); - } - function set_data_click($number, $time, $exercisetype, $click) { - $types = array(); - foreach (array_keys($click['types']) as $type) { - if ($exercisetype=='JQuiz' && $type=='clues') { - $type = 'showanswer'; - } else { - // remove final 's' - $type = substr($type, 0, strlen($type)-1); - } - // $types[] = get_string($type, 'hotpot'); - $types[] = $type; - } - $this->data['click'] = array( - 'number' => $number, - 'time' => $time, - 'type' => empty($types) ? '??' : implode(',', $types) - ); - } - function set_data_totals(&$click, &$clicks, &$questioncount, &$blank, &$attempt) { - $count= array( - 'click' => array( - 'correct' => count($click['correct']), - 'wrong' => count($click['wrong']), - 'answers' => count($click['answers']), - 'hints' => array_sum($click['hints']), - 'clues' => array_sum($click['clues']), - 'events' => array_sum($click['events']), - 'score' => array_sum($click['score']), - 'maxscore' => array_sum($click['weighting']), - ), - 'clicks' => array( - 'correct' => count($clicks['correct']), - 'wrong' => count($clicks['wrong']), - 'answers' => count($clicks['answers']), - 'hints' => array_sum($clicks['hints']), - 'clues' => array_sum($clicks['clues']), - 'score' => array_sum($clicks['score']), - 'maxscore' => array_sum($clicks['weighting']), - ) - ); - foreach ($count as $period=>$values) { - $count[$period]['nottried'] = $questioncount - ($values['correct'] + $values['wrong']); - $count[$period]['percent'] = empty($values['maxscore']) ? $blank : round(100 * $values['score'] / $values['maxscore'], 0); - // blank out zero click values - if ($period=='click') { - foreach ($values as $detail=>$value) { - if ($detail=='answers' || $detail=='hints' || $detail=='clues' || $detail=='events') { - if (empty($value)) { - $count[$period][$detail] = $blank; - } - } - } - } - } - $this->data['totals'] = array( - $count['click']['answers'], // "q's tried" - $count['clicks']['answers'], // "q's tried so far" - $count['click']['correct'], // "right" - $count['click']['wrong'], // "wrong" - $count['click']['nottried'], // "not tried" - $count['clicks']['correct'], // "right so far" - $count['clicks']['wrong'], // "wrong so far" - $count['clicks']['nottried'], // "not tried so far" - $count['click']['answers'], // "answers", - $count['click']['hints'], // "hints", - $count['click']['clues'], // "clues", - $count['click']['events'], // "answers", - $count['clicks']['hints'], // "hints so far", - $count['clicks']['clues'], // "clues so far", - $count['click']['score'], // 'raw score', - $count['click']['maxscore'], // 'max score', - $count['click']['percent'], // '% score' - $count['clicks']['score'], // 'raw score, - $count['clicks']['maxscore'], // 'max score, - $count['clicks']['percent'], // '% score - $attempt->score // 'hotpot score' - ); - } - function update_event_count(&$click, $detail, $q) { - if ($detail=='checks' || $detail=='hints' || $detail=='clues') { - $click['types'][$detail] = true; - } - if ($detail=='answers' || $detail=='hints' || $detail=='clues') { - $click['events'][$q] = isset($click['events'][$q]) ? $click['events'][$q]+1 : 1; - } - if ($detail=='answers') { - $click['changes'][$q] = isset($click['changes'][$q]) ? $click['changes'][$q]+1 : 1; - } - } - function set_data(&$cells, $zone) { - foreach ($this->data[$zone] as $name=>$value) { - $cells[] = $value; - } - } -} // end class - diff --git a/mod/hotpot/report/default.php b/mod/hotpot/report/default.php deleted file mode 100644 index 37f1a97351a..00000000000 --- a/mod/hotpot/report/default.php +++ /dev/null @@ -1,851 +0,0 @@ -id" or q=$quiz->id", and "mode=reportname". -//////////////////////////////////////////////////////////////////// - -// Included by ../report.php - -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 - ksort($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 -///////////////////////////////////////////////// - -// 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 - - -////////////////////////////////////////// -/// 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; - } - } - -////////////////////////////////////////// -/// print an html report - - function print_html_report(&$tables) { - global $OUTPUT; - $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) { - echo $OUTPUT->spacer(array('height'=>30, 'width'=>10, 'br'=>true)); // should be done with CSS instead - } - } - } - function print_html_start(&$table) { - global $OUTPUT; - // 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].'"'; - $class = ' class="'.(empty($table->class[$i]) ? $d : $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"; - } - - echo $OUTPUT->box_start("generalbox boxalign$table->tablealign"); - 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) { - global $OUTPUT; - 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.(empty($table->fontsize[$col]) ? '' : '')."
\n"; - echo $OUTPUT->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; - } - -////////////////////////////////////////// -/// 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("-"); - $wsnamelimit = 0; // no limit - } else { - // Moodle <= 1.5 - require_once("$CFG->libdir/excel/Worksheet.php"); - require_once("$CFG->libdir/excel/Workbook.php"); - $wb = new Workbook("-"); - $wsnamelimit = 31; // max length in chars - } - - // send HTTP headers - $this->print_excel_headers($wb, $course, $hotpot); - - // create one worksheet for each table - foreach($tables as $table) { - unset($ws); - if (empty($table->caption)) { - $wsname = ''; - } else { - $wsname = strip_tags($table->caption); - if ($wsnamelimit && strlen($wsname) > $wsnamelimit) { - $wsname = substr($wsname, -$wsnamelimit); // end of string - // $wsname = substr($wsname, 0, $wsnamelimit); // start of string - } - } - $ws = &$wb->add_worksheet($wsname); - - $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 = 'UTF-8'; - } - 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/report/fullstat/report.php b/mod/hotpot/report/fullstat/report.php deleted file mode 100644 index f289bde7190..00000000000 --- a/mod/hotpot/report/fullstat/report.php +++ /dev/null @@ -1,449 +0,0 @@ -create_responses_table($hotpot, $course, $users, $attempts, $questions, $options, $tables); - $this->create_analysis_table($users, $attempts, $questions, $options, $tables); - // print report - $this->print_report($course, $hotpot, $tables, $options); - return true; - } - function create_responses_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { - global $CFG, $OUTPUT; - $is_html = ($options['reportformat']=='htm'); - // shortcuts for font tags - $br = $is_html ? "
\n" : "\n"; - $blank = $is_html ? ' ' : ""; - $font_end = $is_html ? '
' : ''; - $font_red = $is_html ? '' : ''; - $font_blue = $is_html ? '' : ''; - $font_brown = $is_html ? '' : ''; - $font_green = $is_html ? '' : ''; - $font_small = $is_html ? '' : ''; - $nobr_start = $is_html ? '' : ''; - $nobr_end = $is_html ? '' : ''; - // is review allowed? (do this once here, to save time later) - $allow_review = ($is_html && (has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review)); - // assume penalties column is NOT required - $show_penalties = false; - // initialize $table - unset($table); - $table->border = 1; - $table->width = '100%'; - // initialize legend, if necessary - if (!empty($options['reportshowlegend'])) { - $table->legend = array(); - } - // headings for name, attempt number, score/grade and penalties - $table->head = array( - get_string("name"), - hotpot_grade_heading($hotpot, $options), - get_string('attempt', 'quiz'), - ); - $table->align = array('left', 'center', 'center'); - $table->size = array(150, 80, 10); - $table->wrap = array(0, 0, 0); - $table->fontsize = array(0, 0, 0); - // question headings - $this->add_question_headings($questions, $table, 'left', 0, false, 2); - // penalties (not always needed) and raw score - array_push($table->head, - get_string('penalties', 'hotpot'), - get_string('score', 'quiz') - ); - array_push($table->align, 'center', 'center'); - array_push($table->size, 50, 50); - array_push($table->wrap, 0, 0); - array_push($table->fontsize, 0, 0); - // message strings - $strnoresponse = get_string('noresponse', 'quiz'); - // array to map columns onto question ids ($col => $id) - $questionids = array_keys($questions); - // add details of users' responses - foreach ($users as $user) { - // shortcut to user info held in first attempt record - $u = &$user->attempts[0]; - if (function_exists("fullname")) { - $name = fullname($u); - } else { - $name = "$u->firstname $u->lastname"; - } - if ($is_html) { - $name = ''.$name.''; - } - $grade = isset($user->grade) ? $user->grade : $blank; - foreach ($user->attempts as $attempt) { - $attemptnumber = $attempt->attempt; - if ($allow_review) { - $attemptnumber = ' '.$attemptnumber.''; - } - $cells = array ($name, $grade, $attemptnumber); - // $name and $grade are only printed on first line per user - $name = $blank; - $grade = $blank; - $start_col = count($cells); - foreach ($questionids as $col => $id) { - $cells[$start_col + $col] = "$font_brown($strnoresponse)$font_end"; - } - if (isset($attempt->penalties)) { - $show_penalties = true; - $penalties = $attempt->penalties; - } else { - $penalties = $blank; - } - array_push($cells, $penalties, hotpot_format_score($attempt)); - // get responses to questions in this attempt - foreach ($attempt->responses as $response) { - // check this question id is OK (should be) - $col = array_search($response->question, $questionids); - if (is_numeric($col)) { - // correct - if ($value = hotpot_strings($response->correct)) { - $this->set_legend($table, $col, $value, $questions[$response->question]); - } else { - $value = "($strnoresponse)"; - } - $cell = $font_red.$value.$font_end; - // wrong - if ($value = hotpot_strings($response->wrong)) { - if (isset($table->legend)) { - $values = array(); - foreach (explode(',', $value) as $v) { - $this->set_legend($table, $col, $v, $questions[$response->question]); - $values[] = $v; - } - $value = implode(',', $values); - } - $cell .= $br.$font_blue.$value.$font_end; - } - // ignored - if ($value = hotpot_strings($response->ignored)) { - if (isset($table->legend)) { - $values = array(); - foreach (explode(',', $value) as $v) { - $this->set_legend($table, $col, $v, $questions[$response->question]); - $values[] = $v; - } - $value = implode(',', $values); - } - $cell .= $br.$font_brown.$value.$font_end; - } - // numeric - if (is_numeric($response->score)) { - if (empty($table->caption)) { - $table->caption = get_string('indivresp', 'quiz'); - if ($is_html) { - $table->caption .= $OUTPUT->old_help_icon('responsestable', $table->caption, 'hotpot'); - } - } - $hints = empty($response->hints) ? 0 : $response->hints; - $clues = empty($response->clues) ? 0 : $response->clues; - $checks = empty($response->checks) ? 0 : $response->checks; - $numeric = $response->score.'% '.$blank.' ('.$hints.','.$clues.','.$checks.')'; - $cell .= $br.$nobr_start.$font_green.$numeric.$font_end.$nobr_end; - } - $cells[$start_col + $col] = $cell; - } - } - $table->data[] = $cells; - } - // insert 'tabledivider' between users - $table->data[] = 'hr'; - } // end foreach $users - // remove final 'hr' from data rows - array_pop($table->data); - if (!$show_penalties) { - $col = 3 + count($questionids); - $this->remove_column($table, $col); - } - $tables[] = &$table; - } - function create_analysis_table(&$users, &$attempts, &$questions, &$options, &$tables) { - global $OUTPUT; - $is_html = ($options['reportformat']=='htm'); - // the fields we are interested in, in the order we want them - $fields = array('correct', 'wrong', 'ignored', 'hints', 'clues', 'checks', 'weighting'); - $string_fields = array('correct', 'wrong', 'ignored'); - $q = array(); // statistics about the $q(uestions) - $f = array(); // statistics about the $f(ields) - //////////////////////////////////////////// - // compile the statistics about the questions - //////////////////////////////////////////// - foreach ($questions as $id=>$question) { - // extract scores for attempts at this question - $scores = array(); - foreach ($question->attempts as $attempt) { - $scores[] = $attempt->score; - } - // sort scores values (in ascending order) - asort($scores); - // get the borderline high and low scores - $count = count($scores); - switch ($count) { - case 0: - $lo_score = 0; - $hi_score = 0; - break; - case 1: - $lo_score = 0; - $hi_score = $scores[0]; - break; - default: - $lo_score = $scores[round($count*1/3)]; - $hi_score = $scores[round($count*2/3)]; - break; - } - // get statistics for each attempt which includes this question - foreach ($question->attempts as $attempt) { - $is_hi_score = ($attempt->score >= $hi_score); - $is_lo_score = ($attempt->score < $lo_score); - // reference to the response to the current question - $response = &$attempt->responses[$id]; - // update statistics for fields in this response - foreach($fields as $field) { - if (!isset($q[$id])) { - $q[$id] = array(); - } - if (!isset($f[$field])) { - $f[$field] = array('count' => 0); - } - if (!isset($q[$id][$field])) { - $q[$id][$field] = array('count' => 0); - } - $values = explode(',', $response->$field); - $values = array_unique($values); - foreach($values as $value) { - // $value should be an integer (string_id or count) - if (is_numeric($value)) { - $f[$field]['count']++; - if (!isset($q[$id][$field][$value])) { - $q[$id][$field][$value] = 0; - } - $q[$id][$field]['count']++; - $q[$id][$field][$value]++; - } - } - } // end foreach $field - // initialize counters for this question, if necessary - if (!isset($q[$id]['count'])) { - $q[$id]['count'] = array('hi'=>0, 'lo'=>0, 'correct'=>0, 'total'=>0, 'sum'=>0); - } - // increment counters - $q[$id]['count']['sum'] += $response->score; - $q[$id]['count']['total']++; - if ($response->score==100) { - $q[$id]['count']['correct']++; - if ($is_hi_score) { - $q[$id]['count']['hi']++; - } else if ($is_lo_score) { - $q[$id]['count']['lo']++; - } - } - } // end foreach attempt - } // end foreach question - // check we have some details - if (count($q)) { - $showhideid = 'showhide'; - // shortcuts for html tags - $bold_start = $is_html ? '' : ""; - $bold_end = $is_html ? '' : ""; - $div_start = $is_html ? '
' : ""; - $div_end = $is_html ? '
' : ""; - $font_red = $is_html ? '' : ''; - $font_blue = $is_html ? '' : ''; - $font_green = $is_html ? '' : ''; - $font_brown = $is_html ? '' : ''; - $font_end = $is_html ? ''."\n" : ''; - $br = $is_html ? '
' : "\n"; - $space = $is_html ? ' ' : ""; - $no_value = $is_html ? '--' : ""; - $help_button = $is_html ? $OUTPUT->old_help_icon("discrimination", get_string('discrimination', 'quiz'), "quiz") : ""; - // table properties - unset($table); - $table->border = 1; - $table->width = '100%'; - $table->caption = get_string('itemanal', 'quiz'); - if ($is_html) { - $table->caption .= $OUTPUT->old_help_icon('analysistable', $table->caption, 'hotpot'); - } - // initialize legend, if necessary - if (!empty($options['reportshowlegend'])) { - if (empty($tables) || empty($tables[0]->legend)) { - $table->legend = array(); - } else { - $table->legend = $tables[0]->legend; - unset($tables[0]->legend); - } - } - // headings for name, attempt number and score/grade - $table->head = array($space); - $table->align = array('right'); - $table->size = array(80); - // question headings - $this->add_question_headings($questions, $table, 'left', 0); - // initialize statistics - $table->stat = array(); - $table->statheadercols = array(0); - // add headings for the $foot of the $table - $table->foot = array(); - $table->foot[0] = array(get_string('average', 'hotpot')); - $table->foot[1] = array(get_string('percentcorrect', 'quiz')); - $table->foot[2] = array(get_string('discrimination', 'quiz').$help_button); - // maximum discrimination index (also default the default value) - $max_d_index = 10; - //////////////////////////////////////////// - // format the statistics into the $table - //////////////////////////////////////////// - // add $stat(istics) and $foot of $table - $questionids = array_keys($q); - foreach ($questionids as $col => $id) { - $row = 0; - // print the question text if there is no legend - if (empty($table->legend)) { - // add button to show/hide question text - if (!isset($table->stat[0])) { - $button = $is_html ? hotpot_showhide_button($showhideid) : ""; - $table->stat[0] = array(get_string('question', 'quiz').$button); - } - // add the question name/text - $name = hotpot_get_question_name($questions[$id]); - $table->stat[$row++][$col+1] = $div_start.$bold_start.$name.$bold_end.$div_end.$space; - } - // add details about each field - foreach ($fields as $field) { - // check this row is required - if ($f[$field]['count']) { - $values = array(); - $string_type = array_search($field, $string_fields); - // get the value of each response to this field - // and the count of that value - foreach ($q[$id][$field] as $value => $count) { - if (is_numeric($value) && $count) { - if (is_numeric($string_type)) { - $value = hotpot_string($value); - $this->set_legend($table, $col, $value, $questions[$id]); - switch ($string_type) { - case 0: // correct - $font_start = $font_red; - break; - case 1: // wrong - $font_start = $font_blue; - break; - case 2: // ignored - $font_start = $font_brown; - break; - } - } else { // numeric field - $font_start = $font_green; - } - $values[] = $font_start.round(100*$count/$q[$id]['count']['total']).'%'.$font_end.' '.$value; - } - } // end foreach $value => $count - // initialize stat(istics) row for this field, if required - if (!isset($table->stat[$row])) { - $table->stat[$row] = array(get_string($field, 'hotpot')); - } - // sort the values by frequency (using user-defined function) - usort($values, "hotpot_sort_stat_values"); - // add stat(istics) values for this field - $table->stat[$row++][$col+1] = count($values) ? implode($br, $values) : $space; - } - } // end foreach field - // default percent correct and discrimination index for this question - $average = $no_value; - $percent = $no_value; - $d_index = $no_value; - if (isset($q[$id]['count'])) { - // average and percent correct - if ($q[$id]['count']['total']) { - $average = round($q[$id]['count']['sum'] / $q[$id]['count']['total']).'%'; - $percent = round(100*$q[$id]['count']['correct'] / $q[$id]['count']['total']).'%'; - $percent .= ' ('.$q[$id]['count']['correct'].'/'.$q[$id]['count']['total'].')'; - } - // discrimination index - if ($q[$id]['count']['lo']) { - $d_index = min($max_d_index, round($q[$id]['count']['hi'] / $q[$id]['count']['lo'], 1)); - } else { - $d_index = $q[$id]['count']['hi'] ? $max_d_index : 0; - } - $d_index .= ' ('.$q[$id]['count']['hi'].'/'.$q[$id]['count']['lo'].')'; - } - $table->foot[0][$col+1] = $average; - $table->foot[1][$col+1] = $percent; - $table->foot[2][$col+1] = $d_index; - } // end foreach $question ($col) - // add javascript to show/hide question text - if (isset($table->stat[0]) && $is_html && empty($table->legend)) { - $i = count($table->stat[0]); - $table->stat[0][$i-1] .= hotpot_showhide_set($showhideid); - } - $tables[] = &$table; - $this->create_legend_table($tables, $table); - } // end if (empty($q) - } // end function -} // end class -function hotpot_sort_stat_values($a, $b) { - // sorts in descending order - // assumes first chars in $a and $b are a percentage - $a_val = intval(strip_tags($a)); - $b_val = intval(strip_tags($b)); - return ($a_val<$b_val) ? 1 : ($a_val==$b_val ? 0 : -1); -} -function hotpot_showhide_button($id) { - $show = get_string('show'); - $hide = get_string('hide'); - $pref = '1'; - $text = ($pref=='1' ? $hide : $show); -return << -//'; - html += ''; - html += ''; - html += ''; - document.writeln(html); - } -//]]> - -SHOWHIDE_BUTTON -; -} -function hotpot_showhide_set($id) { -return << -// - -SHOWHIDE_SET -; -} - diff --git a/mod/hotpot/report/overview/report.php b/mod/hotpot/report/overview/report.php deleted file mode 100644 index 310aacab29f..00000000000 --- a/mod/hotpot/report/overview/report.php +++ /dev/null @@ -1,172 +0,0 @@ -create_overview_table($hotpot, $cm, $course, $users, $attempts, $questions, $options, $tables); - $this->print_report($course, $hotpot, $tables, $options); - return true; - } - function create_overview_table(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { - global $CFG, $OUTPUT; - $strtimeformat = get_string('strftimedatetime'); - $is_html = ($options['reportformat']=='htm'); - $spacer = $is_html ? ' ' : ' '; - $br = $is_html ? "
\n" : "\n"; - // initialize $table - unset($table); - $table->border = 1; - $table->width = 10; - $table->head = array(); - $table->align = array(); - $table->size = array(); - $table->wrap = array(); - // picture column, if required - if ($is_html) { - $table->head[] = $spacer; - $table->align[] = 'center'; - $table->size[] = 10; - $table->wrap[] = "nowrap"; - } - array_push($table->head, - get_string("name"), - hotpot_grade_heading($hotpot, $options), - get_string("attempt", "quiz"), - get_string("time", "quiz"), - get_string("reportstatus", "hotpot"), - get_string("timetaken", "quiz"), - get_string("score", "quiz") - ); - array_push($table->align, "left", "center", "center", "left", "center", "center", "center"); - array_push($table->wrap, "nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap"); - array_push($table->size, "*", "*", "*", "*", "*", "*", "*"); - $abandoned = 0; - foreach ($users as $user) { - // shortcut to user info held in first attempt record - $u = &$user->attempts[0]; - $picture = ''; - $name = fullname($u); - if ($is_html) { - //grrrr - $usr = clone($u); - $u->id = $u->userid; - $picture = $OUTPUT->user_picture($usr, array('courseid'=>$course->id)); - $name = ''.$name.''; - } - $grade = isset($user->grade) && $user->grade<>' ' ? $user->grade : $spacer; - $attemptcount = count($user->attempts); - if ($attemptcount>1) { - $text = $name; - $name = NULL; - $name->text = $text; - $name->rowspan = $attemptcount; - $text = $grade; - $grade = NULL; - $grade->text = $text; - $grade->rowspan = $attemptcount; - } - $data = array(); - if ($is_html) { - if ($attemptcount>1) { - $text = $picture; - $picture = NULL; - $picture->text = $text; - $picture->rowspan = $attemptcount; - } - $data[] = $picture; - } - array_push($data, $name, $grade); - foreach ($user->attempts as $attempt) { - // increment count of abandoned attempts - // if attempt is marked as finished but has no score - if ($attempt->status==HOTPOT_STATUS_ABANDONED) { - $abandoned++; - } - $attemptnumber = $attempt->attempt; - $starttime = trim(userdate($attempt->timestart, $strtimeformat)); - if ($is_html && isset($attempt->score) && (has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review)) { - $attemptnumber = ''.$attemptnumber.''; - $starttime = ''.$starttime.''; - } - if ($is_html && has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id))) { - $checkbox = ''.$spacer; - } else { - $checkbox = ''; - } - $timetaken = empty($attempt->timefinish) ? $spacer : format_time($attempt->timefinish - $attempt->timestart); - $score = hotpot_format_score($attempt); - if ($is_html && is_numeric($score) && $score==$user->grade) { // best grade - $score = ''.$score.''; - } - array_push($data, - $attemptnumber, - $checkbox.$starttime, - hotpot_format_status($attempt), - $timetaken, - $score - ); - $table->data[] = $data; - $data = array(); - } // end foreach $attempt - $table->data[] = 'hr'; - } // end foreach $user - // remove final 'hr' from data rows - array_pop($table->data); - // add the "delete" form to the table - if ($options['reportformat']=='htm' && has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id))) { - $strdeletecheck = get_string('deleteattemptcheck','quiz'); - $table->start = $this->deleteform_javascript(); - $table->start .= '
'."\n"; - $table->start .= ''."\n"; - $table->start .= ''."\n"; - $table->finish = '
'."\n"; - $table->finish .= ' '."\n"; - if ($abandoned) { - $table->finish .= ''."\n"; - } - $table->finish .= ''."\n"; - $table->finish .= '
'."\n"; - $table->finish .= '
'."\n"; - } - $tables[] = &$table; - } - function deleteform_javascript() { - $strselectattempt = addslashes_js(get_string('selectattempt','hotpot')); - return << - - -END_OF_JAVASCRIPT -; - } // end function -} // end class - diff --git a/mod/hotpot/report/simplestat/report.php b/mod/hotpot/report/simplestat/report.php deleted file mode 100644 index 1ff5ddbf108..00000000000 --- a/mod/hotpot/report/simplestat/report.php +++ /dev/null @@ -1,203 +0,0 @@ -create_scores_table($hotpot, $course, $users, $attempts, $questions, $options, $tables); - $this->print_report($course, $hotpot, $tables, $options); - return true; - } - function create_scores_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) { - global $CFG, $OUTPUT; - $download = ($options['reportformat']=='htm') ? false : true; - $is_html = ($options['reportformat']=='htm'); - $blank = ($download ? '' : ' '); - $no_value = ($download ? '' : '-'); - $allow_review = true; - // start the table - unset($table); - $table->border = 1; - $table->head = array(); - $table->align = array(); - $table->size = array(); - // picture column, if required - if ($is_html) { - $table->head[] = ' '; - $table->align[] = 'center'; - $table->size[] = 10; - } - // name, grade and attempt number - array_push($table->head, - get_string("name"), - hotpot_grade_heading($hotpot, $options), - get_string("attempt", "quiz") - ); - array_push($table->align, "left", "center", "center"); - array_push($table->size, '', '', ''); - // question headings - $this->add_question_headings($questions, $table); - // penalties and raw score - array_push($table->head, - get_string('penalties', 'hotpot'), - get_string('score', 'quiz') - ); - array_push($table->align, "center", "center"); - array_push($table->size, '', ''); - $table->data = array(); - $q = array( - 'grade' => array('count'=>0, 'total'=>0), - 'penalties' => array('count'=>0, 'total'=>0), - 'score' => array('count'=>0, 'total'=>0), - ); - foreach ($users as $user) { - // shortcut to user info held in first attempt record - $u = &$user->attempts[0]; - $picture = ''; - $name = fullname($u); - if ($is_html) { - $picture = $OUTPUT->user_picture($u, array('courseid'=>$course->id)); - $name = html_writer::link($CFG->wwwroot.'/user/view.php?id='.$u->userid.'&course='.$course->id, $name); - } - if (isset($user->grade)) { - $grade = $user->grade; - $q['grade']['count'] ++; - if (is_numeric($grade)) { - $q['grade']['total'] += $grade; - } - } else { - $grade = $no_value; - } - $attemptcount = count($user->attempts); - if ($attemptcount>1) { - $text = $name; - $name = NULL; - $name->text = $text; - $name->rowspan = $attemptcount; - $text = $grade; - $grade = NULL; - $grade->text = $text; - $grade->rowspan = $attemptcount; - } - $data = array(); - if ($is_html) { - if ($attemptcount>1) { - $text = $picture; - $picture = NULL; - $picture->text = $text; - $picture->rowspan = $attemptcount; - } - $data[] = $picture; - } - array_push($data, $name, $grade); - foreach ($user->attempts as $attempt) { - // set flag if this is best grade - $is_best_grade = ($is_html && $attempt->score==$user->grade); - // get attempt number - $attemptnumber= $attempt->attempt; - if ($is_html && $allow_review) { - $attemptnumber = ''.$attemptnumber.''; - } - if ($is_best_grade) { - $score = ''.$attemptnumber.''; - } - $data[] = $attemptnumber; - // get responses to questions in this attempt by this user - foreach ($questions as $id=>$question) { - if (!isset($q[$id])) { - $q[$id] = array('count'=>0, 'total'=>0); - } - if (isset($attempt->responses[$id])) { - $score = $attempt->responses[$id]->score; - if (is_numeric($score)) { - $q[$id]['count'] ++; - $q[$id]['total'] += $score; - if ($is_best_grade) { - $score = ''.$score.''; - } - } else if (empty($score)) { - $score = $no_value; - } - } else { - $score = $no_value; - } - $data[] = $score; - } // foreach $questions - if (isset($attempt->penalties)) { - $penalties = $attempt->penalties; - if (is_numeric($penalties)) { - $q['penalties']['count'] ++; - $q['penalties']['total'] += $penalties; - } - if ($is_best_grade) { - $penalties = ''.$penalties.''; - } - } else { - $penalties = $no_value; - } - $data[] = $penalties; - if (isset($attempt->score)) { - $score = $attempt->score; - if (is_numeric($score)) { - $q['score']['total'] += $score; - $q['score']['count'] ++; - } - if ($is_best_grade) { - $score = ''.$score.''; - } - } else { - $score = $no_value; - } - $data[] = $score; - // append data for this attempt - $table->data[] = $data; - // reset data array for next attempt, if any - $data = array(); - } // end foreach $attempt - $table->data[] = 'hr'; - } // end foreach $user - // remove final 'hr' from data rows - array_pop($table->data); - // add averages to foot of table - $averages = array(); - if ($is_html) { - $averages[] = $blank; - } - array_push($averages, get_string('average', 'hotpot')); - $col = count($averages); - if (empty($q['grade']['count'])) { - // remove score $col from $table - $this->remove_column($table, $col); - } else { - $precision = ($hotpot->grademethod==HOTPOT_GRADEMETHOD_AVERAGE || $hotpot->grade<100) ? 1 : 0; - $averages[] = round($q['grade']['total'] / $q['grade']['count'], $precision); - $col++; - } - // skip the attempt number column - $averages[$col++] = $blank; - foreach ($questions as $id=>$question) { - if (empty($q[$id]['count'])) { - // remove this question $col from $table - $this->remove_column($table, $col); - } else { - $averages[$col++] = round($q[$id]['total'] / $q[$id]['count']); - } - } - if (empty($q['penalties']['count'])) { - // remove penalties $col from $table - $this->remove_column($table, $col); - } else { - $averages[$col++] = round($q['penalties']['total'] / $q['penalties']['count']); - } - if (empty($q['score']['count'])) { - // remove score $col from $table - $this->remove_column($table, $col); - } else { - $averages[$col++] = round($q['score']['total'] / $q['score']['count']); - } - $table->foot = array($averages); - $tables[] = &$table; - } -} // end class - diff --git a/mod/hotpot/restorelib.php b/mod/hotpot/restorelib.php deleted file mode 100644 index 957a8cc4a62..00000000000 --- a/mod/hotpot/restorelib.php +++ /dev/null @@ -1,537 +0,0 @@ -id, - // fk->course, files) - // | - // +--------------+---------------+ - // | | - // hotpot_attempts hotpot_questions - // (UL, pk->id, (UL, pk->id, - // fk->hotpot) fk->hotpot, text) - // | | | - // +-------------------+----------+ | - // | | | - // hotpot_details hotpot_responses | - // (UL, pk->id, (UL, pk->id, | - // fk->attempt) fk->attempt, question, | - // correct, wrong, ignored) | - // | | - // +-------+-------+ - // | - // hotpot_strings - // (UL, pk->id) - // - // Meaning: pk->primary key field of the table - // fk->foreign key to link with parent - // nt->nested field (recursive data) - // CL->course level info - // UL->user level info - // files->table may have files - // - //----------------------------------------------------------- - -require_once ("$CFG->dirroot/mod/hotpot/lib.php"); - -function hotpot_restore_mods($mod, $restore) { - //This function restores a single hotpot activity - - // This function is called by "restore_create_modules" (in "backup/restorelib.php") - // which is called by "backup/restore_execute.html" (included by "backup/restore.php") - // $mod is an object - // id : id field in 'modtype' table - // modtype : 'hotpot' - // $restore is an object - // backup_unique_code : xxxxxxxxxx - // file : '/full/path/to/backupfile.zip' - // mods : an array of $modinfo's (see below) - // restoreto : See RESTORETO_XXX constants in backup/lib.php - // users : 0=all, 1=course, 2=none - // logs : 0=no, 1=yes - // user_files : 0=no, 1=yes - // course_files : 0=no, 1=yes - // course_id : id of course into which data is to be restored - // deleting : true if 'restoreto'==RESTORETO_NEW_COURSE, otherwise false - // original_wwwroot : 'http://your.server.com/moodle' - // $modinfo is an array - // 'modname' : array( 'restore'=> 0=no 1=yes, 'userinfo' => 0=no 1=yes) - - global $CFG; - $status = true; - - // get course module data this hotpot activity - $data = backup_getid($restore->backup_unique_code, 'hotpot', $mod->id); - if ($data) { - // $data is an object - // backup_code => xxxxxxxxxx, - // table_name => 'hotpot', - // old_id => xxx, - // new_id => NULL, - // info => xml tree array of info backed up for this hotpot activity - $xml = &$data->info['MOD']['#']; - $table = 'hotpot'; - $foreign_keys = array('course' => $restore->course_id); - $more_restore = ''; - // print a message after each hotpot is backed up - if (!defined('RESTORE_SILENTLY')) { - $more_restore .= 'print "
  • ".get_string("modulename", "hotpot")." "".format_string($record->name,true).""
  • ";'; - } - $more_restore .= 'backup_flush(300);'; - if (function_exists('restore_userdata_selected')) { - // Moodle >= 1.6 - $restore_userdata_selected = restore_userdata_selected($restore, 'hotpot', $mod->id); - } else { - // Moodle <= 1.5 - $restore_userdata_selected = $restore->mods['hotpot']->userinfo; - } - if ($restore_userdata_selected) { - $has_details = false; - if (isset($xml["ATTEMPT_DATA"]["0"]["#"]["ATTEMPT"]["0"]["#"]["DETAILS"]["0"]["#"])) { - $details = trim($xml["ATTEMPT_DATA"]["0"]["#"]["ATTEMPT"]["0"]["#"]["DETAILS"]["0"]["#"]); - if ($details<>'' && $details<>'') { - $has_details = true; - } - } - if ($has_details && empty($xml["STRING_DATA"]) && empty($xml["QUESTION_DATA"])) { - // HotPot v2.0.x (regenerate questions, responses and strings from attempt details) - $more_restore .= '$status = hotpot_restore_attempts($restore, $status, $xml, $record, true);'; - } else { - // HotPot v2.1+ - $more_restore .= '$status = hotpot_restore_strings($restore, $status, $xml, $record);'; - $more_restore .= '$status = hotpot_restore_questions($restore, $status, $xml, $record);'; - $more_restore .= '$status = hotpot_restore_attempts($restore, $status, $xml, $record);'; - } - } - - // if necessary, adjust HotPot date/time fields and write to restorelog - if ($restore->course_startdateoffset) { - restore_log_date_changes('Hotpot', $restore, $xml, array('TIMEOPEN', 'TIMECLOSE', 'TIMECREATED', 'TIMEMODIFIED')); - } - - $status = hotpot_restore_records( - $restore, $status, $xml, $table, $foreign_keys, $more_restore - ); - } - return $status; -} -function hotpot_restore_strings(&$restore, $status, &$xml, &$record) { - // $xml is an XML tree for a hotpot record - // $record is the newly added hotpot record - return hotpot_restore_records( - $restore, $status, $xml, 'hotpot_strings', array(), '', 'STRING_DATA', 'STRING', 'md5key' - ); -} -function hotpot_restore_questions(&$restore, $status, &$xml, &$record) { - // $xml is an XML tree for a hotpot record - // $record is the newly added hotpot record - $foreignkeys = array( - 'hotpot'=>$record->id, - 'text'=>'hotpot_strings' - ); - return hotpot_restore_records( - $restore, $status, $xml, 'hotpot_questions', $foreignkeys, '', 'QUESTION_DATA', 'QUESTION' - ); -} -function hotpot_restore_attempts(&$restore, $status, &$xml, &$record, $hotpot_v20=false) { - // $xml is an XML tree for a hotpot record - // $record is the newly added hotpot record - global $DB; - $foreignkeys = array( - 'userid'=>'user', - 'hotpot'=>$record->id, - ); - $more_restore = ''; - $more_restore .= 'hotpot_restore_details($restore, $status, $xml, $record);'; - if ($hotpot_v20) { - // HotPot v2.0.x (regenerate questions and responses from details) - $more_restore .= 'hotpot_add_attempt_details($record);'; // see "hotpot/lib.php" - } else { - // HotPot v2.1+ - $more_restore .= '$status = hotpot_restore_responses($restore, $status, $xml, $record);'; - // save clickreportid (to be updated it later) - $more_restore .= 'if (!empty($record->clickreportid)) {'; - $more_restore .= '$GLOBALS["hotpot_backup_clickreportids"][$record->id]=$record->clickreportid;'; - $more_restore .= '}'; - // initialize global array to store clickreportids - $GLOBALS["hotpot_backup_clickreportids"] = array(); - } - $status = hotpot_restore_records( - $restore, $status, $xml, 'hotpot_attempts', $foreignkeys, $more_restore, 'ATTEMPT_DATA', 'ATTEMPT' - ); - if ($hotpot_v20) { - if ($status) { - global $CFG; - // based on code in "mod/hotpot/db/update_to_v2.php" - $params = array($record->id); - $DB->execute("UPDATE {hotpot_attempts} SET status=1 WHERE hotpot=? AND timefinish=0 AND score IS NULL", $params); - $DB->execute("UPDATE {hotpot_attempts} SET status=3 WHERE hotpot=? AND timefinish>0 AND score IS NULL", $params); - $DB->execute("UPDATE {hotpot_attempts} SET status=4 WHERE hotpot=? AND timefinish>0 AND score IS NOT NULL", $params); - $DB->execute("UPDATE {hotpot_attempts} SET clickreportid=id WHERE hotpot=? AND clickreportid IS NULL", $params); - } - } else { - $status = hotpot_restore_clickreportids($restore, $status); - unset($GLOBALS["hotpot_backup_clickreportids"]); // tidy up - } - return $status; -} -function hotpot_restore_clickreportids(&$restore, $status) { - // update clickreport ids, if any - global $CFG, $DB; - foreach ($GLOBALS["hotpot_backup_clickreportids"] as $id=>$clickreportid) { - if ($status) { - $attempt_record = backup_getid($restore->backup_unique_code, 'hotpot_attempts', $clickreportid); - if ($attempt_record) { - $new_clickreportid = $attempt_record->new_id; - $status = $DB->execute("UPDATE {hotpot_attempts} SET clickreportid=? WHERE id=?", array($new_clickreportid, $id)); - } else { - // New clickreport id could not be found - if (!defined('RESTORE_SILENTLY')) { - print "
    • New clickreportid could not be found: attempt id=$id, clickreportid=$clickreportid
    "; - } - $status = false; - } - } - } - return $status; -} -function hotpot_restore_responses(&$restore, $status, &$xml, &$record) { - // $xml is an XML tree for an attempt record - // $record is the newly added attempt record - $foreignkeys = array( - 'attempt'=>$record->id, - 'question'=>'hotpot_questions', - 'correct'=>'hotpot_strings', - 'wrong'=>'hotpot_strings', - 'ignored'=>'hotpot_strings' - ); - return hotpot_restore_records( - $restore, $status, $xml, 'hotpot_responses', $foreignkeys, '', 'RESPONSE_DATA', 'RESPONSE' - ); -} -function hotpot_restore_details(&$restore, $status, &$xml, &$record) { - global $DB; - // $xml is an XML tree for an attempt record - // $record is the newly added attempt record - if (empty($record->details)) { - $status = true; - } else { - $details = new stdClass(); - $details->attempt = $record->id; - $details->details = $record->details; - if ($DB->insert_record('hotpot_details', $details)) { - $status = true; - } else { - if (!defined('RESTORE_SILENTLY')) { - print "
    • Details record could not be updated: attempt=$record->attempt
    "; - } - $status = false; - } - } - return $status; -} -function hotpot_restore_records(&$restore, $status, &$xml, $table, $foreign_keys, $more_restore='', $records_TAG='', $record_TAG='', $secondary_key='') { -// general purpose function to restore a group of records - // $restore : (see "hotpot_restore_mods" above) - // $xml : an XML tree (or sub-tree) - // $records_TAG : (optional) the name of an XML tag which starts a block of records - // If no $records_TAG is specified, $xml is assumed to be a block of records - // $record_TAG : (optional) the name of an XML tag which starts a single record - // If no $record_TAG is specified, the block of records is assumed to be a single record - // other parameters are explained in "hotpot_restore_record" below - - $i = 0; // index for $records_TAG - do { - unset($xml_records); - if ($records_TAG) { - if (isset($xml[$records_TAG][$i]['#'])) { - $xml_records = &$xml[$records_TAG][$i]['#']; - } - } else { - if ($i==0) { - $xml_records = &$xml; - } - } - if (isset($xml_records)) { - $ii = 0; // index for $record_TAG - do { - unset($xml_record); - if ($record_TAG) { - if (isset($xml_records[$record_TAG][$ii]['#'])) { - $xml_record = &$xml_records[$record_TAG][$ii]['#']; - } - } else { - if ($ii==0) { - $xml_record = &$xml_records; - } - } - if (isset($xml_record)) { - $status = hotpot_restore_record( - $restore, $status, $xml_record, $table, $foreign_keys, $more_restore, $secondary_key - ); - } - $ii++; - } while ($status && isset($xml_record)); - } - $i++; - } while ($status && isset($xml_records)); - return $status; -} -function hotpot_restore_record(&$restore, $status, &$xml, $table, $foreign_keys, $more_restore, $secondary_key) { -// general purpose function to restore a single record - // $restore : (see "hotpot_restore_mods" above) - // $status : current status of backup (true or false) - // $xml : XML tree of current record - // $table : name of Moodle database table to restore to - // $foreign_keys : array of foreign keys, if any, specifed as $key=>$value - // $key : the name of a field in the current $record - // $value : if $value is numeric, then $record->$key is set to $value. - // Otherwise $value is assumed to be a table name and $record->$key - // is treated as a comma separated list of ids in that table - // $more_restore : optional PHP code to be eval(uated) for each record - // $secondary_key : - // the name of the secondary key field, if any, in the current $record. - // If this field is specified, then the current record will only be added - // if the $record->$secondarykey value does not already exist in $table - - // maintain a cache of info on table columns - global $DB; - - static $table_columns = array(); - if (empty($table_columns[$table])) { - global $CFG, $DB; - $table_columns[$table] = $DB->get_columns($table); - } - - // get values for fields in this record - $record = new stdClass(); - $TAGS = array_keys($xml); - foreach ($TAGS as $TAG) { - $value = $xml[$TAG][0]['#']; - if (is_string($value)) { - $tag = strtolower($TAG); - $record->$tag = backup_todb($value); - } - } - - // update foreign keys, if any - $ok = true; - foreach ($foreign_keys as $key=>$value) { - if (is_numeric($value)) { - $record->$key = $value; - } else { - $key_table = $value; - $new_ids = array(); - if (isset($record->$key)) { - $old_ids = explode(',', $record->$key); - foreach ($old_ids as $old_id) { - if (empty($old_id)) { - // do nothing - } else { - $key_record = backup_getid($restore->backup_unique_code, $key_table, $old_id); - if ($key_record) { - $new_ids[] = $key_record->new_id; - } else { - // foreign key could not be updated - if (!defined('RESTORE_SILENTLY')) { - print "
    • Warning:
      Foreign key could not be updated:
      "; - print "'$key_table' record (old id=$old_id) is missing from backup data
      "; - print "'$table' record "; - if (isset($record->id)) { - print "(old id=$record->id) "; - } - print "was not restored
    "; - } - $ok = false; - } - } - } - } - $record->$key = implode(',', $new_ids); - } - } - - // set md5 keys if necessary (restoring from Moodle<1.6) - if ($table=='hotpot_questions' && empty($record->md5key)) { - $record->md5key = md5($record->name); - } - if ($table=='hotpot_strings' && empty($record->md5key)) { - $record->md5key = md5($record->string); - } - - // check all "not null" fields have been set - foreach ($table_columns[$table] as $column) { - if ($column->not_null) { - $name = $column->name; - if ($name=='id' || (isset($record->$name) && ! is_null($record->$name))) { - // do nothing - } else if (isset($column->default_value)) { - $record->$name = $column->default_value; - } else if (preg_match('/[INTD]/', $column->meta_type)) { - $record->$name = 0; - } else { - $record->$name = ''; - } - } - } - - // check everything is OK so far - if ($ok) { - // store old record id, if necessary - if (isset($record->id)) { - $record->old_id = $record->id; - unset($record->id); - } - // if there is a secondary key field ... - if ($secondary_key) { - // check to see if a record with the same value already exists - $key_records = $DB->get_records($table, array($secondary_key=>$record->$secondary_key)); - if ($key_records) { - // set new record id from already existing record - $key_record = reset($key_records); - $record->id = $key_record->id; - } - } - if (empty($record->id)) { - // add the $record (and get new id) - $record->id = $DB->insert_record($table, $record); - } - // check $record was added (or found) - if (is_numeric($record->id)) { - // if there was an old id, save a mapping to the new id - if (isset($record->old_id)) { - backup_putid($restore->backup_unique_code, $table, $record->old_id, $record->id); - } - } else { - // failed to add (or find) $record - if (!defined('RESTORE_SILENTLY')) { - print "
    • Record could not be added: table=$table
    "; - } - $status = false; - } - // restore related records, if required - if ($more_restore) { - eval($more_restore); - } - } - return $status; -} -//This function returns a log record with all the necessay transformations -//done. It's used by restore_log_module() to restore modules log. -function hotpot_restore_logs($restore, $log) { - // assume the worst - $status = false; - switch ($log->action) { - case "add": - case "update": - case "view": - if ($log->cmid) { - //Get the new_id of the module (to recode the info field) - $mod = backup_getid($restore->backup_unique_code, $log->module, $log->info); - if ($mod) { - $log->url = "view.php?id=".$log->cmid; - $log->info = $mod->new_id; - $status = true; - } - } - break; - case "view all": - $log->url = "index.php?id=".$log->course; - $status = true; - break; - case "report": - if ($log->cmid) { - //Get the new_id of the module (to recode the info field) - $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info); - if ($mod) { - $log->url = "report.php?id=".$log->cmid; - $log->info = $mod->new_id; - $status = true; - } - } - break; - case "attempt": - case "submit": - case "review": - if ($log->cmid) { - //Get the new_id of the module (to recode the info field) - $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info); - if ($mod) { - //Extract the attempt id from the url field - $attemptid = substr(strrchr($log->url,"="),1); - //Get the new_id of the attempt (to recode the url field) - $attempt = backup_getid($restore->backup_unique_code,"hotpot_attempts",$attemptid); - if ($attempt) { - $log->url = "review.php?id=".$log->cmid."&attempt=".$attempt->new_id; - $log->info = $mod->new_id; - $status = true; - } - } - } - break; - default: - // Oops, unknown $log->action - if (!defined('RESTORE_SILENTLY')) { - print "

    action (".$log->module."-".$log->action.") unknown. Not restored

    "; - } - break; - } // end switch - return $status ? $log : false; -} - -function hotpot_decode_content_links($content, $restore) { - $search = '/\$@(HOTPOT)\*([a-z]+)\*([a-z]+)\*([0-9]+)@\$/is'; - if (preg_match_all($search, $content, $matches, PREG_OFFSET_CAPTURE)) { - $i_max = count($matches[0]) - 1; - for ($i=$i_max; $i>=0; $i--) { - $start = $matches[0][$i][1]; - $length = strlen($matches[0][$i][0]); - $replace = hotpot_decode_content_link( - // $scriptname, $paramname, $paramvalue, $restore - $matches[2][$i][0], $matches[3][$i][0], $matches[4][$i][0], $restore - ); - $content = substr_replace($content, $replace, $start, $length); - } - } - return $content; -} - -function hotpot_decode_content_link($scriptname, $paramname, $paramvalue, &$restore) { - global $CFG; - - $table = ''; - switch ($paramname) { - case 'id': - switch ($scriptname) { - case 'index': - $table = 'course'; - break; - case 'report': - case 'review': - case 'view': - $table = 'course_modules'; - break; - case 'attempt': - $table = 'hotpot_attempts'; - break; - } - break; - case 'hp': - case 'hotpotid': - $table = 'hotpot'; - break; - } - - $new_id = 0; - if ($table) { - if ($rec = backup_getid($restore->backup_unique_code, $table, $paramvalue)) { - $new_id = $rec->new_id; - } - } - - return "$CFG->wwwroot/mod/hotpot/$scriptname.php?$paramname=$new_id"; -} - diff --git a/mod/hotpot/review.php b/mod/hotpot/review.php deleted file mode 100644 index 70622268afd..00000000000 --- a/mod/hotpot/review.php +++ /dev/null @@ -1,251 +0,0 @@ -set_url('/mod/hotpot/review.php', array('id'=>$id,'attempt'=>$attempt)); - if (! $cm = get_coursemodule_from_id('hotpot', $id)) { - print_error('invalidcoursemodule'); - } - if (! $course = $DB->get_record("course", array("id"=>$cm->course))) { - print_error('coursemisconf'); - } - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$cm->instance))) { - print_error('invalidcoursemodule'); - } - } else { - $PAGE->set_url('/mod/hotpot/review.php', array('hp'=>$hp,'attempt'=>$attempt)); - if (! $hotpot = $DB->get_record("hotpot", array("id"=>$hp))) { - print_error('invalidcoursemodule'); - } - if (! $course = $DB->get_record("course", array("id"=>$hotpot->course))) { - print_error('coursemisconf'); - } - if (! $cm = get_coursemodule_from_instance("hotpot", $hotpot->id, $course->id)) { - print_error('invalidcoursemodule'); - } - } - if (! $attempt = $DB->get_record("hotpot_attempts", array("id"=>$attempt))) { - print_error('invalidattemptid', 'hotpot'); - } - - require_login($course, true, $cm); - - $context = get_context_instance(CONTEXT_MODULE, $cm->id); - if (!has_capability('mod/hotpot:viewreport',$context)) { - if (!$hotpot->review) { - print_error("noreview", "quiz"); - } - //if (time() < $hotpot->timeclose) { - // print_error("noreviewuntil", "quiz", '', userdate($hotpot->timeclose)); - //} - if ($attempt->userid != $USER->id) { - print_error('notyourattempt', 'hotpot'); - } - } - 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 - - $PAGE->requires->js('/lib/overlib/overlib.js', true); - $PAGE->requires->js('/lib/overlib/overlib_cssstyle.js', true); - $PAGE->set_title(format_string($course->shortname) . ": $hotpot->name"); - $PAGE->set_heading($course->fullname); - echo $OUTPUT->header(); - print ''; // for overlib - echo $OUTPUT->heading($hotpot->name); - hotpot_print_attempt_summary($hotpot, $attempt); - hotpot_print_review_buttons($course, $hotpot, $attempt, $context); - $action = has_capability('mod/hotpot:viewreport',$context) ? optional_param('action', '', PARAM_ALPHA) : ''; - if ($action) { - $xml = $DB->get_field('hotpot_details', 'details', array('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, $context); - echo $OUTPUT->footer(); -/////////////////////////// -// functions -/////////////////////////// -function hotpot_print_attempt_summary(&$hotpot, &$attempt) { - // start table - global $OUTPUT; - echo $OUTPUT->box_start("generalbox boxaligncenter boxwidthwide"); - 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.'
    '; - echo $OUTPUT->box_end(); -} -function hotpot_print_review_buttons(&$course, &$hotpot, &$attempt, $context) { - global $DB, $OUTPUT; - - print "\n".''; - print "\n\n".'\n".'\n".'\n\n"; - print '\n"; - print "
    '; - echo $OUTPUT->single_button(new moodle_url("report.php", array('hp'=>$hotpot->id)), get_string('continue')); - if (has_capability('mod/hotpot:viewreport',$context) && $DB->record_exists('hotpot_details', array('attempt'=>$attempt->id))) { - print "'; - echo $OUTPUT->single_button(new moodle_url("review.php", array('hp'=>$hotpot->id, 'attempt'=>$attempt->id, 'action'=>'showxmlsource')), get_string('showxmlsource', 'hotpot')); - print "'; - echo $OUTPUT->single_button(new moodle_url("review.php", array('hp'=>$hotpot->id,'attempt'=>$attempt->id, 'action'=>'showxmltree')), get_string('showxmltree', 'hotpot')); - $colspan = 3; - } else { - $colspan = 1; - } - print "
    '; - echo $OUTPUT->spacer(array('height'=>4, 'width'=>1)); // should be done with CSS instead - print "
    \n"; -} -function hotpot_print_attempt_details(&$hotpot, &$attempt) { - global $DB, $OUTPUT; - - // 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 = $DB->get_records('hotpot_questions', array('hotpot'=>$hotpot->id), 'id'); - $responses = $DB->get_records('hotpot_responses', array('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 - echo $OUTPUT->box_start("generalbox boxaligncenter boxwidthwide"); - 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"; - echo $OUTPUT->box_end(); -} - diff --git a/mod/hotpot/settings.php b/mod/hotpot/settings.php deleted file mode 100644 index 85fde9d2274..00000000000 --- a/mod/hotpot/settings.php +++ /dev/null @@ -1,11 +0,0 @@ -fulltree) { - $settings->add(new admin_setting_configcheckbox('hotpot_showtimes', get_string('showtimes', 'hotpot'), - get_string('configshowtimes', 'hotpot'), 0) ); - - $settings->add(new admin_setting_configtext('hotpot_excelencodings', get_string('excelencodings', 'hotpot'), - get_string('configexcelencodings', 'hotpot'), '') ); -} diff --git a/mod/hotpot/show.php b/mod/hotpot/show.php deleted file mode 100644 index ebadb2ca1c3..00000000000 --- a/mod/hotpot/show.php +++ /dev/null @@ -1,75 +0,0 @@ -action = required_param('action', PARAM_ALPHA); - $params->course = required_param('course', PARAM_INT); - $params->reference = required_param('reference', PARAM_PATH); - - $PAGE->set_url('/mod/hotpot/show.php', array('action'=>$params->action, 'course'=>$params->course, 'reference'=>$params->reference)); - - require_login($params->course); - - if (!has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $params->course))) { - print_error('nopermissiontoviewpage'); - } - if (has_capability('mod/hotpot:viewreport', get_context_instance(CONTEXT_SYSTEM))) { - $params->location = optional_param('location', HOTPOT_LOCATION_COURSEFILES, PARAM_INT); - } else { - $params->location = HOTPOT_LOCATION_COURSEFILES; - } - $title = get_string($params->action, 'hotpot').': '.$params->reference; - $PAGE->set_title($title); - $PAGE->set_heading($title); - echo $OUTPUT->header(); - hotpot_print_show_links($params->course, $params->location, $params->reference); -?> - -box_start("generalbox boxaligncenter boxwidthwide"); - if($hp = new hotpot_xml_quiz($params)) { - print '
    ';
    -        switch ($params->action) {
    -            case 'showxmlsource':
    -                print htmlspecialchars($hp->source);
    -                break;
    -            case 'showxmltree':
    -                if (isset($hp->xml)) {
    -                    print_r($hp->xml);
    -                }
    -                break;
    -            case 'showhtmlsource':
    -                print htmlspecialchars($hp->html);
    -                break;
    -            case 'showhtmlquiz':
    -                print $hp->html;
    -                break;
    -        }
    -        print '
    '; - } else { - echo $OUTPUT->box("Could not open Hot Potatoes XML file", "errorboxcontent generalbox"); - } - echo $OUTPUT->box_end(); - print '
    '; - echo $OUTPUT->close_window_button(); -?> diff --git a/mod/hotpot/template/default.php b/mod/hotpot/template/default.php deleted file mode 100644 index b2cc108b955..00000000000 --- a/mod/hotpot/template/default.php +++ /dev/null @@ -1,111 +0,0 @@ -parent->template_dirpath.DIRECTORY_SEPARATOR.$filename; - // try and open the template file - if (!file_exists($filepath) || !is_readable($filepath)) { - print_error('cannotopentemplate', '', $this->parent->course_homeurl, $filepath); - } - // 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_'.str_replace('.', '', $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 { - print_error('cannotfindmethod', 'hotpot', $this->parent->course_homeurl, $method); - } - } - } - 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_callback('/&#(\d+);/', array(&$this, 'js_safe_callback'), $str); - } - return $str; - } - function js_safe_callback(&$matches) { - return '\\u'.sprintf('%04X', $matches[1]); - } - 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 deleted file mode 100644 index ad7e63a64da..00000000000 --- a/mod/hotpot/template/v6.php +++ /dev/null @@ -1,1515 +0,0 @@ -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); - } - // fix doctype (convert short dtd to long dtd) - $this->html = preg_replace( - '/]*>/', - '', - $this->html, 1 - ); - } - - // 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 str_replace('<=', '<=', $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() { - $caption = $this->parent->xml_value('hotpot-config-file,global,last-q-caption'); - return ($caption=='<=' ? '<=' : $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 str_replace('=>', '=>', $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() { - $value = $this->parent->xml_value('hotpot-config-file,global,font-size'); - return (empty($value) ? 'small' : $value); - } - 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(); - } - - // switch off scorm - function v6_expand_Scorm12() { - return false; - } - - // 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': - $tags = 'data,questions,question-record'; - while (($question="[$i]['#']") && $this->parent->xml_value($tags, $question)) { - $i++; - } - break; - } // end switch - } - return $i; - } - function v6_expand_MatchDivItems() { - $this->set_jmatch_items(); - - $l_keys = $this->shuffle_jmatch_items($this->l_items); - $r_keys = $this->shuffle_jmatch_items($this->r_items); - - $options = ''; - foreach ($r_keys as $key) { - if (! $this->r_items[$key]['fixed']) { - $options .= ''."\n"; - } - } - - $str = ''; - foreach ($l_keys as $key) { - $str .= ''.$this->l_items[$key]['text'].''; - $str .= ''; - if ($this->r_items[$key]['fixed']) { - $str .= $this->r_items[$key]['text']; - } else { - $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->js_safe($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() { - $this->set_jmatch_items(); - $str = ''; - foreach ($this->l_items as $i=>$item) { - for ($ii=0; $ii<$i; $ii++) { - if ($this->r_items[$ii]['text']==$this->r_items[$i]['text']) { - break; - } - } - $str .= "F[$i] = new Array();\n"; - $str .= "F[$i][0] = '".$this->js_safe($item['text'], true)."';\n"; - $str .= "F[$i][1] = ".($ii+1).";\n"; - } - return $str; - } - function v6_expand_DragArray() { - $this->set_jmatch_items(); - $str = ''; - foreach ($this->r_items as $i=>$item) { - for ($ii=0; $ii<$i; $ii++) { - if ($this->r_items[$ii]['text']==$this->r_items[$i]['text']) { - break; - } - } - $str .= "D[$i] = new Array();\n"; - $str .= "D[$i][0] = '".$this->js_safe($item['text'], true)."';\n"; - $str .= "D[$i][1] = ".($ii+1).";\n"; - $str .= "D[$i][2] = ".$item['fixed'].";\n"; - } - return $str; - } - - function set_jmatch_items() { - if (count($this->l_items)) { - return; - } - $tags = 'data,matching-exercise,pair'; - $i = 0; - while (($item = "[$i]['#']") && $this->parent->xml_value($tags, $item)) { - $leftitem = $item."['left-item'][0]['#']"; - $lefttext = $this->parent->xml_value($tags, $leftitem."['text'][0]['#']"); - - $rightitem = $item."['right-item'][0]['#']"; - $righttext = $this->parent->xml_value($tags, $rightitem."['text'][0]['#']"); - - if (strlen($righttext)) { - $addright = true; - } else { - $addright = false; - } - if (strlen($lefttext)) { - $this->l_items[] = array( - 'text' => $lefttext, - 'fixed' => $this->int_value($tags, $leftitem."['fixed'][0]['#']") - ); - $addright = true; // force right item to be added - } - if ($addright) { - $this->r_items[] = array( - 'text' => $righttext, - 'fixed' => $this->int_value($tags, $rightitem."['fixed'][0]['#']") - ); - } - $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 - if (! $gapsize = $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',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 - foreach ($chars as $char) { - $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() { - if ($this->parent->quiztype=='jcloze') { - $tag = 'guesses-correct'; - } else { - $tag = 'guess-correct'; - } - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.','.$tag); - } - function v6_expand_Incorrect() { - if ($this->parent->quiztype=='jcloze') { - $tag = 'guesses-incorrect'; - } else { - $tag = 'guess-incorrect'; - } - return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.','.$tag); - } - 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]['#']"); - - $first_answer_text = $this->parent->xml_value($tags, $question."['answers'][0]['#']['answer'][0]['#']['text'][0]['#']"); - - // check we have a question (or at least one answer) - if (($question_text || $first_answer_text) && $question_type) { - - $str .= '