diff --git a/mod/hotpot/README.TXT b/mod/hotpot/README.TXT
index 6536e4a988c..dd37661399a 100644
--- a/mod/hotpot/README.TXT
+++ b/mod/hotpot/README.TXT
@@ -1,10 +1,10 @@
-This is v2.1.14 of the HotPot module
+This is v2.1.15 of the HotPot module
This module allows teachers to administer Hot Potatoes and TexToys quizzes via Moodle.
It has been tested on:
- Hot Potatoes 6
- Moodle 1.1 thru 1.6
- - PHP 4.1 thru 5.0
+ - PHP 4.1 thru 5.1.2
- MySQL and PostgreSQL databases
This module may be distributed under the terms of the General Public License
diff --git a/mod/hotpot/lib.php b/mod/hotpot/lib.php
index f09af6bc88e..c6e240112fc 100644
--- a/mod/hotpot/lib.php
+++ b/mod/hotpot/lib.php
@@ -166,23 +166,23 @@ define("HOTPOT_DISPLAYNEXT_INDEX", "2");
// 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
+// 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 $hp->redirect (if set) OR hotpot/view.php (to displsay quiz)
+// continue to $hp->redirect (if set) OR hotpot/view.php (to displsay quiz)
// $hp is an object containing the values of the form in mod.html
// i.e. all the fields in the 'hotpot' table, plus the following:
-// $hp->course : an id in the 'course' table
-// $hp->coursemodule : an id in the 'course_modules' table
-// $hp->section : an id in the 'course_sections' table
-// $hp->module : an id in the 'modules' table
-// $hp->modulename : always 'hotpot'
-// $hp->instance : an id in the 'hotpot' table
-// $hp->mode : 'add' or 'update'
-// $hp->sesskey : unique string required for Moodle's session management
+// $hp->course : an id in the 'course' table
+// $hp->coursemodule : an id in the 'course_modules' table
+// $hp->section : an id in the 'course_sections' table
+// $hp->module : an id in the 'modules' table
+// $hp->modulename : always 'hotpot'
+// $hp->instance : an id in the 'hotpot' table
+// $hp->mode : 'add' or 'update'
+// $hp->sesskey : unique string required for Moodle's session management
function hotpot_add_instance(&$hp) {
if (hotpot_set_form_values($hp)) {
@@ -1255,9 +1255,9 @@ class hotpot_xml_tree {
if (empty($str)) {
$this->xml = array();
} else {
- if (empty($CFG->unicodedb)) {
- $str = utf8_encode($str);
- }
+ if (empty($CFG->unicodedb)) {
+ $str = utf8_encode($str);
+ }
$this->xml = xmlize($str, 0);
}
$this->xml_root = $xml_root;
@@ -1268,9 +1268,9 @@ class hotpot_xml_tree {
eval('$value = &$this->xml'.$this->xml_root.$tags.$more_tags.';');
if (is_string($value)) {
- if (empty($CFG->unicodedb)) {
- $value = utf8_decode($value);
- }
+ if (empty($CFG->unicodedb)) {
+ $value = utf8_decode($value);
+ }
// decode angle brackets
$value = strtr($value, array('<'=>'<', '>'=>'>', '&'=>'&'));
@@ -1296,7 +1296,7 @@ class hotpot_xml_tree {
// encode unicode characters as HTML entities
// (in particular, accented charaters that have not been encoded by HP)
- // unicode characetsr can be detected by checking the hex value of a character
+ // 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
@@ -1306,20 +1306,6 @@ class hotpot_xml_tree {
// 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);
-
- // NOTICE
- // ======
- // the following lines have been removed because
- // the final "preg_replace" takes several SECONDS to run
-
- // encode any orphaned angle brackets back to html entities
- //if (empty($this->tag_pattern)) {
- // $q = "'"; // single quote
- // $qq = '"'; // double quote
- // $this->tag_pattern = '<(([^>'.$q.$qq.']*)|('."{$q}[^$q]*$q".')|('."{$qq}[^$qq]*$qq".'))*>';
- //}
- //$value = preg_replace('/<([^>]*'.$this->tag_pattern.')/', '<$1', $value);
- //$value = preg_replace('/('.$this->tag_pattern.'[^<]*)>/', '$1>', $value);
}
return $value;
}
@@ -1389,9 +1375,9 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
$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
+ // 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');
@@ -1664,10 +1650,10 @@ class hotpot_xml_quiz extends hotpot_xml_tree {
$filepath = "$Q\.($filetype)";
// pattern to match tags which contain the file path
- // wmp : url
+ // wmp : url
// quicktime : src
// realplayer : src
- // flash : movie (doesn't need replacing)
+ // flash : movie (doesn't need replacing)
$param_url = "//is";
// pattern to match tags which link to multimedia files (not swf)
@@ -2176,7 +2162,7 @@ if (!function_exists('html_entity_decode')) {
// required for Moodle 1.x
if (!isset($CFG->pixpath)) {
- $CFG->pixpath = "$CFG->wwwroot/pix";
+ $CFG->pixpath = "$CFG->wwwroot/pix";
}
if (!defined('PARAM_RAW')) define('PARAM_RAW', 0x0000);
diff --git a/mod/hotpot/report/click/report.php b/mod/hotpot/report/click/report.php
index c7d3944cbed..2bbc4163d74 100644
--- a/mod/hotpot/report/click/report.php
+++ b/mod/hotpot/report/click/report.php
@@ -1,539 +1,540 @@
-create_clickreport_table($hotpot, $cm, $course, $users, $attempts, $questions, $options, $tables=array());
- // print the table
- $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 && (isteacher($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) {
- // get exercise details (course name, section number, activity number, quiztype and question count)
- $record = get_record("course_sections", "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;
- $records = get_records_sql_menu("
- SELECT userid, MAX(time) AS logintime
- FROM {$CFG->prefix}log
- WHERE userid=$attempt->userid AND action='login' AND time<$attempt->timestart
- GROUP BY userid
- ");
- if (empty($records)) {
- $logindate = $blank;
- $logintime = $blank;
- } else {
- $logintime = $records[$attempt->userid];
- $logindate = trim(userdate($logintime, $strftimedate));
- $logintime = trim(userdate($logintime, $strftimetime));
- }
- $records = get_records_sql_menu("
- SELECT userid, MIN(time) AS logouttime
- FROM {$CFG->prefix}log
- WHERE userid=$attempt->userid AND action='logout' AND time>$attempt->cr_timefinish
- GROUP BY userid
- ");
- 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
-?>
+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 && (isteacher($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) {
+ // get exercise details (course name, section number, activity number, quiztype and question count)
+ $record = get_record("course_sections", "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;
+ $records = get_records_sql_menu("
+ SELECT userid, MAX(time) AS logintime
+ FROM {$CFG->prefix}log
+ WHERE userid=$attempt->userid AND action='login' AND time<$attempt->timestart
+ GROUP BY userid
+ ");
+ if (empty($records)) {
+ $logindate = $blank;
+ $logintime = $blank;
+ } else {
+ $logintime = $records[$attempt->userid];
+ $logindate = trim(userdate($logintime, $strftimedate));
+ $logintime = trim(userdate($logintime, $strftimetime));
+ }
+ $records = get_records_sql_menu("
+ SELECT userid, MIN(time) AS logouttime
+ FROM {$CFG->prefix}log
+ WHERE userid=$attempt->userid AND action='logout' AND time>$attempt->cr_timefinish
+ GROUP BY userid
+ ");
+ 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/overview/report.php b/mod/hotpot/report/overview/report.php
index f98b0a35b03..f34c1475980 100644
--- a/mod/hotpot/report/overview/report.php
+++ b/mod/hotpot/report/overview/report.php
@@ -1,167 +1,169 @@
-create_overview_table($hotpot, $cm, $course, $users, $attempts, $questions, $options, $tables=array());
- $this->print_report($course, $hotpot, $tables, $options);
- return true;
- }
- function create_overview_table(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options, &$tables) {
- global $CFG;
- $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) {
- $picture = print_user_picture($u->userid, $course->id, $u->picture, false, true);
- $name = ''.$name.'';
- }
- $grade = isset($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) && (isteacher($course->id) || $hotpot->review)) {
- $attemptnumber = ''.$attemptnumber.'';
- $starttime = ''.$starttime.'';
- }
- if ($is_html && isteacher($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' && isteacher($course->id)) {
- $strdeletecheck = get_string('deleteattemptcheck','quiz');
- $table->start = $this->deleteform_javascript();
- $table->start .= ''."\n";
- }
- $tables[] = &$table;
- }
- function deleteform_javascript() {
- $strselectattempt = addslashes(get_string('selectattempt','hotpot'));
- return <<
-
-
-END_OF_JAVASCRIPT
-;
- } // end function
-} // end class
-?>
+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;
+ $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) {
+ $picture = print_user_picture($u->userid, $course->id, $u->picture, false, true);
+ $name = ''.$name.'';
+ }
+ $grade = isset($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) && (isteacher($course->id) || $hotpot->review)) {
+ $attemptnumber = ''.$attemptnumber.'';
+ $starttime = ''.$starttime.'';
+ }
+ if ($is_html && isteacher($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' && isteacher($course->id)) {
+ $strdeletecheck = get_string('deleteattemptcheck','quiz');
+ $table->start = $this->deleteform_javascript();
+ $table->start .= ''."\n";
+ }
+ $tables[] = &$table;
+ }
+ function deleteform_javascript() {
+ $strselectattempt = addslashes(get_string('selectattempt','hotpot'));
+ return <<
+
+
+END_OF_JAVASCRIPT
+;
+ } // end function
+} // end class
+?>
diff --git a/mod/hotpot/template/v6.php b/mod/hotpot/template/v6.php
index 75d93f75a3b..4863219514e 100644
--- a/mod/hotpot/template/v6.php
+++ b/mod/hotpot/template/v6.php
@@ -411,9 +411,9 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $i;
}
function v6_expand_MatchDivItems() {
- $str = '';
-
- $this->get_jmatch_items($l_items=array(), $r_items = array());
+ $l_items = array();
+ $r_items = array();
+ $this->get_jmatch_items($l_items, $r_items);
$l_keys = $this->shuffle_jmatch_items($l_items);
$r_keys = $this->shuffle_jmatch_items($r_items);
@@ -422,6 +422,8 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
foreach ($r_keys as $key) {
$options .= ''."\n";
}
+
+ $str = '';
foreach ($l_keys as $key) {
$str .= '| '.$l_items[$key]['text'][0]['#'].' | ';
$str .= ' | ';
@@ -693,8 +695,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// specials (JMatch)
function v6_expand_FixedArray() {
+ $l_items = array();
+ $r_items = array();
+ $this->get_jmatch_items($l_items, $r_items);
+
$str = '';
- $this->get_jmatch_items($l_items=array(), $r_items = array());
foreach ($l_items as $i=>$item) {
$str .= "F[$i] = new Array();\n";
$str .= "F[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n";
@@ -703,8 +708,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $str;
}
function v6_expand_DragArray() {
+ $l_items = array();
+ $r_items = array();
+ $this->get_jmatch_items($l_items, $r_items);
+
$str = '';
- $this->get_jmatch_items($l_items=array(), $r_items = array());
foreach ($r_items as $i=>$item) {
$str .= "D[$i] = new Array();\n";
$str .= "D[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n";
@@ -1085,7 +1093,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// jcross6.js_
function v6_expand_LetterArray() {
- $this->v6_get_jcross_grid($row=NULL, $r_max=0, $c_max=0);
+ $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(";
@@ -1097,7 +1109,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $str;
}
function v6_expand_GuessArray() {
- $this->v6_get_jcross_grid($row=NULL, $r_max=0, $c_max=0);
+ $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";
@@ -1105,7 +1121,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $str;
}
function v6_expand_ClueNumArray() {
- $this->v6_get_jcross_grid($row=NULL, $r_max=0, $c_max=0);
+ $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++) {
@@ -1128,7 +1148,11 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $str;
}
function v6_expand_GridBody() {
- $this->v6_get_jcross_grid($row=NULL, $r_max=0, $c_max=0);
+ $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++) {
diff --git a/mod/hotpot/version.php b/mod/hotpot/version.php
index 6cf8232e46a..5e41689c56e 100644
--- a/mod/hotpot/version.php
+++ b/mod/hotpot/version.php
@@ -3,8 +3,8 @@
/// Code fragment to define the version of hotpot
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
/////////////////////////////////////////////////////////////////////////////////
-$module->version = 2005090714; // release date of this version (see note below)
-$module->release = 'v2.1.14'; // human-friendly version name (used in mod/hotpot/lib.php)
+$module->version = 2005090715; // release date of this version (see note below)
+$module->release = 'v2.1.15'; // human-friendly version name (used in mod/hotpot/lib.php)
$module->cron = 0; // period for cron to check this module (secs)
// interpretation of YYYYMMDDXY version numbers
// YYYY : year