f3555dc1dbfc260236cce2eddfc9871764abedbf
[moodle.git] / lib / db / postgres7.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 PostgreSQL 7
20 function main_upgrade($oldversion=0) {
22     global $CFG, $THEME, $db;
24     $result = true;
27     if ($oldversion < 2003010101) {
28         delete_records("log_display", "module", "user");
29         $new->module = "user";
30         $new->action = "view";
31         $new->mtable = "user";
32         $new->field  = "CONCAT(firstname,\" \",lastname)";
33         insert_record("log_display", $new);
35         delete_records("log_display", "module", "course");
36         $new->module = "course";
37         $new->action = "view";
38         $new->mtable = "course";
39         $new->field  = "fullname";
40         insert_record("log_display", $new);
41         $new->action = "update";
42         insert_record("log_display", $new);
43         $new->action = "enrol";
44         insert_record("log_display", $new);
45     }
46     
47     //support user based course creating
48     if ($oldversion < 2003032400) {
49         execute_sql("CREATE TABLE {$CFG->prefix}user_coursecreators (
50                                   id int8 SERIAL PRIMARY KEY,
51                                   userid int8  NOT NULL default '0'
52                                   )");
53     }
55     if ($oldversion < 2003041400) {
56         table_column("course_modules", "", "visible", "integer", "1", "unsigned", "1", "not null", "score");
57     }
59     if ($oldversion < 2003042104) {  // Try to update permissions of all files
60         if ($files = get_directory_list($CFG->dataroot)) {
61             echo "Attempting to update permissions for all files... ignore any errors.";
62             foreach ($files as $file) {
63                 echo "$CFG->dataroot/$file<br />";
64                 @chmod("$CFG->dataroot/$file", $CFG->directorypermissions);
65             }
66         }
67     }
69     if ($oldversion < 2003042400) {
70     // Rebuild all course caches, because of changes to do with visible variable
71         if ($courses = get_records_sql("SELECT * FROM {$CFG->prefix}course")) {
72             require_once("$CFG->dirroot/course/lib.php");
73             foreach ($courses as $course) {
74                 $modinfo = serialize(get_array_of_activities($course->id));
76                 if (!set_field("course", "modinfo", $modinfo, "id", $course->id)) {
77                     notify("Could not cache module information for course '$course->fullname'!");
78                 }
79             }
80         }
81     }
83     if ($oldversion < 2003042500) {                 
84     //  Convert all usernames to lowercase.  
85         $users = get_records_sql("SELECT id, username FROM {$CFG->prefix}user"); 
86         $cerrors = "";
87         $rarray = array();
89         foreach ($users as $user) {      // Check for possible conflicts
90             $lcname = trim(moodle_strtolower($user->username));
91             if (in_array($lcname, $rarray)) {
92                 $cerrors .= $user->id."->".$lcname.'<br/>' ; 
93             } else {
94                 array_push($rarray,$lcname);
95             }
96         }
98         if ($cerrors != '') {
99             notify("Error: Cannot convert usernames to lowercase. 
100                     Following usernames would overlap (id->username):<br/> $cerrors . 
101                     Please resolve overlapping errors."); 
102             $result = false;
103         }
105         $cerrors = "";
106         echo "Checking userdatabase:<br />";
107         foreach ($users as $user) {
108             $lcname = trim(moodle_strtolower($user->username));
109             if ($lcname != $user->username) {
110                 $convert = set_field("user" , "username" , $lcname, "id", $user->id);
111                 if (!$convert) {
112                     if ($cerrors){
113                        $cerrors .= ", ";
114                     }   
115                     $cerrors .= $item;
116                 } else {
117                     echo ".";
118                 }   
119             }
120         }
121         if ($cerrors != '') {
122             notify("There were errors when converting following usernames to lowercase. 
123                    '$cerrors' . Sorry, but you will need to fix your database by hand.");
124             $result = false;
125         }
126     }
128     if ($oldversion < 2003042700) {
129         /// Changing to multiple indexes
130         execute_sql(" CREATE INDEX {$CFG->prefix}log_coursemoduleaction_idx ON {$CFG->prefix}log (course,module,action) ");
131         execute_sql(" CREATE INDEX {$CFG->prefix}log_courseuserid_idx ON {$CFG->prefix}log (course,userid) ");
132     }
134     if ($oldversion < 2003042801) {
135         execute_sql("CREATE TABLE {$CFG->prefix}course_display (
136                          id SERIAL PRIMARY KEY,
137                          course integer NOT NULL default '0',
138                          userid integer NOT NULL default '0',
139                          display integer NOT NULL default '0'
140                       )");
142         execute_sql("CREATE INDEX {$CFG->prefix}course_display_courseuserid_idx ON {$CFG->prefix}course_display (course,userid)");
143     }
145     if ($oldversion < 2003050400) {
146         table_column("course_sections", "", "visible", "integer", "1", "unsigned", "1", "", "");
147     }
148                                                             
149     if ($oldversion < 2003050401) {
150         table_column("user", "", "lang", "VARCHAR", "5", "", "$CFG->lang" ,"NOT NULL","");
151     }
153     if ($oldversion < 2003050900) {
154         table_column("modules", "", "visible", "integer", "1", "unsigned", "1", "", "");
155     }
157     if ($oldversion < 2003050902) {
158         if (get_records("modules", "name", "pgassignment")) {
159             print_simple_box("Note: the pgassignment module will soon be deleted from CVS!  Go to the new 'Manage Modules' page and DELETE IT from your system", "center", "50%", "$THEME->cellheading", "20", "noticebox");
160         }
161     }
163     if ($oldversion < 2003051600) {
164         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");
165     }
167     if ($oldversion < 2003052300) {
168         table_column("user", "", "autosubscribe", "integer", "1", "unsigned", "1", "", "htmleditor");
169     }
171     if ($oldversion < 2003072100) {
172         table_column("course", "", "visible", "integer", "1", "unsigned", "1", "", "marker");
173     }
175     if ($oldversion < 2003072101) {
176         table_column("course_sections", "sequence", "sequence", "text", "", "", "", "", "");
177     }
179     if ($oldversion < 2003072800) {
180         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");
181         flush();
182         execute_sql(" CREATE INDEX {$CFG->prefix}log_timecoursemoduleaction_idx ON {$CFG->prefix}log (time,course,module,action) ");
183         execute_sql(" CREATE INDEX {$CFG->prefix}user_students_courseuserid_idx ON {$CFG->prefix}user_students (course,userid) ");
184         execute_sql(" CREATE INDEX {$CFG->prefix}user_teachers_courseuserid_idx ON {$CFG->prefix}user_teachers (course,userid) ");
185     }
187     if ($oldversion < 2003072802) {
188         table_column("course_categories", "", "description", "text", "", "", "");
189         table_column("course_categories", "", "parent", "integer", "10", "unsigned");
190         table_column("course_categories", "", "sortorder", "integer", "10", "unsigned");
191         table_column("course_categories", "", "courseorder", "text", "", "", "");
192         table_column("course_categories", "", "visible", "integer", "1", "unsigned", "1");
193         table_column("course_categories", "", "timemodified", "integer", "10", "unsigned");
194     }
196     if ($oldversion < 2003080400) {
197         notify("If the following command fails you may want to change the type manually, from TEXT to INTEGER.  Moodle should keep working even if you don't.");
198         table_column("course_categories", "courseorder", "courseorder", "integer", "10", "unsigned");
199         table_column("course", "", "sortorder", "integer", "10", "unsigned", "0", "", "category");
200     }
202     if ($oldversion < 2003081502) {
203         execute_sql(" CREATE TABLE {$CFG->prefix}scale (
204                          id SERIAL PRIMARY KEY,
205                          courseid integer NOT NULL default '0',
206                          userid integer NOT NULL default '0',
207                          name varchar(255) NOT NULL default '',
208                          scale text,
209                          description text,
210                          timemodified integer NOT NULL default '0'
211                       )");
212     }
214     if ($oldversion < 2003081503) {
215         table_column("forum", "", "scale", "integer", "10", "unsigned", "0", "", "assessed");
216         get_scales_menu(0);    // Just to force the default scale to be created
217     }
219     if ($oldversion < 2003081600) {
220         table_column("user_teachers", "", "editall", "integer", "1", "unsigned", "1", "", "role");
221         table_column("user_teachers", "", "timemodified", "integer", "10", "unsigned", "0", "", "editall");
222     }
224     if ($oldversion < 2003081900) {
225         table_column("course_categories", "courseorder", "coursecount", "integer", "10", "unsigned", "0");
226     }
228     if ($oldversion < 2003080700) {
229         notify("Cleaning up categories and course ordering...");
230         fix_course_sortorder();
231     }
234     if ($oldversion < 2003082001) {
235         table_column("course", "", "showgrades", "integer", "2", "unsigned", "1", "", "format");
236     }
238     if ($oldversion < 2003082101) {
239         execute_sql(" CREATE INDEX {$CFG->prefix}course_category_idx ON {$CFG->prefix}course (category) ");
240     }
241     if ($oldversion < 2003082702) {
242         execute_sql(" INSERT INTO {$CFG->prefix}log_display (module, action, mtable, field) VALUES ('course', 'user report', 'user', 'CONCAT(firstname,\" \",lastname)') ");
243     }
245     if ($oldversion < 2003091000) {
246         # Old field that was never added!
247         table_column("course", "", "showrecent", "integer", "10", "unsigned", "1", "", "numsections");
248     }
250     if ($oldversion < 2003091400) {
251         table_column("course_modules", "", "indent", "integer", "5", "unsigned", "0", "", "score");
252     }
254     if ($oldversion < 2003092900) {
255         table_column("course", "", "maxbytes", "integer", "10", "unsigned", "0", "", "marker");
256     }
258     if ($oldversion < 2003102700) {
259         table_column("user_students", "", "timeaccess", "integer", "10", "unsigned", "0", "", "time");
260         table_column("user_teachers", "", "timeaccess", "integer", "10", "unsigned", "0", "", "timemodified");
262         $db->debug = false;
263         $CFG->debug = 0;
264         notify("Calculating access times.  Please wait - this may take a long time on big sites...", "green");
265         flush();
267         if ($courses = get_records_select("course", "category > 0")) {
268             foreach ($courses as $course) {
269                 notify("Processing $course->fullname ...", "green");
270                 flush();
271                 if ($users = get_records_select("user_teachers", "course = '$course->id'", 
272                                                 "id", "id, userid, timeaccess")) {
273                     foreach ($users as $user) {
274                         $loginfo = get_record_sql("SELECT id, time FROM {$CFG->prefix}log                                                                                  WHERE course = '$course->id' and userid = '$user->userid'                                                               ORDER by time DESC");
275                         if (empty($loginfo->time)) {
276                             $loginfo->time = 0;
277                         }
278                         execute_sql("UPDATE {$CFG->prefix}user_teachers                                                                                      SET timeaccess = '$loginfo->time' 
279                                      WHERE userid = '$user->userid' AND course = '$course->id'", false);
280                         
281                     }
282                 }
284                 if ($users = get_records_select("user_students", "course = '$course->id'", 
285                                                 "id", "id, userid, timeaccess")) {
286                     foreach ($users as $user) {
287                         $loginfo = get_record_sql("SELECT id, time FROM {$CFG->prefix}log 
288                                                    WHERE course = '$course->id' and userid = '$user->userid' 
289                                                    ORDER by time DESC");
290                         if (empty($loginfo->time)) {
291                             $loginfo->time = 0;
292                         }
293                         execute_sql("UPDATE {$CFG->prefix}user_students 
294                                      SET timeaccess = '$loginfo->time' 
295                                      WHERE userid = '$user->userid' AND course = '$course->id'", false);
296                         
297                     }
298                 }
299             }
300         }
301         notify("All courses complete.", "green");
302         $db->debug = true;
303     }
305     if ($oldversion < 2003103100) {
306         table_column("course", "", "showreports", "integer", "4", "unsigned", "0", "", "maxbytes");
307     }
310     if ($oldversion < 2003121600) {
311         execute_sql("CREATE TABLE {$CFG->prefix}groups (
312                         id SERIAL PRIMARY KEY,
313                         courseid integer NOT NULL default '0',
314                         name varchar(255) NOT NULL default '',
315                         description text,
316                         lang varchar(10) NOT NULL default '',
317                         picture integer NOT NULL default '0',
318                         timecreated integer NOT NULL default '0',
319                         timemodified integer NOT NULL default '0'
320                      )");
321     
322         execute_sql("CREATE INDEX {$CFG->prefix}groups_idx ON {$CFG->prefix}groups (courseid) ");
323     
324         execute_sql("CREATE TABLE {$CFG->prefix}groups_members (
325                         id SERIAL PRIMARY KEY,
326                         groupid integer NOT NULL default '0',
327                         userid integer NOT NULL default '0',
328                         timeadded integer NOT NULL default '0'
329                      )");
330       
331         execute_sql("CREATE INDEX {$CFG->prefix}groups_members_idx ON {$CFG->prefix}groups_members (groupid) ");
332     }
334     if ($oldversion < 2003122600) {
335         table_column("course", "", "groupmode", "integer", "4", "unsigned", "0", "", "visible");
336         table_column("course", "", "groupmodeforce", "integer", "4", "unsigned", "0", "", "groupmode");
337     }
339     if ($oldversion < 2004010900) {
340         table_column("course_modules", "", "groupmode", "integer", "4", "unsigned", "0", "", "visible");
341     }
343     if ($oldversion < 2004011700) {
344         modify_database("", "CREATE TABLE prefix_event (
345                                 id SERIAL PRIMARY KEY,
346                                 name varchar(255) NOT NULL default '',
347                                 description text,
348                                 courseid integer NOT NULL default '0',
349                                 groupid integer NOT NULL default '0',
350                                 userid integer NOT NULL default '0',
351                                 modulename varchar(20) NOT NULL default '',
352                                 instance integer NOT NULL default '0',
353                                 eventtype varchar(20) NOT NULL default '',
354                                 timestart integer NOT NULL default '0',
355                                 timeduration integer NOT NULL default '0',
356                                 timemodified integer NOT NULL default '0'
357                              ); ");
359         modify_database("", "CREATE INDEX prefix_event_courseid_idx ON prefix_event (courseid);");
360         modify_database("", "CREATE INDEX prefix_event_userid_idx ON prefix_event (userid);");
361     }
364     if ($oldversion < 2004012800) {
365         modify_database("", "CREATE TABLE prefix_user_preferences (
366                                 id SERIAL PRIMARY KEY,
367                                 userid integer NOT NULL default '0',
368                                 name varchar(50) NOT NULL default '',
369                                 value varchar(255) NOT NULL default ''
370                              ); ");
372         modify_database("", "CREATE INDEX prefix_user_preferences_useridname_idx ON prefix_user_preferences (userid,name);");
373     }
375     if ($oldversion < 2004012900) {
376         table_column("config", "value", "value", "text", "", "", "");
377     }
379     if ($oldversion < 2004013101) {
380         table_column("log", "", "cmid", "integer", "10", "unsigned", "0", "", "module");
381         set_config("upgrade", "logs");
382     }
384     if ($oldversion < 2004020900) {
385         table_column("course", "", "lang", "varchar", "5", "", "", "", "groupmodeforce");
386     }
388     if ($oldversion < 2004020903) {
389         modify_database("", "CREATE TABLE prefix_cache_text (
390                                 id SERIAL PRIMARY KEY,
391                                 md5key varchar(32) NOT NULL default '',
392                                 formattedtext text,
393                                 timemodified integer NOT NULL default '0'
394                              );");
395     }
397     if ($oldversion < 2004021000) {
398         $textfilters = array();
399         for ($i=1; $i<=10; $i++) {
400             $variable = "textfilter$i";
401             if (!empty($CFG->$variable)) {   /// No more filters
402                 if (is_readable("$CFG->dirroot/".$CFG->$variable)) {
403                     $textfilters[] = $CFG->$variable;
404                 }
405             }
406         }
407         $textfilters = implode(',', $textfilters);
408         if (empty($textfilters)) {
409             $textfilters = 'mod/glossary/dynalink.php';
410         }
411         set_config('textfilters', $textfilters);
412     }
414     if ($oldversion < 2004021201) {
415         modify_database("", "CREATE TABLE prefix_cache_filters (
416                                 id SERIAL PRIMARY KEY,
417                                 filter varchar(32) NOT NULL default '',
418                                 version integer NOT NULL default '0',
419                                 md5key varchar(32) NOT NULL default '',
420                                 rawtext text,
421                                 timemodified integer NOT NULL default '0'
422                              );");
424         modify_database("", "CREATE INDEX prefix_cache_filters_filtermd5key_idx ON prefix_cache_filters (filter,md5key);");
425         modify_database("", "CREATE INDEX prefix_cache_text_md5key_idx ON prefix_cache_text (md5key);");
426     }
428     if ($oldversion < 2004021500) {
429         table_column("groups", "", "hidepicture", "integer", "2", "unsigned", "0", "", "picture");
430     }
432     if ($oldversion < 2004021700) {
433         if (!empty($CFG->textfilters)) {
434             $CFG->textfilters = str_replace("tex_filter.php", "filter.php", $CFG->textfilters);
435             $CFG->textfilters = str_replace("multilang.php", "filter.php", $CFG->textfilters);
436             $CFG->textfilters = str_replace("censor.php", "filter.php", $CFG->textfilters);
437             $CFG->textfilters = str_replace("mediaplugin.php", "filter.php", $CFG->textfilters);
438             $CFG->textfilters = str_replace("algebra_filter.php", "filter.php", $CFG->textfilters);
439             $CFG->textfilters = str_replace("dynalink.php", "filter.php", $CFG->textfilters);
440             set_config("textfilters", $CFG->textfilters);
441         }
442     }
444     if ($oldversion < 2004022000) {
445         table_column("user", "", "emailstop", "integer", "1", "unsigned", "0", "not null", "email");
446     }
448     if ($oldversion < 2004022200) {     /// Final renaming I hope.  :-)
449         if (!empty($CFG->textfilters)) {
450             $CFG->textfilters = str_replace("/filter.php", "", $CFG->textfilters);
451             $CFG->textfilters = str_replace("mod/glossary/dynalink.php", "mod/glossary", $CFG->textfilters);
452             $textfilters = explode(',', $CFG->textfilters);
453             foreach ($textfilters as $key => $textfilter) {
454                 $textfilters[$key] = trim($textfilter);
455             }
456             set_config("textfilters", implode(',',$textfilters));
457         }
458     }
460     if ($oldversion < 2004030702) {     /// Because of the renaming of Czech language pack
461         execute_sql("UPDATE {$CFG->prefix}user SET lang = 'cs' WHERE lang = 'cz'");
462         execute_sql("UPDATE {$CFG->prefix}course SET lang = 'cs' WHERE lang = 'cz'");
463     }
465     if ($oldversion < 2004041800) {     /// Integrate Block System from contrib
466         table_column("course", "", "blockinfo", "varchar", "255", "", "", "not null", "modinfo");
467     }
469     if ($oldversion < 2004042600) {     /// Rebuild course caches for resource icons
470         include_once("$CFG->dirroot/course/lib.php");
471         rebuild_course_cache();
472     }
474     if ($oldversion < 2004042700) {     /// Increase size of lang fields
475         table_column("user",   "lang", "lang", "varchar", "10", "", "en");
476         table_column("groups", "lang", "lang", "varchar", "10", "", "");
477         table_column("course", "lang", "lang", "varchar", "10", "", "");
478     }
480     if ($oldversion < 2004042701) {     /// Add hiddentopics field to control hidden topics behaviour
481         #table_column("course", "", "hiddentopics", "integer", "1", "unsigned", "0", "not null", "visible");
482         #See 'hiddensections' further down
483     }
485     if ($oldversion < 2004042702) {     /// Add a format field for the description 
486         table_column("event", "", "format", "integer", "4", "unsigned", "0", "not null", "description");
487     }
489     if ($oldversion < 2004043001) {     /// Add hiddentopics field to control hidden topics behaviour
490         table_column("course", "", "hiddensections", "integer", "2", "unsigned", "0", "not null", "visible");
491     }
492     
493     if ($oldversion < 2004050400) {     /// add a visible field for events
494         table_column("event", "", "visible", "smallint", "1", "", "1", "not null", "timeduration");
495         if ($events = get_records('event')) {
496             foreach($events as $event) {
497                 if ($moduleid = get_field('modules', 'id', 'name', $event->modulename)) {
498                     if (get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $event->instance) == 0) {
499                         set_field('event', 'visible', 0, 'id', $event->id);
500                     }
501                 }
502             }
503         }
504     }
506     if ($oldversion < 2004052800) {     /// First version tagged "1.4 development", version.php 1.227
507         set_config('siteblocksadded', true);   /// This will be used later by the block upgrade
508     }
510     if ($oldversion < 2004053000) {     /// set defaults for site course
511         $site = get_site();
512         set_field('course', 'numsections', 0, 'id', $site->id);
513         set_field('course', 'groupmodeforce', 1, 'id', $site->id);
514         set_field('course', 'teacher', get_string('administrator'), 'id', $site->id);
515         set_field('course', 'teachers', get_string('administrators'), 'id', $site->id);
516         set_field('course', 'student', get_string('user'), 'id', $site->id);
517         set_field('course', 'students', get_string('users'), 'id', $site->id);
518     }
520     if ($oldversion < 2004060100) {
521         set_config('digestmailtime', 0);
522         table_column('user', "", 'maildigest', 'smallint', '1', '', '0', 'not null', 'mailformat');
523     }
525     if ($oldversion < 2004062400) {
526         table_column('user_teachers', "", 'timeend', 'int', '10', 'unsigned', '0', 'not null', 'editall');
527         table_column('user_teachers', "", 'timestart', 'int', '10', 'unsigned', '0', 'not null', 'editall');
528     }
530     if ($oldversion < 2004062401) {
531         table_column('course', '', 'idnumber', 'varchar', '100', '', '', 'not null', 'shortname');
532         execute_sql('UPDATE '.$CFG->prefix.'course SET idnumber = shortname');   // By default
533     }
535     if ($oldversion < 2004062600) {
536         table_column('course', '', 'cost', 'varchar', '10', '', '', 'not null', 'lang');
537     }
539     if ($oldversion < 2004072900) {
540         table_column('course', '', 'enrolperiod', 'int', '10', 'unsigned', '0', 'not null', 'startdate');
541     }
543     if ($oldversion < 2004072901) {  // Fixing error in schema
544         if ($record = get_record('log_display', 'module', 'course', 'action', 'update')) {
545             delete_records('log_display', 'module', 'course', 'action', 'update');
546             insert_record('log_display', $record, false);
547         }
548     }
550     if ($oldversion < 2004081200) {  // Fixing version errors in some blocks
551         set_field('blocks', 'version', 2004081200, 'name', 'admin');
552         set_field('blocks', 'version', 2004081200, 'name', 'calendar_month');
553         set_field('blocks', 'version', 2004081200, 'name', 'course_list');
554     }
556     if ($oldversion < 2004081500) {  // Adding new "auth" field to user table to allow more flexibility
557         table_column('user', '', 'auth', 'varchar', '20', '', 'manual', 'not null', 'id');
559         execute_sql("UPDATE {$CFG->prefix}user SET auth = 'manual'");  // Set everyone to 'manual' to be sure
561         if ($admins = get_admins()) {   // Set all the NON-admins to whatever the current auth module is
562             $adminlist = array();
563             foreach ($admins as $user) {
564                 $adminlist[] = $user->id; 
565             }
566             $adminlist = implode(',', $adminlist);
567             execute_sql("UPDATE {$CFG->prefix}user SET auth = '$CFG->auth' WHERE id NOT IN ($adminlist)");
568         }
569     }
570     
571     if ($oldversion < 2004082600) {
572         //update auth-fields for external users
573         include_once ($CFG->dirroot."/auth/".$CFG->auth."/lib.php");
574         if (function_exists('auth_get_userlist')) {
575             $externalusers = auth_get_userlist();
576             if (!empty($externalusers)){
577                 $externalusers = '\''. implode('\',\'',$externalusers).'\'';
578                 execute_sql("UPDATE {$CFG->prefix}user SET auth = '$CFG->auth' WHERE username  IN ($externalusers)");
579             }
580         }
581     }
582         
583     if ($oldversion < 2004082900) {  // Make sure guest is "manual" too.
584         set_field('user', 'auth', 'manual', 'username', 'guest');
585     }
587     /* Just commenteed unused fields out
588     if ($oldversion < 2004090300) { // Add guid-field used in user syncronization
589             table_column('user', '', 'guid', 'varchar', '128', '', '', '', 'auth');
590             execute_sql("CREATE INDEX {$CFG->prefix}user_auth_guid_idx ON {$CFG->prefix}user (auth, guid)"); 
591     }
592     */
594     if ($oldversion < 2004091900) {  //Modify idnumber to hold longer keys 
595         set_field('user', 'auth', 'manual', 'username', 'guest');
596         table_column('user', 'idnumber', 'idnumber', 'varchar', '64', '', '', '', '');
597         execute_sql("DROP INDEX {$CFG->prefix}user_idnumber_idx ;",false);// added in case of conflicts with upgrade from 14stable
598         execute_sql("DROP INDEX {$CFG->prefix}user_auth_idx ;",false);// added in case of conflicts with upgrade from 14stable
599         execute_sql("CREATE INDEX {$CFG->prefix}user_idnumber_idx ON {$CFG->prefix}user (idnumber)"); 
600         execute_sql("CREATE INDEX {$CFG->prefix}user_auth_idx ON {$CFG->prefix}user (auth)"); 
601     }
603     if ($oldversion < 2004092000) { //redoing this just to be sure that column type is text (postgres type changes didnt work when this was done first time)
604         table_column("config", "value", "value", "text", "", "", "");
605     }
607     if ($oldversion < 2004093001) { // add new table for sessions storage
608         execute_sql(" CREATE TABLE {$CFG->prefix}sessions (
609                           sesskey char(32) PRIMARY KEY,
610                           expiry integer NOT null,
611                           expireref varchar(64),
612                           data text NOT null
613                       );");
615         execute_sql(" CREATE INDEX {$CFG->prefix}sessions_expiry_idx ON {$CFG->prefix}sessions (expiry)");
616     }
618     if ($oldversion < 2004111500) {  // Update any users/courses using wrongly-named lang pack
619         execute_sql("UPDATE {$CFG->prefix}user SET lang = 'mi_nt' WHERE lang = 'ma_nt'");
620         execute_sql("UPDATE {$CFG->prefix}course SET lang = 'mi_nt' WHERE lang = 'ma_nt'");
621     }
623     if ($oldversion < 2004111700) { // add indexes- drop them first silently to avoid conflicts when upgrading.
624         execute_sql("DROP INDEX {$CFG->prefix}course_idnumber_idx;",false);
625         execute_sql("DROP INDEX {$CFG->prefix}course_shortname_idx;",false);
626         execute_sql("DROP INDEX {$CFG->prefix}user_students_userid_idx;",false);
627         execute_sql("DROP INDEX {$CFG->prefix}user_teachers_userid_idx;",false);
629         modify_database("","CREATE INDEX {$CFG->prefix}course_idnumber_idx ON {$CFG->prefix}course (idnumber);" );
630         modify_database("","CREATE INDEX {$CFG->prefix}course_shortname_idx ON {$CFG->prefix}course (shortname);" );
631         modify_database("","CREATE INDEX {$CFG->prefix}user_students_userid_idx ON {$CFG->prefix}user_students (userid);");
632         modify_database("","CREATE INDEX {$CFG->prefix}user_teachers_userid_idx ON {$CFG->prefix}user_teachers (userid);");
633     }
634  
635     if ($oldversion < 2004111700) { // add an index to event for timestart and timeduration- drop them first silently to avoid conflicts when upgrading.
636         execute_sql("DROP INDEX {$CFG->prefix}event_timestart_idx;",false);
637         execute_sql("DROP INDEX {$CFG->prefix}event_timeduration_idx;",false);
639         modify_database('','CREATE INDEX prefix_event_timestart_idx ON prefix_event (timestart);');
640         modify_database('','CREATE INDEX prefix_event_timeduration_idx ON prefix_event (timeduration);');
641     }
643     if ($oldversion < 2004117000) { // add an index on the groups_members table- drop them first silently to avoid conflicts when upgrading.
644         execute_sql("DROP INDEX {$CFG->prefix}groups_members_userid_idx;",false);
646         modify_database('','CREATE INDEX prefix_groups_members_userid_idx ON prefix_groups_members (userid);');
647     }
648     
649     if ($oldversion < 2004111700) { //add indexes on modules and course_modules- drop them first silently to avoid conflicts when upgrading.
650         execute_sql("DROP INDEX {$CFG->prefix}course_modules_visible_idx;",false);
651         execute_sql("DROP INDEX {$CFG->prefix}course_modules_course_idx;",false); 
652         execute_sql("DROP INDEX {$CFG->prefix}course_modules_module_idx;",false); 
653         execute_sql("DROP INDEX {$CFG->prefix}course_modules_instance_idx;",false);
654         execute_sql("DROP INDEX {$CFG->prefix}course_modules_deleted_idx;",false);
655         execute_sql("DROP INDEX {$CFG->prefix}modules_name_idx;",false);
657         modify_database('','CREATE INDEX prefix_course_modules_visible_idx ON prefix_course_modules (visible);');
658         modify_database('','CREATE INDEX prefix_course_modules_course_idx ON prefix_course_modules (course);');
659         modify_database('','CREATE INDEX prefix_course_modules_module_idx ON prefix_course_modules (module);');
660         modify_database('','CREATE INDEX prefix_course_modules_instance_idx ON prefix_course_modules (instance);');
661         modify_database('','CREATE INDEX prefix_course_modules_deleted_idx ON prefix_course_modules (deleted);');
662         modify_database('','CREATE INDEX prefix_modules_name_idx ON prefix_modules (name);');
663     }
664     
665     if ($oldversion < 2004111700) { // add an index on user students timeaccess (used for sorting)- drop them first silently to avoid conflicts when upgrading
666         execute_sql("DROP INDEX {$CFG->prefix}user_students_timeaccess_idx;",false);
668         modify_database('','CREATE INDEX prefix_user_students_timeaccess_idx ON prefix_user_students (timeaccess);');
669     }
670     
671     if ($oldversion < 2004111700) { //add indexes on faux foreign keys  - drop them first silently to avoid conflicts when upgrading.
672         execute_sql("DROP INDEX {$CFG->prefix}course_sections_coursesection_idx;",false);
673         execute_sql("DROP INDEX {$CFG->prefix}scale_courseid_idx;",false); 
674         execute_sql("DROP INDEX {$CFG->prefix}user_admins_userid_idx;",false);
675         execute_sql("DROP INDEX {$CFG->prefix}user_coursecreators_userid_idx;",false); 
677         modify_database('','CREATE INDEX prefix_course_sections_coursesection_idx ON prefix_course_sections (course,section);');
678         modify_database('','CREATE INDEX prefix_scale_courseid_idx ON prefix_scale (courseid);');
679         modify_database('','CREATE INDEX prefix_user_admins_userid_idx ON prefix_user_admins (userid);');
680         modify_database('','CREATE INDEX prefix_user_coursecreators_userid_idx ON prefix_user_coursecreators (userid);');
681     }
682    
683     if ($oldversion < 2004111700) { // make new indexes on user table.
684         fix_course_sortorder(0,0,1);
686         execute_sql("DROP INDEX {$CFG->prefix}course_category_idx;",false);
687         execute_sql("DROP INDEX {$CFG->prefix}course_category_sortorder_uk;",false);
688         modify_database('', "CREATE UNIQUE INDEX prefix_course_category_sortorder_uk ON prefix_course(category,sortorder)"); 
690         execute_sql("DROP INDEX {$CFG->prefix}user_deleted_idx;",false);
691         execute_sql("DROP INDEX {$CFG->prefix}user_confirmed_idx;",false);
692         execute_sql("DROP INDEX {$CFG->prefix}user_firstname_idx;",false);
693         execute_sql("DROP INDEX {$CFG->prefix}user_lastname_idx;",false);
694         execute_sql("DROP INDEX {$CFG->prefix}user_city_idx;",false); 
695         execute_sql("DROP INDEX {$CFG->prefix}user_country_idx;",false); 
696         execute_sql("DROP INDEX {$CFG->prefix}user_lastaccess_idx;",false);
698         modify_database("","CREATE INDEX prefix_user_deleted_idx ON prefix_user (deleted)");
699         modify_database("","CREATE INDEX prefix_user_confirmed_idx ON prefix_user (confirmed)");
700         modify_database("","CREATE INDEX prefix_user_firstname_idx ON prefix_user (firstname)");
701         modify_database("","CREATE INDEX prefix_user_lastname_idx ON prefix_user (lastname)");
702         modify_database("","CREATE INDEX prefix_user_city_idx ON prefix_user (city)");
703         modify_database("","CREATE INDEX prefix_user_country_idx ON prefix_user (country)");
704         modify_database("","CREATE INDEX prefix_user_lastaccess_idx ON prefix_user (lastaccess)");
705     }
707     if ($oldversion < 2004111700) { // one more index for email (for sorting)
708         execute_sql("DROP INDEX {$CFG->prefix}user_email_idx;",false);
710         modify_database('','CREATE INDEX prefix_user_email_idx ON prefix_user (email);');
711      }
713     if ($oldversion < 2004112200) { // new 'enrol' field for enrolment tables
714         table_column('user_students', '', 'enrol', 'varchar', '20', '', '', 'not null');
715         table_column('user_teachers', '', 'enrol', 'varchar', '20', '', '', 'not null');
716         modify_database("","CREATE INDEX {$CFG->prefix}user_students_enrol_idx ON {$CFG->prefix}user_students (enrol);");
717         modify_database("","CREATE INDEX {$CFG->prefix}user_teachers_enrol_idx ON {$CFG->prefix}user_teachers (enrol);");
718     } 
720     if ($oldversion < 2004112300) { // update log display to use correct postgres friendly sql
721         execute_sql("UPDATE {$CFG->prefix}log_display SET field='firstname||\' \'||lastname' WHERE module='user' AND action='view' AND mtable='user'");
722         execute_sql("UPDATE {$CFG->prefix}log_display SET field='firstname||\' \'||lastname' WHERE module='course' AND action='user report' AND mtable='user'");
723     }
725     if ($oldversion < 2004112400) {
727         /// Delete duplicate enrolments 
728         /// and then tell the database course,userid is a unique combination
729         if ($users = get_records_select("user_students", "userid > 0 GROUP BY course, userid ".
730                                         "HAVING count(*) > 1", "", "max(id) as id, userid, course ,count(*)")) {
731             foreach ($users as $user) {
732                 delete_records_select("user_students", "userid = '$user->userid' ".
733                                      "AND course = '$user->course' AND id <> '$user->id'");
734             }
735         }
736         flush();
738         // drop some indexes quietly -- they may or may not exist depending on what version 
739         // the user upgrades from 
740         execute_sql("DROP INDEX {$CFG->prefix}user_students_courseuserid_idx ", false);
741         execute_sql("DROP INDEX {$CFG->prefix}user_students_courseuserid_uk  ", false);        
742         modify_database('','CREATE UNIQUE INDEX prefix_user_students_courseuserid_uk ON prefix_user_students (course,userid);');        
744         /// Delete duplicate teacher enrolments 
745         /// and then tell the database course,userid is a unique combination
746         if ($users = get_records_select("user_teachers", "userid > 0 GROUP BY course, userid ".
747                                         "HAVING count(*) > 1", "", "max(id) as id, userid, course ,count(*)")) {
748             foreach ($users as $user) {
749                 delete_records_select("user_teachers", "userid = '$user->userid' ".
750                                      "AND course = '$user->course' AND id <> '$user->id'");
751             }
752         }
753         flush();
755         // drop some indexes quietly -- they may or may not exist depending on what version 
756         // the user upgrades from 
757         execute_sql("DROP INDEX {$CFG->prefix}user_teachers_courseuserid_idx ", false);
758         execute_sql("DROP INDEX {$CFG->prefix}user_teachers_courseuserid_uk  ", false);
759         modify_database('','CREATE UNIQUE INDEX prefix_user_teachers_courseuserid_uk ON prefix_user_teachers (course,userid);');        
760     } 
761     
762     if ($oldversion < 2004112401) {
763         // some postgres databases may have a non-unique index mislabeled unique.
764         fix_course_sortorder(0,0,1);
765         execute_sql("DROP INDEX {$CFG->prefix}course_category_sortorder_uk  ", false);
766         execute_sql("DROP INDEX {$CFG->prefix}course_category_idx  ", false);
767         modify_database('', "CREATE UNIQUE INDEX prefix_course_category_sortorder_uk ON prefix_course(category,sortorder);");
768         
769         // odd! username was missing its unique index!
770         // first silently drop it just in case...
771         execute_sql("ALTER TABLE {$CFG->prefix}user DROP CONSTRAINT {$CFG->prefix}user_username_uk;", false);   
772         execute_sql("DROP INDEX {$CFG->prefix}user_username_uk", false);
773         modify_database('', "CREATE UNIQUE INDEX prefix_user_username_uk ON prefix_user (username);");
774         
775     } 
777     if ($oldversion < 2004112900) {
778         table_column('user', '', 'policyagreed', 'integer', '1', 'unsigned', '0', 'not null', 'confirmed');
779     }
781     if ($oldversion < 2004121400) {
782         table_column('groups', '', 'password', 'varchar', '50', '', '', 'not null', 'description');
783     }
785     if ($oldversion < 2004121600) {
786         modify_database('',"CREATE TABLE prefix_dst_preset (
787                                 id SERIAL PRIMARY KEY,
788                                 name varchar(48) NOT NULL default '',
789                                 apply_offset integer NOT NULL default '0',
790                                 activate_index integer NOT NULL default '1',
791                                 activate_day integer NOT NULL default '1',
792                                 activate_month integer NOT NULL default '1',
793                                 activate_time char(5) NOT NULL default '03:00',
794                                 deactivate_index integer NOT NULL default '1',
795                                 deactivate_day integer NOT NULL default '1',
796                                 deactivate_month integer NOT NULL default '2',
797                                 deactivate_time char(5) NOT NULL default '03:00',
798                                 last_change integer NOT NULL default '0',
799                                 next_change integer NOT NULL default '0',
800                                 current_offset integer NOT NULL default '0'
801                              );");
802     }
804     if ($oldversion < 2004122800) {
805         execute_sql("DROP TABLE {$CFG->prefix}message", false);
806         execute_sql("DROP TABLE {$CFG->prefix}message_read", false);
807         execute_sql("DROP TABLE {$CFG->prefix}message_contacts", false);
809         execute_sql("DROP INDEX {$CFG->prefix}message_useridfrom_idx", false);
810         execute_sql("DROP INDEX {$CFG->prefix}message_useridto_idx", false);
811         execute_sql("DROP INDEX {$CFG->prefix}message_read_useridfrom_idx", false);
812         execute_sql("DROP INDEX {$CFG->prefix}message_read_useridto_idx", false);
813         execute_sql("DROP INDEX {$CFG->prefix}message_contacts_useridcontactid_idx", false);
815         modify_database('',"CREATE TABLE prefix_message (
816                                id SERIAL PRIMARY KEY,
817                                useridfrom integer NOT NULL default '0',
818                                useridto integer NOT NULL default '0',
819                                message text,
820                                timecreated integer NOT NULL default '0',
821                                messagetype varchar(50) NOT NULL default ''
822                             );
824                             CREATE INDEX prefix_message_useridfrom_idx ON prefix_message (useridfrom);
825                             CREATE INDEX prefix_message_useridto_idx ON prefix_message (useridto);
827                             CREATE TABLE prefix_message_read (
828                                id SERIAL PRIMARY KEY,
829                                useridfrom integer NOT NULL default '0',
830                                useridto integer NOT NULL default '0',
831                                message text,
832                                timecreated integer NOT NULL default '0',
833                                timeread integer NOT NULL default '0',
834                                messagetype varchar(50) NOT NULL default '',
835                                mailed integer NOT NULL default '0'
836                             );
838                             CREATE INDEX prefix_message_read_useridfrom_idx ON prefix_message_read (useridfrom);
839                             CREATE INDEX prefix_message_read_useridto_idx ON prefix_message_read (useridto);
840                             ");
841       
842         modify_database('',"CREATE TABLE prefix_message_contacts (
843                                id SERIAL PRIMARY KEY,
844                                userid integer NOT NULL default '0',
845                                contactid integer NOT NULL default '0',
846                                blocked integer NOT NULL default '0'
847                             );
849                             CREATE INDEX prefix_message_contacts_useridcontactid_idx ON prefix_message_contacts (userid,contactid);
850                             ");
852         modify_database('',"INSERT INTO prefix_log_display VALUES ('message', 'write', 'user', 'firstname||\' \'||lastname');
853                             INSERT INTO prefix_log_display VALUES ('message', 'read', 'user', 'firstname||\' \'||lastname');
854                             ");
855     }
857     if ($oldversion < 2004122801) {
858         table_column('message', '', 'format', 'integer', '4', 'unsigned', '0', 'not null', 'message');
859         table_column('message_read', '', 'format', 'integer', '4', 'unsigned', '0', 'not null', 'message');
860     }
861        
862                                 
863     if ($oldversion < 2005010100) {
864         modify_database('',"INSERT INTO prefix_log_display VALUES ('message', 'add contact', 'user', 'firstname||\' \'||lastname');
865                             INSERT INTO prefix_log_display VALUES ('message', 'remove contact', 'user', 'firstname||\' \'||lastname');
866                             INSERT INTO prefix_log_display VALUES ('message', 'block contact', 'user', 'firstname||\' \'||lastname');
867                             INSERT INTO prefix_log_display VALUES ('message', 'unblock contact', 'user', 'firstname||\' \'||lastname');
868                             ");
869     }
871     if ($oldversion < 2005011000) {     // Create a .htaccess file in dataroot, just in case
872         if (!file_exists($CFG->dataroot.'/.htaccess')) {
873             if ($handle = fopen($CFG->dataroot.'/.htaccess', 'w')) {   // For safety
874                 @fwrite($handle, "deny from all\r\n");
875                 @fclose($handle); 
876                 notify("Created a default .htaccess file in $CFG->dataroot");
877             }
878         }
879     }
881     if ($oldversion < 2005012500) { // add new table for meta courses.
882         /*
883         modify_database("","CREATE TABLE prefix_meta_course (
884                  id SERIAL primary key,
885                  parent_course integer NOT NULL,
886                  child_course integer NOT NULL
887              );");
889         modify_database("","CREATE INDEX prefix_meta_course_parent_idx ON prefix_meta_course (parent_course);");
890         modify_database("","CREATE INDEX prefix_meta_course_child_idx ON prefix_meta_course (child_course);");
891         table_column('course','','meta_course','integer','1','','0','not null');
892         */ // taking this OUT for upgrade from 1.4 to 1.5 (those tracking head will have already seen it)
893     }
895     if ($oldversion < 2005012501) { //fix table names for consistency
896         execute_sql("DROP TABLE {$CFG->prefix}meta_course",false); // drop silently
897         execute_sql("ALTER TABLE {$CFG->prefix}course DROP COLUMN meta_course",false); // drop silently
898         
899         modify_database("","CREATE TABLE prefix_course_meta (
900                  id SERIAL primary key,
901                  parent_course integer NOT NULL,
902                  child_course integer NOT NULL
903              );");
905         modify_database("","CREATE INDEX prefix_course_meta_parent_idx ON prefix_course_meta (parent_course);");
906         modify_database("","CREATE INDEX prefix_course_meta_child_idx ON prefix_course_meta (child_course);");
907         table_column('course','','metacourse','integer','1','','0','not null');
908     }
910     if ($oldversion < 2005020100) {
911         fix_course_sortorder(0, 1, 1);
912     } 
914     if ($oldversion < 2005021000) {     // New fields for theme choices
915         table_column('course', '', 'theme', 'varchar', '50', '', '', '', 'lang');
916         table_column('groups', '', 'theme', 'varchar', '50', '', '', '', 'lang');
917         table_column('user',   '', 'theme', 'varchar', '50', '', '', '', 'lang');
919         set_config('theme', 'standardwhite');         // Reset to a known good theme 
920     }
922     if ($oldversion < 2005021700) {
923         table_column('user', '', 'dstpreset', 'int', '10', '', '0', 'not null', 'timezone');
924     }
926     if ($oldversion < 2005021800) {
927         modify_database("","CREATE TABLE adodb_logsql (
928                               created timestamp NOT NULL,
929                               sql0 varchar(250) NOT NULL,
930                               sql1 text NOT NULL,
931                               params text NOT NULL,
932                               tracer text NOT NULL,
933                               timer decimal(16,6) NOT NULL
934                            );");
935     }
937     if ($oldversion < 2005022400) {
938         table_column('dst_preset', '', 'family', 'varchar', '100', '', '', 'not null', 'name');
939         table_column('dst_preset', '', 'year', 'int', '10', '', '0', 'not null', 'family');
940     }
942     if ($oldversion < 2005030501) {
943         table_column('user', '', 'msn', 'varchar', '50', '', '', '', 'icq');
944         table_column('user', '', 'aim', 'varchar', '50', '', '', '', 'icq');
945         table_column('user', '', 'yahoo', 'varchar', '50', '', '', '', 'icq');
946         table_column('user', '', 'skype', 'varchar', '50', '', '', '', 'icq');
947     }
949     if ($oldversion < 2005032300) {
950         table_column('user', 'dstpreset', 'timezonename', 'varchar', '100');
951         execute_sql('UPDATE '.$CFG->prefix.'user SET timezonename = \'\'');
952     }
955     if ($oldversion < 2005032600) {
956         execute_sql('DROP TABLE '.$CFG->prefix.'dst_preset', false);
957         modify_database('',"CREATE TABLE prefix_timezone (
958                               id SERIAL PRIMARY KEY,
959                               name varchar(100) NOT NULL default '',
960                               year integer NOT NULL default '0',
961                               rule varchar(20) NOT NULL default '',
962                               gmtoff integer NOT NULL default '0',
963                               dstoff integer NOT NULL default '0',
964                               dst_month integer NOT NULL default '0',
965                               dst_startday integer NOT NULL default '0',
966                               dst_weekday integer NOT NULL default '0',
967                               dst_skipweeks integer NOT NULL default '0',
968                               dst_time varchar(5) NOT NULL default '00:00',
969                               std_month integer NOT NULL default '0',
970                               std_startday integer NOT NULL default '0',
971                               std_weekday integer NOT NULL default '0',
972                               std_skipweeks integer NOT NULL default '0',
973                               std_time varchar(5) NOT NULL default '00:00'
974                             );");
975     }
977     if ($oldversion < 2005032800) {
978         modify_database('',"CREATE TABLE prefix_grade_category (
979                               id SERIAL PRIMARY KEY,
980                               name varchar(64) default NULL,
981                               courseid integer NOT NULL default '0',
982                               drop_x_lowest integer NOT NULL default '0',
983                               bonus_points integer NOT NULL default '0',
984                               hidden integer NOT NULL default '0',
985                               weight decimal(4,2) default '0.00'
986                             );");
987         
988         modify_database('',"CREATE INDEX prefix_grade_category_courseid_idx ON prefix_grade_category (courseid);");
989         
990         modify_database('',"CREATE TABLE prefix_grade_exceptions (
991                               id SERIAL PRIMARY KEY,
992                               courseid integer  NOT NULL default '0',
993                               grade_itemid integer  NOT NULL default '0',
994                               userid integer  NOT NULL default '0'
995                             );");
996         
997         modify_database('',"CREATE INDEX prefix_grade_exceptions_courseid_idx ON prefix_grade_exceptions (courseid);");
998         
999         
1000         modify_database('',"CREATE TABLE prefix_grade_item (
1001                               id SERIAL PRIMARY KEY,
1002                               courseid integer default NULL,
1003                               category integer default NULL,
1004                               modid integer default NULL,
1005                               cminstance integer default NULL,
1006                               scale_grade float(11) default '1.0000000000',
1007                               extra_credit integer NOT NULL default '0',
1008                               sort_order integer  NOT NULL default '0'
1009                             );");
1010         
1011         modify_database('',"CREATE INDEX prefix_grade_item_courseid_idx ON prefix_grade_item (courseid);");
1012         
1013         modify_database('',"CREATE TABLE prefix_grade_letter (
1014                               id SERIAL PRIMARY KEY,
1015                               courseid integer NOT NULL default '0',
1016                               letter varchar(8) NOT NULL default 'NA',
1017                               grade_high decimal(6,2) NOT NULL default '100.00',
1018                               grade_low decimal(6,2) NOT NULL default '0.00'
1019                             );");
1021         modify_database('',"CREATE INDEX prefix_grade_letter_courseid_idx ON prefix_grade_letter (courseid);");
1022         
1023         modify_database('',"CREATE TABLE prefix_grade_preferences (
1024                               id SERIAL PRIMARY KEY,
1025                               courseid integer default NULL,
1026                               preference integer NOT NULL default '0',
1027                               value integer NOT NULL default '0'
1028                             );");
1029         
1030         modify_database('',"CREATE UNIQUE INDEX prefix_grade_prefs_courseidpref_uk ON prefix_grade_preferences (courseid,preference);");
1031     }
1033     if ($oldversion < 2005033100) {   // Get rid of defunct field from course modules table
1034          delete_records('course_modules', 'deleted', 1);  // Delete old records we don't need any more
1035          execute_sql('DROP INDEX '.$CFG->prefix.'course_modules_deleted_idx;');  // Old index
1036          execute_sql('ALTER TABLE '.$CFG->prefix.'course_modules DROP deleted;');    // Old field
1037     }
1039     if ($oldversion < 2005040800) {
1040         table_column('user', 'timezone', 'timezone', 'varchar', '100', '', '99');
1041         execute_sql(" ALTER TABLE {$CFG->prefix}user DROP timezonename ");
1042     }
1044     if ($oldversion < 2005041101) {
1045         require_once($CFG->libdir.'/filelib.php');
1046         if (is_readable($CFG->dirroot.'/lib/timezones.txt')) {  // Distribution file
1047             if ($timezones = get_records_csv($CFG->dirroot.'/lib/timezones.txt', 'timezone')) {
1048                 $db->debug = false;
1049                 update_timezone_records($timezones);
1050                 notify(count($timezones).' timezones installed');
1051                 $db->debug = true;
1052             }
1053         }
1054     }
1056     if ($oldversion < 2005041900) {  // Copy all Dialogue entries into Messages, and hide Dialogue module
1058         if ($entries = get_records_sql('SELECT e.id, e.userid, c.recipientid, e.text, e.timecreated
1059                                           FROM '.$CFG->prefix.'dialogue_conversations c,
1060                                                '.$CFG->prefix.'dialogue_entries e
1061                                          WHERE e.conversationid = c.id')) {
1062             foreach ($entries as $entry) {
1063                 $message = NULL;
1064                 $message->useridfrom    = $entry->userid;
1065                 $message->useridto      = $entry->recipientid;
1066                 $message->message       = addslashes($entry->text);
1067                 $message->format        = FORMAT_HTML;
1068                 $message->timecreated   = $entry->timecreated;
1069                 $message->messagetype   = 'direct';
1070             
1071                 insert_record('message_read', $message);
1072             }
1073         }
1075         set_field('modules', 'visible', 0, 'name', 'dialogue');
1077         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');
1079     }
1081     if ($oldversion < 2005042100) {
1082         $result = table_column('event', '', 'repeatid', 'int', '10', 'unsigned', '0', 'not null', 'userid') && $result;
1083     }
1085     if ($oldversion < 2005042400) {  // Add user tracking prefs field.
1086         table_column('user', '', 'trackforums', 'int', '4', 'unsigned', '0', 'not null', 'autosubscribe');
1087     }
1089     if ($oldversion < 2005051500) {  // Add user tracking prefs field.
1090         table_column('grade_category', 'weight', 'weight', 'numeric(5,2)', '', '', '0.00', '', '');
1091     }
1093     if ($oldversion < 2005053000 ) { // Add config_plugins table
1094         
1095         // this table was created on the MOODLE_15_STABLE branch
1096         // so it may already exist. Therefore we hide potential errors
1097         // (Postgres doesn't support CREATE TABLE IF NOT EXISTS)
1098         execute_sql("CREATE TABLE {$CFG->prefix}config_plugins (
1099                         id     SERIAL PRIMARY KEY,
1100                         plugin varchar(100) NOT NULL default 'core',
1101                         name   varchar(100) NOT NULL default '',
1102                         value  text NOT NULL default '',
1103                         CONSTRAINT {$CFG->prefix}config_plugins_plugin_name_uk UNIQUE (plugin, name)
1104                      );", false);
1106     }
1108     if ($oldversion < 2005060200) {  // migrate some config items to config_plugins table
1110         // NOTE: this block is in both postgres AND mysql upgrade
1111         // files. If you edit either, update the otherone. 
1112         $user_fields = array("firstname", "lastname", "email", 
1113                              "phone1", "phone2", "department", 
1114                              "address", "city", "country", 
1115                              "description", "idnumber", "lang");
1116         if (!empty($CFG->auth)) { // if we have no auth, just pass
1117             foreach ($user_fields as $field) {
1118                 $suffixes = array('', '_editlock', '_updateremote', '_updatelocal');
1119                 foreach ($suffixes as $suffix) {
1120                     $key = 'auth_user_' . $field . $suffix;
1121                     if (isset($CFG->$key)) {
1122                         
1123                         // translate keys & values
1124                         // to the new convention
1125                         // this should support upgrading 
1126                         // even 1.5dev installs
1127                         $newkey = $key;
1128                         $newval = $CFG->$key;
1129                         if ($suffix === '') {
1130                             $newkey = 'field_map_' . $field;
1131                         } elseif ($suffix === '_editlock') {
1132                             $newkey = 'field_lock_' . $field;
1133                             $newval = ($newval==1) ? 'locked' : 'unlocked'; // translate 0/1 to locked/unlocked
1134                         } elseif ($suffix === '_updateremote') {
1135                             $newkey = 'field_updateremote_' . $field;                            
1136                         } elseif ($suffix === '_updatelocal') {
1137                             $newkey = 'field_updatelocal_' . $field;
1138                             $newval = ($newval==1) ? 'onlogin' : 'oncreate'; // translate 0/1 to locked/unlocked
1139                         }
1141                         if (!(set_config($newkey, addslashes($newval), 'auth/'.$CFG->auth)
1142                             && delete_records('config', 'name', $key))) {
1143                             notify("Error updating Auth configuration $key to {$CFG->auth} $newkey .");
1144                             $result = false;
1145                         }
1146                     } // end if isset key
1147                 } // end foreach suffix
1148             } // end foreach field
1149         }
1150     }
1152     if ($oldversion < 2005060201) {  // Close down the Attendance module, we are removing it from CVS.
1153         if (!file_exists($CFG->dirroot.'/mod/attendance/lib.php')) {
1154             if (count_records('attendance')) {   // We have some data, so should keep it
1156                 set_field('modules', 'visible', 0, 'name', 'attendance');
1157                 notify('The Attendance module has been discontinued.  If you really want to 
1158                         continue using it, you should download it individually from 
1159                         http://download.moodle.org/modules and install it, then 
1160                         reactivate it from Admin >> Configuration >> Modules.  
1161                         None of your existing data has been deleted, so all existing 
1162                         Attendance activities should re-appear.');
1164             } else {  // No data, so do a complete delete
1166                 execute_sql('DROP TABLE '.$CFG->prefix.'attendance', false);
1167                 delete_records('modules', 'name', 'attendance');
1168                 notify("The Attendance module has been discontinued and removed from your site.  
1169                         You weren't using it anyway.  ;-)");
1170             }
1171         }
1172     }
1174     if ($oldversion < 2005060223) { // Mass cleanup of bad postgres upgrade scripts
1175         execute_sql("DROP TABLE {$CFG->prefix}attendance_roll", false); // There are no attendance module anymore
1176         modify_database('','ALTER TABLE prefix_config ALTER value SET NOT NULL');
1177         modify_database('','ALTER TABLE prefix_course ALTER metacourse SET NOT NULL');
1178         modify_database('','ALTER TABLE prefix_course ALTER theme SET NOT NULL');
1179         modify_database('','ALTER TABLE prefix_event ALTER repeatid SET NOT NULL');
1180         modify_database('','ALTER TABLE prefix_groups ALTER password SET NOT NULL');
1181         modify_database('','ALTER TABLE prefix_groups ALTER theme SET NOT NULL');
1182         modify_database('','ALTER TABLE prefix_message ALTER format SET NOT NULL');
1183         modify_database('','ALTER TABLE prefix_message_read ALTER format SET NOT NULL');
1184         modify_database('','ALTER TABLE prefix_groups ALTER theme SET NOT NULL');
1185         modify_database('','ALTER TABLE prefix_user ALTER aim DROP DEFAULT');
1186         modify_database('','ALTER TABLE prefix_user ALTER idnumber DROP DEFAULT');
1187         modify_database('','ALTER TABLE prefix_user ALTER msn DROP DEFAULT');
1188         modify_database('','ALTER TABLE prefix_user ALTER policyagreed SET NOT NULL');
1189         modify_database('','ALTER TABLE prefix_user ALTER skype DROP DEFAULT');
1190         modify_database('','ALTER TABLE prefix_user ALTER theme SET NOT NULL');
1191         modify_database('','ALTER TABLE prefix_user ALTER timezone SET NOT NULL');
1192         modify_database('','ALTER TABLE prefix_user ALTER trackforums SET NOT NULL');
1193         modify_database('','ALTER TABLE prefix_user ALTER yahoo DROP DEFAULT');
1194         modify_database('','ALTER TABLE prefix_user_students ALTER enrol SET NOT NULL');
1195         modify_database('','ALTER TABLE prefix_user_teachers ALTER enrol SET NOT NULL');
1196     }
1198     if ($oldversion < 2005071700) {  // Close down the Dialogue module, we are removing it from CVS.
1199         if (!file_exists($CFG->dirroot.'/mod/dialogue/lib.php')) {
1200             if (count_records('dialogue')) {   // We have some data, so should keep it
1202                 set_field('modules', 'visible', 0, 'name', 'dialogue');
1203                 notify('The Dialogue module has been discontinued.  If you really want to 
1204                         continue using it, you should download it individually from 
1205                         http://download.moodle.org/modules and install it, then 
1206                         reactivate it from Admin >> Configuration >> Modules.  
1207                         None of your existing data has been deleted, so all existing 
1208                         Dialogue activities should re-appear.');
1210             } else {  // No data, so do a complete delete
1212                 execute_sql('DROP TABLE '.$CFG->prefix.'dialogue', false);
1213                 delete_records('modules', 'name', 'dialogue');
1214                 notify("The Dialogue module has been discontinued and removed from your site.  
1215                         You weren't using it anyway.  ;-)");
1216             }
1217         }
1218     }
1220     if ($oldversion < 2005072000) {  // Add a couple fields to mdl_event to work towards iCal import/export
1221         table_column('event', '', 'uuid', 'char', '36', '', '', 'not null', 'visible');
1222         table_column('event', '', 'sequence', 'integer', '10', 'unsigned', '1', 'not null', 'uuid');
1223     }
1224     
1225     if ($oldversion < 2005072100) { // run the online assignment cleanup code
1226         include($CFG->dirroot.'/'.$CFG->admin.'/oacleanup.php');
1227         if (function_exists('online_assignment_cleanup')) {
1228             online_assignment_cleanup();
1229         }
1230     }
1232     if ($oldversion < 2005072200) { // fix the mistakenly-added currency stuff from enrol/authorize
1233         execute_sql("DROP TABLE {$CFG->prefix}currencies", false); // drop silently
1234         execute_sql("ALTER TABLE {$CFG->prefix}course DROP currency", false);
1235         $defaultcurrency = empty($CFG->enrol_currency) ? 'USD' : $CFG->enrol_currency;
1236         table_column('course', '', 'currency', 'char', '3', '', $defaultcurrency, 'not null', 'cost');
1237     }
1239     if ($oldversion < 2005081600) { //set up the course requests table
1240         modify_database('',"CREATE TABLE prefix_course_request (
1241            id SERIAL PRIMARY KEY,
1242            fullname varchar(254) NOT NULL default '',
1243            shortname varchar(15) NOT NULL default '',
1244            summary text NOT NULL default '',
1245            reason text NOT NULL default '',
1246            requester INTEGER NOT NULL default 0
1247          );");
1248         
1249         modify_database('','CREATE INDEX prefix_course_request_shortname_idx ON prefix_course_request (shortname);');
1251         table_column('course','','requested');
1252     }
1254     if ($oldversion < 2005081601) {
1255         modify_database('','CREATE TABLE prefix_course_allowed_modules (
1256             id SERIAL PRIMARY KEY,
1257             course INTEGER NOT NULL default 0,
1258             module INTEGER NOT NULL default 0
1259          );');
1260          
1261         modify_database('','CREATE INDEX prefix_course_allowed_modules_course_idx ON prefix_course_allowed_modules (course);');
1262         modify_database('','CREATE INDEX prefix_course_allowed_modules_module_idx ON prefix_course_allowed_modules (module);');
1263         table_column('course','','restrictmodules','int','1','','0','not null');
1264     }
1265     
1266     if ($oldversion < 2005081700) {
1267         table_column('course_categories','','depth','integer');
1268         table_column('course_categories','','path','varchar','255');
1269     }
1271     if  ($oldversion < 2005090100) { // stats!
1272         modify_database('','CREATE TABLE prefix_stats_daily (
1273            id SERIAL PRIMARY KEY,
1274            courseid INTEGER NOT NULL default 0,
1275            timeend INTEGER NOT NULL default 0,
1276            students INTEGER NOT NULL default 0,
1277            teachers INTEGER NOT NULL default 0,
1278            activestudents INTEGER NOT NULL default 0,
1279            activeteachers INTEGER NOT NULL default 0,
1280            studentreads INTEGER NOT NULL default 0,
1281            studentwrites INTEGER NOT NULL default 0,
1282            teacherreads INTEGER NOT NULL default 0,
1283            teacherwrites INTEGER NOT NULL default 0,
1284            logins INTEGER NOT NULL default 0,
1285            uniquelogins INTEGER NOT NULL default 0
1286         );');
1288         modify_database('','CREATE INDEX prefix_stats_daily_courseid_idx ON prefix_stats_daily (courseid);');
1289         modify_database('','CREATE INDEX prefix_stats_daily_timeend_idx ON prefix_stats_daily (timeend);');
1290         
1291         modify_database('','CREATE TABLE prefix_stats_weekly (
1292            id SERIAL PRIMARY KEY,
1293            courseid INTEGER NOT NULL default 0,
1294            timeend INTEGER NOT NULL default 0,
1295            students INTEGER NOT NULL default 0,
1296            teachers INTEGER NOT NULL default 0,
1297            activestudents INTEGER NOT NULL default 0,
1298            activeteachers INTEGER NOT NULL default 0,
1299            studentreads INTEGER NOT NULL default 0,
1300            studentwrites INTEGER NOT NULL default 0,
1301            teacherreads INTEGER NOT NULL default 0,
1302            teacherwrites INTEGER NOT NULL default 0,
1303            logins INTEGER NOT NULL default 0,
1304            uniquelogins INTEGER NOT NULL default 0
1305         );');
1307         modify_database('','CREATE INDEX prefix_stats_weekly_courseid_idx ON prefix_stats_weekly (courseid);');
1308         modify_database('','CREATE INDEX prefix_stats_weekly_timeend_idx ON prefix_stats_weekly (timeend);');
1310         modify_database('','CREATE TABLE prefix_stats_monthly (
1311            id SERIAL PRIMARY KEY,
1312            courseid INTEGER NOT NULL default 0,
1313            timeend INTEGER NOT NULL default 0,
1314            students INTEGER NOT NULL default 0,
1315            teachers INTEGER NOT NULL default 0,
1316            activestudents INTEGER NOT NULL default 0,
1317            activeteachers INTEGER NOT NULL default 0,
1318            studentreads INTEGER NOT NULL default 0,
1319            studentwrites INTEGER NOT NULL default 0,
1320            teacherreads INTEGER NOT NULL default 0,
1321            teacherwrites INTEGER NOT NULL default 0,
1322            logins INTEGER NOT NULL default 0,
1323            uniquelogins INTEGER NOT NULL default 0
1324         );');
1326         modify_database('','CREATE INDEX prefix_stats_monthly_courseid_idx ON prefix_stats_monthly (courseid);');
1327         modify_database('','CREATE INDEX prefix_stats_monthly_timeend_idx ON prefix_stats_monthly (timeend);');
1328         
1329         modify_database("","CREATE TABLE prefix_stats_user_daily (
1330            id SERIAL PRIMARY KEY,
1331            courseid INTEGER NOT NULL default 0,
1332            userid INTEGER NOT NULL default 0,
1333            roleid INTEGER NOT NULL default 0,
1334            timeend INTEGER NOT NULL default 0,
1335            reads INTEGER NOT NULL default 0,
1336            writes INTEGER NOT NULL default 0,
1337            stattype varchar(30) NOT NULL default ''
1338          );");
1339          
1340          modify_database("","CREATE INDEX prefix_stats_user_daily_courseid_idx ON prefix_stats_user_daily (courseid);");
1341          modify_database("","CREATE INDEX prefix_stats_user_daily_userid_idx ON prefix_stats_user_daily (userid);");
1342          modify_database("","CREATE INDEX prefix_stats_user_daily_roleid_idx ON prefix_stats_user_daily (roleid);");
1343          modify_database("","CREATE INDEX prefix_stats_user_daily_timeend_idx ON prefix_stats_user_daily (timeend);");
1345          modify_database("","CREATE TABLE prefix_stats_user_weekly (
1346            id SERIAL PRIMARY KEY,
1347            courseid INTEGER NOT NULL default 0,
1348            userid INTEGER NOT NULL default 0,
1349            roleid INTEGER NOT NULL default 0,
1350            timeend INTEGER NOT NULL default 0,
1351            reads INTEGER NOT NULL default 0,
1352            writes INTEGER NOT NULL default 0,
1353            stattype varchar(30) NOT NULL default ''
1354          );");
1355          
1356          modify_database("","CREATE INDEX prefix_stats_user_weekly_courseid_idx ON prefix_stats_user_weekly (courseid);");
1357          modify_database("","CREATE INDEX prefix_stats_user_weekly_userid_idx ON prefix_stats_user_weekly (userid);");
1358          modify_database("","CREATE INDEX prefix_stats_user_weekly_roleid_idx ON prefix_stats_user_weekly (roleid);");
1359          modify_database("","CREATE INDEX prefix_stats_user_weekly_timeend_idx ON prefix_stats_user_weekly (timeend);");
1361          modify_database("","CREATE TABLE prefix_stats_user_monthly (
1362            id SERIAL PRIMARY KEY,
1363            courseid INTEGER NOT NULL default 0,
1364            userid INTEGER NOT NULL default 0,
1365            roleid INTEGER NOT NULL default 0,
1366            timeend INTEGER NOT NULL default 0,
1367            reads INTEGER NOT NULL default 0,
1368            writes INTEGER NOT NULL default 0,
1369            stattype varchar(30) NOT NULL default ''
1370          );");
1371          
1372          modify_database("","CREATE INDEX prefix_stats_user_monthly_courseid_idx ON prefix_stats_user_monthly (courseid);");
1373          modify_database("","CREATE INDEX prefix_stats_user_monthly_userid_idx ON prefix_stats_user_monthly (userid);");
1374          modify_database("","CREATE INDEX prefix_stats_user_monthly_roleid_idx ON prefix_stats_user_monthly (roleid);");
1375          modify_database("","CREATE INDEX prefix_stats_user_monthly_timeend_idx ON prefix_stats_user_monthly (timeend);");
1376     }
1377     
1378     if ($oldversion < 2005100300) {
1379         table_column('course','','expirynotify','integer','1');
1380         table_column('course','','expirythreshold','integer');
1381         table_column('course','','notifystudents','integer','1');
1382         $new = new stdClass();
1383         $new->name = 'lastexpirynotify';
1384         $new->value = 0;
1385         insert_record('config', $new);
1386     }
1388     if ($oldversion < 2005100400) {
1389         table_column('course','','enrollable','integer','1','unsigned','1');
1390         table_column('course','','enrolstartdate','integer');
1391         table_column('course','','enrolenddate','integer');
1392     }
1395     if ($oldversion < 2005101200) { // add enrolment key to course_request.
1396         table_column('course_request','','password','text');
1397     }
1399     if ($oldversion < 2006030800) { # add extra indexes to log (see bug #4112)
1400         modify_database('',"CREATE INDEX prefix_log_userid_idx ON prefix_log (userid);");
1401         modify_database('',"CREATE INDEX prefix_log_info_idx ON prefix_log (info);");
1402     }
1404     if ($oldversion < 2006030900) {
1405         table_column('course','','enrol','varchar','20','','');
1407         if ($CFG->enrol == 'internal' || $CFG->enrol == 'manual') {
1408             set_config('enrol_plugins_enabled', 'manual');
1409             set_config('enrol', 'manual');
1410         } else {
1411             set_config('enrol_plugins_enabled', 'manual,'.$CFG->enrol);
1412         }
1414         require_once("$CFG->dirroot/enrol/enrol.class.php");
1415         $defaultenrol = enrolment_factory::factory($CFG->enrol);
1416         if (!method_exists($defaultenrol, 'print_entry')) { // switch enrollable to off for all courses in this case
1417             modify_database('', 'UPDATE prefix_course SET enrollable = 0');
1418         }
1420         execute_sql("UPDATE {$CFG->prefix}user_students SET enrol='manual' WHERE enrol='' OR enrol='internal'");
1421         execute_sql("UPDATE {$CFG->prefix}user_teachers SET enrol='manual' WHERE enrol=''");
1423     }
1425     return $result;
1428 ?>