public function test_reorder_rows()
 {
     global $DB;
     $dbman = $DB->get_manager();
     $this->resetAfterTest();
     $table = new xmldb_table('test_table');
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $tablename = $table->getName();
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('otherid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('otherdata', XMLDB_TYPE_TEXT, 'big', null, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('unique', XMLDB_KEY_UNIQUE, array('otherid', 'sortorder'));
     $dbman->create_table($table);
     // Rows intentionally added in a slightly 'random' order.
     // Note we are testing hat the otherid = 1 rows don't get messed up,
     // as well as testing that the otherid = 2 rows are updated correctly.
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 1, 'otherdata' => 'To become 4'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 2, 'otherdata' => 'To become 1'));
     $DB->insert_record($tablename, array('otherid' => 1, 'sortorder' => 1, 'otherdata' => 'Other 1'));
     $DB->insert_record($tablename, array('otherid' => 1, 'sortorder' => 2, 'otherdata' => 'Other 2'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 3, 'otherdata' => 'To stay at 3'));
     $DB->insert_record($tablename, array('otherid' => 2, 'sortorder' => 4, 'otherdata' => 'To become 2'));
     update_field_with_unique_index($tablename, 'sortorder', array(1 => 4, 2 => 1, 3 => 3, 4 => 2), array('otherid' => 2));
     $this->assertEquals(array(3 => (object) array('id' => 3, 'otherid' => 1, 'sortorder' => 1, 'otherdata' => 'Other 1'), 4 => (object) array('id' => 4, 'otherid' => 1, 'sortorder' => 2, 'otherdata' => 'Other 2')), $DB->get_records($tablename, array('otherid' => 1), 'sortorder'));
     $this->assertEquals(array(2 => (object) array('id' => 2, 'otherid' => 2, 'sortorder' => 1, 'otherdata' => 'To become 1'), 6 => (object) array('id' => 6, 'otherid' => 2, 'sortorder' => 2, 'otherdata' => 'To become 2'), 5 => (object) array('id' => 5, 'otherid' => 2, 'sortorder' => 3, 'otherdata' => 'To stay at 3'), 1 => (object) array('id' => 1, 'otherid' => 2, 'sortorder' => 4, 'otherdata' => 'To become 4')), $DB->get_records($tablename, array('otherid' => 2), 'sortorder'));
 }
Exemplo n.º 2
0
 /**
  * Get a xmldb_table object for testing, deleting any existing table
  * of the same name, for example if one was left over from a previous test
  * run that crashed.
  *
  * @param string $suffix table name suffix, use if you need more test tables
  * @return xmldb_table the table object.
  */
 private function get_test_table($suffix = '')
 {
     $tablename = "test_table";
     if ($suffix !== '') {
         $tablename .= $suffix;
     }
     $table = new xmldb_table($tablename);
     $table->setComment("This is a test'n drop table. You can drop it safely");
     return new xmldb_table($tablename);
 }
Exemplo n.º 3
0
 public function setUp()
 {
     global $CFG, $DB, $UNITTEST;
     if (isset($UNITTEST->func_test_db)) {
         $this->tdb = $UNITTEST->func_test_db;
     } else {
         $this->tdb = $DB;
     }
     unset($CFG->xmldbreconstructprevnext);
     // remove this unhack ;-)
     $dbman = $this->tdb->get_manager();
     $table = new xmldb_table('test_table0');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general');
     $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null);
     $table->add_field('intro', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null);
     $table->add_field('logo', XMLDB_TYPE_BINARY, 'big', null, XMLDB_NOTNULL, null);
     $table->add_field('assessed', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('assesstimestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('assesstimefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('scale', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('maxbytes', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('forcesubscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('trackingtype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1');
     $table->add_field('rsstype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('rssarticles', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('grade', XMLDB_TYPE_NUMBER, '20,0', XMLDB_UNSIGNED, null, null, null);
     $table->add_field('percent', XMLDB_TYPE_NUMBER, '5,2', null, null, null, null);
     $table->add_field('warnafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('blockafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('blockperiod', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('type-name', XMLDB_KEY_UNIQUE, array('type', 'name'));
     $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
     $table->add_index('rsstype', XMLDB_INDEX_UNIQUE, array('rsstype'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     // Second, smaller table
     $table = new xmldb_table('test_table1');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('name', XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
     $table->add_field('secondname', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null);
     $table->add_field('intro', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null);
     $table->add_field('avatar', XMLDB_TYPE_BINARY, 'medium', null, null, null, null);
     $table->add_field('grade', XMLDB_TYPE_NUMBER, '20,10', null, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     // make sure no tables are present!
     $this->tearDown();
 }
Exemplo n.º 4
0
/**
 *
 * @global stdClass $CFG
 * @global moodle_database $DB
 * @global core_renderer $OUTPUT
 * @param int $oldversion
 * @return bool
 */
function xmldb_lesson_upgrade($oldversion)
{
    global $CFG, $DB, $OUTPUT;
    $dbman = $DB->get_manager();
    // Moodle v2.2.0 release upgrade line
    // Put any upgrade step following this
    // Moodle v2.3.0 release upgrade line
    // Put any upgrade step following this
    // Moodle v2.4.0 release upgrade line
    // Put any upgrade step following this
    // Moodle v2.5.0 release upgrade line.
    // Put any upgrade step following this.
    // Moodle v2.6.0 release upgrade line.
    // Put any upgrade step following this.
    // Moodle v2.7.0 release upgrade line.
    // Put any upgrade step following this.
    //GWL : To Add a custom table visited_links
    if ($oldversion < 2014051201) {
        // create new table
        $table = new xmldb_table('lesson_visited_links');
        // Set up the comment.
        $table->setComment('To store visited lession links');
        // Adding fields to table facetoface_notification_hist
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->add_field('user_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('page_id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        // Adding keys to table facetoface_sessions_config
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('page_id', XMLDB_KEY_FOREIGN, array('page_id'), 'lesson_pages', array('id'));
        // Launch create table for facetoface_sessions_config
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }
        upgrade_mod_savepoint(true, 2014051201, 'lesson');
    }
    return true;
}
Exemplo n.º 5
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB, $DB, $OUTPUT;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     // Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir = $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir = $XMLDB->editeddirs[$dirpath];
         $structure = $editeddir->xml_file->getStructure();
     }
     $tableparam = optional_param('table', NULL, PARAM_CLEAN);
     // If no table, show form
     if (!$tableparam) {
         // No postaction here
         $this->postaction = NULL;
         // Get list of tables
         $dbtables = $DB->get_tables();
         $selecttables = array();
         foreach ($dbtables as $dbtable) {
             $i = $structure->findTableInArray($dbtable);
             if ($i === NULL) {
                 $selecttables[$dbtable] = $dbtable;
             }
         }
         // Get list of after tables
         $aftertables = array();
         if ($tables = $structure->getTables()) {
             foreach ($tables as $aftertable) {
                 $aftertables[$aftertable->getName()] = $aftertable->getName();
             }
         }
         if (!$selecttables) {
             $this->errormsg = 'No tables available to be retrofitted';
             return false;
         }
         // Now build the form
         $o = '<form id="form" action="index.php" method="post">';
         $o .= '<div>';
         $o .= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
         $o .= '    <input type="hidden" name ="action" value="new_table_from_mysql" />';
         $o .= '    <input type="hidden" name ="postaction" value="edit_table" />';
         $o .= '    <input type="hidden" name ="sesskey" value="' . sesskey() . '" />';
         $o .= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
         $o .= '      <tr><td><label for="menutable" accesskey="t">' . $this->str['createtable'] . ' </label>' . html_writer::select($selecttables, 'table') . '<label for="menuafter" accesskey="a">' . $this->str['aftertable'] . ' </label>' . html_writer::select($aftertables, 'after') . '</td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><input type="submit" value="' . $this->str['create'] . '" /></td></tr>';
         $o .= '      <tr><td colspan="2" align="center"><a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a></td></tr>';
         $o .= '    </table>';
         $o .= '</div></form>';
         $this->output = $o;
         // If table, retrofit information and, if everything works,
         // go to the table edit action
     } else {
         // Get some params (table is mandatory here)
         $tableparam = required_param('table', PARAM_CLEAN);
         $afterparam = required_param('after', PARAM_CLEAN);
         // Create one new xmldb_table
         $table = new xmldb_table(strtolower(trim($tableparam)));
         $table->setComment($table->getName() . ' table retrofitted from MySQL');
         // Get fields info from ADODb
         $dbfields = $DB->get_columns($tableparam);
         if ($dbfields) {
             foreach ($dbfields as $dbfield) {
                 // Create new XMLDB field
                 $field = new xmldb_field($dbfield->name);
                 // Set field with info retrofitted
                 $field->setFromADOField($dbfield);
                 // Add field to the table
                 $table->addField($field);
             }
         }
         // Get PK, UK and indexes info from ADODb
         $dbindexes = $DB->get_indexes($tableparam);
         if ($dbindexes) {
             $lastkey = NULL;
             //To temp store the last key processed
             foreach ($dbindexes as $indexname => $dbindex) {
                 // Add the indexname to the array
                 $dbindex['name'] = $indexname;
                 // We are handling one xmldb_key (primaries + uniques)
                 if ($dbindex['unique']) {
                     $key = new xmldb_key(strtolower($dbindex['name']));
                     // Set key with info retrofitted
                     $key->setFromADOKey($dbindex);
                     // Set default comment to PKs
                     if ($key->getType() == XMLDB_KEY_PRIMARY) {
                     }
                     // Add key to the table
                     $table->addKey($key);
                     // We are handling one xmldb_index (non-uniques)
                 } else {
                     $index = new xmldb_index(strtolower($dbindex['name']));
                     // Set index with info retrofitted
                     $index->setFromADOIndex($dbindex);
                     // Add index to the table
                     $table->addIndex($index);
                 }
             }
         }
         // Finally, add the whole retroffited table to the structure
         // in the place specified
         $structure->addTable($table, $afterparam);
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
Exemplo n.º 6
0
 /**
  * Test behaviour of create_table()
  */
 public function test_create_table()
 {
     $DB = $this->tdb;
     // Do not use global $DB!
     $dbman = $this->tdb->get_manager();
     // Create table.
     $table = $this->tables['test_table1'];
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     // Basic get_tables() test.
     $tables = $DB->get_tables();
     $this->assertArrayHasKey('test_table1', $tables);
     // Basic get_columns() tests.
     $columns = $DB->get_columns('test_table1');
     $this->assertSame('R', $columns['id']->meta_type);
     $this->assertSame('I', $columns['course']->meta_type);
     $this->assertSame('C', $columns['name']->meta_type);
     $this->assertSame('C', $columns['secondname']->meta_type);
     $this->assertSame('C', $columns['thirdname']->meta_type);
     $this->assertSame('X', $columns['intro']->meta_type);
     $this->assertSame('B', $columns['avatar']->meta_type);
     $this->assertSame('N', $columns['grade']->meta_type);
     $this->assertSame('N', $columns['percentfloat']->meta_type);
     $this->assertSame('I', $columns['userid']->meta_type);
     // Some defaults.
     $this->assertTrue($columns['course']->has_default);
     $this->assertEquals(0, $columns['course']->default_value);
     $this->assertTrue($columns['name']->has_default);
     $this->assertSame('Moodle', $columns['name']->default_value);
     $this->assertTrue($columns['secondname']->has_default);
     $this->assertSame('', $columns['secondname']->default_value);
     $this->assertTrue($columns['thirdname']->has_default);
     $this->assertSame('', $columns['thirdname']->default_value);
     $this->assertTrue($columns['percentfloat']->has_default);
     $this->assertEquals(99.90000000000001, $columns['percentfloat']->default_value);
     $this->assertTrue($columns['userid']->has_default);
     $this->assertEquals(0, $columns['userid']->default_value);
     // Basic get_indexes() test.
     $indexes = $DB->get_indexes('test_table1');
     $courseindex = reset($indexes);
     $this->assertEquals(1, $courseindex['unique']);
     $this->assertSame('course', $courseindex['columns'][0]);
     // Check sequence returns 1 for first insert.
     $rec = (object) array('course' => 10, 'secondname' => 'not important', 'intro' => 'not important');
     $this->assertSame(1, $DB->insert_record('test_table1', $rec));
     // Check defined defaults are working ok.
     $dbrec = $DB->get_record('test_table1', array('id' => 1));
     $this->assertSame('Moodle', $dbrec->name);
     $this->assertSame('', $dbrec->thirdname);
     // Check exceptions if multiple R columns.
     $table = new xmldb_table('test_table2');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('rid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('primaryx', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('ddl_exception', $e);
     }
     // Check exceptions missing primary key on R column.
     $table = new xmldb_table('test_table2');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('ddl_exception', $e);
     }
     // Long table name names - the largest allowed.
     $table = new xmldb_table('test_table0123456789_____xyz');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     $dbman->drop_table($table);
     // Table name is too long.
     $table = new xmldb_table('test_table0123456789_____xyz9');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid table name.
     $table = new xmldb_table('test_tableCD');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Weird column names - the largest allowed.
     $table = new xmldb_table('test_table3');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abcdef____0123456789_______xyz', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     $dbman->drop_table($table);
     // Too long field name - max 30.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abcdeabcdeabcdeabcdeabcdeabcdez', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid field name.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abCD', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid integer length.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '21', null, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid integer default.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid decimal length.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '21,10', null, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid decimal decimals.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '10,11', null, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid decimal default.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '10,5', null, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid float length.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '21,10', null, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid float decimals.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '10,11', null, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
     // Invalid float default.
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '10,5', null, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (moodle_exception $e) {
         $this->assertInstanceOf('coding_exception', $e);
     }
 }
Exemplo n.º 7
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     // Set own core attributes
     $this->does_generate = ACTION_NONE;
     //$this->does_generate = ACTION_GENERATE_HTML;
     // These are always here
     global $CFG, $XMLDB;
     // Do the job, setting result as needed
     // Get the dir containing the file
     $dirpath = required_param('dir', PARAM_PATH);
     $dirpath = $CFG->dirroot . $dirpath;
     // Get the correct dirs
     if (!empty($XMLDB->dbdirs)) {
         $dbdir = $XMLDB->dbdirs[$dirpath];
     } else {
         return false;
     }
     if (!empty($XMLDB->editeddirs)) {
         $editeddir = $XMLDB->editeddirs[$dirpath];
         $structure = $editeddir->xml_file->getStructure();
     }
     // If the changeme table exists, just get it and continue
     $changeme_exists = false;
     if ($tables = $structure->getTables()) {
         if ($table = $structure->getTable('changeme')) {
             $changeme_exists = true;
         }
     }
     if (!$changeme_exists) {
         // Lets create the table
         $field = new xmldb_field('id');
         $field->setType(XMLDB_TYPE_INTEGER);
         $field->setLength(10);
         $field->setNotNull(true);
         $field->setSequence(true);
         $field->setLoaded(true);
         $field->setChanged(true);
         $key = new xmldb_key('primary');
         $key->setType(XMLDB_KEY_PRIMARY);
         $key->setFields(array('id'));
         $key->setLoaded(true);
         $key->setChanged(true);
         $table = new xmldb_table('changeme');
         $table->setComment('Default comment for the table, please edit me');
         $table->addField($field);
         $table->addKey($key);
         // Finally, add the whole retrofitted table to the structure
         // in the place specified
         $structure->addTable($table);
     }
     // Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     // Return ok if arrived here
     return $result;
 }
Exemplo n.º 8
0
 /**
  * Test behaviour of create_table()
  */
 public function test_create_table()
 {
     $DB = $this->tdb;
     // do not use global $DB!
     $dbman = $this->tdb->get_manager();
     // create table
     $table = $this->tables['test_table1'];
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     // basic get_tables() test
     $tables = $DB->get_tables();
     $this->assertTrue(array_key_exists('test_table1', $tables));
     // basic get_columns() tests
     $columns = $DB->get_columns('test_table1');
     $this->assertEquals($columns['id']->meta_type, 'R');
     $this->assertEquals($columns['course']->meta_type, 'I');
     $this->assertEquals($columns['name']->meta_type, 'C');
     $this->assertEquals($columns['secondname']->meta_type, 'C');
     $this->assertEquals($columns['thirdname']->meta_type, 'C');
     $this->assertEquals($columns['intro']->meta_type, 'X');
     $this->assertEquals($columns['avatar']->meta_type, 'B');
     $this->assertEquals($columns['grade']->meta_type, 'N');
     $this->assertEquals($columns['percentfloat']->meta_type, 'N');
     $this->assertEquals($columns['userid']->meta_type, 'I');
     // some defaults
     $this->assertTrue($columns['course']->has_default);
     $this->assertEquals($columns['course']->default_value, 0);
     $this->assertTrue($columns['name']->has_default);
     $this->assertEquals($columns['name']->default_value, 'Moodle');
     $this->assertTrue($columns['secondname']->has_default);
     $this->assertEquals($columns['secondname']->default_value, '');
     $this->assertTrue($columns['thirdname']->has_default);
     $this->assertEquals($columns['thirdname']->default_value, '');
     $this->assertTrue($columns['percentfloat']->has_default);
     $this->assertEquals($columns['percentfloat']->default_value, 99.90000000000001);
     $this->assertTrue($columns['userid']->has_default);
     $this->assertEquals($columns['userid']->default_value, 0);
     // basic get_indexes() test
     $indexes = $DB->get_indexes('test_table1');
     $courseindex = reset($indexes);
     $this->assertEquals($courseindex['unique'], 1);
     $this->assertEquals($courseindex['columns'][0], 'course');
     // check sequence returns 1 for first insert
     $rec = (object) array('course' => 10, 'secondname' => 'not important', 'intro' => 'not important');
     $this->assertSame($DB->insert_record('test_table1', $rec), 1);
     // check defined defaults are working ok
     $dbrec = $DB->get_record('test_table1', array('id' => 1));
     $this->assertEquals($dbrec->name, 'Moodle');
     $this->assertEquals($dbrec->thirdname, '');
     // check exceptions if multiple R columns
     $table = new xmldb_table('test_table2');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('rid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('primaryx', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertTrue($e instanceof ddl_exception);
     }
     // check exceptions missing primary key on R column
     $table = new xmldb_table('test_table2');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertTrue($e instanceof ddl_exception);
     }
     // long table name names - the largest allowed
     $table = new xmldb_table('test_table0123456789_____xyz');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     $dbman->drop_table($table);
     // table name is too long
     $table = new xmldb_table('test_table0123456789_____xyz9');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // invalid table name
     $table = new xmldb_table('test_tableCD');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // weird column names - the largest allowed
     $table = new xmldb_table('test_table3');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abcdef____0123456789_______xyz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     $dbman->create_table($table);
     $this->assertTrue($dbman->table_exists($table));
     $dbman->drop_table($table);
     // Too long field name - max 30
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abcdeabcdeabcdeabcdeabcdeabcdez', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid field name
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('abCD', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid integer length
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '21', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '2');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid integer default
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid decimal length
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '21,10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid decimal decimals
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '10,11', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid decimal default
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_NUMBER, '10,5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid float length
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '21,10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid float decimals
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '10,11', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
     // Invalid float default
     $table = new xmldb_table('test_table4');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('num', XMLDB_TYPE_FLOAT, '10,5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'x');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     $this->tables[$table->getName()] = $table;
     try {
         $dbman->create_table($table);
         $this->fail('Exception expected');
     } catch (Exception $e) {
         $this->assertSame(get_class($e), 'coding_exception');
     }
 }
Exemplo n.º 9
0
    /**
     * Test behaviour of create_table()
     */
    public function test_create_table() {
        $DB = $this->tdb; // do not use global $DB!
        $dbman = $this->tdb->get_manager();

        // create table
        $table = $this->tables['test_table1'];

        $dbman->create_table($table);
        $this->assertTrue($dbman->table_exists($table));

        // basic get_tables() test
        $tables = $DB->get_tables();
        $this->assertTrue(array_key_exists('test_table1', $tables));

        // basic get_columns() tests
        $columns = $DB->get_columns('test_table1');
        $this->assertEqual($columns['id']->meta_type, 'R');
        $this->assertEqual($columns['course']->meta_type, 'I');
        $this->assertEqual($columns['name']->meta_type, 'C');
        $this->assertEqual($columns['secondname']->meta_type, 'C');
        $this->assertEqual($columns['thirdname']->meta_type, 'C');
        $this->assertEqual($columns['intro']->meta_type, 'X');
        $this->assertEqual($columns['avatar']->meta_type, 'B');
        $this->assertEqual($columns['grade']->meta_type, 'N');
        $this->assertEqual($columns['percentfloat']->meta_type, 'N');
        $this->assertEqual($columns['userid']->meta_type, 'I');
        // some defaults
        $this->assertTrue($columns['course']->has_default);
        $this->assertEqual($columns['course']->default_value, 0);
        $this->assertTrue($columns['name']->has_default);
        $this->assertEqual($columns['name']->default_value, 'Moodle');
        $this->assertTrue($columns['secondname']->has_default);
        $this->assertEqual($columns['secondname']->default_value, '');
        $this->assertTrue($columns['thirdname']->has_default);
        $this->assertEqual($columns['thirdname']->default_value, '');
        $this->assertTrue($columns['percentfloat']->has_default);
        $this->assertEqual($columns['percentfloat']->default_value, 99.9);
        $this->assertTrue($columns['userid']->has_default);
        $this->assertEqual($columns['userid']->default_value, 0);

        // basic get_indexes() test
        $indexes = $DB->get_indexes('test_table1');
        $courseindex = reset($indexes);
        $this->assertEqual($courseindex['unique'], 1);
        $this->assertEqual($courseindex['columns'][0], 'course');

        // check sequence returns 1 for first insert
        $rec = (object)array(
                'course'     => 10,
                'secondname' => 'not important',
                'intro'      => 'not important');
        $this->assertIdentical($DB->insert_record('test_table1', $rec), 1);

        // check defined defaults are working ok
        $dbrec = $DB->get_record('test_table1', array('id' => 1));
        $this->assertEqual($dbrec->name, 'Moodle');
        $this->assertEqual($dbrec->thirdname, '');

        // check exceptions if multiple R columns
        $table = new xmldb_table ('test_table2');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('rid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('primaryx', XMLDB_KEY_PRIMARY, array('id'));
        $table->setComment("This is a test'n drop table. You can drop it safely");

        $this->tables[$table->getName()] = $table;

        try {
            $dbman->create_table($table);
            $this->fail('Exception expected');
        } catch (Exception $e) {
            $this->assertTrue($e instanceof ddl_exception);
        }

        // check exceptions missing primary key on R column
        $table = new xmldb_table ('test_table2');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
        $table->setComment("This is a test'n drop table. You can drop it safely");

        $this->tables[$table->getName()] = $table;

        try {
            $dbman->create_table($table);
            $this->fail('Exception expected');
        } catch (Exception $e) {
            $this->assertTrue($e instanceof ddl_exception);
        }

    }
Exemplo n.º 10
0
function xmldb_facetoface_upgrade($oldversion=0) {
    global $CFG, $USER, $DB, $OUTPUT;

    $dbman = $DB->get_manager(); // loads ddl manager and xmldb classes

    require_once($CFG->dirroot . '/mod/facetoface/lib.php');

    $result = true;

    if ($result && $oldversion < 2008050500) {
        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('thirdpartywaitlist');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'thirdparty');
        $result = $result && $dbman->add_field($table, $field);
    }

    if ($result && $oldversion < 2008061000) {
        $table = new xmldb_table('facetoface_submissions');
        $field = new xmldb_field('notificationtype');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timemodified');
        $result = $result && $dbman->add_field($table, $field);
    }

    if ($result && $oldversion < 2008080100) {
        echo $OUTPUT->notification(get_string('upgradeprocessinggrades', 'facetoface'), 'notifysuccess');
        require_once $CFG->dirroot.'/mod/facetoface/lib.php';

        $transaction = $DB->start_delegated_transaction();
        $DB->debug = false; // too much debug output

        // Migrate the grades to the gradebook
        $sql = "SELECT f.id, f.name, f.course, s.grade, s.timegraded, s.userid,
            cm.idnumber as cmidnumber
            FROM {facetoface_submissions} s
            JOIN {facetoface} f ON s.facetoface = f.id
            JOIN {course_modules} cm ON cm.instance = f.id
            JOIN {modules} m ON m.id = cm.module
            WHERE m.name='facetoface'";
        if ($rs = $DB->get_recordset_sql($sql)) {
            foreach ($rs as $facetoface) {
                $grade = new stdclass();
                $grade->userid = $facetoface->userid;
                $grade->rawgrade = $facetoface->grade;
                $grade->rawgrademin = 0;
                $grade->rawgrademax = 100;
                $grade->timecreated = $facetoface->timegraded;
                $grade->timemodified = $facetoface->timegraded;

                $result = $result && (GRADE_UPDATE_OK == facetoface_grade_item_update($facetoface, $grade));
            }
            $rs->close();
        }
        $DB->debug = true;

        // Remove the grade and timegraded fields from facetoface_submissions
        if ($result) {
            $table = new xmldb_table('facetoface_submissions');
            $field1 = new xmldb_field('grade');
            $field2 = new xmldb_field('timegraded');
            $result = $result && $dbman->drop_field($table, $field1, false, true);
            $result = $result && $dbman->drop_field($table, $field2, false, true);
        }

        $transaction->allow_commit();
    }

    if ($result && $oldversion < 2008090800) {

        // Define field timemodified to be added to facetoface_submissions
        $table = new xmldb_table('facetoface_submissions');
        $field = new xmldb_field('timecancelled');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '20', null, XMLDB_NOTNULL, null, 0, 'timemodified');

        // Launch add field
        $result = $result && $dbman->add_field($table, $field);
    }

    if ($result && $oldversion < 2009111300) {
        // New fields necessary for the training calendar
        $table = new xmldb_table('facetoface');
        $field1 = new xmldb_field('shortname');
        $field1->set_attributes(XMLDB_TYPE_CHAR, '32', null, null, null, null, 'timemodified');
        $result = $result && $dbman->add_field($table, $field1);

        $field2 = new xmldb_field('description');
        $field2->set_attributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, 'shortname');
        $result = $result && $dbman->add_field($table, $field2);

        $field3 = new xmldb_field('showoncalendar');
        $field3->set_attributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'description');
        $result = $result && $dbman->add_field($table, $field3);
    }

    if ($result && $oldversion < 2009111600) {

        $table1 = new xmldb_table('facetoface_session_field');
        $table1->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table1->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table1->add_field('shortname', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table1->add_field('type', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
        $table1->add_field('possiblevalues', XMLDB_TYPE_TEXT, 'medium', null, null, null, null);
        $table1->add_field('required', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table1->add_field('defaultvalue', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table1->add_field('isfilter', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1');
        $table1->add_field('showinsummary', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1');
        $table1->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $result = $result && $dbman->create_table($table1);

        $table2 = new xmldb_table('facetoface_session_data');
        $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table2->add_field('fieldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
        $table2->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
        $table2->add_field('data', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $result = $result && $dbman->create_table($table2);
    }

    if ($result && $oldversion < 2009111900) {
        // Remove unused field
        $table = new xmldb_table('facetoface_sessions');
        $field = new xmldb_field('closed');
        $result = $result && $dbman->drop_field($table, $field);
    }

    // Migration of old Location, Venue and Room fields
    if ($result && $oldversion < 2009112300) {
        // Create three new custom fields
        $newfield1 = new stdClass();
        $newfield1->name = 'Location';
        $newfield1->shortname = 'location';
        $newfield1->type = 0; // free text
        $newfield1->required = 1;
        if (!$locationfieldid = $DB->insert_record('facetoface_session_field', $newfield1)) {
            $result = false;
        }

        $newfield2 = new stdClass();
        $newfield2->name = 'Venue';
        $newfield2->shortname = 'venue';
        $newfield2->type = 0; // free text
        $newfield2->required = 1;
        if (!$venuefieldid = $DB->insert_record('facetoface_session_field', $newfield2)) {
            $result = false;
        }

        $newfield3 = new stdClass();
        $newfield3->name = 'Room';
        $newfield3->shortname = 'room';
        $newfield3->type = 0; // free text
        $newfield3->required = 1;
        $newfield3->showinsummary = 0;
        if (!$roomfieldid = $DB->insert_record('facetoface_session_field', $newfield3)) {
            $result = false;
        }

        // Migrate data into the new fields
        $olddebug = $DB->debug;
        $DB->debug = false; // too much debug output

        if ($rs = $DB->get_recordset('facetoface_sessions', array(), '', 'id, location, venue, room')) {
            foreach ($rs as $session) {
                $locationdata = new stdClass();
                $locationdata->sessionid = $session->id;
                $locationdata->fieldid = $locationfieldid;
                $locationdata->data = $session->location;
                $result = $result && $DB->insert_record('facetoface_session_data', $locationdata);

                $venuedata = new stdClass();
                $venuedata->sessionid = $session->id;
                $venuedata->fieldid = $venuefieldid;
                $venuedata->data = $session->venue;
                $result = $result && $DB->insert_record('facetoface_session_data', $venuedata);

                $roomdata = new stdClass();
                $roomdata->sessionid = $session->id;
                $roomdata->fieldid = $roomfieldid;
                $roomdata->data = $session->room;
                $result = $result && $DB->insert_record('facetoface_session_data', $roomdata);
            }
            $rs->close();
        }

        $DB->debug = $olddebug;

        // Drop the old fields
        $table = new xmldb_table('facetoface_sessions');
        $oldfield1 = new xmldb_field('location');
        $result = $result && $dbman->drop_field($table, $oldfield1);
        $oldfield2 = new xmldb_field('venue');
        $result = $result && $dbman->drop_field($table, $oldfield2);
        $oldfield3 = new xmldb_field('room');
        $result = $result && $dbman->drop_field($table, $oldfield3);
    }

    // Migration of old Location, Venue and Room placeholders in email templates
    if ($result && $oldversion < 2009112400) {
        $transaction = $DB->start_delegated_transaction();

        $olddebug = $DB->debug;
        $DB->debug = false; // too much debug output

        $templatedfields = array('confirmationsubject', 'confirmationinstrmngr', 'confirmationmessage',
            'cancellationsubject', 'cancellationinstrmngr', 'cancellationmessage',
            'remindersubject', 'reminderinstrmngr', 'remindermessage',
            'waitlistedsubject', 'waitlistedmessage');

        if ($rs = $DB->get_recordset('facetoface', array(), '', 'id, ' . implode(', ', $templatedfields))) {
            foreach ($rs as $activity) {
                $todb = new stdClass();
                $todb->id = $activity->id;

                foreach ($templatedfields as $fieldname) {
                    $s = $activity->$fieldname;
                    $s = str_replace('[location]', '[session:location]', $s);
                    $s = str_replace('[venue]', '[session:venue]', $s);
                    $s = str_replace('[room]', '[session:room]', $s);
                    $todb->$fieldname = $s;
                }

                $result = $result && $DB->update_record('facetoface', $todb);
            }
            $rs->close();
        }

        $DB->debug = $olddebug;

        $transaction->allow_commit();
    }

    if ($result && $oldversion < 2009120900) {
        // Create Calendar events for all existing Face-to-face sessions
        try {
            $transaction = $DB->start_delegated_transaction();

            if ($records = $DB->get_records('facetoface_sessions', '', '', '', 'id, facetoface')) {
                // Remove all exising site-wide events (there shouldn't be any)
                foreach ($records as $record) {
                    if (!facetoface_remove_session_from_calendar($record, SITEID)) {
                        $result = false;
                        throw new Exception('Could not remove session from site calendar');
                        break;
                    }
                }

                // Add new site-wide events
                foreach ($records as $record) {
                    $session = facetoface_get_session($record->id);
                    $facetoface = $DB->get_record('facetoface', 'id', $record->facetoface);

                    if (!facetoface_add_session_to_calendar($session, $facetoface, 'site')) {
                        $result = false;
                        throw new Exception('Could not add session to site calendar');
                        break;
                    }
                }
            }
            $transaction->allow_commit();
        } catch (Exception $e) {
            $transaction->rollback($e);
        }

    }

    if ($result && $oldversion < 2009122901) {

    /// Create table facetoface_session_roles
        $table = new xmldb_table('facetoface_session_roles');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('roleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));
        $result = $result && $dbman->create_table($table);

    /// Create table facetoface_signups
        $table = new xmldb_table('facetoface_signups');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('mailedreminder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('discountcode', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
        $table->add_field('notificationtype', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));
        $result = $result && $dbman->create_table($table);

    /// Create table facetoface_signups_status
        $table = new xmldb_table('facetoface_signups_status');
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('signupid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('statuscode', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('superceded', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
        $table->add_field('createdby', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('grade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, '0');
        $table->add_field('note', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('signupid', XMLDB_KEY_FOREIGN, array('signupid'), 'facetoface_signups', array('id'));
        $result = $result && $dbman->create_table($table);

    /// Migrate submissions to signups
        $table = new xmldb_table('facetoface_submissions');
        if ($dbman->table_exists($table)) {
            require_once $CFG->dirroot.'/mod/facetoface/lib.php';

            $transaction = $DB->start_delegated_transaction();

            // Get all submissions and loop through
            $rs = $DB->get_recordset('facetoface_submissions');

            foreach ($rs as $submission) {

                // Insert signup
                $signup = new stdClass();
                $signup->sessionid = $submission->sessionid;
                $signup->userid = $submission->userid;
                $signup->mailedreminder = $submission->mailedreminder;
                $signup->discountcode = $submission->discountcode;
                $signup->notificationtype = $submission->notificationtype;

                $id = $DB->insert_record('facetoface_signups', $signup);

                $signup->id = $id;

                // Check facetoface still exists (some of them are missing)
                // Also, we need the course id so we can load the grade
                $facetoface = $DB->get_record('facetoface', 'id', $submission->facetoface);
                if (!$facetoface) {
                    // If facetoface delete, ignore as it's of no use to us now
                    mtrace('Could not find facetoface instance '.$submission->facetoface);
                    continue;
                }

                // Get grade
                $grade = facetoface_get_grade($submission->userid, $facetoface->course, $facetoface->id);

                // Create initial "booked" signup status
                $status = new stdClass();
                $status->signupid = $signup->id;
                $status->statuscode = MDL_F2F_STATUS_BOOKED;
                $status->superceded = ($grade->grade > 0 || $submission->timecancelled) ? 1 : 0;
                $status->createdby = $USER->id;
                $status->timecreated = $submission->timecreated;
                $status->mailed = 0;

                $DB->insert_record('facetoface_signups_status', $status);

                // Create attended signup status
                if ($grade->grade > 0) {
                    $status->statuscode = MDL_F2F_STATUS_FULLY_ATTENDED;
                    $status->grade = $grade->grade;
                    $status->timecreated = $grade->dategraded;
                    $status->superceded = $submission->timecancelled ? 1 : 0;

                    $DB->insert_record('facetoface_signups_status', $status);
                }

                // If cancelled, create status
                if ($submission->timecancelled) {
                    $status->statuscode = MDL_F2F_STATUS_USER_CANCELLED;
                    $status->timecreated = $submission->timecancelled;
                    $status->superceded = 0;

                    $DB->insert_record('facetoface_signups_status', $status);
                }
            }

            $rs->close();
            $transaction->allow_commit();

            /// Drop table facetoface_submissions
            $table = new xmldb_table('facetoface_submissions');
            $result = $result && $dbman->drop_table($table);
        }

    // New field necessary for overbooking
        $table = new xmldb_table('facetoface_sessions');
        $field1 = new xmldb_field('allowoverbook');
        $field1->set_attributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'capacity');
        $result = $result && $dbman->add_field($table, $field1);
    }

    if ($result && $oldversion < 2010012000) {
        // New field for storing recommendations/advice
        $table = new xmldb_table('facetoface_signups_status');
        $field1 = new xmldb_field('advice');
        $field1->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null);
        $result = $result && $dbman->add_field($table, $field1);
    }

    if ($result && $oldversion < 2010012001) {
        // New field for storing manager approval requirement
        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('approvalreqd');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'showoncalendar');
        $result = $result && $dbman->add_field($table, $field);
    }

    if ($result && $oldversion < 2010012700) {
        // New fields for storing request emails
        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('requestsubject');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, 'reminderperiod');
        $result = $result && $dbman->add_field($table, $field);

        $field = new xmldb_field('requestinstrmngr');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, 'requestsubject');
        $result = $result && $dbman->add_field($table, $field);

        $field = new xmldb_field('requestmessage');
        $field->set_attributes(XMLDB_TYPE_TEXT, 'medium', null, null, null, null, 'requestinstrmngr');
        $result = $result && $dbman->add_field($table, $field);
    }

    if ($result && $oldversion < 2010051000) {
        // Create Calendar events for all existing Face-to-face sessions
        $transaction = $DB->start_delegated_transaction();

        if ($records = $DB->get_records('facetoface_sessions', '', '', '', 'id, facetoface')) {
            // Remove all exising site-wide events (there shouldn't be any)
            foreach ($records as $record) {
                facetoface_remove_session_from_calendar($record, SITEID);
            }

            // Add new site-wide events
            foreach ($records as $record) {
                $session = facetoface_get_session($record->id);
                $facetoface = $DB->get_record('facetoface', 'id', $record->facetoface);

                facetoface_add_session_to_calendar($session, $facetoface, 'site');
            }
        }

        $transaction->allow_commit();

        // Add tables required for site notices
        $table1 = new xmldb_table('facetoface_notice');
        $table1->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table1->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table1->add_field('text', XMLDB_TYPE_TEXT, 'medium', null, null, null, null);
        $table1->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $result = $result && $dbman->create_table($table1);

        $table2 = new xmldb_table('facetoface_notice_data');
        $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table2->add_field('fieldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
        $table2->add_field('noticeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
        $table2->add_field('data', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table2->add_index('facetoface_notice_date_fieldid', XMLDB_INDEX_NOTUNIQUE, array('fieldid'));
        $result = $result && $dbman->create_table($table2);
    }

    if ($result && $oldversion < 2010100400) {
        // Remove unused mailed field
        $table = new xmldb_table('facetoface_signups_status');
        $field = new xmldb_field('mailed');
        if ($dbman->field_exists($table, $field)) {
            $result = $result && $dbman->drop_field($table, $field, false, true);
        }

    }

    // 2.0 upgrade line -----------------------------------

    if ($oldversion < 2011120701) {
        // Update existing select fields to use new seperator
        $badrows = $DB->get_records_sql(
            "
                SELECT
                    *
                FROM
                    {facetoface_session_field}
                WHERE
                    possiblevalues LIKE '%;%'
                AND possiblevalues NOT LIKE '%" . CUSTOMFIELD_DELIMITER . "%'
                AND type IN (".CUSTOMFIELD_TYPE_SELECT.",".CUSTOMFIELD_TYPE_MULTISELECT.")
            "
        );

        if ($badrows) {
            $transaction = $DB->start_delegated_transaction();

            foreach ($badrows as $bad) {
                $fixedrow = new stdClass();
                $fixedrow->id = $bad->id;
                $fixedrow->possiblevalues = str_replace(';', CUSTOMFIELD_DELIMITER, $bad->possiblevalues);
                $DB->update_record('facetoface_session_field', $fixedrow);
            }

            $transaction->allow_commit();
        }

        $bad_data_rows = $DB->get_records_sql(
            "
                SELECT
                    sd.id, sd.data
                FROM
                    {facetoface_session_field} sf
                JOIN
                    {facetoface_session_data} sd
                  ON
                    sd.fieldid=sf.id
                WHERE
                    sd.data LIKE '%;%'
                AND sd.data NOT LIKE '%". CUSTOMFIELD_DELIMITER ."%'
                AND sf.type = ".CUSTOMFIELD_TYPE_MULTISELECT
        );

        if ($bad_data_rows) {
            $transaction = $DB->start_delegated_transaction();

            foreach ($bad_data_rows as $bad) {
                $fixedrow = new stdClass();
                $fixedrow->id = $bad->id;
                $fixedrow->data = str_replace(';', CUSTOMFIELD_DELIMITER, $bad->data);
                $DB->update_record('facetoface_session_data', $fixedrow);
            }

            $transaction->allow_commit();
        }

        upgrade_mod_savepoint(true, 2011120701, 'facetoface');
    }

    if ($oldversion < 2011120702) {
        $table = new xmldb_table('facetoface_session_field');
        $index = new xmldb_index('ind_session_field_unique');
        $index->set_attributes(XMLDB_INDEX_UNIQUE, array('shortname'));

        if ($dbman->table_exists($table)) {
            //do we need to check for duplicates?
            if (!$dbman->index_exists($table, $index)) {

                //check for duplicate records and make them unique
                $replacements = array();

                $transaction = $DB->start_delegated_transaction();

                $sql = 'SELECT
                            l.id,
                            l.shortname
                        FROM
                            {facetoface_session_field} l,
                            ( SELECT
                                    MIN(id) AS id,
                                    shortname
                              FROM
                                    {facetoface_session_field}
                              GROUP BY
                                    shortname
                              HAVING COUNT(*)>1
                             ) a
                        WHERE
                            l.id<>a.id
                        AND l.shortname = a.shortname
                ';

                $rs = $DB->get_recordset_sql($sql, null);

                //$rs = facetoface_tbl_duplicate_values('facetoface_session_field','shortname');
                if ($rs !== false) {
                    foreach ($rs as $item) {
                        $data = (object)$item;
                        //randomize the value
                        $data->shortname = $DB->escape($data->shortname.'_'.$data->id);
                        $DB->update_record('facetoface_session_field', $data);
                        $replacements[]=array($item['id'], $item['shortname'], $data->shortname);
                    }
                }

                $transaction->allow_commit();
                facetoface_send_admin_upgrade_msg($replacements);

                //Apply the index
                $dbman->add_index($table, $index);
            }
        }

        upgrade_mod_savepoint(true, 2011120702, 'facetoface');
    }

    if ($oldversion < 2011120703) {

        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('intro', XMLDB_TYPE_TEXT, 'big', null, null, null, null, 'name');

        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        // Add the introformat field
        $field = new xmldb_field('introformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'intro');

        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        $field = new xmldb_field('description');
        if ($dbman->field_exists($table, $field)) {

            // Move all data from description to intro
            $facetofaces = $DB->get_records('facetoface');
            foreach ($facetofaces as $facetoface) {
                $facetoface->intro = $facetoface->description;
                $facetoface->introformat = FORMAT_HTML;
                $DB->update_record('facetoface', $facetoface);
            }

            // Remove the old description field
            $dbman->drop_field($table, $field);
        }

        // facetoface savepoint reached
        upgrade_mod_savepoint(true, 2011120703, 'facetoface');
    }

    if ($oldversion < 2012140605) {
        //Remove additional html anchor reference from existing manager approval request message formats
        $links = array(
            '[Teilnehmerlink]#unbestätigt' => '[Teilnehmerlink]',
            '[attendeeslink]#unapproved' => '[attendeeslink]',
            '[enlaceasistentes] # no aprobados' => '[enlaceasistentes]',
            '[เชื่อมโยงผู้เข้าร่วมประชุม] อนุมัติ #' => '[เชื่อมโยงผู้เข้าร่วมประชุม]',
        );
        //mssql has a problem with ntext columns being used in REPLACE function calls
        $dbfamily = $DB->get_dbfamily();
        foreach ($links as $key => $replacement) {
            if ($dbfamily == 'mssql') {
                $sql = "UPDATE {facetoface} SET requestinstrmngr = CAST(REPLACE(CAST(requestinstrmngr as nvarchar(max)), ?, ?) as ntext)";
            } else {
                $sql = "UPDATE {facetoface} SET requestinstrmngr = REPLACE(requestinstrmngr, ?, ?)";
            }
            $result = $result && $DB->execute($sql, array($key, $replacement));
        }
        $stringmanager = get_string_manager();
        $langs = array("de", "en", "es", "fi", "fr", "he", "hu", "it", "ja", "nl", "pl", "pt_br",
            "sv", "th", "zh_cn");
        $strings = array("cancellationinstrmngr", "confirmationinstrmngr", "requestinstrmngr", "reminderinstrmngr");

        foreach ($langs as $lang) {
            $sql = "UPDATE {facetoface} SET ";
            $params = array();

            foreach ($strings as $str) {
                $remove = $stringmanager->get_string('setting:default' . $str . 'copybelow', 'facetoface', null, $lang);
                if ($dbfamily == 'mssql') {
                    $sql .= "{$str} = CAST(REPLACE(CAST({$str} as nvarchar(max)), ?, '') as ntext)";
                } else {
                    $sql .= "{$str} = REPLACE({$str}, ?, '')";
                }
                $params[] = $remove;

                if ($str != "reminderinstrmngr") {
                    $sql .= ", ";
                }
            }

            $result = $result && $DB->execute($sql, $params);
        }
        // facetoface savepoint reached

        upgrade_mod_savepoint(true, 2012140605, 'facetoface');
    }

    if ($oldversion < 2012140609) {
        //add a field for the user calendar entry checkbox
        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('usercalentry');
        $field->set_attributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, 1);

        //just double check the field doesn't somehow exist
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        //update the existing showoncalendar field, change true to F2F_CAL_SITE
        $sql = 'UPDATE {facetoface}
                SET showoncalendar = ?
                WHERE showoncalendar = ?';
        $DB->execute($sql, array(F2F_CAL_SITE, F2F_CAL_COURSE));

        upgrade_mod_savepoint(true, 2012140609, 'facetoface');
    }

    if ($oldversion < 2013013000) {
        //add the usermodified field to sessions
        $table = new xmldb_table('facetoface_sessions');
        $field = new xmldb_field('usermodified', XMLDB_TYPE_INTEGER, '20', null);
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }
        //add the sessiontimezone field to sessions_dates
        $table = new xmldb_table('facetoface_sessions_dates');
        $field = new xmldb_field('sessiontimezone', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'sessionid');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        //fix if no users had bad timezones set
        //first get default zone
        $fixsessions = false;

        $badzones = get_bad_timezone_list();
        $goodzones = get_clean_timezone_list();
        //see what the site config is
        if (isset($CFG->forcetimezone)) {
            $default = $CFG->forcetimezone;
        } else if (isset($CFG->timezone)) {
            $default = $CFG->timezone;
        }
        if($default == 99) {
            //both set to server local time so get system tz
            $default = date_default_timezone_get();
        }
        //only fix if the site setting is not a Moodle offset, and is in the approved list
        if (!is_float($default) && in_array($default, $goodzones)) {
            $fixsessions = true;
        }

        if ($fixsessions) {
            //check no users have deprecated or totally unknown timezones
            list($insql, $inparams) = $DB->get_in_or_equal(array_keys($badzones));
            $sql = "SELECT count(id) from {user} WHERE timezone $insql";
            $badusers = $DB->count_records_sql($sql, $inparams);
            $fullzones = array_merge(array_keys($badzones), array_values($goodzones));
            $fullzones[] = 99;
            list($insql, $inparams) = $DB->get_in_or_equal($fullzones, SQL_PARAMS_QM, 'param', false);
            $sql = "SELECT count(id) from {user} WHERE timezone $insql";
            $unknownusercount = $DB->count_records_sql($sql, $inparams);

            if ($badusers > 0 || $unknownusercount > 0) {
                //some users have bad timezones set
                //output a notice and direct to the new admin tool
                $info = get_string('badusertimezonemessage', 'mod_facetoface');
                echo $OUTPUT->notification($info, 'notifynotice');
            } else {
                //only if the site timezone is sensible AND no users have bad zones
                $sql = 'UPDATE {facetoface_sessions_dates} SET sessiontimezone = ?';
                $DB->execute($sql, array($default));
            }
        }
        //sessions created before this upgrade may still need fixing
        $sql = "SELECT count(id) from {facetoface_sessions_dates} WHERE sessiontimezone IS NULL OR " . $DB->sql_compare_text('sessiontimezone', 255) . " = ?";
        $unfixedsessions = $DB->count_records_sql($sql, array(''));
        if ($unfixedsessions > 0) {
            $info = get_string('timezoneupgradeinfomessage', 'facetoface');
            echo $OUTPUT->notification($info, 'notifynotice');
        }
        upgrade_mod_savepoint(true, 2013013000, 'facetoface');
    }
    if ($oldversion < 2013013001) {

        // Define table facetoface_notification_tpl to be created
        $table = new xmldb_table('facetoface_notification_tpl');

        // Set up the comment for the notification templates table.
        $table->setComment('Face-to-face notification templates');

        // Adding fields to table facetoface_notification_tpl
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
        $table->add_field('body', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
        $table->add_field('managerprefix', XMLDB_TYPE_TEXT, 'big', null, null, null, null);
        $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');

        // Adding keys to table facetoface_notification_tpl
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));

        // Adding indexes to table facetoface_notification_tpl
        $table->add_index('title', XMLDB_INDEX_UNIQUE, array('title'));
        $table->add_index('status', XMLDB_INDEX_NOTUNIQUE, array('status'));

        // Launch create table for facetoface_notification_tpl
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013013001, 'facetoface');
    }

    if ($result && $oldversion < 2013013002) {

        // Define table facetoface_notification to be created
        $table = new xmldb_table('facetoface_notification');

        // Set up the comment for the facetoface notification table.
        $table->setComment('Facetoface notifications');

        // Adding fields to table facetoface_notification
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('type', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
        $table->add_field('conditiontype', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('scheduleunit', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
        $table->add_field('scheduleamount', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
        $table->add_field('scheduletime', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('ccmanager', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('managerprefix', XMLDB_TYPE_TEXT, 'big', null, null, null, null);
        $table->add_field('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
        $table->add_field('body', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
        $table->add_field('booked', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('waitlisted', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('cancelled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('facetofaceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('issent', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);

        // Adding keys to table facetoface_notification
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->add_key('facetofaceid', XMLDB_KEY_FOREIGN, array('facetofaceid'), 'facetoface', array('id'));

        // Adding indexes to table facetoface_notification
        $table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));
        $table->add_index('title', XMLDB_INDEX_NOTUNIQUE, array('title'));
        $table->add_index('status', XMLDB_INDEX_NOTUNIQUE, array('status'));
        $table->add_index('issent', XMLDB_INDEX_NOTUNIQUE, array('issent'));

        // Launch create table for facetoface_notification
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013013002, 'facetoface');
    }

    if ($oldversion < 2013013003) {

        // Define table facetoface_notification_sent to be created
        $table = new xmldb_table('facetoface_notification_sent');

        // Set up the comment for the facetoface notifications sent table.
        $table->setComment('Face-to-face notification reciepts');

        // Adding fields to table facetoface_notification_sent
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('notificationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);

        // Adding keys to table facetoface_notification_sent
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('notificationid', XMLDB_KEY_FOREIGN, array('notificationid'), 'facetoface_notification', array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));

        // Launch create table for facetoface_notification_sent
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013013003, 'facetoface');
    }

    if ($oldversion < 2013013004) {
        // Move existing face-to-face messages to the new notification system
        // Get facetoface's
        $facetofaces = $DB->get_records('facetoface');
        if ($facetofaces) {
            // Loop over facetofaces
            foreach ($facetofaces as $facetoface) {
                // Get each message and create notification
                $defaults = array();
                $defaults['facetofaceid'] = $facetoface->id;
                $defaults['courseid'] = $facetoface->course;
                $defaults['type'] = MDL_F2F_NOTIFICATION_AUTO;
                $defaults['booked'] = 0;
                $defaults['waitlisted'] = 0;
                $defaults['cancelled'] = 0;
                $defaults['issent'] = 0;
                $defaults['status'] = 1;
                $defaults['ccmanager'] = 0;

                $confirmation = new facetoface_notification($defaults, false);
                $confirmation->title = $facetoface->confirmationsubject;
                $confirmation->body = text_to_html($facetoface->confirmationmessage);
                $confirmation->conditiontype = MDL_F2F_CONDITION_BOOKING_CONFIRMATION;
                if (!empty($facetoface->confirmationinstrmngr)) {
                    $confirmation->ccmanager = 1;
                    $confirmation->managerprefix = text_to_html($facetoface->confirmationinstrmngr);
                }
                $result = $result && $confirmation->save();

                $waitlist = new facetoface_notification($defaults, false);
                $waitlist->title = $facetoface->waitlistedsubject;
                $waitlist->body = text_to_html($facetoface->waitlistedmessage);
                $waitlist->conditiontype = MDL_F2F_CONDITION_WAITLISTED_CONFIRMATION;
                $result = $result && $waitlist->save();

                $cancellation = new facetoface_notification($defaults, false);
                $cancellation->title = $facetoface->cancellationsubject;
                $cancellation->body = text_to_html($facetoface->cancellationmessage);
                $cancellation->conditiontype = MDL_F2F_CONDITION_CANCELLATION_CONFIRMATION;
                if (!empty($facetoface->cancellationinstrmngr)) {
                    $cancellation->ccmanager = 1;
                    $cancellation->managerprefix = text_to_html($facetoface->cancellationinstrmngr);
                }
                $result = $result && $cancellation->save();

                $reminder = new facetoface_notification($defaults, false);
                $reminder->title = $facetoface->remindersubject;
                $reminder->body = text_to_html($facetoface->remindermessage);
                $reminder->conditiontype = MDL_F2F_CONDITION_BEFORE_SESSION;
                $reminder->scheduleunit = MDL_F2F_SCHEDULE_UNIT_DAY;
                $reminder->scheduleamount = $facetoface->reminderperiod;
                if (!empty($facetoface->reminderinstrmngr)) {
                    $reminder->ccmanager = 1;
                    $reminder->managerprefix = text_to_html($facetoface->reminderinstrmngr);
                }
                $result = $result && $reminder->save();

                if (!empty($facetoface->approvalreqd)) {
                    $request = new facetoface_notification($defaults, false);
                    $request->title = $facetoface->requestsubject;
                    $request->body = text_to_html($facetoface->requestmessage);
                    $request->conditiontype = MDL_F2F_CONDITION_BOOKING_REQUEST;
                    if (!empty($facetoface->requestinstrmngr)) {
                        $request->ccmanager = 1;
                        $request->managerprefix = text_to_html($facetoface->requestinstrmngr);
                    }
                    $result = $result && $request->save();
                }
            }
        }

        // Copy over templates from lang files
        $tpl_confirmation = new stdClass();
        $tpl_confirmation->status = 1;
        $tpl_confirmation->title = get_string('setting:defaultconfirmationsubjectdefault', 'facetoface');
        $tpl_confirmation->body = text_to_html(get_string('setting:defaultconfirmationmessagedefault', 'facetoface'));
        $tpl_confirmation->managerprefix = text_to_html(get_string('setting:defaultconfirmationinstrmngrdefault', 'facetoface'));
        $DB->insert_record('facetoface_notification_tpl', $tpl_confirmation);

        $tpl_cancellation = new stdClass();
        $tpl_cancellation->status = 1;
        $tpl_cancellation->title = get_string('setting:defaultcancellationsubjectdefault', 'facetoface');
        $tpl_cancellation->body = text_to_html(get_string('setting:defaultcancellationmessagedefault', 'facetoface'));
        $tpl_cancellation->managerprefix = text_to_html(get_string('setting:defaultcancellationinstrmngrdefault', 'facetoface'));
        $DB->insert_record('facetoface_notification_tpl', $tpl_cancellation);

        $tpl_waitlist = new stdClass();
        $tpl_waitlist->status = 1;
        $tpl_waitlist->title = get_string('setting:defaultwaitlistedsubjectdefault', 'facetoface');
        $tpl_waitlist->body = text_to_html(get_string('setting:defaultwaitlistedmessagedefault', 'facetoface'));
        $DB->insert_record('facetoface_notification_tpl', $tpl_waitlist);

        $tpl_reminder = new stdClass();
        $tpl_reminder->status = 1;
        $tpl_reminder->title = get_string('setting:defaultremindersubjectdefault', 'facetoface');
        $tpl_reminder->body = text_to_html(get_string('setting:defaultremindermessagedefault', 'facetoface'));
        $tpl_reminder->managerprefix = text_to_html(get_string('setting:defaultreminderinstrmngrdefault', 'facetoface'));
        $DB->insert_record('facetoface_notification_tpl', $tpl_reminder);

        $tpl_request = new stdClass();
        $tpl_request->status = 1;
        $tpl_request->title = get_string('setting:defaultrequestsubjectdefault', 'facetoface');
        $tpl_request->body = text_to_html(get_string('setting:defaultrequestmessagedefault', 'facetoface'));
        $tpl_request->managerprefix = text_to_html(get_string('setting:defaultrequestinstrmngrdefault', 'facetoface'));
        $DB->insert_record('facetoface_notification_tpl', $tpl_request);

        // Drop columns from facetoface table
        if ($result) {
            $msg_cols = array(
                'confirmationsubject',
                'confirmationinstrmngr',
                'confirmationmessage',
                'waitlistedsubject',
                'waitlistedmessage',
                'cancellationsubject',
                'cancellationinstrmngr',
                'cancellationmessage',
                'remindersubject',
                'reminderinstrmngr',
                'remindermessage',
                'reminderperiod',
                'requestsubject',
                'requestinstrmngr',
                'requestmessage'
            );

            $table = new xmldb_table('facetoface');
            foreach ($msg_cols as $mc) {
                $field = new xmldb_field($mc);
                if ($dbman->field_exists($table, $field)) {
                    $dbman->drop_field($table, $field);
                }
            }
        }

        upgrade_mod_savepoint(true, 2013013004, 'facetoface');
    }

    if ($oldversion < 2013013005) {
        $table = new xmldb_table('facetoface_signups');
        $field = new xmldb_field('mailedreminder');

        if (!$dbman->field_exists($table, $field)) {
            // Get all sessions with reminders sent that have had
            // the reminder converted to the new style notification
            $sessions = $DB->get_records_sql(
                "
                SELECT
                    fs.sessionid,
                    ss.facetoface AS facetofaceid,
                    fn.id AS notificationid
                FROM
                    {facetoface_signups} fs
                INNER JOIN
                    {facetoface_sessions} ss
                 ON fs.sessionid = ss.id
                INNER JOIN
                    {facetoface_notification} fn
                 ON fn.facetofaceid = ss.facetoface
                WHERE
                    fs.mailedreminder = 1
                AND fn.type = ".MDL_F2F_NOTIFICATION_AUTO."
                AND fn.conditiontype = ".MDL_F2F_CONDITION_BEFORE_SESSION."
                AND fn.scheduletime IS NOT NULL
                GROUP BY
                    fs.sessionid,
                    ss.facetoface,
                    fn.id
                "
            );

            if ($sessions) {
                // Add entries to sent table
                foreach ($sessions as $session) {
                    $record = new stdClass();
                    $record->sessionid = $session->sessionid;
                    $record->notificationid = $session->notificationid;
                    $DB->insert_record('facetoface_notification_sent', $record);
                }
            }

            // Drop column from signups table, already checked it exists.
            $dbman->drop_field($table, $field);
        }

        upgrade_mod_savepoint(true, 2013013005, 'facetoface');
    }

    if ($oldversion < 2013013006) {

        // Define table facetoface_room to be created
        $table = new xmldb_table('facetoface_room');

        // Set up comment for the facetoface room table.
        $table->setComment('Table for storing pre-defined facetoface room data');

        // Adding fields to table facetoface_room
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, null, null, null);
        $table->add_field('building', XMLDB_TYPE_CHAR, '100', null, null, null, null);
        $table->add_field('address', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table->add_field('capacity', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
        $table->add_field('type', XMLDB_TYPE_CHAR, '10', null, null, null, null);
        $table->add_field('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
        $table->add_field('custom', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');

        // Adding keys to table facetoface_room
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));

        // Adding indexes to table facetoface_room
        $table->add_index('custom', XMLDB_INDEX_NOTUNIQUE, array('custom'));

        // Launch create table for facetoface_room
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        // Add roomid field to facetoface_sessions table
        $table = new xmldb_table('facetoface_sessions');

        $field = new xmldb_field('roomid');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'discountcost');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        // Populate new sesion room table with the data from the session custom fields
        $rs = $DB->get_recordset('facetoface_sessions', array(), '', 'id, capacity');

        $fieldmappings = array('room' => 'name', 'venue' => 'building', 'location' => 'address');

        foreach ($rs as $session) {
            $sql = "SELECT f.shortname, d.data
                FROM {facetoface_session_data} d
                INNER JOIN {facetoface_session_field} f ON d.fieldid = f.id
                WHERE d.sessionid = ?
                AND f.shortname IN('room', 'venue', 'location')";
            if ($data = $DB->get_records_sql($sql, array($session->id))) {
                $todb = new stdClass;
                $todb->custom = 1;
                $todb->capacity = $session->capacity;
                foreach ($data as $d) {
                    $todb->{$fieldmappings[$d->shortname]} = $d->data;
                }
                if (!$roomid = $DB->insert_record('facetoface_room', $todb)) {
                    error('Could not populate session room data from custom fields');
                }
                $todb = new stdClass;
                $todb->id = $session->id;
                $todb->roomid = $roomid;
                if (!$DB->update_record('facetoface_sessions', $todb)) {
                    error('Could not update session roomid');
                }
            }
        }

        // Remove location, room and venue custom fields and data
        $DB->delete_records_select('facetoface_session_data',
            "fieldid IN(
                SELECT id FROM {facetoface_session_field}
                WHERE shortname IN('room', 'venue', 'location'))");

        $DB->delete_records_select('facetoface_session_field',
            "shortname IN('room', 'venue', 'location')");

        upgrade_mod_savepoint(true, 2013013006, 'facetoface');
    }

    if ($oldversion < 2013013007) {

        // original table name - to long for XMLDB editor
        $table = new xmldb_table('facetoface_notification_history');
        if ($dbman->table_exists($table)) {
            $dbman->rename_table($table, 'facetoface_notification_hist');
        }

        // create new table instead
        $table = new xmldb_table('facetoface_notification_hist');

        // Set up the comment for the facetoface notification history table.
        $table->setComment('Notifications history (stores ical event information)');

        // Adding fields to table facetoface_notification_hist
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->add_field('notificationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('sessiondateid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('ical_uid', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->add_field('ical_method', XMLDB_TYPE_CHAR, '32', null, null, null, null, null, null);
        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);

        // Adding keys to table facetoface_notification_hist
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('notificationid', XMLDB_KEY_FOREIGN, array('notificationid'), 'facetoface_notification', array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));
        $table->add_key('sessiondateid', XMLDB_KEY_FOREIGN, array('sessiondateid'), 'facetoface_sessions_dates', array('id'));
        $table->add_index('f2f_hist_userid_idx', XMLDB_INDEX_NOTUNIQUE, array('userid'));

        // Launch create table for facetoface_notification_hist
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }
        upgrade_mod_savepoint(true, 2013013007, 'facetoface');
    }

    if ($oldversion < 2013070900) {
        // Change the cost fields to varchars instead of integers.
        $table = new xmldb_table('facetoface_sessions');
        $costfield = new xmldb_field('normalcost', XMLDB_TYPE_CHAR, '255', null, true, null, '0','duration');
        $discountfield = new xmldb_field('discountcost', XMLDB_TYPE_CHAR, '255', null, true, null, '0','normalcost');
        $dbman->change_field_type($table, $costfield);
        $dbman->change_field_type($table, $discountfield);
        upgrade_mod_savepoint(true, 2013070900, 'facetoface');
    }

    if ($oldversion < 2013070901) {

        // Add manager decline notification template.
        if ($dbman->table_exists('facetoface_notification_tpl')) {
            $decline = new stdClass();
            $decline->status = 1;
            $decline->title = get_string('setting:defaultdeclinesubjectdefault', 'facetoface');
            $decline->body = text_to_html(get_string('setting:defaultdeclinemessagedefault', 'facetoface'));
            $decline->managerprefix = text_to_html(get_string('setting:defaultdeclineinstrmngrdefault', 'facetoface'));

            $DB->insert_record('facetoface_notification_tpl', $decline);
        }

        upgrade_mod_savepoint(true, 2013070901, 'facetoface');
    }

    // Re-adding the rooms upgrades because of version conflicts with 2.2, see T-11146.
    if ($oldversion < 2013090200) {

        // Define table facetoface_notification_tpl to be created
        $table = new xmldb_table('facetoface_notification_tpl');

        // Set up the comment for the notification templates table.
        $table->setComment('Face-to-face notification templates');

        // Adding fields to table facetoface_notification_tpl
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
        $table->add_field('body', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
        $table->add_field('managerprefix', XMLDB_TYPE_TEXT, 'big', null, null, null, null);
        $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');

        // Adding keys to table facetoface_notification_tpl
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));

        // Adding indexes to table facetoface_notification_tpl
        $table->add_index('title', XMLDB_INDEX_UNIQUE, array('title'));
        $table->add_index('status', XMLDB_INDEX_NOTUNIQUE, array('status'));

        // Launch create table for facetoface_notification_tpl
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013090200, 'facetoface');
    }

    if ($result && $oldversion < 2013090201) {

        // Define table facetoface_notification to be created
        $table = new xmldb_table('facetoface_notification');

        // Set up the comment for the facetoface notification table.
        $table->setComment('Facetoface notifications');

        // Adding fields to table facetoface_notification
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('type', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
        $table->add_field('conditiontype', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('scheduleunit', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
        $table->add_field('scheduleamount', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
        $table->add_field('scheduletime', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('ccmanager', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('managerprefix', XMLDB_TYPE_TEXT, 'big', null, null, null, null);
        $table->add_field('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
        $table->add_field('body', XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
        $table->add_field('booked', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('waitlisted', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, '0');
        $table->add_field('cancelled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('facetofaceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
        $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('issent', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
        $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);

        // Adding keys to table facetoface_notification
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
        $table->add_key('facetofaceid', XMLDB_KEY_FOREIGN, array('facetofaceid'), 'facetoface', array('id'));

        // Adding indexes to table facetoface_notification
        $table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));
        $table->add_index('title', XMLDB_INDEX_NOTUNIQUE, array('title'));
        $table->add_index('status', XMLDB_INDEX_NOTUNIQUE, array('status'));
        $table->add_index('issent', XMLDB_INDEX_NOTUNIQUE, array('issent'));

        // Launch create table for facetoface_notification
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013090201, 'facetoface');
    }

    if ($oldversion < 2013090202) {

        // Define table facetoface_notification_sent to be created
        $table = new xmldb_table('facetoface_notification_sent');

        // Set up the comment for the facetoface notifications sent table.
        $table->setComment('Face-to-face notification reciepts');

        // Adding fields to table facetoface_notification_sent
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('notificationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);

        // Adding keys to table facetoface_notification_sent
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('notificationid', XMLDB_KEY_FOREIGN, array('notificationid'), 'facetoface_notification', array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));

        // Launch create table for facetoface_notification_sent
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        upgrade_mod_savepoint(true, 2013090202, 'facetoface');
    }

    if ($oldversion < 2013090203) {
        // Move existing face-to-face messages to the new notification system

        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('confirmationinstrmngr');
        if ($dbman->field_exists($table, $field)) {
            // If this field still exists the notifications haven't been transfered yet.
            $facetofaces = $DB->get_records('facetoface');
            if ($facetofaces) {
                // Loop over facetofaces
                foreach ($facetofaces as $facetoface) {

                    // Get each message and create notification
                    $defaults = array();
                    $defaults['facetofaceid'] = $facetoface->id;
                    $defaults['courseid'] = $facetoface->course;
                    $defaults['type'] = MDL_F2F_NOTIFICATION_AUTO;
                    $defaults['booked'] = 0;
                    $defaults['waitlisted'] = 0;
                    $defaults['cancelled'] = 0;
                    $defaults['issent'] = 0;
                    $defaults['status'] = 1;
                    $defaults['ccmanager'] = 0;

                    $confirmation = new facetoface_notification($defaults, false);
                    $confirmation->title = $facetoface->confirmationsubject;
                    $confirmation->body = text_to_html($facetoface->confirmationmessage);
                    $confirmation->conditiontype = MDL_F2F_CONDITION_BOOKING_CONFIRMATION;
                    if (!empty($facetoface->confirmationinstrmngr)) {
                        $confirmation->ccmanager = 1;
                        $confirmation->managerprefix = text_to_html($facetoface->confirmationinstrmngr);
                    }
                    $result = $result && $confirmation->save();

                    $waitlist = new facetoface_notification($defaults, false);
                    $waitlist->title = $facetoface->waitlistedsubject;
                    $waitlist->body = text_to_html($facetoface->waitlistedmessage);
                    $waitlist->conditiontype = MDL_F2F_CONDITION_WAITLISTED_CONFIRMATION;
                    $result = $result && $waitlist->save();

                    $cancellation = new facetoface_notification($defaults, false);
                    $cancellation->title = $facetoface->cancellationsubject;
                    $cancellation->body = text_to_html($facetoface->cancellationmessage);
                    $cancellation->conditiontype = MDL_F2F_CONDITION_CANCELLATION_CONFIRMATION;
                    if (!empty($facetoface->cancellationinstrmngr)) {
                        $cancellation->ccmanager = 1;
                        $cancellation->managerprefix = text_to_html($facetoface->cancellationinstrmngr);
                    }
                    $result = $result && $cancellation->save();

                    $reminder = new facetoface_notification($defaults, false);
                    $reminder->title = $facetoface->remindersubject;
                    $reminder->body = text_to_html($facetoface->remindermessage);
                    $reminder->conditiontype = MDL_F2F_CONDITION_BEFORE_SESSION;
                    $reminder->scheduleunit = MDL_F2F_SCHEDULE_UNIT_DAY;
                    $reminder->scheduleamount = $facetoface->reminderperiod;
                    if (!empty($facetoface->reminderinstrmngr)) {
                        $reminder->ccmanager = 1;
                        $reminder->managerprefix = text_to_html($facetoface->reminderinstrmngr);
                    }
                    $result = $result && $reminder->save();

                    if (!empty($facetoface->approvalreqd)) {
                        $request = new facetoface_notification($defaults, false);
                        $request->title = $facetoface->requestsubject;
                        $request->body = text_to_html($facetoface->requestmessage);
                        $request->conditiontype = MDL_F2F_CONDITION_BOOKING_REQUEST;
                        if (!empty($facetoface->requestinstrmngr)) {
                            $request->ccmanager = 1;
                            $request->managerprefix = text_to_html($facetoface->requestinstrmngr);
                        }
                        $result = $result && $request->save();
                    }
                }
            }

            // Drop columns from facetoface table
            if ($result) {
                $msg_cols = array(
                    'confirmationsubject',
                    'confirmationinstrmngr',
                    'confirmationmessage',
                    'waitlistedsubject',
                    'waitlistedmessage',
                    'cancellationsubject',
                    'cancellationinstrmngr',
                    'cancellationmessage',
                    'remindersubject',
                    'reminderinstrmngr',
                    'remindermessage',
                    'reminderperiod',
                    'requestsubject',
                    'requestinstrmngr',
                    'requestmessage'
                );

                $table = new xmldb_table('facetoface');
                foreach ($msg_cols as $mc) {
                    $field = new xmldb_field($mc);
                    if ($dbman->field_exists($table, $field)) {
                        $dbman->drop_field($table, $field);
                    }
                }
            }
        }

        // If the templates tables exists but there aren't any templates.
        if ($dbman->table_exists('facetoface_notification_tpl')) {
            $count_templates = $DB->count_records('facetoface_notification_tpl');
            if ($count_templates == 0) {
                // Copy over templates from lang files
                $tpl_confirmation = new stdClass();
                $tpl_confirmation->status = 1;
                $tpl_confirmation->title = get_string('setting:defaultconfirmationsubjectdefault', 'facetoface');
                $tpl_confirmation->body = text_to_html(get_string('setting:defaultconfirmationmessagedefault', 'facetoface'));
                $tpl_confirmation->managerprefix = text_to_html(get_string('setting:defaultconfirmationinstrmngrdefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_confirmation);

                $tpl_cancellation = new stdClass();
                $tpl_cancellation->status = 1;
                $tpl_cancellation->title = get_string('setting:defaultcancellationsubjectdefault', 'facetoface');
                $tpl_cancellation->body = text_to_html(get_string('setting:defaultcancellationmessagedefault', 'facetoface'));
                $tpl_cancellation->managerprefix = text_to_html(get_string('setting:defaultcancellationinstrmngrdefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_cancellation);

                $tpl_waitlist = new stdClass();
                $tpl_waitlist->status = 1;
                $tpl_waitlist->title = get_string('setting:defaultwaitlistedsubjectdefault', 'facetoface');
                $tpl_waitlist->body = text_to_html(get_string('setting:defaultwaitlistedmessagedefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_waitlist);

                $tpl_reminder = new stdClass();
                $tpl_reminder->status = 1;
                $tpl_reminder->title = get_string('setting:defaultremindersubjectdefault', 'facetoface');
                $tpl_reminder->body = text_to_html(get_string('setting:defaultremindermessagedefault', 'facetoface'));
                $tpl_reminder->managerprefix = text_to_html(get_string('setting:defaultreminderinstrmngrdefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_reminder);

                $tpl_request = new stdClass();
                $tpl_request->status = 1;
                $tpl_request->title = get_string('setting:defaultrequestsubjectdefault', 'facetoface');
                $tpl_request->body = text_to_html(get_string('setting:defaultrequestmessagedefault', 'facetoface'));
                $tpl_request->managerprefix = text_to_html(get_string('setting:defaultrequestinstrmngrdefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_request);

                $tpl_decline = new stdClass();
                $tpl_decline->status = 1;
                $tpl_decline->title = get_string('setting:defaultdeclinesubjectdefault', 'facetoface');
                $tpl_decline->body = text_to_html(get_string('setting:defaultdeclinemessagedefault', 'facetoface'));
                $tpl_decline->managerprefix = text_to_html(get_string('setting:defaultdeclineinstrmngrdefault', 'facetoface'));
                $DB->insert_record('facetoface_notification_tpl', $tpl_decline);
            }
        }

        upgrade_mod_savepoint(true, 2013090203, 'facetoface');
    }

    if ($oldversion < 2013090204) {
        // Get all sessions with reminders sent that have had
        // the reminder converted to the new style notification
        $table = new xmldb_table('facetoface_signups');
        $field = new xmldb_field('mailedreminder');
        if ($dbman->field_exists($table, $field)) {
            $sessions = $DB->get_records_sql(
                "
                SELECT
                    fs.sessionid,
                    ss.facetoface AS facetofaceid,
                    fn.id AS notificationid
                FROM
                    {facetoface_signups} fs
                INNER JOIN
                    {facetoface_sessions} ss
                 ON fs.sessionid = ss.id
                INNER JOIN
                    {facetoface_notification} fn
                 ON fn.facetofaceid = ss.facetoface
                WHERE
                    fs.mailedreminder = 1
                AND fn.type = ".MDL_F2F_NOTIFICATION_AUTO."
                AND fn.conditiontype = ".MDL_F2F_CONDITION_BEFORE_SESSION."
                AND fn.scheduletime IS NOT NULL
                GROUP BY
                    fs.sessionid,
                    ss.facetoface,
                    fn.id
                "
            );

            // If the notification_sent table exists but is empty.
            if ($dbman->table_exists('facetoface_notification_sent')) {
                $count_notifications = $DB->count_records('facetoface_notification_sent');
                if ($count_notifications == 0) {
                    // Loop through all the sessions.
                    if ($sessions) {
                        // And add entries to sent table
                        foreach ($sessions as $session) {
                            $record = new stdClass();
                            $record->sessionid = $session->sessionid;
                            $record->notificationid = $session->notificationid;
                            $DB->insert_record('facetoface_notification_sent', $record);
                        }
                    }
                }
            }

            // Drop column from signups table
            $dbman->drop_field($table, $field);
        }

        upgrade_mod_savepoint(true, 2013090204, 'facetoface');
    }

    if ($oldversion < 2013090205) {

        // Define table facetoface_room to be created
        $table = new xmldb_table('facetoface_room');

        // Set up comment for the facetoface room table.
        $table->setComment('Table for storing pre-defined facetoface room data');

        // Adding fields to table facetoface_room
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
        $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, null, null, null);
        $table->add_field('building', XMLDB_TYPE_CHAR, '100', null, null, null, null);
        $table->add_field('address', XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $table->add_field('capacity', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
        $table->add_field('type', XMLDB_TYPE_CHAR, '10', null, null, null, null);
        $table->add_field('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
        $table->add_field('custom', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');

        // Adding keys to table facetoface_room
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));

        // Adding indexes to table facetoface_room
        $table->add_index('custom', XMLDB_INDEX_NOTUNIQUE, array('custom'));

        // Launch create table for facetoface_room
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }

        // Add roomid field to facetoface_sessions table
        $table = new xmldb_table('facetoface_sessions');

        $field = new xmldb_field('roomid');
        $field->set_attributes(XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'discountcost');
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);

            // Populate new sesion room table with the data from the session custom fields
            $rs = $DB->get_recordset('facetoface_sessions', array(), '', 'id, capacity');

            $fieldmappings = array('room' => 'name', 'venue' => 'building', 'location' => 'address');

            foreach ($rs as $session) {
                $sql = "SELECT f.shortname, d.data
                    FROM {facetoface_session_data} d
                    INNER JOIN {facetoface_session_field} f ON d.fieldid = f.id
                    WHERE d.sessionid = ?
                    AND f.shortname IN('room', 'venue', 'location')";
                if ($data = $DB->get_records_sql($sql, array($session->id))) {
                    $todb = new stdClass;
                    $todb->custom = 1;
                    $todb->capacity = $session->capacity;
                    foreach ($data as $d) {
                        $todb->{$fieldmappings[$d->shortname]} = $d->data;
                    }
                    if (!$roomid = $DB->insert_record('facetoface_room', $todb)) {
                        error('Could not populate session room data from custom fields');
                    }
                    $todb = new stdClass;
                    $todb->id = $session->id;
                    $todb->roomid = $roomid;
                    if (!$DB->update_record('facetoface_sessions', $todb)) {
                        error('Could not update session roomid');
                    }
                }
            }

            // Remove location, room and venue custom fields and data
            $DB->delete_records_select('facetoface_session_data',
                "fieldid IN(
                    SELECT id FROM {facetoface_session_field}
                    WHERE shortname IN('room', 'venue', 'location'))");

            $DB->delete_records_select('facetoface_session_field',
                "shortname IN('room', 'venue', 'location')");
        }

        upgrade_mod_savepoint(true, 2013090205, 'facetoface');
    }

    if ($oldversion < 2013090206) {

        // original table name - to long for XMLDB editor
        $table = new xmldb_table('facetoface_notification_history');
        if ($dbman->table_exists($table)) {
            $dbman->rename_table($table, 'facetoface_notification_hist');
        }

        // create new table instead
        $table = new xmldb_table('facetoface_notification_hist');

        // Set up the comment for the facetoface notification history table.
        $table->setComment('Notifications history (stores ical event information)');

        // Adding fields to table facetoface_notification_hist
        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
        $table->add_field('notificationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('sessionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('sessiondateid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
        $table->add_field('ical_uid', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
        $table->add_field('ical_method', XMLDB_TYPE_CHAR, '32', null, null, null, null, null, null);
        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);

        // Adding keys to table facetoface_notification_hist
        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
        $table->add_key('notificationid', XMLDB_KEY_FOREIGN, array('notificationid'), 'facetoface_notification', array('id'));
        $table->add_key('sessionid', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', array('id'));
        $table->add_key('sessiondateid', XMLDB_KEY_FOREIGN, array('sessiondateid'), 'facetoface_sessions_dates', array('id'));
        $table->add_index('f2f_hist_userid_idx', XMLDB_INDEX_NOTUNIQUE, array('userid'));

        // Launch create table for facetoface_notification_hist
        if (!$dbman->table_exists($table)) {
            $dbman->create_table($table);
        }
        upgrade_mod_savepoint(true, 2013090206, 'facetoface');
    }

    if ($oldversion < 2013092000) {
        // Define field archived to be added to facetoface_signups.
        $table = new xmldb_table('facetoface_signups');
        $field = new xmldb_field('archived', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'notificationtype');

        // Conditionally launch add field archived.
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        // Define field multiplesessions to be added to facetoface.
        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('multiplesessions', XMLDB_TYPE_INTEGER, '1', null, null, null, '0', 'usercalentry');

        // Conditionally launch add field multiplesessions.
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2013092000, 'facetoface');
    }

    if ($oldversion < 2013101500) {
        // Define field "advice" to be dropped.
        $table = new xmldb_table('facetoface_signups_status');
        $field = new xmldb_field('advice');

        // Conditionally drop field.
        if ($dbman->field_exists($table, $field)) {
            $dbman->drop_field($table, $field);
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2013101500, 'facetoface');
    }

    if ($oldversion < 2013102100) {

        $table = new xmldb_table('facetoface');
        $field = new xmldb_field('completionstatusrequired', XMLDB_TYPE_CHAR, '255');

        // Conditionally add field.
        if (!$dbman->field_exists($table, $field)) {
            $dbman->add_field($table, $field);
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2013102100, 'facetoface');
    }

    if ($oldversion < 2013103000) {
        // Adding foreign keys.
        $tables = array(
            'facetoface' => array(
                new xmldb_key('face_cou_fk', XMLDB_KEY_FOREIGN, array('course'), 'course', 'id')),
            'facetoface_session_roles' => array(
                new xmldb_key('facesessrole_use_fk', XMLDB_KEY_FOREIGN, array('userid'), 'user', 'id')),
            'facetoface_sessions' => array(
                new xmldb_key('facesess_roo_fk', XMLDB_KEY_FOREIGN, array('roomid'), 'facetoface_room', 'id'),
                new xmldb_key('facesess_use_fk', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', 'id')),
            'facetoface_signups' => array(
                new xmldb_key('facesign_use_fk', XMLDB_KEY_FOREIGN, array('userid'), 'user', 'id')),
            'facetoface_signups_status' => array(
                new xmldb_key('facesignstat_cre_fk', XMLDB_KEY_FOREIGN, array('createdby'), 'user', 'id')),
            'facetoface_session_data' => array(
                new xmldb_key('facesessdata_fie_fk', XMLDB_KEY_FOREIGN, array('fieldid'), 'facetoface_session_field', 'id'),
                new xmldb_key('facesessdata_ses_fk', XMLDB_KEY_FOREIGN, array('sessionid'), 'facetoface_sessions', 'id')),
            'facetoface_notice_data' => array(
                new xmldb_key('facenotidata_fie_fk', XMLDB_KEY_FOREIGN, array('fieldid'), 'facetoface_session_field', 'id'),
                new xmldb_key('facenotidata_not_fk', XMLDB_KEY_FOREIGN, array('noticeid'), 'facetoface_notice', 'id')),
            'facetoface_notification' => array(
                new xmldb_key('facenoti_use_fk', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', 'id')),
            'facetoface_notification_hist' => array(
                new xmldb_key('facenotihist_use_fk', XMLDB_KEY_FOREIGN, array('userid'), 'user', 'id')));


        foreach ($tables as $tablename => $keys) {
            $table = new xmldb_table($tablename);
            foreach ($keys as $key) {
                $dbman->add_key($table, $key);
            }
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2013103000, 'facetoface');
    }

    if ($oldversion < 2013120100) {

        $strmgr = get_string_manager();
        $langs = array_keys($strmgr->get_list_of_translations());
        foreach ($langs as $lang) {

            if ($lang == 'en' || $strmgr->get_string('facetoface', 'facetoface', null, $lang) !== $strmgr->get_string('facetoface', 'facetoface', null, 'en')) {

                $f2flabel = $strmgr->get_string('facetoface', 'facetoface', null, $lang);
                $courselabel = $strmgr->get_string('course', 'moodle', null, $lang);

                $body_key = "/{$courselabel}:\s*\[facetofacename\]/";
                $body_replacement = "{$courselabel}:   [coursename]<br />\n{$f2flabel}:   [facetofacename]";

                $title_key = "/{$courselabel}/";
                $title_replacement = "{$f2flabel}";

                $managerprefix_key = "/{$courselabel}:\s*\[facetofacename\]/";
                $managerprefix_replacement = "{$courselabel}:   [coursename]<br />\n{$f2flabel}:   [facetofacename]";

                $records = $DB->get_records('facetoface_notification_tpl', null, '', 'id, title, body, managerprefix');
                foreach($records as $row) {

                    $row->body = preg_replace($body_key, $body_replacement, $row->body);
                    $row->title = preg_replace($title_key, $title_replacement, $row->title);
                    $row->managerprefix = preg_replace($managerprefix_key, $managerprefix_replacement, $row->managerprefix);
                    $result = $DB->update_record('facetoface_notification_tpl', $row);
                }

                $records = $DB->get_records('facetoface_notification', null, '', 'id, title, body, managerprefix');
                foreach($records as $row) {

                    $row->body = preg_replace($body_key, $body_replacement, $row->body);
                    $row->title = preg_replace($title_key, $title_replacement, $row->title);
                    $row->managerprefix = preg_replace($managerprefix_key, $managerprefix_replacement, $row->managerprefix);
                    $result = $DB->update_record('facetoface_notification', $row);
                }
            }
        }
        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2013120100, 'facetoface');
    }

    if ($oldversion < 2014021000) {
        $del_users = $DB->get_records('user', array('deleted' => 1));
        $sus_users = $DB->get_records('user', array('deleted' => 0, 'suspended' => 1));

        foreach ($del_users as $user) {
            // Cancel already deleted users facetoface signups.
            facetoface_eventhandler_user_deleted($user);
        }

        foreach ($sus_users as $user) {
            // Cancel already suspended users facetoface signups.
            facetoface_eventhandler_user_suspended($user);
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2014021000, 'facetoface');
    }

    if ($oldversion < 2014021300) {
        $table = new xmldb_table('facetoface_session_field');
        $field = new xmldb_field('isfilter');

        if ($dbman->field_exists($table, $field)) {
            // Get custom fields marked as filters.
            $selectedfilters = $DB->get_fieldset_select('facetoface_session_field', 'id', 'isfilter = 1');
            // Activate room, building, and address as default filters.
            $selectedfilters = array_merge($selectedfilters, array('room', 'building', 'address'));
            $calendarfilters = count($selectedfilters) ? implode(',', $selectedfilters) : '';
            // Store the selected filters in the DB.
            set_config('facetoface_calendarfilters', $calendarfilters);
            // Remove isfilter field (now unnecessary).
            $dbman->drop_field($table, $field);
        }

        // Facetoface savepoint reached.
        upgrade_mod_savepoint(true, 2014021300, 'facetoface');
    }

    return $result;
}
Exemplo n.º 11
0
 /**
  * Invoke method, every class will have its own
  * returns true/false on completion, setting both
  * errormsg and output as necessary
  */
 function invoke()
 {
     parent::invoke();
     $result = true;
     /// Set own core attributes
     //$this->does_generate = ACTION_NONE;
     $this->does_generate = ACTION_GENERATE_HTML;
     /// These are always here
     global $XMLDB, $DB, $CFG;
     $dbman = $DB->get_manager();
     $gen = $dbman->generator;
     $dbfamily = $DB->get_dbfamily();
     /// Where all the tests will be stored
     $tests = array();
     /// The back to edit table button
     $b = ' <p class="centerpara buttons">';
     $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
     $b .= '</p>';
     $o = $b;
     /// Silenty drop any previous test tables
     $table = new xmldb_table('testtable');
     if ($dbman->table_exists($table)) {
         $dbman->drop_table($table);
     }
     $table = new xmldb_table('anothertest');
     if ($dbman->table_exists($table)) {
         $dbman->drop_table($table);
     }
     $table = new xmldb_table('newnameforthetable');
     if ($dbman->table_exists($table)) {
         $dbman->drop_table($table);
     }
     /// 1st test. Complete table creation.
     $table = new xmldb_table('testtable');
     $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
     $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general');
     $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null);
     $table->add_field('intro', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null);
     $table->add_field('logo', XMLDB_TYPE_BINARY, 'big', null, XMLDB_NOTNULL, null);
     $table->add_field('assessed', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('assesstimestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('assesstimefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('scale', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
     $table->add_field('maxbytes', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('forcesubscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('trackingtype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1');
     $table->add_field('rsstype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('rssarticles', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('grade', XMLDB_TYPE_NUMBER, '20,0', XMLDB_UNSIGNED, null, null, null);
     $table->add_field('percent', XMLDB_TYPE_NUMBER, '5,2', null, null, null, null);
     $table->add_field('warnafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('blockafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_field('blockperiod', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
     $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
     $table->add_key('type-name', XMLDB_KEY_UNIQUE, array('type', 'name'));
     $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
     $table->add_index('rsstype', XMLDB_INDEX_UNIQUE, array('rsstype'));
     $table->setComment("This is a test'n drop table. You can drop it safely");
     /// Get SQL code and execute it
     $test = new stdClass();
     $test->sql = $gen->getCreateTableSQL($table);
     try {
         $dbman->create_table($table);
         $test->status = true;
     } catch (moodle_exception $e) {
         $test->status = false;
         $test->error = $DB->get_last_error() . "\n" . $e;
     }
     $tests['create table'] = $test;
     /// 2nd test. drop table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getDropTableSQL($table);
         try {
             $dbman->drop_table($table);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop table'] = $test;
     }
     /// 3rd test. creating another, smaller table
     if ($test->status) {
         $table = new xmldb_table('anothertest');
         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
         $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
         $table->add_field('name', XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
         $table->add_field('secondname', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null);
         $table->add_field('intro', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null);
         $table->add_field('avatar', XMLDB_TYPE_BINARY, 'medium', null, null, null, null);
         $table->add_field('grade', XMLDB_TYPE_NUMBER, '20,10', null, null, null);
         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getCreateTableSQL($table);
         try {
             $dbman->create_table($table);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['create table - 2'] = $test;
     }
     if ($test->status) {
         /// Insert two records to do the work with real data
         $rec = new stdClass();
         $rec->course = 1;
         $rec->name = 'Martin';
         $rec->secondname = 'Dougiamas';
         $rec->intro = 'The creator of Moodle';
         $rec->grade = 10.0001;
         $DB->insert_record('anothertest', $rec);
         $rec->course = 2;
         $rec->name = 'Eloy';
         $rec->secondname = 'Lafuente';
         $rec->intro = 'One poor developer';
         $rec->grade = 9.99;
         $DB->insert_record('anothertest', $rec);
     }
     /// 4th test. Adding one field
     if ($test->status) {
         /// Create a new field with complex specs
         $field = new xmldb_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getAddFieldSQL($table, $field);
         try {
             $dbman->add_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field'] = $test;
     }
     /// 5th test. Dropping one complex field
     if ($test->status) {
         /// Create a new field with complex specs
         $test = new stdClass();
         $test->sql = $gen->getDropFieldSQL($table, $field);
         try {
             $dbman->drop_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop field'] = $test;
     }
     /// 6th test. Adding one complex field again
     if ($test->status) {
         /// Create a new field with complex specs
         $field = new xmldb_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getAddFieldSQL($table, $field);
         try {
             $dbman->add_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field again'] = $test;
     }
     /// 7th test. Dropping one complex field again
     if ($test->status) {
         /// Create a new field with complex specs
         $field = new xmldb_field('type');
         $test = new stdClass();
         $test->sql = $gen->getDropFieldSQL($table, $field);
         try {
             $dbman->drop_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop field again'] = $test;
     }
     /// 8th test. Adding one numeric field
     if ($test->status) {
         /// Create a new field (numeric)
         $field = new xmldb_field('onenumber', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getAddFieldSQL($table, $field);
         try {
             $dbman->add_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add numeric field'] = $test;
     }
     /// 9th test. Change the type of one column from integer to varchar
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('course', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, '0');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (int2char)'] = $test;
     }
     /// 10th test. Change the type of one column from varchar to integer
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (char2int)'] = $test;
     }
     /// 11th test. Change the type of one column from number to varchar
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, "test'n drop");
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (number2char)'] = $test;
     }
     /// 12th test. Change the type of one column from varchar to float
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade', XMLDB_TYPE_FLOAT, '20,10', XMLDB_UNSIGNED, null, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (char2float)'] = $test;
     }
     /// 13th test. Change the type of one column from float to char
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'test');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (float2char)'] = $test;
     }
     /// 14th test. Change the type of one column from char to number
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '20,10', XMLDB_UNSIGNED, null, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_type($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field type (char2number)'] = $test;
     }
     /// 15th test. Change the precision of one text field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('intro');
         $field->set_attributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_precision($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field precision (text)'] = $test;
     }
     /// 16th test. Change the precision of one char field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('secondname');
         $field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_precision($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field precision (char)'] = $test;
     }
     /// 17th test. Change the precision of one numeric field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade');
         $field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_precision($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field precision (number)'] = $test;
     }
     /// 18th test. Change the precision of one integer field to a smaller one
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('course');
         $field->set_attributes(XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_precision($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field precision (integer) to smaller one'] = $test;
     }
     /// 19th test. Change the sign of one numeric field to unsigned
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade');
         $field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', XMLDB_UNSIGNED, null, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_unsigned($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field sign (unsigned)'] = $test;
     }
     /// 20th test. Change the sign of one numeric field to signed
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('grade');
         $field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null);
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_unsigned($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field sign (signed)'] = $test;
     }
     /// 21th test. Change the nullability of one char field to not null
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('name');
         $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, 'Moodle');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_notnull($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field nullability (not null)'] = $test;
     }
     /// 22th test. Change the nullability of one char field to null
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('name');
         $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
         $test->sql = $gen->getAlterFieldSQL($table, $field);
         try {
             $dbman->change_field_notnull($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['change field nullability (null)'] = $test;
     }
     /// 23th test. Dropping the default of one field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('name');
         $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, null);
         $test->sql = $gen->getModifyDefaultSQL($table, $field);
         try {
             $dbman->change_field_default($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop field default of NULL field'] = $test;
     }
     /// 24th test. Creating the default for one field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('name');
         $field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
         $test->sql = $gen->getModifyDefaultSQL($table, $field);
         try {
             $dbman->change_field_default($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field default of NULL field'] = $test;
     }
     /// 25th test. Creating the default for one field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('secondname');
         $field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, 'Moodle2');
         $test->sql = $gen->getModifyDefaultSQL($table, $field);
         try {
             $dbman->change_field_default($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field default of NOT NULL field'] = $test;
     }
     /// 26th test. Dropping the default of one NOT NULL field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('secondname');
         $field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null);
         $test->sql = $gen->getModifyDefaultSQL($table, $field);
         try {
             $dbman->change_field_default($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop field default of NOT NULL field'] = $test;
     }
     /// 27th test. Adding one unique index to the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $index = new xmldb_index('secondname');
         $index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'secondname', 'grade'));
         $test->sql = $gen->getAddIndexSQL($table, $index);
         try {
             $dbman->add_index($table, $index, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add unique index'] = $test;
     }
     /// 28th test. Adding one not unique index to the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $index = new xmldb_index('secondname');
         $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
         $test->sql = $gen->getAddIndexSQL($table, $index);
         try {
             $dbman->add_index($table, $index, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add not unique index'] = $test;
     }
     /// 29th test. Re-add the same index than previous test. Check find_index_name() works.
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $index = new xmldb_index('secondname');
         $index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('name', 'course'));
         if ($indexfound = $dbman->find_index_name($table, $index)) {
             $test->status = true;
             $test->sql = array();
         } else {
             $test->status = true;
             $test->error = 'Index not found!';
             $test->sql = array();
         }
         $tests['check find_index_name()'] = $test;
     }
     /// 30th test. Dropping one index from the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $index = new xmldb_index('name');
         $index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'grade', 'secondname'));
         $test->sql = $gen->getDropIndexSQL($table, $index);
         try {
             $dbman->drop_index($table, $index, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop index'] = $test;
     }
     /// 31th test. Adding one unique key to the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('id-course-grade');
         $key->set_attributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
         $test->sql = $gen->getAddKeySQL($table, $key);
         try {
             $dbman->add_key($table, $key, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add unique key'] = $test;
     }
     /// 32th test. Adding one foreign+unique key to the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('course');
         $key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
         $test->sql = $gen->getAddKeySQL($table, $key);
         try {
             $dbman->add_key($table, $key, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add foreign+unique key'] = $test;
     }
     /// 33th test. Drop one key
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('course');
         $key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
         $test->sql = $gen->getDropKeySQL($table, $key);
         try {
             $dbman->drop_key($table, $key, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop foreign+unique key'] = $test;
     }
     /// 34th test. Adding one foreign key to the table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('course');
         $key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
         $test->sql = $gen->getAddKeySQL($table, $key);
         try {
             $dbman->add_key($table, $key, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add foreign key'] = $test;
     }
     /// 35th test. Drop one foreign key
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('course');
         $key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
         $test->sql = $gen->getDropKeySQL($table, $key);
         try {
             $dbman->drop_key($table, $key, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop foreign key'] = $test;
     }
     /// 36th test. Adding one complex field and forcing creation of enum/ck manually (to test dropping latter)
     /// TODO: Drop this test in Moodle 2.1
     if ($test->status) {
         /// Create a new field with complex specs (enums are good candidates)
         $field = new xmldb_field('type');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getAddFieldSQL($table, $field);
         try {
             $dbman->add_field($table, $field, false, false);
             $test->status = true;
             /// Now, let's add one enum/check manually, because XMLDB stuff hasn't support for that
             /// anymore. We are dropping enums support, but need to check dropping them until Moodle 2.1.
             switch ($dbfamily) {
                 case 'mysql':
                     $create_enum = "ALTER TABLE {anothertest} MODIFY COLUMN type enum('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda') NOT NULL DEFAULT 'general'";
                     break;
                 case 'mssql':
                 case 'oracle':
                 case 'postgres':
                     $create_enum = "ALTER TABLE {anothertest} ADD CONSTRAINT xmldb_ck CHECK (type IN ('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'))";
                     break;
             }
             $test->sql[] = $create_enum;
             $DB->execute($create_enum);
             /// Create the enum/check. Not the best way but works for this needed test
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field with enum/ck manually'] = $test;
     }
     /// 37th test. Dropping one field containing enum/ck
     /// TODO: Drop this test in Moodle 2.1
     if ($test->status) {
         $test = new stdClass();
         $test->sql = $gen->getDropFieldSQL($table, $field);
         $field = new xmldb_field('type');
         try {
             $dbman->drop_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop field with enum/ck'] = $test;
     }
     /// 38th test. Adding one complex field and forcing creation of enum/ck manually (to test dropping latter)
     /// TODO: Drop this test in Moodle 2.1
     if ($test->status) {
         /// Create a new field with complex specs (enums are good candidates)
         $field = new xmldb_field('type');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getAddFieldSQL($table, $field);
         try {
             $dbman->add_field($table, $field, false, false);
             $test->status = true;
             /// Now, let's add one enum/check manually, because XMLDB stuff hasn't support for that
             /// anymore. We are dropping enums support, but need to check dropping them until Moodle 2.1.
             switch ($dbfamily) {
                 case 'mysql':
                     $create_enum = "ALTER TABLE {anothertest} MODIFY COLUMN type enum('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda') NOT NULL DEFAULT 'general'";
                     break;
                 case 'mssql':
                 case 'oracle':
                 case 'postgres':
                     $create_enum = "ALTER TABLE {anothertest} ADD CONSTRAINT xmldb_ck CHECK (type IN ('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'))";
                     break;
             }
             $test->sql[] = $create_enum;
             $DB->execute($create_enum);
             /// Create the enum/check. Not the best way but works for this needed test
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['add field with enum/ck manually again'] = $test;
     }
     /// 39th test. Dropping the enum from one field
     /// TODO: Drop this test in Moodle 2.1
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('type');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         $test->sql = $gen->getDropEnumSQL($table, $field);
         try {
             $dbman->drop_enum_from_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop enum/ck from field containing enum'] = $test;
     }
     /// 40th test. Drop enum from field not containing enum
     /// TODO: Drop this test in Moodle 2.1
     if ($test->status) {
         /// Drop enum from field not containing enum
         $field = new xmldb_field('type');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getDropEnumSQL($table, $field);
         try {
             $dbman->drop_enum_from_field($table, $field, false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['drop enum/ck from field not containing enum'] = $test;
     }
     /// 41th test. Renaming one index
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $index = new xmldb_index('anyname');
         $index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'course'));
         $test->sql = $gen->getRenameIndexSQL($table, $index, 'newnamefortheindex');
         try {
             $dbman->rename_index($table, $index, 'newnamefortheindex', false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . "Getting this error is the expected behaviour. Function is experimental and ins't used in code at all. Don't worry!";
         }
         $tests['rename index (experimental. DO NOT USE IT)'] = $test;
         $test = new stdClass();
         $test->status = true;
         // ignore errors here
     }
     /// 42th test. Renaming one key
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $key = new xmldb_key('anyname');
         $key->set_attributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
         $test->sql = $gen->getRenameKeySQL($table, $key, 'newnameforthekey', true);
         $olddebug = $CFG->debug;
         if ($olddebug > DEBUG_ALL) {
             $CFG->debug = DEBUG_ALL;
             // do not show experimental debug warning
         }
         try {
             $dbman->rename_key($table, $key, 'newnameforthekey', false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . "Getting this error is the expected behaviour. Function is experimental and ins't used in code at all. Don't worry!";
         }
         $CFG->debug = $olddebug;
         $tests['rename key (experimental. DO NOT USE IT)'] = $test;
         $test = new stdClass();
         $test->status = true;
         // ignore errors here
     }
     /// 43th test. Renaming one field
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $field = new xmldb_field('type');
         $field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
         $test->sql = $gen->getRenameFieldSQL($table, $field, 'newnameforthefield', true);
         try {
             $dbman->rename_field($table, $field, 'newnameforthefield', false, false);
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['rename field'] = $test;
     }
     /// 44th test. Renaming one table
     if ($test->status) {
         /// Get SQL code and execute it
         $test = new stdClass();
         $test->sql = $gen->getRenameTableSQL($table, 'newnameforthetable', true);
         try {
             $dbman->rename_table($table, 'newnameforthetable');
             $test->status = true;
         } catch (moodle_exception $e) {
             $test->status = false;
             $test->error = $DB->get_last_error() . "\n" . $e;
         }
         $tests['rename table'] = $test;
     }
     /// 45th test. Getting the PK sequence name for one table
     if ($test->status) {
         $table->setName('newnameforthetable');
         $test = new stdClass();
         $test->sql = array($dbman->find_sequence_name($table));
         $test->status = $dbman->find_sequence_name($table);
         if (!$test->status) {
             if (!($test->error = $DB->get_last_error())) {
                 //If no db errors, result is ok. Just the driver doesn't support this
                 $test->sql = array('Not needed for this DB. Correct.');
                 $test->status = true;
             } else {
                 $test->error .= "\n" . $e;
             }
         }
         $tests['find sequence name'] = $test;
     }
     /// 46th test. Inserting TEXT contents
     $textlib = textlib_get_instance();
     if ($test->status) {
         $test = new stdClass();
         $test->status = false;
         $test->sql = array();
         $basetext = "\\ ''語 • Русский • Deutsch • English • Español • Français • Italiano • Nederlands • Polski • Português • Svenska • العربية • فارسی 한국어 • עברית • ไทย中文  Ελληνικά • Български • Српски • Українська • Bosanski • Català • Česky • Dansk • Eesti • Simple English • Esperanto • Euskara • Galego • Hrvatski • Ido • Bahasa Indonesia • Íslenska • Lëtzebuergesch • Lietuvių • Magyar • Bahasa Melayu اردو • ئۇيغۇرچه • हिन्दी • नेपाल भाषा मराठी • தமிழ் Հայերեն • Беларуская • Чăваш • Ирон æвзаг • Македонски • Сибирской говор • Afrikaans • Aragonés • Arpitan • Asturianu • Kreyòl Ayisyen • Azərbaycan • Bân-lâm-gú • Basa Banyumasan • Brezhoneg • Corsu • Cymraeg • Deitsch • Føroyskt • Frysk • Furlan • Gaeilge • Gàidhlig • Ilokano • Interlingua • Basa Jawa • Kapampangan • Kernewek • Kurdî  كوردی • Ladino  לאדינו • Latina • Latviešu • Limburgs • Lumbaart • Nedersaksisch • Nouormand • Occitan • O‘zbek • Piemontèis • Plattdüütsch • Ripoarisch • Sámegiella • Scots • Shqip • Sicilianu • Sinugboanon • Srpskohrvatski / Српскохрватски • Basa Sunda • Kiswahili • Tagalog • Tatarça • Walon • Winaray  Авар • Башҡорт • Кыргызча  Монгол • Қазақша • Тоҷикӣ • Удмурт • Armãneashce • Bamanankan • Eald Englisc • Gaelg • Interlingue • Kaszëbsczi • Kongo • Ligure • Lingála • lojban • Malagasy • Malti • Māori • Nāhuatl • Ekakairũ Naoero • Novial • Pangasinán • Tok Pisin • Romani / रोमानी • Rumantsch • Runa Simi • Sardu • Tetun • Türkmen / تركمن / Туркмен • Vèneto • Volapük • Võro • West-Vlaoms • Wollof • Zazaki • Žemaitėška";
         /// Create one big text (1.500.000 chars)
         $fulltext = '';
         for ($i = 0; $i < 1000; $i++) {
             //1500 * 1000 chars
             $fulltext .= $basetext;
         }
         /// Build the record to insert
         $rec->intro = $fulltext;
         $rec->name = 'texttest';
         /// Calculate its length
         $textlen = $textlib->strlen($fulltext);
         if ($rec->id = $DB->insert_record('newnameforthetable', $rec)) {
             if ($new = $DB->get_record('newnameforthetable', array('id' => $rec->id))) {
                 $DB->delete_records('newnameforthetable', array('id' => $new->id));
                 $newtextlen = $textlib->strlen($new->intro);
                 if ($fulltext === $new->intro) {
                     $test->sql = array($newtextlen . ' cc. (text) sent and received ok');
                     $test->status = true;
                 } else {
                     $test->error = $DB->get_last_error();
                     $test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
                     $test->status = false;
                 }
             } else {
                 $test->error = $DB->get_last_error() . 'xx';
             }
         } else {
             $test->error = $DB->get_last_error() . 'yy' . var_export($rec->id, true);
         }
         $tests['insert record ' . $textlen . ' cc. (text)'] = $test;
     }
     /// 47th test. Inserting BINARY contents
     if ($test->status) {
         $test = new stdClass();
         $test->status = false;
         /// Build the record to insert
         $rec->avatar = $fulltext;
         $rec->name = 'binarytest';
         /// Calculate its length
         $textlen = strlen($rec->avatar);
         if ($rec->id = $DB->insert_record('newnameforthetable', $rec)) {
             if ($new = $DB->get_record('newnameforthetable', array('id' => $rec->id))) {
                 $newtextlen = strlen($new->avatar);
                 if ($rec->avatar === $new->avatar) {
                     $test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
                     $test->status = true;
                 } else {
                     $test->error = $DB->get_last_error();
                     $test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
                     $test->status = false;
                 }
             } else {
                 $test->error = $DB->get_last_error();
             }
         } else {
             $test->error = $DB->get_last_error();
         }
         $tests['insert record ' . $textlen . ' bytes (binary)'] = $test;
     }
     /// 48th test. $DB->update_record with TEXT and BINARY contents
     if ($test->status) {
         $test = new stdClass();
         $test->status = false;
         $test->sql = array();
         /// Build the record to insert
         $rec->intro = $basetext;
         $rec->avatar = $basetext;
         $rec->name = 'updatelobs';
         /// Calculate its length
         $textlen = $textlib->strlen($basetext);
         $imglen = strlen($basetext);
         if ($DB->update_record('newnameforthetable', $rec)) {
             if ($new = $DB->get_record('newnameforthetable', array('id' => $rec->id))) {
                 $newtextlen = $textlib->strlen($new->intro);
                 $newimglen = strlen($new->avatar);
                 if ($basetext === $new->avatar && $basetext === $new->intro) {
                     $test->sql = array($newtextlen . ' cc. (text) sent and received ok', $newimglen . ' bytes (binary) sent and received ok');
                     $test->status = true;
                 } else {
                     if ($rec->avatar !== $new->avatar) {
                         $test->error = $DB->get_last_error();
                         $test->sql = array($newimglen . ' bytes (binary) transfer failed. Data changed!');
                         $test->status = false;
                     } else {
                         $test->error = $DB->get_last_error();
                         $test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
                         $test->status = false;
                     }
                 }
             } else {
                 $test->error = $DB->get_last_error();
             }
         } else {
             $test->error = $DB->get_last_error();
         }
         $tests['update record ' . $textlen . ' cc. (text) and ' . $imglen . ' bytes (binary)'] = $test;
     }
     /// 49th test. $DB->set_field with TEXT contents
     if ($test->status) {
         $test = new stdClass();
         $test->status = false;
         $test->sql = array();
         /// Build the record to insert
         $rec->intro = $fulltext;
         $rec->name = 'updatelobs';
         /// Calculate its length
         $textlen = $textlib->strlen($fulltext);
         if ($DB->set_field('newnameforthetable', 'intro', $rec->intro, array('name' => $rec->name))) {
             if ($new = $DB->get_record('newnameforthetable', array('id' => $rec->id))) {
                 $newtextlen = $textlib->strlen($new->intro);
                 if ($fulltext === $new->intro) {
                     $test->sql = array($newtextlen . ' cc. (text) sent and received ok');
                     $test->status = true;
                 } else {
                     $test->error = $DB->get_last_error();
                     $test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
                     $test->status = false;
                 }
             } else {
                 $test->error = $DB->get_last_error();
             }
         } else {
             $test->error = $DB->get_last_error();
         }
         $tests['set field ' . $textlen . ' cc. (text)'] = $test;
     }
     /// 50th test. $DB->set_field with BINARY contents
     if ($test->status) {
         $test = new stdClass();
         $test->status = false;
         $test->sql = array();
         /// Build the record to insert
         $rec->avatar = $fulltext;
         $rec->name = 'updatelobs';
         /// Calculate its length
         $textlen = strlen($rec->avatar);
         if ($DB->set_field('newnameforthetable', 'avatar', $rec->avatar, array('name' => $rec->name))) {
             if ($new = $DB->get_record('newnameforthetable', array('id' => $rec->id))) {
                 $newtextlen = strlen($new->avatar);
                 if ($rec->avatar === $new->avatar) {
                     $test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
                     $test->status = true;
                 } else {
                     $test->error = $DB->get_last_error();
                     $test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
                     $test->status = false;
                 }
             } else {
                 $test->error = $DB->get_last_error();
             }
         } else {
             $test->error = $DB->get_last_error();
         }
         $tests['set field ' . $textlen . ' bytes (binary)'] = $test;
     }
     /// TODO: Check here values of the inserted records to see that everything has the correct value
     /// Iterate over tests, showing information as needed
     $o .= '<ol>';
     foreach ($tests as $key => $test) {
         $o .= '<li>' . $key . ($test->status ? '<font color="green"> Ok</font>' : ' <font color="red">Error</font>');
         if (!$test->status) {
             $o .= '<br/><font color="red">' . $test->error . '</font>';
         }
         $o .= '<pre>' . implode('<br/>', $test->sql) . '</pre>';
         $o .= '</li>';
     }
     $o .= '</ol>';
     $this->output = $o;
     /// Launch postaction if exists (leave this here!)
     if ($this->getPostAction() && $result) {
         return $this->launch($this->getPostAction());
     }
     /// Return ok if arrived here
     return $result;
 }
Exemplo n.º 12
0
function xmldb_core_install() {
    global $CFG, $DB, $SITE;

    // switch to new default theme 
    set_config('theme', 'standard');

    $dbman = $DB->get_manager(); // loads ddl manager and xmldb classes
    $systemcontext = context_system::instance();
    // add coursetype and icon fields to course table

    $table = new xmldb_table('course');

    $field = new xmldb_field('coursetype');
    if (!$dbman->field_exists($table, $field)) {
        $field->set_attributes(XMLDB_TYPE_INTEGER, '4', null, null, null, null, null);
        $dbman->add_field($table, $field);
    }

    $field = new xmldb_field('icon');
    if (!$dbman->field_exists($table, $field)) {
        $field->set_attributes(XMLDB_TYPE_CHAR, '255', null, null, null, null);
        $dbman->add_field($table, $field);
    }

    // rename the moodle 'manager' fullname to "Site Manager" to make it
    // distinct from the "Staff Manager"
    if ($managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager', 'name' => get_string('manager', 'role')))) {
        $todb = new stdClass();
        $todb->id = $managerroleid;
        $todb->name = get_string('sitemanager', 'local_core');
        $DB->update_record('role', $todb);
    }

    // Create roles.
    $manager             = $DB->get_record('role', array('shortname' => 'manager'));
    $managerrole         = $manager->id;
    $staffmanagerrole    = create_role('', 'staffmanager', '', 'staffmanager');
    $assessorrole        = create_role('', 'assessor', '', 'assessor');
    $regionalmanagerrole = create_role('', 'regionalmanager', '');
    $regionaltrainerrole = create_role('', 'regionaltrainer', '');

    $defaultallowassigns = array(
        array($managerrole, $staffmanagerrole),
        array($managerrole, $assessorrole),
        array($managerrole, $regionalmanagerrole),
        array($managerrole, $regionaltrainerrole)
    );
    foreach ($defaultallowassigns as $allow) {
        list($fromroleid, $toroleid) = $allow;
        allow_assign($fromroleid, $toroleid);
    }

    $defaultallowoverrides = array(
        array($managerrole, $staffmanagerrole),
        array($managerrole, $assessorrole),
        array($managerrole, $regionalmanagerrole),
        array($managerrole, $regionaltrainerrole)
    );
    foreach ($defaultallowoverrides as $allow) {
        list($fromroleid, $toroleid) = $allow;
        allow_override($fromroleid, $toroleid); // There is a rant about this in MDL-15841.
    }

    $defaultallowswitch = array(
        array($managerrole, $staffmanagerrole),
    );
    foreach ($defaultallowswitch as $allow) {
        list($fromroleid, $toroleid) = $allow;
        allow_switch($fromroleid, $toroleid);
    }

    set_role_contextlevels($staffmanagerrole,   get_default_contextlevels('staffmanager'));
    assign_capability('moodle/user:viewdetails', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/user:viewuseractivitiesreport', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/cohort:view', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/comment:view', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/comment:delete', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/comment:post', CAP_ALLOW, $staffmanagerrole, $systemcontext->id, true);
    $systemcontext->mark_dirty();
    set_role_contextlevels($assessorrole,       get_default_contextlevels('teacher'));

    $role_to_modify = array(
        'editingteacher' => 'editingtrainer',
        'teacher' => 'trainer',
        'student' => 'learner'
    );

    $DB->update_record('role', array('id' => $assessorrole, 'archetype' => 'assessor'));
    assign_capability('moodle/user:editownprofile', CAP_ALLOW, $assessorrole, $systemcontext->id, true);
    assign_capability('moodle/user:editownprofile', CAP_ALLOW, $regionalmanagerrole, $systemcontext->id, true);
    assign_capability('moodle/user:editownprofile', CAP_ALLOW, $regionaltrainerrole, $systemcontext->id, true);

    foreach ($role_to_modify as $old => $new) {
        if ($old_role = $DB->get_record('role', array('shortname' => $old))) {
            $new_role = new stdClass();
            $new_role->id = $old_role->id;
            $new_role->name = '';
            $new_role->description = '';

            $DB->update_record('role', $new_role);
        }
    }



    // Set up frontpage.
    set_config('frontpage', '');
    set_config('frontpageloggedin', '');

    require_once($CFG->dirroot . '/lib/completionlib.php');
    if(!completion_info::is_enabled_for_site()){
        set_config('coreinstallation', 1);
        set_config('enablecompletion', 1);
        set_config('enablecompletion', 1, 'moodlecourse');
        set_config('completionstartonenrol', 1, 'moodlecourse');
    }
    // Add completionstartonenrol column to course table.
    $table = new xmldb_table('course');

    // Define field completionstartonenrol to be added to course.
    $field = new xmldb_field('completionstartonenrol', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');

    // Conditionally launch add field completionstartonenrol.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Add RPL column to course_completions table
    $table = new xmldb_table('course_completions');

    // Define field rpl to be added to course_completions
    $field = new xmldb_field('rpl', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'reaggregate');

    // Conditionally launch add field rpl
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Define field rplgrade to be added to course_completions
    $field = new xmldb_field('rplgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, 'rpl');

    // Conditionally launch add field rpl
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Add RPL column to course_completion_crit_compl table
    $table = new xmldb_table('course_completion_crit_compl');

    // Define field rpl to be added to course_completion_crit_compl
    $field = new xmldb_field('rpl', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'unenroled');

    // Conditionally launch add field rpl
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Define fields status and renewalstatus to be added to course_completions.
    $table = new xmldb_table('course_completions');
    $field = new xmldb_field('status', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');

    // Conditionally launch add field status.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    $field = new xmldb_field('renewalstatus', XMLDB_TYPE_INTEGER, '2', null, null, null, '0');

    // Conditionally launch add field renewalstatus.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    rebuild_course_cache($SITE->id, true);

    // readd specific course completion changes for anyone
    // upgrading from moodle 2.2.2+
    require_once($CFG->dirroot . '/local/core/db/utils.php');
    local_readd_course_completion_changes();

    // remove any references to "complete on unenrolment" critiera type
    // these could exist in an upgrade from moodle 2.2 but the criteria
   
    $DB->delete_records('course_completion_criteria', array('criteriatype' => 3));

    //disable autoupdate notifications from Moodle
    set_config('disableupdatenotifications', '1');
    set_config('disableupdateautodeploy', '1');
    set_config('updateautodeploy', false);
    set_config('updateautocheck', false);
    set_config('updatenotifybuilds', false);

    // Disable editing execpaths by default for security.
    set_config('preventexecpath', '1');
    // Then provide default values to prevent them appearing on the upgradesettings page.
    set_config('geoipfile', $CFG->dataroot . 'geoip/GeoLiteCity.dat');
    set_config('location', '', 'enrol_flatfile');
    set_config('filter_tex_pathlatex', '/usr/bin/latex');
    set_config('filter_tex_pathdvips', '/usr/bin/dvips');
    set_config('filter_tex_pathconvert', '/usr/bin/convert');
    set_config('pathtodu', '');
    set_config('pathtoclam', '');
    set_config('aspellpath', '');
    set_config('pathtodot', '');
    set_config('quarantinedir', '');
    set_config('backup_auto_destination', '', 'backup');
    // Adding some upgrade code from lib/db/upgrade.php to
    // avoid conflicts every time we upgrade moodle.
    // This can be removed once we reach the verion of Moodle that
    // includes this functionality. E.g. 2.5 for badges, 2.6? for
    // course completion.

    // Add openbadges tables.

    // Define table 'badge' to be created
    $table = new xmldb_table('badge');

    // Adding fields to table 'badge'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'id');
    $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null, 'name');
    $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'description');
    $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
    $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timemodified');
    $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'usercreated');
    $table->add_field('issuername', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'usermodified');
    $table->add_field('issuerurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'issuername');
    $table->add_field('issuercontact', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'issuerurl');
    $table->add_field('expiredate', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'issuercontact');
    $table->add_field('expireperiod', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'expiredate');
    $table->add_field('type', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'expireperiod');
    $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'type');
    $table->add_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'courseid');
    $table->add_field('messagesubject', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'message');
    $table->add_field('attachment', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'messagesubject');
    $table->add_field('notification', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'attachment');
    $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'notification');
    $table->add_field('nextcron', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'status');

    // Adding keys to table 'badge'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
    $table->add_key('fk_usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
    $table->add_key('fk_usercreated', XMLDB_KEY_FOREIGN, array('usercreated'), 'user', array('id'));

    // Adding indexes to table 'badge'
    $table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));

    // Set the comment for the table 'badge'.
    $table->setComment('Defines badge');

    // Conditionally launch create table for 'badge'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_criteria' to be created
    $table = new xmldb_table('badge_criteria');

    // Adding fields to table 'badge_criteria'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
    $table->add_field('criteriatype', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'badgeid');
    $table->add_field('method', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'criteriatype');

    // Adding keys to table 'badge_criteria'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));

    // Adding indexes to table 'badge_criteria'
    $table->add_index('criteriatype', XMLDB_INDEX_NOTUNIQUE, array('criteriatype'));
    $table->add_index('badgecriteriatype', XMLDB_INDEX_UNIQUE, array('badgeid', 'criteriatype'));

    // Set the comment for the table 'badge_criteria'.
    $table->setComment('Defines criteria for issuing badges');

    // Conditionally launch create table for 'badge_criteria'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_criteria_param' to be created
    $table = new xmldb_table('badge_criteria_param');

    // Adding fields to table 'badge_criteria_param'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
    $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'critid');
    $table->add_field('value', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name');

    // Adding keys to table 'badge_criteria_param'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));

    // Set the comment for the table 'badge_criteria_param'.
    $table->setComment('Defines parameters for badges criteria');

    // Conditionally launch create table for 'badge_criteria_param'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_issued' to be created
    $table = new xmldb_table('badge_issued');

    // Adding fields to table 'badge_issued'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
    $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'badgeid');
    $table->add_field('uniquehash', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'userid');
    $table->add_field('dateissued', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'uniquehash');
    $table->add_field('dateexpire', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'dateissued');
    $table->add_field('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'dateexpire');
    $table->add_field('issuernotified', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'visible');

    // Adding keys to table 'badge_issued'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
    $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));

    // Adding indexes to table 'badge_issued'
    $table->add_index('badgeuser', XMLDB_INDEX_UNIQUE, array('badgeid', 'userid'));

    // Set the comment for the table 'badge_issued'.
    $table->setComment('Defines issued badges');

    // Conditionally launch create table for 'badge_issued'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_criteria_met' to be created
    $table = new xmldb_table('badge_criteria_met');

    // Adding fields to table 'badge_criteria_met'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('issuedid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'id');
    $table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuedid');
    $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'critid');
    $table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');

    // Adding keys to table 'badge_criteria_met'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));
    $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
    $table->add_key('fk_issuedid', XMLDB_KEY_FOREIGN, array('issuedid'), 'badge_issued', array('id'));

    // Set the comment for the table 'badge_criteria_met'.
    $table->setComment('Defines criteria that were met for an issued badge');

    // Conditionally launch create table for 'badge_criteria_met'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_manual_award' to be created
    $table = new xmldb_table('badge_manual_award');

    // Adding fields to table 'badge_manual_award'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
    $table->add_field('recipientid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'badgeid');
    $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'recipientid');
    $table->add_field('issuerrole', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerid');
    $table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerrole');

    // Adding keys to table 'badge_manual_award'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
    $table->add_key('fk_recipientid', XMLDB_KEY_FOREIGN, array('recipientid'), 'user', array('id'));
    $table->add_key('fk_issuerid', XMLDB_KEY_FOREIGN, array('issuerid'), 'user', array('id'));
    $table->add_key('fk_issuerrole', XMLDB_KEY_FOREIGN, array('issuerrole'), 'role', array('id'));

    // Set the comment for the table 'badge_manual_award'.
    $table->setComment('Track manual award criteria for badges');

    // Conditionally launch create table for 'badge_manual_award'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define table 'badge_backpack' to be created
    $table = new xmldb_table('badge_backpack');

    // Adding fields to table 'badge_backpack'
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
    $table->add_field('email', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'userid');
    $table->add_field('backpackurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'email');
    $table->add_field('backpackuid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackurl');
    $table->add_field('backpackgid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackuid');
    $table->add_field('autosync', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'backpackgid');
    $table->add_field('password', XMLDB_TYPE_CHAR, '50', null, null, null, null, 'autosync');

    // Adding keys to table 'badge_backpack'
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));

    // Set the comment for the table 'badge_backpack'.
    $table->setComment('Defines settings for connecting external backpack');

    // Conditionally launch create table for 'badge_backpack'
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Create a new 'badge_external' table first.
    // Define table 'badge_external' to be created.
    $table = new xmldb_table('badge_external');

    // Adding fields to table 'badge_external'.
    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('backpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
    $table->add_field('collectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackid');

    // Adding keys to table 'badge_external'.
    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('fk_backpackid', XMLDB_KEY_FOREIGN, array('backpackid'), 'badge_backpack', array('id'));

    // Set the comment for the table 'badge_external'.
    $table->setComment('Setting for external badges display');

    // Conditionally launch create table for 'badge_external'.
    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Define field backpackgid to be dropped from 'badge_backpack'.
    $table = new xmldb_table('badge_backpack');
    $field = new xmldb_field('backpackgid');

    if ($dbman->field_exists($table, $field)) {
        // Perform user data migration.
        $usercollections = $DB->get_records('badge_backpack');
        foreach ($usercollections as $usercollection) {
            $collection = new stdClass();
            $collection->backpackid = $usercollection->id;
            $collection->collectionid = $usercollection->backpackgid;
            $DB->insert_record('badge_external', $collection);
        }

        // Launch drop field backpackgid.
        $dbman->drop_field($table, $field);
    }

    // Create missing badgeid foreign key on badge_manual_award.
    $table = new xmldb_table('badge_manual_award');
    $key = new xmldb_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('id'), 'badge', array('id'));

    $dbman->drop_key($table, $key);
    $key->set_attributes(XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
    $dbman->add_key($table, $key);

    // Drop unused badge image field.
    $table = new xmldb_table('badge');
    $field = new xmldb_field('image', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'description');

    // Conditionally launch drop field eventtype.
    if ($dbman->field_exists($table, $field)) {
        $dbman->drop_field($table, $field);
    }

    // Define field completionprogressonview to be added to course.
    $table = new xmldb_table('course');
    $field = new xmldb_field('completionprogressonview', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'enablecompletion');

    // Conditionally launch add field completionprogressonview.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    $field = new xmldb_field('audiencevisible', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 2);

    // Conditionally launch add field audiencevisible to course table.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Define field invalidatecache to be added to course_completions.
    $table = new xmldb_table('course_completions');
    $field = new xmldb_field('invalidatecache', XMLDB_TYPE_INTEGER, '1', null, null, null, '0');

    // Conditionally launch add field invalidatecache.
    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    // Backporting MDL-41914 to add new webservice core_user_add_user_device.
    $table = new xmldb_table('user_devices');

    $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
    $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
    $table->add_field('appid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, 'userid');
    $table->add_field('name', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'appid');
    $table->add_field('model', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'name');
    $table->add_field('platform', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'model');
    $table->add_field('version', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'platform');
    $table->add_field('pushid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'version');
    $table->add_field('uuid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'pushid');
    $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'uuid');
    $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timecreated');

    $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
    $table->add_key('pushid-userid', XMLDB_KEY_UNIQUE, array('pushid', 'userid'));
    $table->add_key('pushid-platform', XMLDB_KEY_UNIQUE, array('pushid', 'platform'));
    $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));

    if (!$dbman->table_exists($table)) {
        $dbman->create_table($table);
    }

    // Add timecompleted for module completion.
    $table = new xmldb_table('course_modules_completion');
    $field = new xmldb_field('timecompleted', XMLDB_TYPE_INTEGER, '10');

    if (!$dbman->field_exists($table, $field)) {
        $dbman->add_field($table, $field);
    }

    return true;
}