New icon to support toc bug fix
[moodle.git] / lib / db / mysql.php
1 <?PHP  //$Id$
2 //
3 // This file keeps track of upgrades to Moodle.
4 //
5 // Sometimes, changes between versions involve
6 // alterations to database structures and other
7 // major things that may break installations.
8 //
9 // The upgrade function in this file will attempt
10 // to perform all the necessary actions to upgrade
11 // your older installtion to the current version.
12 //
13 // If there's something it cannot do itself, it
14 // will tell you what you need to do.
15 //
16 // Versions are defined by /version.php
17 //
18 // This file is tailored to MySQL
20 function main_upgrade($oldversion=0) {
22     global $CFG, $THEME, $db;
24     $result = true;
26     if ($oldversion == 0) {
27         execute_sql("
28           CREATE TABLE `config` (
29             `id` int(10) unsigned NOT NULL auto_increment,
30             `name` varchar(255) NOT NULL default '',
31             `value` varchar(255) NOT NULL default '',
32             PRIMARY KEY  (`id`),
33             UNIQUE KEY `name` (`name`)
34           ) COMMENT='Moodle configuration variables';");
35         notify("Created a new table 'config' to hold configuration data");
36     }
37     if ($oldversion < 2002073100) {
38         execute_sql(" DELETE FROM `modules` WHERE `name` = 'chat' ");
39     }
40     if ($oldversion < 2002080200) {
41         execute_sql(" ALTER TABLE `modules` DROP `fullname`  ");
42         execute_sql(" ALTER TABLE `modules` DROP `search`  ");
43     }
44     if ($oldversion < 2002080300) {
45         execute_sql(" ALTER TABLE `log_display` CHANGE `table` `mtable` VARCHAR( 20 ) NOT NULL ");
46         execute_sql(" ALTER TABLE `user_teachers` CHANGE `authority` `authority` TINYINT( 3 ) DEFAULT '3' NOT NULL ");
47     }
48     if ($oldversion < 2002082100) {
49         execute_sql(" ALTER TABLE `course` CHANGE `guest` `guest` TINYINT(2) UNSIGNED DEFAULT '0' NOT NULL ");
50     }
51     if ($oldversion < 2002082101) {
52         execute_sql(" ALTER TABLE `user` ADD `maildisplay` TINYINT(2) UNSIGNED DEFAULT '2' NOT NULL AFTER `mailformat` ");
53     }
54     if ($oldversion < 2002090100) {
55         execute_sql(" ALTER TABLE `course_sections` CHANGE `summary` `summary` TEXT NOT NULL ");
56     }
57     if ($oldversion < 2002090701) {
58         execute_sql(" ALTER TABLE `user_teachers` CHANGE `authority` `authority` TINYINT( 10 ) DEFAULT '3' NOT NULL ");
59         execute_sql(" ALTER TABLE `user_teachers` ADD `role` VARCHAR(40) NOT NULL AFTER `authority` ");
60     }
61     if ($oldversion < 2002090800) {
62         execute_sql(" ALTER TABLE `course` ADD `teachers` VARCHAR( 100 ) DEFAULT 'Teachers' NOT NULL AFTER `teacher` ");
63         execute_sql(" ALTER TABLE `course` ADD `students` VARCHAR( 100 ) DEFAULT 'Students' NOT NULL AFTER `student` ");
64     }
65     if ($oldversion < 2002091000) {
66         execute_sql(" ALTER TABLE `user` CHANGE `personality` `secret` VARCHAR( 15 ) NOT NULL DEFAULT ''  ");
67     }
68     if ($oldversion < 2002091400) {
69         execute_sql(" ALTER TABLE `user` ADD `lang` VARCHAR( 3 ) DEFAULT 'en' NOT NULL AFTER `country`  ");
70     }
71     if ($oldversion < 2002091900) {
72         notify("Most Moodle configuration variables have been moved to the database and can now be edited via the admin page.");
73         notify("Although it is not vital that you do so, you might want to edit <U>config.php</U> and remove all the unused settings (except the database, URL and directory definitions).  See <U>config-dist.php</U> for an example of how your new slim config.php should look.");
74     }
75     if ($oldversion < 2002092000) {
76         execute_sql(" ALTER TABLE `user` CHANGE `lang` `lang` VARCHAR(5) DEFAULT 'en' NOT NULL  ");
77     }
78     if ($oldversion < 2002092100) {
79         execute_sql(" ALTER TABLE `user` ADD `deleted` TINYINT(1) UNSIGNED DEFAULT '0' NOT NULL AFTER `confirmed` ");
80     }
81     if ($oldversion < 2002101001) {
82         execute_sql(" ALTER TABLE `user` ADD `htmleditor` TINYINT(1) UNSIGNED DEFAULT '1' NOT NULL AFTER `maildisplay` ");
83     }
84     if ($oldversion < 2002101701) {
85         execute_sql(" ALTER TABLE `reading` RENAME `resource` ");  // Small line with big consequences!
86         execute_sql(" DELETE FROM `log_display` WHERE module = 'reading'");
87         execute_sql(" INSERT INTO log_display (module, action, mtable, field) VALUES ('resource', 'view', 'resource', 'name') ");
88         execute_sql(" UPDATE log SET module = 'resource' WHERE module = 'reading' ");
89         execute_sql(" UPDATE modules SET name = 'resource' WHERE name = 'reading' ");
90     }
92     if ($oldversion < 2002102503) {
93         execute_sql(" ALTER TABLE `course` ADD `modinfo` TEXT NOT NULL AFTER `format` ");
94         require_once("$CFG->dirroot/mod/forum/lib.php");
95         require_once("$CFG->dirroot/course/lib.php");
97         if (! $module = get_record("modules", "name", "forum")) {
98             notify("Could not find forum module!!");
99             return false;
100         }
102         // First upgrade the site forums
103         if ($site = get_site()) {
104             print_heading("Making News forums editable for main site (moving to section 1)...");
105             if ($news = forum_get_course_forum($site->id, "news")) {
106                 $mod->course = $site->id;
107                 $mod->module = $module->id;
108                 $mod->instance = $news->id;
109                 $mod->section = 1;
110                 if (! $mod->coursemodule = add_course_module($mod) ) {
111                     notify("Could not add a new course module to the site");
112                     return false;
113                 }
114                 if (! $sectionid = add_mod_to_section($mod) ) {
115                     notify("Could not add the new course module to that section");
116                     return false;
117                 }
118                 if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
119                     notify("Could not update the course module with the correct section");
120                     return false;
121                 }
122             }
123         }
126         // Now upgrade the courses.
127         if ($courses = get_records_sql("SELECT * FROM course WHERE category > 0")) {
128             print_heading("Making News and Social forums editable for each course (moving to section 0)...");
129             foreach ($courses as $course) {
130                 if ($course->format == "social") {  // we won't touch them
131                     continue;
132                 }
133                 if ($news = forum_get_course_forum($course->id, "news")) {
134                     $mod->course = $course->id;
135                     $mod->module = $module->id;
136                     $mod->instance = $news->id;
137                     $mod->section = 0;
138                     if (! $mod->coursemodule = add_course_module($mod) ) {
139                         notify("Could not add a new course module to the course '$course->fullname'");
140                         return false;
141                     }
142                     if (! $sectionid = add_mod_to_section($mod) ) {
143                         notify("Could not add the new course module to that section");
144                         return false;
145                     }
146                     if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
147                         notify("Could not update the course module with the correct section");
148                         return false;
149                     }
150                 }
151                 if ($social = forum_get_course_forum($course->id, "social")) {
152                     $mod->course = $course->id;
153                     $mod->module = $module->id;
154                     $mod->instance = $social->id;
155                     $mod->section = 0;
156                     if (! $mod->coursemodule = add_course_module($mod) ) {
157                         notify("Could not add a new course module to the course '$course->fullname'");
158                         return false;
159                     }
160                     if (! $sectionid = add_mod_to_section($mod) ) {
161                         notify("Could not add the new course module to that section");
162                         return false;
163                     }
164                     if (! set_field("course_modules", "section", $sectionid, "id", $mod->coursemodule)) {
165                         notify("Could not update the course module with the correct section");
166                         return false;
167                     }
168                 }
169             }
170         }
171     }
173     if ($oldversion < 2002111003) {
174         execute_sql(" ALTER TABLE `course` ADD `modinfo` TEXT NOT NULL AFTER `format` ");
175         if ($courses = get_records_sql("SELECT * FROM course")) {
176             require_once("$CFG->dirroot/course/lib.php");
177             foreach ($courses as $course) {
179                 $modinfo = serialize(get_array_of_activities($course->id));
181                 if (!set_field("course", "modinfo", $modinfo, "id", $course->id)) {
182                     notify("Could not cache module information for course '$course->fullname'!");
183                 }
184             }
185         }
186     }
188     if ($oldversion < 2002111100) {
189         print_simple_box_start("CENTER", "", "#FFCCCC");
190         echo "<FONT SIZE=+1>";
191         echo "<P>Changes have been made to all built-in themes, to add the new popup navigation menu.";
192         echo "<P>If you have customised themes, you will need to edit theme/xxxx/header.html as follows:";
193         echo "<UL><LI>Change anywhere it says <B>$"."button</B> to say <B>$"."menu</B>";
194         echo "<LI>Add <B>$"."button</B> elsewhere (eg at the end of the navigation bar)</UL>";
195         echo "<P>See the standard themes for examples, eg: theme/standard/header.html";
196         print_simple_box_end();
197     }
199     if ($oldversion < 2002111200) {
200         execute_sql(" ALTER TABLE `course` ADD `showrecent` TINYINT(5) UNSIGNED DEFAULT '1' NOT NULL AFTER `numsections` ");
201     }
203     if ($oldversion < 2002111400) {
204     // Rebuild all course caches, because some may not be done in new installs (eg site page)
205         if ($courses = get_records_sql("SELECT * FROM course")) {
206             require_once("$CFG->dirroot/course/lib.php");
207             foreach ($courses as $course) {
209                 $modinfo = serialize(get_array_of_activities($course->id));
211                 if (!set_field("course", "modinfo", $modinfo, "id", $course->id)) {
212                     notify("Could not cache module information for course '$course->fullname'!");
213                 }
214             }
215         }
216     }
218     if ($oldversion < 2002112000) {
219         set_config("guestloginbutton", 1);
220     }
222     if ($oldversion < 2002122300) {
223         execute_sql("ALTER TABLE `log` CHANGE `user` `userid` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
224         execute_sql("ALTER TABLE `user_admins` CHANGE `user` `userid` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
225         execute_sql("ALTER TABLE `user_students` CHANGE `user` `userid` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
226         execute_sql("ALTER TABLE `user_teachers` CHANGE `user` `userid` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
227         execute_sql("ALTER TABLE `user_students` CHANGE `start` `timestart` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
228         execute_sql("ALTER TABLE `user_students` CHANGE `end` `timeend` INT(10) UNSIGNED DEFAULT '0' NOT NULL ");
229     }
231     if ($oldversion < 2002122700) {
232         if (! record_exists("log_display", "module", "user", "action", "view")) {
233             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('user', 'view', 'user', 'CONCAT(firstname,' ',lastname)') ");
234         }
235     }
236     if ($oldversion < 2003010101) {
237         delete_records("log_display", "module", "user");
238         $new->module = "user";
239         $new->action = "view";
240         $new->mtable = "user";
241         $new->field  = "CONCAT(firstname,\" \",lastname)";
242         insert_record("log_display", $new);
244         delete_records("log_display", "module", "course");
245         $new->module = "course";
246         $new->action = "view";
247         $new->mtable = "course";
248         $new->field  = "fullname";
249         insert_record("log_display", $new);
250         $new->action = "update";
251         insert_record("log_display", $new);
252         $new->action = "enrol";
253         insert_record("log_display", $new);
254     }
256     if ($oldversion < 2003012200) {
257         // execute_sql(" ALTER TABLE `log_display` CHANGE `module` `module` VARCHAR( 20 ) NOT NULL ");
258         // Commented out - see below where it's done properly
259     }
261     if ($oldversion < 2003032500) {
262         modify_database("", "CREATE TABLE `prefix_user_coursecreators` (
263                              `id` int(10) unsigned NOT NULL auto_increment,
264                              `userid` int(10) unsigned NOT NULL default '0',
265                              PRIMARY KEY  (`id`),
266                              UNIQUE KEY `id` (`id`)
267                              ) TYPE=MyISAM COMMENT='One record per course creator';");
268     }
269     if ($oldversion < 2003032602) {
270         // Redoing it because of no prefix last time
271         execute_sql(" ALTER TABLE `{$CFG->prefix}log_display` CHANGE `module` `module` VARCHAR( 20 ) NOT NULL ");
272         // Add some indexes for speed
273         execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX(course) ");
274         execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX(userid) ");
275     }
277     if ($oldversion < 2003041400) {
278         table_column("course_modules", "", "visible", "integer", "1", "unsigned", "1", "not null", "score");
279     }
281     if ($oldversion < 2003042104) {  // Try to update permissions of all files
282         if ($files = get_directory_list($CFG->dataroot)) {
283             echo "Attempting to update permissions for all files... ignore any errors.";
284             foreach ($files as $file) {
285                 echo "$CFG->dataroot/$file<br />";
286                 @chmod("$CFG->dataroot/$file", $CFG->directorypermissions);
287             }
288         }
289     }
291     if ($oldversion < 2003042400) {
292     // Rebuild all course caches, because of changes to do with visible variable
293         if ($courses = get_records_sql("SELECT * FROM {$CFG->prefix}course")) {
294             require_once("$CFG->dirroot/course/lib.php");
295             foreach ($courses as $course) {
296                 $modinfo = serialize(get_array_of_activities($course->id));
298                 if (!set_field("course", "modinfo", $modinfo, "id", $course->id)) {
299                     notify("Could not cache module information for course '$course->fullname'!");
300                 }
301             }
302         }
303     }
305     if ($oldversion < 2003042500) {
306     //  Convert all usernames to lowercase.
307         $users = get_records_sql("SELECT id, username FROM {$CFG->prefix}user");
308         $cerrors = "";
309         $rarray = array();
311         foreach ($users as $user) {      // Check for possible conflicts
312             $lcname = trim(moodle_strtolower($user->username));
313             if (in_array($lcname, $rarray)) {
314                 $cerrors .= $user->id."->".$lcname.'<br/>' ;
315             } else {
316                 array_push($rarray,$lcname);
317             }
318         }
320         if ($cerrors != '') {
321             notify("Error: Cannot convert usernames to lowercase.
322                     Following usernames would overlap (id->username):<br/> $cerrors .
323                     Please resolve overlapping errors.");
324             $result = false;
325         }
327         $cerrors = "";
328         echo "Checking userdatabase:<br />";
329         foreach ($users as $user) {
330             $lcname = trim(moodle_strtolower($user->username));
331             if ($lcname != $user->username) {
332                 $convert = set_field("user" , "username" , $lcname, "id", $user->id);
333                 if (!$convert) {
334                     if ($cerrors){
335                        $cerrors .= ", ";
336                     }
337                     $cerrors .= $item;
338                 } else {
339                     echo ".";
340                 }
341             }
342         }
343         if ($cerrors != '') {
344             notify("There were errors when converting following usernames to lowercase.
345                    '$cerrors' . Sorry, but you will need to fix your database by hand.");
346             $result = false;
347         }
348     }
350     if ($oldversion < 2003042600) {
351         /// Some more indexes - we need all the help we can get on the logs
352         //execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX(module) ");
353         //execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX(action) ");
354     }
356     if ($oldversion < 2003042700) {
357         /// Changing to multiple indexes
358         execute_sql(" ALTER TABLE `{$CFG->prefix}log` DROP INDEX module ", false);
359         execute_sql(" ALTER TABLE `{$CFG->prefix}log` DROP INDEX action ", false);
360         execute_sql(" ALTER TABLE `{$CFG->prefix}log` DROP INDEX course ", false);
361         execute_sql(" ALTER TABLE `{$CFG->prefix}log` DROP INDEX userid ", false);
362         execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX coursemoduleaction (course,module,action) ");
363         execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX courseuserid (course,userid) ");
364     }
366     if ($oldversion < 2003042801) {
367         execute_sql("CREATE TABLE `{$CFG->prefix}course_display` (
368                         `id` int(10) unsigned NOT NULL auto_increment,
369                         `course` int(10) unsigned NOT NULL default '0',
370                         `userid` int(10) unsigned NOT NULL default '0',
371                         `display` int(10) NOT NULL default '0',
372                         PRIMARY KEY  (`id`),
373                         UNIQUE KEY `id` (`id`),
374                         KEY `courseuserid` (course,userid)
375                      ) TYPE=MyISAM COMMENT='Stores info about how to display the course'");
376     }
378     if ($oldversion < 2003050400) {
379         table_column("course_sections", "", "visible", "integer", "1", "unsigned", "1", "", "");
380     }
382     if ($oldversion < 2003050900) {
383         table_column("modules", "", "visible", "integer", "1", "unsigned", "1", "", "");
384     }
386     if ($oldversion < 2003050902) {
387         if (get_records("modules", "name", "pgassignment")) {
388             print_simple_box("Note: the pgassignment module has been removed (it will be replaced later by the workshop module).  Go to the new 'Manage Modules' page and DELETE IT from your system", "center", "50%", "$THEME->cellheading", "20", "noticebox");
389         }
390     }
392     if ($oldversion < 2003051600) {
393         print_simple_box("Thanks for upgrading!<p>There are many changes since the last release.  Please read the release notes carefully.  If you are using CUSTOM themes you will need to edit them.  You will also need to check your site's config.php file.", "center", "50%", "$THEME->cellheading", "20", "noticebox");
394     }
396     if ($oldversion < 2003052300) {
397         table_column("user", "", "autosubscribe", "integer", "1", "unsigned", "1", "", "htmleditor");
398     }
400     if ($oldversion < 2003072100) {
401         table_column("course", "", "visible", "integer", "1", "unsigned", "1", "", "marker");
402     }
404     if ($oldversion < 2003072101) {
405         table_column("course_sections", "sequence", "sequence", "text", "", "", "", "", "");
406     }
408     if ($oldversion < 2003072800) {
409         print_simple_box("The following database index improves performance, but can be quite large - if you are upgrading and you have problems with a limited quota you may want to delete this index later from the '{$CFG->prefix}log' table in your database", "center", "50%", "$THEME->cellheading", "20", "noticebox");
410         flush();
411         execute_sql(" ALTER TABLE `{$CFG->prefix}log` ADD INDEX timecoursemoduleaction (time,course,module,action) ");
412         execute_sql(" ALTER TABLE `{$CFG->prefix}user_students` ADD INDEX courseuserid (course,userid) ");
413         execute_sql(" ALTER TABLE `{$CFG->prefix}user_teachers` ADD INDEX courseuserid (course,userid) ");
414     }
416     if ($oldversion < 2003072803) {
417         table_column("course_categories", "", "description", "text", "", "", "");
418         table_column("course_categories", "", "parent", "integer", "10", "unsigned");
419         table_column("course_categories", "", "sortorder", "integer", "10", "unsigned");
420         table_column("course_categories", "", "courseorder", "text", "", "", "");
421         table_column("course_categories", "", "visible", "integer", "1", "unsigned", "1");
422         table_column("course_categories", "", "timemodified", "integer", "10", "unsigned");
423     }
425     if ($oldversion < 2003080400) {
426         table_column("course_categories", "courseorder", "courseorder", "integer", "10", "unsigned");
427         table_column("course", "", "sortorder", "integer", "10", "unsigned", "0", "", "category");
428     }
430     if ($oldversion < 2003080700) {
431         notify("Cleaning up categories and course ordering...");
432         fix_course_sortorder();
433     }
435     if ($oldversion < 2003081001) {
436         table_column("course", "format", "format", "varchar", "10", "", "topics");
437     }
439     if ($oldversion < 2003081500) {
440 //        print_simple_box("Some important changes have been made to how course creators work.  Formerly, they could create new courses and assign teachers, and teachers could edit courses.  Now, ordinary teachers can no longer edit courses - they <b>need to be a teacher of a course AND a course creator</b>.  A new site-wide configuration variable allows you to choose whether to allow course creators to create new courses as well (by default this is off).  <p>The following update will automatically convert all your existing teachers into course creators, to maintain backward compatibility.  Make sure you look at your upgraded site carefully and understand these new changes.", "center", "50%", "$THEME->cellheading", "20", "noticebox");
442 //        $count = 0;
443 //        $errorcount = 0;
444 //        if ($teachers = get_records("user_teachers")) {
445 //            foreach ($teachers as $teacher) {
446 //                if (! record_exists("user_coursecreators", "userid", $teacher->userid)) {
447 //                    $creator = NULL;
448 //                    $creator->userid = $teacher->userid;
449 //                    if (!insert_record("user_coursecreators", $creator)) {
450 //                        $errorcount++;
451 //                    } else {
452 //                        $count++;
453 //                    }
454 //                }
455 //            }
456 //        }
457 //        print_simple_box("$count teachers were upgraded to course creators (with $errorcount errors)", "center", "50%", "$THEME->cellheading", "20", "noticebox");
459     }
461     if ($oldversion < 2003081501) {
462         execute_sql(" CREATE TABLE `{$CFG->prefix}scale` (
463                          `id` int(10) unsigned NOT NULL auto_increment,
464                          `courseid` int(10) unsigned NOT NULL default '0',
465                          `userid` int(10) unsigned NOT NULL default '0',
466                          `name` varchar(255) NOT NULL default '',
467                          `scale` text NOT NULL,
468                          `description` text NOT NULL,
469                          `timemodified` int(10) unsigned NOT NULL default '0',
470                          PRIMARY KEY  (id)
471                        ) TYPE=MyISAM COMMENT='Defines grading scales'");
473     }
475     if ($oldversion < 2003081503) {
476         table_column("forum", "", "scale", "integer", "10", "unsigned", "0", "", "assessed");
477         get_scales_menu(0);    // Just to force the default scale to be created
478     }
480     if ($oldversion < 2003081600) {
481         table_column("user_teachers", "", "editall", "integer", "1", "unsigned", "1", "", "role");
482         table_column("user_teachers", "", "timemodified", "integer", "10", "unsigned", "0", "", "editall");
483     }
485     if ($oldversion < 2003081900) {
486         table_column("course_categories", "courseorder", "coursecount", "integer", "10", "unsigned", "0");
487     }
489     if ($oldversion < 2003082001) {
490         table_column("course", "", "showgrades", "integer", "2", "unsigned", "1", "", "format");
491     }
493     if ($oldversion < 2003082101) {
494         execute_sql(" ALTER TABLE `{$CFG->prefix}course` ADD INDEX category (category) ");
495     }
496     if ($oldversion < 2003082702) {
497         execute_sql(" INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'user report', 'user', 'CONCAT(firstname,\" \",lastname)') ");
498     }
500     if ($oldversion < 2003091400) {
501         table_column("course_modules", "", "indent", "integer", "5", "unsigned", "0", "", "score");
502     }
504     if ($oldversion < 2003092900) {
505         table_column("course", "", "maxbytes", "integer", "10", "unsigned", "0", "", "marker");
506     }
508     if ($oldversion < 2003102700) {
509         table_column("user_students", "", "timeaccess", "integer", "10", "unsigned", "0", "", "time");
510         table_column("user_teachers", "", "timeaccess", "integer", "10", "unsigned", "0", "", "timemodified");
512         $db->debug = false;
513         $CFG->debug = 0;
514         notify("Calculating access times.  Please wait - this may take a long time on big sites...", "green");
515         flush();
517         if ($courses = get_records_select("course", "category > 0")) {
518             foreach ($courses as $course) {
519                 notify("Processing $course->fullname ...", "green");
520                 flush();
521                 if ($users = get_records_select("user_teachers", "course = '$course->id'",
522                                                 "id", "id, userid, timeaccess")) {
523                     foreach ($users as $user) {
524                         $loginfo = get_record_sql("SELECT id, time FROM {$CFG->prefix}log                                                                                  WHERE course = '$course->id' and userid = '$user->userid'                                                               ORDER by time DESC");
525                         if (empty($loginfo->time)) {
526                             $loginfo->time = 0;
527                         }
528                         execute_sql("UPDATE {$CFG->prefix}user_teachers                                                                                      SET timeaccess = '$loginfo->time'
529                                      WHERE userid = '$user->userid' AND course = '$course->id'", false);
531                     }
532                 }
534                 if ($users = get_records_select("user_students", "course = '$course->id'",
535                                                 "id", "id, userid, timeaccess")) {
536                     foreach ($users as $user) {
537                         $loginfo = get_record_sql("SELECT id, time FROM {$CFG->prefix}log
538                                                    WHERE course = '$course->id' and userid = '$user->userid'
539                                                    ORDER by time DESC");
540                         if (empty($loginfo->time)) {
541                             $loginfo->time = 0;
542                         }
543                         execute_sql("UPDATE {$CFG->prefix}user_students
544                                      SET timeaccess = '$loginfo->time'
545                                      WHERE userid = '$user->userid' AND course = '$course->id'", false);
547                     }
548                 }
549             }
550         }
551         notify("All courses complete.", "green");
552         $db->debug = true;
553     }
555     if ($oldversion < 2003103100) {
556         table_column("course", "", "showreports", "integer", "4", "unsigned", "0", "", "maxbytes");
557     }
559     if ($oldversion < 2003121600) {
560         modify_database("", "CREATE TABLE `prefix_groups` (
561                                 `id` int(10) unsigned NOT NULL auto_increment,
562                                 `courseid` int(10) unsigned NOT NULL default '0',
563                                 `name` varchar(254) NOT NULL default '',
564                                 `description` text NOT NULL,
565                                 `lang` varchar(10) NOT NULL default 'en',
566                                 `picture` int(10) unsigned NOT NULL default '0',
567                                 `timecreated` int(10) unsigned NOT NULL default '0',
568                                 `timemodified` int(10) unsigned NOT NULL default '0',
569                                 PRIMARY KEY  (`id`),
570                                 KEY `courseid` (`courseid`)
571                               ) TYPE=MyISAM COMMENT='Each record is a group in a course.'; ");
573         modify_database("", "CREATE TABLE `prefix_groups_members` (
574                                 `id` int(10) unsigned NOT NULL auto_increment,
575                                 `groupid` int(10) unsigned NOT NULL default '0',
576                                 `userid` int(10) unsigned NOT NULL default '0',
577                                 `timeadded` int(10) unsigned NOT NULL default '0',
578                                 PRIMARY KEY  (`id`),
579                                 KEY `groupid` (`groupid`)
580                               ) TYPE=MyISAM COMMENT='Lists memberships of users in groups'; ");
581     }
583     if ($oldversion < 2003121800) {
584         table_column("course", "modinfo", "modinfo", "longtext", "", "", "");
585     }
587     if ($oldversion < 2003122600) {
588         table_column("course", "", "groupmode", "integer", "4", "unsigned", "0", "", "showreports");
589         table_column("course", "", "groupmodeforce", "integer", "4", "unsigned", "0", "", "groupmode");
590     }
592     if ($oldversion < 2004010900) {
593         table_column("course_modules", "", "groupmode", "integer", "4", "unsigned", "0", "", "visible");
594     }
596     if ($oldversion < 2004011700) {
597         modify_database("", "CREATE TABLE `prefix_event` (
598                               `id` int(10) unsigned NOT NULL auto_increment,
599                               `name` varchar(255) NOT NULL default '',
600                               `description` text NOT NULL,
601                               `courseid` int(10) unsigned NOT NULL default '0',
602                               `groupid` int(10) unsigned NOT NULL default '0',
603                               `userid` int(10) unsigned NOT NULL default '0',
604                               `modulename` varchar(20) NOT NULL default '',
605                               `instance` int(10) unsigned NOT NULL default '0',
606                               `eventtype` varchar(20) NOT NULL default '',
607                               `timestart` int(10) unsigned NOT NULL default '0',
608                               `timeduration` int(10) unsigned NOT NULL default '0',
609                               `timemodified` int(10) unsigned NOT NULL default '0',
610                               PRIMARY KEY  (`id`),
611                               UNIQUE KEY `id` (`id`),
612                               KEY `courseid` (`courseid`),
613                               KEY `userid` (`userid`)
614                             ) TYPE=MyISAM COMMENT='For everything with a time associated to it'; ");
615     }
617     if ($oldversion < 2004012800) {
618         modify_database("", "CREATE TABLE `prefix_user_preferences` (
619                               `id` int(10) unsigned NOT NULL auto_increment,
620                               `userid` int(10) unsigned NOT NULL default '0',
621                               `name` varchar(50) NOT NULL default '',
622                               `value` varchar(255) NOT NULL default '',
623                               PRIMARY KEY  (`id`),
624                               UNIQUE KEY `id` (`id`),
625                               KEY `useridname` (userid,name)
626                             ) TYPE=MyISAM COMMENT='Allows modules to store arbitrary user preferences'; ");
627     }
629     if ($oldversion < 2004012900) {
630         table_column("config", "value", "value", "text", "", "", "");
631     }
633     if ($oldversion < 2004013101) {
634         table_column("log", "", "cmid", "integer", "10", "unsigned", "0", "", "module");
635         set_config("upgrade", "logs");
636     }
638     if ($oldversion < 2004020900) {
639         table_column("course", "", "lang", "varchar", "5", "", "", "", "groupmodeforce");
640     }
642     if ($oldversion < 2004020903) {
643         modify_database("", "CREATE TABLE `prefix_cache_text` (
644                                 `id` int(10) unsigned NOT NULL auto_increment,
645                                 `md5key` varchar(32) NOT NULL default '',
646                                 `formattedtext` longtext NOT NULL,
647                                 `timemodified` int(10) unsigned NOT NULL default '0',
648                                 PRIMARY KEY  (`id`),
649                                 KEY `md5key` (`md5key`)
650                              ) TYPE=MyISAM COMMENT='For storing temporary copies of processed texts';");
651     }
653     if ($oldversion < 2004021000) {
654         $textfilters = array();
655         for ($i=1; $i<=10; $i++) {
656             $variable = "textfilter$i";
657             if (!empty($CFG->$variable)) {   /// No more filters
658                 if (is_readable("$CFG->dirroot/".$CFG->$variable)) {
659                     $textfilters[] = $CFG->$variable;
660                 }
661             }
662         }
663         $textfilters = implode(',', $textfilters);
664         if (empty($textfilters)) {
665             $textfilters = 'mod/glossary/dynalink.php';
666         }
667         set_config('textfilters', $textfilters);
668     }
670     if ($oldversion < 2004021201) {
671         modify_database("", "CREATE TABLE `prefix_cache_filters` (
672                                 `id` int(10) unsigned NOT NULL auto_increment,
673                                 `filter` varchar(32) NOT NULL default '',
674                                 `version` int(10) unsigned NOT NULL default '0',
675                                 `md5key` varchar(32) NOT NULL default '',
676                                 `rawtext` text NOT NULL,
677                                 `timemodified` int(10) unsigned NOT NULL default '0',
678                                 PRIMARY KEY  (`id`),
679                                 KEY `filtermd5key` (filter,md5key)
680                               ) TYPE=MyISAM COMMENT='For keeping information about cached data';");
681     }
683     if ($oldversion < 2004021500) {
684         table_column("groups", "", "hidepicture", "integer", "2", "unsigned", "0", "", "picture");
685     }
687     if ($oldversion < 2004021700) {
688         if (!empty($CFG->textfilters)) {
689             $CFG->textfilters = str_replace("tex_filter.php", "filter.php", $CFG->textfilters);
690             $CFG->textfilters = str_replace("multilang.php", "filter.php", $CFG->textfilters);
691             $CFG->textfilters = str_replace("censor.php", "filter.php", $CFG->textfilters);
692             $CFG->textfilters = str_replace("mediaplugin.php", "filter.php", $CFG->textfilters);
693             $CFG->textfilters = str_replace("algebra_filter.php", "filter.php", $CFG->textfilters);
694             $CFG->textfilters = str_replace("dynalink.php", "filter.php", $CFG->textfilters);
695             set_config("textfilters", $CFG->textfilters);
696         }
697     }
699     if ($oldversion < 2004022000) {
700         table_column("user", "", "emailstop", "integer", "1", "unsigned", "0", "not null", "email");
701     }
703     if ($oldversion < 2004022200) {     /// Final renaming I hope.  :-)
704         if (!empty($CFG->textfilters)) {
705             $CFG->textfilters = str_replace("/filter.php", "", $CFG->textfilters);
706             $CFG->textfilters = str_replace("mod/glossary/dynalink.php", "mod/glossary", $CFG->textfilters);
707             $textfilters = explode(',', $CFG->textfilters);
708             foreach ($textfilters as $key => $textfilter) {
709                 $textfilters[$key] = trim($textfilter);
710             }
711             set_config("textfilters", implode(',',$textfilters));
712         }
713     }
715     if ($oldversion < 2004030702) {     /// Because of the renaming of Czech language pack
716         execute_sql("UPDATE {$CFG->prefix}user SET lang = 'cs' WHERE lang = 'cz'");
717         execute_sql("UPDATE {$CFG->prefix}course SET lang = 'cs' WHERE lang = 'cz'");
718     }
720     if ($oldversion < 2004041800) {     /// Integrate Block System from contrib
721         table_column("course", "", "blockinfo", "varchar", "255", "", "", "not null", "modinfo");
722     }
724     if ($oldversion < 2004042600) {     /// Rebuild course caches for resource icons
725         include_once("$CFG->dirroot/course/lib.php");
726         rebuild_course_cache();
727     }
729     if ($oldversion < 2004042700) {     /// Increase size of lang fields
730         table_column("user",   "lang", "lang", "varchar", "10", "", "en");
731         table_column("groups", "lang", "lang", "varchar", "10", "", "");
732         table_column("course", "lang", "lang", "varchar", "10", "", "");
733     }
735     if ($oldversion < 2004042701) {     /// Add hiddentopics field to control hidden topics behaviour
736         table_column("course", "", "hiddentopics", "integer", "1", "unsigned", "0", "not null", "visible");
737     }
739     if ($oldversion < 2004042702) {     /// add a format field for the description
740         table_column("event", "", "format", "integer", "4", "unsigned", "0", "not null", "description");
741     }
743     if ($oldversion < 2004042900) {
744         execute_sql(" ALTER TABLE `{$CFG->prefix}course` DROP `showrecent` ");
745     }
747     if ($oldversion < 2004043001) {     /// Change hiddentopics to hiddensections
748         table_column("course", "hiddentopics", "hiddensections", "integer", "2", "unsigned", "0", "not null");
749     }
751     if ($oldversion < 2004050400) {     /// add a visible field for events
752         table_column("event", "", "visible", "tinyint", "1", "", "1", "not null", "timeduration");
753         if ($events = get_records('event')) {
754             foreach($events as $event) {
755                 if ($moduleid = get_field('modules', 'id', 'name', $event->modulename)) {
756                     if (get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $event->instance) == 0) {
757                         set_field('event', 'visible', 0, 'id', $event->id);
758                     }
759                 }
760             }
761         }
762     }
764     if ($oldversion < 2004052800) {     /// First version tagged "1.4 development", version.php 1.227
765         set_config('siteblocksadded', true);   /// This will be used later by the block upgrade
766     }
768     if ($oldversion < 2004053000) {     /// set defaults for site course
769         $site = get_site();
770         set_field('course', 'numsections', 0, 'id', $site->id);
771         set_field('course', 'groupmodeforce', 1, 'id', $site->id);
772         set_field('course', 'teacher', get_string('administrator'), 'id', $site->id);
773         set_field('course', 'teachers', get_string('administrators'), 'id', $site->id);
774         set_field('course', 'student', get_string('user'), 'id', $site->id);
775         set_field('course', 'students', get_string('users'), 'id', $site->id);
776     }
778     if ($oldversion < 2004060100) {
779         set_config('digestmailtime', 0);
780         table_column('user', "", 'maildigest', 'tinyint', '1', '', '0', 'not null', 'mailformat');
781     }
783     if ($oldversion < 2004062400) {
784         table_column('user_teachers', "", 'timeend', 'int', '10', 'unsigned', '0', 'not null', 'editall');
785         table_column('user_teachers', "", 'timestart', 'int', '10', 'unsigned', '0', 'not null', 'editall');
786     }
788     if ($oldversion < 2004062401) {
789         table_column('course', '', 'idnumber', 'varchar', '100', '', '', 'not null', 'shortname');
790         execute_sql('UPDATE '.$CFG->prefix.'course SET idnumber = shortname');   // By default
791     }
793     if ($oldversion < 2004062600) {
794         table_column('course', '', 'cost', 'varchar', '10', '', '', 'not null', 'lang');
795     }
797     if ($oldversion < 2004072900) {
798         table_column('course', '', 'enrolperiod', 'int', '10', 'unsigned', '0', 'not null', 'startdate');
799     }
801     if ($oldversion < 2004072901) {  // Fixing error in schema
802         if ($record = get_record('log_display', 'module', 'course', 'action', 'update')) {
803             delete_records('log_display', 'module', 'course', 'action', 'update');
804             insert_record('log_display', $record, false);
805         }
806     }
808     if ($oldversion < 2004081200) {  // Fixing version errors in some blocks
809         set_field('blocks', 'version', 2004081200, 'name', 'admin');
810         set_field('blocks', 'version', 2004081200, 'name', 'calendar_month');
811         set_field('blocks', 'version', 2004081200, 'name', 'course_list');
812     }
814     if ($oldversion < 2004081500) {  // Adding new "auth" field to user table to allow more flexibility
815         table_column('user', '', 'auth', 'varchar', '20', '', 'manual', 'not null', 'id');
817         execute_sql("UPDATE {$CFG->prefix}user SET auth = 'manual'");  // Set everyone to 'manual' to be sure
819         if ($admins = get_admins()) {   // Set all the NON-admins to whatever the current auth module is
820             $adminlist = array();
821             foreach ($admins as $user) {
822                 $adminlist[] = $user->id; 
823             }
824             $adminlist = implode(',', $adminlist);
825             execute_sql("UPDATE {$CFG->prefix}user SET auth = '$CFG->auth' WHERE id NOT IN ($adminlist)");
826         }
827     }
828     
829     if ($oldversion < 2004082200) { // Making admins teachers on site course
830         $site = get_site();
831         $admins = get_admins();
832         foreach ($admins as $admin) {
833             add_teacher($admin->id, $site->id);
834         }
835     }
837     if ($oldversion < 2004082600) {
838         //update auth-fields for external users
839         include_once ($CFG->dirroot."/auth/".$CFG->auth."/lib.php");
840         if (function_exists('auth_get_userlist')) {
841             $externalusers = auth_get_userlist();
842             if (!empty($externalusers)){
843                 $externalusers = '\''. implode('\',\'',$externalusers).'\'';
844                 execute_sql("UPDATE {$CFG->prefix}user SET auth = '$CFG->auth' WHERE username  IN ($externalusers)");
845             }
846         }
847     }
849     if ($oldversion < 2004082900) {  // Make sure guest is "manual" too.
850         set_field('user', 'auth', 'manual', 'username', 'guest');
851     }
852     
853     /* Commented out unused guid-field code
854     if ($oldversion < 2004090300) { // Add guid-field used in user syncronization
855         table_column('user', '', 'guid', 'varchar', '128', '', '', '', 'auth');
856         execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX authguid (auth, guid)");
857     }
858     */
860     if ($oldversion < 2004091900) { // modify idnumber to hold longer values
861         table_column('user', 'idnumber', 'idnumber', 'varchar', '64', '', '', '', '');
862         execute_sql("ALTER TABLE {$CFG->prefix}user DROP INDEX user_idnumber",false); // added in case of conflicts with upgrade from 14stable
863         execute_sql("ALTER TABLE {$CFG->prefix}user DROP INDEX user_auth",false); // added in case of conflicts with upgrade from 14stable
865         execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX idnumber (idnumber)");
866         execute_sql("ALTER TABLE {$CFG->prefix}user ADD INDEX auth (auth)");
867     }
869     if ($oldversion < 2004093001) { // add new table for sessions storage
870         execute_sql(" CREATE TABLE `{$CFG->prefix}sessions` (
871                           `sesskey` char(32) NOT null,
872                           `expiry` int(11) unsigned NOT null,
873                           `expireref` varchar(64),
874                           `data` text NOT null,
875                           PRIMARY KEY (`sesskey`), 
876                           KEY (`expiry`) 
877                       ) TYPE=MyISAM COMMENT='Optional database session storage, not used by default';");
878     }
880     if ($oldversion < 2004111500) {  // Update any users/courses using wrongly-named lang pack
881         execute_sql("UPDATE {$CFG->prefix}user SET lang = 'mi_nt' WHERE lang = 'ma_nt'");
882         execute_sql("UPDATE {$CFG->prefix}course SET lang = 'mi_nt' WHERE lang = 'ma_nt'");
883     }
885     if ($oldversion < 2004111700) { // add indexes. - drop them first silently to avoid conflicts when upgrading.
886         execute_sql(" ALTER TABLE `{$CFG->prefix}course` DROP INDEX idnumber;",false);
887         execute_sql(" ALTER TABLE `{$CFG->prefix}course` DROP INDEX shortname;",false);
888         execute_sql(" ALTER TABLE `{$CFG->prefix}user_students` DROP INDEX userid;",false);
889         execute_sql(" ALTER TABLE `{$CFG->prefix}user_teachers` DROP INDEX userid;",false);
891         execute_sql(" ALTER TABLE `{$CFG->prefix}course` ADD INDEX idnumber (idnumber);");
892         execute_sql(" ALTER TABLE `{$CFG->prefix}course` ADD INDEX shortname (shortname);");
893         execute_sql(" ALTER TABLE `{$CFG->prefix}user_students` ADD INDEX userid (userid);");
894         execute_sql(" ALTER TABLE `{$CFG->prefix}user_teachers` ADD INDEX userid (userid);");
895     }
897     if ($oldversion < 2004111700) {// add an index to event for timestart and timeduration. - drop them first silently to avoid conflicts when upgrading.
898         execute_sql("ALTER TABLE {$CFG->prefix}event DROP INDEX timestart;",false);
899         execute_sql("ALTER TABLE {$CFG->prefix}event DROP INDEX timeduration;",false); 
901         modify_database('','ALTER TABLE prefix_event ADD INDEX timestart (timestart);');
902         modify_database('','ALTER TABLE prefix_event ADD INDEX timeduration (timeduration);');
903     }
905     if ($oldversion < 2004111700) { //add indexes on modules and course_modules. - drop them first silently to avoid conflicts when upgrading.
906         execute_sql("ALTER TABLE {$CFG->prefix}course_modules drop key visible;",false);
907         execute_sql("ALTER TABLE {$CFG->prefix}course_modules drop key course;",false);
908         execute_sql("ALTER TABLE {$CFG->prefix}course_modules drop key module;",false);
909         execute_sql("ALTER TABLE {$CFG->prefix}course_modules drop key instance;",false);
910         execute_sql("ALTER TABLE {$CFG->prefix}course_modules drop key deleted;",false);
911         execute_sql("ALTER TABLE {$CFG->prefix}modules drop key name;",false);
913         modify_database('','ALTER TABLE prefix_course_modules add key visible(visible);');
914         modify_database('','ALTER TABLE prefix_course_modules add key course(course);');
915         modify_database('','ALTER TABLE prefix_course_modules add key module(module);');
916         modify_database('','ALTER TABLE prefix_course_modules add key instance (instance);');
917         modify_database('','ALTER TABLE prefix_course_modules add key deleted (deleted);');
918         modify_database('','ALTER TABLE prefix_modules add key name(name);');
919     }
921     if ($oldversion < 2004111700) { // add an index on the groups_members table. - drop them first silently to avoid conflicts when upgrading.
922         execute_sql("ALTER TABLE {$CFG->prefix}groups_members DROP INDEX userid;",false);
924         modify_database('','ALTER TABLE prefix_groups_members ADD INDEX userid (userid);');
925     }
927     if ($oldversion < 2004111700) { // add an index on user students timeaccess (used for sorting)- drop them first silently to avoid conflicts when upgrading
928         execute_sql("ALTER TABLE {$CFG->prefix}user_students DROP INDEX timeaccess;",false);
930         modify_database('','ALTER TABLE prefix_user_students ADD INDEX timeaccess (timeaccess);');
931     }
933     if ($oldversion < 2004111700) {  // add indexes on faux-foreign keys. - drop them first silently to avoid conflicts when upgrading.
934         execute_sql("ALTER TABLE {$CFG->prefix}scale DROP INDEX courseid;",false);
935         execute_sql("ALTER TABLE {$CFG->prefix}user_admins DROP INDEX userid;",false);
936         execute_sql("ALTER TABLE {$CFG->prefix}user_coursecreators DROP INDEX userid;",false);
938         modify_database('','ALTER TABLE prefix_scale ADD INDEX courseid (courseid);');
939         modify_database('','ALTER TABLE prefix_user_admins ADD INDEX userid (userid);');
940         modify_database('','ALTER TABLE prefix_user_coursecreators ADD INDEX userid (userid);');
941     }
943     if ($oldversion < 2004111700) { // replace index on course
944         fix_course_sortorder(0,0,1);
945         execute_sql("ALTER TABLE `{$CFG->prefix}course` DROP KEY category",false);
947         execute_sql("ALTER TABLE `{$CFG->prefix}course` DROP KEY category_sortorder;",false);
948         modify_database('', "ALTER TABLE `prefix_course` ADD UNIQUE KEY category_sortorder(category,sortorder)"); 
950         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_deleted_idx;",false);
951         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_confirmed_idx;",false);
952         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_firstname_idx;",false);
953         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_lastname_idx;",false);
954         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_city_idx;",false); 
955         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_country_idx;",false); 
956         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_lastaccess_idx;",false);
958         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_deleted_idx  (deleted)");
959         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_confirmed_idx (confirmed)");
960         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_firstname_idx (firstname)");
961         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_lastname_idx (lastname)");
962         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_city_idx (city)");
963         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_country_idx (country)");
964         modify_database("", "ALTER TABLE `prefix_user` ADD INDEX prefix_user_lastaccess_idx (lastaccess)");
965      }
966  
967     if ($oldversion < 2004111700) { // one more index for email (for sorting)
968         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_email_idx;",false);
969         modify_database('','ALTER TABLE `prefix_user` ADD INDEX prefix_user_email_idx (email);');
970     }
972     if ($oldversion < 2004112200) { // new 'enrol' field for enrolment tables
973         table_column('user_students', '', 'enrol', 'varchar', '20', '', '', 'not null');
974         table_column('user_teachers', '', 'enrol', 'varchar', '20', '', '', 'not null');
975         execute_sql("ALTER TABLE `{$CFG->prefix}user_students` ADD INDEX enrol (enrol);");
976         execute_sql("ALTER TABLE `{$CFG->prefix}user_teachers` ADD INDEX enrol (enrol);");
977     }
978     
979     if ($oldversion < 2004112400) {
980         /// Delete duplicate enrolments 
981         /// and then tell the database course,userid is a unique combination
982         if ($users = get_records_select("user_students", "userid > 0 GROUP BY course, userid ".
983                                         "HAVING count(*) > 1", "", "max(id) as id, userid, course ,count(*)")) {
984             foreach ($users as $user) {
985                 delete_records_select("user_students", "userid = '$user->userid' ".
986                                      "AND course = '$user->course' AND id <> '$user->id'");
987             }
988         }
989         flush();
990         
991         modify_database('','ALTER TABLE prefix_user_students DROP INDEX courseuserid;');
992         modify_database('','ALTER TABLE prefix_user_students ADD UNIQUE INDEX courseuserid(course,userid);');        
994         /// Delete duplicate teacher enrolments 
995         /// and then tell the database course,userid is a unique combination
996         if ($users = get_records_select("user_teachers", "userid > 0 GROUP BY course, userid ".
997                                         "HAVING count(*) > 1", "", "max(id) as id, userid, course ,count(*)")) {
998             foreach ($users as $user) {
999                 delete_records_select("user_teachers", "userid = '$user->userid' ".
1000                                      "AND course = '$user->course' AND id <> '$user->id'");
1001             }
1002         }
1003         flush();
1004         modify_database('','ALTER TABLE prefix_user_teachers DROP INDEX courseuserid;');
1005         modify_database('','ALTER TABLE prefix_user_teachers ADD UNIQUE INDEX courseuserid(course,userid);');        
1006     } 
1008     if ($oldversion < 2004112900) {
1009         table_column('user', '', 'policyagreed', 'integer', '1', 'unsigned', '0', 'not null', 'confirmed');
1010     }
1012     if ($oldversion < 2004121400) {
1013         table_column('groups', '', 'password', 'varchar', '50', '', '', 'not null', 'description');
1014     }
1016     if ($oldversion < 2004121500) {
1017         modify_database('',"CREATE TABLE prefix_dst_preset (
1018             id int(10) NOT NULL auto_increment,
1019             name char(48) default '' NOT NULL,
1020             
1021             apply_offset tinyint(3) default '0' NOT NULL,
1022             
1023             activate_index tinyint(1) default '1' NOT NULL,
1024             activate_day tinyint(1) default '1' NOT NULL,
1025             activate_month tinyint(2) default '1' NOT NULL,
1026             activate_time char(5) default '03:00' NOT NULL,
1027             
1028             deactivate_index tinyint(1) default '1' NOT NULL,
1029             deactivate_day tinyint(1) default '1' NOT NULL,
1030             deactivate_month tinyint(2) default '2' NOT NULL,
1031             deactivate_time char(5) default '03:00' NOT NULL,
1032             
1033             last_change int(10) default '0' NOT NULL,
1034             next_change int(10) default '0' NOT NULL,
1035             current_offset tinyint(3) default '0' NOT NULL,
1036             
1037             PRIMARY KEY (id))");
1038     }       
1040     if ($oldversion < 2004122800) {
1041         execute_sql("DROP TABLE {$CFG->prefix}message", false);
1042         execute_sql("DROP TABLE {$CFG->prefix}message_read", false);
1043         execute_sql("DROP TABLE {$CFG->prefix}message_contacts", false);
1045         modify_database('',"CREATE TABLE `prefix_message` (
1046                                `id` int(10) unsigned NOT NULL auto_increment,
1047                                `useridfrom` int(10) NOT NULL default '0',
1048                                `useridto` int(10) NOT NULL default '0',
1049                                `message` text NOT NULL,
1050                                `timecreated` int(10) NOT NULL default '0',
1051                                `messagetype` varchar(50) NOT NULL default '',
1052                                PRIMARY KEY  (`id`),
1053                                KEY `useridfrom` (`useridfrom`),
1054                                KEY `useridto` (`useridto`)
1055                              ) TYPE=MyISAM COMMENT='Stores all unread messages';");
1057         modify_database('',"CREATE TABLE `prefix_message_read` (
1058                                `id` int(10) unsigned NOT NULL auto_increment,
1059                                `useridfrom` int(10) NOT NULL default '0',
1060                                `useridto` int(10) NOT NULL default '0',
1061                                `message` text NOT NULL,
1062                                `timecreated` int(10) NOT NULL default '0',
1063                                `timeread` int(10) NOT NULL default '0',
1064                                `messagetype` varchar(50) NOT NULL default '',
1065                                `mailed` tinyint(1) NOT NULL default '0',
1066                                PRIMARY KEY  (`id`),
1067                                KEY `useridfrom` (`useridfrom`),
1068                                KEY `useridto` (`useridto`)
1069                              ) TYPE=MyISAM COMMENT='Stores all messages that have been read';");
1071         modify_database('',"CREATE TABLE `prefix_message_contacts` (
1072                                `id` int(10) unsigned NOT NULL auto_increment,
1073                                `userid` int(10) unsigned NOT NULL default '0',
1074                                `contactid` int(10) unsigned NOT NULL default '0',
1075                                `blocked` tinyint(1) unsigned NOT NULL default '0',
1076                                PRIMARY KEY  (`id`),
1077                                UNIQUE KEY `usercontact` (`userid`,`contactid`)
1078                              ) TYPE=MyISAM COMMENT='Maintains lists of relationships between users';");
1080         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'write', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1081         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'read', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1082     }
1084     if ($oldversion < 2004122801) {
1085         table_column('message', '', 'format', 'integer', '4', 'unsigned', '0', 'not null', 'message');
1086         table_column('message_read', '', 'format', 'integer', '4', 'unsigned', '0', 'not null', 'message');
1087     }
1089     if ($oldversion < 2005010100) {
1090         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'add contact', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1091         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'remove contact', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1092         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'block contact', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1093         modify_database('', "INSERT INTO prefix_log_display (module, action, mtable, field) VALUES ('message', 'unblock contact', 'user', 'CONCAT(firstname,\" \",lastname)'); ");
1094     }
1096     if ($oldversion < 2005011000) {     // Create a .htaccess file in dataroot, just in case
1097         if (!file_exists($CFG->dataroot.'/.htaccess')) {
1098             if ($handle = fopen($CFG->dataroot.'/.htaccess', 'w')) {   // For safety
1099                 @fwrite($handle, "deny from all\r\nAllowOverride None\r\n");
1100                 @fclose($handle); 
1101                 notify("Created a default .htaccess file in $CFG->dataroot");
1102             }
1103         }
1104     }
1105     
1107     if ($oldversion < 2005012500) { 
1108         /*
1109         // add new table for meta courses.
1110         modify_database("","CREATE TABLE `prefix_meta_course` (
1111             `id` int(1) unsigned NOT NULL auto_increment,
1112             `parent_course` int(10) NOT NULL default 0,
1113             `child_course` int(10) NOT NULL default 0,
1114             PRIMARY KEY (`id`),
1115             KEY `parent_course` (parent_course),
1116             KEY `child_course` (child_course)
1117         );");
1118         // add flag to course field
1119         table_column('course','','meta_course','integer','1','','0','not null');
1120         */ // taking this OUT for upgrade from 1.4 to 1.5 (those tracking head will have already seen it)
1121     }
1123     if ($oldversion < 2005012501) { 
1124         execute_sql("DROP TABLE {$CFG->prefix}meta_course",false); // drop silently
1125         execute_sql("ALTER TABLE {$CFG->prefix}course DROP COLUMN meta_course",false); // drop silently
1126         
1127         // add new table for meta courses.
1128         modify_database("","CREATE TABLE `prefix_course_meta` (
1129             `id` int(10) unsigned NOT NULL auto_increment,
1130             `parent_course` int(10) NOT NULL default 0,
1131             `child_course` int(10) NOT NULL default 0,
1132             PRIMARY KEY (`id`),
1133             KEY `parent_course` (parent_course),
1134             KEY `child_course` (child_course)
1135         );");
1136         // add flag to course field
1137         table_column('course','','metacourse','integer','1','','0','not null');
1138     }
1140     if ($oldversion < 2005012800) {
1141         // fix a typo (int 1 becomes int 10) 
1142         table_column('course_meta','id','id','integer','10','','0','not null');
1143     }
1145     if ($oldversion < 2005020100) {
1146         fix_course_sortorder(0, 1, 1);
1147     }   
1150     if ($oldversion < 2005020101) {
1151         // hopefully this is the LAST TIME we need to do this ;)
1152         if ($rows = count_records("course_meta")) {
1153             // we need to upgrade
1154             modify_database("","CREATE TABLE `prefix_course_meta_tmp` (
1155             `parent_course` int(10) NOT NULL default 0,
1156             `child_course` int(10) NOT NULL default 0);");
1157             
1158             execute_sql("INSERT INTO {$CFG->prefix}course_meta_tmp (parent_course,child_course) 
1159                SELECT {$CFG->prefix}course_meta.parent_course, {$CFG->prefix}course_meta.child_course
1160                FROM {$CFG->prefix}course_meta");
1161             $insertafter = true;
1162         }
1164         execute_sql("DROP TABLE {$CFG->prefix}course_meta");
1166         modify_database("","CREATE TABLE `prefix_course_meta` (
1167             `id` int(10) unsigned NOT NULL auto_increment,
1168             `parent_course` int(10) unsigned NOT NULL default 0,
1169             `child_course` int(10) unsigned NOT NULL default 0,
1170             PRIMARY KEY (`id`),
1171             KEY `parent_course` (parent_course),
1172             KEY `child_course` (child_course));");
1174         if (!empty($insertafter)) {
1175             execute_sql("INSERT INTO {$CFG->prefix}course_meta (parent_course,child_course) 
1176                SELECT {$CFG->prefix}course_meta_tmp.parent_course, {$CFG->prefix}course_meta_tmp.child_course
1177                FROM {$CFG->prefix}course_meta_tmp");
1179             execute_sql("DROP TABLE {$CFG->prefix}course_meta_tmp");
1180         }
1181     }
1183     if ($oldversion < 2005020800) {     // Expand module column to max 20 chars
1184         table_column('log','module','module','varchar','20','','','not null');
1185     }
1187     if ($oldversion < 2005021000) {     // New fields for theme choices
1188         table_column('course', '', 'theme', 'varchar', '50', '', '', '', 'lang');
1189         table_column('groups', '', 'theme', 'varchar', '50', '', '', '', 'lang');
1190         table_column('user',   '', 'theme', 'varchar', '50', '', '', '', 'lang');
1192         set_config('theme', 'standardwhite');         // Reset to a known good theme 
1193     }
1194     
1195     if ($oldversion < 2005021600) {     // course.idnumber should be varchar(100)
1196         table_column('course', 'idnumber', 'idnumber', 'varchar', '100', '', '', '', '');
1197     }
1199     if ($oldversion < 2005021700) {
1200         table_column('user', '', 'dstpreset', 'int', '10', '', '0', 'not null', 'timezone');
1201     }
1203     if ($oldversion < 2005021800) {     // For database debugging, not for normal use
1204         modify_database(""," CREATE TABLE `adodb_logsql` (
1205                                `created` datetime NOT NULL,
1206                                `sql0` varchar(250) NOT NULL,
1207                                `sql1` text NOT NULL,
1208                                `params` text NOT NULL,
1209                                `tracer` text NOT NULL,
1210                                `timer` decimal(16,6) NOT NULL
1211                               );");
1212     }
1214     if ($oldversion < 2005022400) {
1215         // Add more visible digits to the fields
1216         table_column('dst_preset', 'activate_index', 'activate_index', 'tinyint', '2', '', '0', 'not null');
1217         table_column('dst_preset', 'activate_day', 'activate_day', 'tinyint', '2', '', '0', 'not null');
1218         // Add family and year fields
1219         table_column('dst_preset', '', 'family', 'varchar', '100', '', '', 'not null', 'name');
1220         table_column('dst_preset', '', 'year', 'int', '10', '', '0', 'not null', 'family');
1221     }
1223     if ($oldversion < 2005030501) {
1224         table_column('user', '', 'msn', 'varchar', '50', '', '', '', 'icq');
1225         table_column('user', '', 'aim', 'varchar', '50', '', '', '', 'icq');
1226         table_column('user', '', 'yahoo', 'varchar', '50', '', '', '', 'icq');
1227         table_column('user', '', 'skype', 'varchar', '50', '', '', '', 'icq');
1228     }
1230     if ($oldversion < 2005032300) {
1231         table_column('user', 'dstpreset', 'timezonename', 'varchar', '100');
1232         execute_sql('UPDATE `'.$CFG->prefix.'user` SET timezonename = \'\'');
1233     }
1235     if ($oldversion < 2005032600) {
1236         execute_sql('DROP TABLE '.$CFG->prefix.'dst_preset', false);
1237         modify_database('',"CREATE TABLE `prefix_timezone` (
1238                               `id` int(10) NOT NULL auto_increment,
1239                               `name` varchar(100) NOT NULL default '',
1240                               `year` int(11) NOT NULL default '0',
1241                               `rule` varchar(20) NOT NULL default '',
1242                               `gmtoff` int(11) NOT NULL default '0',
1243                               `dstoff` int(11) NOT NULL default '0',
1244                               `dst_month` tinyint(2) NOT NULL default '0',
1245                               `dst_startday` tinyint(3) NOT NULL default '0',
1246                               `dst_weekday` tinyint(3) NOT NULL default '0',
1247                               `dst_skipweeks` tinyint(3) NOT NULL default '0',
1248                               `dst_time` varchar(5) NOT NULL default '00:00',
1249                               `std_month` tinyint(2) NOT NULL default '0',
1250                               `std_startday` tinyint(3) NOT NULL default '0',
1251                               `std_weekday` tinyint(3) NOT NULL default '0',
1252                               `std_skipweeks` tinyint(3) NOT NULL default '0',
1253                               `std_time` varchar(5) NOT NULL default '00:00',
1254                               PRIMARY KEY (`id`)
1255                             ) TYPE=MyISAM COMMENT='Rules for calculating local wall clock time for users';");
1256     }
1258     if ($oldversion < 2005032800) {
1259         execute_sql("CREATE TABLE `{$CFG->prefix}grade_category` (
1260             `id` int(10) unsigned NOT NULL auto_increment,
1261             `name` varchar(64) NOT NULL default '',
1262             `courseid` int(10) unsigned NOT NULL default '0',
1263             `drop_x_lowest` int(10) unsigned NOT NULL default '0',
1264             `bonus_points` int(10) unsigned NOT NULL default '0',
1265             `hidden` int(10) unsigned NOT NULL default '0',
1266             `weight` decimal(4,2) NOT NULL default '0.00',
1267             PRIMARY KEY  (`id`),
1268             KEY `courseid` (`courseid`)
1269           ) TYPE=MyISAM ;");
1271         execute_sql("CREATE TABLE `{$CFG->prefix}grade_exceptions` (
1272             `id` int(10) unsigned NOT NULL auto_increment,
1273             `courseid` int(10) unsigned NOT NULL default '0',
1274             `grade_itemid` int(10) unsigned NOT NULL default '0',
1275             `userid` int(10) unsigned NOT NULL default '0',
1276             PRIMARY KEY  (`id`),
1277             KEY `courseid` (`courseid`)
1278           ) TYPE=MyISAM ;");
1281         execute_sql("CREATE TABLE `{$CFG->prefix}grade_item` (
1282             `id` int(10) unsigned NOT NULL auto_increment,
1283             `courseid` int(10) unsigned NOT NULL default '0',
1284             `category` int(10) unsigned NOT NULL default '0',
1285             `modid` int(10) unsigned NOT NULL default '0',
1286             `cminstance` int(10) unsigned NOT NULL default '0',
1287             `scale_grade` float(11,10) default '1.0000000000',
1288             `extra_credit` int(10) unsigned NOT NULL default '0',
1289             `sort_order` int(10) unsigned NOT NULL default '0',
1290             PRIMARY KEY  (`id`),
1291             KEY `courseid` (`courseid`)
1292           ) TYPE=MyISAM ;");
1295         execute_sql("CREATE TABLE `{$CFG->prefix}grade_letter` (
1296             `id` int(10) unsigned NOT NULL auto_increment,
1297             `courseid` int(10) unsigned NOT NULL default '0',
1298             `letter` varchar(8) NOT NULL default 'NA',
1299             `grade_high` decimal(4,2) NOT NULL default '100.00',
1300             `grade_low` decimal(4,2) NOT NULL default '0.00',
1301             PRIMARY KEY  (`id`),
1302             KEY `courseid` (`courseid`)
1303           ) TYPE=MyISAM ;");
1304           
1306         execute_sql("CREATE TABLE `{$CFG->prefix}grade_preferences` (
1307             `id` int(10) unsigned NOT NULL auto_increment,
1308             `courseid` int(10) unsigned NOT NULL default '0',
1309             `preference` int(10) NOT NULL default '0',
1310             `value` int(10) NOT NULL default '0',
1311             PRIMARY KEY  (`id`),
1312             UNIQUE KEY `courseidpreference` (`courseid`,`preference`)
1313           ) TYPE=MyISAM ;");
1314           
1315     }
1317     if ($oldversion < 2005033100) {   // Get rid of defunct field from course modules table
1318          delete_records('course_modules', 'deleted', 1);  // Delete old records we don't need any more
1319          execute_sql('ALTER TABLE `'.$CFG->prefix.'course_modules` DROP INDEX `deleted`');  // Old index
1320          execute_sql('ALTER TABLE `'.$CFG->prefix.'course_modules` DROP `deleted`');    // Old field
1321     }
1323     if ($oldversion < 2005040800) {
1324         table_column('user', 'timezone', 'timezone', 'varchar', '100', '', '99');
1325         execute_sql(" ALTER TABLE `{$CFG->prefix}user` DROP `timezonename` ");
1326     }
1327     
1328     if ($oldversion < 2005041101) {
1329         require_once($CFG->libdir.'/filelib.php');
1330         if (is_readable($CFG->dirroot.'/lib/timezones.txt')) {  // Distribution file
1331             if ($timezones = get_records_csv($CFG->dirroot.'/lib/timezones.txt', 'timezone')) {
1332                 $db->debug = false;
1333                 update_timezone_records($timezones);
1334                 notify(count($timezones).' timezones installed');
1335                 $db->debug = true;
1336             }
1337         }
1338     }
1340     if ($oldversion < 2005041900) {  // Copy all Dialogue entries into Messages, and hide Dialogue module
1342         if ($entries = get_records_sql('SELECT e.id, e.userid, c.recipientid, e.text, e.timecreated
1343                                           FROM '.$CFG->prefix.'dialogue_conversations c,
1344                                                '.$CFG->prefix.'dialogue_entries e
1345                                          WHERE e.conversationid = c.id')) {
1346             foreach ($entries as $entry) {
1347                 $message = new object;
1348                 $message->useridfrom    = $entry->userid;
1349                 $message->useridto      = $entry->recipientid;
1350                 $message->message       = addslashes($entry->text);
1351                 $message->format        = FORMAT_HTML;
1352                 $message->timecreated   = $entry->timecreated;
1353                 $message->messagetype   = 'direct';
1354             
1355                 insert_record('message_read', $message);
1356             }
1357         }
1359         set_field('modules', 'visible', 0, 'name', 'dialogue');
1361         notify('The Dialogue module has been disabled, and all the old Messages from it copied into the new standard Message feature.  If you really want Dialogue back, you can enable it using the "eye" icon here:  Admin >> Modules >> Dialogue');
1363     }
1365     if ($oldversion < 2005042100) {
1366         $result = table_column('event', '', 'repeatid', 'int', '10', 'unsigned', '0', 'not null', 'userid') && $result;
1367     }
1369     if ($oldversion < 2005042400) {  // Add user tracking prefs field.
1370         table_column('user', '', 'trackforums', 'int', '4', 'unsigned', '0', 'not null', 'autosubscribe');
1371     }
1373     if ($oldversion < 2005053000 ) { // Add config_plugins table
1374         
1375         // this table was created on the MOODLE_15_STABLE branch
1376         // so it may already exist.
1377         $result = execute_sql("CREATE TABLE IF NOT EXISTS `{$CFG->prefix}config_plugins` (
1378                                   `id`         int(10) unsigned NOT NULL auto_increment,
1379                                   `plugin`     varchar(100) NOT NULL default 'core',
1380                                   `name`       varchar(100) NOT NULL default '',
1381                                   `value`      text NOT NULL default '',
1382                                   PRIMARY KEY  (`id`),
1383                                            UNIQUE KEY `plugin_name` (`plugin`, `name`)
1384                                   ) TYPE=MyISAM 
1385                                   COMMENT='Moodle modules and plugins configuration variables';");
1386     }
1388     if ($oldversion < 2005060200) {  // migrate some config items to config_plugins table
1390         // NOTE: this block is in both postgres AND mysql upgrade
1391         // files. If you edit either, update the otherone. 
1392         $user_fields = array("firstname", "lastname", "email", 
1393                              "phone1", "phone2", "department", 
1394                              "address", "city", "country", 
1395                              "description", "idnumber", "lang");
1396         if (!empty($CFG->auth)) { // if we have no auth, just pass
1397             foreach ($user_fields as $field) {
1398                 $suffixes = array('', '_editlock', '_updateremote', '_updatelocal');
1399                 foreach ($suffixes as $suffix) {
1400                     $key = 'auth_user_' . $field . $suffix;
1401                     if (isset($CFG->$key)) {
1402                         
1403                         // translate keys & values
1404                         // to the new convention
1405                         // this should support upgrading 
1406                         // even 1.5dev installs
1407                         $newkey = $key;
1408                         $newval = $CFG->$key;
1409                         if ($suffix === '') {
1410                             $newkey = 'field_map_' . $field;
1411                         } elseif ($suffix === '_editlock') {
1412                             $newkey = 'field_lock_' . $field;
1413                             $newval = ($newval==1) ? 'locked' : 'unlocked'; // translate 0/1 to locked/unlocked
1414                         } elseif ($suffix === '_updateremote') {
1415                             $newkey = 'field_updateremote_' . $field;                            
1416                         } elseif ($suffix === '_updatelocal') {
1417                             $newkey = 'field_updatelocal_' . $field;
1418                             $newval = ($newval==1) ? 'onlogin' : 'oncreate'; // translate 0/1 to locked/unlocked
1419                         }
1421                         if (!(set_config($newkey, addslashes($newval), 'auth/'.$CFG->auth)
1422                             && delete_records('config', 'name', $key))) {
1423                             notify("Error updating Auth configuration $key to {$CFG->auth} $newkey .");
1424                             $result = false;
1425                         }
1426                     } // end if isset key
1427                 } // end foreach suffix
1428             } // end foreach field
1429         }
1430     }
1432     if ($oldversion < 2005060201) {  // Close down the Attendance module, we are removing it from CVS.
1433         if (!file_exists($CFG->dirroot.'/mod/attendance/lib.php')) {
1434             if (count_records('attendance')) {   // We have some data, so should keep it
1436                 set_field('modules', 'visible', 0, 'name', 'attendance');
1437                 notify('The Attendance module has been discontinued.  If you really want to 
1438                         continue using it, you should download it individually from 
1439                         http://download.moodle.org/modules and install it, then 
1440                         reactivate it from Admin >> Configuration >> Modules.  
1441                         None of your existing data has been deleted, so all existing 
1442                         Attendance activities should re-appear.');
1444             } else {  // No data, so do a complete delete
1446                 execute_sql('DROP TABLE '.$CFG->prefix.'attendance', false);
1447                 delete_records('modules', 'name', 'attendance');
1448                 notify("The Attendance module has been discontinued and removed from your site.  
1449                         You weren't using it anyway.  ;-)");
1450             }
1451         }
1452     }
1454     if ($oldversion < 2005071700) {  // Close down the Dialogue module, we are removing it from CVS.
1455         if (!file_exists($CFG->dirroot.'/mod/dialogue/lib.php')) {
1456             if (count_records('dialogue')) {   // We have some data, so should keep it
1458                 set_field('modules', 'visible', 0, 'name', 'dialogue');
1459                 notify('The Dialogue module has been discontinued.  If you really want to 
1460                         continue using it, you should download it individually from 
1461                         http://download.moodle.org/modules and install it, then 
1462                         reactivate it from Admin >> Configuration >> Modules.  
1463                         None of your existing data has been deleted, so all existing 
1464                         Dialogue activities should re-appear.');
1466             } else {  // No data, so do a complete delete
1468                 execute_sql('DROP TABLE '.$CFG->prefix.'dialogue', false);
1469                 delete_records('modules', 'name', 'dialogue');
1470                 notify("The Dialogue module has been discontinued and removed from your site.  
1471                         You weren't using it anyway.  ;-)");
1472             }
1473         }
1474     }
1476     if ($oldversion < 2005072000) {  // Add a couple fields to mdl_event to work towards iCal import/export
1477         table_column('event', '', 'uuid', 'char', '36', '', '', 'not null', 'visible');
1478         table_column('event', '', 'sequence', 'integer', '10', 'unsigned', '1', 'not null', 'uuid');
1479     }
1481     if ($oldversion < 2005072100) { // run the online assignment cleanup code
1482         include($CFG->dirroot.'/'.$CFG->admin.'/oacleanup.php');
1483         if (function_exists('online_assignment_cleanup')) {
1484             online_assignment_cleanup();
1485         }
1486     }
1488     if ($oldversion < 2005072200) { // fix the mistakenly-added currency stuff from enrol/authorize
1489         execute_sql("DROP TABLE {$CFG->prefix}currencies", false); // drop silently
1490         execute_sql("ALTER TABLE {$CFG->prefix}course DROP currency", false);
1491         $defaultcurrency = empty($CFG->enrol_currency) ? 'USD' : $CFG->enrol_currency;
1492         table_column('course', '', 'currency', 'char', '3', '', $defaultcurrency, 'not null', 'cost');
1493     }
1495     if ($oldversion < 2005081600) { //set up the course requests table
1496         modify_database('',"CREATE TABLE `prefix_course_request`  (
1497           `id` int(10) unsigned NOT NULL auto_increment,
1498           `fullname` varchar(254) NOT NULL default '',
1499           `shortname` varchar(15) NOT NULL default '',
1500           `summary` text NOT NULL,
1501           `reason` text NOT NULL,
1502           `requester` int(10) NOT NULL default 0,
1503           PRIMARY KEY (`id`),
1504           KEY `shortname` (`shortname`)
1505         ) TYPE=MyISAM;");
1506         
1507         table_column('course','','requested');
1508     }
1510     if ($oldversion < 2005081601) {
1511         modify_database('',"CREATE TABLE `prefix_course_allowed_modules` (
1512          `id` int(10) unsigned NOT NULL auto_increment,
1513          `course` int(10) unsigned NOT NULL default 0,
1514          `module` int(10) unsigned NOT NULL default 0,
1515          PRIMARY KEY (`id`),
1516          KEY `course` (`course`),
1517          KEY `module` (`module`)
1518       ) TYPE=MyISAM;");
1519         
1520         table_column('course','','restrictmodules','int','1','','0','not null');
1521     }
1523     if ($oldversion < 2005081700) {
1524         table_column('course_categories','','depth','integer');
1525         table_column('course_categories','','path','varchar','255');
1526     }
1528     if ($oldversion < 2005090100) {
1529         modify_database("","CREATE TABLE `prefix_stats_daily` (
1530           `id` int(10) unsigned NOT NULL auto_increment,
1531           `courseid` int(10) unsigned NOT NULL default 0,
1532           `timeend` int(10) unsigned NOT NULL default 0,
1533           `students` int(10) unsigned NOT NULL default 0,
1534           `teachers` int(10) unsigned NOT NULL default 0,
1535           `activestudents` int(10) unsigned NOT NULL default 0,
1536           `activeteachers` int(10) unsigned NOT NULL default 0,
1537           `studentreads` int(10) unsigned NOT NULL default 0,
1538           `studentwrites` int(10) unsigned NOT NULL default 0,
1539           `teacherreads` int(10) unsigned NOT NULL default 0,
1540           `teacherwrites` int(10) unsigned NOT NULL default 0,
1541           `logins` int(10) unsigned NOT NULL default 0,
1542           `uniquelogins` int(10) unsigned NOT NULL default 0,
1543           PRIMARY KEY (`id`),
1544           KEY `courseid` (`courseid`),
1545           KEY `timeend` (`timeend`)
1546        );");
1548         modify_database("","CREATE TABLE prefix_stats_weekly (
1549           `id` int(10) unsigned NOT NULL auto_increment,
1550           `courseid` int(10) unsigned NOT NULL default 0,
1551           `timeend` int(10) unsigned NOT NULL default 0,
1552           `students` int(10) unsigned NOT NULL default 0,
1553           `teachers` int(10) unsigned NOT NULL default 0,
1554           `activestudents` int(10) unsigned NOT NULL default 0,
1555           `activeteachers` int(10) unsigned NOT NULL default 0,
1556           `studentreads` int(10) unsigned NOT NULL default 0,
1557           `studentwrites` int(10) unsigned NOT NULL default 0,
1558           `teacherreads` int(10) unsigned NOT NULL default 0,
1559           `teacherwrites` int(10) unsigned NOT NULL default 0,
1560           `logins` int(10) unsigned NOT NULL default 0,
1561           `uniquelogins` int(10) unsigned NOT NULL default 0,
1562           PRIMARY KEY (`id`),
1563           KEY `courseid` (`courseid`),
1564           KEY `timeend` (`timeend`)
1565        );");
1567         modify_database("","CREATE TABLE prefix_stats_monthly (
1568           `id` int(10) unsigned NOT NULL auto_increment,
1569           `courseid` int(10) unsigned NOT NULL default 0,
1570           `timeend` int(10) unsigned NOT NULL default 0,
1571           `students` int(10) unsigned NOT NULL default 0,
1572           `teachers` int(10) unsigned NOT NULL default 0,
1573           `activestudents` int(10) unsigned NOT NULL default 0,
1574           `activeteachers` int(10) unsigned NOT NULL default 0,
1575           `studentreads` int(10) unsigned NOT NULL default 0,
1576           `studentwrites` int(10) unsigned NOT NULL default 0,
1577           `teacherreads` int(10) unsigned NOT NULL default 0,
1578           `teacherwrites` int(10) unsigned NOT NULL default 0,
1579           `logins` int(10) unsigned NOT NULL default 0,
1580           `uniquelogins` int(10) unsigned NOT NULL default 0,
1581           PRIMARY KEY (`id`),
1582           KEY `courseid` (`courseid`),
1583           KEY `timeend` (`timeend`)
1584        );");
1586         modify_database("","CREATE TABLE prefix_stats_user_daily (
1587           `id` int(10) unsigned NOT NULL auto_increment,
1588           `courseid` int(10) unsigned NOT NULL default 0,
1589           `userid` int(10) unsigned NOT NULL default 0,
1590           `roleid` int(10) unsigned NOT NULL default 0,
1591           `timeend` int(10) unsigned NOT NULL default 0,
1592           `statsreads` int(10) unsigned NOT NULL default 0,
1593           `statswrites` int(10) unsigned NOT NULL default 0,
1594           `stattype` varchar(30) NOT NULL default '',
1595           PRIMARY KEY (`id`),
1596           KEY `courseid` (`courseid`),
1597           KEY `userid` (`userid`),
1598           KEY `roleid` (`roleid`),
1599           KEY `timeend` (`timeend`)
1600        );");
1602         modify_database("","CREATE TABLE prefix_stats_user_weekly (
1603           `id` int(10) unsigned NOT NULL auto_increment,
1604           `courseid` int(10) unsigned NOT NULL default 0,
1605           `userid` int(10) unsigned NOT NULL default 0,
1606           `roleid` int(10) unsigned NOT NULL default 0,
1607           `timeend` int(10) unsigned NOT NULL default 0,
1608           `statsreads` int(10) unsigned NOT NULL default 0,
1609           `statswrites` int(10) unsigned NOT NULL default 0,
1610           `stattype` varchar(30) NOT NULL default '',
1611           PRIMARY KEY (`id`),
1612           KEY `courseid` (`courseid`),
1613           KEY `userid` (`userid`),
1614           KEY `roleid` (`roleid`),
1615           KEY `timeend` (`timeend`)
1616        );");
1618         modify_database("","CREATE TABLE prefix_stats_user_monthly (
1619           `id` int(10) unsigned NOT NULL auto_increment,
1620           `courseid` int(10) unsigned NOT NULL default 0,
1621           `userid` int(10) unsigned NOT NULL default 0,
1622           `roleid` int(10) unsigned NOT NULL default 0,
1623           `timeend` int(10) unsigned NOT NULL default 0,
1624           `statsreads` int(10) unsigned NOT NULL default 0,
1625           `statswrites` int(10) unsigned NOT NULL default 0,
1626           `stattype` varchar(30) NOT NULL default '',
1627           PRIMARY KEY (`id`),
1628           KEY `courseid` (`courseid`),
1629           KEY `userid` (`userid`),
1630           KEY `roleid` (`roleid`),
1631           KEY `timeend` (`timeend`)
1632        );");
1633          
1634     }
1636     if ($oldversion < 2005100300) {
1637         table_column('course','','expirynotify','tinyint','1');
1638         table_column('course','','expirythreshold','int','10');
1639         table_column('course','','notifystudents','tinyint','1');
1640         $new = new stdClass();
1641         $new->name = 'lastexpirynotify';
1642         $new->value = 0;
1643         insert_record('config', $new);
1644     }
1646     if ($oldversion < 2005100400) {
1647         table_column('course','','enrollable','tinyint','1','unsigned','1');
1648         table_column('course','','enrolstartdate','int');
1649         table_column('course','','enrolenddate','int');
1650     }
1652     if ($oldversion < 2005101200) { // add enrolment key to course_request.
1653         table_column('course_request','','password','varchar',50);
1654     }
1656     if ($oldversion < 2006030800) { # add extra indexes to log (see bug #4112)
1657         modify_database('',"ALTER TABLE prefix_log ADD INDEX userid (userid);");
1658         modify_database('',"ALTER TABLE prefix_log ADD INDEX info (info);");
1659     }
1661     if ($oldversion < 2006030900) {
1662         table_column('course','','enrol','varchar','20','','');
1664         if ($CFG->enrol == 'internal' || $CFG->enrol == 'manual') {
1665             set_config('enrol_plugins_enabled', 'manual');
1666             set_config('enrol', 'manual');
1667         } else {
1668             set_config('enrol_plugins_enabled', 'manual,'.$CFG->enrol);
1669         }
1671         require_once("$CFG->dirroot/enrol/enrol.class.php");
1672         $defaultenrol = enrolment_factory::factory($CFG->enrol);
1673         if (!method_exists($defaultenrol, 'print_entry')) { // switch enrollable to off for all courses in this case
1674             modify_database('', 'UPDATE prefix_course SET enrollable = 0');
1675         }
1677         execute_sql("UPDATE {$CFG->prefix}user_students SET enrol='manual' WHERE enrol='' OR enrol='internal'");
1678         execute_sql("UPDATE {$CFG->prefix}user_teachers SET enrol='manual' WHERE enrol=''");
1680     }
1681     
1682     if ($oldversion < 2006031000) {
1684         modify_database("","CREATE TABLE prefix_post (
1685           `id` int(10) unsigned NOT NULL auto_increment,
1686           `userid` int(10) unsigned NOT NULL default '0',
1687           `courseid` int(10) unsigned NOT NULL default'0',
1688           `groupid` int(10) unsigned NOT NULL default'0',
1689           `moduleid` int(10) unsigned NOT NULL default'0',
1690           `coursemoduleid` int(10) unsigned NOT NULL default'0',
1691           `subject` varchar(128) NOT NULL default '',
1692           `summary` longtext,
1693           `content` longtext,
1694           `uniquehash` varchar(128) NOT NULL default '',
1695           `rating` int(10) unsigned NOT NULL default'0',
1696           `format` int(10) unsigned NOT NULL default'0',
1697           `publishstate` enum('draft','site','public') NOT NULL default 'draft',
1698           `lastmodified` int(10) unsigned NOT NULL default '0',
1699           `created` int(10) unsigned NOT NULL default '0',
1700           PRIMARY KEY  (`id`),
1701           UNIQUE KEY `id_user_idx` (`id`, `userid`),
1702           KEY `post_lastmodified_idx` (`lastmodified`),
1703           KEY `post_subject_idx` (`subject`)
1704         ) TYPE=MyISAM  COMMENT='New moodle post table. Holds data posts such as forum entries or blog entries.';");
1706         modify_database("","CREATE TABLE prefix_tags (
1707           `id` int(10) unsigned NOT NULL auto_increment,
1708           `type` varchar(255) NOT NULL default 'official',
1709           `userid` int(10) unsigned NOT NULL default'0',
1710           `text` varchar(255) NOT NULL default '',
1711           PRIMARY KEY  (`id`)
1712         ) TYPE=MyISAM COMMENT ='tags structure for moodle.';");
1714         modify_database("","CREATE TABLE prefix_blog_tag_instance (
1715           `id` int(10) unsigned NOT NULL auto_increment,
1716           `entryid` int(10) unsigned NOT NULL default'0',
1717           `tagid` int(10) unsigned NOT NULL default'0',
1718           `groupid` int(10) unsigned NOT NULL default'0',
1719           `courseid` int(10) unsigned NOT NULL default'0',
1720           `userid` int(10) unsigned NOT NULL default'0',
1721           PRIMARY KEY  (`id`)
1722           ) TYPE=MyISAM COMMENT ='tag instance for blogs.';");
1723     }
1725     if ($oldversion < 2006031400) {
1726         require_once("$CFG->dirroot/enrol/enrol.class.php");
1727         $defaultenrol = enrolment_factory::factory($CFG->enrol);
1728         if (!method_exists($defaultenrol, 'print_entry')) {
1729             set_config('enrol', 'manual');
1730         }
1731     }
1732     
1733     if ($oldversion < 2006031600) {
1734         execute_sql(" ALTER TABLE `{$CFG->prefix}grade_category` CHANGE `weight` `weight` decimal(5,2) default '0.00';");
1735     }
1737     if ($oldversion < 2006032000) {
1738         table_column('post','','module','varchar','20','','','not null', 'id');
1739         modify_database('',"ALTER TABLE prefix_post ADD INDEX post_module_idx (module);");
1740         modify_database('',"UPDATE prefix_post SET module = 'blog';");
1741     }
1743     if ($oldversion < 2006032001) {
1744         table_column('blog_tag_instance','','timemodified','integer','10','unsigned','0','not null', 'userid');
1745         modify_database('',"ALTER TABLE prefix_blog_tag_instance ADD INDEX bti_entryid_idx (entryid);");
1746         modify_database('',"ALTER TABLE prefix_blog_tag_instance ADD INDEX bti_tagid_idx (tagid);");
1747         modify_database('',"UPDATE prefix_blog_tag_instance SET timemodified = '".time()."';");
1748     }
1750     if ($oldversion < 2006040500) { // Add an index to course_sections that was never upgraded (bug 5100)
1751         execute_sql(" CREATE INDEX coursesection ON {$CFG->prefix}course_sections (course,section) ", false);
1752     }
1754     /// change all the int(11) to int(10) for blogs and tags
1756     if ($oldversion < 2006041000) {
1757         table_column('post','id','id','integer','10','unsigned','0','not null');
1758         table_column('post','userid','userid','integer','10','unsigned','0','not null');
1759         table_column('post','courseid','courseid','integer','10','unsigned','0','not null');
1760         table_column('post','groupid','groupid','integer','10','unsigned','0','not null');
1761         table_column('post','moduleid','moduleid','integer','10','unsigned','0','not null');
1762         table_column('post','coursemoduleid','coursemoduleid','integer','10','unsigned','0','not null');
1763         table_column('post','rating','rating','integer','10','unsigned','0','not null');
1764         table_column('post','format','format','integer','10','unsigned','0','not null');
1765         table_column('tags','id','id','integer','10','unsigned','0','not null');
1766         table_column('tags','userid','userid','integer','10','unsigned','0','not null');
1767         table_column('blog_tag_instance','id','id','integer','10','unsigned','0','not null');
1768         table_column('blog_tag_instance','entryid','entryid','integer','10','unsigned','0','not null');
1769         table_column('blog_tag_instance','tagid','tagid','integer','10','unsigned','0','not null');
1770         table_column('blog_tag_instance','groupid','groupid','integer','10','unsigned','0','not null');
1771         table_column('blog_tag_instance','courseid','courseid','integer','10','unsigned','0','not null');
1772         table_column('blog_tag_instance','userid','userid','integer','10','unsigned','0','not null');
1773     }
1775     if ($oldversion < 2006041001) {
1776         table_column('cache_text','formattedtext','formattedtext','longblob','','','','not null');
1777     }
1778     
1779     if ($oldversion < 2006041100) {
1780         table_column('course_modules','','visibleold','integer','1','unsigned','1','not null', 'visible');
1781     }
1782     
1783     if ($oldversion < 2006041801) { // forgot auto_increments for ids
1784         modify_database('',"ALTER TABLE prefix_post CHANGE id id INT UNSIGNED NOT NULL AUTO_INCREMENT");
1785         modify_database('',"ALTER TABLE prefix_tags CHANGE id id INT UNSIGNED NOT NULL AUTO_INCREMENT");
1786         modify_database('',"ALTER TABLE prefix_blog_tag_instance CHANGE id id INT UNSIGNED NOT NULL AUTO_INCREMENT");
1787     }
1788     
1789     // changed user->firstname, user->lastname, course->shortname to varchar(100)
1790     
1791     if ($oldversion < 2006041900) {
1792         table_column('course','shortname','shortname','varchar','100','','','not null');
1793         table_column('user','firstname','firstname','varchar','100','','','not null');
1794         table_column('user','lastname','lastname','varchar','100','','','not null');
1795     }
1796     
1797     if ($oldversion < 2006042400) {
1798         // Look through table log_display and get rid of duplicates.
1799         $rs = get_recordset_sql('SELECT DISTINCT * FROM '.$CFG->prefix.'log_display');
1800         
1801         // Drop the log_display table and create it back with an id field.
1802         execute_sql("DROP TABLE {$CFG->prefix}log_display", false);
1803         
1804         modify_database('', "CREATE TABLE prefix_log_display (
1805                                `id` int(10) unsigned NOT NULL auto_increment,
1806                                `module` varchar(30),
1807                                `action` varchar(40),
1808                                `mtable` varchar(30),
1809                                `field` varchar(50),
1810                                PRIMARY KEY (`id`)
1811                                ) TYPE=MyISAM");
1812         
1813         // Add index to ensure that module and action combination is unique.
1814         modify_database('', "ALTER TABLE prefix_log_display ADD UNIQUE `moduleaction`(`module` , `action`)");
1815         
1816         // Insert the records back in, sans duplicates.
1817         if ($rs && $rs->RecordCount() > 0) {
1818             while (!$rs->EOF) {
1819                 $sql = "INSERT INTO {$CFG->prefix}log_display ".
1820                             "VALUES('', '".$rs->fields['module']."', ".
1821                             "'".$rs->fields['action']."', ".
1822                             "'".$rs->fields['mtable']."', ".
1823                             "'".$rs->fields['field']."')";
1824                 
1825                 execute_sql($sql, false);
1826                 $rs->MoveNext();
1827             }
1828         }
1829     }
1830     
1831     // change tags->type to varchar(20), adding 2 indexes for tags table.
1832     if ($oldversion < 2006042401) {
1833         table_column('tags','type','type','varchar','20','','','not null');
1834         modify_database('',"ALTER TABLE prefix_tags ADD INDEX tags_typeuserid_idx (type(20), userid)");
1835         modify_database('',"ALTER TABLE prefix_tags ADD INDEX tags_text_idx(text(255))");
1836     }
1837     
1838     /***************************************************
1839      * The following is an effort to change all the    *
1840      * default NULLs to NOT NULL defaut '' in all      *
1841      * mysql tables, to prevent 5303 and be consistent *
1842      ***************************************************/
1844     if ($oldversion < 2006042800) {
1846         execute_sql("UPDATE {$CFG->prefix}grade_category SET name='' WHERE name IS NULL");
1847         table_column('grade_category','name','name','varchar','64','','','not null');
1849         execute_sql("UPDATE {$CFG->prefix}grade_category SET weight='0' WHERE weight IS NULL");
1850         execute_sql("ALTER TABLE {$CFG->prefix}grade_category change weight weight decimal(5,2) NOT NULL default 0.00");
1851         execute_sql("UPDATE {$CFG->prefix}grade_item SET courseid='0' WHERE courseid IS NULL");
1852         table_column('grade_item','courseid','courseid','int','10','unsigned','0','not null');
1854         execute_sql("UPDATE {$CFG->prefix}grade_item SET category='0' WHERE category IS NULL");
1855         table_column('grade_item','category','category','int','10','unsigned','0','not null');
1857         execute_sql("UPDATE {$CFG->prefix}grade_item SET modid='0' WHERE modid IS NULL");
1858         table_column('grade_item','modid','modid','int','10','unsigned','0','not null');
1860         execute_sql("UPDATE {$CFG->prefix}grade_item SET cminstance='0' WHERE cminstance IS NULL");
1861         table_column('grade_item','cminstance','cminstance','int','10','unsigned','0','not null');
1863         execute_sql("UPDATE {$CFG->prefix}grade_item SET scale_grade='0' WHERE scale_grade IS NULL");
1864         execute_sql("ALTER TABLE {$CFG->prefix}grade_item change scale_grade scale_grade float(11,10) NOT NULL default 1.0000000000");
1865         
1866         execute_sql("UPDATE {$CFG->prefix}grade_preferences SET courseid='0' WHERE courseid IS NULL");
1867         table_column('grade_preferences','courseid','courseid','int','10','unsigned','0','not null');
1869         execute_sql("UPDATE {$CFG->prefix}user SET idnumber='' WHERE idnumber IS NULL");
1870         table_column('user','idnumber','idnumber','varchar','64','','','not null');
1872         execute_sql("UPDATE {$CFG->prefix}user SET icq='' WHERE icq IS NULL");
1873         table_column('user','icq','icq','varchar','15','','','not null');
1874         
1875         execute_sql("UPDATE {$CFG->prefix}user SET skype='' WHERE skype IS NULL");
1876         table_column('user','skype','skype','varchar','50','','','not null');
1877         
1878         execute_sql("UPDATE {$CFG->prefix}user SET yahoo='' WHERE yahoo IS NULL");
1879         table_column('user','yahoo','yahoo','varchar','50','','','not null');
1881         execute_sql("UPDATE {$CFG->prefix}user SET aim='' WHERE aim IS NULL");
1882         table_column('user','aim','aim','varchar','50','','','not null');
1884         execute_sql("UPDATE {$CFG->prefix}user SET msn='' WHERE msn IS NULL");
1885         table_column('user','msn','msn','varchar','50','','','not null');
1887         execute_sql("UPDATE {$CFG->prefix}user SET phone1='' WHERE phone1 IS NULL");
1888         table_column('user','phone1','phone1','varchar','20','','','not null');
1890         execute_sql("UPDATE {$CFG->prefix}user SET phone2='' WHERE phone2 IS NULL");
1891         table_column('user','phone2','phone2','varchar','20','','','not null');
1893         execute_sql("UPDATE {$CFG->prefix}user SET institution='' WHERE institution IS NULL");
1894         table_column('user','institution','institution','varchar','40','','','not null');
1896         execute_sql("UPDATE {$CFG->prefix}user SET department='' WHERE department IS NULL");
1897         table_column('user','department','department','varchar','30','','','not null');
1899         execute_sql("UPDATE {$CFG->prefix}user SET address='' WHERE address IS NULL");
1900         table_column('user','address','address','varchar','70','','','not null');
1901         
1902         execute_sql("UPDATE {$CFG->prefix}user SET city='' WHERE city IS NULL");
1903         table_column('user','city','city','varchar','20','','','not null');
1905         execute_sql("UPDATE {$CFG->prefix}user SET country='' WHERE country IS NULL");
1906         table_column('user','country','country','char','2','','','not null');
1908         execute_sql("UPDATE {$CFG->prefix}user SET lang='' WHERE lang IS NULL");
1909         table_column('user','lang','lang','varchar','10','','en','not null');
1911         execute_sql("UPDATE {$CFG->prefix}user SET lastIP='' WHERE lastIP IS NULL");
1912         table_column('user','lastIP','lastIP','varchar','15','','','not null');
1914         execute_sql("UPDATE {$CFG->prefix}user SET secret='' WHERE secret IS NULL");
1915         table_column('user','secret','secret','varchar','15','','','not null');
1917         execute_sql("UPDATE {$CFG->prefix}user SET picture='0' WHERE picture IS NULL");
1918         table_column('user','picture','picture','tinyint','1','','0','not null');
1920         execute_sql("UPDATE {$CFG->prefix}user SET url='' WHERE url IS NULL");
1921         table_column('user','url','url','varchar','255','','','not null');
1922     }
1923     
1924     if ($oldversion < 2006050400) {
1926         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_deleted_idx;",false);
1927         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_confirmed_idx;",false);
1928         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_firstname_idx;",false);
1929         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_lastname_idx;",false);
1930         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_city_idx;",false);
1931         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_country_idx;",false);
1932         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_lastaccess_idx;",false);
1933         execute_sql("ALTER TABLE `{$CFG->prefix}user` DROP INDEX {$CFG->prefix}user_email_idx;",false);
1935         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_deleted (deleted)",false);
1936         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_confirmed (confirmed)",false);
1937         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_firstname (firstname)",false);
1938         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_lastname (lastname)",false);
1939         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_city (city)",false);
1940         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_country (country)",false);
1941         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_lastaccess (lastaccess)",false);
1942         execute_sql("ALTER TABLE `{$CFG->prefix}user` ADD INDEX user_email (email)",false);
1943     }
1944     
1945     if ($oldversion < 2006050500) {
1946         table_column('log', 'action', 'action', 'varchar', '40', '', '', 'not null');
1947     }
1949     if ($oldversion < 2006050501) {
1950         table_column('sessions', 'data', 'data', 'mediumtext', '', '', '', 'not null');
1951     }
1952     
1953     // renaming of reads and writes for stats_user_xyz
1954     if ($oldversion < 2006052400) { // change this later
1956         // we are using this because we want silent updates
1958         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_daily` CHANGE `reads` statsreads int(10) unsigned  NOT NULL default 0", false);
1959         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_daily` CHANGE `writes` statswrites int(10) unsigned  NOT NULL default 0", false);
1960         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_weekly` CHANGE `reads` statsreads int(10) unsigned  NOT NULL default 0", false);
1961         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_weekly` CHANGE `writes` statswrites int(10) unsigned  NOT NULL default 0", false);
1962         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_monthly` CHANGE `reads` statsreads int(10) unsigned  NOT NULL default 0", false);
1963         execute_sql("ALTER TABLE `{$CFG->prefix}stats_user_monthly` CHANGE `writes` statswrites int(10) unsigned  NOT NULL default 0", false);
1964   
1965     }
1967     // Adding some missing log actions
1968     if ($oldversion < 2006060400) {
1969         // But only if they doesn't exist (because this was introduced after branch and we could be duplicating!)
1970         if (!record_exists('log_display', 'module', 'course', 'action', 'report log')) {
1971             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'report log', 'course', 'fullname')");
1972         }
1973         if (!record_exists('log_display', 'module', 'course', 'action', 'report live')) {
1974             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'report live', 'course', 'fullname')");
1975         }
1976         if (!record_exists('log_display', 'module', 'course', 'action', 'report outline')) {
1977             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'report outline', 'course', 'fullname')");
1978         }
1979         if (!record_exists('log_display', 'module', 'course', 'action', 'report participation')) {
1980             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'report participation', 'course', 'fullname')");
1981         }
1982         if (!record_exists('log_display', 'module', 'course', 'action', 'report stats')) {
1983             execute_sql("INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'report stats', 'course', 'fullname')");
1984         }
1985     }
1987     //Renaming lastIP to lastip (all fields lowercase)
1988     if ($oldversion < 2006060900) {
1989         //Only if it exists
1990         $fields = $db->MetaColumnNames($CFG->prefix.'user');
1991         if (in_array('lastIP',$fields)) {
1992             table_column("user", "lastIP", "lastip", "varchar", "15", "", "", "not null", "currentlogin");
1993         }
1994     }
1996     // Change in MySQL 5.0.3 concerning how decimals are stored. Mimic from 16_STABLE
1997     // this isn't dangerous because it's a simple type change, but be careful with
1998     // versions and duplicate work in order to provide smooth upgrade paths.
1999     if ($oldversion < 2006071800) {
2000         table_column('grade_letter', 'grade_high', 'grade_high', 'decimal(5,2)', '', '', '100.00', 'not null', '');
2001         table_column('grade_letter', 'grade_low', 'grade_low', 'decimal(5,2)', '', '', '0.00', 'not null', '');
2002     }
2003     
2004     if ($oldversion < 2006080400) {
2005         execute_sql("CREATE TABLE {$CFG->prefix}role (
2006                               `id` int(10) unsigned NOT NULL auto_increment,
2007                               `name` varchar(255) NOT NULL default '',
2008                               `description` text NOT NULL default '',
2009                               `sortorder` int(10) unsigned NOT NULL default '0',
2010                               PRIMARY KEY  (`id`)
2011                             )", true);
2013         execute_sql("CREATE TABLE {$CFG->prefix}context (
2014                               `id` int(10) unsigned NOT NULL auto_increment,
2015                               `level` int(10) unsigned NOT NULL default '0',
2016                               `instanceid` int(10) unsigned NOT NULL default '0',
2017                               PRIMARY KEY  (`id`)
2018                             )", true);
2020         execute_sql("CREATE TABLE {$CFG->prefix}role_assignments (
2021                               `id` int(10) unsigned NOT NULL auto_increment,
2022                               `roleid` int(10) unsigned NOT NULL default '0',
2023                               `contextid` int(10) unsigned NOT NULL default '0',
2024                               `userid` int(10) unsigned NOT NULL default '0',
2025                               `hidden` int(1) unsigned NOT NULL default '0',
2026                               `timestart` int(10) unsigned NOT NULL default '0',
2027                               `timeend` int(10) unsigned NOT NULL default '0',
2028                               `timemodified` int(10) unsigned NOT NULL default '0',
2029                               `modifierid` int(10) unsigned NOT NULL default '0',
2030                               `enrol` varchar(20) NOT NULL default '',
2031                               `sortorder` int(10) unsigned NOT NULL default '0',
2032                               PRIMARY KEY  (`id`)
2033                             )", true);
2035         execute_sql("CREATE TABLE {$CFG->prefix}role_capabilities (
2036                               `id` int(10) unsigned NOT NULL auto_increment,
2037                               `contextid` int(10) unsigned NOT NULL default '0',
2038                               `roleid` int(10) unsigned NOT NULL default '0',
2039                               `capability` varchar(255) NOT NULL default '',
2040                               `permission` int(10) unsigned NOT NULL default '0',
2041                               `timemodified` int(10) unsigned NOT NULL default '0',
2042                               `modifierid` int(10) unsigned NOT NULL default '0',
2043                               PRIMARY KEY (`id`)
2044                             )", true);
2045                             
2046         execute_sql("CREATE TABLE {$CFG->prefix}role_deny_grant (
2047                               `id` int(10) unsigned NOT NULL auto_increment,
2048                               `roleid` int(10) unsigned NOT NULL default '0',
2049                               `unviewableroleid` int(10) unsigned NOT NULL default '0',
2050                               PRIMARY KEY (`id`)
2051                             )", true);
2052                             
2053         execute_sql("CREATE TABLE {$CFG->prefix}capabilities ( 
2054                               `id` int(10) unsigned NOT NULL auto_increment, 
2055                               `name` varchar(255) NOT NULL default '', 
2056                               `captype` varchar(50) NOT NULL default '', 
2057                               `contextlevel` int(10) unsigned NOT NULL default '0', 
2058                               `component` varchar(100) NOT NULL default '', 
2059                               PRIMARY KEY (`id`) 
2060                             )", true);     
2061                             
2062         execute_sql("CREATE TABLE {$CFG->prefix}role_names ( 
2063                               `id` int(10) unsigned NOT NULL auto_increment, 
2064                               `roleid` int(10) unsigned NOT NULL default '0',
2065                               `contextid` int(10) unsigned NOT NULL default '0', 
2066                               `text` text NOT NULL default '',
2067                               PRIMARY KEY (`id`) 
2068                             )", true);                      
2069                         
2070     }
2071     
2072     if ($oldversion < 2006081000) {
2073       
2074         execute_sql("ALTER TABLE `{$CFG->prefix}role` ADD INDEX `sortorder` (`sortorder`)",true);
2075         
2076         execute_sql("ALTER TABLE `{$CFG->prefix}context` ADD INDEX `instanceid` (`instanceid`)",true);
2077         execute_sql("ALTER TABLE `{$CFG->prefix}context` ADD UNIQUE INDEX `level-instanceid` (`level`, `instanceid`)",true);
2079         execute_sql("ALTER TABLE `{$CFG->prefix}role_assignments` ADD INDEX `roleid` (`roleid`)",true);
2080         execute_sql("ALTER TABLE `{$CFG->prefix}role_assignments` ADD INDEX `contextid` (`contextid`)",true);  
2081         execute_sql("ALTER TABLE `{$CFG->prefix}role_assignments` ADD INDEX `userid` (`userid`)",true);
2082         execute_sql("ALTER TABLE `{$CFG->prefix}role_assignments` ADD UNIQUE INDEX `contextid-roleid-userid` (`contextid`, `roleid`, `userid`)",true);
2083         execute_sql("ALTER TABLE `{$CFG->prefix}role_assignments` ADD INDEX `sortorder` (`sortorder`)",true);
2085         execute_sql("ALTER TABLE `{$CFG->prefix}role_capabilities` ADD INDEX `roleid` (`roleid`)",true);  
2086         execute_sql("ALTER TABLE `{$CFG->prefix}role_capabilities` ADD INDEX `contextid` (`contextid`)",true); 
2087         execute_sql("ALTER TABLE `{$CFG->prefix}role_capabilities` ADD INDEX `modifierid` (`modifierid`)",true); 
2088         execute_sql("ALTER TABLE `{$CFG->prefix}role_capabilities` ADD UNIQUE INDEX `roleid-contextid-capability` (`roleid`, `contextid`, `capability`)",true);         
2089                         
2090         execute_sql("ALTER TABLE `{$CFG->prefix}role_deny_grant` ADD INDEX `roleid` (`roleid`)",true);
2091         execute_sql("ALTER TABLE `{$CFG->prefix}role_deny_grant` ADD INDEX `unviewableroleid` (`unviewableroleid`)",true);    
2092         execute_sql("ALTER TABLE `{$CFG->prefix}role_deny_grant` ADD UNIQUE INDEX `roleid-unviewableroleid` (`roleid`, `unviewableroleid`)",true);         
2093        
2094         execute_sql("ALTER TABLE `{$CFG->prefix}capabilities` ADD UNIQUE INDEX `name` (`name`)",true); 
2095                              
2096         execute_sql("ALTER TABLE `{$CFG->prefix}role_names` ADD INDEX `roleid` (`roleid`)",true);                         
2097         execute_sql("ALTER TABLE `{$CFG->prefix}role_names` ADD INDEX `contextid` (`contextid`)",true); 
2098         execute_sql("ALTER TABLE `{$CFG->prefix}role_names` ADD UNIQUE INDEX `roleid-contextid` (`roleid`, `contextid`)",true);                 
2099     }
2100     
2101     if ($oldversion < 2006081600) {
2102         execute_sql("ALTER TABLE `{$CFG->prefix}role_capabilities` CHANGE permission permission int(10) NOT NULL default '0'",true);   
2103     }
2104     
2105     // drop role_deny_grant table, and create 2 new ones
2106     if ($oldversion < 2006081700) {
2107         execute_sql("DROP TABLE `{$CFG->prefix}role_deny_grant`", true);
2108         
2109         execute_sql("CREATE TABLE {$CFG->prefix}role_allow_assign (
2110                     `id` int(10) unsigned NOT NULL auto_increment,
2111                     `roleid` int(10) unsigned NOT NULL default '0',
2112                     `allowassign` int(10) unsigned NOT NULL default '0',
2113                     KEY `roleid` (`roleid`),
2114                     KEY `allowassign` (`allowassign`),
2115                     UNIQUE KEY `roleid-allowassign` (`roleid`, `allowassign`),
2116                     PRIMARY KEY (`id`)
2117                     )", true); 
2118                             
2119         execute_sql("CREATE TABLE {$CFG->prefix}role_allow_override (
2120                     `id` int(10) unsigned NOT NULL auto_increment,
2121                     `roleid` int(10) unsigned NOT NULL default '0',
2122                     `allowoverride` int(10) unsigned NOT NULL default '0',
2123                     KEY `roleid` (`roleid`),
2124                     KEY `allowoverride` (`allowoverride`),
2125                     UNIQUE KEY `roleid-allowoverride` (`roleid`, `allowoverride`),
2126                     PRIMARY KEY (`id`)
2127                     )", true); 
2128         
2129     }
2130     
2131     if ($oldversion < 2006082100) {
2132         execute_sql("ALTER TABLE `{$CFG->prefix}context` DROP INDEX `level-instanceid`;",false);
2133         table_column('context', 'level', 'aggregatelevel', 'int', '10', 'unsigned', '0', 'not null', '');
2134         execute_sql("ALTER TABLE `{$CFG->prefix}context` ADD UNIQUE INDEX `aggregatelevel-instanceid` (`aggregatelevel`, `instanceid`)",false);
2135     }
2136     
2137     if ($oldversion < 2006082200) {
2138         table_column('timezone', 'rule', 'tzrule', 'varchar', '20', '', '', 'not null', '');
2139     }
2141     if ($oldversion < 2006082800) {
2142         table_column('user', '', 'ajax', 'integer', '1', 'unsigned', '1', '', 'htmleditor');
2143     }
2145     if ($oldversion < 2006082900) {
2146         execute_sql("DROP TABLE {$CFG->prefix}sessions", true);
2147         execute_sql("
2148             CREATE TABLE {$CFG->prefix}sessions2 (
2149                 sesskey VARCHAR(64) NOT NULL default '',
2150                 expiry DATETIME NOT NULL,
2151                 expireref VARCHAR(250),
2152                 created DATETIME NOT NULL,
2153                 modified DATETIME NOT NULL,
2154                 sessdata TEXT,
2155                 CONSTRAINT  PRIMARY KEY (sesskey)
2156             ) COMMENT='Optional database session storage in new format, not used by default';", true);
2158         execute_sql("
2159             CREATE INDEX {$CFG->prefix}sess_exp_ix ON {$CFG->prefix}sessions2 (expiry);", true);
2160         execute_sql("
2161             CREATE INDEX {$CFG->prefix}sess_exp2_ix ON {$CFG->prefix}sessions2 (expireref);", true);
2162     }
2164     if ($oldversion < 2006083001) {
2165         table_column('sessions2', 'sessdata', 'sessdata', 'LONGTEXT', '', '', '', '', '');
2166     }
2167     
2168     if ($oldversion < 2006083002) {
2169         table_column('capabilities', '', 'riskbitmask', 'INTEGER', '10', 'unsigned', '0', 'not null', '');
2170     }
2172     if ($oldversion < 2006083100) {
2173         execute_sql("ALTER TABLE {$CFG->prefix}course CHANGE modinfo modinfo longtext NULL AFTER showgrades");
2174     }
2176     if ($oldversion < 2006083101) {
2177         execute_sql("ALTER TABLE {$CFG->prefix}course_categories CHANGE description description text NULL AFTER name");
2178     }
2180     if ($oldversion < 2006083102) {
2181         execute_sql("ALTER TABLE {$CFG->prefix}user CHANGE description description text NULL AFTER url");
2182     }
2184     if ($oldversion < 2006090200) {
2185         execute_sql("ALTER TABLE {$CFG->prefix}course_sections CHANGE summary summary text NULL AFTER section");
2186         execute_sql("ALTER TABLE {$CFG->prefix}course_sections CHANGE sequence sequence text NULL AFTER section");
2187     }
2190     // table to keep track of course page access times, used in online participants block, and participants list
2191     if ($oldversion < 2006091200) {
2192         execute_sql("CREATE TABLE {$CFG->prefix}user_lastaccess ( 
2193                     `id` int(10) unsigned NOT NULL auto_increment, 
2194                     `userid` int(10) unsigned NOT NULL default '0',
2195                     `courseid` int(10) unsigned NOT NULL default '0', 
2196                     `timeaccess` int(10) unsigned NOT NULL default '0', 
2197                     KEY `userid` (`userid`),
2198                     KEY `courseid` (`courseid`),
2199                     UNIQUE KEY `userid-courseid` (`userid`, `courseid`),
2200                     PRIMARY KEY (`id`) 
2201                     )TYPE=MYISAM COMMENT ='time user last accessed any page in a course';", true);
2202     }
2204     if ($oldversion < 2006091212) {   // Reload the guest roles completely with new defaults
2205         if ($guestroles = get_roles_with_capability('moodle/legacy:guest', CAP_ALLOW)) {
2206             delete_records('capabilities');
2207             $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
2208             foreach ($guestroles as $guestrole) {
2209                 delete_records('role_capabilities', 'roleid', $guestrole->id);
2210                 assign_capability('moodle/legacy:guest', CAP_ALLOW, $guestrole->id, $sitecontext->id);
2211             }
2212         }
2213     }
2215     if ($oldversion < 2006091700) {
2216         table_column('course','','defaultrole','integer','10', 'unsigned', '0', 'not null');
2217     }
2219     if ($oldversion < 2006091800) {
2220         delete_records('config', 'name', 'showsiteparticipantslist');
2221         delete_records('config', 'name', 'requestedteachername');
2222         delete_records('config', 'name', 'requestedteachersname');
2223         delete_records('config', 'name', 'requestedstudentname');
2224         delete_records('config', 'name', 'requestedstudentsname');
2225     }
2227     if ($oldversion < 2006091901) {
2228         if ($roles = get_records('role')) {
2229             $first = array_shift($roles);
2230             if (!empty($first->shortname)) {
2231                 // shortnames already exist
2232             } else {
2233                 table_column('role', '', 'shortname', 'varchar', '100', '', '', 'not null', 'name');
2234                 $legacy_names = array('admin', 'coursecreator', 'editingteacher', 'teacher', 'student', 'guest');
2235                 foreach ($legacy_names as $name) {
2236                     if ($roles = get_roles_with_capability('moodle/legacy:'.$name, CAP_ALLOW)) {
2237                         $i = '';
2238                         foreach ($roles as $role) {
2239                             if (empty($role->shortname)) {
2240                                 $updated = new object();
2241                                 $updated->id = $role->id;
2242                                 $updated->shortname = $name.$i;
2243                                 update_record('role', $updated);
2244                                 $i++;
2245                             }
2246                         }
2247                     }
2248                 }
2249             }
2250         }
2251     }
2253     /// Tables for customisable user profile fields
2254     if ($oldversion < 2006092000) {
2255         execute_sql("CREATE TABLE {$CFG->prefix}user_info_field (
2256                         id BIGINT(10) NOT NULL auto_increment,
2257                         name VARCHAR(255) NOT NULL default '',
2258                         datatype VARCHAR(255) NOT NULL default '',
2259                         categoryid BIGINT(10) unsigned NOT NULL default 0,
2260                         sortorder BIGINT(10) unsigned NOT NULL default 0,
2261                         required TINYINT(2) unsigned NOT NULL default 0,
2262                         locked TINYINT(2) unsigned NOT NULL default 0,
2263                         visible SMALLINT(4) unsigned NOT NULL default 0,
2264                         defaultdata LONGTEXT,
2265                         CONSTRAINT  PRIMARY KEY (id));", true);
2267         execute_sql("ALTER TABLE {$CFG->prefix}user_info_field COMMENT='Customisable user profile fields';", true);
2269         execute_sql("CREATE TABLE {$CFG->prefix}user_info_category (
2270                         id BIGINT(10) NOT NULL auto_increment,
2271                         name VARCHAR(255) NOT NULL default '',
2272                         sortorder BIGINT(10) unsigned NOT NULL default 0,
2273                         CONSTRAINT  PRIMARY KEY (id));", true);
2275         execute_sql("ALTER TABLE {$CFG->prefix}user_info_category COMMENT='Customisable fields categories';", true);
2277         execute_sql("CREATE TABLE {$CFG->prefix}user_info_data (
2278                         id BIGINT(10) NOT NULL auto_increment,
2279                         userid BIGINT(10) unsigned NOT NULL default 0,
2280                         fieldid BIGINT(10) unsigned NOT NULL default 0,
2281                         data LONGTEXT NOT NULL,
2282                         CONSTRAINT  PRIMARY KEY (id));", true);
2284         execute_sql("ALTER TABLE {$CFG->prefix}user_info_data COMMENT='Data for the customisable user fields';", true);
2287     }
2289     if ($oldversion < 2006092200) {
2290        table_column('context', 'aggregatelevel', 'contextlevel', 'int', '10', 'unsigned', '0', 'not null', '');
2291 /*        execute_sql("ALTER TABLE `{$CFG->prefix}context` DROP INDEX `aggregatelevel-instanceid`;",false);
2292         execute_sql("ALTER TABLE `{$CFG->prefix}context` ADD UNIQUE INDEX `contextlevel-instanceid` (`contextlevel`, `instanceid`)",false);   // see 2006092409 below  */
2293     }
2295     if ($oldversion < 2006092201) {
2296         execute_sql('TRUNCATE TABLE '.$CFG->prefix.'cache_text', true);
2297         table_column('cache_text','formattedtext','formattedtext','longtext','','','','not null');
2298     }
2300     if ($oldversion < 2006092302) {
2301         // fix sortorder first if needed
2302         if ($roles = get_all_roles()) {
2303             $i = 0;
2304             foreach ($roles as $rolex) {
2305                 if ($rolex->sortorder != $i) {
2306                     $r = new object();
2307                     $r->id = $rolex->id;
2308                     $r->sortorder = $i;
2309                     update_record('role', $r);
2310                 }
2311                 $i++;
2312             }
2313         }
2314 /*        execute_sql("ALTER TABLE {$CFG->prefix}role DROP INDEX {$CFG->prefix}role_sor_ix;", false);
2315         execute_sql("ALTER TABLE {$CFG->prefix}role ADD UNIQUE INDEX {$CFG->prefix}role_sor_uix (sortorder)", false);*/
2316     }
2318     if ($oldversion < 2006092400) {
2319         table_column('user', '', 'trustbitmask', 'INTEGER', '10', 'unsigned', '0', 'not null', '');
2320     }
2322     if ($oldversion < 2006092409) {
2323         // ok, once more and now correctly!
2324         execute_sql("DROP INDEX `aggregatelevel-instanceid` ON {$CFG->prefix}context ;", false);
2325         execute_sql("DROP INDEX `contextlevel-instanceid` ON {$CFG->prefix}context ;", false);
2326         execute_sql("CREATE UNIQUE INDEX {$CFG->prefix}cont_conins_uix ON {$CFG->prefix}context (contextlevel, instanceid);", false);
2328         execute_sql("DROP INDEX {$CFG->prefix}role_sor_ix ON {$CFG->prefix}role ;", false);
2329         execute_sql("DROP INDEX {$CFG->prefix}role_sor_uix ON {$CFG->prefix}role ;", false);
2330         execute_sql("CREATE UNIQUE INDEX {$CFG->prefix}role_sor_uix ON {$CFG->prefix}role (sortorder);", false);
2331     }
2333     if ($oldversion < 2006092601) {
2334         table_column('log_display', 'field', 'field', 'varchar', '200', '', '', 'not null', '');
2335     }
2337     return $result;
2340 ?>