Example #1
0
function xmldb_blocktype_taggedposts_upgrade($oldversion = 0)
{
    if ($oldversion < 2015011500) {
        $table = new XMLDBTable('blocktype_taggedposts_tags');
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
        $table->addFieldInfo('block_instance', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL);
        $table->addFieldInfo('tag', XMLDB_TYPE_CHAR, 128, null, XMLDB_NOTNULL);
        $table->addFieldInfo('tagtype', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL);
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('tagtagtypeix', XMLDB_INDEX_NOTUNIQUE, array('tag', 'tagtype'));
        if (!table_exists($table)) {
            create_table($table);
            $rs = get_recordset('block_instance', 'blocktype', 'taggedposts', 'id', 'id, configdata');
            while ($bi = $rs->FetchRow()) {
                // Each block will have only one tag (because we combined this upgrade block
                // with the upgrade block for the "multiple tags" enhancement.
                $configdata = unserialize($bi['configdata']);
                if (!empty($configdata['tagselect'])) {
                    $todb = new stdClass();
                    $todb->block_instance = $bi['id'];
                    $todb->tag = $configdata['tagselect'];
                    $todb->tagtype = PluginBlocktypeTaggedposts::TAGTYPE_INCLUDE;
                    insert_record('blocktype_taggedposts_tags', $todb);
                }
            }
        }
    }
    return true;
}
 function get_all_elements()
 {
     $elements = array();
     $rs = get_recordset('course_categories', '', '', '', 'id');
     while ($course = rs_fetch_next_record($rs)) {
         $elements[] = $course->id;
     }
     return $elements;
 }
 function get_all_elements()
 {
     $elements = array();
     $rs = get_recordset('user', '', '', '', 'id');
     while ($user = rs_fetch_next_record($rs)) {
         $elements[] = $user->id;
     }
     return $elements;
 }
Example #4
0
                allow_override($fromroleid, $targetroleid);
            }
        }
    }
    /// Updated allowoverrides sitewide, so force a premissions refresh, and redirect.
    mark_context_dirty($systemcontext->path);
    add_to_log(SITEID, 'role', 'edit allow override', 'admin/roles/allowoverride.php', '', '', $USER->id);
    redirect($CFG->wwwroot . '/' . $CFG->admin . '/roles/allowoverride.php');
}
/// Load the current settings
$allowed = array();
foreach ($roles as $role) {
    // Make an array $role->id => false. This is probalby too clever for its own good.1
    $allowed[$role->id] = array_combine(array_keys($roles), array_fill(0, count($roles), false));
}
$raas = get_recordset('role_allow_override');
foreach ($raas as $raa) {
    $raa = (object) $raa;
    $allowed[$raa->roleid][$raa->allowoverride] = true;
}
/// Display the editing form.
admin_externalpage_setup('defineroles', '', array(), $CFG->wwwroot . '/' . $CFG->admin . '/roles/allowoverride.php');
admin_externalpage_print_header();
$currenttab = 'allowoverride';
require_once 'managetabs.php';
$table->tablealign = 'center';
$table->cellpadding = 5;
$table->cellspacing = 0;
$table->width = '90%';
$table->align[] = 'left';
$table->rotateheaders = true;
function backup_messages($bf, $preferences)
{
    global $CFG;
    $status = true;
    /// Check we have something to backup
    $unreads = count_records('message');
    $reads = count_records('message_read');
    $contacts = count_records('message_contacts');
    if ($unreads || $reads || $contacts) {
        $counter = 0;
        /// message open tag
        fwrite($bf, start_tag("MESSAGES", 2, true));
        if ($unreads) {
            $rs_unreads = get_recordset('message');
            /// Iterate over every unread
            while ($unread = rs_fetch_next_record($rs_unreads)) {
                /// start message
                fwrite($bf, start_tag("MESSAGE", 3, true));
                fwrite($bf, full_tag("ID", 4, false, $unread->id));
                fwrite($bf, full_tag("STATUS", 4, false, "UNREAD"));
                fwrite($bf, full_tag("USERIDFROM", 4, false, $unread->useridfrom));
                fwrite($bf, full_tag("USERIDTO", 4, false, $unread->useridto));
                fwrite($bf, full_tag("MESSAGE", 4, false, $unread->message));
                fwrite($bf, full_tag("FORMAT", 4, false, $unread->format));
                fwrite($bf, full_tag("TIMECREATED", 4, false, $unread->timecreated));
                fwrite($bf, full_tag("MESSAGETYPE", 4, false, $unread->messagetype));
                /// end message
                fwrite($bf, end_tag("MESSAGE", 3, true));
                /// Do some output
                $counter++;
                if ($counter % 20 == 0) {
                    echo ".";
                    if ($counter % 400 == 0) {
                        echo "<br />";
                    }
                    backup_flush(300);
                }
            }
            rs_close($rs_unreads);
        }
        if ($reads) {
            $rs_reads = get_recordset('message_read');
            /// Iterate over every unread
            while ($read = rs_fetch_next_record($rs_reads)) {
                /// start message
                fwrite($bf, start_tag("MESSAGE", 3, true));
                fwrite($bf, full_tag("ID", 4, false, $read->id));
                fwrite($bf, full_tag("STATUS", 4, false, "READ"));
                fwrite($bf, full_tag("USERIDFROM", 4, false, $read->useridfrom));
                fwrite($bf, full_tag("USERIDTO", 4, false, $read->useridto));
                fwrite($bf, full_tag("MESSAGE", 4, false, $read->message));
                fwrite($bf, full_tag("FORMAT", 4, false, $read->format));
                fwrite($bf, full_tag("TIMECREATED", 4, false, $read->timecreated));
                fwrite($bf, full_tag("MESSAGETYPE", 4, false, $read->messagetype));
                fwrite($bf, full_tag("TIMEREAD", 4, false, $read->timeread));
                fwrite($bf, full_tag("MAILED", 4, false, $read->mailed));
                /// end message
                fwrite($bf, end_tag("MESSAGE", 3, true));
                /// Do some output
                $counter++;
                if ($counter % 20 == 0) {
                    echo ".";
                    if ($counter % 400 == 0) {
                        echo "<br />";
                    }
                    backup_flush(300);
                }
            }
            rs_close($rs_reads);
        }
        if ($contacts) {
            fwrite($bf, start_tag("CONTACTS", 3, true));
            $rs_contacts = get_recordset('message_contacts');
            /// Iterate over every contact
            while ($contact = rs_fetch_next_record($rs_contacts)) {
                /// start contact
                fwrite($bf, start_tag("CONTACT", 4, true));
                fwrite($bf, full_tag("ID", 5, false, $contact->id));
                fwrite($bf, full_tag("USERID", 5, false, $contact->userid));
                fwrite($bf, full_tag("CONTACTID", 5, false, $contact->contactid));
                fwrite($bf, full_tag("BLOCKED", 5, false, $contact->blocked));
                /// end contact
                fwrite($bf, end_tag("CONTACT", 4, true));
                /// Do some output
                $counter++;
                if ($counter % 20 == 0) {
                    echo ".";
                    if ($counter % 400 == 0) {
                        echo "<br />";
                    }
                    backup_flush(300);
                }
            }
            rs_close($rs_contacts);
            fwrite($bf, end_tag("CONTACTS", 3, true));
        }
        /// messages close tag
        $status = fwrite($bf, end_tag("MESSAGES", 2, true));
    }
    return $status;
}
Example #6
0
/**
 * Get the first two columns from a number of records as an associative array.
 *
 * Arguments as for @see function get_recordset.
 * 
 * If no errors occur, and at least one records is found, the return value
 * is an associative whose keys come from the first field of each record,
 * and whose values are the corresponding second fields. If no records are found,
 * or an error occurs, false is returned.
 *
 * @param string $table the table to query.
 * @param string $field a field to check (optional).
 * @param string $value the value the field must have (requred if field1 is given, else optional).
 * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
 * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
 * @return mixed an associative array, or false if no records were found or an error occured.
 */
function get_records_menu($table, $field = '', $value = '', $sort = '', $fields = '*')
{
    $rs = get_recordset($table, $field, $value, $sort, $fields);
    return recordset_to_menu($rs);
}
Example #7
0
function xmldb_main_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $USER, $SITE, $db;
    $result = true;
    if ($result && $oldversion < 2006100401) {
        /// Only for those tracking Moodle 1.7 dev, others will have these dropped in moodle_install_roles()
        if (!empty($CFG->rolesactive)) {
            drop_table(new XMLDBTable('user_students'));
            drop_table(new XMLDBTable('user_teachers'));
            drop_table(new XMLDBTable('user_coursecreators'));
            drop_table(new XMLDBTable('user_admins'));
        }
        upgrade_main_savepoint($result, 2006100401);
    }
    if ($result && $oldversion < 2006100601) {
        /// Disable the exercise module because it's unmaintained
        if ($module = get_record('modules', 'name', 'exercise')) {
            if ($module->visible) {
                // Hide/disable the module entry
                set_field('modules', 'visible', '0', 'id', $module->id);
                // Save existing visible state for all activities
                set_field('course_modules', 'visibleold', '1', 'visible', '1', 'module', $module->id);
                set_field('course_modules', 'visibleold', '0', 'visible', '0', 'module', $module->id);
                // Hide all activities
                set_field('course_modules', 'visible', '0', 'module', $module->id);
                //require_once($CFG->dirroot.'/course/lib.php');
                //rebuild_course_cache();  // Rebuld cache for all modules because they might have changed
            }
        }
        upgrade_main_savepoint($result, 2006100601);
    }
    if ($result && $oldversion < 2006101001) {
        /// Disable the LAMS module by default (if it is installed)
        if (count_records('modules', 'name', 'lams') && !count_records('lams')) {
            set_field('modules', 'visible', 0, 'name', 'lams');
            // Disable it by default
        }
        upgrade_main_savepoint($result, 2006101001);
    }
    if ($result && $oldversion < 2006102600) {
        /// Define fields to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('description');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'categoryid');
        $field1 = new XMLDBField('param1');
        $field1->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'defaultdata');
        $field2 = new XMLDBField('param2');
        $field2->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param1');
        $field3 = new XMLDBField('param3');
        $field3->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param2');
        $field4 = new XMLDBField('param4');
        $field4->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param3');
        $field5 = new XMLDBField('param5');
        $field5->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param4');
        /// Launch add fields
        $result = $result && add_field($table, $field);
        $result = $result && add_field($table, $field1);
        $result = $result && add_field($table, $field2);
        $result = $result && add_field($table, $field3);
        $result = $result && add_field($table, $field4);
        $result = $result && add_field($table, $field5);
        upgrade_main_savepoint($result, 2006102600);
    }
    if ($result && $oldversion < 2006112000) {
        /// Define field attachment to be added to post
        $table = new XMLDBTable('post');
        $field = new XMLDBField('attachment');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'format');
        /// Launch add field attachment
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2006112000);
    }
    if ($result && $oldversion < 2006112200) {
        /// Define field imagealt to be added to user
        $table = new XMLDBTable('user');
        $field = new XMLDBField('imagealt');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'trustbitmask');
        /// Launch add field imagealt
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('user');
        $field = new XMLDBField('screenreader');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0', 'imagealt');
        /// Launch add field screenreader
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2006112200);
    }
    if ($result && $oldversion < 2006120300) {
        /// Delete guest course section settings
        // following code can be executed repeatedly, such as when upgrading from 1.7.x - it is ok
        if ($guest = get_record('user', 'username', 'guest')) {
            execute_sql("DELETE FROM {$CFG->prefix}course_display where userid={$guest->id}", true);
        }
        upgrade_main_savepoint($result, 2006120300);
    }
    if ($result && $oldversion < 2006120400) {
        /// Remove secureforms config setting
        execute_sql("DELETE FROM {$CFG->prefix}config where name='secureforms'", true);
        upgrade_main_savepoint($result, 2006120400);
    }
    if (!empty($CFG->rolesactive) && $oldversion < 2006120700) {
        // add moodle/user:viewdetails to all roles!
        // note: use of assign_capability() is discouraged in upgrade script!
        if ($roles = get_records('role')) {
            $context = get_context_instance(CONTEXT_SYSTEM);
            foreach ($roles as $roleid => $role) {
                assign_capability('moodle/user:viewdetails', CAP_ALLOW, $roleid, $context->id);
            }
        }
        upgrade_main_savepoint($result, 2006120700);
    }
    // Move the auth plugin settings into the config_plugin table
    if ($result && $oldversion < 2007010300) {
        if ($CFG->auth == 'email') {
            set_config('registerauth', 'email');
        } else {
            set_config('registerauth', '');
        }
        $authplugins = get_list_of_plugins('auth');
        foreach ($CFG as $k => $v) {
            if (strpos($k, 'ldap_') === 0) {
                //upgrade nonstandard ldap settings
                $setting = substr($k, 5);
                if (set_config($setting, $v, "auth/ldap")) {
                    delete_records('config', 'name', $k);
                    unset($CFG->{$k});
                }
                continue;
            }
            if (strpos($k, 'auth_') !== 0) {
                continue;
            }
            $authsetting = substr($k, 5);
            foreach ($authplugins as $auth) {
                if (strpos($authsetting, $auth) !== 0) {
                    continue;
                }
                $setting = substr($authsetting, strlen($auth));
                if (set_config($setting, $v, "auth/{$auth}")) {
                    delete_records('config', 'name', $k);
                    unset($CFG->{$k});
                }
                break;
                // don't check the rest of the auth plugin names
            }
        }
        upgrade_main_savepoint($result, 2007010300);
    }
    if ($result && $oldversion < 2007010301) {
        //
        // Core MNET tables
        //
        $table = new XMLDBTable('mnet_host');
        $table->comment = 'Information about the local and remote hosts for RPC';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f->comment = 'Unique Host ID';
        $f = $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('wwwroot', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('ip_address', XMLDB_TYPE_CHAR, '39', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '80', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('public_key', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('public_key_expires', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('transport', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('portno', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('last_connect_time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('last_log_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_host2service');
        $table->comment = 'Information about the services for a given host';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('serviceid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('publish', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('subscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_serviceid', XMLDB_INDEX_UNIQUE, array('hostid', 'serviceid'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_log');
        $table->comment = 'Store session data from users migrating to other sites';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('remoteid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('ip', XMLDB_TYPE_CHAR, '15', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('coursename', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('module', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('cmid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('action', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('url', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('info', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('host_user_course', XMLDB_INDEX_NOTUNIQUE, array('hostid', 'userid', 'course'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_rpc');
        $table->comment = 'Functions or methods that we may publish or subscribe to';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('function_name', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('xmlrpc_path', XMLDB_TYPE_CHAR, '80', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('parent_type', XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('parent', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('enabled', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('help', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('profile', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('enabled_xpath', XMLDB_INDEX_NOTUNIQUE, array('enabled', 'xmlrpc_path'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_service');
        $table->comment = 'A service is a group of functions';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('description', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('apiversion', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('offer', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_service2rpc');
        $table->comment = 'Group functions or methods under a service';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('serviceid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('rpcid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('unique', XMLDB_INDEX_UNIQUE, array('rpcid', 'serviceid'));
        // Create the table
        $result = $result && create_table($table);
        //
        // Prime MNET configuration entries -- will be needed later by auth/mnet
        //
        include_once $CFG->dirroot . '/mnet/lib.php';
        $env = new mnet_environment();
        $env->init();
        unset($env);
        // add mnethostid to user-
        $table = new XMLDBTable('user');
        $field = new XMLDBField('mnethostid');
        $field->setType(XMLDB_TYPE_INTEGER);
        $field->setLength(10);
        $field->setNotNull(true);
        $field->setSequence(null);
        $field->setEnum(null);
        $field->setDefault('0');
        $field->setPrevious("deleted");
        $field->setNext("username");
        $result = $result && add_field($table, $field);
        // The default mnethostid is zero... we need to update this for all
        // users of the local IdP service.
        set_field('user', 'mnethostid', $CFG->mnet_localhost_id, 'mnethostid', '0');
        $index = new XMLDBIndex('username');
        $index->setUnique(true);
        $index->setFields(array('username'));
        drop_index($table, $index);
        $index->setFields(array('mnethostid', 'username'));
        if (!add_index($table, $index)) {
            notify(get_string('duplicate_usernames', 'mnet', 'http://docs.moodle.org/en/DuplicateUsernames'));
        }
        unset($table, $field, $index);
        /**
         ** auth/mnet tables
         **/
        $table = new XMLDBTable('mnet_session');
        $table->comment = 'Store session data from users migrating to other sites';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('token', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('mnethostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('useragent', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('confirm_timeout', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('session_id', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('expires', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('token', XMLDB_INDEX_UNIQUE, array('token'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_sso_access_control');
        $table->comment = 'Users by host permitted (or not) to login from a remote provider';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('mnet_host_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('access', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, 'allow');
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('mnethostid_username', XMLDB_INDEX_UNIQUE, array('mnet_host_id', 'username'));
        // Create the table
        $result = $result && create_table($table);
        if (empty($USER->mnet_host_id)) {
            $USER->mnet_host_id = $CFG->mnet_localhost_id;
            // Something for the current user to prevent warnings
        }
        /**
         ** enrol/mnet tables
         **/
        $table = new XMLDBTable('mnet_enrol_course');
        $table->comment = 'Information about courses on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('remoteid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cat_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cat_name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('cat_description', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '254', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '15', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('summary', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('startdate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cost', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('currency', XMLDB_TYPE_CHAR, '3', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('defaultroleid', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('defaultrolename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_remoteid', XMLDB_INDEX_UNIQUE, array('hostid', 'remoteid'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_enrol_assignments');
        $table->comment = 'Information about enrolments on courses on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('rolename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('enroltime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('enroltype', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_courseid', XMLDB_INDEX_NOTUNIQUE, array('hostid', 'courseid'));
        $table->addIndexInfo('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
        // Create the table
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007010301);
    }
    if ($result && $oldversion < 2007010404) {
        /// Define field shortname to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('shortname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'shortname', 'id');
        /// Launch add field shortname
        $result = $result && add_field($table, $field);
        /// Changing type of field name on table user_info_field to text
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('name');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null, 'shortname');
        /// Launch change of type for field name
        $result = $result && change_field_type($table, $field);
        /// For existing fields use 'name' as the 'shortname' entry
        if ($fields = get_records_select('user_info_field', '', '', 'id, name')) {
            foreach ($fields as $field) {
                $field->shortname = clean_param($field->name, PARAM_ALPHANUM);
                $result && update_record('user_info_field', $field);
            }
        }
        upgrade_main_savepoint($result, 2007010404);
    }
    if ($result && $oldversion < 2007011501) {
        if (!empty($CFG->enablerecordcache) && empty($CFG->rcache) && empty($CFG->cachetype) && empty($CFG->intcachemax)) {
            set_config('cachetype', 'internal');
            set_config('rcache', true);
            set_config('intcachemax', $CFG->enablerecordcache);
            unset_config('enablerecordcache');
            unset($CFG->enablerecordcache);
        }
        upgrade_main_savepoint($result, 2007011501);
    }
    if ($result && $oldversion < 2007012100) {
        /// Some old PG servers have user->firstname & user->lastname with 30cc. They must be 100cc.
        /// Fixing that conditionally. MDL-7110
        if ($CFG->dbfamily == 'postgres') {
            /// Get Metadata from user table
            $cols = array_change_key_case($db->MetaColumns($CFG->prefix . 'user'), CASE_LOWER);
            /// Process user->firstname if needed
            if ($col = $cols['firstname']) {
                if ($col->max_length < 100) {
                    /// Changing precision of field firstname on table user to (100)
                    $table = new XMLDBTable('user');
                    $field = new XMLDBField('firstname');
                    $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'idnumber');
                    /// Launch change of precision for field firstname
                    $result = $result && change_field_precision($table, $field);
                }
            }
            /// Process user->lastname if needed
            if ($col = $cols['lastname']) {
                if ($col->max_length < 100) {
                    /// Changing precision of field lastname on table user to (100)
                    $table = new XMLDBTable('user');
                    $field = new XMLDBField('lastname');
                    $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'firstname');
                    /// Launch change of precision for field lastname
                    $result = $result && change_field_precision($table, $field);
                }
            }
        }
        upgrade_main_savepoint($result, 2007012100);
    }
    if ($result && $oldversion < 2007012101) {
        /// Changing precision of field lang on table course to (30)
        $table = new XMLDBTable('course');
        $field = new XMLDBField('lang');
        $field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null, 'groupmodeforce');
        /// Launch change of precision for field course->lang
        $result = $result && change_field_precision($table, $field);
        /// Changing precision of field lang on table user to (30)
        $table = new XMLDBTable('user');
        $field = new XMLDBField('lang');
        $field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'en', 'country');
        /// Launch change of precision for field user->lang
        $result = $result && change_field_precision($table, $field);
        upgrade_main_savepoint($result, 2007012101);
    }
    if ($result && $oldversion < 2007012400) {
        /// Rename field access on table mnet_sso_access_control to accessctrl
        $table = new XMLDBTable('mnet_sso_access_control');
        $field = new XMLDBField('access');
        $field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'allow', 'mnet_host_id');
        /// Launch rename field accessctrl
        $result = $result && rename_field($table, $field, 'accessctrl');
        upgrade_main_savepoint($result, 2007012400);
    }
    if ($result && $oldversion < 2007012500) {
        execute_sql("DELETE FROM {$CFG->prefix}user WHERE username='******'", true);
        upgrade_main_savepoint($result, 2007012500);
    }
    if ($result && $oldversion < 2007020400) {
        /// Only for MySQL and PG, declare the user->ajax field as not null. MDL-8421.
        if ($CFG->dbfamily == 'mysql' || $CFG->dbfamily == 'postgres') {
            /// Changing nullability of field ajax on table user to not null
            $table = new XMLDBTable('user');
            $field = new XMLDBField('ajax');
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'htmleditor');
            /// Launch change of nullability for field ajax
            $result = $result && change_field_notnull($table, $field);
        }
        upgrade_main_savepoint($result, 2007020400);
    }
    if (!empty($CFG->rolesactive) && $result && $oldversion < 2007021401) {
        /// create default logged in user role if not present - upgrade rom 1.7.x
        if (empty($CFG->defaultuserroleid) or empty($CFG->guestroleid) or $CFG->defaultuserroleid == $CFG->guestroleid) {
            if (!get_records('role', 'shortname', 'user')) {
                $userroleid = create_role(addslashes(get_string('authenticateduser')), 'user', addslashes(get_string('authenticateduserdescription')), 'moodle/legacy:user');
                if ($userroleid) {
                    reset_role_capabilities($userroleid);
                    set_config('defaultuserroleid', $userroleid);
                }
            }
        }
        upgrade_main_savepoint($result, 2007021401);
    }
    if ($result && $oldversion < 2007021501) {
        /// delete removed setting from config
        unset_config('tabselectedtofront');
        upgrade_main_savepoint($result, 2007021501);
    }
    if ($result && $oldversion < 2007032200) {
        /// Define table role_sortorder to be created
        $table = new XMLDBTable('role_sortorder');
        /// Adding fields to table role_sortorder
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('roleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('sortoder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table role_sortorder
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('roleid', XMLDB_KEY_FOREIGN, array('roleid'), 'role', array('id'));
        $table->addKeyInfo('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
        /// Adding indexes to table role_sortorder
        $table->addIndexInfo('userid-roleid-contextid', XMLDB_INDEX_UNIQUE, array('userid', 'roleid', 'contextid'));
        /// Launch create table for role_sortorder
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007032200);
    }
    /// code to change lenghen tag field to 255, MDL-9095
    if ($result && $oldversion < 2007040400) {
        /// Define index text (not unique) to be dropped form tags
        $table = new XMLDBTable('tags');
        $index = new XMLDBIndex('text');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('text'));
        /// Launch drop index text
        $result = $result && drop_index($table, $index);
        $field = new XMLDBField('text');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'userid');
        /// Launch change of type for field text
        $result = $result && change_field_type($table, $field);
        $index = new XMLDBIndex('text');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('text'));
        /// Launch add index text
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007040400);
    }
    if ($result && $oldversion < 2007041100) {
        /// Define field idnumber to be added to course_modules
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('idnumber');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'section');
        /// Launch add field idnumber
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007041100);
    }
    /* Changes to the custom profile menu type - store values rather than indices.
       We could do all this with one tricky SQL statement but it's a one-off so no
       harm in using PHP loops */
    if ($result && $oldversion < 2007041600) {
        /// Get the menu fields
        if ($fields = get_records('user_info_field', 'datatype', 'menu')) {
            foreach ($fields as $field) {
                /// Get user data for the menu field
                if ($data = get_records('user_info_data', 'fieldid', $field->id)) {
                    /// Get the menu options
                    $options = explode("\n", $field->param1);
                    foreach ($data as $d) {
                        $key = array_search($d->data, $options);
                        /// If the data is an integer and is not one of the options,
                        /// set the respective option value
                        if (is_int($d->data) and ($key === NULL or $key === false) and isset($options[$d->data])) {
                            $d->data = $options[$d->data];
                            $result = $result && update_record('user_info_data', $d);
                        }
                    }
                }
            }
        }
        upgrade_main_savepoint($result, 2007041600);
    }
    /// adding new gradebook tables
    if ($result && $oldversion < 2007041800) {
        /// Define table events_handlers to be created
        $table = new XMLDBTable('events_handlers');
        /// Adding fields to table events_handlers
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('eventname', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlermodule', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerfile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerfunction', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        /// Adding keys to table events_handlers
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table events_handlers
        $table->addIndexInfo('eventname-handlermodule', XMLDB_INDEX_UNIQUE, array('eventname', 'handlermodule'));
        /// Launch create table for events_handlers
        $result = $result && create_table($table);
        /// Define table events_queue to be created
        $table = new XMLDBTable('events_queue');
        /// Adding fields to table events_queue
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('eventdata', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('schedule', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('stackdump', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table events_queue
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch create table for events_queue
        $result = $result && create_table($table);
        /// Define table events_queue_handlers to be created
        $table = new XMLDBTable('events_queue_handlers');
        /// Adding fields to table events_queue_handlers
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('queuedeventid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('status', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
        $table->addFieldInfo('errormessage', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table events_queue_handlers
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('queuedeventid', XMLDB_KEY_FOREIGN, array('queuedeventid'), 'events_queue', array('id'));
        $table->addKeyInfo('handlerid', XMLDB_KEY_FOREIGN, array('handlerid'), 'events_handlers', array('id'));
        /// Launch create table for events_queue_handlers
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007041800);
    }
    if ($result && $oldversion < 2007043001) {
        /// Define field schedule to be added to events_handlers
        $table = new XMLDBTable('events_handlers');
        $field = new XMLDBField('schedule');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'handlerfunction');
        /// Launch add field schedule
        $result = $result && add_field($table, $field);
        /// Define field status to be added to events_handlers
        $table = new XMLDBTable('events_handlers');
        $field = new XMLDBField('status');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'schedule');
        /// Launch add field status
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007043001);
    }
    if ($result && $oldversion < 2007050201) {
        /// Define field theme to be added to course_categories
        $table = new XMLDBTable('course_categories');
        $field = new XMLDBField('theme');
        $field->setAttributes(XMLDB_TYPE_CHAR, '50', null, null, null, null, null, null, 'path');
        /// Launch add field theme
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007050201);
    }
    if ($result && $oldversion < 2007051100) {
        /// Define field forceunique to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('forceunique');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'visible');
        /// Launch add field forceunique
        $result = $result && add_field($table, $field);
        /// Define field signup to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('signup');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'forceunique');
        /// Launch add field signup
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007051100);
    }
    if (!empty($CFG->rolesactive) && $result && $oldversion < 2007051801) {
        // Get the role id of the "Auth. User" role and check if the default role id is different
        // note: use of assign_capability() is discouraged in upgrade script!
        $userrole = get_record('role', 'shortname', 'user');
        $defaultroleid = $CFG->defaultuserroleid;
        if ($defaultroleid != $userrole->id) {
            //  Add in the new moodle/my:manageblocks capibility to the default user role
            $context = get_context_instance(CONTEXT_SYSTEM);
            assign_capability('moodle/my:manageblocks', CAP_ALLOW, $defaultroleid, $context->id);
        }
        upgrade_main_savepoint($result, 2007051801);
    }
    if ($result && $oldversion < 2007052200) {
        /// Define field schedule to be dropped from events_queue
        $table = new XMLDBTable('events_queue');
        $field = new XMLDBField('schedule');
        /// Launch drop field stackdump
        $result = $result && drop_field($table, $field);
        upgrade_main_savepoint($result, 2007052200);
    }
    if ($result && $oldversion < 2007052300) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_remove_rqp_qtype();
        upgrade_main_savepoint($result, 2007052300);
    }
    if ($result && $oldversion < 2007060500) {
        /// Define field usermodified to be added to post
        $table = new XMLDBTable('post');
        $field = new XMLDBField('usermodified');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'created');
        /// Launch add field usermodified
        $result = $result && add_field($table, $field);
        /// Define key usermodified (foreign) to be added to post
        $table = new XMLDBTable('post');
        $key = new XMLDBKey('usermodified');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Launch add key usermodified
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007060500);
    }
    if ($result && $oldversion < 2007070603) {
        // Small update of guest user to be 100% sure it has the correct mnethostid (MDL-10375)
        set_field('user', 'mnethostid', $CFG->mnet_localhost_id, 'username', 'guest');
        upgrade_main_savepoint($result, 2007070603);
    }
    if ($result && $oldversion < 2007071400) {
        /**
         ** mnet application table
         **/
        $table = new XMLDBTable('mnet_application');
        $table->comment = 'Information about applications on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('display_name', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('xmlrpc_server_url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('sso_land_url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        // Insert initial applications (moodle and mahara)
        $application = new stdClass();
        $application->name = 'moodle';
        $application->display_name = 'Moodle';
        $application->xmlrpc_server_url = '/mnet/xmlrpc/server.php';
        $application->sso_land_url = '/auth/mnet/land.php';
        if ($result) {
            $newid = insert_record('mnet_application', $application, false);
        }
        $application = new stdClass();
        $application->name = 'mahara';
        $application->display_name = 'Mahara';
        $application->xmlrpc_server_url = '/api/xmlrpc/server.php';
        $application->sso_land_url = '/auth/xmlrpc/land.php';
        $result = $result && insert_record('mnet_application', $application, false);
        // New mnet_host->applicationid field
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('applicationid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, $newid, 'last_log_id');
        $result = $result && add_field($table, $field);
        /// Define key applicationid (foreign) to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch add key applicationid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007071400);
    }
    if ($result && $oldversion < 2007071607) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_remove_rqp_qtype_config_string();
        upgrade_main_savepoint($result, 2007071607);
    }
    if ($result && $oldversion < 2007072200) {
        /// Remove all grade tables used in development phases - we need new empty tables for final gradebook upgrade
        $tables = array('grade_categories', 'grade_items', 'grade_calculations', 'grade_grades', 'grade_grades_raw', 'grade_grades_final', 'grade_grades_text', 'grade_outcomes', 'grade_outcomes_courses', 'grade_history', 'grade_import_newitem', 'grade_import_values');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        $tables = array('grade_categories_history', 'grade_items_history', 'grade_grades_history', 'grade_grades_text_history', 'grade_scale_history', 'grade_outcomes_history');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        /// Define table grade_outcomes to be created
        $table = new XMLDBTable('grade_outcomes');
        /// Adding fields to table grade_outcomes
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_outcomes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Launch create table for grade_outcomes
        $result = $result && create_table($table);
        /// Define table grade_categories to be created
        $table = new XMLDBTable('grade_categories');
        /// Adding fields to table grade_categories
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_categories
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
        /// Launch create table for grade_categories
        $result = $result && create_table($table);
        /// Define table grade_items to be created
        $table = new XMLDBTable('grade_items');
        /// Adding fields to table grade_items
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
        $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
        $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
        $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregationcoef', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_items
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        /// Adding indexes to table grade_grades
        $table->addIndexInfo('locked-locktime', XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        $table->addIndexInfo('itemtype-needsupdate', XMLDB_INDEX_NOTUNIQUE, array('itemtype', 'needsupdate'));
        $table->addIndexInfo('gradetype', XMLDB_INDEX_NOTUNIQUE, array('gradetype'));
        /// Launch create table for grade_items
        $result = $result && create_table($table);
        /// Define table grade_grades to be created
        $table = new XMLDBTable('grade_grades');
        /// Adding fields to table grade_grades
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_grades
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Adding indexes to table grade_grades
        $table->addIndexInfo('locked-locktime', XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        /// Launch create table for grade_grades
        $result = $result && create_table($table);
        /// Define table grade_outcomes_history to be created
        $table = new XMLDBTable('grade_outcomes_history');
        /// Adding fields to table grade_outcomes_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        /// Adding keys to table grade_outcomes_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_outcomes_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_outcomes_history
        $result = $result && create_table($table);
        /// Define table grade_categories_history to be created
        $table = new XMLDBTable('grade_categories_history');
        /// Adding fields to table grade_categories_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_categories_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_categories', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_categories_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_categories_history
        $result = $result && create_table($table);
        /// Define table grade_items_history to be created
        $table = new XMLDBTable('grade_items_history');
        /// Adding fields to table grade_items_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
        $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
        $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
        $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregationcoef', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_items_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_items', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_items_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_items_history
        $result = $result && create_table($table);
        /// Define table grade_grades_history to be created
        $table = new XMLDBTable('grade_grades_history');
        /// Adding fields to table grade_grades_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_grades_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades', array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_grades_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_grades_history
        $result = $result && create_table($table);
        /// Define table scale_history to be created
        $table = new XMLDBTable('scale_history');
        /// Adding fields to table scale_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table scale_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'scale', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table scale_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for scale_history
        $result = $result && create_table($table);
        /// upgrade the old 1.8 gradebook - migrade data into new grade tables
        if ($result) {
            if ($rs = get_recordset('course')) {
                while ($course = rs_fetch_next_record($rs)) {
                    // this function uses SQL only, it must not be changed after 1.9 goes stable!!
                    if (!upgrade_18_gradebook($course->id)) {
                        $result = false;
                        break;
                    }
                }
                rs_close($rs);
            }
        }
        upgrade_main_savepoint($result, 2007072200);
    }
    if ($result && $oldversion < 2007072400) {
        /// Dropping one DEFAULT in a TEXT column. It's was only one remaining
        /// since Moodle 1.7, so new servers won't have those anymore.
        /// Changing the default of field sessdata on table sessions2 to drop it
        $table = new XMLDBTable('sessions2');
        $field = new XMLDBField('sessdata');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'modified');
        /// Launch change of default for field sessdata
        $result = $result && change_field_default($table, $field);
        upgrade_main_savepoint($result, 2007072400);
    }
    if ($result && $oldversion < 2007073100) {
        /// Define table grade_outcomes_courses to be created
        $table = new XMLDBTable('grade_outcomes_courses');
        /// Adding fields to table grade_outcomes_courses
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_outcomes_courses
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('courseid-outcomeid', XMLDB_KEY_UNIQUE, array('courseid', 'outcomeid'));
        /// Launch create table for grade_outcomes_courses
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007073100);
    }
    if ($result && $oldversion < 2007073101) {
        // Add new tag tables
        /// Define table tag to be created
        $table = new XMLDBTable('tag');
        /// Adding fields to table tag
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('tagtype', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        $table->addFieldInfo('descriptionformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('flag', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null, null, '0');
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table tag
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag
        $table->addIndexInfo('name', XMLDB_INDEX_UNIQUE, array('name'));
        /// Launch create table for tag
        $result = $result && create_table($table);
        /// Define table tag_correlation to be created
        $table = new XMLDBTable('tag_correlation');
        /// Adding fields to table tag_correlation
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('tagid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('correlatedtags', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table tag_correlation
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag_correlation
        $table->addIndexInfo('tagid', XMLDB_INDEX_UNIQUE, array('tagid'));
        /// Launch create table for tag_correlation
        $result = $result && create_table($table);
        /// Define table tag_instance to be created
        $table = new XMLDBTable('tag_instance');
        /// Adding fields to table tag_instance
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('tagid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table tag_instance
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag_instance
        $table->addIndexInfo('tagiditem', XMLDB_INDEX_NOTUNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch create table for tag_instance
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007073101);
    }
    if ($result && $oldversion < 2007073103) {
        /// Define field rawname to be added to tag
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('rawname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'name');
        /// Launch add field rawname
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007073103);
    }
    if ($result && $oldversion < 2007073105) {
        /// Define field description to be added to grade_outcomes
        $table = new XMLDBTable('grade_outcomes');
        $field = new XMLDBField('description');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'scaleid');
            /// Launch add field description
            $result = $result && add_field($table, $field);
        }
        $table = new XMLDBTable('grade_outcomes_history');
        $field = new XMLDBField('description');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'scaleid');
            /// Launch add field description
            $result = $result && add_field($table, $field);
        }
        upgrade_main_savepoint($result, 2007073105);
    }
    // adding unique contraint on (courseid,shortname) of an outcome
    if ($result && $oldversion < 2007080100) {
        /// Define key courseid-shortname (unique) to be added to grade_outcomes
        $table = new XMLDBTable('grade_outcomes');
        $key = new XMLDBKey('courseid-shortname');
        $key->setAttributes(XMLDB_KEY_UNIQUE, array('courseid', 'shortname'));
        /// Launch add key courseid-shortname
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007080100);
    }
    /// originally there was supportname and supportemail upgrade code - this is handled in upgradesettings.php instead
    if ($result && $oldversion < 2007080202) {
        /// Define index tagiditem (not unique) to be dropped form tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch drop index tagiditem
        drop_index($table, $index);
        /// Define index tagiditem (unique) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch add index tagiditem
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007080202);
    }
    if ($result && $oldversion < 2007080300) {
        /// Define field aggregateoutcomes to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregateoutcomes');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
            /// Launch add field aggregateoutcomes
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateoutcomes to be added to grade_categories
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregateoutcomes');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
            /// Launch add field aggregateoutcomes
            $result = $result && add_field($table, $field);
        }
        upgrade_main_savepoint($result, 2007080300);
    }
    if ($result && $oldversion < 2007080800) {
        /// Normalize course->shortname MDL-10026
        /// Changing precision of field shortname on table course to (100)
        $table = new XMLDBTable('course');
        $field = new XMLDBField('shortname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'fullname');
        /// Launch change of precision for field shortname
        $result = $result && change_field_precision($table, $field);
        upgrade_main_savepoint($result, 2007080800);
    }
    if ($result && $oldversion < 2007080900) {
        /// Add context.path & index
        $table = new XMLDBTable('context');
        $field = new XMLDBField('path');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'instanceid');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('context');
        $index = new XMLDBIndex('path');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('path'));
        $result = $result && add_index($table, $index);
        /// Add context.depth
        $table = new XMLDBTable('context');
        $field = new XMLDBField('depth');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'path');
        $result = $result && add_field($table, $field);
        /// make sure the system context has proper data
        get_system_context(false);
        upgrade_main_savepoint($result, 2007080900);
    }
    if ($result && $oldversion < 2007080903) {
        /// Define index
        $table = new XMLDBTable('grade_grades');
        $index = new XMLDBIndex('locked-locktime');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        /// Define index
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('locked-locktime');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        /// Define index itemtype-needsupdate (not unique) to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('itemtype-needsupdate');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('itemtype', 'needsupdate'));
        if (!index_exists($table, $index)) {
            /// Launch add index itemtype-needsupdate
            $result = $result && add_index($table, $index);
        }
        /// Define index
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('gradetype');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('gradetype'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007080903);
    }
    if ($result && $oldversion < 2007081000) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_upgrade_context_etc();
        upgrade_main_savepoint($result, 2007081000);
    }
    if ($result && $oldversion < 2007081302) {
        $table = new XMLDBTable('groups');
        $field = new XMLDBField('password');
        if (field_exists($table, $field)) {
            /// 1.7.*/1.6.*/1.5.* - create 'groupings' and 'groupings_groups' + rename password to enrolmentkey
            /// or second run after fixing structure broken from 1.8.x
            $result = $result && upgrade_17_groups();
        } else {
            if (table_exists(new XMLDBTable('groups_groupings'))) {
                /// ELSE 'groups_groupings' table exists, this is 1.8.* properly upgraded
                $result = $result && upgrade_18_groups();
            } else {
                /// broken groups, failed 1.8.x upgrade
                upgrade_18_broken_groups();
                notify('Warning: failed groups upgrade detected! Unfortunately this problem ' . 'can not be fixed automatically. Mapping of groups to courses was lost, ' . 'you can either revert to backup from 1.7.x and run ugprade again or ' . 'continue and fill in the missing course ids into groups table manually.');
                $result = false;
            }
        }
        upgrade_main_savepoint($result, 2007081302);
    }
    if ($result && $oldversion < 2007081303) {
        /// Common groups upgrade for 1.8.* and 1.7.*/1.6.*..
        // delete not used fields
        $table = new XMLDBTable('groups');
        $field = new XMLDBField('theme');
        if (field_exists($table, $field)) {
            drop_field($table, $field);
        }
        $table = new XMLDBTable('groups');
        $field = new XMLDBField('lang');
        if (field_exists($table, $field)) {
            drop_field($table, $field);
        }
        /// Add groupingid field/f.key to 'course' table.
        $table = new XMLDBTable('course');
        $field = new XMLDBField('defaultgroupingid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupmodeforce');
        $result = $result && add_field($table, $field);
        /// Add grouping ID, grouponly field/f.key to 'course_modules' table.
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('groupingid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupmode');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('groupmembersonly');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupingid');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('course_modules');
        $key = new XMLDBKey('groupingid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007081303);
    }
    if ($result && $oldversion < 2007082300) {
        /// Define field ordering to be added to tag_instance table
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('ordering');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'itemid');
        /// Launch add field rawname
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007082300);
    }
    if ($result && $oldversion < 2007082700) {
        /// Define field timemodified to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('timemodified');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'ordering');
        /// Launch add field timemodified
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007082700);
    }
    /// migrate all tags table to tag - this code MUST use SQL only,
    /// because if the db structure changes the library functions will fail in future
    if ($result && $oldversion < 2007082701) {
        $tagrefs = array();
        // $tagrefs[$oldtagid] = $newtagid
        if ($rs = get_recordset('tags')) {
            $db->debug = false;
            while ($oldtag = rs_fetch_next_record($rs)) {
                $raw_normalized = clean_param($oldtag->text, PARAM_TAG);
                $normalized = moodle_strtolower($raw_normalized);
                // if this tag does not exist in tag table yet
                if (!($newtag = get_record('tag', 'name', addslashes($normalized), '', '', '', '', 'id'))) {
                    $itag = new object();
                    $itag->name = $normalized;
                    $itag->rawname = $raw_normalized;
                    $itag->userid = $oldtag->userid;
                    $itag->timemodified = time();
                    $itag->descriptionformat = 0;
                    // default format
                    if ($oldtag->type == 'official') {
                        $itag->tagtype = 'official';
                    } else {
                        $itag->tagtype = 'default';
                    }
                    if ($idx = insert_record('tag', addslashes_recursive($itag))) {
                        $tagrefs[$oldtag->id] = $idx;
                    }
                    // if this tag is already used by tag table
                } else {
                    $tagrefs[$oldtag->id] = $newtag->id;
                }
            }
            $db->debug = true;
            rs_close($rs);
        }
        // fetch all the tag instances and migrate them as well
        if ($rs = get_recordset('blog_tag_instance')) {
            $db->debug = false;
            while ($blogtag = rs_fetch_next_record($rs)) {
                if (array_key_exists($blogtag->tagid, $tagrefs)) {
                    $tag_instance = new object();
                    $tag_instance->tagid = $tagrefs[$blogtag->tagid];
                    $tag_instance->itemtype = 'blog';
                    $tag_instance->itemid = $blogtag->entryid;
                    $tag_instance->ordering = 1;
                    // does not matter much, because originally there was no ordering in blogs
                    $tag_instance->timemodified = time();
                    insert_record('tag_instance', $tag_instance);
                }
            }
            $db->debug = true;
            rs_close($rs);
        }
        unset($tagrefs);
        // release memory
        $table = new XMLDBTable('tags');
        drop_table($table);
        $table = new XMLDBTable('blog_tag_instance');
        drop_table($table);
        upgrade_main_savepoint($result, 2007082701);
    }
    /// MDL-11015, MDL-11016
    if ($result && $oldversion < 2007082800) {
        /// Changing type of field userid on table tag to int
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('userid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field userid
        $result = $result && change_field_type($table, $field);
        /// Changing type of field descriptionformat on table tag to int
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('descriptionformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'description');
        /// Launch change of type for field descriptionformat
        $result = $result && change_field_type($table, $field);
        /// Define key userid (foreign) to be added to tag
        $table = new XMLDBTable('tag');
        $key = new XMLDBKey('userid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch add key userid
        $result = $result && add_key($table, $key);
        /// Define index tagiditem (unique) to be dropped form tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch drop index tagiditem
        $result = $result && drop_index($table, $index);
        /// Changing type of field tagid on table tag_instance to int
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('tagid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field tagid
        $result = $result && change_field_type($table, $field);
        /// Define key tagid (foreign) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $key = new XMLDBKey('tagid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('tagid'), 'tag', array('id'));
        /// Launch add key tagid
        $result = $result && add_key($table, $key);
        /// Changing sign of field itemid on table tag_instance to unsigned
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('itemid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'itemtype');
        /// Launch change of sign for field itemid
        $result = $result && change_field_unsigned($table, $field);
        /// Changing sign of field ordering on table tag_instance to unsigned
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('ordering');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'itemid');
        /// Launch change of sign for field ordering
        $result = $result && change_field_unsigned($table, $field);
        /// Define index itemtype-itemid-tagid (unique) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('itemtype-itemid-tagid');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid'));
        /// Launch add index itemtype-itemid-tagid
        $result = $result && add_index($table, $index);
        /// Define index tagid (unique) to be dropped form tag_correlation
        $table = new XMLDBTable('tag_correlation');
        $index = new XMLDBIndex('tagid');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid'));
        /// Launch drop index tagid
        $result = $result && drop_index($table, $index);
        /// Changing type of field tagid on table tag_correlation to int
        $table = new XMLDBTable('tag_correlation');
        $field = new XMLDBField('tagid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field tagid
        $result = $result && change_field_type($table, $field);
        /// Define key tagid (foreign) to be added to tag_correlation
        $table = new XMLDBTable('tag_correlation');
        $key = new XMLDBKey('tagid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('tagid'), 'tag', array('id'));
        /// Launch add key tagid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007082800);
    }
    if ($result && $oldversion < 2007082801) {
        /// Define table user_private_key to be created
        $table = new XMLDBTable('user_private_key');
        /// Adding fields to table user_private_key
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('script', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('value', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iprestriction', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('validuntil', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table user_private_key
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Adding indexes to table user_private_key
        $table->addIndexInfo('script-value', XMLDB_INDEX_NOTUNIQUE, array('script', 'value'));
        /// Launch create table for user_private_key
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007082801);
    }
    /// Going to modify the applicationid from int(1) to int(10). Dropping and
    /// re-creating the associated keys/indexes is mandatory to be cross-db. MDL-11042
    if ($result && $oldversion < 2007082803) {
        /// Define key applicationid (foreign) to be dropped form mnet_host
        $table = new XMLDBTable('mnet_host');
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch drop key applicationid
        $result = $result && drop_key($table, $key);
        /// Changing type of field applicationid on table mnet_host to int
        $field = new XMLDBField('applicationid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'last_log_id');
        /// Launch change of type for field applicationid
        $result = $result && change_field_type($table, $field);
        /// Define key applicationid (foreign) to be added to mnet_host
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch add key applicationid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007082803);
    }
    if ($result && $oldversion < 2007090503) {
        /// Define field aggregatesubcats to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregatesubcats');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'aggregateoutcomes');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateonlygraded to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregateonlygraded');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregatesubcats to be added to grade_categories_history
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregatesubcats');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'aggregateoutcomes');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateonlygraded to be added to grade_categories_history
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregateonlygraded');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// upgrade path in grade_categrories table - now using slash on both ends
        $concat = sql_concat('path', "'/'");
        $sql = "UPDATE {$CFG->prefix}grade_categories SET path = {$concat} WHERE path NOT LIKE '/%/'";
        execute_sql($sql, true);
        /// convert old aggregation constants if needed
        /*for ($i=0; $i<=12; $i=$i+2) {
              $j = $i+1;
              $sql = "UPDATE {$CFG->prefix}grade_categories SET aggregation = $i, aggregateonlygraded = 1 WHERE aggregation = $j";
              execute_sql($sql, true);
          }*/
        // not needed anymore - breaks upgrade now
        upgrade_main_savepoint($result, 2007090503);
    }
    /// To have UNIQUE indexes over NULLable columns isn't cross-db at all
    /// so we create a non unique index and programatically enforce uniqueness
    if ($result && $oldversion < 2007090600) {
        /// Define index idnumber (unique) to be dropped form course_modules
        $table = new XMLDBTable('course_modules');
        $index = new XMLDBIndex('idnumber');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('idnumber'));
        /// Launch drop index idnumber
        $result = $result && drop_index($table, $index);
        /// Define index idnumber-course (not unique) to be added to course_modules
        $table = new XMLDBTable('course_modules');
        $index = new XMLDBIndex('idnumber-course');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'course'));
        /// Launch add index idnumber-course
        $result = $result && add_index($table, $index);
        /// Define index idnumber-courseid (not unique) to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('idnumber-courseid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'courseid'));
        /// Launch add index idnumber-courseid
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007090600);
    }
    /// Create the permanent context_temp table to be used by build_context_path()
    if ($result && $oldversion < 2007092001) {
        /// Define table context_temp to be created
        $table = new XMLDBTable('context_temp');
        /// Adding fields to table context_temp
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table context_temp
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for context_temp
        $result = $result && create_table($table);
        /// make sure category depths, parents and paths are ok, categories from 1.5 may not be properly initialized (MDL-12585)
        upgrade_fix_category_depths();
        /// Recalculate depths, paths and so on
        if (!empty($CFG->rolesactive)) {
            cleanup_contexts();
            // make sure all course, category and user contexts exist - we need it for grade letter upgrade, etc.
            create_contexts(CONTEXT_COURSE, false, true);
            create_contexts(CONTEXT_USER, false, true);
            // we need all contexts path/depths filled properly
            build_context_path(true, true);
            load_all_capabilities();
        } else {
            // upgrade from 1.6 - build all contexts
            create_contexts(null, true, true);
        }
        upgrade_main_savepoint($result, 2007092001);
    }
    /**
     * Merging of grade_grades_text back into grade_grades
     */
    if ($result && $oldversion < 2007092002) {
        /// Define field feedback to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('feedback');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'excluded');
        if (!field_exists($table, $field)) {
            /// Launch add field feedback
            $result = $result && add_field($table, $field);
        }
        /// Define field feedbackformat to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('feedbackformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'feedback');
        if (!field_exists($table, $field)) {
            /// Launch add field feedbackformat
            $result = $result && add_field($table, $field);
        }
        /// Define field information to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('information');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'feedbackformat');
        if (!field_exists($table, $field)) {
            /// Launch add field information
            $result = $result && add_field($table, $field);
        }
        /// Define field informationformat to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('informationformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'information');
        if (!field_exists($table, $field)) {
            /// Launch add field informationformat
            $result = $result && add_field($table, $field);
        }
        /// Define field feedback to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('feedback');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'excluded');
        if (!field_exists($table, $field)) {
            /// Launch add field feedback
            $result = $result && add_field($table, $field);
        }
        /// Define field feedbackformat to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('feedbackformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'feedback');
        if (!field_exists($table, $field)) {
            /// Launch add field feedbackformat
            $result = $result && add_field($table, $field);
        }
        /// Define field information to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('information');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'feedbackformat');
        if (!field_exists($table, $field)) {
            /// Launch add field information
            $result = $result && add_field($table, $field);
        }
        /// Define field informationformat to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('informationformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'information');
        if (!field_exists($table, $field)) {
            /// Launch add field informationformat
            $result = $result && add_field($table, $field);
        }
        $table = new XMLDBTable('grade_grades_text');
        if ($result and table_exists($table)) {
            //migrade existing data into grade_grades table - this is slow but works for all dbs,
            //it will be executed on development sites only
            $fields = array('feedback', 'information');
            foreach ($fields as $field) {
                $sql = "UPDATE {$CFG->prefix}grade_grades\n                           SET {$field} = (\n                                SELECT {$field}\n                                  FROM {$CFG->prefix}grade_grades_text ggt\n                                 WHERE ggt.gradeid = {$CFG->prefix}grade_grades.id)";
                $result = execute_sql($sql) && $result;
            }
            $fields = array('feedbackformat', 'informationformat');
            foreach ($fields as $field) {
                $sql = "UPDATE {$CFG->prefix}grade_grades\n                           SET {$field} = COALESCE((\n                                SELECT {$field}\n                                  FROM {$CFG->prefix}grade_grades_text ggt\n                                 WHERE ggt.gradeid = {$CFG->prefix}grade_grades.id), 0)";
                $result = execute_sql($sql) && $result;
            }
            if ($result) {
                $tables = array('grade_grades_text', 'grade_grades_text_history');
                foreach ($tables as $table) {
                    $table = new XMLDBTable($table);
                    if (table_exists($table)) {
                        drop_table($table);
                    }
                }
            }
        }
        upgrade_main_savepoint($result, 2007092002);
    }
    if ($result && $oldversion < 2007092803) {
        /// Remove obsoleted unit tests tables - they will be recreated automatically
        $tables = array('grade_categories', 'scale', 'grade_items', 'grade_calculations', 'grade_grades', 'grade_grades_raw', 'grade_grades_final', 'grade_grades_text', 'grade_outcomes', 'grade_outcomes_courses');
        foreach ($tables as $tablename) {
            $table = new XMLDBTable('unittest_' . $tablename);
            if (table_exists($table)) {
                drop_table($table);
            }
            $table = new XMLDBTable('unittest_' . $tablename . '_history');
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        /// Define field display to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $field = new XMLDBField('display');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'sortorder');
        /// Launch add field display
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        } else {
            $result = $result && change_field_default($table, $field);
        }
        /// Define field display to be added to grade_items_history
        $table = new XMLDBTable('grade_items_history');
        $field = new XMLDBField('display');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'sortorder');
        /// Launch add field display
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
        /// Define field decimals to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $field = new XMLDBField('decimals');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null, 'display');
        /// Launch add field decimals
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        } else {
            $result = $result && change_field_default($table, $field);
            $result = $result && change_field_notnull($table, $field);
        }
        /// Define field decimals to be added to grade_items_history
        $table = new XMLDBTable('grade_items_history');
        $field = new XMLDBField('decimals');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null, 'display');
        /// Launch add field decimals
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
        /// fix incorrect -1 default for grade_item->display
        execute_sql("UPDATE {$CFG->prefix}grade_items SET display=0 WHERE display=-1");
        upgrade_main_savepoint($result, 2007092803);
    }
    /// migrade grade letters - we can not do this in normal grades upgrade becuase we need all course contexts
    if ($result && $oldversion < 2007092806) {
        $result = upgrade_18_letters();
        /// Define index contextidlowerboundary (not unique) to be added to grade_letters
        $table = new XMLDBTable('grade_letters');
        $index = new XMLDBIndex('contextid-lowerboundary');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid', 'lowerboundary'));
        /// Launch add index contextidlowerboundary
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007092806);
    }
    if ($result && $oldversion < 2007100100) {
        /// Define table cache_flags to be created
        $table = new XMLDBTable('cache_flags');
        /// Adding fields to table cache_flags
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('flagtype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('expiry', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table cache_flags
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /*
         * Note: mysql can not create indexes on text fields larger than 333 chars! 
         */
        /// Adding indexes to table cache_flags
        $table->addIndexInfo('flagtype', XMLDB_INDEX_NOTUNIQUE, array('flagtype'));
        $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name'));
        /// Launch create table for cache_flags
        if (!table_exists($table)) {
            $result = $result && create_table($table);
        }
        upgrade_main_savepoint($result, 2007100100);
    }
    if ($result && $oldversion < 2007100300) {
        /// MNET stuff for roaming theme
        /// Define field force_theme to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('force_theme');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'last_log_id');
        /// Launch add field force_theme
        $result = $result && add_field($table, $field);
        /// Define field theme to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('theme');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'force_theme');
        /// Launch add field theme
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007100300);
    }
    if ($result && $oldversion < 2007100301) {
        /// Define table cache_flags to be created
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('typename');
        if (index_exists($table, $index)) {
            $result = $result && drop_index($table, $index);
        }
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('flagtype');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('flagtype'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('name');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007100301);
    }
    if ($result && $oldversion < 2007100303) {
        /// Changing nullability of field summary on table course to null
        $table = new XMLDBTable('course');
        $field = new XMLDBField('summary');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'idnumber');
        /// Launch change of nullability for field summary
        $result = $result && change_field_notnull($table, $field);
        upgrade_main_savepoint($result, 2007100303);
    }
    if ($result && $oldversion < 2007100500) {
        /// for dev sites - it is ok to do this repeatedly
        /// Changing nullability of field path on table context to null
        $table = new XMLDBTable('context');
        $field = new XMLDBField('path');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'instanceid');
        /// Launch change of nullability for field path
        $result = $result && change_field_notnull($table, $field);
        upgrade_main_savepoint($result, 2007100500);
    }
    if ($result && $oldversion < 2007100700) {
        /// first drop existing tables - we do not need any data from there
        $table = new XMLDBTable('grade_import_values');
        if (table_exists($table)) {
            drop_table($table);
        }
        $table = new XMLDBTable('grade_import_newitem');
        if (table_exists($table)) {
            drop_table($table);
        }
        /// Define table grade_import_newitem to be created
        $table = new XMLDBTable('grade_import_newitem');
        /// Adding fields to table grade_import_newitem
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importcode', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importer', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_import_newitem
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('importer', XMLDB_KEY_FOREIGN, array('importer'), 'user', array('id'));
        /// Launch create table for grade_import_newitem
        $result = $result && create_table($table);
        /// Define table grade_import_values to be created
        $table = new XMLDBTable('grade_import_values');
        /// Adding fields to table grade_import_values
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('newgradeitem', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('importcode', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importer', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_import_values
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('newgradeitem', XMLDB_KEY_FOREIGN, array('newgradeitem'), 'grade_import_newitem', array('id'));
        $table->addKeyInfo('importer', XMLDB_KEY_FOREIGN, array('importer'), 'user', array('id'));
        /// Launch create table for grade_import_values
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007100700);
    }
    /// dropping context_rel table - not used anymore
    if ($result && $oldversion < 2007100800) {
        /// Define table context_rel to be dropped
        $table = new XMLDBTable('context_rel');
        /// Launch drop table for context_rel
        if (table_exists($table)) {
            drop_table($table);
        }
        upgrade_main_savepoint($result, 2007100800);
    }
    /// Truncate the text_cahe table and add new index
    if ($result && $oldversion < 2007100802) {
        /// Truncate the cache_text table
        execute_sql("TRUNCATE TABLE {$CFG->prefix}cache_text", true);
        /// Define index timemodified (not unique) to be added to cache_text
        $table = new XMLDBTable('cache_text');
        $index = new XMLDBIndex('timemodified');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
        /// Launch add index timemodified
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007100802);
    }
    /// newtable for gradebook settings per course
    if ($result && $oldversion < 2007100803) {
        /// Define table grade_settings to be created
        $table = new XMLDBTable('grade_settings');
        /// Adding fields to table grade_settings
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        /// Adding keys to table grade_settings
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        /// Adding indexes to table grade_settings
        $table->addIndexInfo('courseid-name', XMLDB_INDEX_UNIQUE, array('courseid', 'name'));
        /// Launch create table for grade_settings
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007100803);
    }
    /// cleanup in user_lastaccess
    if ($result && $oldversion < 2007100902) {
        $sql = "DELETE\n                  FROM {$CFG->prefix}user_lastaccess\n                 WHERE NOT EXISTS (SELECT 'x'\n                                    FROM {$CFG->prefix}course c\n                                   WHERE c.id = {$CFG->prefix}user_lastaccess.courseid)";
        execute_sql($sql);
        upgrade_main_savepoint($result, 2007100902);
    }
    /// drop old gradebook tables
    if ($result && $oldversion < 2007100903) {
        $tables = array('grade_category', 'grade_item', 'grade_letter', 'grade_preferences', 'grade_exceptions');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        upgrade_main_savepoint($result, 2007100903);
    }
    if ($result && $oldversion < 2007101500 && !file_exists($CFG->dataroot . '/user')) {
        // Get list of users by browsing moodledata/user
        $oldusersdir = $CFG->dataroot . '/users';
        $folders = get_directory_list($oldusersdir, '', false, true, false);
        foreach ($folders as $userid) {
            $olddir = $oldusersdir . '/' . $userid;
            $files = get_directory_list($olddir);
            if (empty($files)) {
                continue;
            }
            // Create new user directory
            if (!($newdir = make_user_directory($userid))) {
                // some weird directory - do not stop the upgrade, just ignore it
                continue;
            }
            // Move contents of old directory to new one
            if (file_exists($olddir) && file_exists($newdir)) {
                foreach ($files as $file) {
                    copy($olddir . '/' . $file, $newdir . '/' . $file);
                }
            } else {
                notify("Could not move the contents of {$olddir} into {$newdir}!");
                $result = false;
                break;
            }
        }
        // Leave a README in old users directory
        $readmefilename = $oldusersdir . '/README.txt';
        if ($handle = fopen($readmefilename, 'w+b')) {
            if (!fwrite($handle, get_string('olduserdirectory'))) {
                // Could not write to the readme file. No cause for huge concern
                notify("Could not write to the README.txt file in {$readmefilename}.");
            }
            fclose($handle);
        } else {
            // Could not create the readme file. No cause for huge concern
            notify("Could not create the README.txt file in {$readmefilename}.");
        }
    }
    if ($result && $oldversion < 2007101502) {
        /// try to remove duplicate entries
        $SQL = "SELECT userid, itemid, COUNT(*)\n               FROM {$CFG->prefix}grade_grades\n               GROUP BY userid, itemid\n               HAVING COUNT( * ) >1";
        // duplicates found
        if ($rs = get_recordset_sql($SQL)) {
            if ($rs && $rs->RecordCount() > 0) {
                while ($dup = rs_fetch_next_record($rs)) {
                    if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades \n                                                    WHERE itemid = {$dup->itemid} AND userid = {$dup->userid}\n                                                    ORDER BY timemodified DESC")) {
                        $processed = 0;
                        // keep the first one
                        foreach ($thisdups as $thisdup) {
                            if ($processed) {
                                // remove the duplicates
                                delete_records('grade_grades', 'id', $thisdup->id);
                            }
                            $processed++;
                        }
                    }
                }
                rs_close($rs);
            }
        }
        /// Define key userid-itemid (unique) to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $key = new XMLDBKey('userid-itemid');
        $key->setAttributes(XMLDB_KEY_UNIQUE, array('userid', 'itemid'));
        /// Launch add key userid-itemid
        $result = $result && add_key($table, $key);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101502);
    }
    if ($result && $oldversion < 2007101505) {
        /// Changing precision of field dst_time on table timezone to (6)
        $table = new XMLDBTable('timezone');
        $field = new XMLDBField('dst_time');
        $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'dst_skipweeks');
        /// Launch change of precision for field dst_time
        $result = $result && change_field_precision($table, $field);
        /// Changing precision of field std_time on table timezone to (6)
        $table = new XMLDBTable('timezone');
        $field = new XMLDBField('std_time');
        $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'std_skipweeks');
        /// Launch change of precision for field std_time
        $result = $result && change_field_precision($table, $field);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101505);
    }
    if ($result && $oldversion < 2007101506) {
        /// CONTEXT_PERSONAL was never implemented - removing
        $sql = "DELETE\n                  FROM {$CFG->prefix}context\n                 WHERE contextlevel=20";
        execute_sql($sql);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101506);
    }
    if ($result && $oldversion < 2007101507) {
        $db->debug = false;
        require_once $CFG->dirroot . '/course/lib.php';
        notify('Started rebuilding of course cache...', 'notifysuccess');
        rebuild_course_cache();
        // Rebuild course cache - new group related fields there
        notify('...finished rebuilding of course cache.', 'notifysuccess');
        $db->debug = true;
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101507);
    }
    if ($result && $oldversion < 2007101508) {
        $db->debug = false;
        notify('Updating country list according to recent official ISO listing...', 'notifysuccess');
        // re-assign users to valid countries
        set_field('user', 'country', 'CD', 'country', 'ZR');
        // Zaire is now Congo Democratique
        set_field('user', 'country', 'TL', 'country', 'TP');
        // Timor has changed
        set_field('user', 'country', 'FR', 'country', 'FX');
        // France metropolitaine doesn't exist
        set_field('user', 'country', 'RS', 'country', 'KO');
        // Kosovo is part of Serbia, "under the auspices of the United Nations, pursuant to UN Security Council Resolution 1244 of 10 June 1999."
        set_field('user', 'country', 'GB', 'country', 'WA');
        // Wales is part of UK (ie Great Britain)
        set_field('user', 'country', 'RS', 'country', 'CS');
        // Re-assign Serbia-Montenegro to Serbia.  This is arbitrary, but there is no way to make an automatic decision on this.
        notify('...update complete. Remember to update the language pack to get the most recent country names defitions and codes.  This is specialy important for sites with users from Congo (now CD), Timor (now TL), Kosovo (now RS), Wales (now GB), Serbia (RS) and Montenegro (ME).  Users based in Montenegro (ME) will need to manually update their profile.', 'notifysuccess');
        $db->debug = true;
        upgrade_main_savepoint($result, 2007101508);
    }
    if ($result && $oldversion < 2007101508.01) {
        // add forgotten table
        /// Define table scale_history to be created
        $table = new XMLDBTable('scale_history');
        /// Adding fields to table scale_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table scale_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'scale', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table scale_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        if ($result and !table_exists($table)) {
            /// Launch create table for scale_history
            $result = $result && create_table($table);
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.01);
    }
    if ($result && $oldversion < 2007101508.02) {
        // upgade totals, no big deal if it fails
        require_once $CFG->libdir . '/statslib.php';
        stats_upgrade_totals();
        if (isset($CFG->loglifetime) and $CFG->loglifetime == 30) {
            set_config('loglifetime', 35);
            // we need more than 31 days for monthly stats!
        }
        notify('Upgrading log table indexes, this may take a long time, please be patient.', 'notifysuccess');
        /// Define index time-course-module-action (not unique) to be dropped form log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('time-course-module-action');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('time', 'course', 'module', 'action'));
        /// Launch drop index time-course-module-action
        if (index_exists($table, $index)) {
            $result = drop_index($table, $index) && $result;
        }
        /// Define index userid (not unique) to be dropped form log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('userid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid'));
        /// Launch drop index userid
        if (index_exists($table, $index)) {
            $result = drop_index($table, $index) && $result;
        }
        /// Define index info (not unique) to be dropped form log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('info');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('info'));
        /// Launch drop index info
        if (index_exists($table, $index)) {
            $result = drop_index($table, $index) && $result;
        }
        /// Define index time (not unique) to be added to log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('time');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('time'));
        /// Launch add index time
        if (!index_exists($table, $index)) {
            $result = add_index($table, $index) && $result;
        }
        /// Define index action (not unique) to be added to log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('action');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch add index action
        if (!index_exists($table, $index)) {
            $result = add_index($table, $index) && $result;
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.02);
    }
    if ($result && $oldversion < 2007101508.03) {
        /// Define index course-userid (not unique) to be dropped form log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('course-userid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'userid'));
        /// Launch drop index course-userid
        if (index_exists($table, $index)) {
            $result = $result && drop_index($table, $index);
        }
        /// Define index userid-course (not unique) to be added to log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('userid-course');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid', 'course'));
        /// Launch add index userid-course
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.03);
    }
    if ($result && $oldversion < 2007101508.04) {
        set_field('tag_instance', 'itemtype', 'post', 'itemtype', 'blog');
        upgrade_main_savepoint($result, 2007101508.04);
    }
    if ($result && $oldversion < 2007101508.05) {
        /// Define index cmid (not unique) to be added to log
        $table = new XMLDBTable('log');
        $index = new XMLDBIndex('cmid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('cmid'));
        /// Launch add index cmid
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.05);
    }
    if ($result && $oldversion < 2007101508.06) {
        /// Define index groupid-courseid-visible-userid (not unique) to be added to event
        $table = new XMLDBTable('event');
        $index = new XMLDBIndex('groupid-courseid-visible-userid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('groupid', 'courseid', 'visible', 'userid'));
        /// Launch add index groupid-courseid-visible-userid
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.06);
    }
    if ($result && $oldversion < 2007101508.07) {
        /// Define table webdav_locks to be created
        $table = new XMLDBTable('webdav_locks');
        /// Adding fields to table webdav_locks
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('token', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('expiry', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('recursive', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('exclusivelock', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('created', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('modified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('owner', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        /// Adding keys to table webdav_locks
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('token', XMLDB_KEY_UNIQUE, array('token'));
        /// Adding indexes to table webdav_locks
        $table->addIndexInfo('path', XMLDB_INDEX_NOTUNIQUE, array('path'));
        $table->addIndexInfo('expiry', XMLDB_INDEX_NOTUNIQUE, array('expiry'));
        /// Launch create table for webdav_locks
        $result = $result && create_table($table);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.07);
    }
    if ($result && $oldversion < 2007101508.08) {
        // MDL-13676
        /// Define field name to be added to role_names
        $table = new XMLDBTable('role_names');
        $field = new XMLDBField('name');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'text');
        /// Launch add field name
        $result = $result && add_field($table, $field);
        /// Copy data from old field to new field
        $result = $result && execute_sql('UPDATE ' . $CFG->prefix . 'role_names SET name = text');
        /// Define field text to be dropped from role_names
        $table = new XMLDBTable('role_names');
        $field = new XMLDBField('text');
        /// Launch drop field text
        $result = $result && drop_field($table, $field);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101508.08);
    }
    if ($result && $oldversion < 2007101509) {
        // force full regrading
        set_field('grade_items', 'needsupdate', 1, 'needsupdate', 0);
    }
    if ($result && $oldversion < 2007101510) {
        /// Fix minor problem caused by MDL-5482.
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_fix_random_question_parents();
        upgrade_main_savepoint($result, 2007101510);
    }
    if ($result && $oldversion < 2007101511) {
        // if guest role used as default user role unset it and force admin to choose new setting
        if (!empty($CFG->defaultuserroleid)) {
            if ($role = get_record('role', 'id', $CFG->defaultuserroleid)) {
                if ($guestroles = get_roles_with_capability('moodle/legacy:guest', CAP_ALLOW)) {
                    if (isset($guestroles[$role->id])) {
                        set_config('defaultuserroleid', null);
                        notify('Guest role removed from "Default role for all users" setting, please select another role.', 'notifysuccess');
                    }
                }
            } else {
                set_config('defaultuserroleid', null);
            }
        }
    }
    if ($result && $oldversion < 2007101512) {
        notify('Increasing size of user idnumber field, this may take a while...', 'notifysuccess');
        /// Under MySQL and Postgres... detect old NULL contents and change them by correct empty string. MDL-14859
        if ($CFG->dbfamily == 'mysql' || $CFG->dbfamily == 'postgres') {
            execute_sql("UPDATE {$CFG->prefix}user SET idnumber = '' WHERE idnumber IS NULL", true);
        }
        /// Define index idnumber (not unique) to be dropped form user
        $table = new XMLDBTable('user');
        $index = new XMLDBIndex('idnumber');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
        /// Launch drop index idnumber
        if (index_exists($table, $index)) {
            $result = $result && drop_index($table, $index);
        }
        /// Changing precision of field idnumber on table user to (255)
        $table = new XMLDBTable('user');
        $field = new XMLDBField('idnumber');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'password');
        /// Launch change of precision for field idnumber
        $result = $result && change_field_precision($table, $field);
        /// Launch add index idnumber again
        $index = new XMLDBIndex('idnumber');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
        $result = $result && add_index($table, $index);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101512);
    }
    if ($result && $oldversion < 2007101513) {
        $log_action = new stdClass();
        $log_action->module = 'course';
        $log_action->action = 'unenrol';
        $log_action->mtable = 'course';
        $log_action->field = 'fullname';
        if (!record_exists("log_display", "action", "unenrol", "module", "course")) {
            $result = $result && insert_record('log_display', $log_action);
        }
        upgrade_main_savepoint($result, 2007101513);
    }
    if ($result && $oldversion < 2007101514) {
        $table = new XMLDBTable('mnet_enrol_course');
        $field = new XMLDBField('sortorder');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', true, true, null, false, false, 0);
        $result = change_field_precision($table, $field);
        upgrade_main_savepoint($result, 2007101514);
    }
    if ($result && $oldversion < 2007101515) {
        $result = delete_records_select('role_names', sql_isempty('role_names', 'name', false, false));
        upgrade_main_savepoint($result, 2007101515);
    }
    if ($result && $oldversion < 2007101517) {
        if (isset($CFG->defaultuserroleid) and isset($CFG->guestroleid) and $CFG->defaultuserroleid == $CFG->guestroleid) {
            // guest can not be selected in defaultuserroleid!
            unset_config('defaultuserroleid');
        }
        upgrade_main_savepoint($result, 2007101517);
    }
    if ($result && $oldversion < 2007101526) {
        /// Changing the default of field lang on table user to en_utf8
        $table = new XMLDBTable('user');
        $field = new XMLDBField('lang');
        $field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'en_utf8', 'country');
        /// Launch change of default for field lang
        $result = $result && change_field_default($table, $field);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101526);
    }
    if ($result && $oldversion < 2007101527) {
        if (!get_config(NULL, 'statsruntimedays')) {
            set_config('statsruntimedays', '31');
        }
    }
    /// For MDL-17501. Ensure that any role that has moodle/course:update also
    /// has moodle/course:visibility.
    if ($result && $oldversion < 2007101532.1) {
        if (!empty($CFG->rolesactive)) {
            // In case we are upgrading from Moodle 1.6.
            /// Get the roles with 'moodle/course:update'.
            $systemcontext = get_context_instance(CONTEXT_SYSTEM);
            $roles = get_roles_with_capability('moodle/course:update', CAP_ALLOW, $systemcontext);
            /// Give those roles 'moodle/course:visibility'.
            foreach ($roles as $role) {
                assign_capability('moodle/course:visibility', CAP_ALLOW, $role->id, $systemcontext->id);
            }
            /// Force all sessions to refresh access data.
            mark_context_dirty($systemcontext->path);
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101532.1);
    }
    if ($result && $oldversion < 2007101542) {
        if (empty($CFG->hiddenuserfields)) {
            set_config('hiddenuserfields', 'firstaccess');
        } else {
            if (strpos($CFG->hiddenuserfields, 'firstaccess') === false) {
                //firstaccess should not already be listed but just in case
                set_config('hiddenuserfields', $CFG->hiddenuserfields . ',firstaccess');
            }
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101542);
    }
    if ($result && $oldversion < 2007101545.01) {
        require_once "{$CFG->dirroot}/filter/tex/lib.php";
        filter_tex_updatedcallback(null);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101545.01);
    }
    if ($result && $oldversion < 2007101546.02) {
        if (empty($CFG->gradebook_latest195_upgrade)) {
            require_once $CFG->libdir . '/gradelib.php';
            // we need constants only
            // reset current coef for simple mean items - it may contain some rubbish ;-)
            $sql = "UPDATE {$CFG->prefix}grade_items\n                       SET aggregationcoef = 0\n                     WHERE categoryid IN (SELECT gc.id\n                                            FROM {$CFG->prefix}grade_categories gc\n                                           WHERE gc.aggregation = " . GRADE_AGGREGATE_WEIGHTED_MEAN2 . ")";
            $result = execute_sql($sql);
        } else {
            // direct upgrade from 1.8.x - no need to reset coef, because it is already ok
            unset_config('gradebook_latest195_upgrade');
        }
        upgrade_main_savepoint($result, 2007101546.02);
    }
    if ($result && $oldversion < 2007101546.03) {
        /// Deleting orphaned messages from deleted users.
        require_once $CFG->dirroot . '/message/lib.php';
        /// Detect deleted users with messages sent(useridfrom) and not read
        if ($deletedusers = get_records_sql("SELECT DISTINCT u.id\n                                           FROM {$CFG->prefix}user u\n                                           JOIN {$CFG->prefix}message m ON m.useridfrom = u.id\n                                          WHERE u.deleted = 1")) {
            foreach ($deletedusers as $deleteduser) {
                message_move_userfrom_unread2read($deleteduser->id);
                // move messages
            }
        }
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101546.03);
    }
    if ($result && $oldversion < 2007101546.05) {
        // force full regrading - the max grade for sum aggregation was not correct when scales involved,
        //                        extra credit grade is not dropped anymore in aggregations if drop low or keep high specified
        //                        sum aggragetion respects drop low and keep high when calculation max value
        set_field('grade_items', 'needsupdate', 1, 'needsupdate', 0);
    }
    if ($result && $oldversion < 2007101546.06) {
        unset_config('grade_report_showgroups');
        upgrade_main_savepoint($result, 2007101546.06);
    }
    if ($result && $oldversion < 2007101547) {
        // Let's check the status of mandatory mnet_host records, fixing them
        // and moving "orphan" users to default localhost record. MDL-16879
        notify('Fixing mnet records, this may take a while...', 'notifysuccess');
        $db->debug = false;
        // Can output too much. Disabling
        upgrade_fix_incorrect_mnethostids();
        $db->debug = true;
        // Restoring debug level
        upgrade_main_savepoint($result, 2007101547);
    }
    if ($result && $oldversion < 2007101551) {
        //insert new record for log_display table
        //used to record tag update.
        if (!record_exists("log_display", "action", "update", "module", "tag")) {
            $log_action = new stdClass();
            $log_action->module = 'tag';
            $log_action->action = 'update';
            $log_action->mtable = 'tag';
            $log_action->field = 'name';
            $result = $result && insert_record('log_display', $log_action);
        }
        upgrade_main_savepoint($result, 2007101551);
    }
    if ($result && $oldversion < 2007101561.01) {
        // As part of security changes password policy will now be enabled by default.
        // If it has not already been enabled then we will enable it... Admins will still
        // be able to switch it off after this upgrade
        if (record_exists('config', 'name', 'passwordpolicy', 'value', 0)) {
            unset_config('passwordpolicy');
        }
        $message = get_string('upgrade197notice', 'admin');
        if (empty($CFG->passwordmainsalt)) {
            $docspath = $CFG->docroot . '/' . str_replace('_utf8', '', current_language()) . '/report/security/report_security_check_passwordsaltmain';
            $message .= "\n" . get_string('upgrade197salt', 'admin', $docspath);
        }
        notify($message, 'notifysuccess');
        unset($message);
        upgrade_main_savepoint($result, 2007101561.01);
    }
    if ($result && $oldversion < 2007101561.02) {
        $messagesubject = s($SITE->shortname) . ': ' . get_string('upgrade197noticesubject', 'admin');
        $message = '<p>' . s($SITE->fullname) . ' (' . s($CFG->wwwroot) . '):</p>' . get_string('upgrade197notice', 'admin');
        if (empty($CFG->passwordmainsalt)) {
            $docspath = $CFG->docroot . '/' . str_replace('_utf8', '', current_language()) . '/report/security/report_security_check_passwordsaltmain';
            $message .= "\n" . get_string('upgrade197salt', 'admin', $docspath);
        }
        // Force administrators to change password on next login
        $systemcontext = get_context_instance(CONTEXT_SYSTEM);
        $sql = "SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, u.password, u.mailformat\n              FROM {$CFG->prefix}role_capabilities rc\n              JOIN {$CFG->prefix}role_assignments ra ON (ra.contextid = rc.contextid AND ra.roleid = rc.roleid)\n              JOIN {$CFG->prefix}user u ON u.id = ra.userid\n             WHERE rc.capability = 'moodle/site:doanything'\n                   AND rc.permission = " . CAP_ALLOW . "\n                   AND u.deleted = 0\n                   AND rc.contextid = " . $systemcontext->id . " AND (u.auth='manual' OR u.auth='email')";
        $adminusers = get_records_sql($sql);
        foreach ($adminusers as $adminuser) {
            if ($preference = get_record('user_preferences', 'userid', $adminuser->id, 'name', 'auth_forcepasswordchange')) {
                if ($preference->value == '1') {
                    continue;
                }
                set_field('user_preferences', 'value', '1', 'id', $preference->id);
            } else {
                $preference = new stdClass();
                $preference->userid = $adminuser->id;
                $preference->name = 'auth_forcepasswordchange';
                $preference->value = '1';
                insert_record('user_preferences', $preference);
            }
            $adminuser->maildisplay = 0;
            // do not use return email to self, it might actually help emails to get through and prevents notices
            // Message them with the notice about upgrading
            email_to_user($adminuser, $adminuser, $messagesubject, html_to_text($message), $message);
        }
        unset($adminusers);
        unset($preference);
        unset($message);
        unset($messagesubject);
        upgrade_main_savepoint($result, 2007101561.02);
    }
    if ($result && $oldversion < 2007101563.02) {
        // this block tries to undo incorrect forcing of new passwords for admins that have no
        // way to change passwords MDL-20933
        $systemcontext = get_context_instance(CONTEXT_SYSTEM);
        $sql = "SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, u.password\n                  FROM {$CFG->prefix}role_capabilities rc\n                  JOIN {$CFG->prefix}role_assignments ra ON (ra.contextid = rc.contextid AND ra.roleid = rc.roleid)\n                  JOIN {$CFG->prefix}user u ON u.id = ra.userid\n                 WHERE rc.capability = 'moodle/site:doanything'\n                       AND rc.permission = " . CAP_ALLOW . "\n                       AND u.deleted = 0\n                       AND rc.contextid = " . $systemcontext->id . " AND u.auth<>'manual' AND u.auth<>'email'";
        if ($adminusers = get_records_sql($sql)) {
            foreach ($adminusers as $adminuser) {
                delete_records('user_preferences', 'userid', $adminuser->id, 'name', 'auth_forcepasswordchange');
            }
        }
        unset($adminusers);
        upgrade_main_savepoint($result, 2007101563.02);
    }
    if ($result && $oldversion < 2007101563.03) {
        // NOTE: this is quite hacky, but anyway it should work fine in 1.9,
        //       in 2.0 we should always use plugin upgrade code for things like this
        $authsavailable = get_list_of_plugins('auth');
        foreach ($authsavailable as $authname) {
            if (!($auth = get_auth_plugin($authname))) {
                continue;
            }
            if ($auth->prevent_local_passwords()) {
                execute_sql("UPDATE {$CFG->prefix}user SET password='******' WHERE auth='{$authname}'");
            }
        }
        upgrade_main_savepoint($result, 2007101563.03);
    }
    return $result;
}
/**
 * Installs the roles system.
 * This function runs on a fresh install as well as on an upgrade from the old
 * hard-coded student/teacher/admin etc. roles to the new roles system.
 */
function moodle_install_roles()
{
    global $CFG, $db;
    /// Create a system wide context for assignemnt.
    $systemcontext = $context = get_context_instance(CONTEXT_SYSTEM);
    /// Create default/legacy roles and capabilities.
    /// (1 legacy capability per legacy role at system level).
    $adminrole = create_role(addslashes(get_string('administrator')), 'admin', addslashes(get_string('administratordescription')), 'moodle/legacy:admin');
    $coursecreatorrole = create_role(addslashes(get_string('coursecreators')), 'coursecreator', addslashes(get_string('coursecreatorsdescription')), 'moodle/legacy:coursecreator');
    $editteacherrole = create_role(addslashes(get_string('defaultcourseteacher')), 'editingteacher', addslashes(get_string('defaultcourseteacherdescription')), 'moodle/legacy:editingteacher');
    $noneditteacherrole = create_role(addslashes(get_string('noneditingteacher')), 'teacher', addslashes(get_string('noneditingteacherdescription')), 'moodle/legacy:teacher');
    $studentrole = create_role(addslashes(get_string('defaultcoursestudent')), 'student', addslashes(get_string('defaultcoursestudentdescription')), 'moodle/legacy:student');
    $guestrole = create_role(addslashes(get_string('guest')), 'guest', addslashes(get_string('guestdescription')), 'moodle/legacy:guest');
    $userrole = create_role(addslashes(get_string('authenticateduser')), 'user', addslashes(get_string('authenticateduserdescription')), 'moodle/legacy:user');
    /// Now is the correct moment to install capabilities - after creation of legacy roles, but before assigning of roles
    if (!assign_capability('moodle/site:doanything', CAP_ALLOW, $adminrole, $systemcontext->id)) {
        error('Could not assign moodle/site:doanything to the admin role');
    }
    if (!update_capabilities()) {
        error('Had trouble upgrading the core capabilities for the Roles System');
    }
    /// Look inside user_admin, user_creator, user_teachers, user_students and
    /// assign above new roles. If a user has both teacher and student role,
    /// only teacher role is assigned. The assignment should be system level.
    $dbtables = $db->MetaTables('TABLES');
    /// Set up the progress bar
    $usertables = array('user_admins', 'user_coursecreators', 'user_teachers', 'user_students');
    $totalcount = $progresscount = 0;
    foreach ($usertables as $usertable) {
        if (in_array($CFG->prefix . $usertable, $dbtables)) {
            $totalcount += count_records($usertable);
        }
    }
    print_progress(0, $totalcount, 5, 1, 'Processing role assignments');
    /// Upgrade the admins.
    /// Sort using id ASC, first one is primary admin.
    if (in_array($CFG->prefix . 'user_admins', $dbtables)) {
        if ($rs = get_recordset_sql('SELECT * from ' . $CFG->prefix . 'user_admins ORDER BY ID ASC')) {
            while ($admin = rs_fetch_next_record($rs)) {
                role_assign($adminrole, $admin->userid, 0, $systemcontext->id);
                $progresscount++;
                print_progress($progresscount, $totalcount, 5, 1, 'Processing role assignments');
            }
            rs_close($rs);
        }
    } else {
        // This is a fresh install.
    }
    /// Upgrade course creators.
    if (in_array($CFG->prefix . 'user_coursecreators', $dbtables)) {
        if ($rs = get_recordset('user_coursecreators')) {
            while ($coursecreator = rs_fetch_next_record($rs)) {
                role_assign($coursecreatorrole, $coursecreator->userid, 0, $systemcontext->id);
                $progresscount++;
                print_progress($progresscount, $totalcount, 5, 1, 'Processing role assignments');
            }
            rs_close($rs);
        }
    }
    /// Upgrade editting teachers and non-editting teachers.
    if (in_array($CFG->prefix . 'user_teachers', $dbtables)) {
        if ($rs = get_recordset('user_teachers')) {
            while ($teacher = rs_fetch_next_record($rs)) {
                // removed code here to ignore site level assignments
                // since the contexts are separated now
                // populate the user_lastaccess table
                $access = new object();
                $access->timeaccess = $teacher->timeaccess;
                $access->userid = $teacher->userid;
                $access->courseid = $teacher->course;
                insert_record('user_lastaccess', $access);
                // assign the default student role
                $coursecontext = get_context_instance(CONTEXT_COURSE, $teacher->course);
                // needs cache
                // hidden teacher
                if ($teacher->authority == 0) {
                    $hiddenteacher = 1;
                } else {
                    $hiddenteacher = 0;
                }
                if ($teacher->editall) {
                    // editting teacher
                    role_assign($editteacherrole, $teacher->userid, 0, $coursecontext->id, $teacher->timestart, $teacher->timeend, $hiddenteacher, $teacher->enrol, $teacher->timemodified);
                } else {
                    role_assign($noneditteacherrole, $teacher->userid, 0, $coursecontext->id, $teacher->timestart, $teacher->timeend, $hiddenteacher, $teacher->enrol, $teacher->timemodified);
                }
                $progresscount++;
                print_progress($progresscount, $totalcount, 5, 1, 'Processing role assignments');
            }
            rs_close($rs);
        }
    }
    /// Upgrade students.
    if (in_array($CFG->prefix . 'user_students', $dbtables)) {
        if ($rs = get_recordset('user_students')) {
            while ($student = rs_fetch_next_record($rs)) {
                // populate the user_lastaccess table
                $access = new object();
                $access->timeaccess = $student->timeaccess;
                $access->userid = $student->userid;
                $access->courseid = $student->course;
                insert_record('user_lastaccess', $access);
                // assign the default student role
                $coursecontext = get_context_instance(CONTEXT_COURSE, $student->course);
                role_assign($studentrole, $student->userid, 0, $coursecontext->id, $student->timestart, $student->timeend, 0, $student->enrol, $student->time);
                $progresscount++;
                print_progress($progresscount, $totalcount, 5, 1, 'Processing role assignments');
            }
            rs_close($rs);
        }
    }
    /// Upgrade guest (only 1 entry).
    if ($guestuser = get_record('user', 'username', 'guest')) {
        role_assign($guestrole, $guestuser->id, 0, $systemcontext->id);
    }
    print_progress($totalcount, $totalcount, 5, 1, 'Processing role assignments');
    /// Insert the correct records for legacy roles
    allow_assign($adminrole, $adminrole);
    allow_assign($adminrole, $coursecreatorrole);
    allow_assign($adminrole, $noneditteacherrole);
    allow_assign($adminrole, $editteacherrole);
    allow_assign($adminrole, $studentrole);
    allow_assign($adminrole, $guestrole);
    allow_assign($coursecreatorrole, $noneditteacherrole);
    allow_assign($coursecreatorrole, $editteacherrole);
    allow_assign($coursecreatorrole, $studentrole);
    allow_assign($coursecreatorrole, $guestrole);
    allow_assign($editteacherrole, $noneditteacherrole);
    allow_assign($editteacherrole, $studentrole);
    allow_assign($editteacherrole, $guestrole);
    /// Set up default allow override matrix
    allow_override($adminrole, $adminrole);
    allow_override($adminrole, $coursecreatorrole);
    allow_override($adminrole, $noneditteacherrole);
    allow_override($adminrole, $editteacherrole);
    allow_override($adminrole, $studentrole);
    allow_override($adminrole, $guestrole);
    allow_override($adminrole, $userrole);
    //See MDL-15841
    //allow_override($editteacherrole, $noneditteacherrole);
    //allow_override($editteacherrole, $studentrole);
    //allow_override($editteacherrole, $guestrole);
    /// Delete the old user tables when we are done
    $tables = array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins');
    foreach ($tables as $tablename) {
        $table = new XMLDBTable($tablename);
        if (table_exists($table)) {
            drop_table($table);
        }
    }
}
Example #9
0
/**
 * Function to be run periodically according to the moodle cron
 * Finds all posts that have yet to be mailed out, and mails them
 * out to all subscribers
*/
function forum_cron()
{
    global $CFG, $USER;
    $CFG->enablerecordcache = true;
    // We want all the caching we can get
    $cronuser = clone $USER;
    $site = get_site();
    // all users that are subscribed to any post that needs sending
    $users = array();
    // status arrays
    $mailcount = array();
    $errorcount = array();
    // caches
    $discussions = array();
    $forums = array();
    $courses = array();
    $coursemodules = array();
    $postinfos = array();
    $subscribedusers = array();
    // Posts older than 2 days will not be mailed.  This is to avoid the problem where
    // cron has not been running for a long time, and then suddenly people are flooded
    // with mail from the past few weeks or months
    $timenow = time();
    $endtime = $timenow - $CFG->maxeditingtime;
    $starttime = $endtime - 48 * 3600;
    // Two days earlier
    if ($posts = forum_get_unmailed_posts($starttime, $endtime)) {
        // Mark them all now as being mailed.  It's unlikely but possible there
        // might be an error later so that a post is NOT actually mailed out,
        // but since mail isn't crucial, we can accept this risk.  Doing it now
        // prevents the risk of duplicated mails, which is a worse problem.
        if (!forum_mark_old_posts_as_mailed($endtime)) {
            mtrace('Errors occurred while trying to mark some posts as being mailed.');
            return false;
            // Don't continue trying to mail them, in case we are in a cron loop
        }
        // checking post validity, and adding users to loop through later
        foreach ($posts as $pid => $post) {
            $discussionid = $post->discussion;
            if (!isset($discussions[$discussionid])) {
                if ($discussion = get_record('forum_discussions', 'id', $post->discussion)) {
                    $discussions[$discussionid] = $discussion;
                } else {
                    mtrace('Could not find discussion ' . $discussionid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $forumid = $discussions[$discussionid]->forum;
            if (!isset($forums[$forumid])) {
                if ($forum = get_record('forum', 'id', $forumid)) {
                    $forums[$forumid] = $forum;
                } else {
                    mtrace('Could not find forum ' . $forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            $courseid = $forums[$forumid]->course;
            if (!isset($courses[$courseid])) {
                if ($course = get_record('course', 'id', $courseid)) {
                    $courses[$courseid] = $course;
                } else {
                    mtrace('Could not find course ' . $courseid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            if (!isset($coursemodules[$forumid])) {
                if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                    $coursemodules[$forumid] = $cm;
                } else {
                    mtrace('Could not course module for forum ' . $forumid);
                    unset($posts[$pid]);
                    continue;
                }
            }
            // caching subscribed users of each forum
            if (!isset($subscribedusers[$forumid])) {
                if ($subusers = forum_subscribed_users($courses[$courseid], $forums[$forumid], 0, true)) {
                    foreach ($subusers as $postuser) {
                        // do not try to mail users with stopped email
                        if ($postuser->emailstop) {
                            add_to_log(SITEID, 'forum', 'mail blocked', '', '', 0, $postuser->id);
                            continue;
                        }
                        // this user is subscribed to this forum
                        $subscribedusers[$forumid][] = $postuser->id;
                        // this user is a user we have to process later
                        $users[$postuser->id] = $postuser;
                    }
                }
            }
            $mailcount[$pid] = 0;
            $errorcount[$pid] = 0;
        }
    }
    if ($users && $posts) {
        $urlinfo = parse_url($CFG->wwwroot);
        $hostname = $urlinfo['host'];
        foreach ($users as $userto) {
            @set_time_limit(120);
            // terminate if processing of any account takes longer than 2 minutes
            // set this so that the capabilities are cached, and environment matches receiving user
            $USER = $userto;
            mtrace('Processing user ' . $userto->id);
            // we might want to add another layer - forums here (by checking array_keys($subscribedusers))
            // so that we can skip many posts
            foreach ($posts as $pid => $post) {
                // Get info about the sending user
                if (array_key_exists($post->userid, $users)) {
                    // we might know him/her already
                    $userfrom = $users[$post->userid];
                } else {
                    if (!($userfrom = get_record('user', 'id', $post->userid))) {
                        mtrace('Could not find user ' . $post->userid);
                        continue;
                    }
                }
                // Set up the environment for the post, discussion, forum, course
                $discussion = $discussions[$post->discussion];
                $forum = $forums[$discussion->forum];
                $course = $courses[$forum->course];
                $cm = $coursemodules[$forum->id];
                // Do some checks  to see if we can bail out now
                if (empty($subscribedusers[$forum->id]) || !in_array($userto->id, $subscribedusers[$forum->id])) {
                    continue;
                    // user does not subscribe to this forum
                }
                // setup global $COURSE properly - needed for roles and languages
                course_setup($course);
                // More environment
                // Get the context (from cache)
                $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
                // Cached already
                $post->modcontext = $modcontext;
                $post->viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext);
                // Make sure groups allow this user to see this email
                if ($discussion->groupid > 0 and $groupmode = groups_get_activity_groupmode($cm)) {
                    // Groups are being used
                    if (!groups_group_exists($discussion->groupid)) {
                        // Can't find group
                        continue;
                        // Be safe and don't send it to anyone
                    }
                    if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $modcontext)) {
                        // do not send posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
                        continue;
                    }
                }
                // Make sure we're allowed to see it...
                if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) {
                    mtrace('user ' . $userto->id . ' can not see ' . $post->id);
                    continue;
                }
                // OK so we need to send the email.
                // Does the user want this post in a digest?  If so postpone it for now.
                if ($userto->maildigest > 0) {
                    // This user wants the mails to be in digest form
                    $queue = new object();
                    $queue->userid = $userto->id;
                    $queue->discussionid = $discussion->id;
                    $queue->postid = $post->id;
                    $queue->timemodified = $post->modified;
                    if (!insert_record('forum_queue', $queue)) {
                        mtrace("Error: mod/forum/cron.php: Could not queue for digest mail for id {$post->id} to user {$userto->id} ({$userto->email}) .. not trying again.");
                    }
                    continue;
                }
                // Prepare to actually send the post now, and build up the content
                $cleanforumname = str_replace('"', "'", strip_tags(format_string($forum->name)));
                $userfrom->customheaders = array('Precedence: Bulk', 'List-Id: "' . $cleanforumname . '" <moodleforum' . $forum->id . '@' . $hostname . '>', 'List-Help: ' . $CFG->wwwroot . '/mod/forum/view.php?f=' . $forum->id, 'Message-ID: <moodlepost' . $post->id . '@' . $hostname . '>', 'In-Reply-To: <moodlepost' . $post->parent . '@' . $hostname . '>', 'References: <moodlepost' . $post->parent . '@' . $hostname . '>', 'X-Course-Id: ' . $course->id, 'X-Course-Name: ' . format_string($course->fullname, true));
                $postsubject = "{$course->shortname}: " . format_string($post->subject, true);
                $posttext = forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto);
                $posthtml = forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $userto);
                // Send the post now!
                mtrace('Sending ', '');
                if (!($mailresult = email_to_user($userto, $userfrom, $postsubject, $posttext, $posthtml, '', '', $CFG->forum_replytouser))) {
                    mtrace("Error: mod/forum/cron.php: Could not send out mail for id {$post->id} to user {$userto->id}" . " ({$userto->email}) .. not trying again.");
                    add_to_log($course->id, 'forum', 'mail error', "discuss.php?d={$discussion->id}#p{$post->id}", substr(format_string($post->subject, true), 0, 30), $cm->id, $userto->id);
                    $errorcount[$post->id]++;
                } else {
                    if ($mailresult === 'emailstop') {
                        // should not be reached anymore - see check above
                    } else {
                        $mailcount[$post->id]++;
                        // Mark post as read if forum_usermarksread is set off
                        if (!$CFG->forum_usermarksread && forum_tp_can_track_forums($forum, $userto) && forum_tp_is_tracked($forum, $userto->id)) {
                            if (!forum_tp_mark_post_read($userto->id, $post, $forum->id)) {
                                mtrace("Error: mod/forum/cron.php: Could not mark post {$post->id} read for user {$userto->id}" . " while sending email.");
                            }
                        }
                    }
                }
                mtrace('post ' . $post->id . ': ' . $post->subject);
            }
        }
    }
    if ($posts) {
        foreach ($posts as $post) {
            mtrace($mailcount[$post->id] . " users were sent post {$post->id}, '{$post->subject}'");
            if ($errorcount[$post->id]) {
                set_field("forum_posts", "mailed", "2", "id", "{$post->id}");
            }
        }
    }
    $USER = clone $cronuser;
    course_setup(SITEID);
    $sitetimezone = $CFG->timezone;
    // Now see if there are any digest mails waiting to be sent, and if we should send them
    mtrace('Starting digest processing...');
    @set_time_limit(300);
    // terminate if not able to fetch all digests in 5 minutes
    if (!isset($CFG->digestmailtimelast)) {
        // To catch the first time
        set_config('digestmailtimelast', 0);
    }
    $timenow = time();
    $digesttime = usergetmidnight($timenow, $sitetimezone) + $CFG->digestmailtime * 3600;
    // Delete any really old ones (normally there shouldn't be any)
    $weekago = $timenow - 7 * 24 * 3600;
    delete_records_select('forum_queue', "timemodified < {$weekago}");
    mtrace('Cleaned old digest records');
    if ($CFG->digestmailtimelast < $digesttime and $timenow > $digesttime) {
        mtrace('Sending forum digests: ' . userdate($timenow, '', $sitetimezone));
        $digestposts_rs = get_recordset('forum_queue');
        if (!rs_EOF($digestposts_rs)) {
            // We have work to do
            $usermailcount = 0;
            //caches - reuse the those filled before too
            $discussionposts = array();
            $userdiscussions = array();
            while ($digestpost = rs_fetch_next_record($digestposts_rs)) {
                if (!isset($users[$digestpost->userid])) {
                    if ($user = get_record('user', 'id', $digestpost->userid)) {
                        $users[$digestpost->userid] = $user;
                    } else {
                        continue;
                    }
                }
                $postuser = $users[$digestpost->userid];
                if ($postuser->emailstop) {
                    add_to_log(SITEID, 'forum', 'mail blocked', '', '', 0, $postuser->id);
                    continue;
                }
                if (!isset($posts[$digestpost->postid])) {
                    if ($post = get_record('forum_posts', 'id', $digestpost->postid)) {
                        $posts[$digestpost->postid] = $post;
                    } else {
                        continue;
                    }
                }
                $discussionid = $digestpost->discussionid;
                if (!isset($discussions[$discussionid])) {
                    if ($discussion = get_record('forum_discussions', 'id', $discussionid)) {
                        $discussions[$discussionid] = $discussion;
                    } else {
                        continue;
                    }
                }
                $forumid = $discussions[$discussionid]->forum;
                if (!isset($forums[$forumid])) {
                    if ($forum = get_record('forum', 'id', $forumid)) {
                        $forums[$forumid] = $forum;
                    } else {
                        continue;
                    }
                }
                $courseid = $forums[$forumid]->course;
                if (!isset($courses[$courseid])) {
                    if ($course = get_record('course', 'id', $courseid)) {
                        $courses[$courseid] = $course;
                    } else {
                        continue;
                    }
                }
                if (!isset($coursemodules[$forumid])) {
                    if ($cm = get_coursemodule_from_instance('forum', $forumid, $courseid)) {
                        $coursemodules[$forumid] = $cm;
                    } else {
                        continue;
                    }
                }
                $userdiscussions[$digestpost->userid][$digestpost->discussionid] = $digestpost->discussionid;
                $discussionposts[$digestpost->discussionid][$digestpost->postid] = $digestpost->postid;
            }
            rs_close($digestposts_rs);
            /// Finished iteration, let's close the resultset
            // Data collected, start sending out emails to each user
            foreach ($userdiscussions as $userid => $thesediscussions) {
                @set_time_limit(120);
                // terminate if processing of any account takes longer than 2 minutes
                mtrace(get_string('processingdigest', 'forum', $userid), '... ');
                // First of all delete all the queue entries for this user
                delete_records('forum_queue', 'userid', $userid);
                $userto = $users[$userid];
                // Override the language and timezone of the "current" user, so that
                // mail is customised for the receiver.
                $USER = $userto;
                course_setup(SITEID);
                $postsubject = get_string('digestmailsubject', 'forum', format_string($site->shortname, true));
                $headerdata = new object();
                $headerdata->sitename = format_string($site->fullname, true);
                $headerdata->userprefs = $CFG->wwwroot . '/user/edit.php?id=' . $userid . '&amp;course=' . $site->id;
                $posttext = get_string('digestmailheader', 'forum', $headerdata) . "\n\n";
                $headerdata->userprefs = '<a target="_blank" href="' . $headerdata->userprefs . '">' . get_string('digestmailprefs', 'forum') . '</a>';
                $posthtml = "<head>";
                foreach ($CFG->stylesheets as $stylesheet) {
                    $posthtml .= '<link rel="stylesheet" type="text/css" href="' . $stylesheet . '" />' . "\n";
                }
                $posthtml .= "</head>\n<body>\n";
                $posthtml .= '<p>' . get_string('digestmailheader', 'forum', $headerdata) . '</p><br /><hr size="1" noshade="noshade" />';
                foreach ($thesediscussions as $discussionid) {
                    @set_time_limit(120);
                    // to be reset for each post
                    $discussion = $discussions[$discussionid];
                    $forum = $forums[$discussion->forum];
                    $course = $courses[$forum->course];
                    $cm = $coursemodules[$forum->id];
                    //override language
                    course_setup($course);
                    $strforums = get_string('forums', 'forum');
                    $canunsubscribe = !forum_is_forcesubscribed($forum);
                    $canreply = forum_user_can_post($forum, $userto);
                    $posttext .= "\n \n";
                    $posttext .= '=====================================================================';
                    $posttext .= "\n \n";
                    $posttext .= "{$course->shortname} -> {$strforums} -> " . format_string($forum->name, true);
                    if ($discussion->name != $forum->name) {
                        $posttext .= " -> " . format_string($discussion->name, true);
                    }
                    $posttext .= "\n";
                    $posthtml .= "<p><font face=\"sans-serif\">" . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/course/view.php?id={$course->id}\">{$course->shortname}</a> -> " . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/index.php?id={$course->id}\">{$strforums}</a> -> " . "<a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/view.php?f={$forum->id}\">" . format_string($forum->name, true) . "</a>";
                    if ($discussion->name == $forum->name) {
                        $posthtml .= "</font></p>";
                    } else {
                        $posthtml .= " -> <a target=\"_blank\" href=\"{$CFG->wwwroot}/mod/forum/discuss.php?d={$discussion->id}\">" . format_string($discussion->name, true) . "</a></font></p>";
                    }
                    $posthtml .= '<p>';
                    $postsarray = $discussionposts[$discussionid];
                    sort($postsarray);
                    // Create an empty array to use for marking read posts.
                    // (I'm sure there's already a structure I can use here, but I can't be sure.)
                    $markread = array();
                    foreach ($postsarray as $postid) {
                        $post = $posts[$postid];
                        if (array_key_exists($post->userid, $users)) {
                            // we might know him/her already
                            $userfrom = $users[$post->userid];
                        } else {
                            if (!($userfrom = get_record('user', 'id', $post->userid))) {
                                mtrace('Could not find user ' . $post->userid);
                                continue;
                            }
                        }
                        $userfrom->customheaders = array("Precedence: Bulk");
                        if ($userto->maildigest == 2) {
                            // Subjects only
                            $by = new object();
                            $by->name = fullname($userfrom);
                            $by->date = userdate($post->modified);
                            $posttext .= "\n" . format_string($post->subject, true) . ' ' . get_string("bynameondate", "forum", $by);
                            $posttext .= "\n---------------------------------------------------------------------";
                            $by->name = "<a target=\"_blank\" href=\"{$CFG->wwwroot}/user/view.php?id={$userfrom->id}&amp;course={$course->id}\">{$by->name}</a>";
                            $posthtml .= '<div><a target="_blank" href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $discussion->id . '#p' . $post->id . '">' . format_string($post->subject, true) . '</a> ' . get_string("bynameondate", "forum", $by) . '</div>';
                        } else {
                            // The full treatment
                            $posttext .= forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto, true);
                            $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, true, false);
                            // Create an array of postid's for this user to mark as read.
                            if (!$CFG->forum_usermarksread && forum_tp_can_track_forums($forum, $userto) && forum_tp_is_tracked($forum, $userto->id)) {
                                $markread[$post->id]->post = $post;
                                $markread[$post->id]->forumid = $forum->id;
                            }
                        }
                    }
                    if ($canunsubscribe) {
                        $posthtml .= "\n<div align=\"right\"><font size=\"1\"><a href=\"{$CFG->wwwroot}/mod/forum/subscribe.php?id={$forum->id}\">" . get_string("unsubscribe", "forum") . "</a></font></div>";
                    } else {
                        $posthtml .= "\n<div align=\"right\"><font size=\"1\">" . get_string("everyoneissubscribed", "forum") . "</font></div>";
                    }
                    $posthtml .= '<hr size="1" noshade="noshade" /></p>';
                }
                $posthtml .= '</body>';
                if ($userto->mailformat != 1) {
                    // This user DOESN'T want to receive HTML
                    $posthtml = '';
                }
                if (!($mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, '', '', $CFG->forum_replytouser))) {
                    mtrace("ERROR!");
                    echo "Error: mod/forum/cron.php: Could not send out digest mail to user {$userto->id} ({$userto->email})... not trying again.\n";
                    add_to_log($course->id, 'forum', 'mail digest error', '', '', $cm->id, $userto->id);
                } else {
                    if ($mailresult === 'emailstop') {
                        // should not happen anymore - see check above
                    } else {
                        mtrace("success.");
                        $usermailcount++;
                        // Mark post as read if forum_usermarksread is set off
                        if (!$CFG->forum_usermarksread && forum_tp_can_track_forums($forum->id, $userto) && forum_tp_is_tracked($forum->id, $userto->id)) {
                            foreach ($markread as $postinfo) {
                                if (!forum_tp_mark_post_read($userto->id, $postinfo->post, $postinfo->forumid)) {
                                    mtrace("Error: mod/forum/cron.php: Could not mark post {$postid} read for user {$userto->id}" . " while sending digest email.");
                                }
                            }
                        }
                    }
                }
            }
        }
        /// We have finishied all digest emails, update $CFG->digestmailtimelast
        set_config('digestmailtimelast', $timenow);
    }
    if (!empty($usermailcount)) {
        mtrace(get_string('digestsentusers', 'forum', $usermailcount));
    }
    $USER = $cronuser;
    course_setup(SITEID);
    // reset cron user language, theme and timezone settings
    if (!empty($CFG->forum_lastreadclean)) {
        $timenow = time();
        if ($CFG->forum_lastreadclean + 24 * 3600 < $timenow) {
            set_config('forum_lastreadclean', $timenow);
            forum_tp_clean_read_records();
        }
    } else {
        set_config('forum_lastreadclean', time());
    }
    return true;
}
}
print_header();
if (empty($_POST['goahead'])) {
    print '<p>Are you sure you want to wipe all the load test data?</p>';
    print '<form enctype="multipart/form-data" action="wipe.php" method="post">
<input type="hidden" name="goahead" value="1" />
<input type="submit" value="Do it!"/>
</form>';
    print_footer();
    exit;
}
print '<ul><li>Deleting occurences</li>';
flush();
$before = get_field_sql('SELECT COUNT(*) FROM ' . $CFG->prefix . 'block_ousearch_occurrences');
$count = 0;
$rs = get_recordset('block_ousearch_documents', 'plugin', 'test/test', '', 'id');
while ($rec = rs_fetch_next_record($rs)) {
    delete_records('block_ousearch_occurrences', 'documentid', $rec->id);
    delete_records('block_ousearch_documents', 'id', $rec->id);
    $count++;
}
rs_close($rs);
$after = get_field_sql('SELECT COUNT(*) FROM ' . $CFG->prefix . 'block_ousearch_occurrences');
$occurrences = $before - $after;
print "<li>{$count} documents deleted ({$occurrences} occurrences)</li>";
flush();
$before = get_field_sql('SELECT COUNT(*) FROM ' . $CFG->prefix . 'block_ousearch_words');
delete_records_select('block_ousearch_words', 'NOT(id IN (select wordid FROM ' . $CFG->prefix . 'block_ousearch_occurrences))');
$after = get_field_sql('SELECT COUNT(*) FROM ' . $CFG->prefix . 'block_ousearch_words');
$words = $before - $after;
print "<li>{$words} words deleted</li></ul>";
 static function get_recordset($table, $field = '', $value = '', $sort = '', $fields = '*', $limitfrom = '', $limitnum = '')
 {
     $rs = get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
     if (!$rs) {
         throw new forum_exception("Failed to get SQL recordset for {$sql}");
     }
     return $rs;
 }
 /**
  * Creates a new ForumNG by copying data (including all messages etc) from
  * an old forum. The old forum will be hidden.
  *
  * Behaviour is undefined if the old forum wasn't eligible for conversion
  * (forum_utils::get_convertible_forums).
  * @param object $course Moodle course object
  * @param int $forumcmid Old forum to convert
  * @param bool $progress If true, print progress to output
  * @param bool $hide If true, newly-created forum is also hidden
  * @param bool $nodata If true, no user data (posts, subscriptions, etc)
  *   is copied; you only get a forum with same configuration
  * @param bool $insection If true, remeber to create the new forumNG in the same section.
  * @throws forum_exception If any error occurs
  */
 public static function create_from_old_forum($course, $forumcmid, $progress, $hide, $nodata, $insection = true)
 {
     global $CFG;
     // Start the clock and a database transaction
     $starttime = microtime(true);
     forum_utils::start_transaction();
     // Note we do not use get_fast_modinfo because it doesn't contain the
     // complete $cm object.
     $cm = forum_utils::get_record('course_modules', 'id', $forumcmid);
     $forum = forum_utils::get_record('forum', 'id', $cm->instance);
     if ($progress) {
         print_heading(s($forum->name), '', 3);
         print '<ul><li>' . get_string('convert_process_init', 'forumng');
         flush();
     }
     // Hide forum
     forum_utils::update_record('course_modules', (object) array('id' => $cm->id, 'visible' => 0));
     // Table for changed subscription constants
     $subscriptiontranslate = array(0 => 1, 1 => 3, 2 => 2, 3 => 0);
     // Get, convert, and create forum table data
     $forumng = (object) array('course' => $course->id, 'name' => addslashes($forum->name), 'type' => 'general', 'intro' => addslashes($forum->intro), 'ratingscale' => $forum->scale, 'ratingfrom' => $forum->assesstimestart, 'ratinguntil' => $forum->assesstimefinish, 'ratingthreshold' => 1, 'grading' => $forum->assessed, 'attachmentmaxbytes' => $forum->maxbytes, 'subscription' => $subscriptiontranslate[$forum->forcesubscribe], 'feedtype' => $forum->rsstype, 'feeditems' => $forum->rssarticles, 'maxpostsperiod' => $forum->blockperiod, 'maxpostsblock' => $forum->blockafter, 'postingfrom' => 0, 'postinguntil' => 0, 'typedata' => null);
     require_once $CFG->dirroot . '/mod/forumng/lib.php';
     // Note: The idnumber is required. We cannot copy it because then there
     // would be a duplicate idnumber. Let's just leave blank, people will
     // have to configure this manually.
     $forumng->cmidnumber = '';
     if (!($newforumid = forumng_add_instance($forumng))) {
         throw new forum_exception("Failed to add forumng instance");
     }
     // Create and add course-modules entry
     $newcm = new stdClass();
     $newcm->course = $course->id;
     $newcm->module = get_field('modules', 'id', 'name', 'forumng');
     if (!$newcm->module) {
         throw new forum_exception("Cannot find forumng module id");
     }
     $newcm->instance = $newforumid;
     $newcm->section = $cm->section;
     $newcm->added = time();
     $newcm->score = $cm->score;
     $newcm->indent = $cm->indent;
     $newcm->visible = 0;
     // Forums are always hidden until finished
     $newcm->groupmode = $cm->groupmode;
     $newcm->groupingid = $cm->groupingid;
     $newcm->idnumber = $cm->idnumber;
     $newcm->groupmembersonly = $cm->groupmembersonly;
     // Include extra OU-specific data
     if (class_exists('ouflags')) {
         $newcm->showto = $cm->showto;
         $newcm->stealth = $cm->stealth;
         $newcm->parentcmid = $cm->parentcmid;
         $newcm->completion = $cm->completion;
         $newcm->completiongradeitemnumber = $cm->completiongradeitemnumber;
         $newcm->completionview = $cm->completionview;
         $newcm->availablefrom = $cm->availablefrom;
         $newcm->availableuntil = $cm->availableuntil;
         $newcm->showavailability = $cm->showavailability;
         $newcm->parentpagename = $cm->parentpagename;
     }
     // Add
     $newcm->id = forum_utils::insert_record('course_modules', $newcm);
     // Update section
     if ($insection) {
         $section = forum_utils::get_record('course_sections', 'id', $newcm->section);
         $updatesection = (object) array('id' => $section->id, 'sequence' => str_replace($cm->id, $cm->id . ',' . $newcm->id, $section->sequence));
         if ($updatesection->sequence == $section->sequence) {
             throw new forum_exception("Unable to update sequence");
         }
         forum_utils::update_record('course_sections', $updatesection);
     }
     // Construct forum object for new forum
     $newforum = self::get_from_id($forumng->id, forum::CLONE_DIRECT);
     if ($progress) {
         print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
     }
     if (!$nodata) {
         // Convert subscriptions
         switch ($newforum->get_effective_subscription_option()) {
             case self::SUBSCRIPTION_PERMITTED:
                 if ($progress) {
                     print '<li>' . get_string('convert_process_subscriptions_normal', 'forumng');
                     flush();
                 }
                 // Standard subscription - just copy subscriptions
                 $rs = forum_utils::get_recordset('forum_subscriptions', 'forum', $forum->id);
                 while ($rec = rs_fetch_next_record($rs)) {
                     forum_utils::insert_record('forumng_subscriptions', (object) array('forumid' => $forumng->id, 'userid' => $rec->userid, 'subscribed' => 1));
                 }
                 rs_close($rs);
                 if ($progress) {
                     print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
                 }
                 break;
             case self::SUBSCRIPTION_INITIALLY_SUBSCRIBED:
                 // Initial subscription is handled differently; the old forum
                 // stores all the subscriptions in the database, while in this
                 // forum we only store people who chose to unsubscribe
                 if ($progress) {
                     print '<li>' . get_string('convert_process_subscriptions_initial', 'forumng');
                     flush();
                 }
                 // Get list of those subscribed on old forum
                 $rs = forum_utils::get_recordset('forum_subscriptions', 'forum', $forum->id);
                 $subscribedbefore = array();
                 while ($rec = rs_fetch_next_record($rs)) {
                     $subscribedbefore[$rec->userid] = true;
                 }
                 rs_close();
                 // Get list of those subscribed on new forum
                 $new = $newforum->get_subscribers();
                 // For anyone in the new list but not the old list, add an
                 // unsubscribe
                 foreach ($new as $user) {
                     if (!array_key_exists($user->id, $subscribedbefore)) {
                         forum_utils::insert_record('forumng_subscriptions', (object) array('forumid' => $forumng->id, 'userid' => $user->id, 'subscribed' => 0));
                     }
                 }
                 if ($progress) {
                     print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
                 }
                 break;
         }
         // Convert discussions
         if ($progress) {
             print '<li>' . get_string('convert_process_discussions', 'forumng');
             flush();
         }
         $rsd = forum_utils::get_recordset('forum_discussions', 'forum', $forum->id);
         $count = 0;
         while ($recd = rs_fetch_next_record($rsd)) {
             // Convert discussion options
             $newd = (object) array('forumid' => $forumng->id, 'timestart' => $recd->timestart, 'timeend' => $recd->timeend, 'deleted' => 0, 'locked' => 0, 'sticky' => 0);
             if ($recd->groupid == -1 || !$newcm->groupmode) {
                 $newd->groupid = null;
             } else {
                 $newd->groupid = $recd->groupid;
             }
             // Save discussion
             $newd->id = forum_utils::insert_record('forumng_discussions', $newd);
             // Convert posts
             $lastposttime = -1;
             $discussionupdate = (object) array('id' => $newd->id);
             $postids = array();
             // From old post id to new post id
             $parentposts = array();
             // From new post id to old parent id
             $subjects = array();
             // From new id to subject text (no slashes)
             $rsp = forum_utils::get_recordset('forum_posts', 'discussion', $recd->id);
             while ($recp = rs_fetch_next_record($rsp)) {
                 // Convert post
                 $newp = (object) array('discussionid' => $newd->id, 'userid' => $recp->userid, 'created' => $recp->created, 'modified' => $recp->modified, 'deleted' => 0, 'deleteuserid' => null, 'mailstate' => self::MAILSTATE_DIGESTED, 'oldversion' => 0, 'edituserid' => null, 'subject' => addslashes($recp->subject), 'message' => addslashes($recp->message), 'format' => $recp->format, 'important' => 0);
                 // Are there any attachments?
                 $attachments = array();
                 if (class_exists('ouflags')) {
                     // OU has customisation for existing forum that supports
                     // multiple attachments
                     $attachmentrecords = forum_utils::get_records('forum_attachments', 'postid', $recp->id);
                     foreach ($attachmentrecords as $reca) {
                         $attachments[] = $reca->attachment;
                     }
                 } else {
                     // Standard forum uses attachment field for filename
                     if ($recp->attachment) {
                         $attachments[] = $recp->attachment;
                     }
                 }
                 $newp->attachments = count($attachments) ? 1 : 0;
                 // Add record
                 $newp->id = forum_utils::insert_record('forumng_posts', $newp);
                 // Remember details for later parent update
                 $postids[$recp->id] = $newp->id;
                 if ($recp->parent) {
                     $parentposts[$newp->id] = $recp->parent;
                 } else {
                     $discussionupdate->postid = $newp->id;
                 }
                 if ($newp->created > $lastposttime) {
                     $discussionupdate->lastpostid = $newp->id;
                 }
                 $subjects[$newp->id] = $recp->subject;
                 // Copy attachments
                 $oldfolder = $CFG->dataroot . "/{$course->id}/{$CFG->moddata}/forum/{$forum->id}/{$recp->id}";
                 $newfolder = forum_post::get_any_attachment_folder($course->id, $forumng->id, $newd->id, $newp->id);
                 $filesok = 0;
                 $filesfailed = 0;
                 foreach ($attachments as $attachment) {
                     // Create folder if it isn't there
                     $attachment = clean_filename($attachment);
                     check_dir_exists($newfolder, true, true);
                     // Copy file
                     try {
                         forum_utils::copy("{$oldfolder}/{$attachment}", "{$newfolder}/{$attachment}");
                         $filesok++;
                     } catch (forum_exception $e) {
                         if ($progress) {
                             print "[<strong>Warning</strong>: file copy failed for post " . $recp->id . " => " . $newp->id . ", file " . s($attachment) . "]";
                         }
                         $filesfailed++;
                     }
                 }
                 // If all files failed, clean up
                 if ($filesfailed && !$filesok) {
                     rmdir($newfolder);
                     $noattachments = (object) array('id' => $newp->id, 'attachments' => 0);
                     forum_utils::update_record('forumng_posts', $noattachments);
                 }
                 // Convert ratings
                 if ($forumng->ratingscale) {
                     $rsr = get_recordset('forum_ratings', 'post', $recp->id);
                     while ($recr = rs_fetch_next_record($rsr)) {
                         forum_utils::insert_record('forumng_ratings', (object) array('postid' => $newp->id, 'userid' => $recr->userid, 'time' => $recr->time, 'rating' => $recr->rating));
                     }
                     rs_close($rsr);
                 }
             }
             rs_close($rsp);
             // Update parent numbers
             $newparentids = array();
             foreach ($parentposts as $newid => $oldparentid) {
                 if (!array_key_exists($oldparentid, $postids)) {
                     throw new forum_exception("Unknown parent post {$oldparentid}");
                 }
                 $newparentid = $postids[$oldparentid];
                 forum_utils::update_record('forumng_posts', (object) array('id' => $newid, 'parentpostid' => $newparentid));
                 $newparentids[$newid] = $newparentid;
             }
             // Update subjects
             $removesubjects = array();
             // Array of ints to cancel subjects
             foreach ($newparentids as $newid => $newparentid) {
                 $subject = $subjects[$newid];
                 $parentsubject = $subjects[$newparentid];
                 if ($subject && ($subject == get_string('re', 'forum') . ' ' . $parentsubject || $subject == $parentsubject)) {
                     $removesubjects[] = $newid;
                 }
             }
             if (count($removesubjects)) {
                 $in = forum_utils::in_or_equals($removesubjects);
                 forum_utils::execute_sql("UPDATE {$CFG->prefix}forumng_posts SET subject=NULL WHERE id {$in}");
             }
             // Update first/last post numbers
             forum_utils::update_record('forumng_discussions', $discussionupdate);
             // Convert read data
             $rsr = forum_utils::get_recordset_sql("\nSELECT\n    userid, MAX(lastread) AS lastread\nFROM\n    {$CFG->prefix}forum_read\nWHERE\n    discussionid = {$recd->id}\nGROUP BY\n    userid");
             while ($recr = rs_fetch_next_record($rsr)) {
                 forum_utils::insert_record('forumng_read', (object) array('discussionid' => $newd->id, 'userid' => $recr->userid, 'time' => $recr->lastread));
             }
             rs_close($rsr);
             // Display dot for each discussion
             if ($progress) {
                 print '.';
                 $count++;
                 if ($count % 10 == 0) {
                     print $count;
                 }
                 flush();
             }
         }
         rs_close($rsd);
         if ($progress) {
             print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
         }
     }
     // Show forum
     if (!$hide && $cm->visible) {
         if ($progress) {
             print '<li>' . get_string('convert_process_show', 'forumng');
             flush();
         }
         $updatecm = (object) array('id' => $newcm->id, 'visible' => 1);
         forum_utils::update_record('course_modules', $updatecm);
         if ($progress) {
             print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
         }
     }
     // Transfer role assignments
     $oldcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
     $newcontext = get_context_instance(CONTEXT_MODULE, $newcm->id);
     $roles = get_records('role_assignments', 'contextid', $oldcontext->id);
     if ($roles) {
         if ($progress) {
             print '<li>' . get_string('convert_process_assignments', 'forumng');
             flush();
         }
         foreach ($roles as $role) {
             $newrole = $role;
             $newrole->contextid = $newcontext->id;
             $newrole->enrol = addslashes($newrole->enrol);
             forum_utils::insert_record('role_assignments', $newrole);
         }
         if ($progress) {
             print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
         }
     }
     // Transfer capabilities
     $capabilities = array('moodle/course:viewhiddenactivities' => 'moodle/course:viewhiddenactivities', 'moodle/site:accessallgroups' => 'moodle/site:accessallgroups', 'moodle/site:trustcontent' => 'moodle/site:trustcontent', 'moodle/site:viewfullnames' => 'moodle/site:viewfullnames', 'mod/forum:viewdiscussion' => 'mod/forumng:viewdiscussion', 'mod/forum:startdiscussion' => 'mod/forumng:startdiscussion', 'mod/forum:replypost' => 'mod/forumng:replypost', 'mod/forum:viewrating' => 'mod/forumng:viewrating', 'mod/forum:viewanyrating' => 'mod/forumng:viewanyrating', 'mod/forum:rate' => 'mod/forumng:rate', 'mod/forum:createattachment' => 'mod/forumng:createattachment', 'mod/forum:deleteanypost' => 'mod/forumng:deleteanypost', 'mod/forum:splitdiscussions' => 'mod/forumng:splitdiscussions', 'mod/forum:movediscussions' => 'mod/forumng:movediscussions', 'mod/forum:editanypost' => 'mod/forumng:editanypost', 'mod/forum:viewsubscribers' => 'mod/forumng:viewsubscribers', 'mod/forum:managesubscriptions' => 'mod/forumng:managesubscriptions', 'mod/forum:viewhiddentimedposts' => 'mod/forumng:viewallposts');
     $caps = get_records('role_capabilities', 'contextid', $oldcontext->id);
     if ($caps) {
         if ($progress) {
             print '<li>' . get_string('convert_process_overrides', 'forumng');
             flush();
         }
         foreach ($caps as $cap) {
             foreach ($capabilities as $key => $capability) {
                 if ($cap->capability != $key) {
                     continue;
                 }
                 $newcap = $cap;
                 $newcap->contextid = $newcontext->id;
                 $newcap->capability = $capability;
                 $newcap->capability = addslashes($newcap->capability);
                 forum_utils::insert_record('role_capabilities', $newcap);
             }
         }
         if ($progress) {
             print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
         }
     }
     // Do course cache
     rebuild_course_cache($course->id, true);
     // Update search data
     if (self::search_installed()) {
         if ($progress) {
             print '<li>' . get_string('convert_process_search', 'forumng') . '</li>';
             flush();
         }
         self::search_update_all($progress, $course->id, $newcm->id);
     }
     // OU only: Transfer external dashboard details to new forum
     if (class_exists('ouflags')) {
         if ($progress) {
             print '<li>' . get_string('convert_process_dashboard', 'forumng');
             flush();
         }
         require_once $CFG->dirroot . '/local/externaldashboard/external_dashboard.php';
         $a = new stdClass();
         list($a->yay, $a->nay) = external_dashboard::transfer_favourites($forumcmid, $newcm->id);
         if ($progress) {
             print ' ' . get_string('convert_process_dashboard_done', 'forumng', $a) . '</li>';
         }
     }
     if ($progress) {
         print '<li>' . get_string('convert_process_update_subscriptions', 'forumng');
         flush();
     }
     self::group_subscription_update(false, $newcm->id);
     if ($progress) {
         print ' ' . get_string('convert_process_state_done', 'forumng') . '</li>';
     }
     forum_utils::finish_transaction();
     if ($progress) {
         $a = (object) array('seconds' => round(microtime(true) - $starttime, 1), 'link' => '<a href="view.php?id=' . $newcm->id . '">' . get_string('convert_newforum', 'forumng') . '</a>');
         print '</ul><p>' . get_string('convert_process_complete', 'forumng', $a) . '</p>';
     }
 }
function xmldb_ouwiki_upgrade($oldversion = 0)
{
    global $CFG, $db;
    $result = true;
    /// And upgrade begins here. For each one, you'll need one
    /// block of code similar to the next one. Please, delete
    /// this comment lines once this file start handling proper
    /// upgrade code.
    /// if ($result && $oldversion < YYYYMMDD00) { //New version in version.php
    ///     $result = result of "/lib/ddllib.php" function calls
    /// }
    if ($result && $oldversion < 2007022300) {
        error('Cannot upgrade OU wiki module - please delete it by going to <a href="modules.php">the modules section</a> then delete it. (Module is called Wiki.) Then let it install itself again.');
    }
    if ($result && $oldversion < 2007041006) {
        // First fix some signed-ness, then upgrade database to support comment system
        $tw = new transaction_wrapper();
        /// Changing sign of field id on table ouwiki_subwikis to unsigned
        $table = new XMLDBTable('ouwiki_subwikis');
        $field = new XMLDBField('id');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
        /// Launch change of sign for field id
        $result = $result && change_field_unsigned($table, $field);
        /// Changing sign of field id on table ouwiki_pages to unsigned
        $table = new XMLDBTable('ouwiki_pages');
        $field = new XMLDBField('id');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
        /// Launch change of sign for field id
        $result = $result && change_field_unsigned($table, $field);
        /// Define key ouwiki_pages_fk_forumid (foreign) to be dropped form ouwiki_pages
        $table = new XMLDBTable('ouwiki_pages');
        $key = new XMLDBKey('ouwiki_pages_fk_forumid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('forumid'), 'forum', array('id'));
        /// Launch drop key ouwiki_pages_fk_forumid
        $result = $result && drop_key($table, $key);
        /// Define field forumid to be dropped from ouwiki_pages
        $table = new XMLDBTable('ouwiki_pages');
        $field = new XMLDBField('forumid');
        /// Launch drop field forumid
        $result = $result && drop_field($table, $field);
        /// Changing sign of field id on table ouwiki_versions to unsigned
        $table = new XMLDBTable('ouwiki_versions');
        $field = new XMLDBField('id');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
        /// Launch change of sign for field id
        $result = $result && change_field_unsigned($table, $field);
        /// Changing sign of field id on table ouwiki_links to unsigned
        $table = new XMLDBTable('ouwiki_links');
        $field = new XMLDBField('id');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
        /// Launch change of sign for field id
        $result = $result && change_field_unsigned($table, $field);
        /// Changing sign of field id on table ouwiki_locks to unsigned
        $table = new XMLDBTable('ouwiki_locks');
        $field = new XMLDBField('id');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null, null);
        /// Launch change of sign for field id
        $result = $result && change_field_unsigned($table, $field);
        // Due to a bug or issues with xmldb/postgres - MDL-9271 - it lost all the primary keys!
        // If this part of the upgrade fails because the primary keys are still there then that's
        // ok.
        /* XMLDB doesn't let you add primary keys! MDL-9272. Otherwise the code would be as follows:
           $table = new XMLDBTable('ouwiki_subwikis');
           $key = new XMLDBKey('primary');
           $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
           $result = $result && add_key($table, $key);
           $table = new XMLDBTable('ouwiki_pages');
           $key = new XMLDBKey('primary');
           $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
           $result = $result && add_key($table, $key);
           $table = new XMLDBTable('ouwiki_versions');
           $key = new XMLDBKey('primary');
           $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
           $result = $result && add_key($table, $key);
           $table = new XMLDBTable('ouwiki_links');
           $key = new XMLDBKey('primary');
           $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
           $result = $result && add_key($table, $key);
           $table = new XMLDBTable('ouwiki_locks');
           $key = new XMLDBKey('primary');
           $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
           $result = $result && add_key($table, $key);
           */
        // This is Postgres-only
        $result &= execute_sql("ALTER TABLE {$CFG->prefix}ouwiki_subwikis ADD CONSTRAINT {$CFG->prefix}ouwisubw_id_pk PRIMARY KEY(id)");
        $result &= execute_sql("ALTER TABLE {$CFG->prefix}ouwiki_pages ADD CONSTRAINT {$CFG->prefix}ouwipage_id_pk PRIMARY KEY(id)");
        $result &= execute_sql("ALTER TABLE {$CFG->prefix}ouwiki_versions ADD CONSTRAINT {$CFG->prefix}ouwivers_id_pk PRIMARY KEY(id)");
        $result &= execute_sql("ALTER TABLE {$CFG->prefix}ouwiki_links ADD CONSTRAINT {$CFG->prefix}ouwilink_id_pk PRIMARY KEY(id)");
        $result &= execute_sql("ALTER TABLE {$CFG->prefix}ouwiki_locks ADD CONSTRAINT {$CFG->prefix}ouwilock_id_pk PRIMARY KEY(id)");
        /// Define table ouwiki_sections to be created
        $table = new XMLDBTable('ouwiki_sections');
        /// Adding fields to table ouwiki_sections
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('pageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('xhtmlid', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table ouwiki_sections
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('ouwiki_sections_fk_pageid', XMLDB_KEY_FOREIGN, array('pageid'), 'ouwiki_pages', array('id'));
        /// Launch create table for ouwiki_sections
        $result = $result && create_table($table);
        /// Define table ouwiki_comments to be created
        $table = new XMLDBTable('ouwiki_comments');
        /// Adding fields to table ouwiki_comments
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('pagesectionid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('title', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('xhtml', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timeposted', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table ouwiki_comments
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oucontent_comments_pagesectionid_fk', XMLDB_KEY_FOREIGN, array('pagesectionid'), 'ouwiki_sections', array('id'));
        $table->addKeyInfo('oucontent_comments_userid_fk', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch create table for ouwiki_comments
        $result = $result && create_table($table);
        if ($result) {
            $tw->commit();
        } else {
            $tw->rollback();
        }
    }
    if ($result && $oldversion < 2007041007) {
        /// Changing nullability of field title on table ouwiki_sections to not null
        $table = new XMLDBTable('ouwiki_sections');
        $field = new XMLDBField('title');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'xhtmlid');
        /// Launch change of nullability for field title
        $result = $result && change_field_notnull($table, $field);
    }
    if ($result && $oldversion < 2007041103) {
        $result &= ouwiki_argh_fix_default('subwikis');
        $result &= ouwiki_argh_fix_default('pages');
        $result &= ouwiki_argh_fix_default('versions');
        $result &= ouwiki_argh_fix_default('links');
        $result &= ouwiki_argh_fix_default('locks');
    }
    if ($result && $oldversion < 2007041700) {
        /// Define key oucontent_comments_sectionid_fk (foreign) to be dropped form ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('oucontent_comments_pagesectionid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('pagesectionid'), 'ouwiki_sections', array('id'));
        /// Launch drop key oucontent_comments_pagesectionid_fk
        $result = $result && drop_key($table, $key);
        /// Rename field pagesectionid on table ouwiki_comments to sectionid
        $table = new XMLDBTable('ouwiki_comments');
        $field = new XMLDBField('pagesectionid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch rename field pagesectionid
        $result = $result && rename_field($table, $field, 'sectionid');
        /// Define key ouwiki_comments_sectionid_fk (foreign) to be added to ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('ouwiki_comments_sectionid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('sectionid'), 'ouwiki_sections', array('id'));
        /// Launch add key oucontent_comments_sectionid_fk
        $result = $result && add_key($table, $key);
    }
    if ($result && $oldversion == 2007041700) {
        /// Define key oucontent_comments_sectionid_fk (foreign) to be dropped form ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('oucontent_comments_pagesectionid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('pagesectionid'), 'ouwiki_sections', array('id'));
        /// Launch drop key oucontent_comments_pagesectionid_fk
        $result = $result && drop_key($table, $key);
        /// Define key ouwiki_comments_sectionid_fk (foreign) to be added to ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('ouwiki_comments_sectionid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('sectionid'), 'ouwiki_sections', array('id'));
        /// Launch add key oucontent_comments_sectionid_fk
        $result = $result && add_key($table, $key);
    }
    if ($result && $oldversion < 2007041701) {
        /// Define key oucontent_comments_userid_fk (foreign) to be dropped form ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('oucontent_comments_userid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch drop key oucontent_comments_userid_fk
        $result = $result && drop_key($table, $key);
        /// Define key ouwiki_comments_userid_fk (foreign) to be added to ouwiki_comments
        $table = new XMLDBTable('ouwiki_comments');
        $key = new XMLDBKey('ouwiki_comments_userid_fk');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch add key ouwiki_comments_userid_fk
        $result = $result && add_key($table, $key);
    }
    if ($result && $oldversion < 2007102900) {
        /// Define field magic to be added to ouwiki_subwikis
        $table = new XMLDBTable('ouwiki_subwikis');
        $field = new XMLDBField('magic');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '16', XMLDB_UNSIGNED, null, null, null, null, null, 'userid');
        /// Launch add field magic
        $result = $result && add_field($table, $field);
        /// Set up all existing field values
        $rs = get_recordset('ouwiki_subwikis', '', '', '', 'id');
        while ($rec = rs_fetch_next_record($rs)) {
            $magicnumber = ouwiki_generate_magic_number();
            set_field('ouwiki_subwikis', 'magic', $magicnumber, 'id', $rec->id);
        }
        rs_close($rs);
        /// Changing nullability of field magic on table ouwiki_subwikis to not null
        $field->setAttributes(XMLDB_TYPE_INTEGER, '16', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'userid');
        /// Launch change of nullability for field magic
        $result = $result && change_field_notnull($table, $field);
    }
    if ($result && $oldversion < 2008073000) {
        /// Define field completionpages to be added to ouwiki
        $table = new XMLDBTable('ouwiki');
        $field = new XMLDBField('completionpages');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '9', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'editend');
        /// Launch add field completionpages
        $result = $result && add_field($table, $field);
        /// Define field completionedits to be added to ouwiki
        $field = new XMLDBField('completionedits');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '9', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completionpages');
        /// Launch add field completionedits
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2008100600) {
        /// Define field deletedat to be added to ouwiki_versions
        $table = new XMLDBTable('ouwiki_versions');
        $field = new XMLDBField('deletedat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'changeprevsize');
        /// Launch add field deletedat (provided field does not already exist)
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
    }
    if ($result && $oldversion < 2010022300) {
        // Add ouwiki delete page capability to admin role if it exists
        // Check whether necessary
        $name = 'Administrator';
        $shortname = 'admin';
        if (($role = get_record('role', 'name', $name)) || ($role = get_record('role', 'shortname', $shortname))) {
            if ($sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID)) {
                // Check role has delete page capability (assign if not)
                $cap = 'mod/ouwiki:deletepage';
                if (!($rcap = get_record('role_capabilities', 'roleid', $role->id, 'capability', $cap, 'contextid', $sitecontext->id))) {
                    assign_capability($cap, CAP_ALLOW, $role->id, $sitecontext->id);
                }
            }
        }
    }
    if ($result && $oldversion < 2009120801) {
        $tw = new transaction_wrapper();
        /// Define table ouwiki_annotations to be created
        $table = new XMLDBTable('ouwiki_annotations');
        /// Adding fields to table ouwiki_annotations
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('pageid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('content', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table ouwiki_annotations
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for ouwiki_annotations - if it does not already exist (extra precaution)
        if (!table_exists($table)) {
            $result = $result && create_table($table);
        }
        /// Define field locked to be added to ouwiki_pages
        $table = new XMLDBTable('ouwiki_pages');
        $field = new XMLDBField('locked');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0', 'currentversionid');
        /// Launch add field locked - if it does not already exist (extra precaution)
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
        if ($result) {
            $tw->commit();
        } else {
            $tw->rollback();
        }
    }
    if ($result && $oldversion < 2010022300) {
        /// Define field commenting to be added to ouwiki
        $table = new XMLDBTable('ouwiki');
        $field = new XMLDBField('commenting');
        $field->setAttributes(XMLDB_TYPE_CHAR, '20', null, null, null, null, null, 'default', 'completionedits');
        /// Launch add field commenting - if it does not already exist (extra precaution)
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
    }
    if ($result && $oldversion < 2010042201) {
        /// Define key subwikiid (foreign) to be added to ouwiki_pages
        $table = new XMLDBTable('ouwiki_pages');
        $key = new XMLDBKey('subwikiid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('subwikiid'), 'ouwiki_subwikis', array('id'));
        /// Launch add key subwikiid
        if (!index_exists($table, $key)) {
            $result = $result && add_key($table, $key);
        }
    }
    return $result;
}
Example #14
0
function xmldb_block_curr_admin_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $db;
    $result = true;
    if ($oldversion < 2009010102) {
        $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
        if ($role = get_record('role', 'shortname', 'curriculumadmin')) {
            if ($role->name == 'Bundle Administrator') {
                $role->name = 'Curriculum Administrator';
                addslashes_object($role);
                update_record('role', $role);
            }
        }
        if (!empty($role->id)) {
            require_once dirname(__FILE__) . '/access.php';
            if (!empty($block_curr_admin_capabilities)) {
                foreach ($block_curr_admin_capabilities as $capname => $caprules) {
                    $result = $result && assign_capability($capname, CAP_ALLOW, $role->id, $context->id);
                }
            }
        }
    }
    if ($oldversion < 2009010103) {
        $table = new XMLDBTable('crlm_curriculum');
        $field = new XMLDBField('timetocomplete');
        $field->setAttributes(XMLDB_TYPE_CHAR, '64', NULL, XMLDB_NOTNULL, NULL, NULL, NULL, '0h, 0d, 0w, 0m, 0y', 'timemodified');
        $result = $result && add_field($table, $field);
        $field = new XMLDBField('frequency');
        $field->setAttributes(XMLDB_TYPE_CHAR, '64', NULL, XMLDB_NOTNULL, NULL, NULL, NULL, '0h, 0d, 0w, 0m, 0y', 'timetocomplete');
        $result = $result && add_field($table, $field);
    }
    if ($oldversion < 2009010104) {
        $table = new XMLDBTable('crlm_config');
        $table->comment = 'Curriculum management configuration values.';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null);
        $f = $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'medium', null, false, null, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('name_ix', XMLDB_INDEX_UNIQUE, array('name'));
        $result = $result && create_table($table);
    }
    if ($oldversion < 2009010105) {
        $table = new XMLDBTable('crlm_coursetemplate');
        $table->comment = 'Course templates';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('location', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null);
        $f = $table->addFieldInfo('templateclass', XMLDB_TYPE_CHAR, '255', null, false, null, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('courseid_ix', XMLDB_INDEX_UNIQUE, array('courseid'));
        $result = $result && create_table($table);
    }
    if ($oldversion < 2009010106) {
        $table = new XMLDBTable('crlm_cluster_curriculum');
        $table->comment = 'Association between clusters and curricula';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id');
        $f->comment = 'Foreign key to cluster id';
        $f = $table->addFieldInfo('curriculumid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid');
        $f->comment = 'Foreign key to curriculum id';
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        $result = $result && create_table($table);
    }
    if ($oldversion < 2009010108) {
        $table = new XMLDBTable('crlm_cluster_track');
        $table->comment = 'Association between clusters and tracks';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id');
        $f->comment = 'Foreign key to cluster id';
        $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid');
        $f->comment = 'Foreign key to track id';
        $f = $table->addFieldInfo('autounenrol', XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, null, 'trackid');
        $f->comment = 'Whether or not to remove a user from classes when removed from cluster';
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        $result = $result && create_table($table);
        $table = new XMLDBTable('crlm_usercluster');
        $f = new XMLDBField('autoenrol');
        $f->setAttributes(XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, 1, 'clusterid');
        $f->comment = 'Whether users should be autoenrolled in tracks associated with this cluster.';
        $result = $result && add_field($table, $f);
    }
    if ($oldversion < 2009010109) {
        /// Define table crlm_class_moodle to be created
        $table = new XMLDBTable('crlm_class_moodle');
        /// Adding fields to table crlm_class_moodle
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('moodlecourseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('enroltype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, null, null, null, null, '0');
        $table->addFieldInfo('enrolplugin', XMLDB_TYPE_CHAR, '20', null, null, null, null, null, 'crlm');
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table crlm_class_moodle
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('mdl_currclasmood_clamoo_uix', XMLDB_KEY_UNIQUE, array('classid', 'moodlecourseid'));
        /// Launch create table for crlm_class_moodle
        $result = $result && create_table($table);
    }
    if ($oldversion < 2009010110) {
        $table = new XMLDBTable('crlm_user_track');
        $table->comment = 'User enrolment in tracks';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id');
        $f->comment = 'Foreign key to user id';
        $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'userid');
        $f->comment = 'Foreign key to track id';
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009010112) {
        /// Define table crlm_notification_log to be created
        $table = new XMLDBTable('crlm_notification_log');
        /// Adding fields to table crlm_notification_log
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('event', XMLDB_TYPE_CHAR, '166', null, null, null, null, null, null);
        $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('data', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table crlm_notification_log
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_notification_log
        $table->addIndexInfo('event_inst_user_ix', XMLDB_INDEX_NOTUNIQUE, array('event', 'instance', 'userid'));
        /// Launch create table for crlm_notification_log
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009010113) {
        /// Define index event_inst_user_ix (not unique) to be dropped from crlm_notification_log
        $table = new XMLDBTable('crlm_notification_log');
        $index = new XMLDBIndex('event_inst_user_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('event', 'instance', 'userid'));
        /// Launch drop index event_inst_user_ix
        $result = $result && drop_index($table, $index);
        /// Define index event_inst_user_ix (not unique) to be added to crlm_notification_log
        $table = new XMLDBTable('crlm_notification_log');
        $index = new XMLDBIndex('event_inst_user_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid', 'instance', 'event'));
        /// Launch add index event_inst_user_ix
        $result = $result && add_index($table, $index);
    }
    if ($result && $oldversion < 2009010114) {
        // Creating track table
        $table = new XMLDBTable('crlm_track');
        $table->comment = 'Track table';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('curid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null);
        $f = $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('startdate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('enddate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('track_curr_idx', XMLDB_INDEX_NOTUNIQUE, array('curid'));
        $result = $result && create_table($table);
        $table = new XMLDBTable('crlm_track_class');
        $table->comment = 'Track class table';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('requried', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('autoenrol', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('default', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $f = $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('trackid_idx', XMLDB_INDEX_NOTUNIQUE, array('trackid'));
        $table->addIndexInfo('track_classid_idx', XMLDB_INDEX_NOTUNIQUE, array('classid'));
        $table->addIndexInfo('track_courseid_idx', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009010115) {
        /// Define table crlm_cluster_profile to be created
        $table = new XMLDBTable('crlm_cluster_profile');
        /// Adding fields to table crlm_cluster_profile
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_cluster_profile
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_cluster_profile
        $result = $result && create_table($table);
        /// Define table crlm_cluster_assignments to be created
        $table = new XMLDBTable('crlm_cluster_assignments');
        /// Adding fields to table crlm_cluster_assignments
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('plugin', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_cluster_assignments
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_cluster_assignments
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009010116) {
        $table = new XMLDBTable('crlm_track_class');
        $field = new XMLDBField('default');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol');
        $result = $result && drop_field($table, $field);
        $field = new XMLDBField('defaulttrack');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010117) {
        /// Remove obsolete job code tables if they exist.
        $table = new XMLDBTable('crlm_jobcode_list');
        if (table_exists($table)) {
            drop_table($table);
        }
        $table = new XMLDBTable('crlm_curriculum_jobcode');
        if (table_exists($table)) {
            drop_table($table);
        }
    }
    if ($result && $oldversion < 2009010118) {
        /// Removing defaulttrack column from table
        $table = new XMLDBTable('crlm_track_class');
        $field = new XMLDBField('defaulttrack');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol');
        $result = $result && drop_field($table, $field);
        /// Adding defaulttrack column to table
        $table = new XMLDBTable('crlm_track');
        $field = new XMLDBField('defaulttrack');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'enddate');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010119) {
        /// Define field completed to be added to crlm_curriculum_assignment
        $table = new XMLDBTable('crlm_curriculum_assignment');
        $field = new XMLDBField('completed');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'curriculumid');
        /// Launch add field completed
        $result = $result && add_field($table, $field);
        /// Define field completiontime to be added to crlm_curriculum_assignment
        $field = new XMLDBField('timecompleted');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'completed');
        /// Launch add field completiontime
        $result = $result && add_field($table, $field);
        /// Define field credits to be added to crlm_curriculum_assignment
        $field = new XMLDBField('credits');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timecompleted');
        /// Launch add field credits
        $result = $result && add_field($table, $field);
        /// Define field locked to be added to crlm_curriculum_assignment
        $table = new XMLDBTable('crlm_curriculum_assignment');
        $field = new XMLDBField('locked');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'credits');
        /// Launch add field locked
        $result = $result && add_field($table, $field);
        /// Define key mdl_currcurrassi_usecur_uix (unique) to be dropped from crlm_curriculum_assignment
        $key = new XMLDBKey('mdl_currcurrassi_usecur_uix');
        $key->setAttributes(XMLDB_KEY_UNIQUE, array('userid', 'curriculumid'));
        /// Launch drop key mdl_currcurrassi_usecur_uix
        $result = $result && drop_key($table, $key);
        /// Define index mdl_currcurrassi_usecurcom_ix (not unique) to be added to crlm_curriculum_assignment
        $index = new XMLDBIndex('mdl_currcurrassi_usecurcom_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid', 'curriculumid', 'completed'));
        /// Launch add index mdl_currcurrassi_usecurcom_ix
        $result = $result && add_index($table, $index);
        /// Define index completed_ix (not unique) to be added to crlm_curriculum_assignment
        $index = new XMLDBIndex('completed_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completed'));
        /// Launch add index completed_ix
        $result = $result && add_index($table, $index);
    }
    if ($result && $oldversion < 2009010120) {
        /// Define field autoenrol to be added to crlm_cluster_assignments
        $table = new XMLDBTable('crlm_cluster_assignments');
        $field = new XMLDBField('autoenrol');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'plugin');
        /// Launch add field autoenrol
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010121) {
        if (!record_exists('mnet_application', 'name', 'java')) {
            $application = new stdClass();
            $application->name = 'java';
            $application->display_name = 'Java servlet';
            $application->xmlrpc_server_url = '/mnet/server';
            $application->sso_land_url = '/mnet/land.jsp';
            $result = $result && insert_record('mnet_application', $application, false);
        }
    }
    if ($result && $oldversion < 2009010122) {
        $table = new XMLDBTable('crlm_track_class');
        $field = new XMLDBField('requried');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'courseid');
        $result = $result && drop_field($table, $field);
    }
    if ($result && $oldversion < 2009010125) {
        $result = $result && execute_sql('CREATE OR REPLACE VIEW `courseNforums` AS select `f`.`id` AS `forumid`,concat(`c`.`shortname`,_utf8\' | \',`f`.`name`) AS `courseNforumname` from (`mdl_forum` `f` join `mdl_course` `c` on((`c`.`id` = `f`.`course`))) order by `c`.`shortname`,`f`.`name`');
    }
    if ($result && $oldversion < 2009010126) {
        $table = new XMLDBTable('crlm_cluster_curriculum');
        $table->comment = 'Association between clusters and curricula';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id');
        $f->comment = 'Foreign key to cluster id';
        $f = $table->addFieldInfo('curriculumid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid');
        $f->comment = 'Foreign key to curriculum id';
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        $result = $result && (table_exists($table) || create_table($table));
        $table = new XMLDBTable('crlm_cluster_track');
        $table->comment = 'Association between clusters and tracks';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('clusterid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'id');
        $f->comment = 'Foreign key to cluster id';
        $f = $table->addFieldInfo('trackid', XMLDB_TYPE_INTEGER, '10', null, true, null, null, null, null, 'clusterid');
        $f->comment = 'Foreign key to track id';
        $f = $table->addFieldInfo('autounenrol', XMLDB_TYPE_INTEGER, '1', null, true, null, null, null, null, 'trackid');
        $f->comment = 'Whether or not to remove a user from classes when removed from cluster';
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('cluster_idx', XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        $result = $result && (table_exists($table) || create_table($table));
    }
    if ($result && $oldversion < 2009010127) {
        // fix silly typos
        $newtable = new XMLDBTable('crlm_user_track');
        $oldtable = new XMLDBTable('clrm_user_track');
        $result = $result && (table_exists($newtable) || rename_table($oldtable, 'crlm_user_track'));
        $oldtable = new XMLDBTable('clrm_cluster_track');
        $result = $result && (!table_exists($oldtable) || drop_table($oldtable));
        $oldtable = new XMLDBTable('clrm_cluster_curriculum');
        $result = $result && (!table_exists($oldtable) || drop_table($oldtable));
    }
    if ($result && $oldversion < 2009010128) {
        require_once $CFG->dirroot . '/curriculum/lib/lib.php';
        cm_migrate_moodle_users();
    }
    if ($result && $oldversion < 2009010131) {
        /// Get rid of any outdated cluster data we might have lying around.
        if ($CFG->dbfamily == 'postgres') {
            $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_assignments\n                    WHERE id IN (\n                        SELECT ca.clusterid\n                        FROM {$CFG->prefix}crlm_cluster_assignments ca\n                        LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ca.clusterid\n                        WHERE c.id IS NULL\n                    )";
            $result = $result && execute_sql($sql);
            $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_curriculum\n                    WHERE id IN (\n                        SELECT cc.clusterid\n                        FROM {$CFG->prefix}crlm_cluster_curriculum cc\n                        LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cc.clusterid\n                        WHERE c.id IS NULL\n                    )";
            $result = $result && execute_sql($sql);
            $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_profile\n                    WHERE id IN (\n                        SELECT cp.clusterid\n                        FROM {$CFG->prefix}crlm_cluster_profile cp\n                        LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cp.clusterid\n                        WHERE c.id IS NULL\n                    )";
            $result = $result && execute_sql($sql);
            $sql = "DELETE FROM {$CFG->prefix}crlm_cluster_track\n                    WHERE id IN (\n                        SELECT ct.clusterid\n                        FROM {$CFG->prefix}crlm_cluster_track ct\n                        LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ct.clusterid\n                        WHERE c.id IS NULL\n                    )";
            $result = $result && execute_sql($sql);
            $sql = "DELETE FROM {$CFG->prefix}crlm_usercluster\n                    WHERE id IN (\n                        SELECT uc.clusterid\n                        FROM {$CFG->prefix}crlm_usercluster uc\n                        LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = uc.clusterid\n                        WHERE c.id IS NULL\n                    )";
            $result = $result && execute_sql($sql);
        } else {
            $sql = "DELETE ca FROM {$CFG->prefix}crlm_cluster_assignments ca\n                    LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ca.clusterid\n                    WHERE c.id IS NULL";
            $result = $result && execute_sql($sql);
            $sql = "DELETE cc FROM {$CFG->prefix}crlm_cluster_curriculum cc\n                    LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cc.clusterid\n                    WHERE c.id IS NULL";
            $result = $result && execute_sql($sql);
            $sql = "DELETE cp FROM {$CFG->prefix}crlm_cluster_profile cp\n                    LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = cp.clusterid\n                    WHERE c.id IS NULL";
            $result = $result && execute_sql($sql);
            $sql = "DELETE ct FROM {$CFG->prefix}crlm_cluster_track ct\n                    LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = ct.clusterid\n                    WHERE c.id IS NULL";
            $result = $result && execute_sql($sql);
            $sql = "DELETE uc FROM {$CFG->prefix}crlm_usercluster uc\n                    LEFT JOIN {$CFG->prefix}crlm_cluster c ON c.id = uc.clusterid\n                    WHERE c.id IS NULL";
            $result = $result && execute_sql($sql);
        }
    }
    if ($result && $oldversion < 2009010133) {
        /// Define field leader to be added to crlm_cluster_assignments
        $table = new XMLDBTable('crlm_cluster_assignments');
        $field = new XMLDBField('leader');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol');
        /// Launch add field leader
        $result = $result && add_field($table, $field);
        /// Define field leader to be added to crlm_usercluster
        $table = new XMLDBTable('crlm_usercluster');
        $field = new XMLDBField('leader');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'autoenrol');
        /// Launch add field leader
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010134) {
        /// Define field inactive to be added to crlm_user
        $table = new XMLDBTable('crlm_user');
        $field = new XMLDBField('inactive');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0', 'timemodified');
        /// Launch add field inactive
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010137) {
        $roleid = get_field('role', 'id', 'shortname', 'curriculumadmin');
        if (!empty($roleid)) {
            $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
            require_once dirname(dirname(__FILE__)) . '/db/access.php';
            if (!empty($block_curr_admin_capabilities)) {
                foreach ($block_curr_admin_capabilities as $capname => $caprules) {
                    $result = $result && assign_capability($capname, CAP_ALLOW, $roleid, $context->id);
                }
            }
        }
    }
    if ($result && $oldversion < 2009010139) {
        global $CURMAN;
        require_once $CFG->dirroot . '/curriculum/lib/classmoodlecourse.class.php';
        $moodleclasses = moodle_get_classes();
        if (!empty($moodleclasses)) {
            foreach ($moodleclasses as $class) {
                $context = get_context_instance(CONTEXT_COURSE, $class->moodlecourseid);
                $sql = "DELETE cmce\n                    FROM {$CURMAN->db->prefix_table('user')} u\n                    JOIN {$CURMAN->db->prefix_table('role_assignments')} ra ON u.id = ra.userid\n                    JOIN {$CURMAN->db->prefix_table(STUTABLE)} cmce ON u.idnumber = cmce.user_idnumber\n                    WHERE ra.roleid NOT IN ({$CFG->gradebookroles})\n                    AND ra.contextid " . get_related_contexts_string($context) . "AND cmce.classid = {$class->classid}";
                $result = $result && execute_sql($sql);
            }
        }
    }
    if ($result && $oldversion < 2009010140) {
        delete_records('crlm_cluster_profile', 'fieldid', 0);
    }
    if ($result && $oldversion < 2009010141) {
        set_config('field_lock_idnumber', 'locked', 'auth/manual');
    }
    if ($result && $oldversion < 2009010143) {
        /// Define table crlm_wait_list to be created
        $table = new XMLDBTable('crlm_wait_list');
        /// Adding fields to table crlm_wait_list
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('classid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('position', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table crlm_wait_list
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_wait_list
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009010145) {
        $table = new XMLDBTable('crlm_wait_list');
        $field = new XMLDBField('enrolmenttime');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010146) {
        // make sure trackclass's courseids are set
        // Let's just assume that all non-Postgres DB's use the same syntax as MySQL and call it a day.
        if ($CFG->dbfamily == 'postgres') {
            $sql = "UPDATE {$CFG->prefix}crlm_track_class\n                       SET courseid = c.courseid\n                      FROM {$CFG->prefix}crlm_track_class tc, {$CFG->prefix}crlm_class c\n                     WHERE tc.classid = c.id AND tc.courseid = 0";
        } else {
            $sql = "UPDATE {$CFG->prefix}crlm_track_class tc, {$CFG->prefix}crlm_class c\n                       SET tc.courseid = c.courseid\n                     WHERE tc.classid = c.id AND tc.courseid = 0";
        }
        $result = $result && execute_sql($sql);
    }
    if ($result && $oldversion < 2009010147) {
        // make sure all users have an idnumber
        $users = get_records('crlm_user', 'idnumber', '');
        foreach ($users as $user) {
            $user = addslashes_recursive($user);
            $mu = addslashes_recursive(get_record('user', 'username', $user->username));
            if (empty($mu->idnumber)) {
                $user->idnumber = $mu->idnumber = $mu->username;
                update_record('user', $mu);
                update_record('crlm_user', $user);
            } else {
                if (!get_record('crlm_user', 'idnumber', $mu->idnumber)) {
                    $user->idnumber = $mu->idnumber;
                    update_record('crlm_user', $user);
                } else {
                    if (!get_record('crlm_user', 'idnumber', $user->username)) {
                        $user->idnumber = $mu->idnumber;
                        update_record('crlm_user', $user);
                    }
                }
            }
        }
    }
    if ($result && $oldversion < 2009010149) {
        /// Define index clusterid_idx (not unique) to be added to crlm_cluster_assignments
        $table = new XMLDBTable('crlm_cluster_assignments');
        $index = new XMLDBIndex('clusterid_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        /// Launch add index clusterid_idx
        $result = $result && add_index($table, $index);
        /// Define index userid_idx (not unique) to be added to crlm_cluster_assignments
        $table = new XMLDBTable('crlm_cluster_assignments');
        $index = new XMLDBIndex('userid_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid'));
        /// Launch add index userid_idx
        $result = $result && add_index($table, $index);
        /// Define index clusterid_idx (not unique) to be added to crlm_cluster_profile
        $table = new XMLDBTable('crlm_cluster_profile');
        $index = new XMLDBIndex('clusterid_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('clusterid'));
        /// Launch add index clusterid_idx
        $result = $result && add_index($table, $index);
    }
    if ($result && $oldversion < 2009010151) {
        $table = new XMLDBTable('crlm_curriculum');
        $field = new XMLDBField('priority');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009010150) {
        require_once CURMAN_DIRLOCATION . '/lib/curriculumcourse.class.php';
        $sql = "SELECT cp.id, cp.courseid, cc.curriculumid\n                FROM {$CFG->prefix}crlm_course_prerequisite cp\n                JOIN {$CFG->prefix}crlm_curriculum_course cc ON cc.id = cp.curriculumcourseid\n                WHERE cp.courseid NOT IN (\n                    SELECT _cc.courseid\n                    FROM {$CFG->prefix}crlm_curriculum_course _cc\n                    WHERE _cc.curriculumid = cc.curriculumid\n                )";
        $students = get_records_sql($sql);
        $retval = 0;
        foreach ($students as $student) {
            $data = new object();
            $data->curriculumid = $student->curriculumid;
            $data->courseid = $student->courseid;
            $data->timeperiod = 'year';
            $currprereq = new curriculumcourse($data);
            $retval = $result && $currprereq->add();
        }
        $results = $retval;
    }
    if ($result && $oldversion < 2009103001) {
        $table = new XMLDBTable('crlm_curriculum');
        $field = new XMLDBField('priority');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $result = $result && add_field($table, $field);
        /// Define table context_levels to be created
        $table = new XMLDBTable('context_levels');
        /// Adding fields to table context_levels
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table context_levels
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table context_levels
        $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name'));
        $table->addIndexInfo('component', XMLDB_INDEX_NOTUNIQUE, array('component'));
        /// Launch create table for context_levels
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2009103003) {
        /// Define table crlm_field to be created
        $table = new XMLDBTable('crlm_field');
        /// Adding fields to table crlm_field
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('datatype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('required', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('forceunique', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('defaultdata', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null);
        $table->addFieldInfo('params', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null);
        $table->addFieldInfo('syncwithmoodle', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field
        $table->addIndexInfo('shortname_idx', XMLDB_INDEX_NOTUNIQUE, array('shortname'));
        /// Launch create table for crlm_field
        $result = $result && create_table($table);
        /// Define table crlm_field_category to be created
        $table = new XMLDBTable('crlm_field_category');
        /// Adding fields to table crlm_field_category
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_category
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_field_category
        $result = $result && create_table($table);
        /// Define table crlm_field_contextlevel to be created
        $table = new XMLDBTable('crlm_field_contextlevel');
        /// Adding fields to table crlm_field_contextlevel
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('contextlevel', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_contextlevel
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_field_contextlevel
        $result = $result && create_table($table);
        /// Define table crlm_field_data to be created
        $table = new XMLDBTable('crlm_field_data');
        /// Adding fields to table crlm_field_data
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('data', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_data
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_data
        $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        /// Launch create table for crlm_field_data
        $result = $result && create_table($table);
    }
    //if ($result && $oldversion < 2010040501) {
    //    require_once($CFG->dirroot . '/blocks/curr_admin/lib.php');
    //    $result = $result && create_views(); // create with default prefix
    //    $result = $result && create_views(''); // create with no prefix
    //}
    if ($result && $oldversion < 2010040501) {
        $table = new XMLDBTable('crlm_field_map');
        /// Adding fields to table crlm_field_data
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('context', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('type', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('elis_field', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('data_field', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_data
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for crlm_field_data
        $result = $result && create_table($table);
    }
    if ($result && $oldversion < 2010040501) {
        require_once "{$CFG->dirroot}/curriculum/lib/customfield.class.php";
        // make sure all ELIS users have a context
        update_capabilities('block/curr_admin');
        $ctxlvl = context_level_base::get_custom_context_level('user', 'block_curr_admin');
        $rs = get_recordset('crlm_user');
        while ($rec = rs_fetch_next_record($rs)) {
            get_context_instance($ctxlvl, $rec->id);
        }
        // sync profile fields
        $fields = field::get_for_context_level($ctxlvl);
        $fields = $fields ? $fields : array();
        require_once $CFG->dirroot . '/curriculum/plugins/moodle_profile/custom_fields.php';
        foreach ($fields as $field) {
            $fieldobj = new field($field);
            $sync_profile_field_with_moodle();
        }
    }
    if ($result && $oldversion < 2010040501) {
        require_once $CFG->dirroot . '/curriculum/lib/notifications.php';
        if (!empty($CFG->coursemanager)) {
            $context_course = CONTEXT_COURSE;
            $sql = "SELECT role_assignments.* FROM {$CFG->prefix}role_assignments role_assignments\n                    JOIN {$CFG->prefix}context context\n                    ON role_assignments.contextid = context.id\n                    WHERE role_assignments.roleid IN ({$CFG->coursemanager})\n                    AND context.contextlevel = {$context_course}";
            if ($records = get_records_sql($sql)) {
                foreach ($records as $record) {
                    cm_assign_instructor_from_mdl($record);
                }
            }
        }
    }
    if ($result && $oldversion < 2010063001) {
        $table = new XMLDBTable('crlm_curriculum_assignment');
        $field = new XMLDBField('user_idnumber');
        $result = $result && drop_field($table, $field);
        $table = new XMLDBTable('crlm_class_enrolment');
        $field = new XMLDBField('user_idnumber');
        $result = $result && drop_field($table, $field);
        $table = new XMLDBTable('crlm_class_instructor');
        $field = new XMLDBField('user_idnumber');
        $result = $result && drop_field($table, $field);
        $table = new XMLDBTable('crlm_class_attendance');
        $field = new XMLDBField('user_idnumber');
        $result = $result && drop_field($table, $field);
    }
    //if ($result && $oldversion < 2010063002) {
    //    require_once($CFG->dirroot . '/blocks/curr_admin/lib.php');
    //    $result = $result && create_views(); // create with default prefix
    //    $result = $result && create_views(''); // create with no prefix
    //}
    if ($result && $oldversion < 2010040505) {
        require_once $CFG->dirroot . '/curriculum/lib/lib.php';
        $result = $result && cm_notify_duplicate_user_info(true);
    }
    if ($result && $oldversion < 2010040506 && $oldversion >= 2010040501) {
        global $CFG, $CURMAN;
        // fix instructor assignments that were migrated incorrectly in the
        // 2010040501 upgrade code (ELIS-1171)
        // remove the obvious errors (instructors assigned to a non-existent class)
        $context_course = CONTEXT_COURSE;
        $sql = "DELETE\n                  FROM {$CFG->prefix}crlm_class_instructor\n                 WHERE NOT EXISTS (SELECT 'x' FROM {$CFG->prefix}crlm_class cmclass\n                                    WHERE cmclass.id = {$CFG->prefix}crlm_class_instructor.classid)";
        $result = $result && execute_sql($sql);
        // warn about other potentially incorrect instructor assignments
        require_once $CFG->dirroot . '/curriculum/lib/lib.php';
        cm_notify_incorrect_instructor_assignment(true);
        // make sure the correct assignments are added
        if (!empty($CFG->coursemanager)) {
            require_once $CFG->dirroot . '/curriculum/lib/notifications.php';
            $context_course = CONTEXT_COURSE;
            $sql = "SELECT role_assignments.* FROM {$CFG->prefix}role_assignments role_assignments\n                    JOIN {$CFG->prefix}context context\n                    ON role_assignments.contextid = context.id\n                    WHERE role_assignments.roleid IN ({$CFG->coursemanager})\n                    AND context.contextlevel = {$context_course}";
            if ($records = get_records_sql($sql)) {
                foreach ($records as $record) {
                    cm_assign_instructor_from_mdl($record);
                }
            }
        }
    }
    if ($result && $oldversion < 2010063002) {
        //get the class table
        $table = new XMLDBTable('crlm_class');
        //add the auto enrol enabled flag
        $field = new XMLDBField('enrol_from_waitlist');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, '0');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010063005) {
        /// Define table crlm_field_data to be dropped
        $table = new XMLDBTable('crlm_field_map');
        /// Launch drop table for crlm_field_data
        $result = $result && drop_table($table);
    }
    if ($result && $oldversion < 2010063006) {
        /// Define table crlm_field_data to be renamed to crlm_field_data_text
        $table = new XMLDBTable('crlm_field_data');
        /// Define index context_idx (not unique) to be dropped form crlm_field_data_text
        $index = new XMLDBIndex('context_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        /// Launch drop index context_idx
        $result = $result && drop_index($table, $index);
        /// Changing nullability of field contextid on table crlm_field_data_text to null
        $field = new XMLDBField('contextid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'id');
        /// Define index context_idx (not unique) to be added to crlm_field_data_text
        $index = new XMLDBIndex('context_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        /// Launch add index context_idx
        $result = $result && add_index($table, $index);
        /// Define index field_idx (not unique) to be added to crlm_field_data_text
        $index = new XMLDBIndex('field_idx');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        /// Launch add index field_idx
        $result = $result && add_index($table, $index);
        /// Launch change of nullability for field contextid
        $result = $result && change_field_notnull($table, $field);
        /// Launch rename table for crlm_field_data
        $result = $result && rename_table($table, 'crlm_field_data_text');
        /// Define table crlm_field_owner to be created
        $table = new XMLDBTable('crlm_field_owner');
        /// Adding fields to table crlm_field_owner
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('plugin', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('exclude', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0');
        $table->addFieldInfo('params', XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null);
        /// Adding keys to table crlm_field_owner
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_owner
        $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        /// Launch create table for crlm_field_owner
        $result = $result && create_table($table);
        /// Define table crlm_field_category_context to be created
        $table = new XMLDBTable('crlm_field_category_context');
        /// Adding fields to table crlm_field_category_context
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('contextlevel', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table crlm_field_category_context
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_category_context
        $table->addIndexInfo('contextlevel_idx', XMLDB_INDEX_NOTUNIQUE, array('contextlevel'));
        $table->addIndexInfo('category_idx', XMLDB_INDEX_NOTUNIQUE, array('categoryid'));
        /// Launch create table for crlm_field_category_context
        $result = $result && create_table($table);
        $usercontextid = context_level_base::get_custom_context_level('user', 'block_curr_admin');
        if ($usercontextid) {
            $sql = "INSERT INTO {$CFG->prefix}crlm_field_category_context\n                           (categoryid, contextlevel)\n                    SELECT id, {$usercontextid}\n                      FROM {$CFG->prefix}crlm_field_category";
            $result = $result && execute_sql($sql);
        }
        /// Define table crlm_field_data_int to be created
        $table = new XMLDBTable('crlm_field_data_int');
        /// Adding fields to table crlm_field_data_int
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('data', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_data_int
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_data_int
        $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        /// Launch create table for crlm_field_data_int
        $result = $result && create_table($table);
        /// Define table crlm_field_data_num to be created
        $table = new XMLDBTable('crlm_field_data_num');
        /// Adding fields to table crlm_field_data_num
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('data', XMLDB_TYPE_NUMBER, '15, 5', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_data_num
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_data_num
        $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        /// Launch create table for crlm_field_data_num
        $result = $result && create_table($table);
        /// Define table crlm_field_data_char to be created
        $table = new XMLDBTable('crlm_field_data_char');
        /// Adding fields to table crlm_field_data_char
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('fieldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('data', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table crlm_field_data_char
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table crlm_field_data_char
        $table->addIndexInfo('context_idx', XMLDB_INDEX_NOTUNIQUE, array('contextid'));
        $table->addIndexInfo('field_idx', XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        /// Launch create table for crlm_field_data_char
        $result = $result && create_table($table);
        $records = get_records('crlm_field');
        if ($records) {
            // FIXME: set data type based on old data type
            foreach ($records as $record) {
                unset($record->name);
                unset($record->shortname);
                unset($record->description);
                $record->defaultdata = addslashes($record->defaultdata);
                if (isset($record->syncwithmoodle)) {
                    // make sure the crlm_field table hasn't been upgraded yet
                    switch ($record->syncwithmoodle) {
                        case 2:
                            // sync from Moodle
                            // create "moodle_profile" owner
                            if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'moodle_profile')) {
                                $owner = new stdClass();
                                $owner->fieldid = $record->id;
                                $owner->plugin = 'moodle_profile';
                                $owner->exclude = true;
                                $result = $result && insert_record('crlm_field_owner', $owner);
                            }
                            // create "manual" owner
                            if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'manual')) {
                                $owner = new stdClass();
                                $owner->fieldid = $record->id;
                                $owner->plugin = 'manual';
                                $owner->exclude = false;
                                $owner->params = array('edit_capability' => 'disabled');
                                if (!$record->visible) {
                                    $owner->params['view_capability'] = 'moodle/user:viewhiddendetails';
                                }
                                $owner->params = serialize($owner->params);
                                $result = $result && insert_record('crlm_field_owner', $owner);
                            }
                            $record->datatype = 'text';
                            break;
                        case 1:
                            // sync to Moodle
                            // create "moodle_profile" owner
                            if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'moodle_profile')) {
                                $owner = new stdClass();
                                $owner->fieldid = $record->id;
                                $owner->plugin = 'moodle_profile';
                                $owner->exclude = false;
                                $result = $result && insert_record('crlm_field_owner', $owner);
                            }
                            // NOTE: fall through
                        // NOTE: fall through
                        default:
                            // no sync or invalid user
                            // create "manual" owner
                            $controltype = $record->datatype;
                            $record->datatype = 'text';
                            if (!record_exists('crlm_field_owner', 'fieldid', $record->id, 'plugin', 'manual')) {
                                $owner = new stdClass();
                                $owner->fieldid = $record->id;
                                $owner->plugin = 'manual';
                                $owner->exclude = false;
                                $owner->params = array('control' => $controltype, 'required' => $record->required);
                                if ($record->locked) {
                                    $owner->params['edit_capability'] = 'moodle/user:update';
                                }
                                if (!$record->visible) {
                                    $owner->params['view_capability'] = 'moodle/user:viewhiddendetails';
                                }
                                if (!empty($record->params)) {
                                    $owner->params += unserialize($record->params);
                                }
                                switch ($controltype) {
                                    case 'checkbox':
                                        // legacy checkboxes are all boolean
                                        $record->datatype = 'bool';
                                        $data_recs = get_records('crlm_field_data_text', 'fieldid', $record->id);
                                        foreach ($data_recs as $data_rec) {
                                            delete_records('crlm_field_data_text', 'id', $data_rec->id);
                                            unset($data_rec->id);
                                            insert_record('crlm_field_data_int', $data_rec);
                                        }
                                        break;
                                    case 'menu':
                                        // menu items should be short text
                                        $record->datatype = 'char';
                                        $data_recs = get_records('crlm_field_data_text', 'fieldid', $record->id);
                                        foreach ($data_recs as $data_rec) {
                                            delete_records('crlm_field_data_text', 'id', $data_rec->id);
                                            unset($data_rec->id);
                                            insert_record('crlm_field_data_char', $data_rec);
                                        }
                                    case 'text':
                                        $owner->params['columns'] = $owner->params['size'];
                                        unset($owner->params['size']);
                                        break;
                                }
                                $owner->params = addslashes(serialize($owner->params));
                                $result = $result && insert_record('crlm_field_owner', $owner);
                            }
                            break;
                    }
                    $record->params = '';
                    $result = $result && update_record('crlm_field', $record);
                    if (!empty($record->defaultdata)) {
                        if (!record_exists_select('crlm_field_data_text', "fieldid = {$record->id} AND contextid IS NULL")) {
                            $defaultdata = new stdClass();
                            $defaultdata->fieldid = $record->id;
                            $defaultdata->data = $record->defaultdata;
                            $result = $result && insert_record('crlm_field_data_text', $defaultdata);
                        }
                    }
                }
            }
        }
        $table = new XMLDBTable('crlm_field');
        /// Define field required to be dropped from crlm_field
        $field = new XMLDBField('required');
        /// Launch drop field required
        $result = $result && drop_field($table, $field);
        /// Define field locked to be dropped from crlm_field
        $field = new XMLDBField('locked');
        /// Launch drop field locked
        $result = $result && drop_field($table, $field);
        /// Define field visible to be dropped from crlm_field
        $field = new XMLDBField('visible');
        /// Launch drop field visible
        $result = $result && drop_field($table, $field);
        /// Define field defaultdata to be dropped from crlm_field
        $field = new XMLDBField('defaultdata');
        /// Launch drop field defaultdata
        $result = $result && drop_field($table, $field);
        /// Define field syncwithmoodle to be dropped from crlm_field
        $field = new XMLDBField('syncwithmoodle');
        /// Launch drop field syncwithmoodle
        $result = $result && drop_field($table, $field);
        /// Define field multivalued to be added to crlm_field
        $field = new XMLDBField('multivalued');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, '0', 'sortorder');
        /// Launch add field multivalued
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010063007) {
        // install.xml accidentally had the char table use an integer data field
        /// Changing type of field data on table crlm_field_data_char to char
        $table = new XMLDBTable('crlm_field_data_char');
        $field = new XMLDBField('data');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'fieldid');
        /// Launch change of type for field data
        $result = $result && change_field_type($table, $field);
    }
    if ($result && $oldversion < 2010063008) {
        $table = new XMLDBTable('crlm_cluster_curriculum');
        $field = new XMLDBField('autoenrol');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'curriculumid');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('crlm_cluster_track');
        $field = new XMLDBField('autoenrol');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'trackid');
        $result = $result && add_field($table, $field);
        /// Define field parent to be added to crlm_cluster
        $table = new XMLDBTable('crlm_cluster');
        $field = new XMLDBField('parent');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'display');
        /// Launch add field parent
        $result = $result && add_field($table, $field);
        /// Define field depth to be added to crlm_cluster
        $field = new XMLDBField('depth');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'parent');
        /// Launch add field depth
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010063013) {
        /*
         * Curriculum
         */
        $table = new XMLDBTable('crlm_curriculum');
        //name field
        $index = new XMLDBIndex('name_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /*
         * Course
         */
        $table = new XMLDBTable('crlm_course');
        //name field
        $index = new XMLDBIndex('name_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        //credits field
        $index = new XMLDBIndex('credits_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('credits'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /*
         * Class
         */
        $table = new XMLDBTable('crlm_class');
        //idnumber field
        $index = new XMLDBIndex('idnumber_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        //enddate field
        $index = new XMLDBIndex('enddate_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('enddate'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /*
         * Class enrolment
         */
        $table = new XMLDBTable('crlm_class_enrolment');
        //completetime field
        $index = new XMLDBIndex('completetime_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completetime'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        //completestatusid field
        $index = new XMLDBIndex('completestatusid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('completestatusid'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        /*
         * CM user
         */
        $table = new XMLDBTable('crlm_user');
        //lastname field
        $index = new XMLDBIndex('lastname_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('lastname'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        //firstname field
        $index = new XMLDBIndex('firstname_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('firstname'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
    }
    if ($result && $oldversion < 2010063015) {
        /// Define field autocreated to be added to crlm_class_moodle
        $table = new XMLDBTable('crlm_class_moodle');
        $field = new XMLDBField('autocreated');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null, null, '-1', 'timemodified');
        /// Launch add field autocreated
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2010111300) {
        $table = new XMLDBTable('crlm_curriculum_assignment');
        $field = new XMLDBField('timeexpired');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timecompleted');
        // Launch add field multivalued
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2011050200) {
        /// Define index startdate_ix (not unique) to be added to crlm_class
        $table = new XMLDBTable('crlm_class');
        $index = new XMLDBIndex('startdate_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('startdate'));
        $result = $result && add_index($table, $index);
        /// Define index enrolmenttime_ix (not unique) to be added to crlm_class_enrolment
        $table = new XMLDBTable('crlm_class_enrolment');
        $index = new XMLDBIndex('enrolmenttime_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('enrolmenttime'));
        $result = $result && add_index($table, $index);
        /// Define index locked_ix (not unique) to be added to crlm_class_graded
        $table = new XMLDBTable('crlm_class_graded');
        $index = new XMLDBIndex('locked_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked'));
        $result = $result && add_index($table, $index);
        /// Define index timegraded_ix (not unique) to be added to crlm_class_graded
        $table = new XMLDBTable('crlm_class_graded');
        $index = new XMLDBIndex('timegraded_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('timegraded'));
        $result = $result && add_index($table, $index);
        /// Define index classid_ix (not unique) to be added to crlm_class_moodle
        $table = new XMLDBTable('crlm_class_moodle');
        $index = new XMLDBIndex('classid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('classid'));
        $result = $result && add_index($table, $index);
        /// Define index curriculumid_ix (not unique) to be added to crlm_cluster_curriculum
        $table = new XMLDBTable('crlm_cluster_curriculum');
        $index = new XMLDBIndex('curriculumid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('curriculumid'));
        $result = $result && add_index($table, $index);
        /// Define index fieldid_ix (not unique) to be added to crlm_cluster_profile
        $table = new XMLDBTable('crlm_cluster_profile');
        $index = new XMLDBIndex('fieldid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        $result = $result && add_index($table, $index);
        /// Define index trackid_ix (not unique) to be added to crlm_cluster_track
        $table = new XMLDBTable('crlm_cluster_track');
        $index = new XMLDBIndex('trackid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('trackid'));
        $result = $result && add_index($table, $index);
        /// Define index idnumber_ix (not unique) to be added to crlm_course_completion
        $table = new XMLDBTable('crlm_course_completion');
        $index = new XMLDBIndex('idnumber_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
        $result = $result && add_index($table, $index);
        /// Define index sortorder_ix (not unique) to be added to crlm_field
        $table = new XMLDBTable('crlm_field');
        $index = new XMLDBIndex('sortorder_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('sortorder'));
        $result = $result && add_index($table, $index);
        /// Define index username_ix (not unique) to be added to crlm_user
        $table = new XMLDBTable('crlm_user');
        $index = new XMLDBIndex('username_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('username'));
        $result = $result && add_index($table, $index);
        /// Define index inactive_ix (not unique) to be added to crlm_user
        $table = new XMLDBTable('crlm_user');
        $index = new XMLDBIndex('inactive_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('inactive'));
        $result = $result && add_index($table, $index);
        /// Define index userid_ix (not unique) to be added to crlm_user_track
        $table = new XMLDBTable('crlm_user_track');
        $index = new XMLDBIndex('userid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid'));
        $result = $result && add_index($table, $index);
        /// Define index trackid_ix (not unique) to be added to crlm_user_track
        $table = new XMLDBTable('crlm_user_track');
        $index = new XMLDBIndex('trackid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('trackid'));
        $result = $result && add_index($table, $index);
        /// Define index classid_ix (not unique) to be added to crlm_wait_list
        $table = new XMLDBTable('crlm_wait_list');
        $index = new XMLDBIndex('classid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('classid'));
        $result = $result && add_index($table, $index);
        /// Define index userid_ix (not unique) to be added to crlm_wait_list
        $table = new XMLDBTable('crlm_wait_list');
        $index = new XMLDBIndex('userid_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('userid'));
        $result = $result && add_index($table, $index);
    }
    if ($result && $oldversion < 2011050201) {
        // make sure that hours are within 24 hours
        $sql = "UPDATE {$CFG->prefix}crlm_class\n                   SET starttimehour = MOD(starttimehour, 24),\n                       endtimehour = MOD(endtimehour, 24)";
        $result = $result && execute_sql($sql);
    }
    if ($result && $oldversion < 2011050202) {
        /// Changing type of field credits on table crlm_class_enrolment to number
        $table = new XMLDBTable('crlm_class_enrolment');
        $field = new XMLDBField('credits');
        $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, null, null, null, null, '0', 'grade');
        /// Launch change of type for field credits
        $result = $result && change_field_type($table, $field);
        /// Changing type of field credits on table crlm_curriculum_assignment to number
        $table = new XMLDBTable('crlm_curriculum_assignment');
        $field = new XMLDBField('credits');
        $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timeexpired');
        /// Launch change of type for field credits
        $result = $result && change_field_type($table, $field);
        /// Changing type of field reqcredits on table crlm_curriculum to number
        $table = new XMLDBTable('crlm_curriculum');
        $field = new XMLDBField('reqcredits');
        $field->setAttributes(XMLDB_TYPE_NUMBER, '10, 2', XMLDB_UNSIGNED, null, null, null, null, null, 'description');
        /// Launch change of type for field reqcredits
        $result = $result && change_field_type($table, $field);
        // update student class credits with decimal credits
        if ($CFG->dbfamily == 'postgres') {
            $sql = "UPDATE {$CFG->prefix}crlm_class_enrolment\n                       SET credits = CAST(c.credits AS numeric)\n                      FROM {$CFG->prefix}crlm_class_enrolment e, {$CFG->prefix}crlm_class cls, {$CFG->prefix}crlm_course c\n                     WHERE e.classid = cls.id\n                       AND cls.courseid = c.id\n                       AND e.credits = CAST(c.credits AS integer)";
        } else {
            $sql = "UPDATE {$CFG->prefix}crlm_class_enrolment e, {$CFG->prefix}crlm_class cls, {$CFG->prefix}crlm_course c\n                       SET e.credits = c.credits\n                     WHERE e.classid = cls.id\n                       AND cls.courseid = c.id\n                       AND e.credits = CAST(c.credits AS unsigned)";
        }
        $result = $result && execute_sql($sql);
    }
    if ($result && $oldversion < 2011050203) {
        //create a new column in the notification log table
        //to store the user who triggered the notification
        $table = new XMLDBTable('crlm_notification_log');
        $field = new XMLDBField('fromuserid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'userid');
        $field->comment = 'CM user id that triggered the notification.';
        $result = $result && add_field($table, $field);
        //populate data, assuming that the user who received the notification is the one whose
        //criteria spawned it
        //NOTE: this fudges data and the side-effect implies that if someone had received a notification
        //for another user and satisfy the same criteria for the same instance for themself, they will not
        //receive a similar notification
        $sql = "UPDATE {$CFG->prefix}crlm_notification_log\n                SET fromuserid = userid";
        $result = $result && execute_sql($sql);
        if ($result) {
            /// Define field certificatecode to be added to crlm_curriculum_assignment
            $table = new XMLDBTable('crlm_curriculum_assignment');
            $field = new XMLDBField('certificatecode');
            $field->setAttributes(XMLDB_TYPE_CHAR, '40', null, null, null, null, null, null, 'locked');
            /// Launch add field autocreated
            $result = $result && add_field($table, $field);
            /// Define index userid_ix (not unique) to be added to crlm_wait_list
            $index = new XMLDBIndex('certificatecode_ix');
            $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('certificatecode'));
            $result = $result && add_index($table, $index);
        }
    }
    if ($result && $oldversion < 2011050204) {
        $table = new XMLDBTable('crlm_notification_log');
        $index = new XMLDBIndex('event_inst_fuser_ix');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('fromuserid', 'instance', 'event'));
        $result = add_index($table, $index);
    }
    if ($result && $oldversion < 2011050205) {
        // Update the ELIS class enrolment grade value and completion score grade values so they store float
        // (decimal) values
        $table = new XMLDBTable('crlm_class_enrolment');
        $field = new XMLDBField('grade');
        $field->setAttributes(XMLDB_TYPE_NUMBER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $field->setDecimals(5);
        $result = change_field_type($table, $field);
        $table = new XMLDBTable('crlm_class_graded');
        $result = $result && change_field_type($table, $field);
        /*
         * Find all of the completion grades that are synchronised from Moodle grade items that are not locked and
         * where the ELIS completion score does not match the value in the Moodle gradebook and delete those
         * completion scores so they can be re-synchronised from Moodle with the correct float values stored.
         */
        // Attempt to handle different DBs in the most efficient way possible
        if ($CFG->dbfamily == 'postgres') {
            $sql = "DELETE FROM {$CFG->prefix}crlm_class_graded\n                    WHERE id IN (\n                        SELECT ccg.id\n                        FROM mdl_crlm_user cu\n                        INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n                        INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n                        INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n                        INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n                        INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n                        INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n                        INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n                        INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n                        WHERE ccg.locked = 0\n                        AND ccc.idnumber != ''\n                        AND gi.itemtype != 'course'\n                        AND ccg.grade != gg.finalgrade\n                        AND gg.finalgrade IS NOT NULL\n                    )";
            $result = $result && execute_sql($sql);
        } else {
            if ($CFG->dbfamily == 'mysql') {
                $sql = "DELETE ccg\n                    FROM mdl_crlm_user cu\n                    INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n                    INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n                    INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n                    INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n                    INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n                    INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n                    INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n                    INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n                    WHERE ccg.locked = 0\n                    AND ccc.idnumber != ''\n                    AND gi.itemtype != 'course'\n                    AND ccg.grade != gg.finalgrade\n                    AND gg.finalgrade IS NOT NULL";
                $result = $result && execute_sql($sql);
            } else {
                $sql = "SELECT ccg.id, ccg.grade\n                    FROM mdl_crlm_user cu\n                    INNER JOIN {$CFG->prefix}crlm_class_enrolment cce ON cce.userid = cu.id\n                    INNER JOIN {$CFG->prefix}crlm_class_graded ccg ON (ccg.userid = cce.userid AND ccg.classid = cce.classid)\n                    INNER JOIN {$CFG->prefix}crlm_course_completion ccc ON ccc.id = ccg.completionid\n                    INNER JOIN {$CFG->prefix}crlm_class_moodle ccm ON ccm.classid = ccg.classid\n                    INNER JOIN {$CFG->prefix}user u ON u.idnumber = cu.idnumber\n                    INNER JOIN {$CFG->prefix}course c ON c.id = ccm.moodlecourseid\n                    INNER JOIN {$CFG->prefix}grade_items gi ON (gi.courseid = c.id AND gi.idnumber = ccc.idnumber)\n                    INNER JOIN {$CFG->prefix}grade_grades gg ON (gg.itemid = gi.id AND gg.userid = u.id)\n                    WHERE ccg.locked = 0\n                    AND ccc.idnumber != ''\n                    AND gi.itemtype != 'course'\n                    AND ccg.grade != gg.finalgrade\n                    AND gg.finalgrade IS NOT NULL";
                if ($rs = get_recordset_sql($sql)) {
                    while ($cg = rs_fetch_next_record($rs)) {
                        $result = $result && delete_records('crlm_class_graded', 'id', $cg->id);
                    }
                    rs_close($rs);
                }
            }
        }
        // Force a re-synchronization of ELIS class grade data
        require_once $CFG->dirroot . '/curriculum/lib/lib.php';
        cm_synchronize_moodle_class_grades();
    }
    if ($result && $oldversion < 2011050206) {
        /// Define table crlm_field_data to be dropped
        $table = new XMLDBTable('crlm_field_map');
        if (table_exists($table)) {
            /// Launch drop table for crlm_field_data
            $result = drop_table($table);
        }
    }
    if ($result && $oldversion < 2011050207) {
        // Delete duplicate class completion element grades
        $xmldbtable = new XMLDBTable('crlm_class_graded_temp');
        if (table_exists($xmldbtable)) {
            drop_table($xmldbtable);
        }
        // Create a temporary table
        $result = $result && execute_sql("CREATE TABLE {$CFG->prefix}crlm_class_graded_temp LIKE {$CFG->prefix}crlm_class_graded");
        // Store the unique values in the temporary table
        $sql = "INSERT INTO {$CFG->prefix}crlm_class_graded_temp\n                SELECT MAX(id) AS id, classid, userid, completionid, grade, locked, timegraded, timemodified\n                FROM {$CFG->prefix}crlm_class_graded\n                GROUP BY classid, userid, completionid, locked";
        $result = $result && execute_sql($sql);
        // Detect if there are still duplicates in the temporary table
        $sql = "SELECT COUNT(*) AS count, classid, userid, completionid, grade, locked, timegraded, timemodified\n                FROM {$CFG->prefix}crlm_class_graded_temp\n                GROUP BY classid, userid, completionid\n                ORDER BY count DESC, classid ASC, userid ASC, completionid ASC";
        if ($result && ($dupcount = get_record_sql($sql, true))) {
            if ($dupcount->count > 1) {
                if ($rs = get_recordset_sql($sql)) {
                    while ($result && ($dupe = rs_fetch_next_record($rs))) {
                        if ($dupe->count <= 1) {
                            continue;
                        }
                        $classid = $dupe->classid;
                        $userid = $dupe->userid;
                        $goodid = 0;
                        // The ID of the record we will keep
                        // Look for the earliest locked grade record for this user and keep that (if any are locked)
                        $sql2 = "SELECT id, grade, locked, timegraded\n                                 FROM mdl_crlm_class_graded\n                                 WHERE classid = {$classid}\n                                 AND userid = {$userid}\n                                 ORDER BY timegraded ASC";
                        if ($rs2 = get_recordset_sql($sql2)) {
                            while ($rec = rs_fetch_next_record($rs2)) {
                                // Store the last record ID just in case we need it for cleanup
                                $lastid = $rec->id;
                                // Don't bother looking at remaining records if we have found a record to keep
                                if (!empty($goodid)) {
                                    continue;
                                }
                                if ($rec->locked = 1) {
                                    $goodid = $rec->id;
                                }
                            }
                            rs_close($rs2);
                            // We need to make sure we have a record ID to keep, if we found no "complete" and locked
                            // records, let's just keep the last record we saw
                            if (empty($goodid)) {
                                $goodid = $lastid;
                            }
                            $select = 'classid = ' . $classid . ' AND userid = ' . $userid . ' AND id != ' . $goodid;
                        }
                        if (!empty($select)) {
                            $result = $result && delete_records_select('crlm_class_graded_temp', $select);
                        }
                    }
                }
            }
        }
        // Drop the real table
        $result = $result && execute_sql("DROP TABLE {$CFG->prefix}crlm_class_graded");
        // Replace the real table with the temporary table that now only contains unique values.
        $result = $result && execute_sql("ALTER TABLE {$CFG->prefix}crlm_class_graded_temp RENAME TO {$CFG->prefix}crlm_class_graded");
    }
    return $result;
}
Example #15
0
 public static function rebuild_users()
 {
     log_debug('Starting rebuild_users()');
     self::delete_bytype('user');
     $users = get_recordset('usr', 'deleted', '0');
     safe_require('artefact', 'internal');
     $publicfields = array_keys(ArtefactTypeProfile::get_public_fields());
     while ($user = $users->FetchRow()) {
         if ($user['id'] == 0) {
             continue;
         }
         self::index_user($user);
     }
     $users->close();
     log_debug('Completed rebuild_users()');
 }
Example #16
0
                allow_assign($fromroleid, $targetroleid);
            }
        }
    }
    /// Updated allowassigns sitewide, so force a premissions refresh, and redirect.
    mark_context_dirty($systemcontext->path);
    add_to_log(SITEID, 'role', 'edit allow assign', 'admin/roles/allowassign.php', '', '', $USER->id);
    redirect($CFG->wwwroot . '/' . $CFG->admin . '/roles/allowassign.php');
}
/// Load the current settings
$allowed = array();
foreach ($roles as $role) {
    // Make an array $role->id => false. This is probalby too clever for its own good.1
    $allowed[$role->id] = array_combine(array_keys($roles), array_fill(0, count($roles), false));
}
$raas = get_recordset('role_allow_assign');
foreach ($raas as $raa) {
    $raa = (object) $raa;
    $allowed[$raa->roleid][$raa->allowassign] = true;
}
/// Display the editing form.
admin_externalpage_setup('defineroles', '', array(), $CFG->wwwroot . '/' . $CFG->admin . '/roles/allowassign.php');
admin_externalpage_print_header();
$currenttab = 'allowassign';
require_once 'managetabs.php';
$table->tablealign = 'center';
$table->cellpadding = 5;
$table->cellspacing = 0;
$table->width = '90%';
$table->align[] = 'left';
$table->rotateheaders = true;
 function action_default()
 {
     global $CFG, $CURMAN;
     require_once $CFG->dirroot . '/curriculum/form/configform.class.php';
     $configform = new cmconfigform('index.php', $this);
     $configform->set_data($CURMAN->config);
     if ($configdata = $configform->get_data()) {
         $old_cluster_groups = $CURMAN->config->cluster_groups;
         $old_site_course_cluster_groups = $CURMAN->config->site_course_cluster_groups;
         $old_cluster_groupings = $CURMAN->config->cluster_groupings;
         // Track settings
         self::config_set_value($configdata, 'userdefinedtrack', 0);
         // Course catalog / Learning plan settings
         self::config_set_value($configdata, 'disablecoursecatalog', 0);
         self::config_set_value($configdata, 'catalog_collapse_count');
         // Curriculum expiration settings (ELIS-1172)
         $curassupdate = false;
         // We need to check for an required update before setting the variable as the API call requires the
         // variable to be set before the changes can take place.
         if (isset($configdata->curriculum_expiration_start) && $configdata->curriculum_expiration_start != $CURMAN->config->curriculum_expiration_start) {
             $curassupdate = true;
         }
         self::config_set_value($configdata, 'enable_curriculum_expiration', 0);
         self::config_set_value($configdata, 'curriculum_expiration_start', '');
         // If this setting is changed, we need to update the existing curriclum expiration values
         if ($curassupdate) {
             if ($rs = get_recordset(CURASSTABLE, '', '', '', 'id, userid, curriculumid')) {
                 $timenow = time();
                 while ($curass = rs_fetch_next_record($rs)) {
                     $update = new stdClass();
                     $update->id = $curass->id;
                     $update->timeexpired = calculate_curriculum_expiry(false, $curass->curriculumid, $curass->userid);
                     $update->timemodified = $timenow;
                     update_record(CURASSTABLE, $update);
                 }
                 rs_close($rs);
             }
         }
         // Certificate settings
         self::config_set_value($configdata, 'disablecertificates', 0);
         self::config_set_value($configdata, 'certificate_border_image', 'Fancy1-blue.jpg');
         self::config_set_value($configdata, 'certificate_seal_image', 'none');
         self::config_set_value($configdata, 'certificate_template_file', 'default.php');
         // Interface settings
         self::config_set_value($configdata, 'time_format_12h', 0);
         self::config_set_value($configdata, 'mymoodle_redirect', 0);
         // User settings
         self::config_set_value($configdata, 'auto_assign_user_idnumber', 0);
         $old_cfg = $CURMAN->config->auto_assign_user_idnumber;
         // if this setting is changed to true, synchronize the users
         if (isset($configdata->auto_assign_user_idnumber) && $configdata->auto_assign_user_idnumber != 0 && $old_cfg == 0) {
             cm_migrate_moodle_users(true, 0);
         }
         self::config_set_value($configdata, 'default_instructor_role', 0);
         self::config_set_value($configdata, 'restrict_to_elis_enrolment_plugin', 0);
         // Cluster settings
         self::config_set_value($configdata, 'cluster_groups', 0);
         self::config_set_value($configdata, 'site_course_cluster_groups', 0);
         self::config_set_value($configdata, 'cluster_groupings', 0);
         //settings specifically for the curriculum administration block
         self::config_set_value($configdata, 'num_block_icons', 5);
         self::config_set_value($configdata, 'display_clusters_at_top_level', 1);
         self::config_set_value($configdata, 'display_curricula_at_top_level', 0);
         //default role assignments on cm entities
         self::config_set_value($configdata, 'default_cluster_role_id', 0);
         self::config_set_value($configdata, 'default_curriculum_role_id', 0);
         self::config_set_value($configdata, 'default_course_role_id', 0);
         self::config_set_value($configdata, 'default_class_role_id', 0);
         self::config_set_value($configdata, 'default_track_role_id', 0);
         //enrolment synchronization roles
         $old_role_sync = $CURMAN->config->enrolment_role_sync_student_role;
         self::config_set_value($configdata, 'enrolment_role_sync_student_role', 0);
         if (isset($configdata->enrolment_role_sync_student_role) && $configdata->enrolment_role_sync_student_role != 0 && $configdata->enrolment_role_sync_student_role != $old_role_sync) {
             require_once CURMAN_DIRLOCATION . '/plugins/enrolment_role_sync/lib.php';
             enrolment_role_sync::student_sync_role_set();
         }
         $old_role_sync = $CURMAN->config->enrolment_role_sync_instructor_role;
         self::config_set_value($configdata, 'enrolment_role_sync_instructor_role', 0);
         if (isset($configdata->enrolment_role_sync_instructor_role) && $configdata->enrolment_role_sync_instructor_role != 0 && $configdata->enrolment_role_sync_instructor_role != $old_role_sync) {
             require_once CURMAN_DIRLOCATION . '/plugins/enrolment_role_sync/lib.php';
             enrolment_role_sync::instructor_sync_role_set();
         }
         // autocreate settings
         self::config_set_value($configdata, 'autocreated_unknown_is_yes', 0);
         // legacy settings
         self::config_set_value($configdata, 'legacy_show_inactive_users', 0);
         //trigger events
         if (!empty($configdata->cluster_groups) && empty($old_cluster_groups)) {
             events_trigger('crlm_cluster_groups_enabled', 0);
         }
         if (!empty($configdata->site_course_cluster_groups) && empty($old_site_course_cluster_groups)) {
             events_trigger('crlm_site_course_cluster_groups_enabled', 0);
         }
         if (!empty($configdata->cluster_groupings) && empty($old_cluster_groupings)) {
             events_trigger('crlm_cluster_groupings_enabled', 0);
         }
     }
     $configform->display();
 }
 function cron()
 {
     global $CFG;
     /// We are going to measure execution times
     $starttime = microtime();
     /// And we have one initial $status
     $status = true;
     /// We require some stuff
     require_once $CFG->libdir . '/rsslib.php';
     require_once MAGPIE_DIR . 'rss_fetch.inc';
     if (!defined('MAGPIE_OUTPUT_ENCODING')) {
         define('MAGPIE_OUTPUT_ENCODING', 'utf-8');
         // see bug 3107
     }
     /// Fetch all site feeds.
     $rs = get_recordset('block_rss_client');
     $counter = 0;
     mtrace('');
     while ($rec = rs_fetch_next_record($rs)) {
         mtrace('    ' . $rec->url . ' ', '');
         /// Fetch the rss feed, using standard magpie caching
         /// so feeds will be renewed only if cache has expired
         // sometimes the cron times out on moodle.org during fetching,
         // there is a 5s limit in magpie which should work, but does not sometimes :-(
         @set_time_limit(60);
         if ($rss = fetch_rss($rec->url)) {
             mtrace('ok');
         } else {
             mtrace('error');
             $status = false;
         }
         $counter++;
     }
     rs_close($rs);
     /// Show times
     mtrace($counter . ' feeds refreshed (took ' . microtime_diff($starttime, microtime()) . ' seconds)');
     /// And return $status
     return $status;
 }
Example #19
0
/**
 * Handler that gets called when cluster-based groupings are enabled
 */
function cluster_groups_crlm_cluster_groupings_enabled()
{
    $result = true;
    //update the groups and groupings info
    if ($recordset = get_recordset(CLSTTABLE)) {
        while ($record = rs_fetch_next_record($recordset)) {
            $result = $result && cluster_groups_update_site_course($record->id);
        }
    }
    //update the parent-child relationships
    if ($recordset = get_recordset(CLSTTABLE)) {
        while ($record = rs_fetch_next_record($recordset)) {
            $result = $result && cluster_groups_update_grouping_closure($record->id);
        }
    }
    return true;
}
/**
 * Creates a copy of the specified report schedule instance in the database
 *
 * @param   int      $id  The record id of the PHP report schedule to copy
 *
 * @return  boolean       true on success, otherwise false
 */
function block_php_report_copy_schedule_instance($id)
{
    if ($php_report_record = get_record('php_report_schedule', 'id', $id)) {
        $config = unserialize($php_report_record->config);
        //update modified time to right now
        $config['timemodified'] = time();
        //modify the label to prevent duplicates
        $config['label'] = block_php_report_get_copy_label($config['label']);
        $php_report_record->config = serialize($config);
        $php_report_record->id = insert_record('php_report_schedule', addslashes_recursive($php_report_record));
        //handle associated ELIS schedule records
        $taskname = block_php_report_get_taskname_from_id($id);
        if ($elis_records = get_recordset('elis_scheduled_tasks', 'taskname', $taskname)) {
            while ($elis_record = rs_fetch_next_record($elis_records)) {
                //make sure this points back to the new PHP report schedule instance
                $elis_record->taskname = block_php_report_get_taskname_from_id($php_report_record->id);
                //new instance, so it's never run before
                $elis_record->lastruntime = 0;
                insert_record('elis_scheduled_tasks', addslashes_recursive($elis_record));
            }
            return true;
        }
    }
    //not found, so signal failure
    return false;
}
function backup_oublog_userdata($bf, $preferences, $blogid)
{
    global $CFG;
    $status = true;
    // Instead of nesting, we will build a flat structure
    // this takes less DB queries, and is more resilient.
    //
    // oublog_instances
    // oublog_posts
    // oublog_edits
    // oublog_comments
    // oublog_tags (via taginstances)
    // oublog_links
    // Instances
    $recs = get_recordset("oublog_instances", "oublogid", $blogid);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("INSTANCES", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("INSTANCE", 5, true));
            $fields = array('id', 'userid', 'name', 'summary', 'accesstoken', 'views');
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("INSTANCE", 5, true));
        }
        $status = fwrite($bf, end_tag("INSTANCES", 4, true));
    }
    unset($recs);
    // Blog post links
    // NOTE: these are links related to blog instances,
    //       not to oublog records
    $sql = "SELECT l.*\r\n            FROM {$CFG->prefix}oublog_links l\r\n            JOIN {$CFG->prefix}oublog_instances i\r\n              ON l.oubloginstancesid=i.id\r\n            WHERE i.oublogid={$blogid}";
    $recs = get_recordset_sql($sql);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("LINKS", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("LINK", 5, true));
            $fields = array('id', 'oubloginstancesid', 'title', 'url', 'sortorder');
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("LINK", 5, true));
        }
        $status = fwrite($bf, end_tag("LINKS", 4, true));
    }
    unset($recs);
    // Blog posts
    $sql = "SELECT p.*\r\n            FROM {$CFG->prefix}oublog_posts p\r\n            JOIN {$CFG->prefix}oublog_instances i\r\n              ON p.oubloginstancesid=i.id\r\n            WHERE i.oublogid={$blogid}";
    $recs = get_recordset_sql($sql);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("POSTS", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("POST", 5, true));
            $fields = array('id', 'oubloginstancesid', 'groupid', 'title', 'message', 'timeposted', 'allowcomments', 'timeupdated', 'lasteditedby', 'deletedby', 'timedeleted', 'visibility');
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("POST", 5, true));
        }
        $status = fwrite($bf, end_tag("POSTS", 4, true));
    }
    unset($recs);
    // Blog post comments
    $sql = "SELECT c.*\r\n            FROM {$CFG->prefix}oublog_comments c\r\n            JOIN {$CFG->prefix}oublog_posts p\r\n              ON c.postid=p.id\r\n            JOIN {$CFG->prefix}oublog_instances i\r\n              ON p.oubloginstancesid=i.id\r\n            WHERE i.oublogid={$blogid}";
    $recs = get_recordset_sql($sql);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("COMMENTS", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("COMMENT", 5, true));
            $fields = array('id', 'postid', 'userid', 'title', 'message', 'timeposted', 'deletedby', 'timedeleted', 'authorname', 'authorip', 'timeapproved');
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("COMMENT", 5, true));
        }
        $status = fwrite($bf, end_tag("COMMENTS", 4, true));
    }
    unset($recs);
    // Blog post edits
    $sql = "SELECT e.*\r\n            FROM {$CFG->prefix}oublog_edits e\r\n            JOIN {$CFG->prefix}oublog_posts p\r\n              ON e.postid=p.id\r\n            JOIN {$CFG->prefix}oublog_instances i\r\n              ON p.oubloginstancesid=i.id\r\n            WHERE i.oublogid={$blogid}";
    $recs = get_recordset_sql($sql);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("EDITS", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("EDIT", 5, true));
            $fields = array('id', 'postid', 'userid', 'oldtitle', 'oldmessage', 'timeupdated');
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("EDIT", 5, true));
        }
        $status = fwrite($bf, end_tag("EDITS", 4, true));
    }
    unset($recs);
    // Blog post tags
    // NOTE: We store a rationalised view of
    //       tags to XML.
    $sql = "SELECT t.*, ti.postid\r\n            FROM {$CFG->prefix}oublog_tags t\r\n            JOIN {$CFG->prefix}oublog_taginstances ti\r\n              ON t.id=ti.tagid\r\n            JOIN {$CFG->prefix}oublog_posts p\r\n              ON ti.postid=p.id\r\n            JOIN {$CFG->prefix}oublog_instances i\r\n              ON p.oubloginstancesid=i.id\r\n            WHERE i.oublogid={$blogid}";
    $recs = get_recordset_sql($sql);
    if ($recs->RecordCount()) {
        $status = fwrite($bf, start_tag("TAGS", 4, true));
        while ($rec = rs_fetch_next_record($recs)) {
            $status = fwrite($bf, start_tag("TAG", 5, true));
            $fields = array('id', 'tagname', 'postid');
            $rec->tagname = $rec->tag;
            // use 'tagname' to disambiguate
            unset($rec->tag);
            // from 'tag' in the XML
            $status = write_rectags($bf, $fields, $rec, 6);
            $status = fwrite($bf, end_tag("TAG", 5, true));
        }
        $status = fwrite($bf, end_tag("TAGS", 4, true));
    }
    unset($recs);
    return $status;
}
Example #22
0
/**
 * Fires an event which can be handled by different parts of the system
 */
function handle_event($event, $data)
{
    global $USER;
    static $event_types = array(), $coreevents_cache = array(), $eventsubs_cache = array();
    if (empty($event_types)) {
        $event_types = array_fill_keys(get_column('event_type', 'name'), true);
    }
    $e = $event_types[$event];
    if (is_null($e)) {
        throw new SystemException("Invalid event");
    }
    if ($data instanceof ArtefactType) {
        // leave $data alone, but convert for the event log
        $logdata = $data->to_stdclass();
    } else {
        if ($data instanceof BlockInstance) {
            // leave $data alone, but convert for the event log
            $logdata = array('id' => $data->get('id'), 'blocktype' => $data->get('blocktype'));
        } else {
            if (is_object($data)) {
                $data = (array) $data;
            } else {
                if (is_numeric($data)) {
                    $data = array('id' => $data);
                }
            }
        }
    }
    $parentuser = $USER->get('parentuser');
    $eventloglevel = get_config('eventloglevel');
    if ($eventloglevel === 'all' or $parentuser and $eventloglevel === 'masq') {
        $logentry = (object) array('usr' => $USER->get('id'), 'realusr' => $parentuser ? $parentuser->id : $USER->get('id'), 'event' => $event, 'data' => json_encode(isset($logdata) ? $logdata : $data), 'time' => db_format_timestamp(time()));
        insert_record('event_log', $logentry);
    }
    if (empty($coreevents_cache)) {
        $rs = get_recordset('event_subscription');
        foreach ($rs as $record) {
            $coreevents_cache[$record['event']][] = $record['callfunction'];
        }
        $rs->close();
    }
    $coreevents = isset($coreevents_cache[$event]) ? $coreevents_cache[$event] : array();
    if (!empty($coreevents)) {
        require_once 'activity.php';
        // core events can generate activity.
        foreach ($coreevents as $ce) {
            if (function_exists($ce)) {
                call_user_func($ce, $data);
            } else {
                log_warn("Event {$event} caused a problem with a core subscription " . " {$ce}, which wasn't callable.  Continuing with event handlers");
            }
        }
    }
    $plugintypes = plugin_types_installed();
    foreach ($plugintypes as $name) {
        $cache_key = "{$event}__{$name}";
        if (!isset($eventsubs_cache[$cache_key])) {
            $eventsubs_cache[$cache_key] = get_records_array($name . '_event_subscription', 'event', $event);
        }
        if ($eventsubs_cache[$cache_key]) {
            $pluginsinstalled = plugins_installed($name);
            foreach ($eventsubs_cache[$cache_key] as $sub) {
                if (!isset($pluginsinstalled[$sub->plugin])) {
                    continue;
                }
                safe_require($name, $sub->plugin);
                $classname = 'Plugin' . ucfirst($name) . ucfirst($sub->plugin);
                try {
                    call_static_method($classname, $sub->callfunction, $event, $data);
                } catch (Exception $e) {
                    log_warn("Event {$event} caused an exception from plugin {$classname} " . "with function {$sub->callfunction}. Continuing with event handlers");
                }
            }
        }
    }
}
Example #23
0
/**
 * Add subscriptions for new users
 */
function forum_add_user_default_subscriptions($userid, $context)
{
    if (empty($context->contextlevel)) {
        return false;
    }
    switch ($context->contextlevel) {
        case CONTEXT_SYSTEM:
            // For the whole site
            $rs = get_recordset('course', '', '', '', 'id');
            while ($course = rs_fetch_next_record($rs)) {
                $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
                forum_add_user_default_subscriptions($userid, $subcontext);
            }
            rs_close($rs);
            break;
        case CONTEXT_COURSECAT:
            // For a whole category
            $rs = get_recordset('course', 'category', $context->instanceid, '', 'id');
            while ($course = rs_fetch_next_record($rs)) {
                $subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
                forum_add_user_default_subscriptions($userid, $subcontext);
            }
            rs_close($rs);
            if ($categories = get_records('course_categories', 'parent', $context->instanceid)) {
                foreach ($categories as $category) {
                    $subcontext = get_context_instance(CONTEXT_COURSECAT, $category->id);
                    forum_add_user_default_subscriptions($userid, $subcontext);
                }
            }
            break;
        case CONTEXT_COURSE:
            // For a whole course
            if ($course = get_record('course', 'id', $context->instanceid)) {
                if ($forums = get_all_instances_in_course('forum', $course, $userid, false)) {
                    foreach ($forums as $forum) {
                        if ($forum->forcesubscribe != FORUM_INITIALSUBSCRIBE) {
                            continue;
                        }
                        if ($modcontext = get_context_instance(CONTEXT_MODULE, $forum->coursemodule)) {
                            if (has_capability('mod/forum:viewdiscussion', $modcontext, $userid)) {
                                forum_subscribe($userid, $forum->id);
                            }
                        }
                    }
                }
            }
            break;
        case CONTEXT_MODULE:
            // Just one forum
            if ($cm = get_coursemodule_from_id('forum', $context->instanceid)) {
                if ($forum = get_record('forum', 'id', $cm->instance)) {
                    if ($forum->forcesubscribe != FORUM_INITIALSUBSCRIBE) {
                        continue;
                    }
                    if (has_capability('mod/forum:viewdiscussion', $context, $userid)) {
                        forum_subscribe($userid, $forum->id);
                    }
                }
            }
            break;
    }
    return true;
}
Example #24
0
 /**
  * Performs the necessary calculations on the grades_final referenced by this grade_item.
  * Also resets the needsupdate flag once successfully performed.
  *
  * This function must be used ONLY from lib/gradeslib.php/grade_regrade_final_grades(),
  * because the regrading must be done in correct order!!
  *
  * @return boolean true if ok, error string otherwise
  */
 function regrade_final_grades($userid = null)
 {
     global $CFG;
     // locked grade items already have correct final grades
     if ($this->is_locked()) {
         return true;
     }
     // calculation produces final value using formula from other final values
     if ($this->is_calculated()) {
         if ($this->compute($userid)) {
             return true;
         } else {
             return "Could not calculate grades for grade item";
             // TODO: improve and localize
         }
         // noncalculated outcomes already have final values - raw grades not used
     } else {
         if ($this->is_outcome_item()) {
             return true;
             // aggregate the category grade
         } else {
             if ($this->is_category_item() or $this->is_course_item()) {
                 // aggregate category grade item
                 $category = $this->get_item_category();
                 $category->grade_item =& $this;
                 if ($category->generate_grades($userid)) {
                     return true;
                 } else {
                     return "Could not aggregate final grades for category:" . $this->id;
                     // TODO: improve and localize
                 }
             } else {
                 if ($this->is_manual_item()) {
                     // manual items track only final grades, no raw grades
                     return true;
                 } else {
                     if (!$this->is_raw_used()) {
                         // hmm - raw grades are not used- nothing to regrade
                         return true;
                     }
                 }
             }
         }
     }
     // normal grade item - just new final grades
     $result = true;
     $grade_inst = new grade_grade();
     $fields = implode(',', $grade_inst->required_fields);
     if ($userid) {
         $rs = get_recordset_select('grade_grades', "itemid={$this->id} AND userid={$userid}", '', $fields);
     } else {
         $rs = get_recordset('grade_grades', 'itemid', $this->id, '', $fields);
     }
     if ($rs) {
         while ($grade_record = rs_fetch_next_record($rs)) {
             $grade = new grade_grade($grade_record, false);
             if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
                 // this grade is locked - final grade must be ok
                 continue;
             }
             $grade->finalgrade = $this->adjust_raw_grade($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax);
             if (grade_floats_different($grade_record->finalgrade, $grade->finalgrade)) {
                 if (!$grade->update('system')) {
                     $result = "Internal error updating final grade";
                 }
             }
         }
         rs_close($rs);
     }
     return $result;
 }
/**
 * Format Upgrade Path
 *
 * @version $Id: upgrade.php,v 1.1 2009/12/21 01:00:29 michaelpenne Exp $
 * @package format_page
 **/
function xmldb_format_page_upgrade($oldversion = 0)
{
    global $CFG, $db;
    include_once $CFG->dirroot . '/course/format/page/lib.php';
    $result = true;
    if ($result && $oldversion < 2007041202) {
        /// Define field id to be added to block_course_menu
        $table = new XMLDBTable('format_page');
        /// Add field showbuttons
        $field = new XMLDBField('showbuttons');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null, null, 0, 'template');
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2007042500) {
        // update showbuttons settings to allow for indedependent bitwise previous & next
        if (defined('BUTTON_BOTH')) {
            $result = set_field('format_page', 'showbuttons', BUTTON_BOTH, 'showbuttons', 1);
        } else {
            $result = false;
            notify('BUTTON_BOTH constant not set', 'notifyfailure');
        }
    }
    if ($result && $oldversion < 2007042503) {
        /// Define index index (not unique) to be added to format_page
        $table = new XMLDBTable('format_page');
        $index = new XMLDBIndex('parentpageindex');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('parent'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        $index = new XMLDBIndex('sortorderpageindex');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('sortorder'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        // now add indexes for format_page_items tables
        $table = new XMLDBTable('format_page_items');
        $index = new XMLDBIndex('format_page_items_sortorder_index');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('sortorder'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        $index = new XMLDBIndex('format_page_items_pageid_index');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('pageid'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
    }
    if ($result && $oldversion < 2007071800) {
        $validcourses = get_records_menu('course', '', '', '', 'id, shortname');
        if (!empty($validcourses)) {
            $keys = array_keys($validcourses);
            $invalidpages = get_records_select_menu('format_page', 'courseid NOT IN(' . implode(', ', $keys) . ')', '', 'id, nameone');
            if (!empty($invalidpages)) {
                $pagekeys = array_keys($invalidpages);
                delete_records_select('format_page_items', 'pageid IN (' . implode(', ', $pagekeys) . ')');
                delete_records_select('format_page', 'id IN (' . implode(', ', $pagekeys) . ')');
            }
        } else {
            delete_records('format_page');
            delete_records('format_page_items');
        }
    }
    if ($result && $oldversion < 2007071801) {
        /// Define field width to be dropped from format_page_items
        $table = new XMLDBTable('format_page_items');
        $field = new XMLDBField('width');
        /// Launch drop field width
        $result = $result && drop_field($table, $field);
    }
    if ($result && $oldversion < 2007071802) {
        /// Changing logic for sortorder field to more closely resemble block weight
        // This could be huge, do not output everything
        $olddebug = $db->debug;
        $db->debug = false;
        // Setup some values
        $result = true;
        $i = 0;
        if ($rs = get_recordset('format_page', '1', '1', '', 'id')) {
            if ($rs->RecordCount() > 0) {
                echo 'Processing page item sortorder field....';
                while ($page = rs_fetch_next_record($rs)) {
                    if ($pageitems = get_records('format_page_items', 'pageid', $page->id, 'sortorder', 'id, position')) {
                        // Organize by position
                        $organized = array('l' => array(), 'c' => array(), 'r' => array());
                        foreach ($pageitems as $pageitem) {
                            $organized[$pageitem->position][] = $pageitem->id;
                        }
                        // Now - reset sortorder value
                        foreach ($organized as $position => $pageitemids) {
                            $sortorder = 0;
                            foreach ($pageitemids as $pageitemid) {
                                $result = $result and set_field('format_page_items', 'sortorder', $sortorder, 'id', $pageitemid);
                                $sortorder++;
                            }
                        }
                    }
                    if ($i % 50 == 0) {
                        echo '.';
                        flush();
                    }
                    $i++;
                }
                if ($result) {
                    notify('SUCCESSFULLY fixed page item sort order field', 'notifysuccess');
                } else {
                    notify('FAILED!  An error occured during upgrade');
                }
            }
            rs_close($rs);
        }
        // Restore
        $db->debug = $olddebug;
    }
    if ($result && $oldversion < 2007071803) {
        // This could be huge, do not output everything
        $olddebug = $db->debug;
        $db->debug = false;
        $result = true;
        // Make sure all block weights are set properly (before this was never really managed properly)
        if ($courses = get_records('course', 'format', 'page', '', 'id')) {
            echo 'Fixing block weights in courses with format = \'page\'....';
            $i = 0;
            foreach ($courses as $course) {
                page_fix_block_weights($course->id);
                if ($i % 5 == 0) {
                    echo '.';
                    flush();
                }
                $i++;
            }
        }
        // Restore
        $db->debug = $olddebug;
    }
    if ($result && $oldversion < 2007071804) {
        /// Changing the default of field sortorder on table format_page_items to 0
        $table = new XMLDBTable('format_page_items');
        $field = new XMLDBField('sortorder');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'position');
        /// Launch change of default for field sortorder
        $result = $result && change_field_default($table, $field);
    }
    if ($result && $oldversion < 2007071805) {
        // This could be huge, do not output everything
        $olddebug = $db->debug;
        $db->debug = false;
        $result = true;
        // Make sure all page sortorder values are set properly (before this was never really managed properly)
        if ($courses = get_records('course', 'format', 'page', '', 'id')) {
            echo 'Fixing page sort orders in courses with format = \'page\'....';
            $i = 0;
            foreach ($courses as $course) {
                page_fix_page_sortorder($course->id);
                if ($i % 5 == 0) {
                    echo '.';
                    flush();
                }
                $i++;
            }
        }
        // Restore
        $db->debug = $olddebug;
    }
    if ($result && $oldversion < 2007071806) {
        // Remove old setting
        if (record_exists('config', 'name', 'pageformatusedefault')) {
            unset_config('pageformatusedefault');
        }
    }
    if ($result && $oldversion < 2007071807) {
        $site = get_site();
        if ($site->format == 'page') {
            $result = ($result and set_field('course', 'format', 'site', 'id', $site->id));
            $result = ($result and set_config('pageformatonfrontpage', 1));
        }
    }
    if ($result && $oldversion < 2008082100) {
        $site = get_site();
        if ($CFG->pageformatonfrontpage == 1) {
            // Turns out having this set is very important - EG: backup/restore
            $result = set_field('course', 'format', 'page', 'id', $site->id);
        }
    }
    if ($result && $oldversion < 2008121000) {
        /// Define field locks to be added to format_page
        $table = new XMLDBTable('format_page');
        $field = new XMLDBField('locks');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'showbuttons');
        /// Launch add field locks
        $result = $result && add_field($table, $field);
    }
    if ($result && $oldversion < 2009060200) {
        //MR-263 column widths to strings to allow for px, % and em etc.
        $table = new XMLDBTable('format_page');
        $field = new XMLDBField('prefleftwidth');
        $field->setType(XMLDB_TYPE_CHAR);
        $result = $result && change_field_type($table, $field);
        $field = new XMLDBField('prefcenterwidth');
        $field->setType(XMLDB_TYPE_CHAR);
        $result = $result && change_field_type($table, $field);
        $field = new XMLDBField('prefrightwidth');
        $field->setType(XMLDB_TYPE_CHAR);
        $result = $result && change_field_type($table, $field);
        // XMLDB_TYPE_CHAR isn't the same as varchar???
        //$alter = "ALTER TABLE {$CFG->prefix}format_page CHANGE prefleftwidth prefleftwidth varchar(8)";
    }
    return $result;
}
Example #26
0
/**
 * Get the first two columns from a number of records as an associative array.
 *
 * Arguments as for @see function get_recordset.
 *
 * If no errors occur, and at least one records is found, the return value
 * is an associative whose keys come from the first field of each record,
 * and whose values are the corresponding second fields. If no records are found,
 * or an error occurs, false is returned.
 *
 * @param string $table the table to query.
 * @param string $field a field to check (optional).
 * @param string $value the value the field must have (requred if field1 is given, else optional).
 * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
 * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
 * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
 * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
 * @return mixed an associative array, or false if no records were found or an error occured.
 */
function get_records_menu($table, $field = '', $value = '', $sort = '', $fields = '*', $limitfrom = '', $limitnum = '')
{
    $rs = get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
    return recordset_to_menu($rs);
}
Example #27
0
function xmldb_main_upgrade($oldversion = 0)
{
    global $CFG, $THEME, $USER, $db;
    $result = true;
    if ($oldversion < 2006100401) {
        /// Only for those tracking Moodle 1.7 dev, others will have these dropped in moodle_install_roles()
        if (!empty($CFG->rolesactive)) {
            drop_table(new XMLDBTable('user_students'));
            drop_table(new XMLDBTable('user_teachers'));
            drop_table(new XMLDBTable('user_coursecreators'));
            drop_table(new XMLDBTable('user_admins'));
        }
        upgrade_main_savepoint($result, 2006100401);
    }
    if ($oldversion < 2006100601) {
        /// Disable the exercise module because it's unmaintained
        if ($module = get_record('modules', 'name', 'exercise')) {
            if ($module->visible) {
                // Hide/disable the module entry
                set_field('modules', 'visible', '0', 'id', $module->id);
                // Save existing visible state for all activities
                set_field('course_modules', 'visibleold', '1', 'visible', '1', 'module', $module->id);
                set_field('course_modules', 'visibleold', '0', 'visible', '0', 'module', $module->id);
                // Hide all activities
                set_field('course_modules', 'visible', '0', 'module', $module->id);
                require_once $CFG->dirroot . '/course/lib.php';
                rebuild_course_cache();
                // Rebuld cache for all modules because they might have changed
            }
        }
        upgrade_main_savepoint($result, 2006100601);
    }
    if ($oldversion < 2006101001) {
        /// Disable the LAMS module by default (if it is installed)
        if (count_records('modules', 'name', 'lams') && !count_records('lams')) {
            set_field('modules', 'visible', 0, 'name', 'lams');
            // Disable it by default
        }
        upgrade_main_savepoint($result, 2006101001);
    }
    if ($result && $oldversion < 2006102600) {
        /// Define fields to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('description');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'categoryid');
        $field1 = new XMLDBField('param1');
        $field1->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'defaultdata');
        $field2 = new XMLDBField('param2');
        $field2->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param1');
        $field3 = new XMLDBField('param3');
        $field3->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param2');
        $field4 = new XMLDBField('param4');
        $field4->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param3');
        $field5 = new XMLDBField('param5');
        $field5->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'param4');
        /// Launch add fields
        $result = $result && add_field($table, $field);
        $result = $result && add_field($table, $field1);
        $result = $result && add_field($table, $field2);
        $result = $result && add_field($table, $field3);
        $result = $result && add_field($table, $field4);
        $result = $result && add_field($table, $field5);
        upgrade_main_savepoint($result, 2006102600);
    }
    if ($result && $oldversion < 2006112000) {
        /// Define field attachment to be added to post
        $table = new XMLDBTable('post');
        $field = new XMLDBField('attachment');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'format');
        /// Launch add field attachment
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2006112000);
    }
    if ($result && $oldversion < 2006112200) {
        /// Define field imagealt to be added to user
        $table = new XMLDBTable('user');
        $field = new XMLDBField('imagealt');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'trustbitmask');
        /// Launch add field imagealt
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('user');
        $field = new XMLDBField('screenreader');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0', 'imagealt');
        /// Launch add field screenreader
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2006112200);
    }
    if ($oldversion < 2006120300) {
        /// Delete guest course section settings
        // following code can be executed repeatedly, such as when upgrading from 1.7.x - it is ok
        if ($guest = get_record('user', 'username', 'guest')) {
            execute_sql("DELETE FROM {$CFG->prefix}course_display where userid={$guest->id}", true);
        }
        upgrade_main_savepoint($result, 2006120300);
    }
    if ($oldversion < 2006120400) {
        /// Remove secureforms config setting
        execute_sql("DELETE FROM {$CFG->prefix}config where name='secureforms'", true);
        upgrade_main_savepoint($result, 2006120400);
    }
    if (!empty($CFG->rolesactive) && $oldversion < 2006120700) {
        // add moodle/user:viewdetails to all roles!
        // note: use of assign_capability() is discouraged in upgrade script!
        if ($roles = get_records('role')) {
            $context = get_context_instance(CONTEXT_SYSTEM);
            foreach ($roles as $roleid => $role) {
                assign_capability('moodle/user:viewdetails', CAP_ALLOW, $roleid, $context->id);
            }
        }
        upgrade_main_savepoint($result, 2006120700);
    }
    // Move the auth plugin settings into the config_plugin table
    if ($oldversion < 2007010300) {
        if ($CFG->auth == 'email') {
            set_config('registerauth', 'email');
        } else {
            set_config('registerauth', '');
        }
        $authplugins = get_list_of_plugins('auth');
        foreach ($CFG as $k => $v) {
            if (strpos($k, 'ldap_') === 0) {
                //upgrade nonstandard ldap settings
                $setting = substr($k, 5);
                if (set_config($setting, $v, "auth/ldap")) {
                    delete_records('config', 'name', $k);
                    unset($CFG->{$k});
                }
                continue;
            }
            if (strpos($k, 'auth_') !== 0) {
                continue;
            }
            $authsetting = substr($k, 5);
            foreach ($authplugins as $auth) {
                if (strpos($authsetting, $auth) !== 0) {
                    continue;
                }
                $setting = substr($authsetting, strlen($auth));
                if (set_config($setting, $v, "auth/{$auth}")) {
                    delete_records('config', 'name', $k);
                    unset($CFG->{$k});
                }
                break;
                // don't check the rest of the auth plugin names
            }
        }
        upgrade_main_savepoint($result, 2007010300);
    }
    if ($oldversion < 2007010301) {
        //
        // Core MNET tables
        //
        $table = new XMLDBTable('mnet_host');
        $table->comment = 'Information about the local and remote hosts for RPC';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f->comment = 'Unique Host ID';
        $f = $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('wwwroot', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('ip_address', XMLDB_TYPE_CHAR, '39', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '80', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('public_key', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        $f = $table->addFieldInfo('public_key_expires', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('transport', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('portno', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('last_connect_time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        $f = $table->addFieldInfo('last_log_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_host2service');
        $table->comment = 'Information about the services for a given host';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('serviceid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('publish', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('subscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_serviceid', XMLDB_INDEX_UNIQUE, array('hostid', 'serviceid'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_log');
        $table->comment = 'Store session data from users migrating to other sites';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('remoteid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('time', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('ip', XMLDB_TYPE_CHAR, '15', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('coursename', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('module', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('cmid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('action', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('url', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('info', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('host_user_course', XMLDB_INDEX_NOTUNIQUE, array('hostid', 'userid', 'course'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_rpc');
        $table->comment = 'Functions or methods that we may publish or subscribe to';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('function_name', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('xmlrpc_path', XMLDB_TYPE_CHAR, '80', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('parent_type', XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('parent', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('enabled', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('help', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('profile', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('enabled_xpath', XMLDB_INDEX_NOTUNIQUE, array('enabled', 'xmlrpc_path'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_service');
        $table->comment = 'A service is a group of functions';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('description', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('apiversion', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('offer', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_service2rpc');
        $table->comment = 'Group functions or methods under a service';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('serviceid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('rpcid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('unique', XMLDB_INDEX_UNIQUE, array('rpcid', 'serviceid'));
        // Create the table
        $result = $result && create_table($table);
        //
        // Prime MNET configuration entries -- will be needed later by auth/mnet
        //
        include_once $CFG->dirroot . '/mnet/lib.php';
        $env = new mnet_environment();
        $env->init();
        unset($env);
        // add mnethostid to user-
        $table = new XMLDBTable('user');
        $field = new XMLDBField('mnethostid');
        $field->setType(XMLDB_TYPE_INTEGER);
        $field->setLength(10);
        $field->setNotNull(true);
        $field->setSequence(null);
        $field->setEnum(null);
        $field->setDefault('0');
        $field->setPrevious("deleted");
        $field->setNext("username");
        $result = $result && add_field($table, $field);
        // The default mnethostid is zero... we need to update this for all
        // users of the local IdP service.
        set_field('user', 'mnethostid', $CFG->mnet_localhost_id, 'mnethostid', '0');
        $index = new XMLDBIndex('username');
        $index->setUnique(true);
        $index->setFields(array('username'));
        drop_index($table, $index);
        $index->setFields(array('mnethostid', 'username'));
        if (!add_index($table, $index)) {
            notify(get_string('duplicate_usernames', 'mnet', 'http://docs.moodle.org/en/DuplicateUsernames'));
        }
        unset($table, $field, $index);
        /**
         ** auth/mnet tables
         **/
        $table = new XMLDBTable('mnet_session');
        $table->comment = 'Store session data from users migrating to other sites';
        // fields
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('token', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('mnethostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('useragent', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('confirm_timeout', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('session_id', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('expires', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('token', XMLDB_INDEX_UNIQUE, array('token'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_sso_access_control');
        $table->comment = 'Users by host permitted (or not) to login from a remote provider';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('username', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('mnet_host_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('access', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, 'allow');
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('mnethostid_username', XMLDB_INDEX_UNIQUE, array('mnet_host_id', 'username'));
        // Create the table
        $result = $result && create_table($table);
        if (empty($USER->mnet_host_id)) {
            $USER->mnet_host_id = $CFG->mnet_localhost_id;
            // Something for the current user to prevent warnings
        }
        /**
         ** enrol/mnet tables
         **/
        $table = new XMLDBTable('mnet_enrol_course');
        $table->comment = 'Information about courses on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('remoteid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cat_id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cat_name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('cat_description', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '254', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '15', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('summary', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('startdate', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('cost', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('currency', XMLDB_TYPE_CHAR, '3', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('defaultroleid', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('defaultrolename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_remoteid', XMLDB_INDEX_UNIQUE, array('hostid', 'remoteid'));
        // Create the table
        $result = $result && create_table($table);
        $table = new XMLDBTable('mnet_enrol_assignments');
        $table->comment = 'Information about enrolments on courses on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('hostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('rolename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('enroltime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, NULL, null, null, 0);
        $f = $table->addFieldInfo('enroltype', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addIndexInfo('hostid_courseid', XMLDB_INDEX_NOTUNIQUE, array('hostid', 'courseid'));
        $table->addIndexInfo('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
        // Create the table
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007010301);
    }
    if ($result && $oldversion < 2007010404) {
        /// Define field shortname to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('shortname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'shortname', 'id');
        /// Launch add field shortname
        $result = $result && add_field($table, $field);
        /// Changing type of field name on table user_info_field to text
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('name');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null, 'shortname');
        /// Launch change of type for field name
        $result = $result && change_field_type($table, $field);
        /// For existing fields use 'name' as the 'shortname' entry
        if ($fields = get_records_select('user_info_field', '', '', 'id, name')) {
            foreach ($fields as $field) {
                $field->shortname = clean_param($field->name, PARAM_ALPHANUM);
                $result && update_record('user_info_field', $field);
            }
        }
        upgrade_main_savepoint($result, 2007010404);
    }
    if ($result && $oldversion < 2007011501) {
        if (!empty($CFG->enablerecordcache) && empty($CFG->rcache) && empty($CFG->cachetype) && empty($CFG->intcachemax)) {
            set_config('cachetype', 'internal');
            set_config('rcache', true);
            set_config('intcachemax', $CFG->enablerecordcache);
            unset_config('enablerecordcache');
            unset($CFG->enablerecordcache);
        }
        upgrade_main_savepoint($result, 2007011501);
    }
    if ($result && $oldversion < 2007012100) {
        /// Some old PG servers have user->firstname & user->lastname with 30cc. They must be 100cc.
        /// Fixing that conditionally. MDL-7110
        if ($CFG->dbfamily == 'postgres') {
            /// Get Metadata from user table
            $cols = array_change_key_case($db->MetaColumns($CFG->prefix . 'user'), CASE_LOWER);
            /// Process user->firstname if needed
            if ($col = $cols['firstname']) {
                if ($col->max_length < 100) {
                    /// Changing precision of field firstname on table user to (100)
                    $table = new XMLDBTable('user');
                    $field = new XMLDBField('firstname');
                    $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'idnumber');
                    /// Launch change of precision for field firstname
                    $result = $result && change_field_precision($table, $field);
                }
            }
            /// Process user->lastname if needed
            if ($col = $cols['lastname']) {
                if ($col->max_length < 100) {
                    /// Changing precision of field lastname on table user to (100)
                    $table = new XMLDBTable('user');
                    $field = new XMLDBField('lastname');
                    $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'firstname');
                    /// Launch change of precision for field lastname
                    $result = $result && change_field_precision($table, $field);
                }
            }
        }
        upgrade_main_savepoint($result, 2007012100);
    }
    if ($result && $oldversion < 2007012101) {
        /// Changing precision of field lang on table course to (30)
        $table = new XMLDBTable('course');
        $field = new XMLDBField('lang');
        $field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null, 'groupmodeforce');
        /// Launch change of precision for field course->lang
        $result = $result && change_field_precision($table, $field);
        /// Changing precision of field lang on table user to (30)
        $table = new XMLDBTable('user');
        $field = new XMLDBField('lang');
        $field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'en', 'country');
        /// Launch change of precision for field user->lang
        $result = $result && change_field_precision($table, $field);
        upgrade_main_savepoint($result, 2007012101);
    }
    if ($result && $oldversion < 2007012400) {
        /// Rename field access on table mnet_sso_access_control to accessctrl
        $table = new XMLDBTable('mnet_sso_access_control');
        $field = new XMLDBField('access');
        $field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'allow', 'mnet_host_id');
        /// Launch rename field accessctrl
        $result = $result && rename_field($table, $field, 'accessctrl');
        upgrade_main_savepoint($result, 2007012400);
    }
    if ($result && $oldversion < 2007012500) {
        execute_sql("DELETE FROM {$CFG->prefix}user WHERE username='******'", true);
        upgrade_main_savepoint($result, 2007012500);
    }
    if ($result && $oldversion < 2007020400) {
        /// Only for MySQL and PG, declare the user->ajax field as not null. MDL-8421.
        if ($CFG->dbfamily == 'mysql' || $CFG->dbfamily == 'postgres') {
            /// Changing nullability of field ajax on table user to not null
            $table = new XMLDBTable('user');
            $field = new XMLDBField('ajax');
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'htmleditor');
            /// Launch change of nullability for field ajax
            $result = $result && change_field_notnull($table, $field);
        }
        upgrade_main_savepoint($result, 2007020400);
    }
    if (!empty($CFG->rolesactive) && $result && $oldversion < 2007021401) {
        /// create default logged in user role if not present - upgrade rom 1.7.x
        if (empty($CFG->defaultuserroleid) or empty($CFG->guestroleid) or $CFG->defaultuserroleid == $CFG->guestroleid) {
            if (!get_records('role', 'shortname', 'user')) {
                $userroleid = create_role(addslashes(get_string('authenticateduser')), 'user', addslashes(get_string('authenticateduserdescription')), 'moodle/legacy:user');
                if ($userroleid) {
                    reset_role_capabilities($userroleid);
                    set_config('defaultuserroleid', $userroleid);
                }
            }
        }
        upgrade_main_savepoint($result, 2007021401);
    }
    if ($result && $oldversion < 2007021501) {
        /// delete removed setting from config
        unset_config('tabselectedtofront');
        upgrade_main_savepoint($result, 2007021501);
    }
    if ($result && $oldversion < 2007032200) {
        /// Define table role_sortorder to be created
        $table = new XMLDBTable('role_sortorder');
        /// Adding fields to table role_sortorder
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('roleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('contextid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('sortoder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table role_sortorder
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('roleid', XMLDB_KEY_FOREIGN, array('roleid'), 'role', array('id'));
        $table->addKeyInfo('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
        /// Adding indexes to table role_sortorder
        $table->addIndexInfo('userid-roleid-contextid', XMLDB_INDEX_UNIQUE, array('userid', 'roleid', 'contextid'));
        /// Launch create table for role_sortorder
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007032200);
    }
    /// code to change lenghen tag field to 255, MDL-9095
    if ($result && $oldversion < 2007040400) {
        /// Define index text (not unique) to be dropped form tags
        $table = new XMLDBTable('tags');
        $index = new XMLDBIndex('text');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('text'));
        /// Launch drop index text
        $result = $result && drop_index($table, $index);
        $field = new XMLDBField('text');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'userid');
        /// Launch change of type for field text
        $result = $result && change_field_type($table, $field);
        $index = new XMLDBIndex('text');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('text'));
        /// Launch add index text
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007040400);
    }
    if ($result && $oldversion < 2007041100) {
        /// Define field idnumber to be added to course_modules
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('idnumber');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'section');
        /// Launch add field idnumber
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007041100);
    }
    /* Changes to the custom profile menu type - store values rather than indices.
       We could do all this with one tricky SQL statement but it's a one-off so no
       harm in using PHP loops */
    if ($result && $oldversion < 2007041600) {
        /// Get the menu fields
        if ($fields = get_records('user_info_field', 'datatype', 'menu')) {
            foreach ($fields as $field) {
                /// Get user data for the menu field
                if ($data = get_records('user_info_data', 'fieldid', $field->id)) {
                    /// Get the menu options
                    $options = explode("\n", $field->param1);
                    foreach ($data as $d) {
                        $key = array_search($d->data, $options);
                        /// If the data is an integer and is not one of the options,
                        /// set the respective option value
                        if (is_int($d->data) and ($key === NULL or $key === false) and isset($options[$d->data])) {
                            $d->data = $options[$d->data];
                            $result = $result && update_record('user_info_data', $d);
                        }
                    }
                }
            }
        }
        upgrade_main_savepoint($result, 2007041600);
    }
    /// adding new gradebook tables
    if ($result && $oldversion < 2007041800) {
        /// Define table events_handlers to be created
        $table = new XMLDBTable('events_handlers');
        /// Adding fields to table events_handlers
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('eventname', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlermodule', XMLDB_TYPE_CHAR, '166', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerfile', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerfunction', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        /// Adding keys to table events_handlers
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table events_handlers
        $table->addIndexInfo('eventname-handlermodule', XMLDB_INDEX_UNIQUE, array('eventname', 'handlermodule'));
        /// Launch create table for events_handlers
        $result = $result && create_table($table);
        /// Define table events_queue to be created
        $table = new XMLDBTable('events_queue');
        /// Adding fields to table events_queue
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('eventdata', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('schedule', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('stackdump', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table events_queue
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch create table for events_queue
        $result = $result && create_table($table);
        /// Define table events_queue_handlers to be created
        $table = new XMLDBTable('events_queue_handlers');
        /// Adding fields to table events_queue_handlers
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('queuedeventid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('handlerid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('status', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
        $table->addFieldInfo('errormessage', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table events_queue_handlers
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('queuedeventid', XMLDB_KEY_FOREIGN, array('queuedeventid'), 'events_queue', array('id'));
        $table->addKeyInfo('handlerid', XMLDB_KEY_FOREIGN, array('handlerid'), 'events_handlers', array('id'));
        /// Launch create table for events_queue_handlers
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007041800);
    }
    if ($result && $oldversion < 2007043001) {
        /// Define field schedule to be added to events_handlers
        $table = new XMLDBTable('events_handlers');
        $field = new XMLDBField('schedule');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'handlerfunction');
        /// Launch add field schedule
        $result = $result && add_field($table, $field);
        /// Define field status to be added to events_handlers
        $table = new XMLDBTable('events_handlers');
        $field = new XMLDBField('status');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'schedule');
        /// Launch add field status
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007043001);
    }
    if ($result && $oldversion < 2007050201) {
        /// Define field theme to be added to course_categories
        $table = new XMLDBTable('course_categories');
        $field = new XMLDBField('theme');
        $field->setAttributes(XMLDB_TYPE_CHAR, '50', null, null, null, null, null, null, 'path');
        /// Launch add field theme
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007050201);
    }
    if ($result && $oldversion < 2007051100) {
        /// Define field forceunique to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('forceunique');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'visible');
        /// Launch add field forceunique
        $result = $result && add_field($table, $field);
        /// Define field signup to be added to user_info_field
        $table = new XMLDBTable('user_info_field');
        $field = new XMLDBField('signup');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'forceunique');
        /// Launch add field signup
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007051100);
    }
    if (!empty($CFG->rolesactive) && $result && $oldversion < 2007051801) {
        // Get the role id of the "Auth. User" role and check if the default role id is different
        // note: use of assign_capability() is discouraged in upgrade script!
        $userrole = get_record('role', 'shortname', 'user');
        $defaultroleid = $CFG->defaultuserroleid;
        if ($defaultroleid != $userrole->id) {
            //  Add in the new moodle/my:manageblocks capibility to the default user role
            $context = get_context_instance(CONTEXT_SYSTEM, SITEID);
            assign_capability('moodle/my:manageblocks', CAP_ALLOW, $defaultroleid, $context->id);
        }
        upgrade_main_savepoint($result, 2007051801);
    }
    if ($result && $oldversion < 2007052200) {
        /// Define field schedule to be dropped from events_queue
        $table = new XMLDBTable('events_queue');
        $field = new XMLDBField('schedule');
        /// Launch drop field stackdump
        $result = $result && drop_field($table, $field);
        upgrade_main_savepoint($result, 2007052200);
    }
    if ($result && $oldversion < 2007052300) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_remove_rqp_qtype();
        upgrade_main_savepoint($result, 2007052300);
    }
    if ($result && $oldversion < 2007060500) {
        /// Define field usermodified to be added to post
        $table = new XMLDBTable('post');
        $field = new XMLDBField('usermodified');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'created');
        /// Launch add field usermodified
        $result = $result && add_field($table, $field);
        /// Define key usermodified (foreign) to be added to post
        $table = new XMLDBTable('post');
        $key = new XMLDBKey('usermodified');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Launch add key usermodified
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007060500);
    }
    if ($result && $oldversion < 2007070603) {
        // Small update of guest user to be 100% sure it has the correct mnethostid (MDL-10375)
        set_field('user', 'mnethostid', $CFG->mnet_localhost_id, 'username', 'guest');
        upgrade_main_savepoint($result, 2007070603);
    }
    if ($result && $oldversion < 2007071400) {
        /**
         ** mnet application table
         **/
        $table = new XMLDBTable('mnet_application');
        $table->comment = 'Information about applications on remote hosts';
        $f = $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', false, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $f = $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('display_name', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('xmlrpc_server_url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        $f = $table->addFieldInfo('sso_land_url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, NULL, null, null, null);
        // PK and indexes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        // Create the table
        $result = $result && create_table($table);
        // Insert initial applications (moodle and mahara)
        $application = new stdClass();
        $application->name = 'moodle';
        $application->display_name = 'Moodle';
        $application->xmlrpc_server_url = '/mnet/xmlrpc/server.php';
        $application->sso_land_url = '/auth/mnet/land.php';
        if ($result) {
            $newid = insert_record('mnet_application', $application, false);
        }
        $application = new stdClass();
        $application->name = 'mahara';
        $application->display_name = 'Mahara';
        $application->xmlrpc_server_url = '/api/xmlrpc/server.php';
        $application->sso_land_url = '/auth/xmlrpc/land.php';
        $result = $result && insert_record('mnet_application', $application, false);
        // New mnet_host->applicationid field
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('applicationid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, $newid, 'last_log_id');
        $result = $result && add_field($table, $field);
        /// Define key applicationid (foreign) to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch add key applicationid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007071400);
    }
    if ($result && $oldversion < 2007071607) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_remove_rqp_qtype_config_string();
        upgrade_main_savepoint($result, 2007071607);
    }
    if ($result && $oldversion < 2007072200) {
        /// Remove all grade tables used in development phases - we need new empty tables for final gradebook upgrade
        $tables = array('grade_categories', 'grade_items', 'grade_calculations', 'grade_grades', 'grade_grades_raw', 'grade_grades_final', 'grade_grades_text', 'grade_outcomes', 'grade_outcomes_courses', 'grade_history', 'grade_import_newitem', 'grade_import_values');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        $tables = array('grade_categories_history', 'grade_items_history', 'grade_grades_history', 'grade_grades_text_history', 'grade_scale_history', 'grade_outcomes_history');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        /// Define table grade_outcomes to be created
        $table = new XMLDBTable('grade_outcomes');
        /// Adding fields to table grade_outcomes
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_outcomes
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Launch create table for grade_outcomes
        $result = $result && create_table($table);
        /// Define table grade_categories to be created
        $table = new XMLDBTable('grade_categories');
        /// Adding fields to table grade_categories
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_categories
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
        /// Launch create table for grade_categories
        $result = $result && create_table($table);
        /// Define table grade_items to be created
        $table = new XMLDBTable('grade_items');
        /// Adding fields to table grade_items
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
        $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
        $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
        $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregationcoef', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_items
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        /// Adding indexes to table grade_grades
        $table->addIndexInfo('locked-locktime', XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        $table->addIndexInfo('itemtype-needsupdate', XMLDB_INDEX_NOTUNIQUE, array('itemtype', 'needsupdate'));
        $table->addIndexInfo('gradetype', XMLDB_INDEX_NOTUNIQUE, array('gradetype'));
        /// Launch create table for grade_items
        $result = $result && create_table($table);
        /// Define table grade_grades to be created
        $table = new XMLDBTable('grade_grades');
        /// Adding fields to table grade_grades
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_grades
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        /// Adding indexes to table grade_grades
        $table->addIndexInfo('locked-locktime', XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        /// Launch create table for grade_grades
        $result = $result && create_table($table);
        /// Define table grade_outcomes_history to be created
        $table = new XMLDBTable('grade_outcomes_history');
        /// Adding fields to table grade_outcomes_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        /// Adding keys to table grade_outcomes_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_outcomes_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_outcomes_history
        $result = $result && create_table($table);
        /// Define table grade_categories_history to be created
        $table = new XMLDBTable('grade_categories_history');
        /// Adding fields to table grade_categories_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_categories_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_categories', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_categories_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_categories_history
        $result = $result && create_table($table);
        /// Define table grade_items_history to be created
        $table = new XMLDBTable('grade_items_history');
        /// Adding fields to table grade_items_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
        $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
        $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
        $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('aggregationcoef', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_items_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_items', array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
        $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_items_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_items_history
        $result = $result && create_table($table);
        /// Define table grade_grades_history to be created
        $table = new XMLDBTable('grade_grades_history');
        /// Adding fields to table grade_grades_history
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
        $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        /// Adding keys to table grade_grades_history
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades', array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
        $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
        /// Adding indexes to table grade_grades_history
        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
        /// Launch create table for grade_grades_history
        $result = $result && create_table($table);
        /// upgrade the old 1.8 gradebook - migrade data into new grade tables
        if ($result) {
            require_once $CFG->libdir . '/db/upgradelib.php';
            if ($rs = get_recordset('course')) {
                while ($course = rs_fetch_next_record($rs)) {
                    // this function uses SQL only, it must not be changed after 1.9 goes stable!!
                    if (!upgrade_18_gradebook($course->id)) {
                        $result = false;
                        break;
                    }
                }
                rs_close($rs);
            }
        }
        upgrade_main_savepoint($result, 2007072200);
    }
    if ($result && $oldversion < 2007072400) {
        /// Dropping one DEFAULT in a TEXT column. It's was only one remaining
        /// since Moodle 1.7, so new servers won't have those anymore.
        /// Changing the default of field sessdata on table sessions2 to drop it
        $table = new XMLDBTable('sessions2');
        $field = new XMLDBField('sessdata');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, null, null, null, null, null, 'modified');
        /// Launch change of default for field sessdata
        $result = $result && change_field_default($table, $field);
        upgrade_main_savepoint($result, 2007072400);
    }
    if ($result && $oldversion < 2007073100) {
        /// Define table grade_outcomes_courses to be created
        $table = new XMLDBTable('grade_outcomes_courses');
        /// Adding fields to table grade_outcomes_courses
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_outcomes_courses
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
        $table->addKeyInfo('courseid-outcomeid', XMLDB_KEY_UNIQUE, array('courseid', 'outcomeid'));
        /// Launch create table for grade_outcomes_courses
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007073100);
    }
    if ($result && $oldversion < 2007073101) {
        // Add new tag tables
        /// Define table tag to be created
        $table = new XMLDBTable('tag');
        /// Adding fields to table tag
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '11', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('tagtype', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        $table->addFieldInfo('descriptionformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('flag', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, null, null, null, null, '0');
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table tag
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag
        $table->addIndexInfo('name', XMLDB_INDEX_UNIQUE, array('name'));
        /// Launch create table for tag
        $result = $result && create_table($table);
        /// Define table tag_correlation to be created
        $table = new XMLDBTable('tag_correlation');
        /// Adding fields to table tag_correlation
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '11', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('tagid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('correlatedtags', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table tag_correlation
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag_correlation
        $table->addIndexInfo('tagid', XMLDB_INDEX_UNIQUE, array('tagid'));
        /// Launch create table for tag_correlation
        $result = $result && create_table($table);
        /// Define table tag_instance to be created
        $table = new XMLDBTable('tag_instance');
        /// Adding fields to table tag_instance
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '11', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('tagid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '11', null, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table tag_instance
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Adding indexes to table tag_instance
        $table->addIndexInfo('tagiditem', XMLDB_INDEX_NOTUNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch create table for tag_instance
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007073101);
    }
    if ($result && $oldversion < 2007073103) {
        /// Define field rawname to be added to tag
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('rawname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'name');
        /// Launch add field rawname
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007073103);
    }
    if ($result && $oldversion < 2007073105) {
        /// Define field description to be added to grade_outcomes
        $table = new XMLDBTable('grade_outcomes');
        $field = new XMLDBField('description');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'scaleid');
            /// Launch add field description
            $result = $result && add_field($table, $field);
        }
        $table = new XMLDBTable('grade_outcomes_history');
        $field = new XMLDBField('description');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'scaleid');
            /// Launch add field description
            $result = $result && add_field($table, $field);
        }
        upgrade_main_savepoint($result, 2007073105);
    }
    // adding unique contraint on (courseid,shortname) of an outcome
    if ($result && $oldversion < 2007080100) {
        /// Define key courseid-shortname (unique) to be added to grade_outcomes
        $table = new XMLDBTable('grade_outcomes');
        $key = new XMLDBKey('courseid-shortname');
        $key->setAttributes(XMLDB_KEY_UNIQUE, array('courseid', 'shortname'));
        /// Launch add key courseid-shortname
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007080100);
    }
    /// originally there was supportname and supportemail upgrade code - this is handled in upgradesettings.php instead
    if ($result && $oldversion < 2007080202) {
        /// Define index tagiditem (not unique) to be dropped form tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch drop index tagiditem
        drop_index($table, $index);
        /// Define index tagiditem (unique) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch add index tagiditem
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007080202);
    }
    if ($result && $oldversion < 2007080300) {
        /// Define field aggregateoutcomes to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregateoutcomes');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
            /// Launch add field aggregateoutcomes
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateoutcomes to be added to grade_categories
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregateoutcomes');
        if (!field_exists($table, $field)) {
            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
            /// Launch add field aggregateoutcomes
            $result = $result && add_field($table, $field);
        }
        upgrade_main_savepoint($result, 2007080300);
    }
    if ($result && $oldversion < 2007080800) {
        /// Normalize course->shortname MDL-10026
        /// Changing precision of field shortname on table course to (100)
        $table = new XMLDBTable('course');
        $field = new XMLDBField('shortname');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, null, null, 'fullname');
        /// Launch change of precision for field shortname
        $result = $result && change_field_precision($table, $field);
        upgrade_main_savepoint($result, 2007080800);
    }
    if ($result && $oldversion < 2007080900) {
        /// Add context.path & index
        $table = new XMLDBTable('context');
        $field = new XMLDBField('path');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'instanceid');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('context');
        $index = new XMLDBIndex('path');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('path'));
        $result = $result && add_index($table, $index);
        /// Add context.depth
        $table = new XMLDBTable('context');
        $field = new XMLDBField('depth');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'path');
        $result = $result && add_field($table, $field);
        /// make sure the system context has proper data
        get_system_context(false);
        upgrade_main_savepoint($result, 2007080900);
    }
    if ($result && $oldversion < 2007080903) {
        /// Define index
        $table = new XMLDBTable('grade_grades');
        $index = new XMLDBIndex('locked-locktime');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        /// Define index
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('locked-locktime');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('locked', 'locktime'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        /// Define index itemtype-needsupdate (not unique) to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('itemtype-needsupdate');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('itemtype', 'needsupdate'));
        if (!index_exists($table, $index)) {
            /// Launch add index itemtype-needsupdate
            $result = $result && add_index($table, $index);
        }
        /// Define index
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('gradetype');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('gradetype'));
        if (!index_exists($table, $index)) {
            /// Launch add index
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007080903);
    }
    if ($result && $oldversion < 2007081000) {
        require_once $CFG->dirroot . '/question/upgrade.php';
        $result = $result && question_upgrade_context_etc();
        upgrade_main_savepoint($result, 2007081000);
    }
    if ($result && $oldversion < 2007081302) {
        require_once $CFG->libdir . '/db/upgradelib.php';
        if (table_exists(new XMLDBTable('groups_groupings'))) {
            /// IF 'groups_groupings' table exists, this is for 1.8.* only.
            $result = $result && upgrade_18_groups();
        } else {
            /// ELSE, 1.7.*/1.6.*/1.5.* - create 'groupings' and 'groupings_groups' + rename password to enrolmentkey
            $result = $result && upgrade_17_groups();
        }
        /// For both 1.8.* and 1.7.*/1.6.*..
        // delete not used fields
        $table = new XMLDBTable('groups');
        $field = new XMLDBField('theme');
        if (field_exists($table, $field)) {
            drop_field($table, $field);
        }
        $table = new XMLDBTable('groups');
        $field = new XMLDBField('lang');
        if (field_exists($table, $field)) {
            drop_field($table, $field);
        }
        /// Add groupingid field/f.key to 'course' table.
        $table = new XMLDBTable('course');
        $field = new XMLDBField('defaultgroupingid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupmodeforce');
        $result = $result && add_field($table, $field);
        /// Add grouping ID, grouponly field/f.key to 'course_modules' table.
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('groupingid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupmode');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('course_modules');
        $field = new XMLDBField('groupmembersonly');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', $prev = 'groupingid');
        $result = $result && add_field($table, $field);
        $table = new XMLDBTable('course_modules');
        $key = new XMLDBKey('groupingid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007081302);
    }
    if ($result && $oldversion < 2007082300) {
        /// Define field ordering to be added to tag_instance table
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('ordering');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'itemid');
        /// Launch add field rawname
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007082300);
    }
    if ($result && $oldversion < 2007082700) {
        /// Define field timemodified to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('timemodified');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'ordering');
        /// Launch add field timemodified
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007082700);
    }
    /// migrate all tags table to tag - this code MUST use SQL only,
    /// because if the db structure changes the library functions will fail in future
    if ($result && $oldversion < 2007082701) {
        $tagrefs = array();
        // $tagrefs[$oldtagid] = $newtagid
        if ($rs = get_recordset('tags')) {
            $db->debug = false;
            while ($oldtag = rs_fetch_next_record($rs)) {
                $raw_normalized = clean_param($oldtag->text, PARAM_TAG);
                $normalized = moodle_strtolower($raw_normalized);
                // if this tag does not exist in tag table yet
                if (!($newtag = get_record('tag', 'name', $normalized, '', '', '', '', 'id'))) {
                    $itag = new object();
                    $itag->name = $normalized;
                    $itag->rawname = $raw_normalized;
                    $itag->userid = $oldtag->userid;
                    $itag->timemodified = time();
                    $itag->descriptionformat = 0;
                    // default format
                    if ($oldtag->type == 'official') {
                        $itag->tagtype = 'official';
                    } else {
                        $itag->tagtype = 'default';
                    }
                    if ($idx = insert_record('tag', $itag)) {
                        $tagrefs[$oldtag->id] = $idx;
                    }
                    // if this tag is already used by tag table
                } else {
                    $tagrefs[$oldtag->id] = $newtag->id;
                }
            }
            $db->debug = true;
            rs_close($rs);
        }
        // fetch all the tag instances and migrate them as well
        if ($rs = get_recordset('blog_tag_instance')) {
            $db->debug = false;
            while ($blogtag = rs_fetch_next_record($rs)) {
                if (array_key_exists($blogtag->tagid, $tagrefs)) {
                    $tag_instance = new object();
                    $tag_instance->tagid = $tagrefs[$blogtag->tagid];
                    $tag_instance->itemtype = 'blog';
                    $tag_instance->itemid = $blogtag->entryid;
                    $tag_instance->ordering = 1;
                    // does not matter much, because originally there was no ordering in blogs
                    $tag_instance->timemodified = time();
                    insert_record('tag_instance', $tag_instance);
                }
            }
            $db->debug = true;
            rs_close($rs);
        }
        unset($tagrefs);
        // release memory
        $table = new XMLDBTable('tags');
        drop_table($table);
        $table = new XMLDBTable('blog_tag_instance');
        drop_table($table);
        upgrade_main_savepoint($result, 2007082701);
    }
    /// MDL-11015, MDL-11016
    if ($result && $oldversion < 2007082800) {
        /// Changing type of field userid on table tag to int
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('userid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field userid
        $result = $result && change_field_type($table, $field);
        /// Changing type of field descriptionformat on table tag to int
        $table = new XMLDBTable('tag');
        $field = new XMLDBField('descriptionformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'description');
        /// Launch change of type for field descriptionformat
        $result = $result && change_field_type($table, $field);
        /// Define key userid (foreign) to be added to tag
        $table = new XMLDBTable('tag');
        $key = new XMLDBKey('userid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Launch add key userid
        $result = $result && add_key($table, $key);
        /// Define index tagiditem (unique) to be dropped form tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('tagiditem');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid', 'itemtype', 'itemid'));
        /// Launch drop index tagiditem
        $result = $result && drop_index($table, $index);
        /// Changing type of field tagid on table tag_instance to int
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('tagid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field tagid
        $result = $result && change_field_type($table, $field);
        /// Define key tagid (foreign) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $key = new XMLDBKey('tagid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('tagid'), 'tag', array('id'));
        /// Launch add key tagid
        $result = $result && add_key($table, $key);
        /// Changing sign of field itemid on table tag_instance to unsigned
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('itemid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'itemtype');
        /// Launch change of sign for field itemid
        $result = $result && change_field_unsigned($table, $field);
        /// Changing sign of field ordering on table tag_instance to unsigned
        $table = new XMLDBTable('tag_instance');
        $field = new XMLDBField('ordering');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null, 'itemid');
        /// Launch change of sign for field ordering
        $result = $result && change_field_unsigned($table, $field);
        /// Define index itemtype-itemid-tagid (unique) to be added to tag_instance
        $table = new XMLDBTable('tag_instance');
        $index = new XMLDBIndex('itemtype-itemid-tagid');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid'));
        /// Launch add index itemtype-itemid-tagid
        $result = $result && add_index($table, $index);
        /// Define index tagid (unique) to be dropped form tag_correlation
        $table = new XMLDBTable('tag_correlation');
        $index = new XMLDBIndex('tagid');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('tagid'));
        /// Launch drop index tagid
        $result = $result && drop_index($table, $index);
        /// Changing type of field tagid on table tag_correlation to int
        $table = new XMLDBTable('tag_correlation');
        $field = new XMLDBField('tagid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null, 'id');
        /// Launch change of type for field tagid
        $result = $result && change_field_type($table, $field);
        /// Define key tagid (foreign) to be added to tag_correlation
        $table = new XMLDBTable('tag_correlation');
        $key = new XMLDBKey('tagid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('tagid'), 'tag', array('id'));
        /// Launch add key tagid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007082800);
    }
    if ($result && $oldversion < 2007082801) {
        /// Define table user_private_key to be created
        $table = new XMLDBTable('user_private_key');
        /// Adding fields to table user_private_key
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('script', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('value', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('iprestriction', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->addFieldInfo('validuntil', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table user_private_key
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
        /// Adding indexes to table user_private_key
        $table->addIndexInfo('script-value', XMLDB_INDEX_NOTUNIQUE, array('script', 'value'));
        /// Launch create table for user_private_key
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007082801);
    }
    /// Going to modify the applicationid from int(1) to int(10). Dropping and
    /// re-creating the associated keys/indexes is mandatory to be cross-db. MDL-11042
    if ($result && $oldversion < 2007082803) {
        /// Define key applicationid (foreign) to be dropped form mnet_host
        $table = new XMLDBTable('mnet_host');
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch drop key applicationid
        $result = $result && drop_key($table, $key);
        /// Changing type of field applicationid on table mnet_host to int
        $field = new XMLDBField('applicationid');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'last_log_id');
        /// Launch change of type for field applicationid
        $result = $result && change_field_type($table, $field);
        /// Define key applicationid (foreign) to be added to mnet_host
        $key = new XMLDBKey('applicationid');
        $key->setAttributes(XMLDB_KEY_FOREIGN, array('applicationid'), 'mnet_application', array('id'));
        /// Launch add key applicationid
        $result = $result && add_key($table, $key);
        upgrade_main_savepoint($result, 2007082803);
    }
    if ($result && $oldversion < 2007090503) {
        /// Define field aggregatesubcats to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregatesubcats');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'aggregateoutcomes');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateonlygraded to be added to grade_categories
        $table = new XMLDBTable('grade_categories');
        $field = new XMLDBField('aggregateonlygraded');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregatesubcats to be added to grade_categories_history
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregatesubcats');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'aggregateoutcomes');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// Define field aggregateonlygraded to be added to grade_categories_history
        $table = new XMLDBTable('grade_categories_history');
        $field = new XMLDBField('aggregateonlygraded');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
        if (!field_exists($table, $field)) {
            /// Launch add field aggregateonlygraded
            $result = $result && add_field($table, $field);
        }
        /// upgrade path in grade_categrories table - now using slash on both ends
        $concat = sql_concat('path', "'/'");
        $sql = "UPDATE {$CFG->prefix}grade_categories SET path = {$concat} WHERE path NOT LIKE '/%/'";
        execute_sql($sql, true);
        /// convert old aggregation constants if needed
        for ($i = 0; $i <= 12; $i = $i + 2) {
            $j = $i + 1;
            $sql = "UPDATE {$CFG->prefix}grade_categories SET aggregation = {$i}, aggregateonlygraded = 1 WHERE aggregation = {$j}";
            execute_sql($sql, true);
        }
        upgrade_main_savepoint($result, 2007090503);
    }
    /// To have UNIQUE indexes over NULLable columns isn't cross-db at all
    /// so we create a non unique index and programatically enforce uniqueness
    if ($result && $oldversion < 2007090600) {
        /// Define index idnumber (unique) to be dropped form course_modules
        $table = new XMLDBTable('course_modules');
        $index = new XMLDBIndex('idnumber');
        $index->setAttributes(XMLDB_INDEX_UNIQUE, array('idnumber'));
        /// Launch drop index idnumber
        $result = $result && drop_index($table, $index);
        /// Define index idnumber-course (not unique) to be added to course_modules
        $table = new XMLDBTable('course_modules');
        $index = new XMLDBIndex('idnumber-course');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'course'));
        /// Launch add index idnumber-course
        $result = $result && add_index($table, $index);
        /// Define index idnumber-courseid (not unique) to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $index = new XMLDBIndex('idnumber-courseid');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'courseid'));
        /// Launch add index idnumber-courseid
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007090600);
    }
    /// Create the permanent context_temp table to be used by build_context_path()
    if ($result && $oldversion < 2007092001) {
        /// Define table context_temp to be created
        $table = new XMLDBTable('context_temp');
        /// Adding fields to table context_temp
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table context_temp
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /// Launch create table for context_temp
        $result = $result && create_table($table);
        /// make sure category depths, parents and paths are ok, categories from 1.5 may not be properly initialized (MDL-12585)
        upgrade_fix_category_depths();
        /// Recalculate depths, paths and so on
        if (!empty($CFG->rolesactive)) {
            cleanup_contexts();
            // make sure all course, category and user contexts exist - we need it for grade letter upgrade, etc.
            create_contexts(CONTEXT_COURSE, false, true);
            create_contexts(CONTEXT_USER, false, true);
            // we need all contexts path/depths filled properly
            build_context_path(true, true);
            load_all_capabilities();
        } else {
            // upgrade from 1.6 - build all contexts
            create_contexts(null, true, true);
        }
        upgrade_main_savepoint($result, 2007092001);
    }
    /**
     * Merging of grade_grades_text back into grade_grades
     */
    if ($result && $oldversion < 2007092002) {
        /// Define field feedback to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('feedback');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'excluded');
        if (!field_exists($table, $field)) {
            /// Launch add field feedback
            $result = $result && add_field($table, $field);
        }
        /// Define field feedbackformat to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('feedbackformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'feedback');
        if (!field_exists($table, $field)) {
            /// Launch add field feedbackformat
            $result = $result && add_field($table, $field);
        }
        /// Define field information to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('information');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'feedbackformat');
        if (!field_exists($table, $field)) {
            /// Launch add field information
            $result = $result && add_field($table, $field);
        }
        /// Define field informationformat to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $field = new XMLDBField('informationformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'information');
        if (!field_exists($table, $field)) {
            /// Launch add field informationformat
            $result = $result && add_field($table, $field);
        }
        /// Define field feedback to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('feedback');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'excluded');
        if (!field_exists($table, $field)) {
            /// Launch add field feedback
            $result = $result && add_field($table, $field);
        }
        /// Define field feedbackformat to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('feedbackformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'feedback');
        if (!field_exists($table, $field)) {
            /// Launch add field feedbackformat
            $result = $result && add_field($table, $field);
        }
        /// Define field information to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('information');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null, 'feedbackformat');
        if (!field_exists($table, $field)) {
            /// Launch add field information
            $result = $result && add_field($table, $field);
        }
        /// Define field informationformat to be added to grade_grades_history
        $table = new XMLDBTable('grade_grades_history');
        $field = new XMLDBField('informationformat');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'information');
        if (!field_exists($table, $field)) {
            /// Launch add field informationformat
            $result = $result && add_field($table, $field);
        }
        $table = new XMLDBTable('grade_grades_text');
        if ($result and table_exists($table)) {
            //migrade existing data into grade_grades table - this is slow but works for all dbs,
            //it will be executed on development sites only
            $fields = array('feedback', 'information');
            foreach ($fields as $field) {
                $sql = "UPDATE {$CFG->prefix}grade_grades\n                           SET {$field} = (\n                                SELECT {$field}\n                                  FROM {$CFG->prefix}grade_grades_text ggt\n                                 WHERE ggt.gradeid = {$CFG->prefix}grade_grades.id)";
                $result = execute_sql($sql) && $result;
            }
            $fields = array('feedbackformat', 'informationformat');
            foreach ($fields as $field) {
                $sql = "UPDATE {$CFG->prefix}grade_grades\n                           SET {$field} = COALESCE((\n                                SELECT {$field}\n                                  FROM {$CFG->prefix}grade_grades_text ggt\n                                 WHERE ggt.gradeid = {$CFG->prefix}grade_grades.id), 0)";
                $result = execute_sql($sql) && $result;
            }
            if ($result) {
                $tables = array('grade_grades_text', 'grade_grades_text_history');
                foreach ($tables as $table) {
                    $table = new XMLDBTable($table);
                    if (table_exists($table)) {
                        drop_table($table);
                    }
                }
            }
        }
        upgrade_main_savepoint($result, 2007092002);
    }
    if ($result && $oldversion < 2007092803) {
        /// Remove obsoleted unit tests tables - they will be recreated automatically
        $tables = array('grade_categories', 'scale', 'grade_items', 'grade_calculations', 'grade_grades', 'grade_grades_raw', 'grade_grades_final', 'grade_grades_text', 'grade_outcomes', 'grade_outcomes_courses');
        foreach ($tables as $tablename) {
            $table = new XMLDBTable('unittest_' . $tablename);
            if (table_exists($table)) {
                drop_table($table);
            }
            $table = new XMLDBTable('unittest_' . $tablename . '_history');
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        /// Define field display to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $field = new XMLDBField('display');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'sortorder');
        /// Launch add field display
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        } else {
            $result = $result && change_field_default($table, $field);
        }
        /// Define field display to be added to grade_items_history
        $table = new XMLDBTable('grade_items_history');
        $field = new XMLDBField('display');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0', 'sortorder');
        /// Launch add field display
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
        /// Define field decimals to be added to grade_items
        $table = new XMLDBTable('grade_items');
        $field = new XMLDBField('decimals');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null, 'display');
        /// Launch add field decimals
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        } else {
            $result = $result && change_field_default($table, $field);
            $result = $result && change_field_notnull($table, $field);
        }
        /// Define field decimals to be added to grade_items_history
        $table = new XMLDBTable('grade_items_history');
        $field = new XMLDBField('decimals');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null, 'display');
        /// Launch add field decimals
        if (!field_exists($table, $field)) {
            $result = $result && add_field($table, $field);
        }
        /// fix incorrect -1 default for grade_item->display
        execute_sql("UPDATE {$CFG->prefix}grade_items SET display=0 WHERE display=-1");
        upgrade_main_savepoint($result, 2007092803);
    }
    /// migrade grade letters - we can not do this in normal grades upgrade becuase we need all course contexts
    if ($result && $oldversion < 2007092806) {
        require_once $CFG->libdir . '/db/upgradelib.php';
        $result = upgrade_18_letters();
        /// Define index contextidlowerboundary (not unique) to be added to grade_letters
        $table = new XMLDBTable('grade_letters');
        $index = new XMLDBIndex('contextid-lowerboundary');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid', 'lowerboundary'));
        /// Launch add index contextidlowerboundary
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007092806);
    }
    if ($result && $oldversion < 2007100100) {
        /// Define table cache_flags to be created
        $table = new XMLDBTable('cache_flags');
        /// Adding fields to table cache_flags
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('flagtype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
        $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('expiry', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table cache_flags
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        /*
         * Note: mysql can not create indexes on text fields larger than 333 chars! 
         */
        /// Adding indexes to table cache_flags
        $table->addIndexInfo('flagtype', XMLDB_INDEX_NOTUNIQUE, array('flagtype'));
        $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name'));
        /// Launch create table for cache_flags
        if (!table_exists($table)) {
            $result = $result && create_table($table);
        }
        upgrade_main_savepoint($result, 2007100100);
    }
    if ($oldversion < 2007100300) {
        /// MNET stuff for roaming theme
        /// Define field force_theme to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('force_theme');
        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'last_log_id');
        /// Launch add field force_theme
        $result = $result && add_field($table, $field);
        /// Define field theme to be added to mnet_host
        $table = new XMLDBTable('mnet_host');
        $field = new XMLDBField('theme');
        $field->setAttributes(XMLDB_TYPE_CHAR, '100', null, null, null, null, null, null, 'force_theme');
        /// Launch add field theme
        $result = $result && add_field($table, $field);
        upgrade_main_savepoint($result, 2007100300);
    }
    if ($result && $oldversion < 2007100301) {
        /// Define table cache_flags to be created
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('typename');
        if (index_exists($table, $index)) {
            $result = $result && drop_index($table, $index);
        }
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('flagtype');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('flagtype'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        $table = new XMLDBTable('cache_flags');
        $index = new XMLDBIndex('name');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name'));
        if (!index_exists($table, $index)) {
            $result = $result && add_index($table, $index);
        }
        upgrade_main_savepoint($result, 2007100301);
    }
    if ($result && $oldversion < 2007100303) {
        /// Changing nullability of field summary on table course to null
        $table = new XMLDBTable('course');
        $field = new XMLDBField('summary');
        $field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'idnumber');
        /// Launch change of nullability for field summary
        $result = $result && change_field_notnull($table, $field);
        upgrade_main_savepoint($result, 2007100303);
    }
    if ($result && $oldversion < 2007100500) {
        /// for dev sites - it is ok to do this repeatedly
        /// Changing nullability of field path on table context to null
        $table = new XMLDBTable('context');
        $field = new XMLDBField('path');
        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null, 'instanceid');
        /// Launch change of nullability for field path
        $result = $result && change_field_notnull($table, $field);
        upgrade_main_savepoint($result, 2007100500);
    }
    if ($result && $oldversion < 2007100700) {
        /// first drop existing tables - we do not need any data from there
        $table = new XMLDBTable('grade_import_values');
        if (table_exists($table)) {
            drop_table($table);
        }
        $table = new XMLDBTable('grade_import_newitem');
        if (table_exists($table)) {
            drop_table($table);
        }
        /// Define table grade_import_newitem to be created
        $table = new XMLDBTable('grade_import_newitem');
        /// Adding fields to table grade_import_newitem
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importcode', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importer', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        /// Adding keys to table grade_import_newitem
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('importer', XMLDB_KEY_FOREIGN, array('importer'), 'user', array('id'));
        /// Launch create table for grade_import_newitem
        $result = $result && create_table($table);
        /// Define table grade_import_values to be created
        $table = new XMLDBTable('grade_import_values');
        /// Adding fields to table grade_import_values
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('newgradeitem', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
        $table->addFieldInfo('importcode', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('importer', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
        /// Adding keys to table grade_import_values
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
        $table->addKeyInfo('newgradeitem', XMLDB_KEY_FOREIGN, array('newgradeitem'), 'grade_import_newitem', array('id'));
        $table->addKeyInfo('importer', XMLDB_KEY_FOREIGN, array('importer'), 'user', array('id'));
        /// Launch create table for grade_import_values
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007100700);
    }
    /// dropping context_rel table - not used anymore
    if ($result && $oldversion < 2007100800) {
        /// Define table context_rel to be dropped
        $table = new XMLDBTable('context_rel');
        /// Launch drop table for context_rel
        if (table_exists($table)) {
            drop_table($table);
        }
        upgrade_main_savepoint($result, 2007100800);
    }
    /// Truncate the text_cahe table and add new index
    if ($result && $oldversion < 2007100802) {
        /// Truncate the cache_text table
        execute_sql("TRUNCATE TABLE {$CFG->prefix}cache_text", true);
        /// Define index timemodified (not unique) to be added to cache_text
        $table = new XMLDBTable('cache_text');
        $index = new XMLDBIndex('timemodified');
        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
        /// Launch add index timemodified
        $result = $result && add_index($table, $index);
        upgrade_main_savepoint($result, 2007100802);
    }
    /// newtable for gradebook settings per course
    if ($result && $oldversion < 2007100803) {
        /// Define table grade_settings to be created
        $table = new XMLDBTable('grade_settings');
        /// Adding fields to table grade_settings
        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
        $table->addFieldInfo('value', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
        /// Adding keys to table grade_settings
        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        /// Adding indexes to table grade_settings
        $table->addIndexInfo('courseid-name', XMLDB_INDEX_UNIQUE, array('courseid', 'name'));
        /// Launch create table for grade_settings
        $result = $result && create_table($table);
        upgrade_main_savepoint($result, 2007100803);
    }
    /// cleanup in user_lastaccess
    if ($result && $oldversion < 2007100902) {
        $sql = "DELETE\n                  FROM {$CFG->prefix}user_lastaccess\n                 WHERE NOT EXISTS (SELECT 'x'\n                                    FROM {$CFG->prefix}course c\n                                   WHERE c.id = {$CFG->prefix}user_lastaccess.courseid)";
        execute_sql($sql);
        upgrade_main_savepoint($result, 2007100902);
    }
    /// drop old gradebook tables
    if ($result && $oldversion < 2007100903) {
        $tables = array('grade_category', 'grade_item', 'grade_letter', 'grade_preferences', 'grade_exceptions');
        foreach ($tables as $table) {
            $table = new XMLDBTable($table);
            if (table_exists($table)) {
                drop_table($table);
            }
        }
        upgrade_main_savepoint($result, 2007100903);
    }
    if ($result && $oldversion < 2007101500 && !file_exists($CFG->dataroot . '/user')) {
        // Get list of users by browsing moodledata/user
        $oldusersdir = $CFG->dataroot . '/users';
        $folders = get_directory_list($oldusersdir, '', false, true, false);
        foreach ($folders as $userid) {
            $olddir = $oldusersdir . '/' . $userid;
            $files = get_directory_list($olddir);
            if (empty($files)) {
                continue;
            }
            // Create new user directory
            if (!($newdir = make_user_directory($userid))) {
                $result = false;
                break;
            }
            // Move contents of old directory to new one
            if (file_exists($olddir) && file_exists($newdir)) {
                foreach ($files as $file) {
                    copy($olddir . '/' . $file, $newdir . '/' . $file);
                }
            } else {
                notify("Could not move the contents of {$olddir} into {$newdir}!");
                $result = false;
                break;
            }
        }
        // Leave a README in old users directory
        $readmefilename = $oldusersdir . '/README.txt';
        if ($handle = fopen($readmefilename, 'w+b')) {
            if (!fwrite($handle, get_string('olduserdirectory'))) {
                // Could not write to the readme file. No cause for huge concern
                notify("Could not write to the README.txt file in {$readmefilename}.");
            }
            fclose($handle);
        } else {
            // Could not create the readme file. No cause for huge concern
            notify("Could not create the README.txt file in {$readmefilename}.");
        }
    }
    if ($result && $oldversion < 2007101502) {
        /// try to remove duplicate entries
        $SQL = "SELECT userid, itemid, COUNT(*)\n               FROM {$CFG->prefix}grade_grades\n               GROUP BY userid, itemid\n               HAVING COUNT( * ) >1";
        // duplicates found
        if ($rs = get_recordset_sql($SQL)) {
            if ($rs && $rs->RecordCount() > 0) {
                while ($dup = rs_fetch_next_record($rs)) {
                    if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades \n                                                    WHERE itemid = {$dup->itemid} AND userid = {$dup->userid}\n                                                    ORDER BY timemodified DESC")) {
                        $processed = 0;
                        // keep the first one
                        foreach ($thisdups as $thisdup) {
                            if ($processed) {
                                // remove the duplicates
                                delete_records('grade_grades', 'id', $thisdup->id);
                            }
                            $processed++;
                        }
                    }
                }
                rs_close($rs);
            }
        }
        /// Define key userid-itemid (unique) to be added to grade_grades
        $table = new XMLDBTable('grade_grades');
        $key = new XMLDBKey('userid-itemid');
        $key->setAttributes(XMLDB_KEY_UNIQUE, array('userid', 'itemid'));
        /// Launch add key userid-itemid
        $result = $result && add_key($table, $key);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101502);
    }
    if ($result && $oldversion < 2007101505) {
        /// Changing precision of field dst_time on table timezone to (6)
        $table = new XMLDBTable('timezone');
        $field = new XMLDBField('dst_time');
        $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'dst_skipweeks');
        /// Launch change of precision for field dst_time
        $result = $result && change_field_precision($table, $field);
        /// Changing precision of field std_time on table timezone to (6)
        $table = new XMLDBTable('timezone');
        $field = new XMLDBField('std_time');
        $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'std_skipweeks');
        /// Launch change of precision for field std_time
        $result = $result && change_field_precision($table, $field);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101505);
    }
    if ($result && $oldversion < 2007101506) {
        /// CONTEXT_PERSONAL was never implemented - removing
        $sql = "DELETE\n                  FROM {$CFG->prefix}context\n                 WHERE contextlevel=20";
        execute_sql($sql);
        /// Main savepoint reached
        upgrade_main_savepoint($result, 2007101506);
    }
    return $result;
}
Example #28
0
File: lib.php Project: r007/PMoodle
/** 
 * Clean up the tag tables, making sure all tagged object still exists.
 *
 * This should normally not be necessary, but in case related tags are not deleted
 * when the tagged record is removed, this should be done once in a while, perhaps on
 * an occasional cron run.  On a site with lots of tags, this could become an expensive 
 * function to call: don't run at peak time.
 */
function tag_cleanup()
{
    global $CFG;
    $instances = get_recordset('tag_instance');
    // cleanup tag instances
    while ($instance = rs_fetch_next_record($instances)) {
        $delete = false;
        if (!record_exists('tag', 'id', $instance->tagid)) {
            // if the tag has been removed, instance should be deleted.
            $delete = true;
        } else {
            switch ($instance->itemtype) {
                case 'user':
                    // users are marked as deleted, but not actually deleted
                    if (record_exists('user', 'id', $instance->itemid, 'deleted', 1)) {
                        $delete = true;
                    }
                    break;
                default:
                    // anything else, if the instance is not there, delete.
                    if (!record_exists($instance->itemtype, 'id', $instance->itemid)) {
                        $delete = true;
                    }
                    break;
            }
        }
        if ($delete) {
            tag_delete_instance($instance->itemtype, $instance->itemid, $instance->tagid);
            //debugging('deleting tag_instance #'. $instance->id .', linked to tag id #'. $instance->tagid, DEBUG_DEVELOPER);
        }
    }
    rs_close($instances);
    // TODO: this will only clean tags of type 'default'.  This is good as
    // it won't delete 'official' tags, but the day we get more than two
    // types, we need to fix this.
    $unused_tags = get_recordset_sql("SELECT tg.id FROM {$CFG->prefix}tag tg WHERE tg.tagtype = 'default' AND NOT EXISTS (" . "SELECT 'x' FROM {$CFG->prefix}tag_instance ti WHERE ti.tagid = tg.id)");
    // cleanup tags
    while ($unused_tag = rs_fetch_next_record($unused_tags)) {
        tag_delete($unused_tag->id);
        //debugging('deleting unused tag #'. $unused_tag->id,  DEBUG_DEVELOPER);
    }
    rs_close($unused_tags);
}
Example #29
0
/**
 * List of courses that a user has access to view. Note that for admins,
 * this usually includes every course on the system.
 *
 * @uses $CFG
 * @param int $userid The user of interest
 * @param string $sort the sortorder in the course table
 * @param string $fields  the fields to return
 * @param bool $doanything True if using the doanything flag
 * @param int $limit Maximum number of records to return, or 0 for unlimited
 * @return array {@link $COURSE} of course objects
 */
function get_my_courses($userid, $sort = NULL, $fields = NULL, $doanything = false, $limit = 0)
{
    global $CFG, $USER;
    // Default parameters
    $d_sort = 'visible DESC,sortorder ASC';
    $d_fields = 'id, category, sortorder, shortname, fullname, idnumber, newsitems, teacher, teachers, student, students, guest, startdate, visible, cost, enrol, summary, groupmode, groupmodeforce';
    $usingdefaults = true;
    if (is_null($sort) || $sort === $d_sort) {
        $sort = $d_sort;
    } else {
        $usingdefaults = false;
    }
    if (is_null($fields) || $fields === $d_fields) {
        $fields = $d_fields;
    } else {
        $usingdefaults = false;
    }
    $reallimit = 0;
    // this is only set if we are using a limit on the first call
    // If using default params, we may have it cached...
    if (!empty($USER->id) && $USER->id == $userid && $usingdefaults) {
        if (!empty($USER->mycourses[$doanything])) {
            if ($limit && $limit < count($USER->mycourses[$doanything])) {
                //silence warnings in PHP 4.x - the last param was added in PHP 5.0.2
                return @array_slice($USER->mycourses[$doanything], 0, $limit, true);
            } else {
                return $USER->mycourses[$doanything];
            }
        } else {
            // now, this is the first call, i.e. no cache, and we are using defaults, with a limit supplied,
            // we need to store the limit somewhere, retrieve all, cache properly and then slice the array
            // to return the proper number of entries. This is so that we don't keep missing calls like limit 20,20,20
            if ($limit) {
                $reallimit = $limit;
                $limit = 0;
            }
        }
    }
    $mycourses = array();
    // Fix fields to refer to the course table c
    $fields = preg_replace('/([a-z0-9*]+)/', 'c.$1', $fields);
    // Attempt to filter the list of courses in order to reduce the number
    // of queries in the next part.
    // Check root permissions
    $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
    // Guest's do not have any courses
    if (has_capability('moodle/legacy:guest', $sitecontext, $userid, false)) {
        return array();
    }
    // we can optimise some things for true admins
    $candoanything = false;
    if ($doanything && has_capability('moodle/site:doanything', $sitecontext, $userid, true)) {
        $candoanything = true;
    }
    if ($candoanything || has_capability('moodle/course:view', $sitecontext, $userid, $doanything)) {
        // User can view all courses, although there might be exceptions
        // which we will filter later.
        $rs = get_recordset('course c', '', '', $sort, $fields);
    } else {
        // The only other context level above courses that applies to moodle/course:view
        // is category. So we consider:
        // 1. All courses in which the user is assigned a role
        // 2. All courses in categories in which the user is assigned a role
        // 2BIS. All courses in subcategories in which the user gets assignment because he is assigned in one of its ascendant categories
        // 3. All courses which have overrides for moodle/course:view
        // Remember that this is just a filter. We check each individual course later.
        // However for a typical student on a large system this can reduce the
        // number of courses considered from around 2,000 to around 2, with corresponding
        // reduction in the number of queries needed.
        $rs = get_recordset_sql("\n            SELECT {$fields}\n            FROM {$CFG->prefix}course c, (\n                SELECT\n                    c.id\n                FROM\n                    {$CFG->prefix}role_assignments ra\n                    INNER JOIN {$CFG->prefix}context x ON x.id         = ra.contextid\n                    INNER JOIN {$CFG->prefix}course c  ON x.instanceid = c.id\n                WHERE\n                    ra.userid      = {$userid} AND\n                    x.contextlevel = 50\n                UNION\n                SELECT\n                    c.id\n                FROM\n                    {$CFG->prefix}role_assignments ra\n                    INNER JOIN {$CFG->prefix}context x ON x.id = ra.contextid\n                    INNER JOIN {$CFG->prefix}course_categories a ON a.path LIKE " . sql_concat("'%/'", 'x.instanceid', "'/%'") . " OR x.instanceid = a.id\n                    INNER JOIN {$CFG->prefix}course c ON c.category = a.id\n                WHERE\n                    ra.userid = {$userid} AND\n                    x.contextlevel = 40\n                UNION\n                SELECT\n                    c.id\n                FROM\n                    {$CFG->prefix}role_capabilities ca\n                    INNER JOIN {$CFG->prefix}context x ON x.id = ca.contextid\n                    INNER JOIN {$CFG->prefix}course c  ON c.id = x.instanceid\n                WHERE\n                    ca.capability  = 'moodle/course:view' AND\n                    ca.contextid  != {$sitecontext->id} AND\n                    x.contextlevel = 50\n            ) cids\n            WHERE c.id = cids.id\n            ORDER BY {$sort}");
    }
    if ($rs && $rs->RecordCount() > 0) {
        while ($course = rs_fetch_next_record($rs)) {
            if ($course->id != SITEID) {
                if ($candoanything) {
                    // no need for further checks...
                    $mycourses[$course->id] = $course;
                    continue;
                }
                // users with moodle/course:view are considered course participants
                // the course needs to be visible, or user must have moodle/course:viewhiddencourses
                // capability set to view hidden courses
                $context = get_context_instance(CONTEXT_COURSE, $course->id);
                if (has_capability('moodle/course:view', $context, $userid, $doanything) && !has_capability('moodle/legacy:guest', $context, $userid, false) && ($course->visible || has_capability('moodle/course:viewhiddencourses', $context, $USER->id))) {
                    $mycourses[$course->id] = $course;
                    // Only return a limited number of courses if limit is set
                    if ($limit > 0) {
                        $limit--;
                        if ($limit == 0) {
                            break;
                        }
                    }
                }
            }
        }
    }
    // Cache if using default params...
    if (!empty($USER->id) && $USER->id == $userid && $usingdefaults && $limit == 0) {
        $USER->mycourses[$doanything] = $mycourses;
    }
    if (!empty($mycourses) && $reallimit) {
        //silence warnings in PHP 4.x - the last param was added in PHP 5.0.2
        return @array_slice($mycourses, 0, $reallimit, true);
    } else {
        return $mycourses;
    }
}