示例#1
0
function xmldb_hotpot_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $db;
    $result = true;
    //===== 1.9.0 upgrade line ======//
    if ($result && $oldversion < 2007101512) {
        // save and disable setting to display debugging messages
        $debug = $db->debug;
        $db->debug = false;
        notify('Fixing hotpot grades, this may take a while if there are many hotpots...', 'notifysuccess');
        hotpot_fix_grades();
        // restore $db->debug
        $db->debug = $debug;
    }
    // update hotpot grades from sites earlier than Moodle 1.9, 27th March 2008
    if ($result && $oldversion < 2007101513) {
        // ensure "hotpot_update_grades" function is available
        require_once $CFG->dirroot . '/mod/hotpot/lib.php';
        // save and disable setting to display debugging messages
        $debug = $db->debug;
        $db->debug = false;
        notify('Processing hotpot grades, this may take a while if there are many hotpots...', 'notifysuccess');
        hotpot_update_grades();
        // restore $db->debug
        $db->debug = $debug;
    }
    return $result;
}
示例#2
0
function hotpot_delete_selected_attempts(&$hotpot, $del)
{
    global $DB;
    $select = '';
    $params = array('hotpotid' => $hotpot->id);
    switch ($del) {
        case 'all':
            $select = "hotpot=:hotpotid";
            break;
        case 'abandoned':
            $select = "hotpot=:hotpotid AND status=" . HOTPOT_STATUS_ABANDONED;
            break;
        case 'selection':
            $ids = array();
            $data = (array) data_submitted();
            foreach ($data as $name => $value) {
                if (preg_match('/^box\\d+$/', $name)) {
                    $ids[] = intval($value);
                }
            }
            if (count($ids)) {
                list($ids, $idparams) = $DB->get_in_or_equal($ids, SQL_PARAMS_NAMED, 'crid0');
                $params = array_merge($params, $idparams);
                $select = "hotpot=:hotpotid AND clickreportid {$ids}";
            }
            break;
    }
    // delete attempts using $select, if it is set
    if ($select) {
        $table = 'hotpot_attempts';
        if ($attempts = $DB->get_records_select($table, $select, $params)) {
            hotpot_delete_and_notify($table, $select, $params, get_string('attempts', 'quiz'));
            $select = 'attempt IN (' . implode(',', array_keys($attempts)) . ')';
            $params = array();
            hotpot_delete_and_notify('hotpot_details', $select, $params, get_string('rawdetails', 'hotpot'));
            hotpot_delete_and_notify('hotpot_responses', $select, $params, get_string('answer', 'quiz'));
            // update grades for all users for this hotpot
            hotpot_update_grades($hotpot);
        }
    }
}
示例#3
0
文件: report.php 项目: r007/PMoodle
function hotpot_delete_selected_attempts(&$hotpot, $del)
{
    $select = '';
    switch ($del) {
        case 'all':
            $select = "hotpot='{$hotpot->id}'";
            break;
        case 'abandoned':
            $select = "hotpot='{$hotpot->id}' AND status=" . HOTPOT_STATUS_ABANDONED;
            break;
        case 'selection':
            $ids = array();
            $data = (array) data_submitted();
            foreach ($data as $name => $value) {
                if (preg_match('/^box\\d+$/', $name)) {
                    $ids[] = intval($value);
                }
            }
            if (count($ids)) {
                $select = "hotpot='{$hotpot->id}' AND clickreportid IN (" . implode(',', $ids) . ")";
            }
            break;
    }
    // delete attempts using $select, if it is set
    if ($select) {
        $table = 'hotpot_attempts';
        if ($attempts = get_records_select($table, $select)) {
            hotpot_delete_and_notify($table, $select, get_string('attempts', 'quiz'));
            $select = 'attempt IN (' . implode(',', array_keys($attempts)) . ')';
            hotpot_delete_and_notify('hotpot_details', $select, get_string('rawdetails', 'hotpot'));
            hotpot_delete_and_notify('hotpot_responses', $select, get_string('answer', 'quiz'));
            // update grades for all users for this hotpot
            hotpot_update_grades($hotpot);
        }
    }
}
示例#4
0
        // (N.B. this does NOT remove the attempt record, just the responses)
        delete_records("hotpot_responses", "attempt", $attempt->id);
    }
}
// remove slashes added by lib/setup.php
$attempt->details = stripslashes($attempt->details);
// add details of this attempt
hotpot_add_attempt_details($attempt);
// add slashes again, so the details can be added to the database
$attempt->details = addslashes($attempt->details);
// update the attempt record
if (!update_record("hotpot_attempts", $attempt)) {
    error("Could not update attempt record: " . $db->ErrorMsg(), $next_url);
}
// update grades for this user
hotpot_update_grades($hotpot, $attempt->userid);
// get previous attempt details record, if any
$details_exist = record_exists("hotpot_details", "attempt", $attempt->id);
// delete/update/add the attempt details record
if (empty($attempt->details)) {
    if ($details_exist) {
        delete_records("hotpot_details", "attempt", $attempt->id);
    }
} else {
    if ($details_exist) {
        set_field("hotpot_details", "details", $attempt->details, "attempt", $attempt->id);
    } else {
        unset($details);
        $details->attempt = $attempt->id;
        $details->details = $attempt->details;
        if (!insert_record("hotpot_details", $details)) {
示例#5
0
/**
 * Update grades in central gradebook
 * this function is called from db/upgrade.php
 *     it is initially called with no arguments, which forces it to get a list of all hotpots
 *     it then iterates through the hotpots, calling itself to create a grade record for each hotpot
 *
 * @param object $hotpot null means all hotpots
 * @param int $userid specific user only, 0 means all users
 */
function hotpot_update_grades($hotpot = null, $userid = 0, $nullifnone = true)
{
    global $CFG;
    if (!function_exists('grade_update')) {
        require_once $CFG->libdir . '/gradelib.php';
    }
    if (is_null($hotpot)) {
        // update (=create) grades for all hotpots
        $sql = "\n            SELECT h.*, cm.idnumber as cmidnumber\n            FROM {$CFG->prefix}hotpot h, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m\n            WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=h.id";
        if ($rs = get_recordset_sql($sql)) {
            while ($hotpot = rs_fetch_next_record($rs)) {
                hotpot_update_grades($hotpot, 0, false);
            }
            rs_close($rs);
        }
    } else {
        // update (=create) grade for a single hotpot
        if ($grades = hotpot_get_user_grades($hotpot, $userid)) {
            hotpot_grade_item_update($hotpot, $grades);
        } else {
            if ($userid && $nullifnone) {
                // no grades for this user, but we must force the creation of a "null" grade record
                $grade = new object();
                $grade->userid = $userid;
                $grade->rawgrade = null;
                hotpot_grade_item_update($hotpot, $grade);
            } else {
                // no grades and no userid
                hotpot_grade_item_update($hotpot);
            }
        }
    }
}
示例#6
0
 /**
  * store
  *
  * @param xxx $hotpot
  */
 public static function store($hotpot)
 {
     global $CFG, $DB, $USER;
     if (empty($hotpot->attempt)) {
         return;
         // no attempt record - shouldn't happen !!
     }
     if ($hotpot->attempt->userid != $USER->id) {
         return;
         // wrong userid - shouldn't happen !!
     }
     // update quiz attempt fields using incoming data
     $hotpot->attempt->score = max(0, optional_param(self::scorefield, 0, PARAM_INT));
     $hotpot->attempt->status = max(0, optional_param('status', 0, PARAM_INT));
     $hotpot->attempt->redirect = max(0, optional_param('redirect', 0, PARAM_INT));
     $hotpot->attempt->details = optional_param(self::detailsfield, '', PARAM_RAW);
     // update timemodified for this attempt
     $hotpot->attempt->timemodified = $hotpot->time;
     // time values, e.g. "2008-09-12 16:18:18 +0900",
     // need to be converted to numeric date stamps
     $timefields = array('starttime', 'endtime');
     foreach ($timefields as $timefield) {
         $hotpot->attempt->{$timefield} = 0;
         // default
         if ($time = optional_param($timefield, '', PARAM_RAW)) {
             // make sure the timezone has a "+" sign
             // Note: sometimes it gets stripped (by optional_param?)
             $time = preg_replace('/(?<= )\\d{4}$/', '+$0', trim($time));
             // convert $time to numeric date stamp
             // PHP4 gives -1 on error, whereas PHP5 give false
             $time = strtotime($time);
             if ($time && $time > 0) {
                 $hotpot->attempt->{$timefield} = $time;
             }
         }
     }
     unset($timefields, $timefield, $time);
     // set finish times
     $hotpot->attempt->timefinish = $hotpot->time;
     // increment quiz attempt duration
     $startfield = self::durationstartfield;
     // "starttime" or "timestart"
     $finishfield = self::durationfinishfield;
     // "endtime" or "timefinish"
     $duration = $hotpot->attempt->{$finishfield} - $hotpot->attempt->{$startfield};
     if (empty($hotpot->attempt->duration)) {
         $hotpot->attempt->duration = $duration;
     } else {
         if ($duration > 0) {
             $hotpot->attempt->duration += $duration;
         }
     }
     unset($duration, $startfield, $finishfield);
     // set clickreportid, (for click reporting)
     $hotpot->attempt->clickreportid = $hotpot->attempt->id;
     // check if there are any previous results stored for this attempt
     // this could happen if ...
     //     - the quiz has been resumed
     //     - clickreporting is enabled for this quiz
     if ($DB->get_field('hotpot_attempts', 'timefinish', array('id' => $hotpot->attempt->id))) {
         if ($hotpot->clickreporting) {
             // self::can_clickreporting()
             // add quiz attempt record for each form submission
             // records are linked via the "clickreportid" field
             // update timemodified and status in previous records in this clickreportid group
             $DB->set_field('hotpot_attempts', 'timemodified', $hotpot->time, array('clickreportid' => $hotpot->attempt->clickreportid));
             $DB->set_field('hotpot_attempts', 'status', $hotpot->attempt->status, array('clickreportid' => $hotpot->attempt->clickreportid));
             // add new attempt record
             unset($hotpot->attempt->id);
             if (!($hotpot->attempt->id = $DB->insert_record('hotpot_attempts', $hotpot->attempt))) {
                 print_error('error_insertrecord', 'hotpot', '', 'hotpot_attempts');
             }
         } else {
             // remove previous responses for this attempt, if required
             // (N.B. this does NOT remove the attempt record, just the responses)
             $DB->delete_records('hotpot_responses', array('attemptid' => $hotpot->attempt->id));
         }
     }
     // add details of this quiz attempt, if required
     // "hotpot_storedetails" is set by administrator
     // Site Admin -> Modules -> Activities -> HotPot
     if ($CFG->hotpot_storedetails) {
         // delete/update/add the details record
         if ($DB->record_exists('hotpot_details', array('attemptid' => $hotpot->attempt->id))) {
             $DB->set_field('hotpot_details', 'details', $hotpot->attempt->details, array('attemptid' => $hotpot->attempt->id));
         } else {
             $details = (object) array('attemptid' => $hotpot->attempt->id, 'details' => $hotpot->attempt->details);
             if (!$DB->insert_record('hotpot_details', $details, false)) {
                 print_error('error_insertrecord', 'hotpot', '', 'hotpot_details');
             }
             unset($details);
         }
     }
     // add details of this attempt
     self::store_details($hotpot->attempt);
     // update the attempt record
     if (!$DB->update_record('hotpot_attempts', $hotpot->attempt)) {
         print_error('error_updaterecord', 'hotpot', '', 'hotpot_attempts');
     }
     // regrade the quiz to take account of the latest quiz attempt score
     hotpot_update_grades($hotpot->to_stdclass(), $hotpot->attempt->userid);
 }
示例#7
0
/**
 * xmldb_hotpot_upgrade
 *
 * @param xxx $oldversion
 * @return xxx
 */
function xmldb_hotpot_upgrade($oldversion)
{
    global $CFG, $DB;
    // this flag will be set to true if any upgrade needs to empty the HotPot cache
    $empty_cache = false;
    $dbman = $DB->get_manager();
    //===== 1.9.0 upgrade line ======//
    // update hotpot grades from sites earlier than Moodle 1.9, 27th March 2008
    $newversion = 2007101511;
    if ($oldversion < $newversion) {
        // ensure "hotpot_upgrade_grades" function is available
        require_once $CFG->dirroot . '/mod/hotpot/lib.php';
        hotpot_upgrade_grades();
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2008011200;
    if ($oldversion < $newversion) {
        // remove unused config setting
        unset_config('hotpot_initialdisable');
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080301;
    if ($oldversion < $newversion) {
        // remove unused config settings
        unset_config('hotpot_showtimes');
        unset_config('hotpot_excelencodings');
        // modify table: hotpot
        $table = new xmldb_table('hotpot');
        // expected structure of hotpot table when we start this upgrade:
        // (i.e. this is how things were at the end of Moodle 1.9)
        //   id, course, name, summary, timeopen, timeclose, location, reference,
        //   outputformat, navigation, studentfeedback, studentfeedbackurl,
        //   forceplugins, shownextquiz, review, grade, grademethod, attempts,
        //   password, subnet, clickreporting, timecreated, timemodified
        // convert, move and rename fields ($newname => $oldfield)
        $fields = array('outputformat' => new xmldb_field('outputformat', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL), 'timeopen' => new xmldb_field('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'studentfeedbackurl'), 'timeclose' => new xmldb_field('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timeopen'), 'grademethod' => new xmldb_field('grademethod', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'grade'), 'sourcefile' => new xmldb_field('reference', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name'), 'sourcelocation' => new xmldb_field('location', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'sourcefile'), 'entrytext' => new xmldb_field('summary', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'sourcelocation'), 'reviewoptions' => new xmldb_field('review', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), 'attemptlimit' => new xmldb_field('attempts', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'reviewoptions'), 'gradeweighting' => new xmldb_field('grade', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'attemptlimit'));
        foreach ($fields as $newname => $field) {
            if ($dbman->field_exists($table, $field)) {
                xmldb_hotpot_fix_previous_field($dbman, $table, $field);
                $dbman->change_field_type($table, $field);
                if ($field->getName() != $newname) {
                    $dbman->rename_field($table, $field, $newname);
                }
            }
        }
        // add fields
        $fields = array(new xmldb_field('sourcefile', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name'), new xmldb_field('sourcetype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'sourcefile'), new xmldb_field('sourceitemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'sourcetype'), new xmldb_field('sourcelocation', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'sourceitemid'), new xmldb_field('configfile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'sourcelocation'), new xmldb_field('configitemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'configfile'), new xmldb_field('configlocation', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'configitemid'), new xmldb_field('entrycm', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'configlocation'), new xmldb_field('entrygrade', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '100', 'entrycm'), new xmldb_field('entrypage', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'entrygrade'), new xmldb_field('entrytext', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'entrypage'), new xmldb_field('entryformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'entrytext'), new xmldb_field('entryoptions', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'entryformat'), new xmldb_field('exitpage', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'entryoptions'), new xmldb_field('exittext', XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'exitpage'), new xmldb_field('exitformat', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'exittext'), new xmldb_field('exitoptions', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'exitformat'), new xmldb_field('exitcm', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'exitoptions'), new xmldb_field('title', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '3', 'navigation'), new xmldb_field('stopbutton', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'title'), new xmldb_field('stoptext', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'stopbutton'), new xmldb_field('usefilters', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'stoptext'), new xmldb_field('useglossary', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'usefilters'), new xmldb_field('usemediafilter', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'useglossary'), new xmldb_field('timelimit', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timeclose'), new xmldb_field('delay1', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'timelimit'), new xmldb_field('delay2', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'delay1'), new xmldb_field('delay3', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2', 'delay2'), new xmldb_field('discarddetails', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'clickreporting'));
        foreach ($fields as $field) {
            if (!$dbman->field_exists($table, $field)) {
                xmldb_hotpot_fix_previous_field($dbman, $table, $field);
                $dbman->add_field($table, $field);
            }
        }
        // remove field: forceplugins (replaced by "usemediafilter")
        $field = new xmldb_field('forceplugins', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        if ($dbman->field_exists($table, $field)) {
            $DB->execute('UPDATE {hotpot} SET ' . "usemediafilter='moodle'" . ' WHERE forceplugins=1');
            $dbman->drop_field($table, $field);
        }
        // remove field: shownextquiz (replaced by "exitcm")
        $field = new xmldb_field('shownextquiz', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        if ($dbman->field_exists($table, $field)) {
            // set exitcm to show next HotPot: -4 = hotpot::ACTIVITY_SECTION_HOTPOT
            $DB->execute('UPDATE {hotpot} SET exitcm=-4 WHERE shownextquiz=1');
            $dbman->drop_field($table, $field);
        }
        // append "id" to fields that are foreign keys in other hotpot tables
        $fields = array('hotpot_attempts' => array('hotpot'), 'hotpot_details' => array('attempt'), 'hotpot_questions' => array('hotpot'), 'hotpot_responses' => array('attempt', 'question'));
        foreach ($fields as $tablename => $fieldnames) {
            $table = new xmldb_table($tablename);
            foreach ($fieldnames as $fieldname) {
                $field = new xmldb_field($fieldname, XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
                if ($dbman->field_exists($table, $field)) {
                    // maybe we should remove all indexes and keys
                    // using this $fieldname before we rename the field
                    $dbman->rename_field($table, $field, $fieldname . 'id');
                }
            }
        }
        // create new table: hotpot_cache
        $table = new xmldb_table('hotpot_cache');
        if (!$dbman->table_exists($table)) {
            $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
            $table->add_field('hotpotid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
            $table->add_field('slasharguments', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL);
            $table->add_field('hotpot_enableobfuscate', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL);
            $table->add_field('hotpot_enableswf', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL);
            $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('sourcefile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('sourcetype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('sourcelocation', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL);
            $table->add_field('sourcelastmodified', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('sourceetag', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('configfile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('configlocation', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
            $table->add_field('configlastmodified', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('configetag', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('navigation', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
            $table->add_field('title', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
            $table->add_field('stopbutton', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, null, null, '0');
            $table->add_field('stoptext', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('usefilters', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, '0');
            $table->add_field('useglossary', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, '0');
            $table->add_field('usemediafilter', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, '0');
            $table->add_field('studentfeedback', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0');
            $table->add_field('studentfeedbackurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL);
            $table->add_field('timelimit', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
            $table->add_field('delay3', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '-1');
            $table->add_field('clickreporting', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
            $table->add_field('content', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL);
            $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL);
            $table->add_field('md5key', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL);
            // Add keys to table hotpot_cache
            $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
            $table->add_key('hotpotid', XMLDB_KEY_FOREIGN, array('hotpotid'), 'hotpot', array('id'));
            // Add indexes to table hotpot_cache
            $table->add_index('hotpotid-md5key', XMLDB_INDEX_NOTUNIQUE, array('hotpotid', 'md5key'));
            $dbman->create_table($table);
        }
        // add new logging actions
        log_update_descriptions('mod/hotpot');
        // hotpot savepoint reached
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080302;
    if ($oldversion < $newversion) {
        // navigation setting of "none" is now "0" (was "6")
        $DB->execute('UPDATE {hotpot} SET navigation=0 WHERE navigation=6');
        // navigation's "give up" button, is replaced by the "stopbutton" field
        $DB->execute('UPDATE {hotpot} SET stopbutton=0 WHERE navigation=5');
        $DB->execute('UPDATE {hotpot} SET navigation=0 WHERE navigation=5');
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080303;
    if ($oldversion < $newversion) {
        // modify table: hotpot_attempts
        $table = new xmldb_table('hotpot_attempts');
        // add field: timemodified
        $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
            $DB->execute('UPDATE {hotpot_attempts} SET timemodified = timefinish WHERE timemodified=0');
            $DB->execute('UPDATE {hotpot_attempts} SET timemodified = timestart  WHERE timemodified=0');
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080305;
    if ($oldversion < $newversion) {
        // modify table: hotpot
        $table = new xmldb_table('hotpot');
        // change fields
        //  - entrycm         (-> signed)
        //  - outputformat    (-> varchar)
        //  - timelimit       (-> signed)
        //  - delay3          (-> signed)
        //  - attemptlimit    (-> unsigned)
        //  - gradeweighting  (-> unsigned)
        //  - grademethod     (-> unsigned)
        $fields = array(new xmldb_field('entrycm', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'), new xmldb_field('outputformat', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL), new xmldb_field('timelimit', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'), new xmldb_field('delay3', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2'), new xmldb_field('attemptlimit', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), new xmldb_field('gradeweighting', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), new xmldb_field('grademethod', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'));
        foreach ($fields as $field) {
            if ($dbman->field_exists($table, $field)) {
                xmldb_hotpot_fix_previous_field($dbman, $table, $field);
                $dbman->change_field_type($table, $field);
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080306;
    if ($oldversion < $newversion) {
        // modify table: hotpot
        $table = new xmldb_table('hotpot');
        // rename field: gradelimit -> gradeweighting
        $field = new xmldb_field('gradelimit', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        if ($dbman->field_exists($table, $field)) {
            $dbman->rename_field($table, $field, 'gradeweighting');
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080308;
    if ($oldversion < $newversion) {
        // add display fields to hotpot
        // (these fields were missing from access.xml so won't be on new sites)
        $tables = array('hotpot' => array(new xmldb_field('title', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '3', 'navigation'), new xmldb_field('stopbutton', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'title'), new xmldb_field('stoptext', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'stopbutton'), new xmldb_field('usefilters', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'stoptext'), new xmldb_field('useglossary', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'usefilters'), new xmldb_field('usemediafilter', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'useglossary')));
        foreach ($tables as $tablename => $fields) {
            $table = new xmldb_table($tablename);
            foreach ($fields as $field) {
                xmldb_hotpot_fix_previous_field($dbman, $table, $field);
                if ($dbman->field_exists($table, $field)) {
                    $dbman->change_field_type($table, $field);
                } else {
                    $dbman->add_field($table, $field);
                }
            }
        }
        $table = new xmldb_table('hotpot');
        $field = new xmldb_field('forceplugins', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        if ($dbman->field_exists($table, $field)) {
            $DB->execute('UPDATE {hotpot} SET ' . "usemediafilter='moodle'" . ' WHERE forceplugins=1');
            $dbman->drop_field($table, $field);
        }
        // force certain fields to be not null
        $tables = array('hotpot' => array(new xmldb_field('entrygrade', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '100')), 'hotpot_cache' => array(new xmldb_field('stopbutton', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), new xmldb_field('usefilters', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), new xmldb_field('useglossary', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0'), new xmldb_field('studentfeedback', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0')));
        foreach ($tables as $tablename => $fields) {
            $table = new xmldb_table($tablename);
            foreach ($fields as $field) {
                if ($dbman->field_exists($table, $field)) {
                    $dbman->change_field_type($table, $field);
                }
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080309;
    if ($oldversion < $newversion) {
        // force certain text fields to be not null
        $tables = array('hotpot' => array(new xmldb_field('sourcefile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL), new xmldb_field('entrytext', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL), new xmldb_field('exittext', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL), new xmldb_field('stoptext', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL)));
        foreach ($tables as $tablename => $fields) {
            $table = new xmldb_table($tablename);
            foreach ($fields as $field) {
                if ($dbman->field_exists($table, $field)) {
                    $fieldname = $field->getName();
                    $DB->set_field_select($tablename, $fieldname, '', "{$fieldname} IS NULL");
                    $dbman->change_field_type($table, $field);
                }
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080311;
    if ($oldversion < $newversion) {
        require_once $CFG->dirroot . '/mod/hotpot/locallib.php';
        /////////////////////////////////////
        /// new file storage migrate code ///
        /////////////////////////////////////
        // set up sql strings to select HotPots with Moodle 1.x file paths (i.e. no leading slash)
        $strupdating = get_string('migratingfiles', 'hotpot');
        $select = 'h.*, cm.id AS cmid';
        $from = '{hotpot} h, {course_modules} cm, {modules} m';
        $where = 'm.name=? AND m.id=cm.module AND cm.instance=h.id AND h.sourcefile<>?' . ' AND ' . $DB->sql_like('h.sourcefile', '?', false, false, true);
        // NOT LIKE
        $params = array('hotpot', '', '/%', 0);
        $orderby = 'h.course, h.id';
        // get HotPot records that need to be updated
        if ($count = $DB->count_records_sql("SELECT COUNT('x') FROM {$from} WHERE {$where}", $params)) {
            $rs = $DB->get_recordset_sql("SELECT {$select} FROM {$from} WHERE {$where} ORDER BY {$orderby}", $params);
        } else {
            $rs = false;
        }
        if ($rs) {
            $i = 0;
            $bar = new progress_bar('hotpotmigratefiles', 500, true);
            // get file storage object
            $fs = get_file_storage();
            if (class_exists('context_course')) {
                $sitecontext = context_course::instance(SITEID);
            } else {
                $sitecontext = get_context_instance(CONTEXT_COURSE, SITEID);
            }
            $coursecontext = null;
            $modulecontext = null;
            foreach ($rs as $hotpot) {
                // apply for more script execution time (3 mins)
                upgrade_set_timeout();
                // get course context for this $hotpot
                if ($coursecontext === null || $coursecontext->instanceid != $hotpot->course) {
                    if (class_exists('context_course')) {
                        $coursecontext = context_course::instance($hotpot->course);
                    } else {
                        $coursecontext = get_context_instance(CONTEXT_COURSE, $hotpot->course);
                    }
                }
                // get module context for this $hotpot/$task
                if ($modulecontext === null || $modulecontext->instanceid != $hotpot->cmid) {
                    if (class_exists('context_module')) {
                        $modulecontext = context_module::instance($hotpot->cmid);
                    } else {
                        $modulecontext = get_context_instance(CONTEXT_MODULE, $hotpot->cmid);
                    }
                }
                // actually there shouldn't be any urls in HotPot activities,
                // but this code will also be used to convert QuizPort to TaskChain
                if (preg_match('/^https?:\\/\\//i', $hotpot->sourcefile)) {
                    $url = $hotpot->sourcefile;
                    $path = parse_url($url, PHP_URL_PATH);
                } else {
                    $url = '';
                    $path = $hotpot->sourcefile;
                }
                $path = clean_param($path, PARAM_PATH);
                // this information should be enough to access the file
                // if it has been migrated into Moodle 2.0 file system
                $old_filename = basename($path);
                $old_filepath = dirname($path);
                if ($old_filepath == '.' || $old_filepath == '') {
                    $old_filepath = '/';
                } else {
                    $old_filepath = '/' . ltrim($old_filepath, '/');
                    // require leading slash
                    $old_filepath = rtrim($old_filepath, '/') . '/';
                    // require trailing slash
                }
                // update $hotpot->sourcefile, if necessary
                if ($hotpot->sourcefile != $old_filepath . $old_filename) {
                    $hotpot->sourcefile = $old_filepath . $old_filename;
                    $DB->set_field('hotpot', 'sourcefile', $hotpot->sourcefile, array('id' => $hotpot->id));
                }
                // set $courseid and $contextid from $task->$location
                // of where we expect to find the $file
                //   0 : HOTPOT_LOCATION_COURSEFILES
                //   1 : HOTPOT_LOCATION_SITEFILES
                //   2 : HOTPOT_LOCATION_WWW (not used)
                if ($hotpot->sourcelocation) {
                    $courseid = SITEID;
                    $contextid = $sitecontext->id;
                } else {
                    $courseid = $hotpot->course;
                    $contextid = $coursecontext->id;
                }
                // we expect to need the $filehash to get a file that has been migrated
                $filehash = sha1('/' . $contextid . '/course/legacy/0' . $old_filepath . $old_filename);
                // we might also need the old file path, if the file has not been migrated
                $oldfilepath = $CFG->dataroot . '/' . $courseid . $old_filepath . $old_filename;
                // set parameters used to add file to filearea
                // (sortorder=1 siginifies the "mainfile" in this filearea)
                $file_record = array('contextid' => $modulecontext->id, 'component' => 'mod_hotpot', 'filearea' => 'sourcefile', 'sortorder' => 1, 'itemid' => 0, 'filepath' => $old_filepath, 'filename' => $old_filename);
                // initialize sourcefile settings
                $hotpot->sourcefile = $old_filepath . $old_filename;
                $hotpot->sourcetype = '';
                $hotpot->sourceitemid = 0;
                if ($file = $fs->get_file($modulecontext->id, 'mod_hotpot', 'sourcefile', 0, $old_filepath, $old_filename)) {
                    // file already exists for this context - shouldn't happen !!
                    // maybe an earlier upgrade failed for some reason ?
                    // anyway we must do this check, so that create_file_from_xxx() does not abort
                } else {
                    if ($url) {
                        // file is on an external url - unusual ?!
                        $file = false;
                        // $fs->create_file_from_url($file_record, $url);
                    } else {
                        if ($file = $fs->get_file_by_hash($filehash)) {
                            // $file has already been migrated to Moodle's file system
                            // this is the route we expect most people to come :-)
                            $file = $fs->create_file_from_storedfile($file_record, $file);
                        } else {
                            if (file_exists($oldfilepath)) {
                                // $file still exists on server's filesystem - unusual ?!
                                $file = $fs->create_file_from_pathname($file_record, $oldfilepath);
                            } else {
                                // file was not migrated and is not on server's filesystem
                                $file = false;
                            }
                        }
                    }
                }
                // if source file did not exist, notify user of the problem
                if (empty($file)) {
                    if ($url) {
                        $msg = "course_modules.id={$hotpot->cmid}, url={$url}";
                    } else {
                        $msg = "course_modules.id={$hotpot->cmid}, path={$path}";
                    }
                    $params = array('update' => $hotpot->cmid, 'onclick' => 'this.target="_blank"');
                    $msg = html_writer::link(new moodle_url('/course/modedit.php', $params), $msg);
                    $msg = get_string('sourcefilenotfound', 'hotpot', $msg);
                    echo html_writer::tag('div', $msg, array('class' => 'notifyproblem'));
                }
                // set $hotpot->sourcetype
                if ($pos = strrpos($hotpot->sourcefile, '.')) {
                    $filetype = substr($hotpot->sourcefile, $pos + 1);
                    switch ($filetype) {
                        case 'jcl':
                            $hotpot->sourcetype = 'hp_6_jcloze_xml';
                            break;
                        case 'jcw':
                            $hotpot->sourcetype = 'hp_6_jcross_xml';
                            break;
                        case 'jmt':
                            $hotpot->sourcetype = 'hp_6_jmatch_xml';
                            break;
                        case 'jmx':
                            $hotpot->sourcetype = 'hp_6_jmix_xml';
                            break;
                        case 'jqz':
                            $hotpot->sourcetype = 'hp_6_jquiz_xml';
                            break;
                        case 'rhb':
                            $hotpot->sourcetype = 'hp_6_rhubarb_xml';
                            break;
                        case 'sqt':
                            $hotpot->sourcetype = 'hp_6_sequitur_xml';
                            break;
                        case 'htm':
                        case 'html':
                        default:
                            if ($file) {
                                $pathnamehash = $fs->get_pathname_hash($modulecontext->id, 'mod_hotpot', 'sourcefile', 0, $old_filepath, $old_filename);
                                if ($contenthash = $DB->get_field('files', 'contenthash', array('pathnamehash' => $pathnamehash))) {
                                    $l1 = $contenthash[0] . $contenthash[1];
                                    $l2 = $contenthash[2] . $contenthash[3];
                                    if (file_exists("{$CFG->dataroot}/filedir/{$l1}/{$l2}/{$contenthash}")) {
                                        $hotpot->sourcetype = hotpot::get_sourcetype($file);
                                    } else {
                                        $msg = html_writer::link(new moodle_url('/course/modedit.php', array('update' => $hotpot->cmid)), "course_modules.id={$hotpot->cmid}, path={$path}");
                                        $msg .= html_writer::empty_tag('br');
                                        $msg .= "filedir path={$l1}/{$l2}/{$contenthash}";
                                        $msg = get_string('sourcefilenotfound', 'hotpot', $msg);
                                        echo html_writer::tag('div', $msg, array('class' => 'notifyproblem'));
                                    }
                                }
                            }
                    }
                }
                // JMatch has 2 output formats
                //     14 : v6  : drop down menus : hp_6_jmatch_xml_v6
                //     15 : v6+ : drag-and-drop   : hp_6_jmatch_xml_v6_plus
                // JMix has 2 output formats
                //     14 : v6  : links           : hp_6_jmix_xml_v6
                //     15 : v6+ : drag-and-drop   : hp_6_jmix_xml_v6_plus
                // since drag-and-drop is the "best" outputformat for both types of quiz,
                // we only need to worry about HotPots whose outputformat was 14 (="v6")
                // set $hotpot->outputformat
                if ($hotpot->outputformat == 14 && ($hotpot->sourcetype == 'hp_6_jmatch_xml' || $hotpot->sourcetype == 'hp_6_jmix_xml')) {
                    $hotpot->outputformat = $hotpot->sourcetype . '_v6';
                } else {
                    $hotpot->outputformat = '';
                    //  = "best" output format
                }
                $DB->update_record('hotpot', $hotpot);
                // update progress bar
                $i++;
                $bar->update($i, $count, $strupdating . ": ({$i}/{$count})");
            }
            $rs->close();
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080316;
    if ($oldversion < $newversion) {
        // because the HotPot activities were probably hidden until now
        // we need to reset the course caches (using "course/lib.php")
        require_once $CFG->dirroot . '/course/lib.php';
        $courseids = array();
        if ($hotpots = $DB->get_records('hotpot', null, '', 'id,course')) {
            foreach ($hotpots as $hotpot) {
                $courseids[$hotpot->course] = true;
            }
            $courseids = array_keys($courseids);
        }
        unset($hotpots, $hotpot);
        foreach ($courseids as $courseid) {
            rebuild_course_cache($courseid, true);
        }
        unset($courseids, $courseid);
        // reset theme cache to force inclusion of new hotpot css
        theme_reset_all_caches();
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080325;
    if ($oldversion < $newversion) {
        $table = new xmldb_table('hotpot');
        $fieldnames = array('sourceitemid', 'configitemid');
        foreach ($fieldnames as $fieldname) {
            $field = new xmldb_field($fieldname);
            if ($dbman->field_exists($table, $field)) {
                $dbman->drop_field($table, $field);
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080330;
    if ($oldversion < $newversion) {
        require_once $CFG->dirroot . '/mod/hotpot/lib.php';
        hotpot_refresh_events();
    }
    $newversion = 2010080333;
    if ($oldversion < $newversion) {
        update_capabilities('mod/hotpot');
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080339;
    if ($oldversion < $newversion) {
        $table = new xmldb_table('hotpot');
        $field = new xmldb_field('exitgrade', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0', 'exitcm');
        xmldb_hotpot_fix_previous_field($dbman, $table, $field);
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080340;
    if ($oldversion < $newversion) {
        // force all text fields to be long text, the default for Moodle 2.3 and later
        $tables = array('hotpot' => array(new xmldb_field('entrytext', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL), new xmldb_field('exittext', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL)), 'hotpot_cache' => array(new xmldb_field('content', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL)), 'hotpot_details' => array(new xmldb_field('details', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL)), 'hotpot_questions' => array(new xmldb_field('name', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL)), 'hotpot_strings' => array(new xmldb_field('string', XMLDB_TYPE_TEXT, 'long', null, XMLDB_NOTNULL)));
        foreach ($tables as $tablename => $fields) {
            $table = new xmldb_table($tablename);
            foreach ($fields as $field) {
                if ($dbman->field_exists($table, $field)) {
                    $fieldname = $field->getName();
                    $DB->set_field_select($tablename, $fieldname, '', "{$fieldname} IS NULL");
                    $dbman->change_field_type($table, $field);
                }
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080342;
    if ($oldversion < $newversion) {
        // force all MySQL integer fields to be signed, the default for Moodle 2.3 and later
        if ($DB->get_dbfamily() == 'mysql') {
            $prefix = $DB->get_prefix();
            $tables = $DB->get_tables();
            foreach ($tables as $table) {
                if (substr($table, 0, 6) == 'hotpot') {
                    $rs = $DB->get_recordset_sql("SHOW COLUMNS FROM {$CFG->prefix}{$table} WHERE type LIKE '%unsigned%'");
                    foreach ($rs as $column) {
                        // copied from as "lib/db/upgradelib.php"
                        $type = preg_replace('/\\s*unsigned/i', 'signed', $column->type);
                        $notnull = $column->null === 'NO' ? 'NOT NULL' : 'NULL';
                        $default = is_null($column->default) || $column->default === '' ? '' : "DEFAULT '{$column->default}'";
                        $autoinc = stripos($column->extra, 'auto_increment') === false ? '' : 'AUTO_INCREMENT';
                        $sql = "ALTER TABLE `{$prefix}{$table}` MODIFY COLUMN `{$column->field}` {$type} {$notnull} {$default} {$autoinc}";
                        $DB->change_database_structure($sql);
                    }
                }
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080353;
    if ($oldversion < $newversion) {
        // remove any unwanted "course_files" folders that may have been created
        // when restoring Moodle 1.9 HotPot activities to a Moodle 2.x site
        // select all HotPot activities which have a "course_files" folder
        // but whose "sourcefile" path does not require such a folder
        $select = 'f.*,' . 'h.id AS hotpotid,' . 'h.sourcefile AS sourcefile';
        $from = '{hotpot} h,' . '{course_modules} cm,' . '{context} c,' . '{files} f';
        $where = $DB->sql_like('h.sourcefile', '?', false, false, true) . ' AND h.id=cm.instance' . ' AND cm.id=c.instanceid' . ' AND c.id=f.contextid' . ' AND f.component=?' . ' AND f.filearea=?' . ' AND f.filepath=?' . ' AND f.filename=?';
        $params = array('/course_files/%', 'mod_hotpot', 'sourcefile', '/course_files/', '.');
        if ($filerecords = $DB->get_records_sql("SELECT {$select} FROM {$from} WHERE {$where}", $params)) {
            $fs = get_file_storage();
            foreach ($filerecords as $filerecord) {
                $file = $fs->get_file_instance($filerecord);
                xmldb_hotpot_move_file($file, '/');
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080366;
    if ($oldversion < $newversion) {
        if ($hotpots = $DB->get_records_select('hotpot', $DB->sql_like('sourcefile', '?'), array('%http://localhost/19/99/%'))) {
            foreach ($hotpots as $hotpot) {
                $sourcefile = str_replace('http://localhost/19/99/', '', $hotpot->sourcefile);
                $DB->set_field('hotpot', 'sourcefile', $sourcefile, array('id' => $hotpot->id));
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2010080370;
    if ($oldversion < $newversion) {
        require_once $CFG->dirroot . '/mod/hotpot/locallib.php';
        $reviewoptions = 0;
        list($times, $items) = hotpot::reviewoptions_times_items();
        foreach ($times as $timename => $timevalue) {
            foreach ($items as $itemname => $itemvalue) {
                $reviewoptions += $timevalue & $itemvalue;
            }
        }
        // $reviewoptions should now be set to 62415
        $DB->set_field('hotpot', 'reviewoptions', $reviewoptions);
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2013111685;
    if ($oldversion < $newversion) {
        $tables = array('hotpot' => array(new xmldb_field('allowpaste', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'stoptext')), 'hotpot_cache' => array(new xmldb_field('hotpot_bodystyles', XMLDB_TYPE_CHAR, '8', null, XMLDB_NOTNULL, null, null, 'slasharguments'), new xmldb_field('sourcerepositoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'sourcelocation'), new xmldb_field('configrepositoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'configlocation'), new xmldb_field('allowpaste', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'stoptext')));
        foreach ($tables as $table => $fields) {
            $table = new xmldb_table($table);
            foreach ($fields as $field) {
                xmldb_hotpot_fix_previous_field($dbman, $table, $field);
                if ($dbman->field_exists($table, $field)) {
                    $dbman->change_field_type($table, $field);
                } else {
                    $dbman->add_field($table, $field);
                }
            }
        }
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2014011694;
    if ($oldversion < $newversion) {
        require_once $CFG->dirroot . '/mod/hotpot/lib.php';
        hotpot_update_grades();
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    $newversion = 2014042111;
    if ($oldversion < $newversion) {
        $empty_cache = true;
        upgrade_mod_savepoint(true, "{$newversion}", 'hotpot');
    }
    if ($empty_cache) {
        $DB->delete_records('hotpot_cache');
    }
    return true;
}
示例#8
0
 /**
  * delete_attempts
  *
  * @param xxx $selected
  */
 public function delete_attempts($selected, $onlymyattempts = true)
 {
     global $DB, $USER;
     if ($this->can_deleteallattempts()) {
         $userid = 0;
         // i.e. any user
     } else {
         if ($this->can_deletemyattempts()) {
             $userid = $USER->id;
             $onlymyattempts = true;
         } else {
             return;
             // user is not allowed to delete attempts
         }
     }
     if ($onlymyattempts) {
         // get attempts for this user only
         $this->get_attempts();
     } else {
         // get attempts for any users
         $this->get_attempts($selected, $userid);
     }
     if (empty($selected) || !$this->attempts) {
         return;
         // nothing to do
     }
     $ids = array();
     $userids = array();
     foreach ($selected as $id => $delete) {
         if ($delete && array_key_exists($id, $this->attempts)) {
             $userid = $this->attempts[$id]->userid;
             if ($this->can_deleteallattempts() || $this->can_deletemyattempts() && $userid == $USER->id) {
                 $ids[] = $id;
                 $userids[$userid] = true;
                 unset($this->attempts[$id]);
             }
         }
     }
     if (count($ids)) {
         $DB->delete_records_list('hotpot_attempts', 'id', $ids);
         $DB->delete_records_list('hotpot_details', 'attemptid', $ids);
         $DB->delete_records_list('hotpot_responses', 'attemptid', $ids);
         $userids = array_keys($userids);
         $stdclass = $this->to_stdclass();
         foreach ($userids as $userid) {
             hotpot_update_grades($stdclass, $userid);
         }
     }
 }
示例#9
0
/**
 * Update grades in central gradebook
 *
 * @param object $hotpot null means all hotpots
 * @param int $userid specific user only, 0 mean all
 */
function hotpot_update_grades($hotpot = null, $userid = 0, $nullifnone = true)
{
    global $CFG;
    if (!function_exists('grade_update')) {
        //workaround for buggy PHP versions
        require_once $CFG->libdir . '/gradelib.php';
    }
    if ($hotpot) {
        if ($grades = hotpot_get_user_grades($hotpot, $userid)) {
            hotpot_grade_item_update($hotpot, $grades);
        } else {
            if ($userid && $nullifnone) {
                $grade = new object();
                $grade->userid = $userid;
                $grade->rawgrade = null;
                hotpot_grade_item_update($hotpot, $grade);
            } else {
                hotpot_grade_item_update($hotpot);
            }
        }
    } else {
        $sql = "SELECT h.*, cm.idnumber as cmidnumber\n                  FROM {$CFG->prefix}hotpot h, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m\n                 WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=s.id";
        if ($rs = get_recordset_sql($sql)) {
            while ($hotpot = rs_fetch_next_record($rs)) {
                hotpot_update_grades($hotpot, 0, false);
            }
            rs_close($rs);
        }
    }
}
示例#10
0
/**
 * Update all grades in gradebook.
 * this function is called from db/upgrade.php
 *     it iterates through the hotpots, calling hotpot_update_grades() to create a grade record for each hotpot
 * @global object
 */
function hotpot_upgrade_grades()
{
    global $DB;
    // upgrade (=create) grades for all hotpots
    $sql = "\n        SELECT COUNT('x')\n        FROM {hotpot} h, {course_modules} cm, {modules} m\n        WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=h.id";
    $count = $DB->count_records_sql($sql);
    $sql = "\n        SELECT h.*, cm.idnumber AS cmidnumber\n        FROM {hotpot} h, {course_modules} cm, {modules} m\n        WHERE m.name='hotpot' AND m.id=cm.module AND cm.instance=h.id";
    if ($rs = $DB->get_recordset_sql($sql)) {
        // too much debug output
        $pbar = new progress_bar('hotpotupgradegrades', 500, true);
        $i = 0;
        foreach ($rs as $hotpot) {
            $i++;
            upgrade_set_timeout(60 * 5);
            // set up timeout, may also abort execution
            hotpot_update_grades($hotpot, 0, false);
            $pbar->update($i, $count, "Updating Hotpot grades ({$i}/{$count}).");
        }
        $rs->close();
    }
}
示例#11
0
/**
 * Update hotpot grades in the gradebook
 *
 * Needed by grade_update_mod_grades() in lib/gradelib.php
 *
 * @param stdclass  $hotpot      instance object with extra cmidnumber and modname property
 * @param integer   $userid      >0 update grade of specific user only, 0 means all participants
 * @param boolean   $nullifnone  TRUE = force creation of NULL grade if this user has no grade
 * @return boolean  TRUE if successful, FALSE otherwise
 * @return void
 */
function hotpot_update_grades($hotpot = null, $userid = 0, $nullifnone = true)
{
    global $CFG, $DB;
    // get hotpot object
    require_once $CFG->dirroot . '/mod/hotpot/locallib.php';
    if ($hotpot === null) {
        // update/create grades for all hotpots
        // set up sql strings
        $strupdating = get_string('updatinggrades', 'hotpot');
        $select = 'h.*, cm.idnumber AS cmidnumber';
        $from = '{hotpot} h, {course_modules} cm, {modules} m';
        $where = 'h.id = cm.instance AND cm.module = m.id AND m.name = ?';
        $params = array('hotpot');
        // get previous record index (if any)
        if (!($config = $DB->get_record('config', array('name' => 'hotpot_update_grades')))) {
            $config = (object) array('id' => 0, 'name' => 'hotpot_update_grades', 'value' => '0');
        }
        $i_min = intval($config->value);
        if ($i_max = $DB->count_records_sql("SELECT COUNT('x') FROM {$from} WHERE {$where}", $params)) {
            if ($rs = $DB->get_recordset_sql("SELECT {$select} FROM {$from} WHERE {$where}", $params)) {
                $bar = new progress_bar('hotpotupgradegrades', 500, true);
                $i = 0;
                foreach ($rs as $hotpot) {
                    // update grade
                    if ($i >= $i_min) {
                        upgrade_set_timeout();
                        // apply for more time (3 mins)
                        hotpot_update_grades($hotpot, $userid, $nullifnone);
                    }
                    // update progress bar
                    $i++;
                    $bar->update($i, $i_max, $strupdating . ": ({$i}/{$i_max})");
                    // update record index
                    if ($i > $i_min) {
                        $config->value = "{$i}";
                        if ($config->id) {
                            $DB->update_record('config', $config);
                        } else {
                            $config->id = $DB->insert_record('config', $config);
                        }
                    }
                }
                $rs->close();
            }
        }
        // delete the record index
        if ($config->id) {
            $DB->delete_records('config', array('id' => $config->id));
        }
        return;
        // finish here
    }
    // sanity check on $hotpot->id
    if (!isset($hotpot->id)) {
        return false;
    }
    if ($hotpot->grademethod == hotpot::GRADEMETHOD_AVERAGE || $hotpot->gradeweighting < 100) {
        $precision = 1;
    } else {
        $precision = 0;
    }
    $weighting = $hotpot->gradeweighting / 100;
    // set the SQL string to determine the $grade
    switch ($hotpot->grademethod) {
        case hotpot::GRADEMETHOD_HIGHEST:
            $gradefield = "ROUND(MAX(score) * {$weighting}, {$precision}) AS grade";
            break;
        case hotpot::GRADEMETHOD_AVERAGE:
            // the 'AVG' function skips abandoned quizzes, so use SUM(score)/COUNT(id)
            $gradefield = "ROUND(SUM(score)/COUNT(id) * {$weighting}, {$precision}) AS grade";
            break;
        case hotpot::GRADEMETHOD_FIRST:
            $gradefield = "ROUND(score * {$weighting}, {$precision})";
            $gradefield = $DB->sql_concat('timestart', "'_'", $gradefield);
            $gradefield = "MIN({$gradefield}) AS grade";
            break;
        case hotpot::GRADEMETHOD_LAST:
            $gradefield = "ROUND(score * {$weighting}, {$precision})";
            $gradefield = $DB->sql_concat('timestart', "'_'", $gradefield);
            $gradefield = "MAX({$gradefield}) AS grade";
            break;
        default:
            return false;
            // shouldn't happen !!
    }
    $select = 'timefinish>0 AND hotpotid= ?';
    $params = array($hotpot->id);
    if ($userid) {
        $select .= ' AND userid = ?';
        $params[] = $userid;
    }
    $sql = "SELECT userid, {$gradefield} FROM {hotpot_attempts} WHERE {$select} GROUP BY userid";
    $grades = array();
    if ($hotpotgrades = $DB->get_records_sql_menu($sql, $params)) {
        foreach ($hotpotgrades as $hotpotuserid => $hotpotgrade) {
            if ($hotpot->grademethod == hotpot::GRADEMETHOD_FIRST || $hotpot->grademethod == hotpot::GRADEMETHOD_LAST) {
                // remove left hand characters in $gradefield (up to and including the underscore)
                $pos = strpos($hotpotgrade, '_') + 1;
                $hotpotgrade = substr($hotpotgrade, $pos);
            }
            $grades[$hotpotuserid] = (object) array('userid' => $hotpotuserid, 'rawgrade' => $hotpotgrade);
        }
    }
    if (count($grades)) {
        hotpot_grade_item_update($hotpot, $grades);
    } else {
        if ($userid && $nullifnone) {
            // no grades for this user, but we must force the creation of a "null" grade record
            hotpot_grade_item_update($hotpot, (object) array('userid' => $userid, 'rawgrade' => null));
        } else {
            // no grades and no userid
            hotpot_grade_item_update($hotpot);
        }
    }
}
示例#12
0
/**
 * Update hotpot grades in the gradebook
 *
 * Needed by grade_update_mod_grades() in lib/gradelib.php
 *
 * @param stdclass  $hotpot      instance object with extra cmidnumber and modname property
 * @param integer   $userid      >0 update grade of specific user only, 0 means all participants
 * @param boolean   $nullifnone  TRUE = force creation of NULL grade if this user has no grade
 * @return boolean  TRUE if successful, FALSE otherwise
 * @return void
 */
function hotpot_update_grades($hotpot = null, $userid = 0, $nullifnone = true)
{
    global $CFG, $DB;
    // get hotpot object
    require_once $CFG->dirroot . '/mod/hotpot/locallib.php';
    if ($hotpot === null) {
        // update/create grades for all hotpots
        // set up sql strings
        $strupdating = get_string('updatinggrades', 'mod_hotpot');
        $select = 'h.*, cm.idnumber AS cmidnumber';
        $from = '{hotpot} h, {course_modules} cm, {modules} m';
        $where = 'h.id = cm.instance AND cm.module = m.id AND m.name = ?';
        $params = array('hotpot');
        // get previous record index (if any)
        $configname = 'update_grades';
        $configvalue = get_config('mod_hotpot', $configname);
        if (is_numeric($configvalue)) {
            $i_min = intval($configvalue);
        } else {
            $i_min = 0;
        }
        if ($i_max = $DB->count_records_sql("SELECT COUNT('x') FROM {$from} WHERE {$where}", $params)) {
            if ($rs = $DB->get_recordset_sql("SELECT {$select} FROM {$from} WHERE {$where}", $params)) {
                if (defined('CLI_SCRIPT') && CLI_SCRIPT) {
                    $bar = false;
                } else {
                    $bar = new progress_bar('hotpotupgradegrades', 500, true);
                }
                $i = 0;
                foreach ($rs as $hotpot) {
                    // update grade
                    if ($i >= $i_min) {
                        upgrade_set_timeout();
                        // apply for more time (3 mins)
                        hotpot_update_grades($hotpot, $userid, $nullifnone);
                    }
                    // update progress bar
                    $i++;
                    if ($bar) {
                        $bar->update($i, $i_max, $strupdating . ": ({$i}/{$i_max})");
                    }
                    // update record index
                    if ($i > $i_min) {
                        set_config($configname, $i, 'mod_hotpot');
                    }
                }
                $rs->close();
            }
        }
        // delete the record index
        unset_config($configname, 'mod_hotpot');
        return;
        // finish here
    }
    // sanity check on $hotpot->id
    if (!isset($hotpot->id)) {
        return false;
    }
    $grades = hotpot_get_grades($hotpot, $userid);
    if (count($grades)) {
        hotpot_grade_item_update($hotpot, $grades);
    } else {
        if ($userid && $nullifnone) {
            // no grades for this user, but we must force the creation of a "null" grade record
            hotpot_grade_item_update($hotpot, (object) array('userid' => $userid, 'rawgrade' => null));
        } else {
            // no grades and no userid
            hotpot_grade_item_update($hotpot);
        }
    }
}