mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
changes to database and most scripts to allow enhancements for HotPot v2.1
- click-by-click reporting - manipulate "chains" of hotpot activities - standardized reporting across all quiz types - several smaller features
This commit is contained in:
parent
1c02f70deb
commit
410229b604
@ -1,5 +1,10 @@
|
||||
This is v2.0.8 of the HotPot module
|
||||
It has been tested on Moodle 1.1 thru 1.5, MySQL and PostGres7 databases and PHP 4.1 thru 5.0.4
|
||||
This is v2.1.0 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.5
|
||||
- PHP 4.1 thru 5.0.4
|
||||
- MySQL and PostgreSQL databases
|
||||
|
||||
This module may be distributed under the terms of the General Public License
|
||||
(see http://www.gnu.org/licenses/gpl.txt for details)
|
||||
@ -9,7 +14,7 @@ This is v2.0.8 of the HotPot module
|
||||
================
|
||||
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.
|
||||
* 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 THIS MODULE
|
||||
@ -121,13 +126,13 @@ 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.
|
||||
* 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/
|
||||
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.
|
||||
Martin Holmes, Half-Baked Software and the University of Victoria HCMC, 1998-2004.
|
||||
|
@ -2,8 +2,9 @@
|
||||
require_once("../../config.php");
|
||||
require_once("lib.php");
|
||||
|
||||
$next_url = "";
|
||||
$msg = '';
|
||||
$next_url = "";
|
||||
$quiz_is_finished = true;
|
||||
|
||||
$attemptid = required_param("attemptid");
|
||||
if (is_numeric($attemptid)) {
|
||||
@ -33,50 +34,132 @@
|
||||
// make sure this user is enrolled in this course
|
||||
require_login($course->id);
|
||||
|
||||
if ($attempt->timefinish && false) {
|
||||
$time = time();
|
||||
$msg = get_string('resultssaved', 'hotpot');
|
||||
|
||||
$msg = 'This attempt has already been submitted';
|
||||
// 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;
|
||||
|
||||
if ($attempt->endtime) {
|
||||
$attempt->endtime = strtotime($attempt->endtime);
|
||||
}
|
||||
if ($attempt->starttime) {
|
||||
$attempt->starttime = strtotime($attempt->starttime);
|
||||
}
|
||||
|
||||
// set clickreportid, (for click reporting)
|
||||
$attempt->clickreportid = $attempt->id;
|
||||
|
||||
if (empty($attempt->status)) {
|
||||
if (empty($attempt->endtime)) {
|
||||
$attempt->status = HOTPOT_STATUS_INPROGRESS;
|
||||
} else {
|
||||
$attempt->status = HOTPOT_STATUS_COMPLETED;
|
||||
}
|
||||
}
|
||||
|
||||
// for the rare case where a quiz was "in progress" during an update from hotpot v1 to v2
|
||||
if (empty($attempt->timestart) && !empty($attempt->starttime)) {
|
||||
$attempt->timestart = $attempt->starttime;
|
||||
}
|
||||
|
||||
|
||||
// check if this is the second (or subsequent) click
|
||||
if (get_field("hotpot_attempts", "timefinish", "id", $attempt->id)) {
|
||||
|
||||
if ($hotpot->clickreporting==HOTPOT_YES) {
|
||||
// add attempt record for each form submission
|
||||
// records are linked via the "clickreportid" field
|
||||
|
||||
// update status in previous records in this group
|
||||
set_field("hotpot_attempts", "status", $attempt->status, "clickreportid", $attempt->clickreportid);
|
||||
|
||||
// add new attempt record
|
||||
unset ($attempt->id);
|
||||
$attempt->id = insert_record("hotpot_attempts", $attempt);
|
||||
|
||||
if (empty($attempt->id)) {
|
||||
error("Could not insert attempt record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
|
||||
// add attempt details record, if necessary
|
||||
if (!empty($attempt->details)) {
|
||||
unset($details);
|
||||
$details->attempt = $attempt->id;
|
||||
$details->details = $attempt->details;
|
||||
if (! insert_record("hotpot_details", $details, false)) {
|
||||
error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// remove previous responses for this attempt
|
||||
// (N.B. this does NOT remove the attempt record, just the responses)
|
||||
$ok = delete_records("hotpot_responses", "attempt", $attempt->id);
|
||||
}
|
||||
}
|
||||
|
||||
// remove slashes added by lib/setup.php
|
||||
$attempt->details = stripslashes($attempt->details);
|
||||
|
||||
// add details of this attempt
|
||||
hotpot_add_attempt_details($attempt);
|
||||
|
||||
// add slashes again, so the details can be added to the database
|
||||
$attempt->details = addslashes($attempt->details);
|
||||
|
||||
// update the attempt record
|
||||
if (! update_record("hotpot_attempts", $attempt)) {
|
||||
error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
|
||||
// get previous attempt details record, if any
|
||||
$details_exist = record_exists("hotpot_details", "attempt", $attempt->id);
|
||||
|
||||
// delete/update/add the attempt details record
|
||||
if (empty($attempt->details)) {
|
||||
if ($details_exist) {
|
||||
delete_records("hotpot_details", "attempt", $attempt->id);
|
||||
}
|
||||
} else {
|
||||
$time = time();
|
||||
$msg = get_string('resultssaved', 'hotpot');
|
||||
|
||||
$attempt->score = isset($_POST['mark']) ? $_POST['mark'] : NULL;
|
||||
$attempt->details = isset($_POST['detail']) ? $_POST['detail'] : NULL;
|
||||
$attempt->endtime = isset($_POST['endtime']) ? strtotime($_POST['endtime']) : NULL;
|
||||
$attempt->starttime = isset($_POST['starttime']) ? strtotime($_POST['starttime']) : NULL;
|
||||
$attempt->timefinish = $time;
|
||||
|
||||
// for the rare case where a quiz was "in progress" during an update from hotpot v1 to v2
|
||||
if (empty($attempt->timestart) && !empty($attempt->starttime)) {
|
||||
$attempt->timestart = $attempt->starttime;
|
||||
if ($details_exist) {
|
||||
set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id);
|
||||
} else {
|
||||
unset($details);
|
||||
$details->attempt = $attempt->id;
|
||||
$details->details = $attempt->details;
|
||||
if (! insert_record("hotpot_details", $details)) {
|
||||
error("Could not insert attempt details record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove slashes added by lib/setup.php
|
||||
$attempt->details = stripslashes($attempt->details);
|
||||
if ($attempt->status==HOTPOT_STATUS_INPROGRESS) {
|
||||
$quiz_is_finished = false;
|
||||
|
||||
// add details of this attempt
|
||||
hotpot_add_attempt_details($attempt);
|
||||
|
||||
// add slashes again, so the details can be added to the database
|
||||
$attempt->details = addslashes($attempt->details);
|
||||
|
||||
if (! update_record("hotpot_attempts", $attempt)) {
|
||||
error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
|
||||
// set previously unfinished attempts of this quiz by this user to "finished"
|
||||
hotpot_close_previous_attempts($hotpot->id, $USER->id, $time);
|
||||
} 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 && is_numeric($next_cm = hotpot_get_next_cm($cm))) {
|
||||
$next_url = "$CFG->wwwroot/mod/hotpot/view.php?id=$next_cm";
|
||||
|
||||
if ($hotpot->shownextquiz==HOTPOT_YES && 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, $msg);
|
||||
if ($quiz_is_finished) {
|
||||
// redirect to the next quiz or the course page
|
||||
redirect($next_url, $msg);
|
||||
} else {
|
||||
// continue the quiz
|
||||
header("Status: 204");
|
||||
header("HTTP/1.0 204 No Response");
|
||||
}
|
||||
|
||||
|
||||
// =================
|
||||
|
@ -6,30 +6,27 @@
|
||||
// This is the "graphical" structure of the hotpot mod:
|
||||
//-----------------------------------------------------------
|
||||
//
|
||||
// hotpot
|
||||
// (CL, pk->id, files)
|
||||
// hotpot
|
||||
// (CL, pk->id,
|
||||
// fk->course, files)
|
||||
// |
|
||||
// +--------------+--------------+
|
||||
// | |
|
||||
// | |
|
||||
// hotpot_attempts hotpot_questions
|
||||
// (UL, pk->id, (UL, pk->id,
|
||||
// fk->hotpot) fk->hotpot, text)
|
||||
// | | |
|
||||
// | | |
|
||||
// +--------------+--------------+ |
|
||||
// | |
|
||||
// | |
|
||||
// hotpot_responses |
|
||||
// (UL, pk->id, |
|
||||
// fk->attempt, question, |
|
||||
// correct, wrong, ignored) |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------+-----------+
|
||||
// |
|
||||
// hotpot_strings
|
||||
// (UL, pk->id)
|
||||
// +--------------+---------------+
|
||||
// | |
|
||||
// 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
|
||||
@ -39,38 +36,37 @@
|
||||
// files->table may have files
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
// It is not necessary to backup "questions", "responses"
|
||||
// and "strings", because they can be restored from the
|
||||
// "details" field of the "attempts" records
|
||||
//-----------------------------------------------------------
|
||||
|
||||
function hotpot_backup_mods($bf, $preferences) {
|
||||
// $bf : resource id for b(ackup) f(ile)
|
||||
// $preferences : object containing switches and settings for this backup
|
||||
|
||||
$level = 3;
|
||||
$level = 3;
|
||||
$status = true;
|
||||
|
||||
$table = 'hotpot';
|
||||
$field = 'course';
|
||||
$value = $preferences->backup_course;
|
||||
|
||||
$modtype = 'hotpot';
|
||||
$select = "course=$preferences->backup_course";
|
||||
|
||||
$records_tag = '';
|
||||
$records_tags = array();
|
||||
|
||||
$record_tag = 'MOD';
|
||||
$record_tags = array('MODTYPE'=>$modtype);
|
||||
$record_tags = array('MODTYPE'=>'hotpot');
|
||||
|
||||
$excluded_tags = array();
|
||||
|
||||
$more_backup = '';
|
||||
if ($preferences->mods[$modtype]->userinfo) {
|
||||
$more_backup .= $modtype.'_backup_attempts($bf, $record, $level, $status);';
|
||||
if ($preferences->mods['hotpot']->userinfo) {
|
||||
$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, $field, $value,
|
||||
$table, $select,
|
||||
$records_tag, $records_tags,
|
||||
$record_tag, $record_tags,
|
||||
$excluded_tags, $more_backup
|
||||
@ -80,8 +76,7 @@
|
||||
// $parent is a reference to a hotpot record
|
||||
|
||||
$table = 'hotpot_attempts';
|
||||
$field = 'hotpot';
|
||||
$value = $parent->id;
|
||||
$select = "hotpot=$parent->id";
|
||||
|
||||
$records_tag = 'ATTEMPT_DATA';
|
||||
$records_tags = array();
|
||||
@ -90,25 +85,175 @@
|
||||
$record_tags = array();
|
||||
|
||||
$more_backup = '';
|
||||
$excluded_tags = array();
|
||||
$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, $field, $value,
|
||||
$table, $select,
|
||||
$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
|
||||
|
||||
function hotpot_backup_records(&$bf, $status, $level, $table, $field, $value, $records_tag, $records_tags, $record_tag, $record_tags, $excluded_tags, $more_backup) {
|
||||
$table = 'hotpot_details';
|
||||
$select = "attempt=$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,
|
||||
$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=$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,
|
||||
$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=$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)";
|
||||
|
||||
$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,
|
||||
$records_tag, $records_tags,
|
||||
$record_tag, $record_tags,
|
||||
$excluded_tags, $more_backup
|
||||
);
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
function hotpot_backup_records(&$bf, $status, $level, $table, $select, $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".
|
||||
|
||||
if ($status && ($records = get_records($table, $field, $value, 'id'))) {
|
||||
if ($status && ($records = get_records_select($table, $select, 'id'))) {
|
||||
|
||||
// start a group of records
|
||||
if ($records_tag) {
|
||||
|
@ -15,6 +15,12 @@ function hotpot_upgrade($oldversion) {
|
||||
$ok = $ok && hotpot_update_to_v2_from_v1();
|
||||
}
|
||||
|
||||
// update to HotPot v2.1
|
||||
if ($oldversion < 2005090700) {
|
||||
$ok = $ok && hotpot_get_update_to_v2();
|
||||
$ok = $ok && hotpot_update_to_v2_1();
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_get_update_to_v2() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
CREATE TABLE prefix_hotpot (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
course int(10) unsigned NOT NULL,
|
||||
course int(10) unsigned NOT NULL default '0',
|
||||
name varchar(255) NOT NULL default '',
|
||||
reference varchar(255) NOT NULL default '',
|
||||
summary text NOT NULL,
|
||||
@ -23,6 +23,9 @@ CREATE TABLE prefix_hotpot (
|
||||
forceplugins int(4) unsigned NOT NULL default '0',
|
||||
password varchar(255) NOT NULL default '',
|
||||
subnet varchar(255) NOT NULL default '',
|
||||
clickreporting tinyint(4) unsigned NOT NULL default '0',
|
||||
studentfeedback tinyint(4) unsigned NOT NULL default '0',
|
||||
studentfeedbackurl varchar(255) default NULL,
|
||||
PRIMARY KEY (id)
|
||||
) TYPE=MyISAM COMMENT='details about Hot Potatoes quizzes';
|
||||
|
||||
@ -32,19 +35,33 @@ CREATE TABLE prefix_hotpot (
|
||||
|
||||
CREATE TABLE prefix_hotpot_attempts (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
hotpot int(10) unsigned NOT NULL,
|
||||
userid int(10) unsigned NOT NULL,
|
||||
hotpot int(10) unsigned NOT NULL default '0',
|
||||
userid int(10) unsigned NOT NULL default '0',
|
||||
starttime int(10) unsigned default NULL,
|
||||
endtime int(10) unsigned default NULL,
|
||||
score int(6) unsigned default NULL,
|
||||
penalties int(6) unsigned default NULL,
|
||||
attempt int(6) unsigned NOT NULL default '0',
|
||||
details text,
|
||||
timestart int(10) unsigned default NULL,
|
||||
timefinish int(10) unsigned default NULL,
|
||||
PRIMARY KEY (id)
|
||||
status tinyint(4) unsigned NOT NULL default '1',
|
||||
clickreportid int(10) unsigned default NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY prefix_hotpot_attempts_hotpot_idx (hotpot),
|
||||
KEY prefix_hotpot_attempts_userid_idx (userid)
|
||||
) TYPE=MyISAM COMMENT='details about Hot Potatoes quiz attempts';
|
||||
|
||||
#
|
||||
# Table structure for table `hotpot_details`
|
||||
#
|
||||
|
||||
CREATE TABLE prefix_hotpot_details (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
attempt int(10) unsigned NOT NULL,
|
||||
details text,
|
||||
PRIMARY KEY (id),
|
||||
KEY prefix_hotpot_details_attempt_idx (attempt)
|
||||
) TYPE=MyISAM COMMENT='raw details (as XML) of Hot Potatoes quiz attempts';
|
||||
|
||||
#
|
||||
# Table structure for table `hotpot_questions`
|
||||
@ -52,22 +69,23 @@ CREATE TABLE prefix_hotpot_attempts (
|
||||
|
||||
CREATE TABLE prefix_hotpot_questions (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
name varchar(255) NOT NULL default '',
|
||||
type int(10) unsigned NOT NULL default '0',
|
||||
text text,
|
||||
name text NOT NULL,
|
||||
type tinyint(4) unsigned default NULL,
|
||||
text int(10) unsigned default NULL,
|
||||
hotpot int(10) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (id)
|
||||
PRIMARY KEY (id),
|
||||
KEY prefix_hotpot_questions_name_idx (name(20)),
|
||||
KEY prefix_hotpot_questions_hotpot_idx (hotpot)
|
||||
) TYPE=MyISAM COMMENT='details about questions in Hot Potatatoes quiz attempts';
|
||||
|
||||
|
||||
#
|
||||
# Table structure for table `hotpot_responses`
|
||||
#
|
||||
|
||||
CREATE TABLE prefix_hotpot_responses (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
attempt int(10) unsigned NOT NULL,
|
||||
question int(10) unsigned NOT NULL,
|
||||
attempt int(10) unsigned NOT NULL default '0',
|
||||
question int(10) unsigned NOT NULL default '0',
|
||||
score smallint(8) default NULL,
|
||||
weighting smallint(8) default NULL,
|
||||
correct varchar(255) default NULL,
|
||||
@ -76,7 +94,9 @@ CREATE TABLE prefix_hotpot_responses (
|
||||
hints smallint(6) default NULL,
|
||||
clues smallint(6) default NULL,
|
||||
checks smallint(6) default NULL,
|
||||
PRIMARY KEY (id)
|
||||
PRIMARY KEY (id),
|
||||
KEY prefix_hotpot_responses_attempt_idx (attempt),
|
||||
KEY prefix_hotpot_responses_question_idx (question)
|
||||
) TYPE=MyISAM COMMENT='details about responses in Hot Potatatoes quiz attempts';
|
||||
|
||||
#
|
||||
@ -86,6 +106,7 @@ CREATE TABLE prefix_hotpot_responses (
|
||||
CREATE TABLE prefix_hotpot_strings (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
string text NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
PRIMARY KEY (id),
|
||||
KEY prefix_hotpot_strings_string_idx (string(20))
|
||||
) TYPE=MyISAM COMMENT='strings used in Hot Potatatoes questions and responses';
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?PHP
|
||||
|
||||
function hotpot_upgrade($oldversion) {
|
||||
global $CFG;
|
||||
|
||||
$ok = true;
|
||||
|
||||
// update from HotPot v1 to HotPot v2
|
||||
@ -9,7 +11,11 @@ function hotpot_upgrade($oldversion) {
|
||||
$ok = $ok && hotpot_update_to_v2_from_v1();
|
||||
}
|
||||
|
||||
|
||||
// update to HotPot v2.1
|
||||
if ($oldversion < 2005090700) {
|
||||
$ok = $ok && hotpot_get_update_to_v2();
|
||||
$ok = $ok && hotpot_update_to_v2_1();
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_get_update_to_v2() {
|
||||
|
@ -4,26 +4,32 @@
|
||||
|
||||
CREATE TABLE prefix_hotpot (
|
||||
id SERIAL PRIMARY KEY,
|
||||
course INT4 NOT NULL default '0',
|
||||
name VARCHAR(255) NOT NULL default '',
|
||||
summary TEXT,
|
||||
timeopen INT4 NOT NULL default '0',
|
||||
timeclose INT4 NOT NULL default '0',
|
||||
location INT2 NOT NULL default '0',
|
||||
reference VARCHAR(255) NOT NULL default '',
|
||||
grade INT4 NOT NULL default '0',
|
||||
grademethod INT2 NOT NULL default '1',
|
||||
attempts INT2 NOT NULL default '0',
|
||||
review INT2 NOT NULL default '0',
|
||||
navigation INT2 NOT NULL default '1',
|
||||
outputformat INT2 NOT NULL default '1',
|
||||
shownextquiz INT2 NOT NULL default '0',
|
||||
forceplugins INT2 NOT NULL default '0',
|
||||
password VARCHAR(255) NOT NULL default '',
|
||||
subnet VARCHAR(255) NOT NULL default '',
|
||||
timecreated INT4 NOT NULL default '0',
|
||||
timemodified INT4 NOT NULL default '0'
|
||||
course INT4 NOT NULL default '0',
|
||||
name VARCHAR(255) NOT NULL default '',
|
||||
summary TEXT,
|
||||
timeopen INT4 NOT NULL default '0',
|
||||
timeclose INT4 NOT NULL default '0',
|
||||
location INT2 NOT NULL default '0',
|
||||
reference VARCHAR(255) NOT NULL default '',
|
||||
navigation INT2 NOT NULL default '1',
|
||||
outputformat INT2 NOT NULL default '1',
|
||||
forceplugins INT2 NOT NULL default '0',
|
||||
shownextquiz INT2 NOT NULL default '0',
|
||||
microreporting INT2 NOT NULL default '0',
|
||||
studentfeedback VARCHAR(255) NOT NULL default '0',
|
||||
|
||||
review INT2 NOT NULL default '0',
|
||||
grade INT4 NOT NULL default '0',
|
||||
grademethod INT2 NOT NULL default '1',
|
||||
attempts INT2 NOT NULL default '0',
|
||||
|
||||
password VARCHAR(255) NOT NULL default '',
|
||||
subnet VARCHAR(255) NOT NULL default '',
|
||||
timecreated INT4 NOT NULL default '0',
|
||||
timemodified INT4 NOT NULL default '0'
|
||||
);
|
||||
COMMENT ON TABLE prefix_hotpot IS 'details about Hot Potatoes quizzes';
|
||||
|
||||
|
||||
#
|
||||
# Table structure for table `hotpot_attempts`
|
||||
@ -31,32 +37,49 @@ CREATE TABLE prefix_hotpot (
|
||||
|
||||
CREATE TABLE prefix_hotpot_attempts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
hotpot INT4 NOT NULL default '0',
|
||||
userid INT4 NOT NULL default '0',
|
||||
attempt INT2 NOT NULL default '0',
|
||||
score INT2,
|
||||
penalties INT2,
|
||||
details TEXT,
|
||||
starttime INT4,
|
||||
endtime INT4,
|
||||
timestart INT4 NOT NULL default '0',
|
||||
timefinish INT4 NOT NULL default '0'
|
||||
hotpot INT4 NOT NULL default '0',
|
||||
userid INT4 NOT NULL default '0',
|
||||
groupid INT4 NOT NULL default '0',
|
||||
attempt INT2 NOT NULL default '0',
|
||||
score INT2,
|
||||
penalties INT2,
|
||||
starttime INT4,
|
||||
endtime INT4,
|
||||
timestart INT4 NOT NULL default '0',
|
||||
timefinish INT4 NOT NULL default '0',
|
||||
status INT2 NOT NULL default '1',
|
||||
microreportid INT4
|
||||
);
|
||||
COMMENT ON TABLE prefix_hotpot IS 'details about Hot Potatoes quiz attempts';
|
||||
CREATE INDEX prefix_hotpot_attempts_hotpot_idx ON prefix_hotpot_attempts (hotpot);
|
||||
CREATE INDEX prefix_hotpot_attempts_userid_idx ON prefix_hotpot_attempts (userid);
|
||||
|
||||
|
||||
#
|
||||
# Table structure for table `prefix_hotpot_details`
|
||||
#
|
||||
|
||||
CREATE TABLE prefix_hotpot_details (
|
||||
id SERIAL PRIMARY KEY,
|
||||
attempt INT4 NOT NULL default '0',
|
||||
details TEXT
|
||||
);
|
||||
COMMENT ON TABLE prefix_hotpot_details IS 'raw details (as XML) of Hot Potatoes quiz attempts';
|
||||
CREATE INDEX prefix_hotpot_details_attempt_idx ON prefix_hotpot_details (attempt);
|
||||
|
||||
|
||||
#
|
||||
# Table structure for table `hotpot_questions`
|
||||
#
|
||||
|
||||
CREATE TABLE prefix_hotpot_questions (
|
||||
id SERIAL PRIMARY KEY,
|
||||
hotpot INT4 NOT NULL default '0',
|
||||
name VARCHAR(255) NOT NULL default '',
|
||||
name TEXT,
|
||||
type INT2 NOT NULL default '0',
|
||||
text TEXT
|
||||
text INT4 NULL,
|
||||
hotpot INT4 NOT NULL default '0'
|
||||
);
|
||||
COMMENT ON TABLE prefix_hotpot_questions IS 'details about questions in Hot Potatatoes quiz attempts';
|
||||
CREATE INDEX prefix_hotpot_questions_hotpot_idx ON prefix_hotpot_questions (hotpot);
|
||||
|
||||
#
|
||||
@ -76,6 +99,7 @@ CREATE TABLE prefix_hotpot_responses (
|
||||
clues INT2,
|
||||
checks INT2
|
||||
);
|
||||
COMMENT ON TABLE prefix_hotpot_responses IS 'details about responses in Hot Potatatoes quiz attempts';
|
||||
CREATE INDEX prefix_hotpot_responses_attempt_idx ON prefix_hotpot_responses (attempt);
|
||||
CREATE INDEX prefix_hotpot_responses_question_idx ON prefix_hotpot_responses (question);
|
||||
|
||||
@ -87,4 +111,4 @@ CREATE TABLE prefix_hotpot_strings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
string TEXT NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON TABLE prefix_hotpot_strings IS 'strings used in Hot Potatatoes questions and responses';
|
||||
|
@ -1,5 +1,124 @@
|
||||
<?PHP
|
||||
|
||||
function hotpot_update_to_v2_1() {
|
||||
global $CFG, $db;
|
||||
$ok = true;
|
||||
|
||||
// hotpot_questions: reduce size of "type" field to "4"
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'type', 'type', 'INTEGER', 4, 'UNSIGNED', 'NULL');
|
||||
|
||||
// hotpot_questions: change type of "name" field to "text"
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'name', 'name', 'TEXT', '', '', 'NOT NULL', '');
|
||||
|
||||
// hotpot_questions: nullify empty and non-numeric (shouldn't be any) values in "text" field
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
$NOT_REGEXP = 'NOT REGEXP';
|
||||
break;
|
||||
case 'postgres7' :
|
||||
$NOT_REGEXP = '!~';
|
||||
break;
|
||||
default:
|
||||
$NOT_REGEXP = '';
|
||||
break;
|
||||
}
|
||||
if ($NOT_REGEXP) {
|
||||
$ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_questions SET text=NULL WHERE text $NOT_REGEXP '^[0-9]+$'");
|
||||
}
|
||||
|
||||
// hotpot_questions: change type of "text" field to "INT(10)"
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot_questions', 'text', 'text', 'INTEGER', 10, 'UNSIGNED', 'NULL');
|
||||
|
||||
// hotpot_attempts
|
||||
|
||||
// hotpot_attempts: create and set status field (1=in-progress, 2=timed-out, 3=abandoned, 4=completed)
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'status', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 1);
|
||||
$ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=1 WHERE timefinish=0 AND SCORE IS NULL");
|
||||
$ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=3 WHERE timefinish>0 AND SCORE IS NULL");
|
||||
$ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=4 WHERE timefinish>0 AND SCORE IS NOT NULL");
|
||||
|
||||
// hotpot_attempts: create and set clickreport fields
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot', '', 'clickreporting', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', 0);
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot_attempts', '', 'clickreportid', 'INTEGER', 10, 'UNSIGNED', 'NULL');
|
||||
$ok = $ok && execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET clickreportid=id WHERE clickreportid IS NULL");
|
||||
|
||||
// hotpot_attempts: create and set studentfeedback field (0=none, 1=formmail, 2=moodleforum, 3=moodlemessaging)
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedback', 'INTEGER', 4, 'UNSIGNED', 'NOT NULL', '0');
|
||||
$ok = $ok && hotpot_db_update_field_type('hotpot', '', 'studentfeedbackurl', 'VARCHAR', 255, '', 'NULL');
|
||||
|
||||
// hotpot_attempts: move "details" to separate table
|
||||
$table = 'hotpot_details';
|
||||
if (hotpot_db_table_exists($table)) {
|
||||
// do nothing
|
||||
} else {
|
||||
$ok = $ok && hotpot_create_table($table);
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
case 'postgres7' :
|
||||
$sql = "
|
||||
INSERT INTO {$CFG->prefix}$table (attempt, details)
|
||||
SELECT a.id AS attempt, a.details AS details
|
||||
FROM {$CFG->prefix}hotpot_attempts AS a
|
||||
WHERE
|
||||
a.details IS NOT NULL AND a.details <> ''
|
||||
AND a.details LIKE '<?xml%' AND a.details LIKE '%</hpjsresult>'
|
||||
";
|
||||
break;
|
||||
default:
|
||||
$sql = '';
|
||||
break;
|
||||
}
|
||||
if ($sql) {
|
||||
$ok = $ok && execute_sql($sql);
|
||||
}
|
||||
}
|
||||
|
||||
// hotpot_attempts: remove the "details" field
|
||||
$ok = $ok && hotpot_db_remove_field('hotpot_attempts', 'details');
|
||||
|
||||
// add indexes
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_attempts', 'hotpot');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_attempts', 'userid');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_details', 'attempt');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_questions', 'name', 20);
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_questions', 'hotpot');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_responses', 'attempt');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_responses', 'question');
|
||||
$ok = $ok && hotpot_db_add_index('hotpot_strings', 'string', 20);
|
||||
|
||||
// hotpot_string: correct double-encoded HTML entities
|
||||
$ok = $ok && execute_sql("
|
||||
UPDATE {$CFG->prefix}hotpot_strings
|
||||
SET string = REPLACE(string, '&','&')
|
||||
WHERE string LIKE '%&#%'
|
||||
AND (string LIKE '<' OR string LIKE '>')
|
||||
");
|
||||
|
||||
// hotpot_question: remove questions which refer to deleted hotpots
|
||||
if ($ok) {
|
||||
// try and get all hotpot records
|
||||
if ($records = get_records('hotpot')) {
|
||||
$ids = implode(',', array_keys($records));
|
||||
$sql = "DELETE FROM {$CFG->prefix}hotpot_questions WHERE hotpot NOT IN ($ids)";
|
||||
} else {
|
||||
// remove all question records (because there are no valid hotpot ids)
|
||||
$sql = "TRUNCATE {$CFG->prefix}hotpot_questions";
|
||||
}
|
||||
print "Removing unused question records ...";
|
||||
execute_sql($sql);
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
// remove old 'v6' templates folder (replaced by 'template' folder)
|
||||
$ds = DIRECTORY_SEPARATOR;
|
||||
$dir = "mod{$ds}hotpot{$ds}v6";
|
||||
print "removing old templates ($dir) ... ";
|
||||
$ok = hotpot_rm("$CFG->dirroot{$ds}$dir", false);
|
||||
print $ok ? get_string('success') : 'failed';
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_update_to_v2_from_v1() {
|
||||
global $CFG;
|
||||
$ok = true;
|
||||
@ -609,6 +728,104 @@ function hotpot_update_print_warning($field, $value, $table, $id) {
|
||||
// database functions
|
||||
///////////////////////////
|
||||
|
||||
function hotpot_db_index_exists($table, $index, $feedback=false) {
|
||||
global $CFG, $db;
|
||||
$exists = false;
|
||||
|
||||
// save and switch off SQL message echo
|
||||
$debug = $db->debug;
|
||||
$db->debug = $feedback;
|
||||
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
$rs = $db->Execute("SHOW INDEX FROM `$table`");
|
||||
if ($rs && $rs->RecordCount()>0) {
|
||||
$records = $rs->GetArray();
|
||||
foreach ($records as $record) {
|
||||
if (isset($record['Key_name']) && $record['Key_name']==$index) {
|
||||
$exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'postgres7' :
|
||||
$rs = $db->Execute("SELECT relname FROM pg_class WHERE relname = '$index' AND relkind='i'");
|
||||
if ($rs && $rs->RecordCount()>0) {
|
||||
$exists = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// restore SQL message echo
|
||||
$db->debug = $debug;
|
||||
|
||||
return $exists;
|
||||
}
|
||||
function hotpot_db_delete_index($table, $index, $feedback=false) {
|
||||
global $CFG, $db;
|
||||
$ok = true;
|
||||
|
||||
// check index exists
|
||||
if (hotpot_db_index_exists($table, $index)) {
|
||||
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
$sql = "ALTER TABLE `$table` DROP INDEX `$index`";
|
||||
break;
|
||||
|
||||
case 'postgres7' :
|
||||
$sql = "DROP INDEX $index";
|
||||
break;
|
||||
|
||||
default: // unknown database type
|
||||
$sql = '';
|
||||
break;
|
||||
}
|
||||
if ($sql) {
|
||||
// save and switch off SQL message echo
|
||||
$debug = $db->debug;
|
||||
$db->debug = $feedback;
|
||||
|
||||
$ok = $db->Execute($sql) ? true : false;
|
||||
|
||||
// restore SQL message echo
|
||||
$db->debug = $debug;
|
||||
|
||||
} else { // unknown database type
|
||||
$ok = false;
|
||||
}
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_db_add_index($table, $field, $length='') {
|
||||
global $CFG, $db;
|
||||
|
||||
// expand $table and $index names
|
||||
$table = "{$CFG->prefix}$table";
|
||||
$index = "{$table}_{$field}_idx";
|
||||
|
||||
// delete $index if it already exists
|
||||
$ok = hotpot_db_delete_index($table, $index);
|
||||
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
$length = empty($length) ? '' : " ($length)";
|
||||
$ok = $ok && $db->Execute("ALTER TABLE `$table` ADD INDEX `$index` (`$field`$length)");
|
||||
break;
|
||||
|
||||
case 'postgres7' :
|
||||
$ok = $ok && $db->Execute("CREATE INDEX $index ON $table ($field)");
|
||||
break;
|
||||
|
||||
default: // unknown database type
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_db_table_exists($table, $feedback=false) {
|
||||
return hotpot_db_object_exists($table, '', $feedback);
|
||||
}
|
||||
@ -766,7 +983,7 @@ function hotpot_db_update_field_type($table, $oldfield, $field, $type, $size, $u
|
||||
}
|
||||
if (empty($oldfield) && hotpot_db_field_exists($table, $field)) {
|
||||
$oldfield = $field;
|
||||
}
|
||||
}
|
||||
if (is_string($unsigned)) {
|
||||
$unsigned = (strtoupper($unsigned)=='UNSIGNED');
|
||||
}
|
||||
@ -901,7 +1118,7 @@ function hotpot_db_update_field_type($table, $oldfield, $field, $type, $size, $u
|
||||
|
||||
// transfer $oldfield values, if necessary
|
||||
if ( $oldfield != '""' ) {
|
||||
execute_sql("UPDATE $table SET $tmpfield = $oldfield");
|
||||
execute_sql("UPDATE $table SET $tmpfield = CAST ($oldfield AS $fieldtype)");
|
||||
execute_sql("ALTER TABLE $table DROP COLUMN $oldfield");
|
||||
}
|
||||
|
||||
@ -963,5 +1180,39 @@ function hotpot_db_update_record($table, $record, $forcenull=false) {
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
function hotpot_rm($target, $output=true) {
|
||||
$ok = true;
|
||||
if (!empty($target)) {
|
||||
if (is_file($target)) {
|
||||
if ($output) {
|
||||
print "removing file: $target ... ";
|
||||
}
|
||||
$ok = @unlink($target);
|
||||
|
||||
} else if (is_dir($target)) {
|
||||
$dir = dir($target);
|
||||
while(false !== ($entry = $dir->read())) {
|
||||
if ($entry!='.' && $entry!='..') {
|
||||
$ok = $ok && hotpot_rm($target.DIRECTORY_SEPARATOR.$entry, $output);
|
||||
}
|
||||
}
|
||||
$dir->close();
|
||||
if ($output) {
|
||||
print "removing folder: $target ... ";
|
||||
}
|
||||
$ok = $ok && @rmdir($target);
|
||||
|
||||
} else { // not a file or directory (probably doesn't exist)
|
||||
$output = false;
|
||||
}
|
||||
if ($output) {
|
||||
if ($ok) {
|
||||
print '<font color="green">OK</font><br>';
|
||||
} else {
|
||||
print '<font color="red">Failed</font><br>';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
?>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
// This page lists all the instances of hotpot in a particular course
|
||||
|
||||
require_once("../../config.php");
|
||||
require_once("../../course/lib.php");
|
||||
require_once("lib.php");
|
||||
|
||||
$id = required_param("id"); // course
|
||||
@ -15,11 +16,22 @@
|
||||
|
||||
add_to_log($course->id, "hotpot", "view all", "index.php?id=$course->id", "");
|
||||
|
||||
// Print the header
|
||||
// Moodle 1.4+ requires sesskey to be passed in forms
|
||||
if (isset($USER->sesskey)) {
|
||||
$sesskey = '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
|
||||
} else {
|
||||
$sesskey = '';
|
||||
}
|
||||
|
||||
// get message strings for titles
|
||||
$strmodulenameplural = get_string("modulenameplural", "hotpot");
|
||||
$strmodulename = get_string("modulename", "hotpot");
|
||||
|
||||
// string translation array for single and double quotes
|
||||
$quotes = array("'"=>"\'", '"'=>'"');
|
||||
|
||||
// Print the header
|
||||
|
||||
$title = "$course->shortname: $strmodulenameplural";
|
||||
$heading = "$course->fullname";
|
||||
$navigation = "$strmodulenameplural";
|
||||
@ -30,89 +42,235 @@
|
||||
|
||||
$next_url = "$CFG->wwwroot/course/view.php?id=$course->id";
|
||||
|
||||
// Get all instances of this module
|
||||
if (! $hotpots = get_all_instances_in_course("hotpot", $course)) {
|
||||
notice("There are no $strmodulenameplural", $next_url);
|
||||
die;
|
||||
// get display section, if any
|
||||
$section = optional_param('section', 0);
|
||||
if ($section) {
|
||||
$displaysection = course_set_display($course->id, $section);
|
||||
} else {
|
||||
if (isset($USER->display[$course->id])) {
|
||||
$displaysection = $USER->display[$course->id];
|
||||
} else {
|
||||
$displaysection = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all instances of this module
|
||||
if (!$hotpots = hotpot_get_all_instances_in_course("hotpot", $course)) {
|
||||
$hotpots = array();
|
||||
}
|
||||
|
||||
|
||||
if (isadmin()) {
|
||||
if (isset($_POST['regrade'])) {
|
||||
$hotpotids = array();
|
||||
foreach ($hotpots as $hotpot) {
|
||||
$hotpotids[] = $hotpot->id;
|
||||
}
|
||||
$hotpotids = implode(',', $hotpotids);
|
||||
|
||||
$select = "hotpot IN ($hotpotids)";
|
||||
|
||||
$questionids = array();
|
||||
if ($questions = get_records_select("hotpot_questions", $select)) {
|
||||
$questionids = array_keys($questions);
|
||||
}
|
||||
$questionids = implode(',', $questionids);
|
||||
|
||||
if ($questionids) {
|
||||
hotpot_delete_and_notify(
|
||||
'hotpot_questions',
|
||||
"id IN ($questionids)",
|
||||
get_string('question', 'quiz')
|
||||
);
|
||||
hotpot_delete_and_notify(
|
||||
'hotpot_responses',
|
||||
"question IN ($questionids)",
|
||||
get_string('answer', 'quiz')
|
||||
);
|
||||
}
|
||||
|
||||
if ($attempts = get_records_select('hotpot_attempts', $select)) {
|
||||
$count = 0;
|
||||
foreach ($attempts as $attempt) {
|
||||
if (isset($attempt->score)) {
|
||||
hotpot_add_attempt_details($attempt);
|
||||
$attempt->details = addslashes($attempt->details);
|
||||
if (! update_record('hotpot_attempts', $attempt)) {
|
||||
error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
$count++;
|
||||
if ($count%10 == 0) {
|
||||
print ".";
|
||||
if ($count%200 == 0) {
|
||||
print "<br>\n";
|
||||
}
|
||||
hotpot_flush(300);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($count) {
|
||||
notify(get_string('added', 'moodle', "$count x ".get_string('attempts', 'quiz')));
|
||||
}
|
||||
notify(get_string('regradecomplete', 'quiz'));
|
||||
// if necessary, remove hotpots that are not in section0 or this $USER's display section
|
||||
if ($displaysection) {
|
||||
foreach ($hotpots as $cmid=>$hotpot) {
|
||||
if ($hotpot->section!=0 && $hotpot->section!=$displaysection) {
|
||||
unset($hotpots[$cmid]);
|
||||
}
|
||||
}
|
||||
print '<center><form action="'.$ME.'" method="post">';
|
||||
print '<input type="hidden" name="id" value="'.$course->id.'">';
|
||||
print '<input type="submit" name="regrade" value="'.get_string('regrade', 'quiz').'">';
|
||||
print '</form></center>'."\n";
|
||||
}
|
||||
|
||||
// Print the list of instances of this module
|
||||
if (empty($hotpots)) {
|
||||
notice("There are no $strmodulenameplural", $next_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$timenow = time();
|
||||
$strupdate = get_string("update");
|
||||
$strusers = get_string("users");
|
||||
// get list of hotpot ids
|
||||
$hotpotids = array();
|
||||
foreach ($hotpots as $cmid=>$hotpot) {
|
||||
$hotpotids[] = $hotpot->id;
|
||||
}
|
||||
$hotpotids = implode(',', $hotpotids);
|
||||
|
||||
// Moodle 1.4+ requires sesskey to be passed in forms
|
||||
if (isset($USER->sesskey)) {
|
||||
$sesskey = '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
|
||||
if (isadmin()) {
|
||||
|
||||
// get regrade settings, if any
|
||||
$regrade = optional_param("regrade");
|
||||
$confirm = optional_param("confirm");
|
||||
|
||||
// check regrade is valid
|
||||
unset($regrade_cmid);
|
||||
if (isset($regrade)) {
|
||||
foreach ($hotpots as $cmid=>$hotpot) {
|
||||
$found = false;
|
||||
if ($hotpot->id==$regrade) {
|
||||
$regrade_cmid = $cmid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// regrade, if necessary
|
||||
if (isset($regrade_cmid)) {
|
||||
|
||||
if (empty($confirm)) {
|
||||
|
||||
$strregradecheck = get_string('regradecheck', 'hotpot', $hotpots[$regrade_cmid]->name);
|
||||
|
||||
print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
|
||||
print_heading($strregradecheck);
|
||||
print ''
|
||||
. '<table border="0"><tr><td>'
|
||||
. '<form target="_parent" method="post" action="'.$ME.'">'
|
||||
. '<input type="hidden" name="id" value="'.$course->id.'">'
|
||||
. '<input type="hidden" name="regrade" value="'.$regrade.'" />'
|
||||
. '<input type="hidden" name="confirm" value="1" />'
|
||||
. $sesskey
|
||||
. '<input type="submit" value="'.get_string("yes").'" />'
|
||||
. '</form>'
|
||||
. '</td><td> </td><td>'
|
||||
. '<form target="_parent" method="post" action="'.$ME.'">'
|
||||
. '<input type="hidden" name="id" value="'.$course->id.'">'
|
||||
. $sesskey
|
||||
. '<input type="submit" value="'.get_string("no").'" />'
|
||||
. '</form>'
|
||||
. '</td></tr></table>'
|
||||
;
|
||||
print_simple_box_end();
|
||||
print_footer($course);
|
||||
exit;
|
||||
|
||||
} else { // regrade has been confirmed, so proceed
|
||||
|
||||
if ($regrade=='all') {
|
||||
$select = "hotpot IN ($hotpotids)";
|
||||
} else {
|
||||
$select = "hotpot=$regrade";
|
||||
}
|
||||
|
||||
$questionids = array();
|
||||
if ($questions = get_records_select("hotpot_questions", $select)) {
|
||||
$questionids = array_keys($questions);
|
||||
}
|
||||
$questionids = implode(',', $questionids);
|
||||
|
||||
if ($questionids) {
|
||||
hotpot_delete_and_notify('hotpot_questions', "id IN ($questionids)", get_string('question', 'quiz'));
|
||||
hotpot_delete_and_notify('hotpot_responses', "question IN ($questionids)", get_string('answer', 'quiz'));
|
||||
}
|
||||
|
||||
if ($attempts = get_records_select('hotpot_attempts', $select)) {
|
||||
|
||||
// start counter and timer
|
||||
$count = 0;
|
||||
$start = microtime();
|
||||
foreach ($attempts as $attempt) {
|
||||
$attempt->details = get_field('hotpot_details', 'details', 'attempt', "$attempt->id");
|
||||
if ($attempt->details) {
|
||||
hotpot_add_attempt_details($attempt);
|
||||
if (! update_record('hotpot_attempts', $attempt)) {
|
||||
error("Could not update attempt record: ".$db->ErrorMsg(), $next_url);
|
||||
}
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
if ($count) {
|
||||
notify(get_string('added', 'moodle', "$count x ".get_string('attempts', 'quiz')));
|
||||
}
|
||||
$msg = get_string('regradecomplete', 'quiz');
|
||||
if (!empty($CFG->hotpot_showtimes)) {
|
||||
$duration = format_time(sprintf("%0.2f", microtime_diff($start, microtime())));
|
||||
$msg .= " ($duration)";
|
||||
}
|
||||
notify($msg);
|
||||
}
|
||||
}
|
||||
} // end regrade
|
||||
|
||||
//print '<center><form action="'.$ME.'" method="post">';
|
||||
//print '<input type="hidden" name="id" value="'.$course->id.'">';
|
||||
//print '<input type="submit" name="regrade" value="'.get_string('regrade', 'quiz').'">';
|
||||
//print '</form></center>'."\n";
|
||||
|
||||
|
||||
// get duplicate hotpot-name questions
|
||||
// - JMatch LHS is longer than 255 bytes
|
||||
// - JQuiz question text is longer than 255 bytes
|
||||
// - other unidentified situations ?!?
|
||||
|
||||
$field = '';
|
||||
$questions = false;
|
||||
$regradehotpots = array();
|
||||
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql' :
|
||||
$field = "CONCAT(hotpot, '_', name)";
|
||||
break;
|
||||
case 'postgres7' :
|
||||
$field = "hotpot||'_'||name";
|
||||
break;
|
||||
}
|
||||
if ($field) {
|
||||
$questions = get_records_sql("
|
||||
SELECT $field, COUNT(*), hotpot, name
|
||||
FROM {$CFG->prefix}hotpot_questions
|
||||
WHERE hotpot IN ($hotpotids)
|
||||
GROUP BY hotpot, name
|
||||
HAVING COUNT(*) >1
|
||||
");
|
||||
}
|
||||
if ($questions) {
|
||||
foreach ($questions as $question) {
|
||||
$regradehotpots[] = $question->hotpot;
|
||||
}
|
||||
$regradehotpots = array_unique($regradehotpots);
|
||||
sort($regradehotpots);
|
||||
}
|
||||
}
|
||||
|
||||
// start timer
|
||||
$start = microtime();
|
||||
|
||||
// get total number of attempts, users and details for these hotpots
|
||||
$tables = "{$CFG->prefix}hotpot_attempts AS a";
|
||||
$fields = "
|
||||
a.hotpot AS hotpot,
|
||||
COUNT(DISTINCT a.clickreportid) AS attemptcount,
|
||||
COUNT(DISTINCT a.userid) AS usercount,
|
||||
MAX(a.score) AS maxscore
|
||||
";
|
||||
$select = "a.hotpot IN ($hotpotids)";
|
||||
if (isteacher($course->id)) {
|
||||
// do nothing (=get all users)
|
||||
} else {
|
||||
$sesskey = '';
|
||||
// restrict results to this user only
|
||||
$select .= " AND a.userid='$USER->id'";
|
||||
}
|
||||
$usejoin = 1;
|
||||
if (isadmin() && $usejoin) {
|
||||
// join attempts table and details table
|
||||
$tables .= ",{$CFG->prefix}hotpot_details AS d";
|
||||
$fields .= ',COUNT(DISTINCT d.id) AS detailcount';
|
||||
$select .= " AND a.id=d.attempt";
|
||||
|
||||
// this may take about twice as long as getting the gradecounts separately :-(
|
||||
// so this operation could be done after getting the $totals from the attempts table
|
||||
}
|
||||
$totals = get_records_sql("SELECT $fields FROM $tables WHERE $select GROUP BY a.hotpot");
|
||||
|
||||
if (isadmin() && empty($usejoin)) {
|
||||
foreach ($hotpots as $hotpot) {
|
||||
$totals[$hotpot->id]->detailcount = 0;
|
||||
if ($ids = get_records('hotpot_attempts', 'hotpot', $hotpot->id)) {
|
||||
$ids = join(',', array_keys($ids));
|
||||
$totals[$hotpot->id]->detailcount = count_records_select('hotpot_details', "attempt IN ($ids)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// message strings for main table
|
||||
$strusers = get_string('users');
|
||||
$strupdate = get_string('update');
|
||||
$strregrade = get_string('regrade', 'hotpot');
|
||||
$strneverclosed = get_string('neverclosed', 'hotpot');
|
||||
$strregraderequired = get_string('regraderequired', 'hotpot');
|
||||
|
||||
// column headings and attributes
|
||||
$table->head = array();
|
||||
$table->align = array();
|
||||
|
||||
if (!empty($CFG->hotpot_showtimes)) {
|
||||
print '<H3>'.sprintf("%0.3f", microtime_diff($start, microtime())).' secs'."</H3>\n";
|
||||
}
|
||||
|
||||
switch ($course->format) {
|
||||
case 'weeks' :
|
||||
$title = get_string("week");
|
||||
@ -138,17 +296,33 @@
|
||||
get_string("bestgrade", "quiz"),
|
||||
get_string("attempts", "quiz")
|
||||
);
|
||||
array_push($table->align, "left", "left", "center", "left");
|
||||
array_push($table->align,
|
||||
"left", "left", "center", "left"
|
||||
);
|
||||
if (isadmin()) {
|
||||
array_push($table->head, $strregrade);
|
||||
array_push($table->align, "center");
|
||||
}
|
||||
|
||||
$currentsection = "";
|
||||
$currentsection = -1;
|
||||
foreach ($hotpots as $hotpot) {
|
||||
|
||||
$printsection = "";
|
||||
if ($hotpot->section !== $currentsection) {
|
||||
if ($hotpot->section != $currentsection) {
|
||||
if ($hotpot->section) {
|
||||
$printsection = $hotpot->section;
|
||||
if ($course->format=='weeks' || $course->format=='topics') {
|
||||
// Show the zoom boxes
|
||||
if ($displaysection==$hotpot->section) {
|
||||
$strshowall = get_string('showall'.$course->format);
|
||||
$printsection .= '<br /><a href="index.php?id='.$course->id.'§ion=all" title="'.$strshowall.'"><img src="'.$CFG->pixpath.'/i/all.gif" height=25 width=16 border=0></a><br />';
|
||||
} else {
|
||||
$strshowone = get_string('showonly'.preg_replace('|s$|', '', $course->format, 1), '', $hotpot->section);
|
||||
$printsection .= '<br /><a href="index.php?id='.$course->id.'§ion='.$hotpot->section.'" title="'.$strshowone.'"><img src="'.$CFG->pixpath.'/i/one.gif" height=16 width=16 border=0></a><br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($currentsection !== "") {
|
||||
if ($currentsection>=0) {
|
||||
$table->data[] = 'hr';
|
||||
}
|
||||
$currentsection = $hotpot->section;
|
||||
@ -156,34 +330,33 @@
|
||||
|
||||
$class = ($hotpot->visible) ? '' : 'class="dimmed" ';
|
||||
$quizname = '<A '.$class.'href="view.php?id='.$hotpot->coursemodule.'">'.$hotpot->name.'</A>';
|
||||
$quizclose = userdate($hotpot->timeclose);
|
||||
$quizclose = empty($hotpot->timeclose) ? $strneverclosed : userdate($hotpot->timeclose);
|
||||
|
||||
$select = isteacher($course->id) ? '' : "userid='$USER->id' AND ";
|
||||
$select .= "hotpot='$hotpot->id' AND timefinish>0";
|
||||
// are there any totals for this hotpot?
|
||||
if (empty($totals[$hotpot->id]->attemptcount)) {
|
||||
$report = " ";
|
||||
$bestscore = " ";
|
||||
|
||||
$attempttable = "{$CFG->prefix}hotpot_attempts";
|
||||
|
||||
// get number of attempts. if any
|
||||
if ($attemptcount = count_records_sql("SELECT COUNT(*) FROM $attempttable WHERE $select")) {
|
||||
|
||||
// report number of attempts (and users)
|
||||
$report = get_string("viewallreports","quiz", $attemptcount);
|
||||
} else {
|
||||
// report number of attempts and users
|
||||
$report = get_string("viewallreports","quiz", $totals[$hotpot->id]->attemptcount);
|
||||
if (isteacher($course->id)) {
|
||||
$usercount = count_records_sql("SELECT COUNT(DISTINCT userid) FROM $attempttable WHERE $select");
|
||||
$report .= " ($usercount $strusers)";
|
||||
$report .= " (".$totals[$hotpot->id]->usercount." $strusers)";
|
||||
}
|
||||
$report = '<a href="report.php?hp='.$hotpot->id.'">'.$report.'</a>';
|
||||
|
||||
// get best score
|
||||
$bestscore = count_records_sql("SELECT MAX(score) FROM $attempttable WHERE $select");
|
||||
if (is_numeric($bestscore)) {
|
||||
$bestscore .= " / $hotpot->grade";
|
||||
if (is_numeric($totals[$hotpot->id]->maxscore)) {
|
||||
$bestscore = $totals[$hotpot->id]->maxscore." / $hotpot->grade";
|
||||
} else {
|
||||
$bestscore = " ";
|
||||
}
|
||||
} else { // no attempts
|
||||
$report = " ";
|
||||
$bestscore = " ";
|
||||
}
|
||||
|
||||
if (isadmin()) {
|
||||
if (in_array($hotpot->id, $regradehotpots)) {
|
||||
$report .= ' <FONT color="red">'.$strregraderequired.'</FONT>';
|
||||
}
|
||||
}
|
||||
|
||||
$data = array ();
|
||||
@ -193,16 +366,37 @@
|
||||
}
|
||||
|
||||
if (isteacheredit($course->id)) {
|
||||
$update = ''
|
||||
. '<form target="_parent" method="get" action="'.$CFG->wwwroot.'/course/mod.php">'
|
||||
$updatebutton = ''
|
||||
. '<form target="'.$CFG->framename.'" method="get" action="'.$CFG->wwwroot.'/course/mod.php">'
|
||||
. '<input type="hidden" name="update" value="'.$hotpot->coursemodule.'" />'
|
||||
. $sesskey
|
||||
. '<input type="submit" value="'.$strupdate.'" />'
|
||||
. '</form>'
|
||||
;
|
||||
array_push($data, $update);
|
||||
array_push($data, $updatebutton);
|
||||
}
|
||||
|
||||
array_push($data, $quizname, $quizclose, $bestscore, $report);
|
||||
|
||||
if (isadmin()) {
|
||||
if (empty($totals[$hotpot->id]->detailcount)) {
|
||||
// no details records for this hotpot, so disable regrade
|
||||
$regradebutton = ' ';
|
||||
} else {
|
||||
$strregradecheck = get_string('regradecheck', 'hotpot', strtr($hotpot->name, $quotes));
|
||||
$regradebutton = ''
|
||||
. '<form target="_parent" method="post" action="'.$ME.'" onsubmit="var x=window.confirm('."'$strregradecheck'".');this.confirm.value=x;return x;">'
|
||||
. '<input type="hidden" name="id" value="'.$course->id.'">'
|
||||
. '<input type="hidden" name="regrade" value="'.$hotpot->id.'" />'
|
||||
. '<input type="hidden" name="confirm" value="" />'
|
||||
. $sesskey
|
||||
. '<input type="submit" value="'.$strregrade.'" />'
|
||||
. '</form>'
|
||||
;
|
||||
}
|
||||
array_push($data, $regradebutton);
|
||||
}
|
||||
|
||||
$table->data[] = $data;
|
||||
}
|
||||
|
||||
@ -211,20 +405,5 @@
|
||||
print_table($table);
|
||||
|
||||
// Finish the page
|
||||
print_footer($course);
|
||||
|
||||
///////////////////
|
||||
// functions
|
||||
|
||||
function hotpot_flush($n=0, $time=false) {
|
||||
if ($time) {
|
||||
$ti = strftime("%X",time());
|
||||
} else {
|
||||
$ti = "";
|
||||
}
|
||||
echo str_repeat(" ", $n) . $ti . "\n";
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
print_footer($course);
|
||||
?>
|
||||
|
3026
mod/hotpot/lib.php
3026
mod/hotpot/lib.php
File diff suppressed because it is too large
Load Diff
@ -2,9 +2,9 @@
|
||||
<!-- It is used from /course/mod.php.The whole instance is available as $form. -->
|
||||
|
||||
<?php
|
||||
require_once(
|
||||
$CFG->dirroot.DIRECTORY_SEPARATOR.'mod'.DIRECTORY_SEPARATOR.'hotpot'.DIRECTORY_SEPARATOR.'lib.php'
|
||||
);
|
||||
|
||||
$ds = DIRECTORY_SEPARATOR;
|
||||
require_once("$CFG->dirroot{$ds}mod{$ds}hotpot{$ds}lib.php");
|
||||
|
||||
// set default values in form fields, if necessary
|
||||
set_form_fields($form);
|
||||
@ -14,22 +14,34 @@ $yes_no_options = array(
|
||||
HOTPOT_NO => get_string("no"),
|
||||
HOTPOT_YES => get_string("yes")
|
||||
);
|
||||
|
||||
$text_source_options = 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")
|
||||
);
|
||||
?>
|
||||
<CENTER>
|
||||
<FORM name="form" method="post" action="<?php echo $ME ?>">
|
||||
<FORM name="form" method="post" action="mod.php">
|
||||
<TABLE cellpadding="5">
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("name") ?>:</B></TD>
|
||||
<TD align="left">
|
||||
<INPUT type="text" name="name" size=40 value="<?php p($form->name) ?>">
|
||||
</TD>
|
||||
<TD align="left"><?php
|
||||
if ($form->mode=='add') {
|
||||
choose_from_menu($text_source_options, "namesource", "$form->namesource", "");
|
||||
} else {
|
||||
print '<INPUT type="hidden" name="namesource" value="'.HOTPOT_TEXTSOURCE_SPECIFIC.'">';
|
||||
}
|
||||
print '<SPAN id="nameSPAN">';
|
||||
print '<INPUT type="text" name="name" size=40 value="'.$form->name.'">';
|
||||
print '</SPAN>';
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right">
|
||||
<B><?php
|
||||
print_string("summary")
|
||||
?>:</B>
|
||||
?>:</B><BR>
|
||||
<FONT size="1"><?php
|
||||
helpbutton("summary", get_string("summary"), "resource", true, true);
|
||||
echo '<BR />';
|
||||
@ -43,40 +55,63 @@ $yes_no_options = array(
|
||||
echo '<BR />';
|
||||
emoticonhelpbutton("form", "description");
|
||||
echo '<BR />';
|
||||
}
|
||||
}
|
||||
?></FONT>
|
||||
</TD>
|
||||
<TD align="left"><?php
|
||||
if ($form->mode=='add') {
|
||||
choose_from_menu($text_source_options, "summarysource", "$form->summarysource", "");
|
||||
} else {
|
||||
print '<INPUT type="hidden" name="summarysource" value="'.HOTPOT_TEXTSOURCE_SPECIFIC.'">';
|
||||
}
|
||||
print '<SPAN id="summarySPAN">';
|
||||
if (function_exists("print_textarea") && isset($usehtmleditor)) {
|
||||
print_textarea($usehtmleditor, 10, 65, 680, 400, "summary", $form->summary);
|
||||
} else {
|
||||
// Moodle 1.1.1 (original size was rows="5" cols="50")
|
||||
print '<TEXTAREA name="summary" rows="10" cols="65" wrap="virtual">'.$form->summary.'</TEXTAREA>';
|
||||
}
|
||||
print '</SPAN>';
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("quizopen", "quiz") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
if (!$form->timeopen and $course->format == "weeks") {
|
||||
$options = array(
|
||||
HOTPOT_NO => get_string("alwaysopen", "hotpot"),
|
||||
HOTPOT_YES => get_string("specifictime", "hotpot")
|
||||
);
|
||||
choose_from_menu($options, "enabletimeopen", "$form->enabletimeopen", "");
|
||||
print '<SPAN id="timeopenSPAN">';
|
||||
print ' ';
|
||||
if (!$form->timeopen && $course->format == "weeks") {
|
||||
$form->timeopen= $course->startdate + (($form->section - 1) * 608400);
|
||||
}
|
||||
print_date_selector("openday", "openmonth", "openyear", $form->timeopen);
|
||||
print ' - ';
|
||||
print_time_selector("openhour", "openminute", $form->timeopen);
|
||||
helpbutton("timeopen", get_string("quizopen","quiz"), "quiz");
|
||||
print '</SPAN>';
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("quizclose", "quiz") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
if (!$form->timeclose and $course->format == "weeks") {
|
||||
$options = array(
|
||||
HOTPOT_NO => get_string("neverclosed", "hotpot"),
|
||||
HOTPOT_YES => get_string("specifictime", "hotpot")
|
||||
);
|
||||
choose_from_menu($options, "enabletimeclose", "$form->enabletimeclose", "");
|
||||
print '<SPAN id="timecloseSPAN">';
|
||||
print ' ';
|
||||
if (!$form->timeclose && $course->format == "weeks") {
|
||||
$form->timeclose= $course->startdate + (($form->section) * 608400);
|
||||
}
|
||||
print_date_selector("closeday", "closemonth", "closeyear", $form->timeclose);
|
||||
print ' - ';
|
||||
print_time_selector("closehour", "closeminute", $form->timeclose);
|
||||
helpbutton("timeopen", get_string("quizclose","quiz"), "quiz");
|
||||
print '</SPAN>';
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
@ -154,10 +189,13 @@ $yes_no_options = array(
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("navigation", "hotpot") ?>:</B></TD>
|
||||
<TD align="right"><B><?php
|
||||
$quizchain = "{$form->mode}quizchain";
|
||||
print_string($quizchain, "hotpot");
|
||||
?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
choose_from_menu($HOTPOT_NAVIGATION, "navigation", "$form->navigation", "");
|
||||
helpbutton("navigation", get_string("navigation","hotpot"), "hotpot");
|
||||
choose_from_menu($yes_no_options, "quizchain", $form->quizchain, "");
|
||||
helpbutton($quizchain, get_string($quizchain,"hotpot"), "hotpot");
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
@ -167,6 +205,21 @@ $yes_no_options = array(
|
||||
helpbutton("outputformat", get_string("outputformat","hotpot"), "hotpot");
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("navigation", "hotpot") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
choose_from_menu($HOTPOT_NAVIGATION, "navigation", "$form->navigation", "");
|
||||
helpbutton("navigation", get_string("navigation","hotpot"), "hotpot");
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("studentfeedback", "hotpot") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
choose_from_menu($HOTPOT_FEEDBACK, "studentfeedback", "$form->studentfeedback", "");
|
||||
print "<input name=\"studentfeedbackurl\" size=\"50\" value=\"$form->studentfeedbackurl\">";
|
||||
helpbutton("studentfeedback", get_string("studentfeedback","hotpot"), "hotpot");
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("forceplugins", "hotpot") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
@ -236,6 +289,31 @@ $yes_no_options = array(
|
||||
<?php helpbutton("requiresubnet", get_string("requiresubnet", "quiz"), "quiz"); ?>
|
||||
</TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"><B><?php print_string("clickreporting", "hotpot") ?>:</B></TD>
|
||||
<TD align="left"><?php
|
||||
choose_from_menu($yes_no_options, "clickreporting", "$form->clickreporting", "");
|
||||
helpbutton("clickreporting", get_string("clickreporting","hotpot"), "hotpot");
|
||||
?></TD>
|
||||
</TR>
|
||||
<TR valign="top">
|
||||
<TD align="right"> </TD>
|
||||
<TD align="left">
|
||||
<!-- buttons -->
|
||||
<INPUT type="submit" value="<?php print_string("savechanges") ?>">
|
||||
<INPUT type="submit" name="cancel" value="<?php print_string("cancel") ?>" /><BR />
|
||||
<?php
|
||||
if (isset($CFG->release) && substr($CFG->release, 0, 3)>=1.5) {
|
||||
$options = array(
|
||||
HOTPOT_DISPLAYNEXT_QUIZ => get_string("displayhotpotnext", "hotpot"),
|
||||
HOTPOT_DISPLAYNEXT_COURSE => get_string("displaycoursenext", "hotpot"),
|
||||
HOTPOT_DISPLAYNEXT_INDEX => get_string("displayindexnext", "hotpot")
|
||||
);
|
||||
choose_from_menu($options, "displaynext", "$form->displaynext", "");
|
||||
} else {
|
||||
print '<INPUT type="hidden" name="displaynext" value="'.HOTPOT_NO.'">'."\n";
|
||||
}
|
||||
?>
|
||||
</TABLE>
|
||||
|
||||
<!-- hidden fields -->
|
||||
@ -249,13 +327,85 @@ $yes_no_options = array(
|
||||
<?php if (isset($USER->sesskey)) { ?>
|
||||
<INPUT type="hidden" name="sesskey" value="<?php p($USER->sesskey) ?>">
|
||||
<?php } ?>
|
||||
|
||||
<!-- buttons -->
|
||||
<INPUT type="submit" value="<?php print_string("savechanges") ?>">
|
||||
<INPUT type="submit" name="cancel" value="<?php print_string("cancel") ?>" />
|
||||
|
||||
|
||||
</FORM>
|
||||
</CENTER>
|
||||
|
||||
<SCRIPT type="" language="">
|
||||
<!--
|
||||
function hpShowHideStudentFeedbackUrl() {
|
||||
var frm = document.forms['form'];
|
||||
if (frm) {
|
||||
var obj = frm.elements['studentfeedback'];
|
||||
var url = frm.elements['studentfeedbackurl'];
|
||||
if (obj && obj.type=='select-one' && url && url.style) {
|
||||
if (obj.onchange==null) {
|
||||
obj.onchange = hpShowHideStudentFeedbackUrl;
|
||||
}
|
||||
var v = obj.options[obj.selectedIndex].value;
|
||||
url.style.display = (v==1 || v==2) ? 'inline' : 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
hpShowHideStudentFeedbackUrl();
|
||||
|
||||
function hpShowHideTime(s) {
|
||||
var frm = document.forms['form'];
|
||||
if (frm) {
|
||||
var obj = frm.elements['enabletime'+s];
|
||||
if (obj && obj.type=='select-one' && document.getElementById) {
|
||||
if (obj.onchange==null) {
|
||||
obj.onchange = new Function("hpShowHideTime('"+s+"')");
|
||||
}
|
||||
var v = obj.options[obj.selectedIndex].value;
|
||||
var obj = document.getElementById('time'+s+'SPAN');
|
||||
if (obj && obj.style) {
|
||||
obj.style.display = (v==0) ? 'none' : 'inline';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
hpShowHideTime('open');
|
||||
hpShowHideTime('close');
|
||||
|
||||
function hpShowHideTextSource(s) {
|
||||
var frm = document.forms['form'];
|
||||
if (frm) {
|
||||
var obj = frm.elements[s+'source'];
|
||||
if (obj && obj.type=='select-one' && document.getElementById) {
|
||||
if (obj.onchange==null) {
|
||||
obj.onchange = new Function("hpShowHideTextSource('"+s+"')");
|
||||
}
|
||||
var v = obj.options[obj.selectedIndex].value;
|
||||
var obj = document.getElementById(s+'SPAN');
|
||||
if (obj && obj.style) {
|
||||
obj.style.display = (v==0 || v==1 || v==2) ? 'none' : 'inline';
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
hpShowHideTextSource('name');
|
||||
//hpShowHideTextSource('summary');
|
||||
|
||||
// override the standard Moodle "setfocus" function,
|
||||
// which gives a js error if the "name" field is hidden
|
||||
function setfocus() {
|
||||
var f = document.form;
|
||||
if (f) {
|
||||
if (canfocus(f, 'namesource')) {
|
||||
f.namesource.focus();
|
||||
} else if (canfocus(f, 'name')) {
|
||||
f.name.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
function canfocus(f, name) {
|
||||
var obj = eval('f.'+name);
|
||||
return (obj==null || obj.type=='hidden' || obj.focus==null || (obj.style && obj.style.display=='none')) ? false : true;
|
||||
}
|
||||
//-->
|
||||
</SCRIPT>
|
||||
<?php
|
||||
|
||||
// ======================
|
||||
@ -265,20 +415,34 @@ $yes_no_options = array(
|
||||
function set_form_fields(&$form) {
|
||||
set_form_field($form, 'name');
|
||||
set_form_field($form, 'summary');
|
||||
set_form_field($form, 'timeopen');
|
||||
set_form_field($form, 'timeclose');
|
||||
set_form_field($form, 'timeopen', get_user_preferences('hotpot_timeopen', 0));
|
||||
set_form_field($form, 'enabletimeopen', empty($form->timeopen) ? HOTPOT_NO : HOTPOT_YES);
|
||||
set_form_field($form, 'timeclose', get_user_preferences('hotpot_timeclose', 0));
|
||||
set_form_field($form, 'enabletimeclose', empty($form->timeclose) ? HOTPOT_NO : HOTPOT_YES);
|
||||
set_form_field($form, 'location', HOTPOT_LOCATION_COURSEFILES);
|
||||
set_form_field($form, 'reference');
|
||||
set_form_field($form, 'navigation', HOTPOT_NAVIGATION_BAR);
|
||||
set_form_field($form, 'outputformat', HOTPOT_OUTPUTFORMAT_BEST);
|
||||
set_form_field($form, 'forceplugins', HOTPOT_NO);
|
||||
set_form_field($form, 'shownextquiz', HOTPOT_NO);
|
||||
set_form_field($form, 'review', HOTPOT_YES);
|
||||
set_form_field($form, 'grade', 100);
|
||||
set_form_field($form, 'grademethod', HOTPOT_GRADEMETHOD_HIGHEST);
|
||||
set_form_field($form, 'attempts', 0); // unlimited
|
||||
set_form_field($form, 'navigation', get_user_preferences('hotpot_navigation', HOTPOT_NAVIGATION_BAR));
|
||||
set_form_field($form, 'outputformat', get_user_preferences('hotpot_outputformat', HOTPOT_OUTPUTFORMAT_BEST));
|
||||
set_form_field($form, 'studentfeedback', get_user_preferences('hotpot_studentfeedback', HOTPOT_FEEDBACK_NONE));
|
||||
set_form_field($form, 'studentfeedbackurl', get_user_preferences('hotpot_studentfeedbackurl', 'http://'));
|
||||
set_form_field($form, 'forceplugins', get_user_preferences('hotpot_forceplugins', HOTPOT_NO));
|
||||
if ($form->mode=='add') {
|
||||
set_form_field($form, 'namesource', get_user_preferences('hotpot_namesource', HOTPOT_TEXTSOURCE_QUIZ));
|
||||
set_form_field($form, 'summarysource', get_user_preferences('hotpot_summarysource', HOTPOT_TEXTSOURCE_QUIZ));
|
||||
$quizchain = get_user_preferences('hotpot_quizchain', HOTPOT_NO);
|
||||
} else {
|
||||
$quizchain = empty($form->quizchain) ? HOTPOT_NO : HOTPOT_YES;
|
||||
}
|
||||
set_form_field($form, 'quizchain', $quizchain);
|
||||
set_form_field($form, 'shownextquiz', get_user_preferences('hotpot_shownextquiz', HOTPOT_NO));
|
||||
set_form_field($form, 'review', get_user_preferences('hotpot_review', HOTPOT_YES));
|
||||
set_form_field($form, 'grade', get_user_preferences('hotpot_grade', 100));
|
||||
set_form_field($form, 'grademethod', get_user_preferences('hotpot_grademethod', HOTPOT_GRADEMETHOD_HIGHEST));
|
||||
set_form_field($form, 'attempts', get_user_preferences('hotpot_attempts', 0)); // 0=unlimited
|
||||
set_form_field($form, 'password');
|
||||
set_form_field($form, 'subnet');
|
||||
set_form_field($form, 'subnet', get_user_preferences('hotpot_subnet'));
|
||||
set_form_field($form, 'clickreporting', HOTPOT_NO);
|
||||
set_form_field($form, 'displaynext', get_user_preferences('hotpot_displaynext', HOTPOT_DISPLAYNEXT_QUIZ));
|
||||
}
|
||||
function set_form_field(&$form, $fieldname, $defaultvalue='') {
|
||||
if (!isset($form->$fieldname)) {
|
||||
|
@ -38,40 +38,37 @@
|
||||
|
||||
// get report mode
|
||||
if (isteacher($course->id)) {
|
||||
$mode = optional_param("mode", "overview", 0);
|
||||
if (is_array($mode)) {
|
||||
$mode = array_keys($mode);
|
||||
$mode = $mode[0];
|
||||
}
|
||||
$mode = optional_param("mode", "overview");
|
||||
} else {
|
||||
// students have no choice
|
||||
$mode = 'overview';
|
||||
}
|
||||
|
||||
// assemble array of form data
|
||||
$formdata = array(
|
||||
'mode' => $mode,
|
||||
'reportcourse' => isadmin() ? optional_param('reportcourse', get_user_preferences('hotpot_reportcourse', 'this')) : 'this',
|
||||
'reportusers' => isteacher($course->id) ? optional_param('reportusers', get_user_preferences('hotpot_reportusers', 'all')) : 'this',
|
||||
'reportattempts' => optional_param('reportattempts', get_user_preferences('hotpot_reportattempts', 'all')),
|
||||
'reportformat' => optional_param('reportformat', 'htm'),
|
||||
'reportshowlegend' => optional_param('reportshowlegend', get_user_preferences('hotpot_reportshowlegend', '0')),
|
||||
'reportencoding' => optional_param('reportencoding', get_user_preferences('hotpot_reportencoding', '')),
|
||||
'reportwrapdata' => optional_param('reportwrapdata', get_user_preferences('hotpot_reportwrapdata', '1')),
|
||||
);
|
||||
|
||||
// get report attributes
|
||||
if (isadmin()) {
|
||||
$reportcourse = optional_param("reportcourse", "this");
|
||||
} else {
|
||||
// students and ordinary teachers have no choice
|
||||
$reportcourse = 'this';
|
||||
foreach ($formdata as $name=>$value) {
|
||||
set_user_preference("hotpot_$name", $value);
|
||||
}
|
||||
if (isteacher($course->id)) {
|
||||
$reportusers = optional_param("reportusers", "all");
|
||||
} else {
|
||||
// students have no choice
|
||||
$reportusers = 'this';
|
||||
}
|
||||
$reportattempts = optional_param("reportattempts", "all");
|
||||
|
||||
/// Start the report
|
||||
|
||||
add_to_log($course->id, "hotpot", "report", "report.php?id=$cm->id", "$hotpot->id", "$cm->id");
|
||||
add_to_log($course->id, "hotpot", "report", "report.php?id=$cm->id&mode=$mode", "$hotpot->id", "$cm->id");
|
||||
|
||||
// print page header. if required
|
||||
if (empty($noheader)) {
|
||||
if ($formdata['reportformat']=='htm') {
|
||||
hotpot_print_report_heading($course, $cm, $hotpot, $mode);
|
||||
if (isteacher($course->id)) {
|
||||
hotpot_print_report_selector($course, $hotpot, $mode, $reportcourse, $reportusers, $reportattempts);
|
||||
hotpot_print_report_selector($course, $hotpot, $formdata);
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +80,7 @@
|
||||
|
||||
$hotpot_ids = '';
|
||||
$course_ids = '';
|
||||
switch ($reportcourse) {
|
||||
switch ($formdata['reportcourse']) {
|
||||
case 'this':
|
||||
$course_ids = $course->id;
|
||||
$hotpot_ids = $hotpot->id;
|
||||
@ -99,7 +96,7 @@
|
||||
|
||||
$user_ids = '';
|
||||
$users = array();
|
||||
switch ($reportusers) {
|
||||
switch ($formdata['reportusers']) {
|
||||
case 'all':
|
||||
$admin_ids = get_records_select_menu('user_admins');
|
||||
if (is_array($admin_ids)) {
|
||||
@ -122,7 +119,9 @@
|
||||
if (is_array($student_ids)) {
|
||||
$users = array_merge($users, $student_ids);
|
||||
}
|
||||
$user_ids = join(',', array_values($users));
|
||||
$user_ids = array_values($users);
|
||||
sort($user_ids);
|
||||
$user_ids = join(',', array_unique($user_ids));
|
||||
break;
|
||||
case 'this':
|
||||
$user_ids = $USER->id;
|
||||
@ -134,18 +133,79 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
// get attempts for these users
|
||||
$fields = 'a.*, u.firstname, u.lastname, u.picture';
|
||||
$table = "{$CFG->prefix}hotpot_attempts AS a, {$CFG->prefix}user AS u";
|
||||
$select = ($mode=='simplestat' || $mode=='fullstat') ? 'a.score IS NOT NULL' : 'a.timefinish>0';
|
||||
$select .= " AND a.hotpot IN ($hotpot_ids) AND a.userid IN ($user_ids) AND a.userid = u.id";
|
||||
$order = "u.lastname, a.attempt";
|
||||
if ($reportattempts=='best') {
|
||||
$fields .= ", MAX(a.score) AS grade";
|
||||
$select .= " GROUP BY a.userid";
|
||||
// database table and selection conditions
|
||||
$table = "{$CFG->prefix}hotpot_attempts AS a";
|
||||
$select = "a.hotpot IN ($hotpot_ids) AND a.userid IN ($user_ids)";
|
||||
if ($mode!='overview') {
|
||||
$select .= ' AND a.status<>'.HOTPOT_STATUS_INPROGRESS;
|
||||
}
|
||||
$attempts = get_records_sql("SELECT $fields FROM $table WHERE $select ORDER BY $order");
|
||||
|
||||
// confine attempts if necessary
|
||||
switch ($formdata['reportattempts']) {
|
||||
case 'best':
|
||||
$function = 'MAX';
|
||||
$fieldnames = array('score', 'id', 'clickreportid');
|
||||
break;
|
||||
case 'first':
|
||||
$function = 'MIN';
|
||||
$fieldnames = array('timestart', 'id', 'clickreportid');
|
||||
break;
|
||||
case 'last':
|
||||
$function = 'MAX';
|
||||
$fieldnames = array('timestart', 'id', 'clickreportid');
|
||||
break;
|
||||
default: // 'all' and any others
|
||||
$function = '';
|
||||
$fieldnames = array();
|
||||
break;
|
||||
}
|
||||
if (empty($function) || empty($fieldnames)) {
|
||||
// do nothing (i.e. get ALL attempts)
|
||||
} else {
|
||||
$groupby = 'userid';
|
||||
$records = hotpot_get_records_groupby($function, $fieldnames, $table, $select, $groupby);
|
||||
|
||||
$ids = array();
|
||||
foreach ($records as $record) {
|
||||
$ids[] = $record->clickreportid;
|
||||
}
|
||||
$select = "a.clickreportid IN (".join(',', $ids).")";
|
||||
}
|
||||
|
||||
// pick out last attempt in each clickreport series
|
||||
$cr_attempts = hotpot_get_records_groupby('MAX', array('timefinish', 'id'), $table, $select, 'clickreportid');
|
||||
|
||||
$fields = 'a.*, u.firstname, u.lastname, u.picture';
|
||||
if ($mode=='click') {
|
||||
$fields .= ', u.idnumber';
|
||||
} else {
|
||||
// overview, simple and detailed reports
|
||||
// get last attempt record in clickreport series
|
||||
$ids = array();
|
||||
foreach ($cr_attempts as $cr_attempt) {
|
||||
$ids[] = $cr_attempt->id;
|
||||
}
|
||||
if (empty($ids)) {
|
||||
$select = "";
|
||||
} else {
|
||||
$ids = array_unique($ids);
|
||||
sort($ids);
|
||||
$select = "a.id IN (".join(',', $ids).")";
|
||||
}
|
||||
}
|
||||
|
||||
$attempts = array();
|
||||
|
||||
if ($select) {
|
||||
// add user information to SQL query
|
||||
$select .= ' AND a.userid = u.id';
|
||||
$table .= ", {$CFG->prefix}user AS u";
|
||||
$order = "u.lastname, a.attempt, a.timefinish";
|
||||
// get the attempts (at last!)
|
||||
$attempts = get_records_sql("SELECT $fields FROM $table WHERE $select ORDER BY $order");
|
||||
}
|
||||
|
||||
// stop now if no attempts were found
|
||||
if (empty($attempts)) {
|
||||
print_heading(get_string('noattempts','quiz'));
|
||||
exit;
|
||||
@ -159,22 +219,26 @@
|
||||
// get grades
|
||||
$grades = hotpot_get_grades($hotpot, $user_ids);
|
||||
|
||||
// get list of attempts by user
|
||||
// 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])) {
|
||||
$grade = isset($grades[$userid]) ? $grades[$userid] : ' ';
|
||||
$users[$userid]->grade = $grade;
|
||||
$users[$userid]->grade = isset($grades[$userid]) ? $grades[$userid] : ' ';
|
||||
$users[$userid]->attempts = array();
|
||||
}
|
||||
|
||||
$users[$userid]->attempts[] = &$attempts[$id];
|
||||
|
||||
|
||||
if ($mode=='click' && isset($cr_attempts[$id])) {
|
||||
$attempts[$id]->cr_lastclick = $cr_attempts[$id]->id;
|
||||
$attempts[$id]->cr_timefinish = $cr_attempts[$id]->timefinish;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Open the selected hotpot report and display it
|
||||
|
||||
$mode = clean_filename($mode);
|
||||
@ -188,18 +252,17 @@
|
||||
|
||||
$report = new hotpot_report();
|
||||
|
||||
if (! $report->display($hotpot, $cm, $course, $users, $attempts, $questions)) {
|
||||
error("Error occurred during pre-processing!", $course_homeurl);
|
||||
if (! $report->display($hotpot, $cm, $course, $users, $attempts, $questions, $formdata)) {
|
||||
error("Error occurred during report processing!", $course_homeurl);
|
||||
}
|
||||
|
||||
if (empty($noheader)) {
|
||||
if ($formdata['reportformat']=='htm') {
|
||||
print_footer($course);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
/// functions to delete attempts and responses
|
||||
|
||||
function hotpot_grade_heading($hotpot, $download) {
|
||||
function hotpot_grade_heading($hotpot, $formdata) {
|
||||
|
||||
global $HOTPOT_GRADEMETHOD;
|
||||
$grademethod = $HOTPOT_GRADEMETHOD[$hotpot->grademethod];
|
||||
@ -207,10 +270,10 @@ function hotpot_grade_heading($hotpot, $download) {
|
||||
if ($hotpot->grade!=100) {
|
||||
$grademethod = "$hotpot->grade x $grademethod/100";
|
||||
}
|
||||
if (empty($download)) {
|
||||
if ($formdata['reportformat']=='htm') {
|
||||
$grademethod = '<FONT size="1">'.$grademethod.'</FONT>';
|
||||
}
|
||||
$nl = $download ? "\n" : '<br>';
|
||||
$nl = $formdata['reportformat']=='htm' ? '<br />' : "\n";
|
||||
return get_string('grade')."$nl($grademethod)";
|
||||
}
|
||||
function hotpot_delete_selected_attempts(&$hotpot, $del) {
|
||||
@ -221,14 +284,14 @@ function hotpot_delete_selected_attempts(&$hotpot, $del) {
|
||||
$select = "hotpot='$hotpot->id'";
|
||||
break;
|
||||
case 'abandoned':
|
||||
$select = "hotpot='$hotpot->id' AND timefinish>0 AND score IS NULL";
|
||||
$select = "hotpot='$hotpot->id' AND status=".HOTPOT_STATUS_ABANDONED;
|
||||
break;
|
||||
case 'selection':
|
||||
$ids = (array)data_submitted();
|
||||
unset($ids['del']);
|
||||
unset($ids['id']);
|
||||
if (!empty($ids)) {
|
||||
$select = "hotpot='$hotpot->id' AND id IN (".implode(',', $ids).")";
|
||||
$select = "hotpot='$hotpot->id' AND clickreportid IN (".implode(',', $ids).")";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -241,9 +304,9 @@ function hotpot_delete_selected_attempts(&$hotpot, $del) {
|
||||
|
||||
hotpot_delete_and_notify($table, $select, get_string('attempts', 'quiz'));
|
||||
|
||||
$table = 'hotpot_responses';
|
||||
$select = 'attempt IN ('.implode(',', array_keys($attempts)).')';
|
||||
hotpot_delete_and_notify($table, $select, get_string('answer', 'quiz'));
|
||||
hotpot_delete_and_notify('hotpot_details', $select, get_string('rawdetails', 'hotpot'));
|
||||
hotpot_delete_and_notify('hotpot_responses', $select, get_string('answer', 'quiz'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +326,13 @@ function hotpot_print_report_heading(&$course, &$cm, &$hotpot, &$mode) {
|
||||
$navigation = "<a href=index.php?id=$course->id>$strmodulenameplural</a> -> ";
|
||||
$navigation .= "<a href=\"view.php?id=$cm->id\">$hotpot->name</a> -> ";
|
||||
if (isteacher($course->id)) {
|
||||
$navigation .= get_string("report$mode", "quiz");
|
||||
if ($mode=='overview' || $mode=='simplestat' || $mode=='fullstat') {
|
||||
$module = "quiz";
|
||||
} else {
|
||||
$module = "hotpot";
|
||||
}
|
||||
$navigation .= get_string("report$mode", $module);
|
||||
|
||||
} else {
|
||||
$navigation .= get_string("report", "quiz");
|
||||
}
|
||||
@ -276,19 +345,33 @@ function hotpot_print_report_heading(&$course, &$cm, &$hotpot, &$mode) {
|
||||
|
||||
print_heading($hotpot->name);
|
||||
}
|
||||
function hotpot_print_report_selector(&$course, &$hotpot, &$mode, &$reportcourse, &$reportusers, &$reportattempts) {
|
||||
function hotpot_print_report_selector(&$course, &$hotpot, &$formdata) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
$reports = hotpot_get_report_names('overview,simplestat');
|
||||
$reports = hotpot_get_report_names('overview,simplestat,fullstat');
|
||||
|
||||
print '<form method="post" action="'."$CFG->wwwroot/mod/hotpot/report.php?hp=$hotpot->id".'">';
|
||||
print '<table cellpadding="4" align="center">';
|
||||
print '<table cellpadding="2" align="center">';
|
||||
|
||||
$menus = array();
|
||||
|
||||
$menus['mode'] = array();
|
||||
foreach ($reports as $name) {
|
||||
if ($name=='overview' || $name=='simplestat' || $name=='fullstat') {
|
||||
$module = "quiz"; // standard reports
|
||||
} else if ($name=='click' && empty($hotpot->clickreporting)) {
|
||||
$module = ""; // clickreporting is disabled
|
||||
} else {
|
||||
$module = "hotpot"; // custom reports
|
||||
}
|
||||
if ($module) {
|
||||
$menus['mode'][$name] = get_string("report$name", $module);
|
||||
}
|
||||
}
|
||||
if (isadmin()) {
|
||||
$menus['reportcourse'] = array(
|
||||
'this' => get_string('thiscourse', 'hotpot'),
|
||||
'this' => get_string('thiscourse', 'hotpot'), // $course->shortname,
|
||||
'all' => get_string('allmycourses', 'hotpot')
|
||||
);
|
||||
}
|
||||
@ -297,23 +380,54 @@ function hotpot_print_report_selector(&$course, &$hotpot, &$mode, &$reportcourse
|
||||
'all' => get_string('allparticipants')
|
||||
);
|
||||
$menus['reportattempts'] = array(
|
||||
'best' => get_string('bestattempt', 'hotpot'),
|
||||
'all' => get_string('allattempts', 'hotpot')
|
||||
'all' => get_string('attemptsall', 'hotpot'),
|
||||
'best' => get_string('attemptsbest', 'hotpot'),
|
||||
'first' => get_string('attemptsfirst', 'hotpot'),
|
||||
'last' => get_string('attemptslast', 'hotpot')
|
||||
);
|
||||
|
||||
print '<tr><td align="center" colspan="'.count($reports).'">';
|
||||
print '<tr><td>';
|
||||
helpbutton('reportcontent', get_string('reportcontent', 'hotpot'), 'hotpot');
|
||||
print '</td><th align="right">'.get_string('reportcontent', 'hotpot').':</th><td colspan="7">';
|
||||
foreach ($menus as $name => $options) {
|
||||
eval('$value=$'.$name.';');
|
||||
$value = $formdata[$name];
|
||||
print choose_from_menu($options, $name, $value, "", "", 0, true);
|
||||
}
|
||||
if (isteacher($course->id)) {
|
||||
helpbutton('reportselector', get_string('report'), 'hotpot');
|
||||
}
|
||||
print '</td></tr>';
|
||||
};
|
||||
print '<input type="submit" value="'.get_string('reportbutton', 'hotpot').'"></td></tr>';
|
||||
|
||||
print '<tr>';
|
||||
foreach ($reports as $name) {
|
||||
print '<td><input type="submit" name="'."mode[$name]".'" value="'.get_string("report$name", "quiz").'"></td>';
|
||||
$menus = array();
|
||||
$menus['reportformat'] = array(
|
||||
'htm' => get_string('reportformathtml', 'hotpot'),
|
||||
'xls' => get_string('reportformatexcel', 'hotpot'),
|
||||
'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 '<tr><td>';
|
||||
helpbutton('reportformat', get_string('reportformat', 'hotpot'), 'hotpot');
|
||||
print '</td>';
|
||||
foreach ($menus as $name => $options) {
|
||||
$value = $formdata[$name];
|
||||
print '<th align="right">'.get_string($name, 'hotpot').':</th><td>'.choose_from_menu($options, $name, $value, "", "", 0, true).'</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@ -332,7 +446,7 @@ function hotpot_get_report_names($names='') {
|
||||
$names = explode(',', $names);
|
||||
}
|
||||
|
||||
$plugins = get_list_of_plugins("mod/hotpot/report");
|
||||
$plugins = get_list_of_plugins('mod/hotpot/report');
|
||||
foreach($names as $name) {
|
||||
if (is_numeric($i = array_search($name, $plugins))) {
|
||||
$reports[] = $name;
|
||||
@ -345,18 +459,18 @@ function hotpot_get_report_names($names='') {
|
||||
|
||||
return $reports;
|
||||
}
|
||||
function hotpot_get_report_users($course_ids, $reportusers) {
|
||||
function hotpot_get_report_users($course_ids, $formdata) {
|
||||
$users = array();
|
||||
|
||||
/// Check to see if groups are being used in this module
|
||||
$currentgroup = false;
|
||||
if ($groupmode = groupmode($course, $cm)) { // Groups are being used
|
||||
$currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id=$cm->id&mode=simplestat");
|
||||
$currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id=$cm->id&mode=simple");
|
||||
}
|
||||
|
||||
$sort = "u.lastname ASC";
|
||||
|
||||
switch ($reportusers) {
|
||||
switch ($formdata['reportusers']) {
|
||||
case 'students':
|
||||
if ($currentgroup) {
|
||||
$users = get_group_students($currentgroup, $sort);
|
||||
@ -375,4 +489,46 @@ function hotpot_get_report_users($course_ids, $reportusers) {
|
||||
|
||||
return $users;
|
||||
}
|
||||
function hotpot_get_records_groupby($function, $fieldnames, $table, $select, $groupby) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
switch (strtolower($CFG->dbtype)) {
|
||||
case 'mysql':
|
||||
$fields = "$groupby, $function(CONCAT(".join(",'_',", $fieldnames).")) AS joinedvalues";
|
||||
break;
|
||||
case 'postgres7':
|
||||
$fields = "$groupby, $function(".join("||'_'||", $fieldnames).") AS joinedvalues";
|
||||
break;
|
||||
default:
|
||||
$fields = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($fields) {
|
||||
$records = get_records_sql("SELECT $fields FROM $table WHERE $select GROUP BY $groupby");
|
||||
}
|
||||
|
||||
if (empty($fields) || empty($records)) {
|
||||
$records = array();
|
||||
}
|
||||
|
||||
$fieldcount = count($fieldnames);
|
||||
|
||||
foreach ($records as $id=>$record) {
|
||||
if (empty($record->joinedvalues)) {
|
||||
unset($records[$id]);
|
||||
} else {
|
||||
$formdata = explode('_', $record->joinedvalues);
|
||||
|
||||
for ($i=0; $i<$fieldcount; $i++) {
|
||||
$fieldname = $fieldnames[$i];
|
||||
$records[$id]->$fieldname = $formdata[$i];
|
||||
}
|
||||
}
|
||||
unset($record->joinedvalues); // tidy up
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
?>
|
||||
|
@ -17,13 +17,14 @@
|
||||
|
||||
class hotpot_default_report {
|
||||
|
||||
function display($cm, $course, $hotpot) { /// This function just displays the 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);
|
||||
$questionids = array_keys($questions);
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$table->head[] = get_string('questionshort', 'hotpot', $i+1);
|
||||
if (isset($table->align)) {
|
||||
@ -42,6 +43,81 @@ class hotpot_default_report {
|
||||
|
||||
}
|
||||
|
||||
function set_legend(&$table, &$q, &$value, &$question) {
|
||||
|
||||
// check the legend is required
|
||||
if (isset($table->legend) && isset($value)) {
|
||||
|
||||
// create question details array, if necessary
|
||||
if (empty($table->legend[$q])) {
|
||||
$table->legend[$q] = array(
|
||||
'name' => hotpot_get_question_name($question),
|
||||
'answers' => array()
|
||||
);
|
||||
}
|
||||
|
||||
// search for this $value in answers array for this $q(uestion)
|
||||
$i_max = count($table->legend[$q]['answers']);
|
||||
for ($i=0; $i<$i_max; $i++) {
|
||||
if ($table->legend[$q]['answers'][$i]==$value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add $value to answers array, if it was not there
|
||||
if ($i==$i_max) {
|
||||
$table->legend[$q]['answers'][$i] = $value;
|
||||
}
|
||||
|
||||
// convert $value to alphabetic index (A, B ... AA, AB ...)
|
||||
$value = $this->dec_to_ALPHA($i);
|
||||
}
|
||||
}
|
||||
function create_legend_table(&$tables, &$table) {
|
||||
|
||||
if (isset($table->legend)) {
|
||||
|
||||
$legend->width = '*';
|
||||
$legend->tablealign = '*';
|
||||
$legend->border = isset($table->border) ? $table->border : NULL;
|
||||
$legend->cellpadding = isset($table->cellpadding) ? $table->cellpadding : NULL;
|
||||
$legend->cellspacing = isset($table->cellspacing) ? $table->cellspacing : NULL;
|
||||
$legend->tableclass = isset($table->tableclass) ? $table->tableclass : NULL;
|
||||
|
||||
$legend->caption = get_string('reportlegend', 'hotpot');
|
||||
$legend->align = array('right', 'left');
|
||||
$legend->statheadercols = array(0);
|
||||
|
||||
$legend->stat = array();
|
||||
|
||||
// put the questions in order
|
||||
sort($table->legend);
|
||||
|
||||
foreach($table->legend as $q=>$question) {
|
||||
|
||||
$legend->stat[] = array(
|
||||
get_string('questionshort', 'hotpot', $q+1),
|
||||
$question['name']
|
||||
);
|
||||
foreach($question['answers'] as $a=>$answer) {
|
||||
$legend->stat[] = array(
|
||||
$this->dec_to_ALPHA($a),
|
||||
$answer
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
unset($table->legend);
|
||||
$tables[] = $legend;
|
||||
}
|
||||
}
|
||||
function dec_to_ALPHA($dec) {
|
||||
if ($dec < 26) {
|
||||
return chr(ord('A') + $dec);
|
||||
} else {
|
||||
return $this->dec_to_ALPHA(intval($dec/26)-1).$this->dec_to_ALPHA($dec % 26);
|
||||
}
|
||||
}
|
||||
function remove_column(&$col, &$table) {
|
||||
|
||||
if (is_array($table)) {
|
||||
@ -106,6 +182,12 @@ class hotpot_default_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)
|
||||
|
||||
@ -113,45 +195,88 @@ class hotpot_default_report {
|
||||
|
||||
|
||||
//////////////////////////////////////////
|
||||
/// print an html report
|
||||
/// print a report
|
||||
|
||||
function print_html(&$cm, &$table, $mode, $tablename='') {
|
||||
|
||||
$this->print_html_table($table);
|
||||
|
||||
// print buttons, if required
|
||||
if (isset($mode) && !empty($table)) {
|
||||
|
||||
// button options
|
||||
$options = array(
|
||||
'id'=>"$cm->id",
|
||||
'mode'=>$mode,
|
||||
'noheader'=>'yes'
|
||||
);
|
||||
if ($tablename) {
|
||||
$options['tablename'] = $tablename;
|
||||
}
|
||||
|
||||
print '<table border="0" align="center"><tr>';
|
||||
print '<td>';
|
||||
|
||||
$options["download"] = "xls";
|
||||
print_single_button("report.php", $options, get_string("downloadexcel"));
|
||||
|
||||
print '</td><td>';
|
||||
|
||||
$options["download"] = "txt";
|
||||
print_single_button("report.php", $options, get_string("downloadtext"));
|
||||
|
||||
print '</table>';
|
||||
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_html_table($table) {
|
||||
global $THEME;
|
||||
|
||||
// do nothing if the table is empty
|
||||
if (empty($table) || $this->set_colspan($table)==0) return true;
|
||||
|
||||
function print_report_start(&$course, &$hotpot, &$options, &$table) {
|
||||
switch ($options['reportformat']) {
|
||||
case 'txt':
|
||||
$this->print_text_start($course, $hotpot, $options);
|
||||
break;
|
||||
case 'xls':
|
||||
$this->print_excel_start($course, $hotpot, $options);
|
||||
break;
|
||||
|
||||
case 'htm':
|
||||
$this->print_html_start($course, $hotpot, $options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function print_report_cells(&$table, &$options, $zone) {
|
||||
switch ($options['reportformat']) {
|
||||
case 'txt':
|
||||
$fmt = 'text';
|
||||
break;
|
||||
case 'xls':
|
||||
$fmt = 'excel';
|
||||
break;
|
||||
default: // 'htm' (and anything else)
|
||||
$fmt = 'html';
|
||||
break;
|
||||
}
|
||||
$fn = "print_{$fmt}_{$zone}";
|
||||
$this->$fn($table, $options);
|
||||
}
|
||||
|
||||
function print_report_finish(&$course, &$hotpot, &$options) {
|
||||
switch ($options['reportformat']) {
|
||||
case 'txt' :
|
||||
// do nothing
|
||||
break;
|
||||
case 'xls':
|
||||
$this->print_excel_finish($course, $hotpot, $options);
|
||||
break;
|
||||
case 'htm':
|
||||
$this->print_html_finish($course, $hotpot, $options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
/// print an html report
|
||||
|
||||
function print_html_report(&$tables) {
|
||||
$count = count($tables);
|
||||
foreach($tables as $i=>$table) {
|
||||
|
||||
$this->print_html_start($table);
|
||||
$this->print_html_head($table);
|
||||
$this->print_html_data($table);
|
||||
$this->print_html_stat($table);
|
||||
$this->print_html_foot($table);
|
||||
$this->print_html_finish($table);
|
||||
|
||||
if (($i+1)<$count) {
|
||||
print_spacer(30, 10, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
function print_html_start(&$table) {
|
||||
|
||||
// default class for the table
|
||||
if (empty($table->tableclass)) {
|
||||
$table->tableclass = 'generaltable';
|
||||
@ -161,12 +286,24 @@ class hotpot_default_report {
|
||||
$d = $table->tableclass.'cell';
|
||||
$h = $table->tableclass.'header';
|
||||
|
||||
$th_side = NULL;
|
||||
$th_side->start = '<th valign="top" align="right" class="'.$h.'">';
|
||||
$th_side->end = '</th>'."\n";
|
||||
$table->th_side = '<th valign="top" align="right" class="'.$h.'">';
|
||||
|
||||
$td = array();
|
||||
$th_top = array();
|
||||
$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++) {
|
||||
|
||||
@ -175,15 +312,12 @@ class hotpot_default_report {
|
||||
$size = empty($table->size[$i]) ? '' : ' width="'.$table->size[$i].'"';
|
||||
$wrap = empty($table->wrap[$i]) ? '' : ' nowrap="nowrap"';
|
||||
|
||||
$th_top[$i]->start = '<th align="center"'.$size.' class="'.$h.'" nowrap="nowrap">';
|
||||
$th_top[$i]->end = '</th>'."\n";
|
||||
$table->th_top[$i] = '<th align="center"'.$size.' class="'.$h.'" nowrap="nowrap">';
|
||||
|
||||
$td[$i]->start = '<td valign="top"'.$align.$class.$wrap.'>';
|
||||
$td[$i]->end = '</td>'."\n";
|
||||
$table->td[$i] = '<td valign="top"'.$align.$class.$wrap.'>';
|
||||
|
||||
if (!empty($table->fontsize[$i])) {
|
||||
$td[$i]->start .= '<font size="'.$table->fontsize[$i].'">';
|
||||
$td[$i]->end = '</font>'.$td[$i]->end;
|
||||
$table->td[$i] .= '<font size="'.$table->fontsize[$i].'">';
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,135 +333,184 @@ class hotpot_default_report {
|
||||
if (empty($table->width)) {
|
||||
$table->width = "80%"; // actually the width of the "simple box"
|
||||
}
|
||||
if (empty($table->tablealign)) {
|
||||
$table->tablealign = "center";
|
||||
}
|
||||
|
||||
print_simple_box_start("center", "$table->width", "#ffffff", 0);
|
||||
if (isset($table->start)) {
|
||||
print $table->start."\n";
|
||||
}
|
||||
|
||||
print_simple_box_start("$table->tablealign", "$table->width", "#ffffff", 0);
|
||||
print '<table width="100%" border="'.$table->border.'" valign="top" align="center" cellpadding="'.$table->cellpadding.'" cellspacing="'.$table->cellspacing.'" class="'.$table->tableclass.'">'."\n";
|
||||
|
||||
if (isset($table->caption)) {
|
||||
print '<tr><td colspan="'.$table->colspan.'" class="'.$table->tableclass.'header"><b>'.$table->caption.'</b></td></tr>'."\n";
|
||||
}
|
||||
|
||||
}
|
||||
function print_html_head(&$table) {
|
||||
if (isset($table->head)) {
|
||||
print '<tr>'."\n";
|
||||
foreach ($table->head as $i => $cell) {
|
||||
print $th_top[$i]->start.$cell.$th_top[$i]->end;
|
||||
print "<tr>\n";
|
||||
foreach ($table->head as $i=>$cell) {
|
||||
$th = $table->th_top[$i];
|
||||
print $th.$cell."</th>\n";
|
||||
}
|
||||
print '</tr>'."\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
|
||||
}
|
||||
function print_html_data(&$table) {
|
||||
if (isset($table->data)) {
|
||||
$skipcell = array();
|
||||
foreach ($table->data as $cells) {
|
||||
print '<tr>'."\n";
|
||||
if (is_array($cells)) {
|
||||
foreach ($cells as $i => $cell) {
|
||||
print $td[$i]->start.$cell.$td[$i]->end;
|
||||
}
|
||||
} else if ($cells == 'hr') {
|
||||
print "<tr>\n";
|
||||
if (is_array($cells)) {
|
||||
$i = 0; // index on $cells
|
||||
$col = 0; // column index
|
||||
while ($col<$table->colspan && isset($cells[$i])) {
|
||||
if (empty($skipcell[$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 = '<td rowspan="'.$cell->rowspan.'"'.substr($td, 3);
|
||||
// skip cells below this one
|
||||
$skipcell[$col] = $cell->rowspan-1;
|
||||
}
|
||||
if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) {
|
||||
$td = '<td colspan="'.$cell->colspan.'"'.substr($td, 3);
|
||||
// skip cells to the right of this one
|
||||
for ($c=1; $c<$cell->colspan; $c++) {
|
||||
if (empty($skipcell[$col+$c])) {
|
||||
$skipcell[$col+$c] = 1;
|
||||
} else {
|
||||
$skipcell[$col+$c] ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // $cell is a string
|
||||
$text = $cell;
|
||||
}
|
||||
print $td.$text."</td>\n";
|
||||
} else {
|
||||
$skipcell[$col]--;
|
||||
}
|
||||
$col++;
|
||||
} // end while
|
||||
} else if ($cells=='hr') {
|
||||
print '<td colspan="'.$table->colspan.'"><div class="tabledivider"></div></td>'."\n";
|
||||
}
|
||||
print '</tr>'."\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
function print_html_stat(&$table) {
|
||||
if (isset($table->stat)) {
|
||||
if (empty($table->statheadercols)) {
|
||||
$table->statheadercols = array();
|
||||
}
|
||||
foreach ($table->stat as $cells) {
|
||||
print '<tr>'."\n";
|
||||
print '<tr>';
|
||||
foreach ($cells as $i => $cell) {
|
||||
if (in_array($i, $table->statheadercols)) {
|
||||
print $th_side->start.$cell.$th_side->end;
|
||||
$th = $table->th_side;
|
||||
print $th.$cell."</th>\n";
|
||||
} else {
|
||||
print $td[$i]->start.$cell.$td[$i]->end;
|
||||
$td = $table->td[$i];
|
||||
print $td.$cell."</td>\n";
|
||||
}
|
||||
}
|
||||
print '</tr>'."\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
function print_html_foot(&$table) {
|
||||
if (isset($table->foot)) {
|
||||
foreach ($table->foot as $cells) {
|
||||
print '<tr>'."\n";
|
||||
print "<tr>\n";
|
||||
foreach ($cells as $i => $cell) {
|
||||
if ($i==0) {
|
||||
print $th_side->start.$cell.$th_side->end;
|
||||
$th = $table->th_side;
|
||||
print $th.$cell."</th>\n";
|
||||
} else {
|
||||
print $th_top[$i]->start.$cell.$th_top[$i]->end;
|
||||
$th = $table->th_top[$i];
|
||||
print $th.$cell."</th>\n";
|
||||
}
|
||||
}
|
||||
print '</tr>'."\n";
|
||||
print "</tr>\n";
|
||||
}
|
||||
}
|
||||
print '</table>'."\n";
|
||||
}
|
||||
function print_html_finish(&$table) {
|
||||
print "</table>\n";
|
||||
print_simple_box_end();
|
||||
|
||||
return true;
|
||||
}
|
||||
function set_colspan(&$table) {
|
||||
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;
|
||||
}
|
||||
if (isset($table->finish)) {
|
||||
print $table->finish."\n";
|
||||
}
|
||||
return $table->colspan;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
/// print a text report
|
||||
|
||||
function print_text(&$course, &$hotpot, &$table) {
|
||||
$this->print_text_headers($course, $hotpot);
|
||||
$this->print_text_head($table);
|
||||
$this->print_text_data($table);
|
||||
$this->print_text_stat($table);
|
||||
$this->print_text_foot($table);
|
||||
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_headers($course, $hotpot) {
|
||||
function print_text_start(&$course, &$hotpot, &$options) {
|
||||
header("Content-Type: application/download\n");
|
||||
header("Content-Disposition: attachment; filename=$course->shortname $hotpot->name.txt");
|
||||
header("Content-Disposition: attachment; filename=$course->shortname-$hotpot->name.txt");
|
||||
header("Expires: 0");
|
||||
header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
|
||||
header("Pragma: public");
|
||||
}
|
||||
function print_text_head(&$table) {
|
||||
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->print_text_cells($table->head);
|
||||
$this->print_text_cells($table->head, $options);
|
||||
}
|
||||
}
|
||||
function print_text_data(&$table) {
|
||||
function print_text_data(&$table, &$options) {
|
||||
if (isset($table->data)) {
|
||||
foreach ($table->data as $cells) {
|
||||
$this->print_text_cells($cells);
|
||||
$this->print_text_cells($cells, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
function print_text_stat(&$table) {
|
||||
function print_text_stat(&$table, &$options) {
|
||||
if (isset($table->stat)) {
|
||||
foreach ($table->stat as $cells) {
|
||||
$this->print_text_cells($cells);
|
||||
$this->print_text_cells($cells, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
function print_text_foot(&$table) {
|
||||
function print_text_foot(&$table, &$options) {
|
||||
if (isset($table->foot)) {
|
||||
foreach ($table->foot as $cells) {
|
||||
$this->print_text_cells($cells);
|
||||
$this->print_text_cells($cells, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
function print_text_cells(&$cells) {
|
||||
function print_text_cells(&$cells, &$options) {
|
||||
|
||||
// do nothing if there are no cells
|
||||
if (empty($cells)) return;
|
||||
if (empty($cells) || is_string($cells)) return;
|
||||
|
||||
// convert to tab-delimted string
|
||||
$str = implode("\t", $cells);
|
||||
@ -349,55 +532,65 @@ class hotpot_default_report {
|
||||
//////////////////////////////////////////
|
||||
/// print an Excel report
|
||||
|
||||
function print_excel(&$course, &$hotpot, &$table) {
|
||||
function print_excel_report(&$course, &$hotpot, &$tables, &$options) {
|
||||
global $CFG;
|
||||
require_once("$CFG->libdir/excel/Worksheet.php");
|
||||
require_once("$CFG->libdir/excel/Workbook.php");
|
||||
|
||||
// array of format objects (one for each cell)
|
||||
$fmt = array();
|
||||
// send headers to browser
|
||||
$this->print_excel_start($course, $hotpot, $options);
|
||||
|
||||
// Create a new workbook and worksheet
|
||||
$wb = new Workbook("-");
|
||||
$ws = &$wb->add_worksheet(get_string('reportsimplestat', 'quiz'));
|
||||
|
||||
$this->print_excel_headers($course, $hotpot);
|
||||
$this->print_excel_head($wb, $ws, $table, $fmt);
|
||||
$this->print_excel_data($wb, $ws, $table, $fmt);
|
||||
$this->print_excel_stat($wb, $ws, $table, $fmt);
|
||||
$this->print_excel_foot($wb, $ws, $table, $fmt);
|
||||
// Create a new workbook
|
||||
$wb = new Workbook("-"); // $course->shortname
|
||||
|
||||
foreach($tables as $table) {
|
||||
// create a worksheet for this table
|
||||
unset($ws);
|
||||
$ws = &$wb->add_worksheet(empty($table->caption) ? '' : strip_tags($table->caption));
|
||||
|
||||
$row = 0;
|
||||
$this->print_excel_head($wb, $ws, $table, $row, $options);
|
||||
$this->print_excel_data($wb, $ws, $table, $row, $options);
|
||||
$this->print_excel_stat($wb, $ws, $table, $row, $options);
|
||||
$this->print_excel_foot($wb, $ws, $table, $row, $options);
|
||||
}
|
||||
|
||||
// close the workbook (and send it to the browser)
|
||||
$wb->close();
|
||||
}
|
||||
function print_excel_headers(&$course, &$instance) {
|
||||
function print_excel_start(&$course, &$hotpot, &$options) {
|
||||
header("Content-type: application/vnd.ms-excel");
|
||||
header("Content-Disposition: attachment; filename=$course->shortname $instance->name.xls" );
|
||||
header("Content-Disposition: attachment; filename=$course->shortname $hotpot->name.xls" );
|
||||
header("Expires: 0");
|
||||
header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
|
||||
header("Pragma: public");
|
||||
}
|
||||
function print_excel_head(&$wb, &$ws, &$table, &$fmt) {
|
||||
function print_excel_head(&$wb, &$ws, &$table, &$row, &$options) {
|
||||
|
||||
// format properties
|
||||
$properties = array('bold'=>1, 'align'=>'center');
|
||||
|
||||
$properties = array(
|
||||
'bold'=>1,
|
||||
'align'=>'center',
|
||||
'valign'=>'bottom',
|
||||
'text_wrap'=>1
|
||||
);
|
||||
// print the headings
|
||||
$this->print_excel_cells($wb, $ws, $table, $fmt, $properties, $table->head);
|
||||
}
|
||||
function print_excel_data(&$wb, &$ws, &$table, &$fmt) {
|
||||
$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;
|
||||
|
||||
// format properties
|
||||
$properties = array();
|
||||
$properties = array('text_wrap' => (empty($options['reportwrapdata']) ? 0 : 1));
|
||||
|
||||
// print the data cells
|
||||
foreach ($table->data as $cells) {
|
||||
$this->print_excel_cells($wb, $ws, $table, $fmt, $properties, $cells, array());
|
||||
$this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
|
||||
}
|
||||
}
|
||||
function print_excel_stat(&$wb, &$ws, &$table, &$fmt) {
|
||||
}
|
||||
function print_excel_stat(&$wb, &$ws, &$table, &$row, &$options) {
|
||||
|
||||
// do nothing if there are no cells
|
||||
if (empty($table->stat)) return;
|
||||
@ -413,10 +606,10 @@ class hotpot_default_report {
|
||||
$properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
|
||||
|
||||
// print this row of statistics
|
||||
$this->print_excel_cells($wb, $ws, $table, $fmt, $properties, $cells, $table->statheadercols);
|
||||
$this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options, $table->statheadercols);
|
||||
}
|
||||
}
|
||||
function print_excel_foot(&$wb, &$ws, &$table, &$fmt) {
|
||||
}
|
||||
function print_excel_foot(&$wb, &$ws, &$table, &$row, &$options) {
|
||||
|
||||
// do nothing if there are no cells
|
||||
if (empty($table->foot)) return;
|
||||
@ -432,54 +625,87 @@ class hotpot_default_report {
|
||||
$properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
|
||||
|
||||
// print this footer row
|
||||
$this->print_excel_cells($wb, $ws, $table, $fmt, $properties, $cells);
|
||||
$this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
|
||||
}
|
||||
}
|
||||
function print_excel_cells(&$wb, &$ws, &$table, &$fmt, &$properties, &$cells, $statheadercols=NULL) {
|
||||
}
|
||||
|
||||
function print_excel_cells(&$wb, &$ws, &$table, &$row, &$properties, &$cells, &$options, $statheadercols=NULL) {
|
||||
|
||||
// do nothing if there are no cells
|
||||
if (empty($cells)) return;
|
||||
|
||||
// next row
|
||||
$row = count($fmt);
|
||||
|
||||
// initialize formats for this row
|
||||
$fmt[$row] = array();
|
||||
if (empty($cells) || is_string($cells)) return;
|
||||
|
||||
foreach($cells as $col => $cell) {
|
||||
|
||||
if ($row==0) {
|
||||
// set column width (excel-width = web-width / 5)
|
||||
$width = (isset($table->size[$col]) && is_numeric($table->size[$col])) ? ceil($table->size[$col]/5) : ($col==0 ? 30 : 15);
|
||||
//$ws->set_column($col, $col, $width);
|
||||
}
|
||||
|
||||
// set text wrap if $cell is a string and contains a newline
|
||||
if (is_string($cell) && preg_match("/\n/", $cell)) {
|
||||
$properties['text_wrap'] = 1;
|
||||
unset($fmt_properties);
|
||||
$fmt_properties = $properties;
|
||||
|
||||
if (empty($fmt_properties['text_wrap'])) {
|
||||
if (strlen("$cell")>=9) {
|
||||
// long cell value
|
||||
$fmt_properties['align'] = 'left';
|
||||
}
|
||||
} else {
|
||||
$properties['text_wrap'] = 0;
|
||||
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)) {
|
||||
$properties['bold'] = in_array($col, $statheadercols) ? 1 : 0;
|
||||
$properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col];
|
||||
$fmt_properties['bold'] = in_array($col, $statheadercols) ? 1 : 0;
|
||||
$fmt_properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col];
|
||||
}
|
||||
|
||||
// create (a reference to) a new format object
|
||||
$fmt[$row][$col] = &$wb->add_format($properties);
|
||||
|
||||
// set vertical alignment
|
||||
$fmt[$row][$col]->set_align('top');
|
||||
// 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);
|
||||
foreach ($wb->formats as $id=>$format) {
|
||||
if (isset($format->properties) && $format->properties==$fmt_properties) {
|
||||
$fmt = &$wb->formats[$id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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['valign'])) {
|
||||
$fmt->set_align($fmt->properties['valign']);
|
||||
} else {
|
||||
$fmt->set_align('top'); // default
|
||||
}
|
||||
}
|
||||
|
||||
// write cell
|
||||
if (is_numeric($cell)) {
|
||||
$ws->write_number($row, $col, $cell, $fmt[$row][$col]);
|
||||
if (is_numeric($cell) && !preg_match("/^0./", $cell)) {
|
||||
$ws->write_number($row, $col, $cell, $fmt);
|
||||
} else {
|
||||
$ws->write_string($row, $col, $cell, $fmt[$row][$col]);
|
||||
if (!empty($options['reportencoding'])) {
|
||||
$in_charset = '';
|
||||
if (function_exists('mb_convert_encoding')) {
|
||||
$in_charset = mb_detect_encoding($cell, 'auto');
|
||||
}
|
||||
if (empty($in_charset)) {
|
||||
$in_charset = get_string('thischarset');
|
||||
}
|
||||
if ($in_charset != 'ASCII' && function_exists('mb_convert_encoding')) {
|
||||
$cell = mb_convert_encoding($cell, $options['reportencoding'], $in_charset);
|
||||
}
|
||||
}
|
||||
$ws->write_string($row, $col, $cell, $fmt);
|
||||
}
|
||||
}
|
||||
} // end foreach $col
|
||||
|
||||
// increment $row
|
||||
$row++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,108 +4,102 @@
|
||||
|
||||
class hotpot_report extends hotpot_default_report {
|
||||
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions) {
|
||||
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options) {
|
||||
global $CFG;
|
||||
|
||||
// retrieve form variables, if any
|
||||
global $download, $tablename;
|
||||
optional_variable($download, "");
|
||||
optional_variable($tablename, "");
|
||||
|
||||
$strbestgrade = "highest"; // $QUIZ_GRADE_METHOD[$hotpot->grademethod];
|
||||
|
||||
// get responses for the attempts by these users
|
||||
foreach ($attempts as $a => $attempt) {
|
||||
|
||||
// initialize the responses array for this attempt
|
||||
foreach ($attempts as $a=>$attempt) {
|
||||
$attempts[$a]->responses = array();
|
||||
}
|
||||
foreach ($questions as $q=>$question) {
|
||||
$questions[$q]->attempts = array();
|
||||
}
|
||||
|
||||
foreach ($questions as $q=>$question) {
|
||||
// get reponses to these attempts
|
||||
$attempt_ids = join(',',array_keys($attempts));
|
||||
if (!$responses = get_records_sql("SELECT * FROM {$CFG->prefix}hotpot_responses WHERE attempt IN ($attempt_ids)")) {
|
||||
$responses = array();
|
||||
}
|
||||
|
||||
if (!isset($questions[$q]->attempts)) {
|
||||
$questions[$q]->attempts = array();
|
||||
}
|
||||
// ids of questions used in these responses
|
||||
$questionids = array();
|
||||
|
||||
// get the response, if any, to this question on this attempt
|
||||
if ($response = get_record('hotpot_responses', 'attempt', $attempt->id, 'question', $question->id)) {
|
||||
foreach ($responses as $response) {
|
||||
// shortcuts to the attempt and question ids
|
||||
$a = $response->attempt;
|
||||
$q = $response->question;
|
||||
|
||||
// add the response for this attempt
|
||||
$attempts[$a]->responses[$q] = $response;
|
||||
// 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];
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
|
||||
// create the tables
|
||||
$this->create_responses_table($users, $attempts, $questions, $r_table=NULL, $download, $course, $hotpot);
|
||||
$this->create_analysis_table($users, $attempts, $questions, $a_table=NULL, $download);
|
||||
$tables = array();
|
||||
$this->create_responses_table($hotpot, $course, $users, $attempts, $questions, $options, $tables);
|
||||
$this->create_analysis_table($users, $attempts, $questions, $options, $tables);
|
||||
|
||||
switch ($download) {
|
||||
case 'txt':
|
||||
switch ($tablename) {
|
||||
case 'r':
|
||||
$this->print_text($course, $hotpot, $r_table);
|
||||
break;
|
||||
case 'a':
|
||||
$this->print_text($course, $hotpot, $a_table);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'xls':
|
||||
switch ($tablename) {
|
||||
case 'r':
|
||||
$this->print_excel($course, $hotpot, $r_table);
|
||||
break;
|
||||
case 'a':
|
||||
$this->print_excel($course, $hotpot, $a_table);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->print_html($cm, $r_table, 'fullstat', 'r');
|
||||
print_spacer(50, 10, true);
|
||||
|
||||
$this->print_html($cm, $a_table, 'fullstat', 'a');
|
||||
}
|
||||
// print report
|
||||
$this->print_report($course, $hotpot, $tables, $options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function create_responses_table(&$users, &$attempts, &$questions, &$table, $download, &$course, &$hotpot) {
|
||||
function create_responses_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
$is_html = ($options['reportformat']=='htm');
|
||||
|
||||
// shortcuts for font tags
|
||||
$br = $download ? "\n" : "<br />\n";
|
||||
$blank = $download ? "" : ' ';
|
||||
$font_end = $download ? '' : '</font>';
|
||||
$font_red = $download ? '' : '<font color="red">';
|
||||
$font_blue = $download ? '' : '<font color="blue">';
|
||||
$font_brown = $download ? '' : '<font color="brown">';
|
||||
$font_green = $download ? '' : '<font color="green">';
|
||||
$font_small = $download ? '' : '<font size="-2">';
|
||||
$nobr_start = $download ? '' : '<nobr>';
|
||||
$nobr_end = $download ? '' : '</nobr>';
|
||||
$br = $is_html ? "<br />\n" : "\n";
|
||||
$blank = $is_html ? ' ' : "";
|
||||
$font_end = $is_html ? '</font>' : '';
|
||||
$font_red = $is_html ? '<font color="red">' : '';
|
||||
$font_blue = $is_html ? '<font color="blue">' : '';
|
||||
$font_brown = $is_html ? '<font color="brown">' : '';
|
||||
$font_green = $is_html ? '<font color="green">' : '';
|
||||
$font_small = $is_html ? '<font size="-2">' : '';
|
||||
$nobr_start = $is_html ? '<nobr>' : '';
|
||||
$nobr_end = $is_html ? '</nobr>' : '';
|
||||
|
||||
// is review allowed? (do this once here, to save time later)
|
||||
$allow_review = (!$download && (isteacher($course->id) || $hotpot->review));
|
||||
$allow_review = ($is_html && (isteacher($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, $download),
|
||||
hotpot_grade_heading($hotpot, $options),
|
||||
get_string('attempt', 'quiz'),
|
||||
);
|
||||
$table->align = array('left', 'center', 'center');
|
||||
@ -143,7 +137,7 @@ class hotpot_report extends hotpot_default_report {
|
||||
} else {
|
||||
$name = "$u->firstname $u->lastname";
|
||||
}
|
||||
if (!$download) { // html
|
||||
if ($is_html) {
|
||||
$name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$u->userid.'&course='.$course->id.'">'.$name.'</a>';
|
||||
}
|
||||
$grade = isset($user->grade) ? $user->grade : $blank;
|
||||
@ -176,58 +170,86 @@ class hotpot_report extends hotpot_default_report {
|
||||
// get responses to questions in this attempt
|
||||
foreach ($attempt->responses as $response) {
|
||||
|
||||
// correct
|
||||
if (!$correct = hotpot_strings($response->correct)) {
|
||||
$correct = "($strnoresponse)";
|
||||
}
|
||||
$cell = $font_red.$correct.$font_end;
|
||||
// check this question id is OK (should be)
|
||||
$col = array_search($response->question, $questionids);
|
||||
if (is_numeric($col)) {
|
||||
|
||||
// wrong
|
||||
if ($wrong = hotpot_strings($response->wrong)) {
|
||||
$cell .= $br.$font_blue.$wrong.$font_end;
|
||||
}
|
||||
|
||||
// ignored
|
||||
if ($ignored = hotpot_strings($response->ignored)) {
|
||||
$cell .= $br.$font_brown.$ignored.$font_end;
|
||||
}
|
||||
|
||||
// numeric
|
||||
if (is_numeric($response->score)) {
|
||||
if (empty($table->caption)) {
|
||||
$table->caption = get_string('indivresp', 'quiz');
|
||||
if (!$download) {
|
||||
$table->caption .= helpbutton('responsestable', $table->caption, 'hotpot', true, false, '', true);
|
||||
}
|
||||
// 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 .= helpbutton('responsestable', $table->caption, 'hotpot', true, false, '', true);
|
||||
}
|
||||
}
|
||||
$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;
|
||||
}
|
||||
$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;
|
||||
}
|
||||
|
||||
// add responses into $cells
|
||||
if (is_numeric($col = array_search($response->question, $questionids))) {
|
||||
$cells[$start_col + $col] = $cell;
|
||||
}
|
||||
}
|
||||
$table->data[] = $cells;
|
||||
}
|
||||
} // end foreach
|
||||
|
||||
// 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($col, $table);
|
||||
}
|
||||
|
||||
$tables[] = &$table;
|
||||
}
|
||||
|
||||
function create_analysis_table(&$users, &$attempts, &$questions, &$table, $download) {
|
||||
function create_analysis_table(&$users, &$attempts, &$questions, &$options, &$tables) {
|
||||
|
||||
$is_html = ($options['reportformat']=='htm');
|
||||
|
||||
// the fields we are interested in, in the order we want them
|
||||
// currently some fields are redundant for some types of quiz
|
||||
// so the the fields could also be set depending on quiz type
|
||||
// (see hotpot_set_fields_by_quiz_type function below)
|
||||
$fields = array('correct', 'wrong', 'ignored', 'hints', 'clues', 'checks', 'weighting');
|
||||
$string_fields = array('correct', 'wrong', 'ignored');
|
||||
|
||||
@ -245,10 +267,10 @@ class hotpot_report extends hotpot_default_report {
|
||||
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) {
|
||||
@ -265,22 +287,23 @@ class hotpot_report extends hotpot_default_report {
|
||||
$hi_score = $scores[round($count*2/3)];
|
||||
break;
|
||||
}
|
||||
|
||||
// initialize statistics array for this question
|
||||
$q[$id] = array();
|
||||
|
||||
// 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);
|
||||
}
|
||||
@ -329,35 +352,45 @@ class hotpot_report extends hotpot_default_report {
|
||||
} // end foreach question
|
||||
|
||||
// check we have some details
|
||||
if ($q) {
|
||||
|
||||
if (count($q)) {
|
||||
$showhideid = 'showhide';
|
||||
|
||||
// shortcuts for html tags
|
||||
$bold_start = $download ? "" : '<strong>';
|
||||
$bold_end = $download ? "" : '</strong>';
|
||||
$div_start = $download ? "" : '<div id="'.$showhideid.'">';
|
||||
$div_end = $download ? "" : '</div>';
|
||||
$bold_start = $is_html ? '<strong>' : "";
|
||||
$bold_end = $is_html ? '</strong>' : "";
|
||||
$div_start = $is_html ? '<div id="'.$showhideid.'">' : "";
|
||||
$div_end = $is_html ? '</div>' : "";
|
||||
|
||||
$font_red = $download ? '' : '<font color="red" size="-2">';
|
||||
$font_blue = $download ? '' : '<font color="blue" size="-2">';
|
||||
$font_green = $download ? '' : '<font color="green" size="-2">';
|
||||
$font_brown = $download ? '' : '<font color="brown" size="-2">';
|
||||
$font_end = $download ? '' : '</font>'."\n";
|
||||
$font_red = $is_html ? '<font color="red" size="-2">' : '';
|
||||
$font_blue = $is_html ? '<font color="blue" size="-2">' : '';
|
||||
$font_green = $is_html ? '<font color="green" size="-2">' : '';
|
||||
$font_brown = $is_html ? '<font color="brown" size="-2">' : '';
|
||||
$font_end = $is_html ? '</font>'."\n" : '';
|
||||
|
||||
$br = $download ? "\n" : '<br />';
|
||||
$space = $download ? "" : ' ';
|
||||
$no_value = $download ? "" : '--';
|
||||
$help_button = $download ? "" : helpbutton("discrimination", "", "quiz", true, false, "", true);
|
||||
$br = $is_html ? '<br />' : "\n";
|
||||
$space = $is_html ? ' ' : "";
|
||||
$no_value = $is_html ? '--' : "";
|
||||
$help_button = $is_html ? helpbutton("discrimination", "", "quiz", true, false, "", true) : "";
|
||||
|
||||
// table properties
|
||||
unset($table);
|
||||
$table->border = 1;
|
||||
$table->width = '100%';
|
||||
$table->caption = get_string('itemanal', 'quiz');
|
||||
if (!$download) {
|
||||
if ($is_html) {
|
||||
$table->caption .= helpbutton('analysistable', $table->caption, 'hotpot', true, false, '', true);
|
||||
}
|
||||
|
||||
// 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');
|
||||
@ -384,20 +417,24 @@ class hotpot_report extends hotpot_default_report {
|
||||
////////////////////////////////////////////
|
||||
|
||||
// add $stat(istics) and $foot of $table
|
||||
$questionids = array_keys($questions);
|
||||
foreach ($questionids as $col => $id) {
|
||||
$questionids = array_keys($q);
|
||||
foreach ($questionids as $col => $id) {
|
||||
|
||||
$row = 0;
|
||||
|
||||
// add button to show/hide question text
|
||||
if (!isset($table->stat[0])) {
|
||||
$button = $download ? "" : hotpot_showhide_button($showhideid);
|
||||
$table->stat[0] = array(get_string('question', 'quiz').$button);
|
||||
}
|
||||
// print the question text if there is no legend
|
||||
if (empty($table->legend)) {
|
||||
|
||||
// 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 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) {
|
||||
@ -407,14 +444,15 @@ class hotpot_report extends hotpot_default_report {
|
||||
|
||||
$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;
|
||||
@ -431,17 +469,17 @@ class hotpot_report extends hotpot_default_report {
|
||||
}
|
||||
$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;
|
||||
}
|
||||
@ -477,12 +515,16 @@ class hotpot_report extends hotpot_default_report {
|
||||
} // end foreach $question ($col)
|
||||
|
||||
// add javascript to show/hide question text
|
||||
if (isset($table->stat[0]) && !$download) {
|
||||
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) {
|
||||
@ -552,50 +594,4 @@ return <<<SHOWHIDE_SET
|
||||
SHOWHIDE_SET
|
||||
;
|
||||
}
|
||||
|
||||
function hotpot_set_fields_by_question_type(&$questions) {
|
||||
// this function is not used
|
||||
$fields = array();
|
||||
foreach ($questions as $question) {
|
||||
// all questions should be the same type,
|
||||
// but just in case, they are all checked
|
||||
switch ($question->type) {
|
||||
case 1: // jcb
|
||||
break;
|
||||
case 2: // jcloze
|
||||
$fields['correct'] = true;
|
||||
$fields['wrong'] = true;
|
||||
$fields['ignored'] = true;
|
||||
$fields['clues'] = true;
|
||||
break;
|
||||
case 3: // jcross
|
||||
$fields['correct'] = true;
|
||||
break;
|
||||
case 4: // jmix
|
||||
$fields['correct'] = true;
|
||||
$fields['ignored'] = true;
|
||||
$fields['checks'] = true;
|
||||
break;
|
||||
case 5: // jmatch
|
||||
$fields['correct'] = true;
|
||||
$fields['checks'] = true;
|
||||
break;
|
||||
case 6: // jmatch
|
||||
case 6.1: // multi-choice
|
||||
case 6.2: // short-answer
|
||||
case 6.3: // hybrid
|
||||
case 6.4: // multi-select
|
||||
$fields['correct'] = true;
|
||||
$fields['wrong'] = true;
|
||||
$fields['ignored'] = true;
|
||||
$fields['hints'] = true;
|
||||
$fields['checks'] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$fields['weighting'] = true;
|
||||
|
||||
$fields = array_keys($fields);
|
||||
return $fields;
|
||||
}
|
||||
?>
|
||||
|
@ -4,144 +4,176 @@
|
||||
|
||||
class hotpot_report extends hotpot_default_report {
|
||||
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions) {
|
||||
|
||||
// retrieve form variables, if any
|
||||
global $download, $tablename;
|
||||
optional_variable($download, "");
|
||||
optional_variable($tablename, "");
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options) {
|
||||
|
||||
// message strings
|
||||
$strdeletecheck = get_string('deleteattemptcheck','quiz');
|
||||
$this->create_overview_table($hotpot, $cm, $course, $users, $attempts, $questions, $options, $tables=array());
|
||||
|
||||
// create scores table
|
||||
$this->create_overview_table($users, $attempts, $questions, $s_table=NULL, $download, $course, $hotpot, $abandoned=0);
|
||||
|
||||
if (isteacher($course->id)) {
|
||||
$this->print_javascript();
|
||||
$onsub = "return delcheck('".$strdeletecheck."', 'selection')";
|
||||
|
||||
// print buttons
|
||||
echo '<form method="post" action="report.php" name="delform" onsubmit="'.$onsub.'">'."\n";
|
||||
echo '<input type="hidden" name="del" value="selection">'."\n";
|
||||
echo '<input type="hidden" name="id" value="'.$cm->id.'">'."\n";
|
||||
}
|
||||
|
||||
// print scores table
|
||||
$this->print_html_table($s_table);
|
||||
|
||||
if (isteacher($course->id)) {
|
||||
//There might be a more elegant way than using the <center> tag for this
|
||||
echo '<center>'."\n";
|
||||
echo '<input type="submit" value="'.get_string("deleteselected").'"> '."\n";
|
||||
if ($abandoned) {
|
||||
echo '<input type=button value="'.get_string('deleteabandoned', 'hotpot').'" onClick="if(delcheck('."'".addslashes(get_string('deleteabandonedcheck', 'hotpot', $abandoned))."', 'abandoned', true".'))document.delform.submit();">'."\n";
|
||||
}
|
||||
echo '<input type=button value="'.get_string("deleteall").'" onClick="if(delcheck('."'".addslashes($strdeletecheck)."', 'all', true".'))document.delform.submit();">'."\n";
|
||||
echo '</center>'."\n";
|
||||
echo '</form>'."\n";
|
||||
}
|
||||
$this->print_report($course, $hotpot, $tables, $options);
|
||||
|
||||
return true;
|
||||
}
|
||||
function create_overview_table(&$users, &$attempts, &$questions, &$table, &$download, &$course, &$hotpot, &$abandoned) {
|
||||
function create_overview_table(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options, &$tables) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
$strtimeformat = get_string('strftimedatetime');
|
||||
$spacer = ' ';
|
||||
|
||||
// start the table
|
||||
$is_html = ($options['reportformat']=='htm');
|
||||
|
||||
$spacer = $is_html ? ' ' : ' ';
|
||||
$br = $is_html ? "<br />\n" : "\n";
|
||||
|
||||
// initialize $table
|
||||
unset($table);
|
||||
$table->border = 1;
|
||||
$table->width = 10;
|
||||
|
||||
$table->head = array(
|
||||
" ", // picture
|
||||
$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, $download),
|
||||
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"),
|
||||
get_string("score", "quiz")
|
||||
);
|
||||
$table->align = array("center", "left", "center", "center", "left", "left", "center");
|
||||
$table->wrap = array("nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap");
|
||||
$table->width = 10;
|
||||
$table->size = array(10, "*", "*", "*", "*", "*", "*");
|
||||
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 = print_user_picture($u->userid, $course->id, $u->picture, false, true);
|
||||
if (function_exists("fullname")) {
|
||||
$name = fullname($u);
|
||||
} else {
|
||||
$name = "$u->firstname $u->lastname";
|
||||
$picture = '';
|
||||
$name = fullname($u);
|
||||
if ($is_html) {
|
||||
$picture = print_user_picture($u->userid, $course->id, $u->picture, false, true);
|
||||
$name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$u->userid.'&course='.$course->id.'">'.$name.'</a>';
|
||||
}
|
||||
$name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$u->userid.'&course='.$course->id.'">'.$name.'</a>';
|
||||
$grade = isset($user->grade) ? $user->grade : $spacer;
|
||||
|
||||
$attempts = array();
|
||||
$starttimes = array();
|
||||
$durations = array();
|
||||
$scores = array();
|
||||
$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 (!empty($attempt->timefinish) && !isset($attempt->score)) {
|
||||
if ($attempt->status==HOTPOT_STATUS_ABANDONED) {
|
||||
$abandoned++;
|
||||
}
|
||||
|
||||
$attemptnumber = $attempt->attempt;
|
||||
$starttime = trim(userdate($attempt->timestart, $strtimeformat));
|
||||
|
||||
if (isset($attempt->score) && (isteacher($course->id) || $hotpot->review)) {
|
||||
if ($is_html && isset($attempt->score) && (isteacher($course->id) || $hotpot->review)) {
|
||||
$attemptnumber = '<a href="review.php?hp='.$hotpot->id.'&attempt='.$attempt->id.'">'.$attemptnumber.'</a>';
|
||||
$starttime = '<a href="review.php?hp='.$hotpot->id.'&attempt='.$attempt->id.'">'.$starttime.'</a>';
|
||||
}
|
||||
|
||||
if (isteacher($course->id)) {
|
||||
$checkbox = '<input type=checkbox name="box'.$attempt->id.'" value="'.$attempt->id.'">'.$spacer;
|
||||
if ($is_html && isteacher($course->id)) {
|
||||
$checkbox = '<input type=checkbox name="box'.$attempt->clickreportid.'" value="'.$attempt->clickreportid.'">'.$spacer;
|
||||
} else {
|
||||
$checkbox = '';
|
||||
}
|
||||
|
||||
$attempts[] = $attemptnumber;
|
||||
$starttimes[] = $checkbox.$starttime;
|
||||
|
||||
$durations[] = empty($attempt->timefinish) ? $spacer : format_time($attempt->timefinish - $attempt->timestart);
|
||||
$timetaken = empty($attempt->timefinish) ? $spacer : format_time($attempt->timefinish - $attempt->timestart);
|
||||
|
||||
$score = hotpot_format_score($attempt);
|
||||
if (is_numeric($score) && $score==$user->grade) { // best grade
|
||||
if ($is_html && is_numeric($score) && $score==$user->grade) { // best grade
|
||||
$score = '<span class="highlight">'.$score.'</span>';
|
||||
}
|
||||
$scores[] = $score;
|
||||
|
||||
array_push($data,
|
||||
$attemptnumber,
|
||||
$checkbox.$starttime,
|
||||
hotpot_format_status($attempt),
|
||||
$timetaken,
|
||||
$score
|
||||
);
|
||||
|
||||
$table->data[] = $data;
|
||||
|
||||
$data = array();
|
||||
} // end foreach $attempt
|
||||
|
||||
$attempts = implode("<br />\n", $attempts);
|
||||
$starttimes = implode("<br />\n", $starttimes);
|
||||
$durations = implode("<br />\n", $durations);
|
||||
$scores = implode("<br />\n", $scores);
|
||||
|
||||
$table->data[] = array ($picture, $name, $grade, $attempts, $starttimes, $durations, $scores);
|
||||
|
||||
$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 .= '<form method="post" action="report.php" name="deleteform" onsubmit="'."return deletecheck('".$strdeletecheck."', 'selection')".'">'."\n";
|
||||
$table->start .= '<input type="hidden" name="del" value="selection">'."\n";
|
||||
$table->start .= '<input type="hidden" name="id" value="'.$cm->id.'">'."\n";
|
||||
|
||||
$table->finish = '<center>'."\n";
|
||||
$table->finish .= '<input type="submit" value="'.get_string("deleteselected").'"> '."\n";
|
||||
if ($abandoned) {
|
||||
$table->finish .= '<input type=button value="'.get_string('deleteabandoned', 'hotpot').'" onClick="if(deletecheck('."'".addslashes(get_string('deleteabandonedcheck', 'hotpot', $abandoned))."', 'abandoned', true".'))document.deleteform.submit();">'."\n";
|
||||
}
|
||||
$table->finish .= '<input type=button value="'.get_string("deleteall").'" onClick="if(deletecheck('."'".addslashes($strdeletecheck)."', 'all', true".'))document.deleteform.submit();">'."\n";
|
||||
$table->finish .= '</center>'."\n";
|
||||
$table->finish .= '</form>'."\n";
|
||||
}
|
||||
|
||||
$tables[] = &$table;
|
||||
}
|
||||
function print_javascript() {
|
||||
function deleteform_javascript() {
|
||||
$strselectattempt = addslashes(get_string('selectattempt','hotpot'));
|
||||
print <<<END_OF_JAVASCRIPT
|
||||
return <<<END_OF_JAVASCRIPT
|
||||
|
||||
<script type="text/javascript">
|
||||
<!--
|
||||
function delcheck(p, v, x) {
|
||||
function deletecheck(p, v, x) {
|
||||
var r = false; // result
|
||||
|
||||
// get length of form elements
|
||||
var f = document.delform;
|
||||
var f = document.deleteform;
|
||||
var l = f ? f.elements.length : 0;
|
||||
|
||||
// count selected items, if necessary
|
||||
|
@ -4,39 +4,28 @@
|
||||
|
||||
class hotpot_report extends hotpot_default_report {
|
||||
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions) {
|
||||
function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options) {
|
||||
|
||||
global $download;
|
||||
optional_variable($download, "");
|
||||
$this->create_scores_table($hotpot, $course, $users, $attempts, $questions, $options, $tables=array());
|
||||
|
||||
$this->create_scores_table($users, $attempts, $questions, $s_table=NULL, $download, $course, $hotpot);
|
||||
|
||||
switch ($download) {
|
||||
case 'txt':
|
||||
$this->print_text($course, $hotpot, $s_table);
|
||||
break;
|
||||
|
||||
case 'xls':
|
||||
$this->print_excel($course, $hotpot, $s_table);
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->print_html($cm, $s_table, 'simplestat');
|
||||
}
|
||||
$this->print_report($course, $hotpot, $tables, $options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function create_scores_table(&$users, &$attempts, &$questions, &$table, $download, $course, $hotpot) {
|
||||
function create_scores_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
$download = ($options['reportformat']=='htm') ? false : true;
|
||||
$is_html = ($options['reportformat']=='htm');
|
||||
$blank = ($download ? '' : ' ');
|
||||
$no_value = ($download ? '' : '-');
|
||||
|
||||
$allow_review = true; // (!$download && (isteacher($course->id) || $hotpot->review));
|
||||
$allow_review = true; // ($options['reportformat']=='htm' && (isteacher($course->id) || $hotpot->review));
|
||||
|
||||
// start the table
|
||||
unset($table);
|
||||
$table->border = 1;
|
||||
|
||||
$table->head = array();
|
||||
@ -44,16 +33,16 @@ class hotpot_report extends hotpot_default_report {
|
||||
$table->size = array();
|
||||
|
||||
// picture column, if required
|
||||
if (!$download) {
|
||||
$table->head = array(' ');
|
||||
$table->align = array('center');
|
||||
$table->size = array(10);
|
||||
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, $download),
|
||||
hotpot_grade_heading($hotpot, $options),
|
||||
get_string("attempt", "quiz")
|
||||
);
|
||||
array_push($table->align, "left", "center", "center");
|
||||
@ -84,12 +73,8 @@ class hotpot_report extends hotpot_default_report {
|
||||
$u = &$user->attempts[0];
|
||||
|
||||
$picture = '';
|
||||
if (function_exists("fullname")) {
|
||||
$name = fullname($u);
|
||||
} else {
|
||||
$name = "$u->firstname $u->lastname";
|
||||
}
|
||||
if (!$download) { // html
|
||||
$name = fullname($u);
|
||||
if ($is_html) {
|
||||
$picture = print_user_picture($u->userid, $course->id, $u->picture, false, true);
|
||||
$name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$u->userid.'&course='.$course->id.'">'.$name.'</a>';
|
||||
}
|
||||
@ -104,33 +89,45 @@ class hotpot_report extends hotpot_default_report {
|
||||
$grade = $no_value;
|
||||
}
|
||||
|
||||
$br = '';
|
||||
$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 (!$download) {
|
||||
array_push($data, $picture);
|
||||
if ($is_html) {
|
||||
if ($attemptcount>1) {
|
||||
$text = $picture;
|
||||
$picture = NULL;
|
||||
$picture->text = $text;
|
||||
$picture->rowspan = $attemptcount;
|
||||
}
|
||||
$data[] = $picture;
|
||||
}
|
||||
array_push($data, $name, $grade);
|
||||
$start_col = count($data);
|
||||
|
||||
$data[] = ''; // attempt number
|
||||
foreach ($questions as $question) {
|
||||
$data[] = '';
|
||||
}
|
||||
array_push($data, '', ''); // penalties and raw score
|
||||
|
||||
foreach ($user->attempts as $attempt) {
|
||||
$col = $start_col;
|
||||
$is_best_grade = (!$download && $attempt->score==$user->grade);
|
||||
|
||||
// attempt number
|
||||
// set flag if this is best grade
|
||||
$is_best_grade = ($is_html && $attempt->score==$user->grade);
|
||||
|
||||
// get attempt number
|
||||
$attemptnumber= $attempt->attempt;
|
||||
if ($allow_review) {
|
||||
$attemptnumber = '<a href="review.php?hp='.$hotpot->id.'&attempt='.$attempt->id.'">'.$attemptnumber.'</a>';
|
||||
if ($is_html && $allow_review) {
|
||||
$attemptnumber = '<a href="review.php?hp='.$hotpot->id.'&attempt='.$attempt->id.'">'.$attemptnumber.'</a>';
|
||||
}
|
||||
if ($is_best_grade) {
|
||||
$score = '<span class="highlight">'.$attemptnumber.'</span>';
|
||||
}
|
||||
$data[$col++] .= $br.$attemptnumber;
|
||||
$data[] = $attemptnumber;
|
||||
|
||||
// get responses to questions in this attempt by this user
|
||||
foreach ($questions as $question) {
|
||||
@ -152,7 +149,8 @@ class hotpot_report extends hotpot_default_report {
|
||||
} else {
|
||||
$score = $no_value;
|
||||
}
|
||||
$data[$col++] .= $br.$score;
|
||||
|
||||
$data[] = $score;
|
||||
} // foreach $questions
|
||||
|
||||
if (isset($attempt->penalties)) {
|
||||
@ -167,6 +165,8 @@ class hotpot_report extends hotpot_default_report {
|
||||
} else {
|
||||
$penalties = $no_value;
|
||||
}
|
||||
$data[] = $penalties;
|
||||
|
||||
if (isset($attempt->score)) {
|
||||
$score = $attempt->score;
|
||||
if (is_numeric($score)) {
|
||||
@ -179,21 +179,25 @@ class hotpot_report extends hotpot_default_report {
|
||||
} else {
|
||||
$score = $no_value;
|
||||
}
|
||||
$data[] = $score;
|
||||
|
||||
$data[$col++] .= $br.$penalties;
|
||||
$data[$col++] .= $br.$score;
|
||||
$br = ($download) ? "\n" : '<br />';
|
||||
// append data for this attempt
|
||||
$table->data[] = $data;
|
||||
|
||||
// reset data array for next attempt, if any
|
||||
$data = array();
|
||||
|
||||
} // end foreach $attempt
|
||||
|
||||
// append data for this user
|
||||
$table->data[] = $data;
|
||||
|
||||
$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 (!$download) {
|
||||
if ($is_html) {
|
||||
$averages[] = $blank;
|
||||
}
|
||||
array_push($averages, get_string('average', 'hotpot'));
|
||||
@ -236,6 +240,8 @@ class hotpot_report extends hotpot_default_report {
|
||||
$col++;
|
||||
}
|
||||
$table->foot = array($averages);
|
||||
|
||||
$tables[] = &$table;
|
||||
}
|
||||
|
||||
} // end class
|
||||
|
@ -5,30 +5,27 @@
|
||||
// This is the "graphical" structure of the hotpot mod:
|
||||
//-----------------------------------------------------------
|
||||
//
|
||||
// hotpot
|
||||
// (CL, pk->id, files)
|
||||
// hotpot
|
||||
// (CL, pk->id,
|
||||
// fk->course, files)
|
||||
// |
|
||||
// +--------------+--------------+
|
||||
// | |
|
||||
// | |
|
||||
// hotpot_attempts hotpot_questions
|
||||
// (UL, pk->id, (UL, pk->id,
|
||||
// fk->hotpot) fk->hotpot, text)
|
||||
// | | |
|
||||
// | | |
|
||||
// +--------------+--------------+ |
|
||||
// | |
|
||||
// | |
|
||||
// hotpot_responses |
|
||||
// (UL, pk->id, |
|
||||
// fk->attempt, question, |
|
||||
// correct, wrong, ignored) |
|
||||
// | |
|
||||
// | |
|
||||
// +-----------+-----------+
|
||||
// |
|
||||
// hotpot_strings
|
||||
// (UL, pk->id)
|
||||
// +--------------+---------------+
|
||||
// | |
|
||||
// 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
|
||||
@ -38,257 +35,438 @@
|
||||
// files->table may have files
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
// It is not necessary to backup "questions", "responses"
|
||||
// and "strings", because they can be restored from the
|
||||
// "details" field of the "attempts" records
|
||||
//-----------------------------------------------------------
|
||||
|
||||
require_once ("$CFG->dirroot/mod/hotpot/lib.php");
|
||||
require_once ("$CFG->dirroot/mod/hotpot/lib.php");
|
||||
|
||||
//This function executes all the restore procedure about this mod
|
||||
function hotpot_restore_mods($mod, $restore) {
|
||||
//This function restores a single hotpot activity
|
||||
function hotpot_restore_mods($mod, $restore) {
|
||||
|
||||
// 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")
|
||||
// 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'
|
||||
// $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 : 0=existing course (replace), 1=existing course (append), 2=new course
|
||||
// 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'==0, otherwise false
|
||||
// original_wwwroot : 'http://your.server.com/moodle'
|
||||
// $restore is an object
|
||||
// backup_unique_code : xxxxxxxxxx
|
||||
// file : '/full/path/to/backupfile.zip'
|
||||
// mods : an array of $modinfo's (see below)
|
||||
// restoreto : 0=existing course (replace), 1=existing course (append), 2=new course
|
||||
// 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'==0, 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)
|
||||
// $modinfo is an array
|
||||
// 'modname' : array( 'restore'=> 0=no 1=yes, 'userinfo' => 0=no 1=yes)
|
||||
|
||||
$status = true;
|
||||
$status = true;
|
||||
|
||||
//Get data record for this instance of the mod
|
||||
$data = backup_getid($restore->backup_unique_code, $mod->modtype, $mod->id);
|
||||
if ($data) {
|
||||
// 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 => array of info for this instance of the mod
|
||||
|
||||
// short cut to xmlized info
|
||||
$info = &$data->info['MOD']['#'];
|
||||
// $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);
|
||||
|
||||
// build the new record
|
||||
$hotpot = NULL;
|
||||
$hotpot->course = $restore->course_id;
|
||||
$more_restore = '';
|
||||
|
||||
// don't include these fields in the hotpot record
|
||||
$excluded_TAGS = array('MODTYPE', 'ID', 'COURSE', 'ATTEMPT_DATA');
|
||||
|
||||
// fill in the fields
|
||||
$TAGS = array_keys($info);
|
||||
foreach ($TAGS as $TAG) {
|
||||
|
||||
if (!in_array($TAG, $excluded_TAGS)) {
|
||||
$tag = strtolower($TAG);
|
||||
$hotpot->$tag = backup_todb($info[$TAG][0]['#']);
|
||||
}
|
||||
}
|
||||
|
||||
// insert the record
|
||||
$hotpot->id = insert_record ('hotpot', $hotpot);
|
||||
if (is_numeric($hotpot->id)) {
|
||||
|
||||
// Do some output
|
||||
echo '<ul><li>'.get_string('modulename', 'hotpot').' "'.$hotpot->name.'"<br>';
|
||||
backup_flush(300);
|
||||
|
||||
// save the new id (required for log retore later on)
|
||||
backup_putid($restore->backup_unique_code, $mod->modtype, $mod->id, $hotpot->id);
|
||||
|
||||
// backup user info, if required
|
||||
if ($restore->mods[$mod->modtype]->userinfo) {
|
||||
|
||||
// are we overwriting a course?
|
||||
if ($restore->deleting) {
|
||||
|
||||
// remove previous attempts, questions and responses for this quiz
|
||||
$select = "hotpot='$hotpot->id'";
|
||||
if ($attempts = get_records_select('hotpot_attempts', $select)) {
|
||||
$ids = implode(',', array_keys($attempts));
|
||||
delete_records_select('hotpot_responses', "attempt IN ($ids)");
|
||||
}
|
||||
delete_records_select('hotpot_questions', $select);
|
||||
delete_records_select('hotpot_attempts', $select);
|
||||
}
|
||||
|
||||
// don't transfer these fields to the attempt records
|
||||
$excluded_TAGS = array('hotpot');
|
||||
|
||||
$i = 0;
|
||||
while ($status && isset($info['ATTEMPT_DATA'][$i]['#'])) {
|
||||
|
||||
$ii = 0;
|
||||
while ($status && isset($info['ATTEMPT_DATA'][$i]['#']['ATTEMPT'][$ii]['#'])) {
|
||||
|
||||
// shortcut to user info record
|
||||
$info_record = &$info['ATTEMPT_DATA'][$i]['#']['ATTEMPT'][$ii]['#'];
|
||||
|
||||
$attempt = NULL;
|
||||
$attempt->hotpot = $hotpot->id;
|
||||
|
||||
$TAGS = array_keys($info_record);
|
||||
foreach ($TAGS as $TAG) {
|
||||
|
||||
if (!in_array($TAG, $excluded_TAGS)) {
|
||||
|
||||
$value = backup_todb($info_record[$TAG][0]['#']);
|
||||
|
||||
if ($TAG=='USERID') {
|
||||
$user = backup_getid($restore->backup_unique_code, 'user', $value);
|
||||
if ($user) {
|
||||
$value = $user->new_id;
|
||||
} else {
|
||||
$status = false; // this shouldn't happen
|
||||
}
|
||||
}
|
||||
|
||||
$tag = strtolower($TAG);
|
||||
$attempt->$tag = $value;
|
||||
}
|
||||
} // end foreach $TAGS
|
||||
|
||||
// store old attempt id
|
||||
$attempt->old_id = $attempt->id;
|
||||
unset($attempt->id);
|
||||
|
||||
// add the attempt record
|
||||
$attempt->id = insert_record ('hotpot_attempts', $attempt);
|
||||
if (is_numeric($attempt->id)) {
|
||||
|
||||
// save the new id (required for log retore later on)
|
||||
backup_putid($restore->backup_unique_code, 'hotpot_attempts', $attempt->old_id, $attempt->id);
|
||||
|
||||
// remove slashes added by backup_todb(), otherwise xmlize() will complain
|
||||
$attempt->details = stripslashes($attempt->details);
|
||||
|
||||
// add questions and responses in attempt $attempt->details
|
||||
hotpot_add_attempt_details($attempt);
|
||||
|
||||
} else { // failed to insert $attempt record
|
||||
$status = false;
|
||||
}
|
||||
|
||||
// do some output, if required
|
||||
if ($status) {
|
||||
if ($ii%10==0) {
|
||||
echo '.';
|
||||
if ($ii%200==0) {
|
||||
echo '<br>';
|
||||
backup_flush(300);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ii++;
|
||||
} // end while $info_record
|
||||
|
||||
$i++;
|
||||
} // end while $info_records
|
||||
}
|
||||
|
||||
// Finalize ul
|
||||
echo "</li></ul>";
|
||||
// print a message after each hotpot is backed up
|
||||
$more_restore .= 'print "<li>".get_string("modulename", "hotpot")." "".$record->name.""</li>";';
|
||||
$more_restore .= 'backup_flush(300);';
|
||||
|
||||
if ($restore->mods['hotpot']->userinfo) {
|
||||
if (isset($xml["STRING_DATA"]) && isset($xml["QUESTION_DATA"])) {
|
||||
// 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);';
|
||||
} else {
|
||||
// could not add hotpot record
|
||||
$status = false;
|
||||
// HotPot v2.0.x (regenerate questions, responses and strings from attempt details)
|
||||
$more_restore .= '$status = hotpot_restore_attempts($restore, $status, $xml, $record, true);';
|
||||
}
|
||||
|
||||
} else {
|
||||
// could not get $data for this hotpot quiz
|
||||
$status = false;
|
||||
}
|
||||
|
||||
return $status;
|
||||
$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', 'string'
|
||||
);
|
||||
}
|
||||
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
|
||||
|
||||
$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 .= '$record->details=stripslashes($record->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 (isset($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();
|
||||
}
|
||||
|
||||
//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;
|
||||
$status = hotpot_restore_records(
|
||||
$restore, $status, $xml, 'hotpot_attempts', $foreignkeys, $more_restore, 'ATTEMPT_DATA', 'ATTEMPT'
|
||||
);
|
||||
|
||||
switch ($log->action) {
|
||||
if ($hotpot_v20) {
|
||||
if ($status) {
|
||||
global $CFG;
|
||||
// based on code in "mod/hotpot/db/update_to_v2.php"
|
||||
execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=1 WHERE hotpot=$record->id AND timefinish=0 AND score IS NULL", false);
|
||||
execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=3 WHERE hotpot=$record->id AND timefinish>0 AND score IS NULL", false);
|
||||
execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET status=4 WHERE hotpot=$record->id AND timefinish>0 AND score IS NOT NULL", false);
|
||||
execute_sql("UPDATE {$CFG->prefix}hotpot_attempts SET clickreportid=id WHERE hotpot=$record->id AND clickreportid IS NULL", false);
|
||||
}
|
||||
} else {
|
||||
$status = hotpot_restore_clickreportids($restore, $status);
|
||||
unset($GLOBALS["hotpot_backup_clickreportids"]); // tidy up
|
||||
}
|
||||
|
||||
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;
|
||||
return $status;
|
||||
}
|
||||
function hotpot_restore_clickreportids(&$restore, $status) {
|
||||
// update clickreport ids, if any
|
||||
global $CFG;
|
||||
$sql = '';
|
||||
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;
|
||||
$sql .= "UPDATE {$CFG->prefix}hotpot_attempts SET clickreportid=$new_clickreportid WHERE id=$id;\n";
|
||||
} else {
|
||||
// New clickreport id could not be found
|
||||
print "<ul><li>New clickreportid could not be found: attempt id=$id, clickreportid=$clickreportid</li></ul>";
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($status && $sql) {
|
||||
if (execute_sql($sql, false)) {
|
||||
// do nothing (update was ok :-)
|
||||
} else {
|
||||
print "<ul><li>Clickreportids could not be updated</li></ul>";
|
||||
$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) {
|
||||
// $xml is an XML tree for an attempt record
|
||||
// $record is the newly added attempt record
|
||||
|
||||
if (empty($record->details)) {
|
||||
$status = true;
|
||||
} else {
|
||||
unset($details);
|
||||
$details->attempt = $record->id;
|
||||
$details->details = $record->details;
|
||||
|
||||
if (insert_record('hotpot_details', $details)) {
|
||||
$status = true;
|
||||
} else {
|
||||
print "<ul><li>Details record could not be updated: attempt=$record->attempt</li></ul>";
|
||||
$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;
|
||||
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 (empty($xml_records)) {
|
||||
// do nothing
|
||||
} else {
|
||||
$ii = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (empty($xml_record)) {
|
||||
// do nothing
|
||||
} else {
|
||||
$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));
|
||||
|
||||
case "view all":
|
||||
$log->url = "index.php?id=".$log->course;
|
||||
$status = true;
|
||||
break;
|
||||
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)
|
||||
|
||||
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;
|
||||
// $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
|
||||
|
||||
unset($record);
|
||||
|
||||
$TAGS = array_keys($xml);
|
||||
foreach ($TAGS as $TAG) {
|
||||
|
||||
$value = $xml[$TAG][0]['#'];
|
||||
if (is_string($value)) {
|
||||
|
||||
$tag = strtolower($TAG);
|
||||
$record->$tag = backup_todb($value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($foreign_keys as $key=>$value) {
|
||||
if (is_numeric($value)) {
|
||||
$record->$key = $value;
|
||||
} else {
|
||||
if (empty($record->$key)) {
|
||||
$record->$key = NULL;
|
||||
} else {
|
||||
$key_table = $value;
|
||||
$new_ids = array();
|
||||
$old_ids = explode(',', $record->$key);
|
||||
foreach ($old_ids as $old_id) {
|
||||
$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
|
||||
print "<ul><li>Foreign key could not be updated: table=$table, $key=".$record->$key."</li></ul>";
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
$record->$key = implode(',', $new_ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// check everything is OK so far
|
||||
if ($status && isset($record)) {
|
||||
|
||||
default:
|
||||
// Oops, unknown $log->action
|
||||
print "<p>action (".$log->module."-".$log->action.") unknown. Not restored</p>";
|
||||
break;
|
||||
// store old record id, if necessary
|
||||
if (isset($record->id)) {
|
||||
$record->old_id = $record->id;
|
||||
unset($record->id);
|
||||
}
|
||||
|
||||
} // end switch
|
||||
// if there is a secondary key field ...
|
||||
if ($secondary_key) {
|
||||
// check to see if a record with the same value already exists
|
||||
$key_record = get_record($table, $secondary_key, $record->$secondary_key);
|
||||
if ($key_record) {
|
||||
// set new record id from already existing record
|
||||
$record->id = $key_record->id;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($record->id)) {
|
||||
// add the $record (and get new id)
|
||||
$record->id = 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
|
||||
print "<ul><li>Record could not be added: table=$table</li></ul>";
|
||||
$status = false;
|
||||
}
|
||||
|
||||
return $status ? $log : 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
|
||||
print "<p>action (".$log->module."-".$log->action.") unknown. Not restored</p>";
|
||||
break;
|
||||
|
||||
} // end switch
|
||||
|
||||
return $status ? $log : false;
|
||||
}
|
||||
?>
|
||||
|
@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
if (! $attempt = get_record("hotpot_attempts", "id", $attempt)) {
|
||||
error("No such attempt ID exists");
|
||||
error("Attempt ID was incorrect");
|
||||
}
|
||||
|
||||
require_login($course->id);
|
||||
@ -70,45 +70,38 @@
|
||||
|
||||
print_header($title, $heading, $navigation, "", "", true, $button, navmenu($course, $cm));
|
||||
|
||||
|
||||
echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
|
||||
print '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
|
||||
|
||||
print_heading($hotpot->name);
|
||||
|
||||
// format attempt properties
|
||||
if (!empty($attempt->timefinish)) {
|
||||
$attempt->timecompleted = userdate($attempt->timefinish);
|
||||
$attempt->timetaken = format_time($attempt->timefinish - $attempt->timestart);
|
||||
} else {
|
||||
$attempt->timecompleted = '-';
|
||||
$attempt->timetaken = '-';
|
||||
}
|
||||
$attempt->score = hotpot_format_score($attempt);
|
||||
hotpot_print_attempt_summary($hotpot, $attempt);
|
||||
hotpot_print_review_buttons($course, $hotpot, $attempt);
|
||||
|
||||
$html = '';
|
||||
$action = isteacher($course->id) ? optional_param('action') : '';
|
||||
if ($action) {
|
||||
|
||||
// start table
|
||||
$html .= '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">'."\n";
|
||||
$xml = get_field('hotpot_details', 'details', 'attempt', $attempt->id);
|
||||
|
||||
// add attempt properties
|
||||
$fields = array('attempt', 'score', 'penalties', 'timetaken', 'timecompleted');
|
||||
foreach ($fields as $field) {
|
||||
if (isset($attempt->$field)) {
|
||||
$module = ($field=='penalties') ? 'hotpot' : 'quiz';
|
||||
$html .= '<tr><th align="right" width="100" class="generaltableheader">'.get_string($field, $module).':</th><td class="generaltablecell">'.$attempt->$field.'</td></tr>';
|
||||
print '<hr>';
|
||||
switch ($action) {
|
||||
case 'showxmltree':
|
||||
print '<pre id="contents">';
|
||||
$xml_tree = new hotpot_xml_tree($xml, "['hpjsresult']['#']");
|
||||
print_r ($xml_tree->xml_value('fields'));
|
||||
print '</pre>';
|
||||
break;
|
||||
case 'showxmlsource':
|
||||
print htmlspecialchars($xml);
|
||||
break;
|
||||
default:
|
||||
print "Action '$action' not recognized";
|
||||
}
|
||||
print '<hr>';
|
||||
|
||||
} else {
|
||||
hotpot_print_attempt_details($hotpot, $attempt);
|
||||
}
|
||||
|
||||
// finish table
|
||||
$html .= '</table>';
|
||||
|
||||
print_simple_box_start("center", "80%", "#ffffff", 0);
|
||||
print $html;
|
||||
print_simple_box_end();
|
||||
|
||||
print_continue("report.php?id=$cm->id");
|
||||
hotpot_print_attempt_details($hotpot, $attempt);
|
||||
print_continue("report.php?id=$cm->id");
|
||||
hotpot_print_review_buttons($course, $hotpot, $attempt);
|
||||
|
||||
print_footer($course);
|
||||
|
||||
@ -116,6 +109,69 @@
|
||||
// functions
|
||||
///////////////////////////
|
||||
|
||||
function hotpot_print_attempt_summary(&$hotpot, &$attempt) {
|
||||
// start table
|
||||
print_simple_box_start("center", "80%", "#ffffff", 0);
|
||||
print '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">'."\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 '<tr><th align="right" width="100" class="generaltableheader">'.$name.':</th><td class="generaltablecell">'.$value.'</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
// finish table
|
||||
print '</table>';
|
||||
print_simple_box_end();
|
||||
}
|
||||
function hotpot_print_review_buttons(&$course, &$hotpot, &$attempt) {
|
||||
print "\n".'<table border="0" align="center" cellpadding="2" cellspacing="2" class="generaltable">';
|
||||
print "\n<tr>\n".'<td align="center">';
|
||||
print_single_button("report.php?hp=$hotpot->id", NULL, get_string('continue'), 'post');
|
||||
if (isteacher($course->id) && record_exists('hotpot_details', 'attempt', $attempt->id)) {
|
||||
print "</td>\n".'<td align="center">';
|
||||
print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmlsource", NULL, get_string('showxmlsource', 'hotpot'), 'post');
|
||||
print "</td>\n".'<td align="center">';
|
||||
print_single_button("review.php?hp=$hotpot->id&attempt=$attempt->id&action=showxmltree", NULL, get_string('showxmltree', 'hotpot'), 'post');
|
||||
$colspan = 3;
|
||||
} else {
|
||||
$colspan = 1;
|
||||
}
|
||||
print "</td>\n</tr>\n";
|
||||
print '<tr><td colspan="'.$colspan.'">';
|
||||
print_spacer(4, 1, false); // height=4, width=1, no <br>
|
||||
print "</td></tr>\n";
|
||||
print "</table>\n";
|
||||
}
|
||||
function hotpot_print_attempt_details(&$hotpot, &$attempt) {
|
||||
|
||||
// define fields to print
|
||||
@ -166,16 +222,19 @@ function hotpot_print_attempt_details(&$hotpot, &$attempt) {
|
||||
}
|
||||
$colspan = max(2, $colspan);
|
||||
|
||||
$html = '';
|
||||
|
||||
// start table of questions and responses
|
||||
$html .= '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">'."\n";
|
||||
print_simple_box_start("center", "80%", "#ffffff", 0);
|
||||
print '<table width="100%" border="1" valign="top" align="center" cellpadding="2" cellspacing="2" class="generaltable">'."\n";
|
||||
|
||||
if (empty($q)) {
|
||||
$html .= '<tr><td align="center" class="generaltablecell"><b>'.get_string("noresponses", "hotpot").'</b></td></tr>';
|
||||
print '<tr><td align="center" class="generaltablecell"><b>'.get_string("noresponses", "hotpot")."</b></td></tr>\n";
|
||||
|
||||
} else {
|
||||
foreach ($q as $question) {
|
||||
|
||||
// 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;
|
||||
@ -188,48 +247,44 @@ function hotpot_print_attempt_details(&$hotpot, &$attempt) {
|
||||
|
||||
// print question if necessary
|
||||
if (!$printedquestion) {
|
||||
$html .= '<tr><td colspan="'.$colspan.'" class="generaltablecell"><b>'.$question['name'].'</b></td></tr>';
|
||||
if ($printseparator) {
|
||||
print '<tr><td colspan="'.$colspan.'"><div class="tabledivider"></div></td></tr>'."\n";
|
||||
}
|
||||
$printseparator = true;
|
||||
|
||||
print '<tr><td colspan="'.$colspan.'" class="generaltablecell"><b>'.$question['name'].'</b></td></tr>'."\n";
|
||||
$printedquestion = true;
|
||||
}
|
||||
|
||||
// print response
|
||||
$html .= '<tr><th align="right" width="100" class="generaltableheader">'.$f[$field]['name'].':</th><td colspan="'.($colspan-1).'" class="generaltablecell">'.$text.'</td></tr>';
|
||||
print '<tr><th align="right" width="100" class="generaltableheader">'.$f[$field]['name'].':</th><td colspan="'.($colspan-1).'" class="generaltablecell">'.$text.'</td></tr>'."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add row of numeric fields
|
||||
$html .= '<tr>';
|
||||
print '<tr>';
|
||||
foreach ($numfields as $field) {
|
||||
if ($f[$field]['count']) {
|
||||
|
||||
// print question if necessary
|
||||
if (!$printedquestion) {
|
||||
$html .= '<tr><td colspan="'.$colspan.'" class="generaltablecell"><b>'.$question['name'].'</b></td></tr>';
|
||||
print '<td colspan="'.$colspan.'" class="generaltablecell"><b>'.$question['name']."</b></td></tr>\n<tr>";
|
||||
$printedquestion = true;
|
||||
}
|
||||
|
||||
// print numeric response
|
||||
$value = isset($question[$field]) ? $question[$field] : '-';
|
||||
$html .= '<th align="right" width="100" class="generaltableheader">'.$f[$field]['name'].':</th><td class="generaltablecell">'.$value.'</td>';
|
||||
print '<th align="right" width="100" class="generaltableheader">'.$f[$field]['name'].':</th><td class="generaltablecell">'.$value.'</td>';
|
||||
}
|
||||
}
|
||||
$html .= '</tr>';
|
||||
|
||||
// add separator
|
||||
if ($printedquestion) {
|
||||
$html .= '<tr><td colspan="'.$colspan.'"><div class="tabledivider"></div></td></tr>';
|
||||
}
|
||||
|
||||
print "</tr>\n";
|
||||
|
||||
} // foreach $q
|
||||
}
|
||||
|
||||
// finish table
|
||||
$html .= '</table>';
|
||||
|
||||
print_simple_box_start("center", "80%", "#ffffff", 0);
|
||||
print $html;
|
||||
print "</table>\n";
|
||||
print_simple_box_end();
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,20 +1,19 @@
|
||||
<?PHP // $Id$
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/// Code fragment to define the version of hotpot
|
||||
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$module->version = 2005031418; // release date of this version (see note below)
|
||||
$module->release = 'v2.0.8'; // human-friendly version name (used in mod/hotpot/lib.php)
|
||||
$module->requires = 2003091111; // Requires at least Moodle version 1.1.1
|
||||
$module->cron = 0; // period for cron to check this module (secs)
|
||||
|
||||
// interpretation of YYYYMMDDXY version numbers
|
||||
// YYYY : year
|
||||
// MM : month
|
||||
// DD : day
|
||||
// X : point release version 1,2,3 etc
|
||||
// Y : increment between point releases
|
||||
|
||||
?>
|
||||
<?PHP // $Id$
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/// Code fragment to define the version of hotpot
|
||||
/// This fragment is called by moodle_needs_upgrading() and /admin/index.php
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$module->version = 2005090700; // release date of this version (see note below)
|
||||
$module->release = 'v2.1.0'; // 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
|
||||
// MM : month
|
||||
// DD : day
|
||||
// X : point release version 1,2,3 etc
|
||||
// Y : increment between point releases
|
||||
|
||||
?>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?PHP
|
||||
// $Id$
|
||||
<?PHP // $Id$
|
||||
|
||||
/// This page prints a hotpot quiz
|
||||
|
||||
@ -8,7 +7,7 @@
|
||||
|
||||
$id = optional_param("id"); // Course Module ID, or
|
||||
$hp = optional_param("hp"); // hotpot ID
|
||||
|
||||
|
||||
if ($id) {
|
||||
if (! $cm = get_record("course_modules", "id", $id)) {
|
||||
error("Course Module ID was incorrect");
|
||||
@ -50,8 +49,8 @@
|
||||
$button = update_module_button($cm->id, $course->id, get_string("modulename", "hotpot").'" style="font-size:0.75em;');
|
||||
$loggedinas = '<span class="logininfo">'.user_login_string($course, $USER).'</span>';
|
||||
|
||||
|
||||
$time = time();
|
||||
$hppassword = optional_param('hppassword');
|
||||
|
||||
if (!isteacher($course->id)) {
|
||||
// check this quiz is available to this student
|
||||
@ -60,7 +59,7 @@
|
||||
$error = '';
|
||||
|
||||
// check quiz is visible
|
||||
if (!$cm->visible) {
|
||||
if (!hotpot_is_visible($cm)) {
|
||||
$error = get_string("activityiscurrentlyhidden");
|
||||
|
||||
// check network address
|
||||
@ -72,7 +71,7 @@
|
||||
$error = get_string("nomoreattempts", "quiz");
|
||||
|
||||
// get password
|
||||
} else if ($hotpot->password && empty($_POST['hppassword'])) {
|
||||
} else if ($hotpot->password && empty($hppassword)) {
|
||||
|
||||
print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas, false);
|
||||
print_heading($hotpot->name);
|
||||
@ -104,7 +103,7 @@
|
||||
exit;
|
||||
|
||||
// check password
|
||||
} else if ($hotpot->password && strcmp($hotpot->password, $_POST['hppassword'])) {
|
||||
} else if ($hotpot->password && strcmp($hotpot->password, $hppassword)) {
|
||||
$error = get_string("passworderror", "quiz");
|
||||
$nextpage = "view.php?id=$cm->id";
|
||||
|
||||
@ -137,14 +136,35 @@
|
||||
error("Quiz is unavailable at the moment");
|
||||
}
|
||||
|
||||
$frameset = isset($_GET['frameset']) ? $_GET['frameset'] : '';
|
||||
$get_js = optional_param('js');
|
||||
$get_css = optional_param('css');
|
||||
$framename = optional_param('framename');
|
||||
|
||||
// look for <FRAMESET> (v5)
|
||||
$frameset = '';
|
||||
$frameset_tags = '';
|
||||
if (preg_match_all('|<frameset([^>]*)>(.*?)</frameset>|is', $hp->html, $matches)) {
|
||||
$last = count($matches[0])-1;
|
||||
$frameset = $matches[2][$last];
|
||||
$frameset_tags = $matches[1][$last];
|
||||
}
|
||||
|
||||
// if HTML is being requested ...
|
||||
if (empty($_GET['js']) && empty($_GET['css'])) {
|
||||
if (empty($get_js) && empty($get_css)) {
|
||||
|
||||
$n = $hotpot->navigation;
|
||||
if (($n!=HOTPOT_NAVIGATION_FRAME && $n!=HOTPOT_NAVIGATION_IFRAME) || $frameset=='main') {
|
||||
if (empty($frameset)) {
|
||||
// HP v6
|
||||
if ($hotpot->navigation==HOTPOT_NAVIGATION_FRAME || $hotpot->navigation==HOTPOT_NAVIGATION_IFRAME) {
|
||||
$get_html = ($framename=='main');
|
||||
} else {
|
||||
$get_html = true;
|
||||
}
|
||||
} else {
|
||||
// HP5 v5
|
||||
$get_html = empty($framename);
|
||||
}
|
||||
|
||||
if ($get_html) {
|
||||
add_to_log($course->id, "hotpot", "view", "view.php?id=$cm->id", "$hotpot->id", "$cm->id");
|
||||
|
||||
$attemptid = hotpot_add_attempt($hotpot->id);
|
||||
@ -152,28 +172,125 @@
|
||||
error('Could not insert attempt record: '.$db->ErrorMsg);
|
||||
}
|
||||
|
||||
if ($n!=HOTPOT_NAVIGATION_BUTTONS) {
|
||||
$hp->remove_nav_buttons();
|
||||
}
|
||||
|
||||
$hp->adjust_media_urls();
|
||||
|
||||
$hp->insert_submission_form($attemptid);
|
||||
|
||||
if ($n==HOTPOT_NAVIGATION_GIVEUP) {
|
||||
$hp->insert_giveup_form($attemptid);
|
||||
if (empty($frameset)) {
|
||||
// HP6 v6
|
||||
if ($hotpot->navigation!=HOTPOT_NAVIGATION_BUTTONS) {
|
||||
$hp->remove_nav_buttons();
|
||||
}
|
||||
if ($hotpot->navigation==HOTPOT_NAVIGATION_GIVEUP) {
|
||||
$hp->insert_giveup_form($attemptid, '<!-- BeginTopNavButtons -->', '<!-- EndTopNavButtons -->');
|
||||
}
|
||||
$hp->insert_submission_form($attemptid, '<!-- BeginSubmissionForm -->', '<!-- EndSubmissionForm -->');
|
||||
|
||||
} else {
|
||||
// HP5 v5
|
||||
if ($hotpot->navigation!=HOTPOT_NAVIGATION_BUTTONS) {
|
||||
$hp->html = preg_replace('#NavBar\+=(.*);#', '', $hp->html);
|
||||
}
|
||||
if ($hotpot->navigation==HOTPOT_NAVIGATION_GIVEUP) {
|
||||
// $hp->insert_giveup_form($attemptid, '<!-- BeginTopNavButtons -->', '<!-- EndTopNavButtons -->');
|
||||
}
|
||||
$hp->insert_submission_form($attemptid, "var NavBar='", "';");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FEEDBACK = new Array();
|
||||
//FEEDBACK[0] = ''; // url of feedback page/script
|
||||
//FEEDBACK[1] = ''; // array of array('teachername', 'value');
|
||||
//FEEDBACK[2] = ''; // 'student name' [formmail only]
|
||||
//FEEDBACK[3] = ''; // 'student email' [formmail only]
|
||||
//FEEDBACK[4] = ''; // window width
|
||||
//FEEDBACK[5] = ''; // window height
|
||||
//FEEDBACK[6] = ''; // 'Send a message to teacher' [prompt/button text]
|
||||
//FEEDBACK[7] = ''; // 'Title'
|
||||
//FEEDBACK[8] = ''; // 'Teacher'
|
||||
//FEEDBACK[9] = ''; // 'Message'
|
||||
//FEEDBACK[10] = ''; // 'Close this window'
|
||||
|
||||
$feedback = array();
|
||||
switch ($hotpot->studentfeedback) {
|
||||
|
||||
case HOTPOT_FEEDBACK_NONE:
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
case HOTPOT_FEEDBACK_WEBPAGE:
|
||||
if (empty($hotpot->studentfeedbackurl)) {
|
||||
$hotpot->studentfeedback = HOTPOT_FEEDBACK_NONE;
|
||||
} else {
|
||||
$feedback[0] = "'$hotpot->studentfeedbackurl'";
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTPOT_FEEDBACK_FORMMAIL:
|
||||
$teachers = hotpot_feedback_teachers($course, $hotpot);
|
||||
if (empty($teachers) || empty($hotpot->studentfeedbackurl)) {
|
||||
$hotpot->studentfeedback = HOTPOT_FEEDBACK_NONE;
|
||||
} else {
|
||||
$feedback[0] = "'$hotpot->studentfeedbackurl'";
|
||||
$feedback[1] = $teachers;
|
||||
$feedback[2] = "'".fullname($USER)."'";
|
||||
$feedback[3] = "'".$USER->email."'";
|
||||
$feedback[4] = 500; // width
|
||||
$feedback[5] = 300; // height
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTPOT_FEEDBACK_MOODLEFORUM:
|
||||
$module = get_record('modules', 'name', 'forum');
|
||||
$forums = get_records('forum', 'course', "$course->id");
|
||||
if (empty($module) || empty($module->visible) || empty($forums)) {
|
||||
$hotpot->studentfeedback = HOTPOT_FEEDBACK_NONE;
|
||||
} else {
|
||||
$feedback[0] = "'$CFG->wwwroot/mod/forum/index.php?id=$course->id'";
|
||||
}
|
||||
break;
|
||||
|
||||
case HOTPOT_FEEDBACK_MOODLEMESSAGING:
|
||||
$teachers = hotpot_feedback_teachers($course, $hotpot);
|
||||
if (empty($CFG->messaging) || empty($teachers)) {
|
||||
$hotpot->studentfeedback = HOTPOT_FEEDBACK_NONE;
|
||||
} else {
|
||||
$feedback[0] = "'$CFG->wwwroot/message/discussion.php?id='";
|
||||
$feedback[1] = $teachers;
|
||||
$feedback[4] = 400; // width
|
||||
$feedback[5] = 500; // height
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if ($hotpot->studentfeedback != HOTPOT_FEEDBACK_NONE) {
|
||||
$feedback[6] = "'Send a message to teacher'";
|
||||
$feedback[7] = "'Title'";
|
||||
$feedback[8] = "'Teacher'";
|
||||
$feedback[9] = "'Message'";
|
||||
$feedback[10] = "'Close this window'";
|
||||
$js = '';
|
||||
foreach ($feedback as $i=>$str) {
|
||||
$js .= 'FEEDBACK['.$i."] = $str;\n";
|
||||
}
|
||||
$js = '<script type="text/javascript" language="javascript">'."<!--\n"."FEEDBACK = new Array();\n".$js."//--></script>\n";
|
||||
$hp->html = preg_replace('|</head>|i', "$js</head>", $hp->html, 1);
|
||||
}
|
||||
|
||||
// insert hot-potatoes.js
|
||||
$hp->insert_script(HOTPOT_JS);
|
||||
|
||||
// extract <head> tag
|
||||
// extract <head> and <body> tags
|
||||
$head = '';
|
||||
$pattern = '|^(.*)<head([^>]*)>(.*?)</head>|is';
|
||||
if (preg_match($pattern, $hp->html, $matches)) {
|
||||
$head = $matches[3];
|
||||
$pattern = '|<head([^>]*)>(.*?)</head>|is';
|
||||
if (preg_match_all($pattern, $hp->html, $matches)) {
|
||||
$last = count($matches[0])-1;
|
||||
$head = $matches[2][$last];
|
||||
|
||||
// remove <title>
|
||||
$head = preg_replace('|<title[^>]*>(.*?)</title>|is', '', $head);
|
||||
}
|
||||
|
||||
// extract <style> tags
|
||||
@ -200,17 +317,47 @@
|
||||
|
||||
// extract <body> tags
|
||||
$body = '';
|
||||
$bodytags = '';
|
||||
$pattern = '|^(.*)<body([^>]*)>(.*?)</body>|is';
|
||||
if (preg_match($pattern, $hp->html, $matches)) {
|
||||
$bodytags = $matches[2];
|
||||
$body = $matches[3];
|
||||
$body_tags = '';
|
||||
$footer = '</html>';
|
||||
|
||||
if ($frameset) {
|
||||
switch ($framename) {
|
||||
case 'top':
|
||||
print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas);
|
||||
print $footer;
|
||||
break;
|
||||
|
||||
default:
|
||||
// add a HotPot navigation frame at the top of the page
|
||||
//$rows = empty($CFG->resource_framesize) ? 85 : $CFG->resource_framesize;
|
||||
//$frameset = "\n\t".'<frame src="view.php?id='.$cm->id.'&framename=top" frameborder="0" name="top"></frame>'.$frameset;
|
||||
//$frameset_tags = preg_replace('|rows="(.*?)"|', 'rows="'.$rows.',\\1"', $frameset_tags);
|
||||
|
||||
// put navigation into var NavBar='';
|
||||
// add form to TopFrame in "WriteFeedback" function
|
||||
// OR add form to BottomFrame in "DisplayExercise" function
|
||||
// submission form: '<!-- BeginSubmissionForm -->', '<!-- EndSubmissionForm -->'
|
||||
// give up form: '<!-- BeginTopNavButtons -->', '<!-- EndTopNavButtons -->'
|
||||
|
||||
print "<HTML>\n";
|
||||
print "<HEAD>\n<TITLE>$title</TITLE>\n$styles\n$scripts</HEAD>\n";
|
||||
print "<FRAMESET$frameset_tags>$frameset</FRAMESET>\n";
|
||||
print "</HTML>\n";
|
||||
break;
|
||||
} // end switch $frameset
|
||||
exit;
|
||||
|
||||
// is there a <body> (HP6 and HP5: v6 and v4)
|
||||
} else if (preg_match_all('|<body([^>]*)>(.*?)</body>|is', $hp->html, $matches)) {
|
||||
$last = count($matches[0])-1;
|
||||
$body = $matches[2][$last];
|
||||
$body_tags = $matches[1][$last];
|
||||
|
||||
// workaround to ensure javascript onload routine for quiz is always executed
|
||||
// $bodytags will only be inserted into the <body ...> tag
|
||||
// $body_tags will only be inserted into the <body ...> tag
|
||||
// if it is included in the theme/$CFG->theme/header.html,
|
||||
// so some old or modified themes may not insert $bodytags
|
||||
if (preg_match('/onload=("|\')(.*?)(\\1)/i', $bodytags, $matches)) {
|
||||
// so some old or modified themes may not insert $body_tags
|
||||
if (preg_match('/onload=("|\')(.*?)(\\1)/i', $body_tags, $matches)) {
|
||||
$body .= ""
|
||||
.'<SCRIPT type="text/javascript">'."\n"
|
||||
."<!--\n"
|
||||
@ -227,17 +374,17 @@
|
||||
."</SCRIPT>\n"
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
$footer = '</body></html>';
|
||||
$footer = '</body>'.$footer;
|
||||
}
|
||||
|
||||
// print the quiz to the browser
|
||||
|
||||
if (isset($_GET['js'])) {
|
||||
if ($get_js) {
|
||||
print($scripts);
|
||||
exit;
|
||||
}
|
||||
if (isset($_GET['css'])) {
|
||||
if ($get_css) {
|
||||
print($styles);
|
||||
exit;
|
||||
}
|
||||
@ -249,7 +396,7 @@
|
||||
print_header(
|
||||
$title, $heading, $navigation,
|
||||
"", $head.$styles.$scripts, true, $button,
|
||||
$loggedinas, false, $bodytags
|
||||
$loggedinas, false, $body_tags
|
||||
);
|
||||
if (!empty($available_msg)) {
|
||||
notify($available_msg);
|
||||
@ -259,13 +406,9 @@
|
||||
|
||||
case HOTPOT_NAVIGATION_FRAME:
|
||||
|
||||
switch ($frameset) {
|
||||
switch ($framename) {
|
||||
case 'top':
|
||||
print_header(
|
||||
$title, $heading, $navigation,
|
||||
"", "", true, $button,
|
||||
$loggedinas
|
||||
);
|
||||
print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas);
|
||||
print $footer;
|
||||
break;
|
||||
|
||||
@ -277,15 +420,12 @@
|
||||
break;
|
||||
|
||||
default:
|
||||
// set frame height (default 85). Height can be changed by admin user
|
||||
// (Administration->Configuration->Module, Resource->Settings)
|
||||
$framesize = isset($CFG->resource_framesize) ? $CFG->resource_framesize : 85;
|
||||
|
||||
$rows = empty($CFG->resource_framesize) ? 85 : $CFG->resource_framesize;
|
||||
print "<HTML>\n";
|
||||
print "<HEAD><TITLE>$title</TITLE></HEAD>\n";
|
||||
print "<FRAMESET rows=$framesize,*>\n";
|
||||
print "<FRAME src=\"view.php?id=$cm->id&frameset=top\">\n";
|
||||
print "<FRAME src=\"view.php?id=$cm->id&frameset=main\">\n";
|
||||
print "<FRAMESET rows=$rows,*>\n";
|
||||
print "<FRAME src=\"view.php?id=$cm->id&framename=top\">\n";
|
||||
print "<FRAME src=\"view.php?id=$cm->id&framename=main\">\n";
|
||||
print "</FRAMESET>\n";
|
||||
print "</HTML>\n";
|
||||
break;
|
||||
@ -295,20 +435,20 @@
|
||||
case HOTPOT_NAVIGATION_IFRAME:
|
||||
|
||||
switch ($frameset) {
|
||||
case 'main':
|
||||
case 'main';
|
||||
print $hp->html;
|
||||
break;
|
||||
|
||||
default:
|
||||
$iframe_id = 'hotpot_iframe';
|
||||
$bodytags = " onload=\"set_iframe_height('$iframe_id')\"";
|
||||
$body_tags = " onload=\"set_iframe_height('$iframe_id')\"";
|
||||
|
||||
$iframe_js = '<SCRIPT src="iframe.js" type="text/javascript" language="javascript">'."\n";
|
||||
|
||||
print_header(
|
||||
$title, $heading, $navigation,
|
||||
"", $head.$styles.$scripts.$iframe_js, true, $button,
|
||||
$loggedinas, false, $bodytags
|
||||
$loggedinas, false, $body_tags
|
||||
);
|
||||
if (!empty($available_msg)) {
|
||||
notify($available_msg);
|
||||
@ -333,4 +473,35 @@
|
||||
print($hp->html);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
/// functions
|
||||
///////////////////////////////////
|
||||
|
||||
function hotpot_feedback_teachers(&$course, &$hotpot) {
|
||||
global $CFG;
|
||||
$teachers = get_records_sql("
|
||||
SELECT
|
||||
u.*
|
||||
FROM
|
||||
{$CFG->prefix}user AS u,
|
||||
{$CFG->prefix}user_teachers AS t
|
||||
WHERE
|
||||
t.userid = u.id
|
||||
AND t.course = $course->id
|
||||
");
|
||||
|
||||
$str = '';
|
||||
if (!empty($teachers)) {
|
||||
foreach ($teachers as $teacher) {
|
||||
if ($hotpot->studentfeedback==HOTPOT_FEEDBACK_MOODLEMESSAGING) {
|
||||
$value = $teacher->id;
|
||||
} else {
|
||||
$value =$teacher->email;
|
||||
}
|
||||
$str .= (empty($str) ? '' : ',')."new Array('".fullname($teacher)."', '$value')";
|
||||
}
|
||||
$str = 'new Array('.$str.");\n";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user