Merge branch 'MDL-46182' of https://github.com/NeillM/moodle
[moodle.git] / lib / db / upgrade.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * This file keeps track of upgrades to Moodle.
19  *
20  * Sometimes, changes between versions involve
21  * alterations to database structures and other
22  * major things that may break installations.
23  *
24  * The upgrade function in this file will attempt
25  * to perform all the necessary actions to upgrade
26  * your older installation to the current version.
27  *
28  * If there's something it cannot do itself, it
29  * will tell you what you need to do.
30  *
31  * The commands in here will all be database-neutral,
32  * using the methods of database_manager class
33  *
34  * Please do not forget to use upgrade_set_timeout()
35  * before any action that may take longer time to finish.
36  *
37  * @package   core_install
38  * @category  upgrade
39  * @copyright 2006 onwards Martin Dougiamas  http://dougiamas.com
40  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
43 defined('MOODLE_INTERNAL') || die();
45 /**
46  * Main upgrade tasks to be executed on Moodle version bump
47  *
48  * This function is automatically executed after one bump in the Moodle core
49  * version is detected. It's in charge of performing the required tasks
50  * to raise core from the previous version to the next one.
51  *
52  * It's a collection of ordered blocks of code, named "upgrade steps",
53  * each one performing one isolated (from the rest of steps) task. Usually
54  * tasks involve creating new DB objects or performing manipulation of the
55  * information for cleanup/fixup purposes.
56  *
57  * Each upgrade step has a fixed structure, that can be summarised as follows:
58  *
59  * if ($oldversion < XXXXXXXXXX.XX) {
60  *     // Explanation of the update step, linking to issue in the Tracker if necessary
61  *     upgrade_set_timeout(XX); // Optional for big tasks
62  *     // Code to execute goes here, usually the XMLDB Editor will
63  *     // help you here. See {@link http://docs.moodle.org/dev/XMLDB_editor}.
64  *     upgrade_main_savepoint(true, XXXXXXXXXX.XX);
65  * }
66  *
67  * All plugins within Moodle (modules, blocks, reports...) support the existence of
68  * their own upgrade.php file, using the "Frankenstyle" component name as
69  * defined at {@link http://docs.moodle.org/dev/Frankenstyle}, for example:
70  *     - {@link xmldb_page_upgrade($oldversion)}. (modules don't require the plugintype ("mod_") to be used.
71  *     - {@link xmldb_auth_manual_upgrade($oldversion)}.
72  *     - {@link xmldb_workshopform_accumulative_upgrade($oldversion)}.
73  *     - ....
74  *
75  * In order to keep the contents of this file reduced, it's allowed to create some helper
76  * functions to be used here in the {@link upgradelib.php} file at the same directory. Note
77  * that such a file must be manually included from upgrade.php, and there are some restrictions
78  * about what can be used within it.
79  *
80  * For more information, take a look to the documentation available:
81  *     - Data definition API: {@link http://docs.moodle.org/dev/Data_definition_API}
82  *     - Upgrade API: {@link http://docs.moodle.org/dev/Upgrade_API}
83  *
84  * @param int $oldversion
85  * @return bool always true
86  */
87 function xmldb_main_upgrade($oldversion) {
88     global $CFG, $USER, $DB, $OUTPUT, $SITE, $COURSE;
90     require_once($CFG->libdir.'/db/upgradelib.php'); // Core Upgrade-related functions
92     $dbman = $DB->get_manager(); // loads ddl manager and xmldb classes
94     if ($oldversion < 2011120500) {
95         // just in case somebody hacks upgrade scripts or env, we really can not continue
96         echo("You need to upgrade to 2.2.x first!\n");
97         exit(1);
98         // Note this savepoint is 100% unreachable, but needed to pass the upgrade checks
99         upgrade_main_savepoint(true, 2011120500);
100     }
102     // Moodle v2.2.0 release upgrade line
103     // Put any upgrade step following this
105     if ($oldversion < 2011120500.02) {
107         upgrade_set_timeout(60*20); // This may take a while
108         // MDL-28180. Some missing restrictions in certain backup & restore operations
109         // were causing incorrect duplicates in the course_completion_aggr_methd table.
110         // This upgrade step takes rid of them.
111         $sql = 'SELECT course, criteriatype, MIN(id) AS minid
112                   FROM {course_completion_aggr_methd}
113               GROUP BY course, criteriatype
114                 HAVING COUNT(*) > 1';
115         $duprs = $DB->get_recordset_sql($sql);
116         foreach ($duprs as $duprec) {
117             // We need to handle NULLs in criteriatype diferently
118             if (is_null($duprec->criteriatype)) {
119                 $where = 'course = ? AND criteriatype IS NULL AND id > ?';
120                 $params = array($duprec->course, $duprec->minid);
121             } else {
122                 $where = 'course = ? AND criteriatype = ? AND id > ?';
123                 $params = array($duprec->course, $duprec->criteriatype, $duprec->minid);
124             }
125             $DB->delete_records_select('course_completion_aggr_methd', $where, $params);
126         }
127         $duprs->close();
129         // Main savepoint reached
130         upgrade_main_savepoint(true, 2011120500.02);
131     }
133     if ($oldversion < 2011120500.03) {
135         // Changing precision of field value on table user_preferences to (1333)
136         $table = new xmldb_table('user_preferences');
137         $field = new xmldb_field('value', XMLDB_TYPE_CHAR, '1333', null, XMLDB_NOTNULL, null, null, 'name');
139         // Launch change of precision for field value
140         $dbman->change_field_precision($table, $field);
142         // Main savepoint reached
143         upgrade_main_savepoint(true, 2011120500.03);
144     }
146     if ($oldversion < 2012020200.03) {
148         // Define index rolecontext (not unique) to be added to role_assignments
149         $table = new xmldb_table('role_assignments');
150         $index = new xmldb_index('rolecontext', XMLDB_INDEX_NOTUNIQUE, array('roleid', 'contextid'));
152         // Conditionally launch add index rolecontext
153         if (!$dbman->index_exists($table, $index)) {
154             $dbman->add_index($table, $index);
155         }
157         // Define index usercontextrole (not unique) to be added to role_assignments
158         $index = new xmldb_index('usercontextrole', XMLDB_INDEX_NOTUNIQUE, array('userid', 'contextid', 'roleid'));
160         // Conditionally launch add index usercontextrole
161         if (!$dbman->index_exists($table, $index)) {
162             $dbman->add_index($table, $index);
163         }
165         // Main savepoint reached
166         upgrade_main_savepoint(true, 2012020200.03);
167     }
169     if ($oldversion < 2012020200.06) {
170         // Previously we always allowed users to override their email address via the messaging system
171         // We have now added a setting to allow admins to turn this this ability on and off
172         // While this setting defaults to 0 (off) we're setting it to 1 (on) to maintain the behaviour for upgrading sites
173         set_config('messagingallowemailoverride', 1);
175         // Main savepoint reached
176         upgrade_main_savepoint(true, 2012020200.06);
177     }
179     if ($oldversion < 2012021700.01) {
180         // Changing precision of field uniquehash on table post to 255
181         $table = new xmldb_table('post');
182         $field = new xmldb_field('uniquehash', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'content');
184         // Launch change of precision for field uniquehash
185         $dbman->change_field_precision($table, $field);
187         // Main savepoint reached
188         upgrade_main_savepoint(true, 2012021700.01);
189     }
191     if ($oldversion < 2012021700.02) {
192         // Somewhere before 1.9 summary and content column in post table were not null. In 1.9+
193         // not null became false.
194         $columns = $DB->get_columns('post');
196         // Fix discrepancies in summary field after upgrade from 1.9
197         if (array_key_exists('summary', $columns) && $columns['summary']->not_null != false) {
198             $table = new xmldb_table('post');
199             $summaryfield = new xmldb_field('summary', XMLDB_TYPE_TEXT, 'big', null, null, null, null, 'subject');
201             if ($dbman->field_exists($table, $summaryfield)) {
202                 $dbman->change_field_notnull($table, $summaryfield);
203             }
205         }
207         // Fix discrepancies in content field after upgrade from 1.9
208         if (array_key_exists('content', $columns) && $columns['content']->not_null != false) {
209             $table = new xmldb_table('post');
210             $contentfield = new xmldb_field('content', XMLDB_TYPE_TEXT, 'big', null, null, null, null, 'summary');
212             if ($dbman->field_exists($table, $contentfield)) {
213                 $dbman->change_field_notnull($table, $contentfield);
214             }
216         }
218         upgrade_main_savepoint(true, 2012021700.02);
219     }
221     // The ability to backup user (private) files is out completely - MDL-29248
222     if ($oldversion < 2012030100.01) {
223         unset_config('backup_general_user_files', 'backup');
224         unset_config('backup_general_user_files_locked', 'backup');
225         unset_config('backup_auto_user_files', 'backup');
227         upgrade_main_savepoint(true, 2012030100.01);
228     }
230     if ($oldversion < 2012030900.01) {
231         // Migrate all numbers to signed & all texts and binaries to big size.
232         // It should be safe to interrupt this and continue later.
233         upgrade_mysql_fix_unsigned_and_lob_columns();
235         // Main savepoint reached
236         upgrade_main_savepoint(true, 2012030900.01);
237     }
239     if ($oldversion < 2012031500.01) {
240         // Upgrade old course_allowed_modules data to be permission overrides.
241         if ($CFG->restrictmodulesfor === 'all') {
242             $courses = $DB->get_records_menu('course', array(), 'id', 'id, 1');
243         } else if ($CFG->restrictmodulesfor === 'requested') {
244             $courses = $DB->get_records_menu('course', array('restrictmodules' => 1), 'id', 'id, 1');
245         } else {
246             $courses = array();
247         }
249         if (!$dbman->table_exists('course_allowed_modules')) {
250             // Upgrade must already have been run on this server. This might happen,
251             // for example, during development of these changes.
252             $courses = array();
253         }
255         $modidtoname = $DB->get_records_menu('modules', array(), 'id', 'id, name');
257         $coursecount = count($courses);
258         if ($coursecount) {
259             $pbar = new progress_bar('allowedmods', 500, true);
260             $transaction = $DB->start_delegated_transaction();
261         }
263         $i = 0;
264         foreach ($courses as $courseid => $notused) {
265             $i += 1;
266             upgrade_set_timeout(60); // 1 minute per course should be fine.
268             $allowedmoduleids = $DB->get_records_menu('course_allowed_modules',
269             array('course' => $courseid), 'module', 'module, 1');
270             if (empty($allowedmoduleids)) {
271                 // This seems to be the best match for backwards compatibility,
272                 // not necessarily with the old code in course_allowed_module function,
273                 // but with the code that used to be in the coures settings form.
274                 $allowedmoduleids = explode(',', $CFG->defaultallowedmodules);
275                 $allowedmoduleids = array_combine($allowedmoduleids, $allowedmoduleids);
276             }
278             $context = context_course::instance($courseid);
280             list($roleids) = get_roles_with_cap_in_context($context, 'moodle/course:manageactivities');
281             list($managerroleids) = get_roles_with_cap_in_context($context, 'moodle/site:config');
282             foreach ($managerroleids as $roleid) {
283                 unset($roleids[$roleid]);
284             }
286             foreach ($modidtoname as $modid => $modname) {
287                 if (isset($allowedmoduleids[$modid])) {
288                     // Module is allowed, no worries.
289                     continue;
290                 }
292                 $capability = 'mod/' . $modname . ':addinstance';
293                 foreach ($roleids as $roleid) {
294                     assign_capability($capability, CAP_PREVENT, $roleid, $context);
295                 }
296             }
298             $pbar->update($i, $coursecount, "Upgrading legacy course_allowed_modules data - $i/$coursecount.");
299         }
301         if ($coursecount) {
302             $transaction->allow_commit();
303         }
305         upgrade_main_savepoint(true, 2012031500.01);
306     }
308     if ($oldversion < 2012031500.02) {
310         // Define field restrictmodules to be dropped from course
311         $table = new xmldb_table('course');
312         $field = new xmldb_field('restrictmodules');
314         // Conditionally launch drop field requested
315         if ($dbman->field_exists($table, $field)) {
316             $dbman->drop_field($table, $field);
317         }
319         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
320         $SITE = $DB->get_record('course', array('id' => $SITE->id));
321         $COURSE = clone($SITE);
323         upgrade_main_savepoint(true, 2012031500.02);
324     }
326     if ($oldversion < 2012031500.03) {
328         // Define table course_allowed_modules to be dropped
329         $table = new xmldb_table('course_allowed_modules');
331         // Conditionally launch drop table for course_allowed_modules
332         if ($dbman->table_exists($table)) {
333             $dbman->drop_table($table);
334         }
336         upgrade_main_savepoint(true, 2012031500.03);
337     }
339     if ($oldversion < 2012031500.04) {
340         // Clean up the old admin settings.
341         unset_config('restrictmodulesfor');
342         unset_config('restrictbydefault');
343         unset_config('defaultallowedmodules');
345         upgrade_main_savepoint(true, 2012031500.04);
346     }
348     if ($oldversion < 2012032300.02) {
349         // Migrate the old admin debug setting.
350         if ($CFG->debug == 38911) {
351             set_config('debug', DEBUG_DEVELOPER);
352         } else if ($CFG->debug == 6143) {
353             set_config('debug', DEBUG_ALL);
354         }
355         upgrade_main_savepoint(true, 2012032300.02);
356     }
358     if ($oldversion < 2012042300.00) {
359         // This change makes the course_section index unique.
361         // Look for any duplicate course_sections entries. There should not be
362         // any but on some busy systems we found a few, maybe due to previous
363         // bugs.
364         $transaction = $DB->start_delegated_transaction();
365         $rs = $DB->get_recordset_sql('
366                 SELECT DISTINCT
367                     cs.id, cs.course
368                 FROM
369                     {course_sections} cs
370                     INNER JOIN {course_sections} older
371                         ON cs.course = older.course AND cs.section = older.section
372                         AND older.id < cs.id');
373         foreach ($rs as $rec) {
374             $DB->delete_records('course_sections', array('id' => $rec->id));
375             // We can't use rebuild_course_cache() here because introducing sectioncache later
376             // so reset modinfo manually.
377             $DB->set_field('course', 'modinfo', null, array('id' => $rec->course));
378         }
379         $rs->close();
380         $transaction->allow_commit();
382         // XMLDB does not allow changing index uniqueness - instead we must drop
383         // index then add it again.
384         // MDL-46182: The query to make the index unique uses the index,
385         // so the removal of the non-unique version needs to happen after any
386         // data changes have been made.
387         $table = new xmldb_table('course_sections');
388         $index = new xmldb_index('course_section', XMLDB_INDEX_NOTUNIQUE, array('course', 'section'));
390         // Conditionally launch drop index course_section.
391         if ($dbman->index_exists($table, $index)) {
392             $dbman->drop_index($table, $index);
393         }
395         // Define index course_section (unique) to be added to course_sections
396         $index = new xmldb_index('course_section', XMLDB_INDEX_UNIQUE, array('course', 'section'));
398         // Conditionally launch add index course_section
399         if (!$dbman->index_exists($table, $index)) {
400             $dbman->add_index($table, $index);
401         }
403         // Main savepoint reached
404         upgrade_main_savepoint(true, 2012042300.00);
405     }
407     if ($oldversion < 2012042300.02) {
408         require_once($CFG->dirroot.'/completion/criteria/completion_criteria.php');
409         // Delete orphaned criteria which were left when modules were removed
410         if ($DB->get_dbfamily() === 'mysql') {
411             $sql = "DELETE cc FROM {course_completion_criteria} cc
412                     LEFT JOIN {course_modules} cm ON cm.id = cc.moduleinstance
413                     WHERE cm.id IS NULL AND cc.criteriatype = ".COMPLETION_CRITERIA_TYPE_ACTIVITY;
414         } else {
415             $sql = "DELETE FROM {course_completion_criteria}
416                     WHERE NOT EXISTS (
417                         SELECT 'x' FROM {course_modules}
418                         WHERE {course_modules}.id = {course_completion_criteria}.moduleinstance)
419                     AND {course_completion_criteria}.criteriatype = ".COMPLETION_CRITERIA_TYPE_ACTIVITY;
420         }
421         $DB->execute($sql);
423         // Main savepoint reached
424         upgrade_main_savepoint(true, 2012042300.02);
425     }
427     if ($oldversion < 2012050300.01) {
428         // Make sure deleted users do not have picture flag.
429         $DB->set_field('user', 'picture', 0, array('deleted'=>1, 'picture'=>1));
430         upgrade_main_savepoint(true, 2012050300.01);
431     }
433     if ($oldversion < 2012050300.02) {
435         // Changing precision of field picture on table user to (10)
436         $table = new xmldb_table('user');
437         $field = new xmldb_field('picture', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'secret');
439         // Launch change of precision for field picture
440         $dbman->change_field_precision($table, $field);
442         // Main savepoint reached
443         upgrade_main_savepoint(true, 2012050300.02);
444     }
446     if ($oldversion < 2012050300.03) {
448         // Define field coursedisplay to be added to course
449         $table = new xmldb_table('course');
450         $field = new xmldb_field('coursedisplay', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'completionnotify');
452         // Conditionally launch add field coursedisplay
453         if (!$dbman->field_exists($table, $field)) {
454             $dbman->add_field($table, $field);
455         }
457         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
458         $SITE = $DB->get_record('course', array('id' => $SITE->id));
459         $COURSE = clone($SITE);
461         // Main savepoint reached
462         upgrade_main_savepoint(true, 2012050300.03);
463     }
465     if ($oldversion < 2012050300.04) {
467         // Define table course_display to be dropped
468         $table = new xmldb_table('course_display');
470         // Conditionally launch drop table for course_display
471         if ($dbman->table_exists($table)) {
472             $dbman->drop_table($table);
473         }
475         // Main savepoint reached
476         upgrade_main_savepoint(true, 2012050300.04);
477     }
479     if ($oldversion < 2012050300.05) {
481         // Clean up removed admin setting.
482         unset_config('navlinkcoursesections');
484         upgrade_main_savepoint(true, 2012050300.05);
485     }
487     if ($oldversion < 2012050400.01) {
489         // Define index sortorder (not unique) to be added to course
490         $table = new xmldb_table('course');
491         $index = new xmldb_index('sortorder', XMLDB_INDEX_NOTUNIQUE, array('sortorder'));
493         // Conditionally launch add index sortorder
494         if (!$dbman->index_exists($table, $index)) {
495             $dbman->add_index($table, $index);
496         }
498         // Main savepoint reached
499         upgrade_main_savepoint(true, 2012050400.01);
500     }
502     if ($oldversion < 2012050400.02) {
504         // Clean up removed admin setting.
505         unset_config('enablecourseajax');
507         upgrade_main_savepoint(true, 2012050400.02);
508     }
510     if ($oldversion < 2012051100.01) {
512         // Define field idnumber to be added to groups
513         $table = new xmldb_table('groups');
514         $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'courseid');
515         $index = new xmldb_index('idnumber', XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
517         // Conditionally launch add field idnumber
518         if (!$dbman->field_exists($table, $field)) {
519             $dbman->add_field($table, $field);
520         }
522         // Conditionally launch add index idnumber
523         if (!$dbman->index_exists($table, $index)) {
524             $dbman->add_index($table, $index);
525         }
527         // Define field idnumber to be added to groupings
528         $table = new xmldb_table('groupings');
529         $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'name');
530         $index = new xmldb_index('idnumber', XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
532         // Conditionally launch add field idnumber
533         if (!$dbman->field_exists($table, $field)) {
534             $dbman->add_field($table, $field);
535         }
537         // Conditionally launch add index idnumber
538         if (!$dbman->index_exists($table, $index)) {
539             $dbman->add_index($table, $index);
540         }
542         // Main savepoint reached
543         upgrade_main_savepoint(true, 2012051100.01);
544     }
546     if ($oldversion < 2012051100.03) {
548         // Amend course table to add sectioncache cache
549         $table = new xmldb_table('course');
550         $field = new xmldb_field('sectioncache', XMLDB_TYPE_TEXT, null, null, null, null, null, 'showgrades');
551         if (!$dbman->field_exists($table, $field)) {
552             $dbman->add_field($table, $field);
553         }
555         // Amend course_sections to add date, time and groupingid availability
556         // conditions and a setting about whether to show them
557         $table = new xmldb_table('course_sections');
558         $field = new xmldb_field('availablefrom', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'visible');
559         if (!$dbman->field_exists($table, $field)) {
560             $dbman->add_field($table, $field);
561         }
562         $field = new xmldb_field('availableuntil', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'availablefrom');
563         if (!$dbman->field_exists($table, $field)) {
564             $dbman->add_field($table, $field);
565         }
566         $field = new xmldb_field('showavailability', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'availableuntil');
567         // Conditionally launch add field showavailability
568         if (!$dbman->field_exists($table, $field)) {
569             $dbman->add_field($table, $field);
570         }
571         $field = new xmldb_field('groupingid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'showavailability');
572         // Conditionally launch add field groupingid
573         if (!$dbman->field_exists($table, $field)) {
574             $dbman->add_field($table, $field);
575         }
577         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
578         $SITE = $DB->get_record('course', array('id' => $SITE->id));
579         $COURSE = clone($SITE);
581         // Add course_sections_availability to add completion & grade availability conditions
582         $table = new xmldb_table('course_sections_availability');
584         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
585         $table->add_field('coursesectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
586         $table->add_field('sourcecmid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
587         $table->add_field('requiredcompletion', XMLDB_TYPE_INTEGER, '1', null, null, null, null);
588         $table->add_field('gradeitemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
589         $table->add_field('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null);
590         $table->add_field('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null);
592         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
593         $table->add_key('coursesectionid', XMLDB_KEY_FOREIGN, array('coursesectionid'), 'course_sections', array('id'));
594         $table->add_key('sourcecmid', XMLDB_KEY_FOREIGN, array('sourcecmid'), 'course_modules', array('id'));
595         $table->add_key('gradeitemid', XMLDB_KEY_FOREIGN, array('gradeitemid'), 'grade_items', array('id'));
597         if (!$dbman->table_exists($table)) {
598             $dbman->create_table($table);
599         }
601         // Main savepoint reached
602         upgrade_main_savepoint(true, 2012051100.03);
603     }
605     if ($oldversion < 2012052100.00) {
607         // Define field referencefileid to be added to files.
608         $table = new xmldb_table('files');
610         // Define field referencefileid to be added to files.
611         $field = new xmldb_field('referencefileid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'sortorder');
613         // Conditionally launch add field referencefileid.
614         if (!$dbman->field_exists($table, $field)) {
615             $dbman->add_field($table, $field);
616         }
618         // Define field referencelastsync to be added to files.
619         $field = new xmldb_field('referencelastsync', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'referencefileid');
621         // Conditionally launch add field referencelastsync.
622         if (!$dbman->field_exists($table, $field)) {
623             $dbman->add_field($table, $field);
624         }
626         // Define field referencelifetime to be added to files.
627         $field = new xmldb_field('referencelifetime', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'referencelastsync');
629         // Conditionally launch add field referencelifetime.
630         if (!$dbman->field_exists($table, $field)) {
631             $dbman->add_field($table, $field);
632         }
634         $key = new xmldb_key('referencefileid', XMLDB_KEY_FOREIGN, array('referencefileid'), 'files_reference', array('id'));
635         // Launch add key referencefileid
636         $dbman->add_key($table, $key);
638         // Define table files_reference to be created.
639         $table = new xmldb_table('files_reference');
641         // Adding fields to table files_reference.
642         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
643         $table->add_field('repositoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
644         $table->add_field('lastsync', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
645         $table->add_field('lifetime', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
646         $table->add_field('reference', XMLDB_TYPE_TEXT, null, null, null, null, null);
648         // Adding keys to table files_reference.
649         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
650         $table->add_key('repositoryid', XMLDB_KEY_FOREIGN, array('repositoryid'), 'repository_instances', array('id'));
652         // Conditionally launch create table for files_reference
653         if (!$dbman->table_exists($table)) {
654             $dbman->create_table($table);
655         }
657         // Main savepoint reached
658         upgrade_main_savepoint(true, 2012052100.00);
659     }
661     if ($oldversion < 2012052500.03) { // fix invalid course_completion_records MDL-27368
662         //first get all instances of duplicate records
663         $sql = 'SELECT userid, course FROM {course_completions} WHERE (deleted IS NULL OR deleted <> 1) GROUP BY userid, course HAVING (count(id) > 1)';
664         $duplicates = $DB->get_recordset_sql($sql, array());
666         foreach ($duplicates as $duplicate) {
667             $pointer = 0;
668             //now get all the records for this user/course
669             $sql = 'userid = ? AND course = ? AND (deleted IS NULL OR deleted <> 1)';
670             $completions = $DB->get_records_select('course_completions', $sql,
671                 array($duplicate->userid, $duplicate->course), 'timecompleted DESC, timestarted DESC');
672             $needsupdate = false;
673             $origcompletion = null;
674             foreach ($completions as $completion) {
675                 $pointer++;
676                 if ($pointer === 1) { //keep 1st record but delete all others.
677                     $origcompletion = $completion;
678                 } else {
679                     //we need to keep the "oldest" of all these fields as the valid completion record.
680                     $fieldstocheck = array('timecompleted', 'timestarted', 'timeenrolled');
681                     foreach ($fieldstocheck as $f) {
682                         if ($origcompletion->$f > $completion->$f) {
683                             $origcompletion->$f = $completion->$f;
684                             $needsupdate = true;
685                         }
686                     }
687                     $DB->delete_records('course_completions', array('id'=>$completion->id));
688                 }
689             }
690             if ($needsupdate) {
691                 $DB->update_record('course_completions', $origcompletion);
692             }
693         }
695         // Main savepoint reached
696         upgrade_main_savepoint(true, 2012052500.03);
697     }
699     if ($oldversion < 2012052900.00) {
700         // Clean up all duplicate records in the course_completions table in preparation
701         // for adding a new index there.
702         upgrade_course_completion_remove_duplicates(
703             'course_completions',
704             array('userid', 'course'),
705             array('timecompleted', 'timestarted', 'timeenrolled')
706         );
708         // Main savepoint reached
709         upgrade_main_savepoint(true, 2012052900.00);
710     }
712     if ($oldversion < 2012052900.01) {
713         // Add indexes to prevent new duplicates in the course_completions table.
714         // Define index useridcourse (unique) to be added to course_completions
715         $table = new xmldb_table('course_completions');
716         $index = new xmldb_index('useridcourse', XMLDB_INDEX_UNIQUE, array('userid', 'course'));
718         // Conditionally launch add index useridcourse
719         if (!$dbman->index_exists($table, $index)) {
720             $dbman->add_index($table, $index);
721         }
723         // Main savepoint reached
724         upgrade_main_savepoint(true, 2012052900.01);
725     }
727     if ($oldversion < 2012052900.02) {
728         // Clean up all duplicate records in the course_completion_crit_compl table in preparation
729         // for adding a new index there.
730         upgrade_course_completion_remove_duplicates(
731             'course_completion_crit_compl',
732             array('userid', 'course', 'criteriaid'),
733             array('timecompleted')
734         );
736         // Main savepoint reached
737         upgrade_main_savepoint(true, 2012052900.02);
738     }
740     if ($oldversion < 2012052900.03) {
741         // Add indexes to prevent new duplicates in the course_completion_crit_compl table.
742         // Define index useridcoursecriteraid (unique) to be added to course_completion_crit_compl
743         $table = new xmldb_table('course_completion_crit_compl');
744         $index = new xmldb_index('useridcoursecriteraid', XMLDB_INDEX_UNIQUE, array('userid', 'course', 'criteriaid'));
746         // Conditionally launch add index useridcoursecriteraid
747         if (!$dbman->index_exists($table, $index)) {
748             $dbman->add_index($table, $index);
749         }
751         // Main savepoint reached
752         upgrade_main_savepoint(true, 2012052900.03);
753     }
755     if ($oldversion < 2012052900.04) {
756         // Clean up all duplicate records in the course_completion_aggr_methd table in preparation
757         // for adding a new index there.
758         upgrade_course_completion_remove_duplicates(
759             'course_completion_aggr_methd',
760             array('course', 'criteriatype')
761         );
763         // Main savepoint reached
764         upgrade_main_savepoint(true, 2012052900.04);
765     }
767     if ($oldversion < 2012052900.05) {
768         // Add indexes to prevent new duplicates in the course_completion_aggr_methd table.
769         // Define index coursecriteratype (unique) to be added to course_completion_aggr_methd
770         $table = new xmldb_table('course_completion_aggr_methd');
771         $index = new xmldb_index('coursecriteriatype', XMLDB_INDEX_UNIQUE, array('course', 'criteriatype'));
773         // Conditionally launch add index coursecriteratype
774         if (!$dbman->index_exists($table, $index)) {
775             $dbman->add_index($table, $index);
776         }
778         // Main savepoint reached
779         upgrade_main_savepoint(true, 2012052900.05);
780     }
782     if ($oldversion < 2012060600.01) {
783         // Add field referencehash to files_reference
784         $table = new xmldb_table('files_reference');
785         $field = new xmldb_field('referencehash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, 'reference');
786         if (!$dbman->field_exists($table, $field)) {
787             $dbman->add_field($table, $field);
788         }
789         upgrade_main_savepoint(true, 2012060600.01);
790     }
792     if ($oldversion < 2012060600.02) {
793         // Populate referencehash field with SHA1 hash of the reference - this shoudl affect only 2.3dev sites
794         // that were using the feature for testing. Production sites have the table empty.
795         $rs = $DB->get_recordset('files_reference', null, '', 'id, reference');
796         foreach ($rs as $record) {
797             $hash = sha1($record->reference);
798             $DB->set_field('files_reference', 'referencehash', $hash, array('id' => $record->id));
799         }
800         $rs->close();
802         upgrade_main_savepoint(true, 2012060600.02);
803     }
805     if ($oldversion < 2012060600.03) {
806         // Merge duplicate records in files_reference that were created during the development
807         // phase at 2.3dev sites. This is needed so we can create the unique index over
808         // (repositoryid, referencehash) fields.
809         $sql = "SELECT repositoryid, referencehash, MIN(id) AS minid
810                   FROM {files_reference}
811               GROUP BY repositoryid, referencehash
812                 HAVING COUNT(*) > 1";
813         $duprs = $DB->get_recordset_sql($sql);
814         foreach ($duprs as $duprec) {
815             // get the list of all ids in {files_reference} that need to be remapped
816             $dupids = $DB->get_records_select('files_reference', "repositoryid = ? AND referencehash = ? AND id > ?",
817                 array($duprec->repositoryid, $duprec->referencehash, $duprec->minid), '', 'id');
818             $dupids = array_keys($dupids);
819             // relink records in {files} that are now referring to a duplicate record
820             // in {files_reference} to refer to the first one
821             list($subsql, $subparams) = $DB->get_in_or_equal($dupids);
822             $DB->set_field_select('files', 'referencefileid', $duprec->minid, "referencefileid $subsql", $subparams);
823             // and finally remove all orphaned records from {files_reference}
824             $DB->delete_records_list('files_reference', 'id', $dupids);
825         }
826         $duprs->close();
828         upgrade_main_savepoint(true, 2012060600.03);
829     }
831     if ($oldversion < 2012060600.04) {
832         // Add a unique index over repositoryid and referencehash fields in files_reference table
833         $table = new xmldb_table('files_reference');
834         $index = new xmldb_index('uq_external_file', XMLDB_INDEX_UNIQUE, array('repositoryid', 'referencehash'));
836         if (!$dbman->index_exists($table, $index)) {
837             $dbman->add_index($table, $index);
838         }
840         upgrade_main_savepoint(true, 2012060600.04);
841     }
843     if ($oldversion < 2012061800.01) {
845         // Define field screenreader to be dropped from user
846         $table = new xmldb_table('user');
847         $field = new xmldb_field('ajax');
849         // Conditionally launch drop field screenreader
850         if ($dbman->field_exists($table, $field)) {
851             $dbman->drop_field($table, $field);
852         }
854         // Main savepoint reached
855         upgrade_main_savepoint(true, 2012061800.01);
856     }
858     if ($oldversion < 2012062000.00) {
859         // Add field newcontextid to backup_files_template
860         $table = new xmldb_table('backup_files_template');
861         $field = new xmldb_field('newcontextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'info');
863         if (!$dbman->field_exists($table, $field)) {
864             $dbman->add_field($table, $field);
865         }
867         upgrade_main_savepoint(true, 2012062000.00);
868     }
870     if ($oldversion < 2012062000.01) {
871         // Add field newitemid to backup_files_template
872         $table = new xmldb_table('backup_files_template');
873         $field = new xmldb_field('newitemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'newcontextid');
875         if (!$dbman->field_exists($table, $field)) {
876             $dbman->add_field($table, $field);
877         }
879         upgrade_main_savepoint(true, 2012062000.01);
880     }
882     // Moodle v2.3.0 release upgrade line
883     // Put any upgrade step following this
885     if ($oldversion < 2012062500.02) {
886         // Drop some old backup tables, not used anymore
888         // Define table backup_files to be dropped
889         $table = new xmldb_table('backup_files');
891         // Conditionally launch drop table for backup_files
892         if ($dbman->table_exists($table)) {
893             $dbman->drop_table($table);
894         }
896         // Define table backup_ids to be dropped
897         $table = new xmldb_table('backup_ids');
899         // Conditionally launch drop table for backup_ids
900         if ($dbman->table_exists($table)) {
901             $dbman->drop_table($table);
902         }
904         // Main savepoint reached
905         upgrade_main_savepoint(true, 2012062500.02);
906     }
908     if ($oldversion < 2012070600.04) {
909         // Define table course_modules_avail_fields to be created
910         $table = new xmldb_table('course_modules_avail_fields');
912         // Adding fields to table course_modules_avail_fields
913         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
914         $table->add_field('coursemoduleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
915         $table->add_field('userfield', XMLDB_TYPE_CHAR, '50', null, null, null, null);
916         $table->add_field('customfieldid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
917         $table->add_field('operator', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null);
918         $table->add_field('value', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
920         // Adding keys to table course_modules_avail_fields
921         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
922         $table->add_key('coursemoduleid', XMLDB_KEY_FOREIGN, array('coursemoduleid'), 'course_modules', array('id'));
924         // Conditionally launch create table for course_modules_avail_fields
925         if (!$dbman->table_exists($table)) {
926             $dbman->create_table($table);
927         }
929         // Main savepoint reached
930         upgrade_main_savepoint(true, 2012070600.04);
931     }
933     if ($oldversion < 2012070600.05) {
934         // Define table course_sections_avail_fields to be created
935         $table = new xmldb_table('course_sections_avail_fields');
937         // Adding fields to table course_sections_avail_fields
938         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
939         $table->add_field('coursesectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
940         $table->add_field('userfield', XMLDB_TYPE_CHAR, '50', null, null, null, null);
941         $table->add_field('customfieldid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
942         $table->add_field('operator', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null);
943         $table->add_field('value', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
945         // Adding keys to table course_sections_avail_fields
946         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
947         $table->add_key('coursesectionid', XMLDB_KEY_FOREIGN, array('coursesectionid'), 'course_sections', array('id'));
949         // Conditionally launch create table for course_sections_avail_fields
950         if (!$dbman->table_exists($table)) {
951             $dbman->create_table($table);
952         }
954         // Main savepoint reached
955         upgrade_main_savepoint(true, 2012070600.05);
956     }
958     if ($oldversion < 2012070600.06) {
960         // Drop "deleted" fields
961         $table = new xmldb_table('course_completions');
962         $field = new xmldb_field('timenotified');
963         $field = new xmldb_field('deleted');
965         // Conditionally launch drop field deleted from course_completions
966         if ($dbman->field_exists($table, $field)) {
967             $dbman->drop_field($table, $field);
968         }
970         $field = new xmldb_field('timenotified');
971         // Conditionally launch drop field timenotified from course_completions
972         if ($dbman->field_exists($table, $field)) {
973             $dbman->drop_field($table, $field);
974         }
976         // Main savepoint reached
977         upgrade_main_savepoint(true, 2012070600.06);
978     }
980     if ($oldversion < 2012070600.07) {
981         $table = new xmldb_table('course_completion_crit_compl');
982         $field = new xmldb_field('deleted');
984         // Conditionally launch drop field deleted from course_completion_crit_compl
985         if ($dbman->field_exists($table, $field)) {
986             $dbman->drop_field($table, $field);
987         }
988         // Main savepoint reached
989         upgrade_main_savepoint(true, 2012070600.07);
990     }
992     if ($oldversion < 2012070600.08) {
994         // Drop unused table "course_completion_notify"
995         $table = new xmldb_table('course_completion_notify');
997         // Conditionally launch drop table course_completion_notify
998         if ($dbman->table_exists($table)) {
999             $dbman->drop_table($table);
1000         }
1002         // Main savepoint reached
1003         upgrade_main_savepoint(true, 2012070600.08);
1004      }
1006     if ($oldversion < 2012070600.09) {
1008         // Define index path (not unique) to be added to context
1009         $table = new xmldb_table('context');
1010         $index = new xmldb_index('path', XMLDB_INDEX_NOTUNIQUE, array('path'), array('varchar_pattern_ops'));
1012         // Recreate index with new pattern hint
1013         if ($DB->get_dbfamily() === 'postgres') {
1014             if ($dbman->index_exists($table, $index)) {
1015                 $dbman->drop_index($table, $index);
1016             }
1017             $dbman->add_index($table, $index);
1018         }
1020         // Main savepoint reached
1021         upgrade_main_savepoint(true, 2012070600.09);
1022     }
1024     if ($oldversion < 2012070600.10) {
1026         // Define index name (unique) to be dropped form role
1027         $table = new xmldb_table('role');
1028         $index = new xmldb_index('name', XMLDB_INDEX_UNIQUE, array('name'));
1030         // Conditionally launch drop index name
1031         if ($dbman->index_exists($table, $index)) {
1032             $dbman->drop_index($table, $index);
1033         }
1035         // Main savepoint reached
1036         upgrade_main_savepoint(true, 2012070600.10);
1037     }
1039     if ($oldversion < 2012070600.11) {
1041         // Define index component-itemid-userid (not unique) to be added to role_assignments
1042         $table = new xmldb_table('role_assignments');
1043         $index = new xmldb_index('component-itemid-userid', XMLDB_INDEX_NOTUNIQUE, array('component', 'itemid', 'userid'));
1045         // Conditionally launch add index component-itemid-userid
1046         if (!$dbman->index_exists($table, $index)) {
1047             $dbman->add_index($table, $index);
1048         }
1050         // Main savepoint reached
1051         upgrade_main_savepoint(true, 2012070600.11);
1052     }
1054     if ($oldversion < 2012071900.01) {
1055         // Cleanup after simpeltests tool
1056         capabilities_cleanup('tool_unittest');
1057         unset_all_config_for_plugin('tool_unittest');
1059         upgrade_main_savepoint(true, 2012071900.01);
1060     }
1062     if ($oldversion < 2012072400.00) {
1063         // Remove obsolete xhtml strict setting - use THEME->doctype in theme config if necessary,
1064         // see theme_config->doctype in lib/outputlib.php for more details.
1065         unset_config('xmlstrictheaders');
1066         upgrade_main_savepoint(true, 2012072400.00);
1067     }
1069     if ($oldversion < 2012072401.00) {
1071         // Saves orphaned questions from the Dark Side
1072         upgrade_save_orphaned_questions();
1074         // Main savepoint reached
1075         upgrade_main_savepoint(true, 2012072401.00);
1076     }
1078     if ($oldversion < 2012072600.01) {
1079         // Handle events with empty eventtype //MDL-32827
1081         $DB->set_field('event', 'eventtype', 'site', array('eventtype' => '', 'courseid' => $SITE->id));
1082         $DB->set_field_select('event', 'eventtype', 'due', "eventtype = '' AND courseid != 0 AND groupid = 0 AND (modulename = 'assignment' OR modulename = 'assign')");
1083         $DB->set_field_select('event', 'eventtype', 'course', "eventtype = '' AND courseid != 0 AND groupid = 0");
1084         $DB->set_field_select('event', 'eventtype', 'group', "eventtype = '' AND groupid != 0");
1085         $DB->set_field_select('event', 'eventtype', 'user', "eventtype = '' AND userid != 0");
1087         // Main savepoint reached
1088         upgrade_main_savepoint(true, 2012072600.01);
1089     }
1091     if ($oldversion < 2012080200.02) {
1092         // Drop obsolete question upgrade field that should have been added to the install.xml.
1093         $table = new xmldb_table('question');
1094         $field = new xmldb_field('oldquestiontextformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
1096         if ($dbman->field_exists($table, $field)) {
1097             $dbman->drop_field($table, $field);
1098         }
1100         upgrade_main_savepoint(true, 2012080200.02);
1101     }
1103     if ($oldversion < 2012081400.01) {
1104         // Move the ability to disable blogs to its own setting MDL-25012.
1106         if (isset($CFG->bloglevel)) {
1107             // Only change settings if existing setting was set.
1108             if (empty($CFG->bloglevel)) {
1109                 set_config('enableblogs', 0);
1110                 // Now set the bloglevel to a valid setting as the disabled setting has been removed.
1111                 // This prevents confusing results when users enable the blog system in future.
1112                 set_config('bloglevel', BLOG_USER_LEVEL);
1113             } else {
1114                 set_config('enableblogs', 1);
1115             }
1116         }
1118         // Main savepoint reached
1119         upgrade_main_savepoint(true, 2012081400.01);
1120     }
1122     if ($oldversion < 2012081600.01) {
1123         // Delete removed setting - Google Maps API V2 will not work in 2013.
1124         unset_config('googlemapkey');
1125         upgrade_main_savepoint(true, 2012081600.01);
1126     }
1128     if ($oldversion < 2012082300.01) {
1129         // Add more custom enrol fields.
1130         $table = new xmldb_table('enrol');
1131         $field = new xmldb_field('customint5', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customint4');
1133         if (!$dbman->field_exists($table, $field)) {
1134             $dbman->add_field($table, $field);
1135         }
1137         $field = new xmldb_field('customint6', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customint5');
1138         if (!$dbman->field_exists($table, $field)) {
1139             $dbman->add_field($table, $field);
1140         }
1142         $field = new xmldb_field('customint7', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customint6');
1143         if (!$dbman->field_exists($table, $field)) {
1144             $dbman->add_field($table, $field);
1145         }
1147         $field = new xmldb_field('customint8', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customint7');
1148         if (!$dbman->field_exists($table, $field)) {
1149             $dbman->add_field($table, $field);
1150         }
1152         $field = new xmldb_field('customchar3', XMLDB_TYPE_CHAR, '1333', null, null, null, null, 'customchar2');
1153         if (!$dbman->field_exists($table, $field)) {
1154             $dbman->add_field($table, $field);
1155         }
1157         $field = new xmldb_field('customtext3', XMLDB_TYPE_TEXT, null, null, null, null, null, 'customtext2');
1158         if (!$dbman->field_exists($table, $field)) {
1159             $dbman->add_field($table, $field);
1160         }
1162         $field = new xmldb_field('customtext4', XMLDB_TYPE_TEXT, null, null, null, null, null, 'customtext3');
1163         if (!$dbman->field_exists($table, $field)) {
1164             $dbman->add_field($table, $field);
1165         }
1167         // Main savepoint reached.
1168         upgrade_main_savepoint(true, 2012082300.01);
1169     }
1171     if ($oldversion < 2012082300.02) {
1172         // Define field component to be added to groups_members
1173         $table = new xmldb_table('groups_members');
1174         $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'timeadded');
1176         // Conditionally launch add field component
1177         if (!$dbman->field_exists($table, $field)) {
1178             $dbman->add_field($table, $field);
1179         }
1181         // Define field itemid to be added to groups_members
1182         $field = new xmldb_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'component');
1184         // Conditionally launch add field itemid
1185         if (!$dbman->field_exists($table, $field)) {
1186             $dbman->add_field($table, $field);
1187         }
1189         // Main savepoint reached
1190         upgrade_main_savepoint(true, 2012082300.02);
1191     }
1193     if ($oldversion < 2012090500.00) {
1194         $subquery = 'SELECT b.id FROM {blog_external} b where b.id = ' . $DB->sql_cast_char2int('{post}.content', true);
1195         $sql = 'DELETE FROM {post}
1196                       WHERE {post}.module = \'blog_external\'
1197                             AND NOT EXISTS (' . $subquery . ')
1198                             AND ' . $DB->sql_isnotempty('post', 'uniquehash', false, false);
1199         $DB->execute($sql);
1200         upgrade_main_savepoint(true, 2012090500.00);
1201     }
1203     if ($oldversion < 2012090700.01) {
1204         // Add a category field in the course_request table
1205         $table = new xmldb_table('course_request');
1206         $field = new xmldb_field('category', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0, 'summaryformat');
1207         if (!$dbman->field_exists($table, $field)) {
1208             $dbman->add_field($table, $field);
1209         }
1211         // Main savepoint reached.
1212         upgrade_main_savepoint(true, 2012090700.01);
1213     }
1215     if ($oldversion < 2012091700.00) {
1217         // Dropping screenreader field from user.
1218         $table = new xmldb_table('user');
1219         $field = new xmldb_field('screenreader');
1221         if ($dbman->field_exists($table, $field)) {
1222             $dbman->drop_field($table, $field);
1223         }
1225         // Main savepoint reached.
1226         upgrade_main_savepoint(true, 2012091700.00);
1227     }
1229     if ($oldversion < 2012092100.01) {
1230         // Some folders still have a sortorder set, which is used for main files but is not
1231         // supported by the folder resource. We reset the value here.
1232         $sql = 'UPDATE {files} SET sortorder = ? WHERE component = ? AND filearea = ? AND sortorder <> ?';
1233         $DB->execute($sql, array(0, 'mod_folder', 'content', 0));
1235         // Main savepoint reached.
1236         upgrade_main_savepoint(true, 2012092100.01);
1237     }
1239     if ($oldversion < 2012092600.00) {
1240         // Define index idname (unique) to be added to tag
1241         $table = new xmldb_table('tag');
1242         $index = new xmldb_index('idname', XMLDB_INDEX_UNIQUE, array('id', 'name'));
1244         // Conditionally launch add index idname
1245         if (!$dbman->index_exists($table, $index)) {
1246             $dbman->add_index($table, $index);
1247         }
1249         // Main savepoint reached
1250         upgrade_main_savepoint(true, 2012092600.00);
1251     }
1253     if ($oldversion < 2012101500.01) {
1254         // Find all orphaned blog associations that might exist.
1255         $sql = "SELECT ba.id
1256                   FROM {blog_association} ba
1257              LEFT JOIN {post} p
1258                     ON p.id = ba.blogid
1259                  WHERE p.id IS NULL";
1260         $orphanedrecordids = $DB->get_records_sql($sql);
1261         // Now delete these associations.
1262         foreach ($orphanedrecordids as $orphanedrecord) {
1263             $DB->delete_records('blog_association', array('id' => $orphanedrecord->id));
1264         }
1266         upgrade_main_savepoint(true, 2012101500.01);
1267     }
1269     if ($oldversion < 2012101800.02) {
1270         // Renaming backups using previous file naming convention.
1271         upgrade_rename_old_backup_files_using_shortname();
1273         // Main savepoint reached.
1274         upgrade_main_savepoint(true, 2012101800.02);
1275     }
1277     if ($oldversion < 2012103001.00) {
1278         // create new event_subscriptions table
1279         $table = new xmldb_table('event_subscriptions');
1280         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1281         $table->add_field('url', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1282         $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1283         $table->add_field('groupid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1284         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1285         $table->add_field('pollinterval', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1286         $table->add_field('lastupdated', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
1287         $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1288         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1289         if (!$dbman->table_exists($table)) {
1290             $dbman->create_table($table);
1291         }
1292         // Main savepoint reached
1293         upgrade_main_savepoint(true, 2012103001.00);
1294     }
1296     if ($oldversion < 2012103002.00) {
1297         // Add subscription field to the event table
1298         $table = new xmldb_table('event');
1299         $field = new xmldb_field('subscriptionid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'timemodified');
1301         // Conditionally launch add field subscriptionid
1302         if (!$dbman->field_exists($table, $field)) {
1303             $dbman->add_field($table, $field);
1304         }
1305         upgrade_main_savepoint(true, 2012103002.00);
1306     }
1308     if ($oldversion < 2012103003.00) {
1309         // Fix uuid field in event table to match RFC-2445 UID property.
1310         $table = new xmldb_table('event');
1311         $field = new xmldb_field('uuid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'visible');
1312         // The column already exists, so make sure there are no nulls (crazy mysql).
1313         $DB->set_field_select('event', 'uuid', '', "uuid IS NULL");
1314         // Changing precision of field uuid on table event to (255).
1315         $dbman->change_field_precision($table, $field);
1316         // Main savepoint reached
1317         upgrade_main_savepoint(true, 2012103003.00);
1318     }
1320     if ($oldversion < 2012110200.00) {
1322         // Define table course_format_options to be created
1323         $table = new xmldb_table('course_format_options');
1325         // Adding fields to table course_format_options
1326         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1327         $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1328         $table->add_field('format', XMLDB_TYPE_CHAR, '21', null, XMLDB_NOTNULL, null, null);
1329         $table->add_field('sectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'format');
1330         $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
1331         $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null);
1333         // Adding keys to table course_format_options
1334         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1335         $table->add_key('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
1337         // Adding indexes to table course_format_options
1338         $table->add_index('formatoption', XMLDB_INDEX_UNIQUE, array('courseid', 'format', 'sectionid', 'name'));
1340         // Conditionally launch create table for course_format_options
1341         if (!$dbman->table_exists($table)) {
1342             $dbman->create_table($table);
1343         }
1345         // Changing type of field format on table course to char with length 21
1346         $table = new xmldb_table('course');
1347         $field = new xmldb_field('format', XMLDB_TYPE_CHAR, '21', null, XMLDB_NOTNULL, null, 'topics', 'summaryformat');
1349         // Launch change of type for field format
1350         $dbman->change_field_type($table, $field);
1352         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
1353         $SITE = $DB->get_record('course', array('id' => $SITE->id));
1354         $COURSE = clone($SITE);
1356         // Main savepoint reached
1357         upgrade_main_savepoint(true, 2012110200.00);
1358     }
1360     if ($oldversion < 2012110201.00) {
1362         // Copy fields 'coursedisplay', 'numsections', 'hiddensections' from table {course}
1363         // to table {course_format_options} as the additional format options
1364         $fields = array();
1365         $table = new xmldb_table('course');
1366         foreach (array('coursedisplay', 'numsections', 'hiddensections') as $fieldname) {
1367             // first check that fields still exist
1368             $field = new xmldb_field($fieldname);
1369             if ($dbman->field_exists($table, $field)) {
1370                 $fields[] = $fieldname;
1371             }
1372         }
1374         if (!empty($fields)) {
1375             $transaction = $DB->start_delegated_transaction();
1376             $rs = $DB->get_recordset_sql('SELECT id, format, '. join(',', $fields).'
1377                 FROM {course}
1378                 WHERE format <> ? AND format <> ?',
1379                 array('scorm', 'social'));
1380             // (do not copy fields from scrom and social formats, we already know that they are not used)
1381             foreach ($rs as $rec) {
1382                 foreach ($fields as $field) {
1383                     try {
1384                         $DB->insert_record('course_format_options',
1385                                 array(
1386                                     'courseid'  => $rec->id,
1387                                     'format'    => $rec->format,
1388                                     'sectionid' => 0,
1389                                     'name'      => $field,
1390                                     'value'     => $rec->$field
1391                                 ));
1392                     } catch (dml_exception $e) {
1393                         // index 'courseid,format,sectionid,name' violation
1394                         // continue; the entry in course_format_options already exists, use it
1395                     }
1396                 }
1397             }
1398             $rs->close();
1399             $transaction->allow_commit();
1401             // Drop fields from table course
1402             foreach ($fields as $fieldname) {
1403                 $field = new xmldb_field($fieldname);
1404                 $dbman->drop_field($table, $field);
1405             }
1406         }
1408         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
1409         $SITE = $DB->get_record('course', array('id' => $SITE->id));
1410         $COURSE = clone($SITE);
1412         // Main savepoint reached
1413         upgrade_main_savepoint(true, 2012110201.00);
1414     }
1416     if ($oldversion < 2012110700.01) {
1418         // Define field caller_component to be added to portfolio_log.
1419         $table = new xmldb_table('portfolio_log');
1420         $field = new xmldb_field('caller_component', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'caller_file');
1422         // Conditionally launch add field caller_component.
1423         if (!$dbman->field_exists($table, $field)) {
1424             $dbman->add_field($table, $field);
1425         }
1427         // Main savepoint reached.
1428         upgrade_main_savepoint(true, 2012110700.01);
1429     }
1431     if ($oldversion < 2012111200.00) {
1433         // Define table temp_enroled_template to be created
1434         $table = new xmldb_table('temp_enroled_template');
1436         // Adding fields to table temp_enroled_template
1437         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1438         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1439         $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1440         $table->add_field('roleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1442         // Adding keys to table temp_enroled_template
1443         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1445         // Adding indexes to table temp_enroled_template
1446         $table->add_index('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
1447         $table->add_index('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
1448         $table->add_index('roleid', XMLDB_INDEX_NOTUNIQUE, array('roleid'));
1450         // Conditionally launch create table for temp_enroled_template
1451         if (!$dbman->table_exists($table)) {
1452             $dbman->create_table($table);
1453         }
1455         // Define table temp_log_template to be created
1456         $table = new xmldb_table('temp_log_template');
1458         // Adding fields to table temp_log_template
1459         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1460         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1461         $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1462         $table->add_field('action', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
1464         // Adding keys to table temp_log_template
1465         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1467         // Adding indexes to table temp_log_template
1468         $table->add_index('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
1469         $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
1470         $table->add_index('user', XMLDB_INDEX_NOTUNIQUE, array('userid'));
1471         $table->add_index('usercourseaction', XMLDB_INDEX_NOTUNIQUE, array('userid', 'course', 'action'));
1473         // Conditionally launch create table for temp_log_template
1474         if (!$dbman->table_exists($table)) {
1475             $dbman->create_table($table);
1476         }
1478         // Main savepoint reached
1479         upgrade_main_savepoint(true, 2012111200.00);
1480     }
1482     if ($oldversion < 2012111200.01) {
1483         // Force the rebuild of the cache of every courses, some cached information could contain wrong icon references.
1484         $DB->execute('UPDATE {course} set modinfo = ?, sectioncache = ?', array(null, null));
1486         // Main savepoint reached.
1487         upgrade_main_savepoint(true, 2012111200.01);
1488     }
1490     if ($oldversion < 2012111601.01) {
1491         // Clea up after old shared memory caching support.
1492         unset_config('cachetype');
1493         unset_config('rcache');
1494         unset_config('rcachettl');
1495         unset_config('intcachemax');
1496         unset_config('memcachedhosts');
1497         unset_config('memcachedpconn');
1499         // Main savepoint reached.
1500         upgrade_main_savepoint(true, 2012111601.01);
1501     }
1503     if ($oldversion < 2012112100.00) {
1505         // Define field eventtype to be added to event_subscriptions.
1506         $table = new xmldb_table('event_subscriptions');
1507         $field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, 'userid');
1509         // Conditionally launch add field eventtype.
1510         if (!$dbman->field_exists($table, $field)) {
1511             $dbman->add_field($table, $field);
1512         }
1514         // Main savepoint reached.
1515         upgrade_main_savepoint(true, 2012112100.00);
1516     }
1518     // Moodle v2.4.0 release upgrade line
1519     // Put any upgrade step following this
1521     if ($oldversion < 2012120300.01) {
1522         // Make sure site-course has format='site' //MDL-36840
1524         if ($SITE->format !== 'site') {
1525             $DB->set_field('course', 'format', 'site', array('id' => $SITE->id));
1526             $SITE->format = 'site';
1527             $COURSE->format = 'site';
1528         }
1530         // Main savepoint reached
1531         upgrade_main_savepoint(true, 2012120300.01);
1532     }
1534     if ($oldversion < 2012120300.04) {
1535         // Remove "_utf8" suffix from all langs in course table.
1536         $langs = $DB->get_records_sql("SELECT DISTINCT lang FROM {course} WHERE lang LIKE ?", array('%_utf8'));
1538         foreach ($langs as $lang=>$unused) {
1539             $newlang = str_replace('_utf8', '', $lang);
1540             $sql = "UPDATE {course} SET lang = :newlang WHERE lang = :lang";
1541             $DB->execute($sql, array('newlang'=>$newlang, 'lang'=>$lang));
1542         }
1544         // Main savepoint reached.
1545         upgrade_main_savepoint(true, 2012120300.04);
1546     }
1548     if ($oldversion < 2012123000.00) {
1549         // Purge removed module filters and all their settings.
1551         $tables = array('filter_active', 'filter_config');
1552         foreach ($tables as $table) {
1553             $DB->delete_records_select($table, "filter LIKE 'mod/%'");
1554             $filters = $DB->get_records_sql("SELECT DISTINCT filter FROM {{$table}} WHERE filter LIKE 'filter/%'");
1555             foreach ($filters as $filter) {
1556                 $DB->set_field($table, 'filter', substr($filter->filter, 7), array('filter'=>$filter->filter));
1557             }
1558         }
1560         $configs = array('stringfilters', 'filterall');
1561         foreach ($configs as $config) {
1562             if ($filters = get_config(null, $config)) {
1563                 $filters = explode(',', $filters);
1564                 $newfilters = array();
1565                 foreach($filters as $filter) {
1566                     if (strpos($filter, '/') === false) {
1567                         $newfilters[] = $filter;
1568                     } else if (strpos($filter, 'filter/') === 0) {
1569                         $newfilters[] = substr($filter, 7);
1570                     }
1571                 }
1572                 $filters = implode(',', $newfilters);
1573                 set_config($config, $filters);
1574             }
1575         }
1577         unset($tables);
1578         unset($table);
1579         unset($configs);
1580         unset($newfilters);
1581         unset($filters);
1582         unset($filter);
1584         // Main savepoint reached.
1585         upgrade_main_savepoint(true, 2012123000.00);
1586     }
1588     if ($oldversion < 2013021100.01) {
1589         // Make sure there are no bogus nulls in old MySQL tables.
1590         $DB->set_field_select('user', 'password', '', "password IS NULL");
1592         // Changing precision of field password on table user to (255).
1593         $table = new xmldb_table('user');
1594         $field = new xmldb_field('password', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'username');
1596         // Launch change of precision for field password.
1597         $dbman->change_field_precision($table, $field);
1599         // Main savepoint reached.
1600         upgrade_main_savepoint(true, 2013021100.01);
1601     }
1603     if ($oldversion < 2013021800.00) {
1604         // Add the site identifier to the cache config's file.
1605         $siteidentifier = $DB->get_field('config', 'value', array('name' => 'siteidentifier'));
1606         cache_helper::update_site_identifier($siteidentifier);
1608         // Main savepoint reached.
1609         upgrade_main_savepoint(true, 2013021800.00);
1610     }
1612     if ($oldversion < 2013021801.00) {
1613         // Fixing possible wrong MIME types for SMART Notebook files.
1614         $extensions = array('%.gallery', '%.galleryitem', '%.gallerycollection', '%.nbk', '%.notebook', '%.xbk');
1615         $select = $DB->sql_like('filename', '?', false);
1616         foreach ($extensions as $extension) {
1617             $DB->set_field_select(
1618                 'files',
1619                 'mimetype',
1620                 'application/x-smarttech-notebook',
1621                 $select,
1622                 array($extension)
1623             );
1624         }
1625         upgrade_main_savepoint(true, 2013021801.00);
1626     }
1628     if ($oldversion < 2013021801.01) {
1629         // This upgrade step is re-written under MDL-38228 (see below).
1630         /*
1631         // Retrieve the list of course_sections as a recordset to save memory
1632         $coursesections = $DB->get_recordset('course_sections', null, 'course, id', 'id, course, sequence');
1633         foreach ($coursesections as $coursesection) {
1634             // Retrieve all of the actual modules in this course and section combination to reduce DB calls
1635             $actualsectionmodules = $DB->get_records('course_modules',
1636                     array('course' => $coursesection->course, 'section' => $coursesection->id), '', 'id, section');
1638             // Break out the current sequence so that we can compare it
1639             $currentsequence = explode(',', $coursesection->sequence);
1640             $newsequence = array();
1642             // Check each of the modules in the current sequence
1643             foreach ($currentsequence as $module) {
1644                 if (isset($actualsectionmodules[$module])) {
1645                     $newsequence[] = $module;
1646                     // We unset the actualsectionmodules so that we don't get duplicates and that we can add orphaned
1647                     // modules later
1648                     unset($actualsectionmodules[$module]);
1649                 }
1650             }
1652             // Append any modules which have somehow been orphaned
1653             foreach ($actualsectionmodules as $module) {
1654                 $newsequence[] = $module->id;
1655             }
1657             // Piece it all back together
1658             $sequence = implode(',', $newsequence);
1660             // Only update if there have been changes
1661             if ($sequence !== $coursesection->sequence) {
1662                 $coursesection->sequence = $sequence;
1663                 $DB->update_record('course_sections', $coursesection);
1665                 // And clear the sectioncache and modinfo cache - they'll be regenerated on next use
1666                 $course = new stdClass();
1667                 $course->id = $coursesection->course;
1668                 $course->sectioncache = null;
1669                 $course->modinfo = null;
1670                 $DB->update_record('course', $course);
1671             }
1672         }
1673         $coursesections->close();
1674         */
1675         // Main savepoint reached.
1676         upgrade_main_savepoint(true, 2013021801.01);
1677     }
1679     if ($oldversion < 2013021902.00) {
1680         // ISO country change: Netherlands Antilles is split into BQ, CW & SX
1681         // http://www.iso.org/iso/iso_3166-1_newsletter_vi-8_split_of_the_dutch_antilles_final-en.pdf
1682         $sql = "UPDATE {user} SET country = '' WHERE country = ?";
1683         $DB->execute($sql, array('AN'));
1685         upgrade_main_savepoint(true, 2013021902.00);
1686     }
1688     if ($oldversion < 2013022600.00) {
1689         // Delete entries regarding invalid 'interests' option which breaks course.
1690         $DB->delete_records('course_sections_avail_fields', array('userfield' => 'interests'));
1691         $DB->delete_records('course_modules_avail_fields', array('userfield' => 'interests'));
1692         // Clear course cache (will be rebuilt on first visit) in case of changes to these.
1693         $DB->execute('UPDATE {course} set modinfo = ?, sectioncache = ?', array(null, null));
1695         upgrade_main_savepoint(true, 2013022600.00);
1696     }
1698     // Add index to field "timemodified" for grade_grades_history table.
1699     if ($oldversion < 2013030400.00) {
1700         $table = new xmldb_table('grade_grades_history');
1701         $field = new xmldb_field('timemodified');
1703         if ($dbman->field_exists($table, $field)) {
1704             $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1705             if (!$dbman->index_exists($table, $index)) {
1706                 $dbman->add_index($table, $index);
1707             }
1708         }
1710         // Main savepoint reached.
1711         upgrade_main_savepoint(true, 2013030400.00);
1712     }
1714     if ($oldversion < 2013030400.02) {
1715         // Cleanup qformat blackboard settings.
1716         unset_all_config_for_plugin('qformat_blackboard');
1718         upgrade_main_savepoint(true, 2013030400.02);
1719     }
1721     // This is checking to see if the site has been running a specific version with a bug in it
1722     // because this upgrade step is slow and is only needed if the site has been running with the affected versions.
1723     if ($oldversion >= 2012062504.08 && $oldversion < 2012062504.13) {
1724         // This upgrade step is re-written under MDL-38228 (see below).
1726         /*
1727         // Retrieve the list of course_sections as a recordset to save memory.
1728         // This is to fix a regression caused by MDL-37939.
1729         // In this case the upgrade step is fixing records where:
1730         // The data in course_sections.sequence contains the correct module id
1731         // The section field for on the course modules table may have been updated to point to the incorrect id.
1733         // This query is looking for sections where the sequence is not in sync with the course_modules table.
1734         // The syntax for the like query is looking for a value in a comma separated list.
1735         // It adds a comma to either site of the list and then searches for LIKE '%,id,%'.
1736         $sequenceconcat = $DB->sql_concat("','", 's.sequence', "','");
1737         $moduleconcat = $DB->sql_concat("'%,'", 'cm.id', "',%'");
1738         $sql = 'SELECT s2.id, s2.course, s2.sequence
1739                 FROM {course_sections} s2
1740                 JOIN(
1741                     SELECT DISTINCT s.id
1742                     FROM
1743                     {course_modules} cm
1744                     JOIN {course_sections} s
1745                     ON
1746                         cm.course = s.course
1747                     WHERE cm.section != s.id AND ' . $sequenceconcat . ' LIKE ' . $moduleconcat . '
1748                 ) d
1749                 ON s2.id = d.id';
1750         $coursesections = $DB->get_recordset_sql($sql);
1752         foreach ($coursesections as $coursesection) {
1753             // Retrieve all of the actual modules in this course and section combination to reduce DB calls.
1754             $actualsectionmodules = $DB->get_records('course_modules',
1755                     array('course' => $coursesection->course, 'section' => $coursesection->id), '', 'id, section');
1757             // Break out the current sequence so that we can compare it.
1758             $currentsequence = explode(',', $coursesection->sequence);
1759             $orphanlist = array();
1761             // Check each of the modules in the current sequence.
1762             foreach ($currentsequence as $cmid) {
1763                 if (!empty($cmid) && !isset($actualsectionmodules[$cmid])) {
1764                     $orphanlist[] = $cmid;
1765                 }
1766             }
1768             if (!empty($orphanlist)) {
1769                 list($sql, $params) = $DB->get_in_or_equal($orphanlist, SQL_PARAMS_NAMED);
1770                 $sql = "id $sql";
1772                 $DB->set_field_select('course_modules', 'section', $coursesection->id, $sql, $params);
1774                 // And clear the sectioncache and modinfo cache - they'll be regenerated on next use.
1775                 $course = new stdClass();
1776                 $course->id = $coursesection->course;
1777                 $course->sectioncache = null;
1778                 $course->modinfo = null;
1779                 $DB->update_record('course', $course);
1780             }
1781         }
1782         $coursesections->close();
1784         // No savepoint needed for this change.
1785          */
1786     }
1788     if ($oldversion < 2013032200.01) {
1789         // GD is now always available
1790         set_config('gdversion', 2);
1792         upgrade_main_savepoint(true, 2013032200.01);
1793     }
1795     if ($oldversion < 2013032600.03) {
1796         // Fixing possible wrong MIME type for MIME HTML (MHTML) files.
1797         $extensions = array('%.mht', '%.mhtml');
1798         $select = $DB->sql_like('filename', '?', false);
1799         foreach ($extensions as $extension) {
1800             $DB->set_field_select(
1801                 'files',
1802                 'mimetype',
1803                 'message/rfc822',
1804                 $select,
1805                 array($extension)
1806             );
1807         }
1808         upgrade_main_savepoint(true, 2013032600.03);
1809     }
1811     if ($oldversion < 2013032600.04) {
1812         // MDL-31983 broke the quiz version number. Fix it.
1813         $DB->set_field('modules', 'version', '2013021500',
1814                 array('name' => 'quiz', 'version' => '2013310100'));
1815         upgrade_main_savepoint(true, 2013032600.04);
1816     }
1818     if ($oldversion < 2013040200.00) {
1819         // Add openbadges tables.
1821         // Define table 'badge' to be created.
1822         $table = new xmldb_table('badge');
1824         // Adding fields to table 'badge'.
1825         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1826         $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'id');
1827         $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null, 'name');
1828         $table->add_field('image', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'description');
1829         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'image');
1830         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
1831         $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timemodified');
1832         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'usercreated');
1833         $table->add_field('issuername', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'usermodified');
1834         $table->add_field('issuerurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'issuername');
1835         $table->add_field('issuercontact', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'issuerurl');
1836         $table->add_field('expiredate', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'issuercontact');
1837         $table->add_field('expireperiod', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'expiredate');
1838         $table->add_field('type', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'expireperiod');
1839         $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'type');
1840         $table->add_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'courseid');
1841         $table->add_field('messagesubject', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'message');
1842         $table->add_field('attachment', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'messagesubject');
1843         $table->add_field('notification', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'attachment');
1844         $table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'notification');
1845         $table->add_field('nextcron', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'status');
1847         // Adding keys to table 'badge'.
1848         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1849         $table->add_key('fk_courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
1850         $table->add_key('fk_usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
1851         $table->add_key('fk_usercreated', XMLDB_KEY_FOREIGN, array('usercreated'), 'user', array('id'));
1853         // Adding indexes to table 'badge'.
1854         $table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));
1856         // Conditionally launch create table for 'badge'.
1857         if (!$dbman->table_exists($table)) {
1858             $dbman->create_table($table);
1859         }
1861         // Define table 'badge_criteria' to be created.
1862         $table = new xmldb_table('badge_criteria');
1864         // Adding fields to table 'badge_criteria'.
1865         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1866         $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
1867         $table->add_field('criteriatype', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'badgeid');
1868         $table->add_field('method', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'criteriatype');
1870         // Adding keys to table 'badge_criteria'.
1871         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1872         $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
1874         // Adding indexes to table 'badge_criteria'.
1875         $table->add_index('criteriatype', XMLDB_INDEX_NOTUNIQUE, array('criteriatype'));
1876         $table->add_index('badgecriteriatype', XMLDB_INDEX_UNIQUE, array('badgeid', 'criteriatype'));
1878         // Conditionally launch create table for 'badge_criteria'.
1879         if (!$dbman->table_exists($table)) {
1880             $dbman->create_table($table);
1881         }
1883         // Define table 'badge_criteria_param' to be created.
1884         $table = new xmldb_table('badge_criteria_param');
1886         // Adding fields to table 'badge_criteria_param'.
1887         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1888         $table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
1889         $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'critid');
1890         $table->add_field('value', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name');
1892         // Adding keys to table 'badge_criteria_param'.
1893         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1894         $table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));
1896         // Conditionally launch create table for 'badge_criteria_param'.
1897         if (!$dbman->table_exists($table)) {
1898             $dbman->create_table($table);
1899         }
1901         // Define table 'badge_issued' to be created.
1902         $table = new xmldb_table('badge_issued');
1904         // Adding fields to table 'badge_issued'.
1905         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1906         $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
1907         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'badgeid');
1908         $table->add_field('uniquehash', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'userid');
1909         $table->add_field('dateissued', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'uniquehash');
1910         $table->add_field('dateexpire', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'dateissued');
1911         $table->add_field('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'dateexpire');
1912         $table->add_field('issuernotified', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'visible');
1914         // Adding keys to table 'badge_issued'.
1915         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1916         $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
1917         $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1919         $table->add_index('badgeuser', XMLDB_INDEX_UNIQUE, array('badgeid', 'userid'));
1921         // Conditionally launch create table for 'badge_issued'.
1922         if (!$dbman->table_exists($table)) {
1923             $dbman->create_table($table);
1924         }
1926         // Define table 'badge_criteria_met' to be created.
1927         $table = new xmldb_table('badge_criteria_met');
1929         // Adding fields to table 'badge_criteria_met'.
1930         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1931         $table->add_field('issuedid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'id');
1932         $table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuedid');
1933         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'critid');
1934         $table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
1936         // Adding keys to table 'badge_criteria_met'
1937         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1938         $table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));
1939         $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1940         $table->add_key('fk_issuedid', XMLDB_KEY_FOREIGN, array('issuedid'), 'badge_issued', array('id'));
1942         // Conditionally launch create table for 'badge_criteria_met'.
1943         if (!$dbman->table_exists($table)) {
1944             $dbman->create_table($table);
1945         }
1947         // Define table 'badge_manual_award' to be created.
1948         $table = new xmldb_table('badge_manual_award');
1950         // Adding fields to table 'badge_manual_award'.
1951         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1952         $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
1953         $table->add_field('recipientid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'badgeid');
1954         $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'recipientid');
1955         $table->add_field('issuerrole', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerid');
1956         $table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerrole');
1958         // Adding keys to table 'badge_manual_award'.
1959         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1960         $table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
1961         $table->add_key('fk_recipientid', XMLDB_KEY_FOREIGN, array('recipientid'), 'user', array('id'));
1962         $table->add_key('fk_issuerid', XMLDB_KEY_FOREIGN, array('issuerid'), 'user', array('id'));
1963         $table->add_key('fk_issuerrole', XMLDB_KEY_FOREIGN, array('issuerrole'), 'role', array('id'));
1965         // Conditionally launch create table for 'badge_manual_award'.
1966         if (!$dbman->table_exists($table)) {
1967             $dbman->create_table($table);
1968         }
1970         // Define table 'badge_backpack' to be created.
1971         $table = new xmldb_table('badge_backpack');
1973         // Adding fields to table 'badge_backpack'.
1974         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1975         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
1976         $table->add_field('email', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'userid');
1977         $table->add_field('backpackurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'email');
1978         $table->add_field('backpackuid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackurl');
1979         $table->add_field('backpackgid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackuid');
1980         $table->add_field('autosync', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'backpackgid');
1981         $table->add_field('password', XMLDB_TYPE_CHAR, '50', null, null, null, null, 'autosync');
1983         // Adding keys to table 'badge_backpack'.
1984         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1985         $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1987         // Conditionally launch create table for 'badge_backpack'.
1988         if (!$dbman->table_exists($table)) {
1989             $dbman->create_table($table);
1990         }
1992         // Main savepoint reached.
1993         upgrade_main_savepoint(true, 2013040200.00);
1994     }
1996     if ($oldversion < 2013040201.00) {
1997         // Convert name field in event table to text type as RFC-2445 doesn't have any limitation on it.
1998         $table = new xmldb_table('event');
1999         $field = new xmldb_field('name', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
2000         if ($dbman->field_exists($table, $field)) {
2001             $dbman->change_field_type($table, $field);
2002         }
2003         // Main savepoint reached.
2004         upgrade_main_savepoint(true, 2013040201.00);
2005     }
2007     if ($oldversion < 2013040300.01) {
2009         // Define field completionstartonenrol to be dropped from course.
2010         $table = new xmldb_table('course');
2011         $field = new xmldb_field('completionstartonenrol');
2013         // Conditionally launch drop field completionstartonenrol.
2014         if ($dbman->field_exists($table, $field)) {
2015             $dbman->drop_field($table, $field);
2016         }
2018         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
2019         $SITE = $DB->get_record('course', array('id' => $SITE->id));
2020         $COURSE = clone($SITE);
2022         // Main savepoint reached.
2023         upgrade_main_savepoint(true, 2013040300.01);
2024     }
2026     if ($oldversion < 2013041200.00) {
2027         // MDL-29877 Some bad restores created grade items with no category information.
2028         $sql = "UPDATE {grade_items}
2029                    SET categoryid = courseid
2030                  WHERE itemtype <> 'course' and itemtype <> 'category'
2031                        AND categoryid IS NULL";
2032         $DB->execute($sql);
2033         upgrade_main_savepoint(true, 2013041200.00);
2034     }
2036     if ($oldversion < 2013041600.00) {
2037         // Copy constants from /course/lib.php instead of including the whole library:
2038         $c = array( 'FRONTPAGENEWS'                 => 0,
2039                     'FRONTPAGECOURSELIST'           => 1,
2040                     'FRONTPAGECATEGORYNAMES'        => 2,
2041                     'FRONTPAGETOPICONLY'            => 3,
2042                     'FRONTPAGECATEGORYCOMBO'        => 4,
2043                     'FRONTPAGEENROLLEDCOURSELIST'   => 5,
2044                     'FRONTPAGEALLCOURSELIST'        => 6,
2045                     'FRONTPAGECOURSESEARCH'         => 7);
2046         // Update frontpage settings $CFG->frontpage and $CFG->frontpageloggedin. In 2.4 there was too much of hidden logic about them.
2047         // This script tries to make sure that with the new (more user-friendly) frontpage settings the frontpage looks as similar as possible to what it was before upgrade.
2048         $ncourses = $DB->count_records('course');
2049         foreach (array('frontpage', 'frontpageloggedin') as $configkey) {
2050             if ($frontpage = explode(',', $CFG->{$configkey})) {
2051                 $newfrontpage = array();
2052                 foreach ($frontpage as $v) {
2053                     switch ($v) {
2054                         case $c['FRONTPAGENEWS']:
2055                             // Not related to course listings, leave as it is.
2056                             $newfrontpage[] = $c['FRONTPAGENEWS'];
2057                             break;
2058                         case $c['FRONTPAGECOURSELIST']:
2059                             if ($configkey === 'frontpageloggedin' && empty($CFG->disablemycourses)) {
2060                                 // In 2.4 unless prohibited in config, the "list of courses" was considered "list of enrolled courses" plus course search box.
2061                                 $newfrontpage[] = $c['FRONTPAGEENROLLEDCOURSELIST'];
2062                             } else if ($ncourses <= 200) {
2063                                 // Still list of courses was only displayed in there were less than 200 courses in system. Otherwise - search box only.
2064                                 $newfrontpage[] = $c['FRONTPAGEALLCOURSELIST'];
2065                                 break; // skip adding search box
2066                             }
2067                             if (!in_array($c['FRONTPAGECOURSESEARCH'], $newfrontpage)) {
2068                                 $newfrontpage[] = $c['FRONTPAGECOURSESEARCH'];
2069                             }
2070                             break;
2071                         case $c['FRONTPAGECATEGORYNAMES']:
2072                             // In 2.4 search box was displayed automatically after categories list. In 2.5 it is displayed as a separate setting.
2073                             $newfrontpage[] = $c['FRONTPAGECATEGORYNAMES'];
2074                             if (!in_array($c['FRONTPAGECOURSESEARCH'], $newfrontpage)) {
2075                                 $newfrontpage[] = $c['FRONTPAGECOURSESEARCH'];
2076                             }
2077                             break;
2078                         case $c['FRONTPAGECATEGORYCOMBO']:
2079                             $maxcourses = empty($CFG->numcoursesincombo) ? 500 : $CFG->numcoursesincombo;
2080                             // In 2.4 combo list was not displayed if there are more than $CFG->numcoursesincombo courses in the system.
2081                             if ($ncourses < $maxcourses) {
2082                                 $newfrontpage[] = $c['FRONTPAGECATEGORYCOMBO'];
2083                             }
2084                             if (!in_array($c['FRONTPAGECOURSESEARCH'], $newfrontpage)) {
2085                                 $newfrontpage[] = $c['FRONTPAGECOURSESEARCH'];
2086                             }
2087                             break;
2088                     }
2089                 }
2090                 set_config($configkey, join(',', $newfrontpage));
2091             }
2092         }
2093         // $CFG->numcoursesincombo no longer affects whether the combo list is displayed. Setting is deprecated.
2094         unset_config('numcoursesincombo');
2096         upgrade_main_savepoint(true, 2013041600.00);
2097     }
2099     if ($oldversion < 2013041601.00) {
2100         // Create a new 'badge_external' table first.
2101         // Define table 'badge_external' to be created.
2102         $table = new xmldb_table('badge_external');
2104         // Adding fields to table 'badge_external'.
2105         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
2106         $table->add_field('backpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
2107         $table->add_field('collectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackid');
2109         // Adding keys to table 'badge_external'.
2110         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2111         $table->add_key('fk_backpackid', XMLDB_KEY_FOREIGN, array('backpackid'), 'badge_backpack', array('id'));
2113         // Conditionally launch create table for 'badge_external'.
2114         if (!$dbman->table_exists($table)) {
2115             $dbman->create_table($table);
2116         }
2118         // Perform user data migration.
2119         $usercollections = $DB->get_records('badge_backpack');
2120         foreach ($usercollections as $usercollection) {
2121             $collection = new stdClass();
2122             $collection->backpackid = $usercollection->id;
2123             $collection->collectionid = $usercollection->backpackgid;
2124             $DB->insert_record('badge_external', $collection);
2125         }
2127         // Finally, drop the column.
2128         // Define field backpackgid to be dropped from 'badge_backpack'.
2129         $table = new xmldb_table('badge_backpack');
2130         $field = new xmldb_field('backpackgid');
2132         // Conditionally launch drop field backpackgid.
2133         if ($dbman->field_exists($table, $field)) {
2134             $dbman->drop_field($table, $field);
2135         }
2137         // Main savepoint reached.
2138         upgrade_main_savepoint(true, 2013041601.00);
2139     }
2141     if ($oldversion < 2013041601.01) {
2142         // Changing the default of field descriptionformat on table user to 1.
2143         $table = new xmldb_table('user');
2144         $field = new xmldb_field('descriptionformat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1', 'description');
2146         // Launch change of default for field descriptionformat.
2147         $dbman->change_field_default($table, $field);
2149         // Main savepoint reached.
2150         upgrade_main_savepoint(true, 2013041601.01);
2151     }
2153     if ($oldversion < 2013041900.00) {
2154         require_once($CFG->dirroot . '/cache/locallib.php');
2155         // The features bin needs updating.
2156         cache_config_writer::update_default_config_stores();
2157         // Main savepoint reached.
2158         upgrade_main_savepoint(true, 2013041900.00);
2159     }
2161     if ($oldversion < 2013042300.00) {
2162         // Adding index to unreadmessageid field of message_working table (MDL-34933)
2163         $table = new xmldb_table('message_working');
2164         $index = new xmldb_index('unreadmessageid_idx', XMLDB_INDEX_NOTUNIQUE, array('unreadmessageid'));
2166         // Conditionally launch add index unreadmessageid
2167         if (!$dbman->index_exists($table, $index)) {
2168             $dbman->add_index($table, $index);
2169         }
2171         // Main savepoint reached.
2172         upgrade_main_savepoint(true, 2013042300.00);
2173     }
2175     // Moodle v2.5.0 release upgrade line.
2176     // Put any upgrade step following this.
2178     if ($oldversion < 2013051400.01) {
2179         // Fix incorrect cc-nc url. Unfortunately the license 'plugins' do
2180         // not give a mechanism to do this.
2182         $sql = "UPDATE {license}
2183                    SET source = :url, version = :newversion
2184                  WHERE shortname = :shortname AND version = :oldversion";
2186         $params = array(
2187             'url' => 'http://creativecommons.org/licenses/by-nc/3.0/',
2188             'shortname' => 'cc-nc',
2189             'newversion' => '2013051500',
2190             'oldversion' => '2010033100'
2191         );
2193         $DB->execute($sql, $params);
2195         // Main savepoint reached.
2196         upgrade_main_savepoint(true, 2013051400.01);
2197     }
2199     if ($oldversion < 2013061400.01) {
2200         // Clean up old tokens which haven't been deleted.
2201         $DB->execute("DELETE FROM {user_private_key} WHERE NOT EXISTS
2202                          (SELECT 'x' FROM {user} WHERE deleted = 0 AND id = userid)");
2204         // Main savepoint reached.
2205         upgrade_main_savepoint(true, 2013061400.01);
2206     }
2208     if ($oldversion < 2013061700.00) {
2209         // MDL-40103: Remove unused template tables from the database.
2210         // These are now created inline with xmldb_table.
2212         $tablestocleanup = array('temp_enroled_template','temp_log_template','backup_files_template','backup_ids_template');
2213         $dbman = $DB->get_manager();
2215         foreach ($tablestocleanup as $table) {
2216             $xmltable = new xmldb_table($table);
2217             if ($dbman->table_exists($xmltable)) {
2218                 $dbman->drop_table($xmltable);
2219             }
2220         }
2222         // Main savepoint reached.
2223         upgrade_main_savepoint(true, 2013061700.00);
2224     }
2226     if ($oldversion < 2013070800.00) {
2228         // Remove orphan repository instances.
2229         if ($DB->get_dbfamily() === 'mysql') {
2230             $sql = "DELETE {repository_instances} FROM {repository_instances}
2231                     LEFT JOIN {context} ON {context}.id = {repository_instances}.contextid
2232                     WHERE {context}.id IS NULL";
2233         } else {
2234             $sql = "DELETE FROM {repository_instances}
2235                     WHERE NOT EXISTS (
2236                         SELECT 'x' FROM {context}
2237                         WHERE {context}.id = {repository_instances}.contextid)";
2238         }
2239         $DB->execute($sql);
2241         // Main savepoint reached.
2242         upgrade_main_savepoint(true, 2013070800.00);
2243     }
2245     if ($oldversion < 2013070800.01) {
2247         // Define field lastnamephonetic to be added to user.
2248         $table = new xmldb_table('user');
2249         $field = new xmldb_field('lastnamephonetic', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'imagealt');
2250         $index = new xmldb_index('lastnamephonetic', XMLDB_INDEX_NOTUNIQUE, array('lastnamephonetic'));
2252         // Conditionally launch add field lastnamephonetic.
2253         if (!$dbman->field_exists($table, $field)) {
2254             $dbman->add_field($table, $field);
2255             $dbman->add_index($table, $index);
2256         }
2258         // Define field firstnamephonetic to be added to user.
2259         $table = new xmldb_table('user');
2260         $field = new xmldb_field('firstnamephonetic', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'lastnamephonetic');
2261         $index = new xmldb_index('firstnamephonetic', XMLDB_INDEX_NOTUNIQUE, array('firstnamephonetic'));
2263         // Conditionally launch add field firstnamephonetic.
2264         if (!$dbman->field_exists($table, $field)) {
2265             $dbman->add_field($table, $field);
2266             $dbman->add_index($table, $index);
2267         }
2269         // Define field alternatename to be added to user.
2270         $table = new xmldb_table('user');
2271         $field = new xmldb_field('middlename', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'firstnamephonetic');
2272         $index = new xmldb_index('middlename', XMLDB_INDEX_NOTUNIQUE, array('middlename'));
2274         // Conditionally launch add field firstnamephonetic.
2275         if (!$dbman->field_exists($table, $field)) {
2276             $dbman->add_field($table, $field);
2277             $dbman->add_index($table, $index);
2278         }
2280         // Define field alternatename to be added to user.
2281         $table = new xmldb_table('user');
2282         $field = new xmldb_field('alternatename', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'middlename');
2283         $index = new xmldb_index('alternatename', XMLDB_INDEX_NOTUNIQUE, array('alternatename'));
2285         // Conditionally launch add field alternatename.
2286         if (!$dbman->field_exists($table, $field)) {
2287             $dbman->add_field($table, $field);
2288             $dbman->add_index($table, $index);
2289         }
2291         // Main savepoint reached.
2292         upgrade_main_savepoint(true, 2013070800.01);
2293     }
2294     if ($oldversion < 2013071500.01) {
2295         // The enrol_authorize plugin has been removed, if there are no records
2296         // and no plugin files then remove the plugin data.
2297         $enrolauthorize = new xmldb_table('enrol_authorize');
2298         $enrolauthorizerefunds = new xmldb_table('enrol_authorize_refunds');
2300         if (!file_exists($CFG->dirroot.'/enrol/authorize/version.php') &&
2301             $dbman->table_exists($enrolauthorize) &&
2302             $dbman->table_exists($enrolauthorizerefunds)) {
2304             $enrolauthorizecount = $DB->count_records('enrol_authorize');
2305             $enrolauthorizerefundcount = $DB->count_records('enrol_authorize_refunds');
2307             if (empty($enrolauthorizecount) && empty($enrolauthorizerefundcount)) {
2309                 // Drop the database tables.
2310                 $dbman->drop_table($enrolauthorize);
2311                 $dbman->drop_table($enrolauthorizerefunds);
2313                 // Drop the message provider and associated data manually.
2314                 $DB->delete_records('message_providers', array('component' => 'enrol_authorize'));
2315                 $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("%_provider_enrol_authorize_%"));
2316                 $DB->delete_records_select('user_preferences', $DB->sql_like('name', '?', false), array("message_provider_enrol_authorize_%"));
2318                 // Remove capabilities.
2319                 capabilities_cleanup('enrol_authorize');
2321                 // Remove all other associated config.
2322                 unset_all_config_for_plugin('enrol_authorize');
2323             }
2324         }
2325         upgrade_main_savepoint(true, 2013071500.01);
2326     }
2328     if ($oldversion < 2013071500.02) {
2329         // Define field attachment to be dropped from badge.
2330         $table = new xmldb_table('badge');
2331         $field = new xmldb_field('image');
2333         // Conditionally launch drop field eventtype.
2334         if ($dbman->field_exists($table, $field)) {
2335             $dbman->drop_field($table, $field);
2336         }
2338         upgrade_main_savepoint(true, 2013071500.02);
2339     }
2341     if ($oldversion < 2013072600.01) {
2342         upgrade_mssql_nvarcharmax();
2343         upgrade_mssql_varbinarymax();
2345         upgrade_main_savepoint(true, 2013072600.01);
2346     }
2348     if ($oldversion < 2013081200.00) {
2349         // Define field uploadfiles to be added to external_services.
2350         $table = new xmldb_table('external_services');
2351         $field = new xmldb_field('uploadfiles', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'downloadfiles');
2353         // Conditionally launch add field uploadfiles.
2354         if (!$dbman->field_exists($table, $field)) {
2355             $dbman->add_field($table, $field);
2356         }
2358         // Main savepoint reached.
2359         upgrade_main_savepoint(true, 2013081200.00);
2360     }
2362     if ($oldversion < 2013082300.01) {
2363         // Define the table 'backup_logs' and the field 'message' which we will be changing from a char to a text field.
2364         $table = new xmldb_table('backup_logs');
2365         $field = new xmldb_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'loglevel');
2367         // Perform the change.
2368         $dbman->change_field_type($table, $field);
2370         // Main savepoint reached.
2371         upgrade_main_savepoint(true, 2013082300.01);
2372     }
2374     // Convert SCORM course format courses to singleactivity.
2375     if ($oldversion < 2013082700.00) {
2376         // First set relevant singleactivity settings.
2377         $formatoptions = new stdClass();
2378         $formatoptions->format = 'singleactivity';
2379         $formatoptions->sectionid = 0;
2380         $formatoptions->name = 'activitytype';
2381         $formatoptions->value = 'scorm';
2383         $courses = $DB->get_recordset('course', array('format' => 'scorm'), 'id');
2384         foreach ($courses as $course) {
2385             $formatoptions->courseid = $course->id;
2386             $DB->insert_record('course_format_options', $formatoptions);
2387         }
2388         $courses->close();
2390         // Now update course format for these courses.
2391         $sql = "UPDATE {course}
2392                    SET format = 'singleactivity', modinfo = '', sectioncache = ''
2393                  WHERE format = 'scorm'";
2394         $DB->execute($sql);
2395         upgrade_main_savepoint(true, 2013082700.00);
2396     }
2398     if ($oldversion < 2013090500.01) {
2399         // Define field calendartype to be added to course.
2400         $table = new xmldb_table('course');
2401         $field = new xmldb_field('calendartype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null);
2403         // Conditionally launch add field calendartype.
2404         if (!$dbman->field_exists($table, $field)) {
2405             $dbman->add_field($table, $field);
2406         }
2408         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
2409         $SITE = $DB->get_record('course', array('id' => $SITE->id));
2410         $COURSE = clone($SITE);
2412         // Define field calendartype to be added to user.
2413         $table = new xmldb_table('user');
2414         $field = new xmldb_field('calendartype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, 'gregorian');
2416         // Conditionally launch add field calendartype.
2417         if (!$dbman->field_exists($table, $field)) {
2418             $dbman->add_field($table, $field);
2419         }
2421         // Main savepoint reached.
2422         upgrade_main_savepoint(true, 2013090500.01);
2423     }
2425     if ($oldversion < 2013091000.02) {
2427         // Define field cacherev to be added to course.
2428         $table = new xmldb_table('course');
2429         $field = new xmldb_field('cacherev', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'completionnotify');
2431         // Conditionally launch add field cacherev.
2432         if (!$dbman->field_exists($table, $field)) {
2433             $dbman->add_field($table, $field);
2434         }
2436         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
2437         $SITE = $DB->get_record('course', array('id' => $SITE->id));
2438         $COURSE = clone($SITE);
2440         // Main savepoint reached.
2441         upgrade_main_savepoint(true, 2013091000.02);
2442     }
2444     if ($oldversion < 2013091000.03) {
2446         // Define field modinfo to be dropped from course.
2447         $table = new xmldb_table('course');
2448         $field = new xmldb_field('modinfo');
2450         // Conditionally launch drop field modinfo.
2451         if ($dbman->field_exists($table, $field)) {
2452             $dbman->drop_field($table, $field);
2453         }
2455         // Define field sectioncache to be dropped from course.
2456         $field = new xmldb_field('sectioncache');
2458         // Conditionally launch drop field sectioncache.
2459         if ($dbman->field_exists($table, $field)) {
2460             $dbman->drop_field($table, $field);
2461         }
2463         // Since structure of 'course' table has changed we need to re-read $SITE from DB.
2464         $SITE = $DB->get_record('course', array('id' => $SITE->id));
2465         $COURSE = clone($SITE);
2467         // Main savepoint reached.
2468         upgrade_main_savepoint(true, 2013091000.03);
2469     }
2471     if ($oldversion < 2013091300.01) {
2473         $table = new xmldb_table('user');
2475         // Changing precision of field institution on table user to (255).
2476         $field = new xmldb_field('institution', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'phone2');
2478         // Launch change of precision for field institution.
2479         $dbman->change_field_precision($table, $field);
2481         // Changing precision of field department on table user to (255).
2482         $field = new xmldb_field('department', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'institution');
2484         // Launch change of precision for field department.
2485         $dbman->change_field_precision($table, $field);
2487         // Changing precision of field address on table user to (255).
2488         $field = new xmldb_field('address', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'department');
2490         // Launch change of precision for field address.
2491         $dbman->change_field_precision($table, $field);
2493         // Main savepoint reached.
2494         upgrade_main_savepoint(true, 2013091300.01);
2495     }
2497     if ($oldversion < 2013092000.01) {
2499         // Define table question_statistics to be created.
2500         $table = new xmldb_table('question_statistics');
2502         // Adding fields to table question_statistics.
2503         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2504         $table->add_field('hashcode', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
2505         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2506         $table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2507         $table->add_field('slot', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2508         $table->add_field('subquestion', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
2509         $table->add_field('s', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2510         $table->add_field('effectiveweight', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
2511         $table->add_field('negcovar', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
2512         $table->add_field('discriminationindex', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
2513         $table->add_field('discriminativeefficiency', XMLDB_TYPE_NUMBER, '15, 5', null, null, null, null);
2514         $table->add_field('sd', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
2515         $table->add_field('facility', XMLDB_TYPE_NUMBER, '15, 10', null, null, null, null);
2516         $table->add_field('subquestions', XMLDB_TYPE_TEXT, null, null, null, null, null);
2517         $table->add_field('maxmark', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null);
2518         $table->add_field('positions', XMLDB_TYPE_TEXT, null, null, null, null, null);
2519         $table->add_field('randomguessscore', XMLDB_TYPE_NUMBER, '12, 7', null, null, null, null);
2521         // Adding keys to table question_statistics.
2522         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2524         // Conditionally launch create table for question_statistics.
2525         if (!$dbman->table_exists($table)) {
2526             $dbman->create_table($table);
2527         }
2529         // Define table question_response_analysis to be created.
2530         $table = new xmldb_table('question_response_analysis');
2532         // Adding fields to table question_response_analysis.
2533         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2534         $table->add_field('hashcode', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
2535         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2536         $table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2537         $table->add_field('subqid', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2538         $table->add_field('aid', XMLDB_TYPE_CHAR, '100', null, null, null, null);
2539         $table->add_field('response', XMLDB_TYPE_TEXT, null, null, null, null, null);
2540         $table->add_field('rcount', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2541         $table->add_field('credit', XMLDB_TYPE_NUMBER, '15, 5', null, XMLDB_NOTNULL, null, null);
2543         // Adding keys to table question_response_analysis.
2544         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2546         // Conditionally launch create table for question_response_analysis.
2547         if (!$dbman->table_exists($table)) {
2548             $dbman->create_table($table);
2549         }
2551         // Main savepoint reached.
2552         upgrade_main_savepoint(true, 2013092000.01);
2553     }
2555     if ($oldversion < 2013092001.01) {
2556         // Force uninstall of deleted tool.
2557         if (!file_exists("$CFG->dirroot/$CFG->admin/tool/bloglevelupgrade")) {
2558             // Remove capabilities.
2559             capabilities_cleanup('tool_bloglevelupgrade');
2560             // Remove all other associated config.
2561             unset_all_config_for_plugin('tool_bloglevelupgrade');
2562         }
2563         upgrade_main_savepoint(true, 2013092001.01);
2564     }
2566     if ($oldversion < 2013092001.02) {
2567         // Define field version to be dropped from modules.
2568         $table = new xmldb_table('modules');
2569         $field = new xmldb_field('version');
2571         // Conditionally launch drop field version.
2572         if ($dbman->field_exists($table, $field)) {
2573             // Migrate all plugin version info to config_plugins table.
2574             $modules = $DB->get_records('modules');
2575             foreach ($modules as $module) {
2576                 set_config('version', $module->version, 'mod_'.$module->name);
2577             }
2578             unset($modules);
2580             $dbman->drop_field($table, $field);
2581         }
2583         // Define field version to be dropped from block.
2584         $table = new xmldb_table('block');
2585         $field = new xmldb_field('version');
2587         // Conditionally launch drop field version.
2588         if ($dbman->field_exists($table, $field)) {
2589             $blocks = $DB->get_records('block');
2590             foreach ($blocks as $block) {
2591                 set_config('version', $block->version, 'block_'.$block->name);
2592             }
2593             unset($blocks);
2595             $dbman->drop_field($table, $field);
2596         }
2598         // Main savepoint reached.
2599         upgrade_main_savepoint(true, 2013092001.02);
2600     }
2602     if ($oldversion < 2013092700.01) {
2604         $table = new xmldb_table('files');
2606         // Define field referencelastsync to be dropped from files.
2607         $field = new xmldb_field('referencelastsync');
2609         // Conditionally launch drop field referencelastsync.
2610         if ($dbman->field_exists($table, $field)) {
2611             $dbman->drop_field($table, $field);
2612         }
2614         // Define field referencelifetime to be dropped from files.
2615         $field = new xmldb_field('referencelifetime');
2617         // Conditionally launch drop field referencelifetime.
2618         if ($dbman->field_exists($table, $field)) {
2619             $dbman->drop_field($table, $field);
2620         }
2622         // Main savepoint reached.
2623         upgrade_main_savepoint(true, 2013092700.01);
2624     }
2626     if ($oldversion < 2013100400.01) {
2627         // Add user_devices core table.
2629         // Define field id to be added to user_devices.
2630         $table = new xmldb_table('user_devices');
2632         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
2633         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
2634         $table->add_field('appid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null, 'userid');
2635         $table->add_field('name', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'appid');
2636         $table->add_field('model', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'name');
2637         $table->add_field('platform', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'model');
2638         $table->add_field('version', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, 'platform');
2639         $table->add_field('pushid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'version');
2640         $table->add_field('uuid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'pushid');
2641         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'uuid');
2642         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timecreated');
2644         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2645         $table->add_key('pushid-userid', XMLDB_KEY_UNIQUE, array('pushid', 'userid'));
2646         $table->add_key('pushid-platform', XMLDB_KEY_UNIQUE, array('pushid', 'platform'));
2647         $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
2649         if (!$dbman->table_exists($table)) {
2650             $dbman->create_table($table);
2651         }
2653         // Main savepoint reached.
2654         upgrade_main_savepoint(true, 2013100400.01);
2655     }
2657     if ($oldversion < 2013100800.00) {
2659         // Define field maxfraction to be added to question_attempts.
2660         $table = new xmldb_table('question_attempts');
2661         $field = new xmldb_field('maxfraction', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '1', 'minfraction');
2663         // Conditionally launch add field maxfraction.
2664         if (!$dbman->field_exists($table, $field)) {
2665             $dbman->add_field($table, $field);
2666         }
2668         // Main savepoint reached.
2669         upgrade_main_savepoint(true, 2013100800.00);
2670     }
2672     if ($oldversion < 2013100800.01) {
2673         // Create a new 'user_password_resets' table.
2674         $table = new xmldb_table('user_password_resets');
2675         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
2676         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null);
2677         $table->add_field('timerequested', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null);
2678         $table->add_field('timererequested', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0, null);
2679         $table->add_field('token', XMLDB_TYPE_CHAR, '32', null, XMLDB_NOTNULL, null, null, null);
2681         // Adding keys to table.
2682         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2683         $table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
2685         // Conditionally launch create table.
2686         if (!$dbman->table_exists($table)) {
2687             $dbman->create_table($table);
2688         }
2689         upgrade_main_savepoint(true, 2013100800.01);
2690     }
2692     if ($oldversion < 2013100800.02) {
2693         $sql = "INSERT INTO {user_preferences}(userid, name, value)
2694                 SELECT id, 'htmleditor', 'textarea' FROM {user} u where u.htmleditor = 0";
2695         $DB->execute($sql);
2697         // Define field htmleditor to be dropped from user
2698         $table = new xmldb_table('user');
2699         $field = new xmldb_field('htmleditor');
2701         // Conditionally launch drop field requested
2702         if ($dbman->field_exists($table, $field)) {
2703             $dbman->drop_field($table, $field);
2704         }
2705         // Main savepoint reached.
2706         upgrade_main_savepoint(true, 2013100800.02);
2707     }
2709     if ($oldversion < 2013100900.00) {
2711         // Define field lifetime to be dropped from files_reference.
2712         $table = new xmldb_table('files_reference');
2713         $field = new xmldb_field('lifetime');
2715         // Conditionally launch drop field lifetime.
2716         if ($dbman->field_exists($table, $field)) {
2717             $dbman->drop_field($table, $field);
2718         }
2720         // Main savepoint reached.
2721         upgrade_main_savepoint(true, 2013100900.00);
2722     }
2724     if ($oldversion < 2013100901.00) {
2725         // Fixing possible wrong MIME type for Java Network Launch Protocol (JNLP) files.
2726         $select = $DB->sql_like('filename', '?', false);
2727         $DB->set_field_select(
2728             'files',
2729             'mimetype',
2730             'application/x-java-jnlp-file',
2731             $select,
2732             array('%.jnlp')
2733         );
2735         // Main savepoint reached.
2736         upgrade_main_savepoint(true, 2013100901.00);
2737     }
2739     if ($oldversion < 2013102100.00) {
2740         // Changing default value for the status of a course backup.
2741         $table = new xmldb_table('backup_courses');
2742         $field = new xmldb_field('laststatus', XMLDB_TYPE_CHAR, '1', null, XMLDB_NOTNULL, null, '5', 'lastendtime');
2744         // Launch change of precision for field value
2745         $dbman->change_field_precision($table, $field);
2747         // Main savepoint reached.
2748         upgrade_main_savepoint(true, 2013102100.00);
2749     }
2751     if ($oldversion < 2013102201.00) {
2752         $params = array('plugin' => 'editor_atto', 'name' => 'version');
2753         $attoversion = $DB->get_record('config_plugins',
2754                                        $params,
2755                                        'value',
2756                                        IGNORE_MISSING);
2758         if ($attoversion) {
2759             $attoversion = floatval($attoversion->value);
2760         }
2761         // Only these versions that were part of 2.6 beta should be removed.
2762         // Manually installed versions of 2.5 - or later releases for 2.6 installed
2763         // via the plugins DB should not be uninstalled.
2764         if ($attoversion && $attoversion > 2013051500.00 && $attoversion < 2013102201.00) {
2765             // Remove all other associated config.
2766             unset_all_config_for_plugin('editor_atto');
2767             unset_all_config_for_plugin('atto_bold');
2768             unset_all_config_for_plugin('atto_clear');
2769             unset_all_config_for_plugin('atto_html');
2770             unset_all_config_for_plugin('atto_image');
2771             unset_all_config_for_plugin('atto_indent');
2772             unset_all_config_for_plugin('atto_italic');
2773             unset_all_config_for_plugin('atto_link');
2774             unset_all_config_for_plugin('atto_media');
2775             unset_all_config_for_plugin('atto_orderedlist');
2776             unset_all_config_for_plugin('atto_outdent');
2777             unset_all_config_for_plugin('atto_strike');
2778             unset_all_config_for_plugin('atto_title');
2779             unset_all_config_for_plugin('atto_underline');
2780             unset_all_config_for_plugin('atto_unlink');
2781             unset_all_config_for_plugin('atto_unorderedlist');
2783         }
2785         // Main savepoint reached.
2786         upgrade_main_savepoint(true, 2013102201.00);
2787     }
2789     if ($oldversion < 2013102500.01) {
2790         // Find all fileareas that have missing root folder entry and add the root folder entry.
2791         if (empty($CFG->filesrootrecordsfixed)) {
2792             upgrade_fix_missing_root_folders();
2793             // To skip running the same script on the upgrade to the next major release.
2794             set_config('filesrootrecordsfixed', 1);
2795         }
2797         // Main savepoint reached.
2798         upgrade_main_savepoint(true, 2013102500.01);
2799     }
2801     if ($oldversion < 2013110500.01) {
2802         // MDL-38228. Corrected course_modules upgrade script instead of 2013021801.01.
2804         // This upgrade script fixes the mismatches between DB fields course_modules.section
2805         // and course_sections.sequence. It makes sure that each module is included
2806         // in the sequence of at least one section.
2807         // There is also a separate script for admins: admin/cli/fix_course_sortorder.php
2809         // This script in included in each major version upgrade process so make sure we don't run it twice.
2810         if (empty($CFG->movingmoduleupgradescriptwasrun)) {
2811             upgrade_course_modules_sequences();
2813             // To skip running the same script on the upgrade to the next major release.
2814             set_config('movingmoduleupgradescriptwasrun', 1);
2815         }
2817         // Main savepoint reached.
2818         upgrade_main_savepoint(true, 2013110500.01);
2819     }
2821     if ($oldversion < 2013110600.01) {
2823         if (!file_exists($CFG->dirroot . '/theme/mymobile')) {
2824             // Replace the mymobile settings.
2825             $DB->set_field('course', 'theme', 'clean', array('theme' => 'mymobile'));
2826             $DB->set_field('course_categories', 'theme', 'clean', array('theme' => 'mymobile'));
2827             $DB->set_field('user', 'theme', 'clean', array('theme' => 'mymobile'));
2828             $DB->set_field('mnet_host', 'theme', 'clean', array('theme' => 'mymobile'));
2830             // Replace the theme configs.
2831             if (get_config('core', 'theme') === 'mymobile') {
2832                 set_config('theme', 'clean');
2833             }
2834             if (get_config('core', 'thememobile') === 'mymobile') {
2835                 set_config('thememobile', 'clean');
2836             }
2837             if (get_config('core', 'themelegacy') === 'mymobile') {
2838                 set_config('themelegacy', 'clean');
2839             }
2840             if (get_config('core', 'themetablet') === 'mymobile') {
2841                 set_config('themetablet', 'clean');
2842             }
2844             // Hacky emulation of plugin uninstallation.
2845             unset_all_config_for_plugin('theme_mymobile');
2846         }
2848         // Main savepoint reached.
2849         upgrade_main_savepoint(true, 2013110600.01);
2850     }
2852     if ($oldversion < 2013110600.02) {
2854         // If the user is logged in, we ensure that the alternate name fields are present
2855         // in the session. It will not be the case when upgrading from 2.5 downwards.
2856         if (!empty($USER->id)) {
2857             $refreshuser = $DB->get_record('user', array('id' => $USER->id));
2858             $fields = array('firstnamephonetic', 'lastnamephonetic', 'middlename', 'alternatename', 'firstname', 'lastname');
2859             foreach ($fields as $field) {
2860                 $USER->{$field} = $refreshuser->{$field};
2861             }
2862         }
2864         // Main savepoint reached.
2865         upgrade_main_savepoint(true, 2013110600.02);
2866     }
2868     // Moodle v2.6.0 release upgrade line.
2869     // Put any upgrade step following this.
2870     if ($oldversion < 2013111800.01) {
2872         // Delete notes of deleted courses.
2873         $sql = "DELETE FROM {post}
2874                  WHERE NOT EXISTS (SELECT {course}.id FROM {course}
2875                                     WHERE {course}.id = {post}.courseid)
2876                        AND {post}.module = ?";
2877         $DB->execute($sql, array('notes'));
2879         // Main savepoint reached.
2880         upgrade_main_savepoint(true, 2013111800.01);
2881     }
2883     if ($oldversion < 2013122400.01) {
2884         // Purge stored passwords from config_log table, ideally this should be in each plugin
2885         // but that would complicate backporting...
2886         $items = array(
2887             'core/cronremotepassword', 'core/proxypassword', 'core/smtppass', 'core/jabberpassword',
2888             'enrol_database/dbpass', 'enrol_ldap/bind_pw', 'url/secretphrase');
2889         foreach ($items as $item) {
2890             list($plugin, $name) = explode('/', $item);
2891             $sqlcomparevalue =  $DB->sql_compare_text('value');
2892             $sqlcompareoldvalue = $DB->sql_compare_text('oldvalue');
2893             if ($plugin === 'core') {
2894                 $sql = "UPDATE {config_log}
2895                            SET value = :value
2896                          WHERE name = :name AND plugin IS NULL AND $sqlcomparevalue <> :empty";
2897                 $params = array('value' => '********', 'name' => $name, 'empty' => '');
2898                 $DB->execute($sql, $params);
2900                 $sql = "UPDATE {config_log}
2901                            SET oldvalue = :value
2902                          WHERE name = :name AND plugin IS NULL AND $sqlcompareoldvalue <> :empty";
2903                 $params = array('value' => '********', 'name' => $name, 'empty' => '');
2904                 $DB->execute($sql, $params);
2906             } else {
2907                 $sql = "UPDATE {config_log}
2908                            SET value = :value
2909                          WHERE name = :name AND plugin = :plugin AND $sqlcomparevalue <> :empty";
2910                 $params = array('value' => '********', 'name' => $name, 'plugin' => $plugin, 'empty' => '');
2911                 $DB->execute($sql, $params);
2913                 $sql = "UPDATE {config_log}
2914                            SET oldvalue = :value
2915                          WHERE name = :name AND plugin = :plugin AND  $sqlcompareoldvalue <> :empty";
2916                 $params = array('value' => '********', 'name' => $name, 'plugin' => $plugin, 'empty' => '');
2917                 $DB->execute($sql, $params);
2918             }
2919         }
2920         // Main savepoint reached.
2921         upgrade_main_savepoint(true, 2013122400.01);
2922     }
2924     if ($oldversion < 2014011000.01) {
2926         // Define table cache_text to be dropped.
2927         $table = new xmldb_table('cache_text');
2929         // Conditionally launch drop table for cache_text.
2930         if ($dbman->table_exists($table)) {
2931             $dbman->drop_table($table);
2932         }
2934         unset_config('cachetext');
2936         // Main savepoint reached.
2937         upgrade_main_savepoint(true, 2014011000.01);
2938     }
2940     if ($oldversion < 2014011701.00) {
2941         // Fix gradebook sortorder duplicates.
2942         upgrade_grade_item_fix_sortorder();
2944         // Main savepoint reached.
2945         upgrade_main_savepoint(true, 2014011701.00);
2946     }
2948     if ($oldversion < 2014012300.01) {
2949         // Remove deleted users home pages.
2950         $sql = "DELETE FROM {my_pages}
2951                 WHERE EXISTS (SELECT {user}.id
2952                                   FROM {user}
2953                                   WHERE {user}.id = {my_pages}.userid
2954                                   AND {user}.deleted = 1)
2955                 AND {my_pages}.private = 1";
2956         $DB->execute($sql);
2958         // Reached main savepoint.
2959         upgrade_main_savepoint(true, 2014012300.01);
2960     }
2962     if ($oldversion < 2014012400.00) {
2963         // Define table lock_db to be created.
2964         $table = new xmldb_table('lock_db');
2966         // Adding fields to table lock_db.
2967         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2968         $table->add_field('resourcekey', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2969         $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2970         $table->add_field('owner', XMLDB_TYPE_CHAR, '36', null, null, null, null);
2972         // Adding keys to table lock_db.
2973         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2975         // Adding indexes to table lock_db.
2976         $table->add_index('resourcekey_uniq', XMLDB_INDEX_UNIQUE, array('resourcekey'));
2977         $table->add_index('expires_idx', XMLDB_INDEX_NOTUNIQUE, array('expires'));
2978         $table->add_index('owner_idx', XMLDB_INDEX_NOTUNIQUE, array('owner'));
2980         // Conditionally launch create table for lock_db.
2981         if (!$dbman->table_exists($table)) {
2982             $dbman->create_table($table);
2983         }
2985         // Main savepoint reached.
2986         upgrade_main_savepoint(true, 2014012400.00);
2987     }
2989     if ($oldversion < 2014021300.01) {
2990         // Delete any cached stats to force recalculation later, then we can be sure that cached records will have the correct
2991         // field.
2992         $DB->delete_records('question_response_analysis');
2993         $DB->delete_records('question_statistics');
2994         $DB->delete_records('quiz_statistics');
2996         // Define field variant to be added to question_statistics.
2997         $table = new xmldb_table('question_statistics');
2998         $field = new xmldb_field('variant', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'subquestion');
3000         // Conditionally launch add field variant.
3001         if (!$dbman->field_exists($table, $field)) {
3002             $dbman->add_field($table, $field);
3003         }
3005         // Main savepoint reached.
3006         upgrade_main_savepoint(true, 2014021300.01);
3007     }
3009     if ($oldversion < 2014021300.02) {
3011         // Define field variant to be added to question_response_analysis.
3012         $table = new xmldb_table('question_response_analysis');
3013         $field = new xmldb_field('variant', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'questionid');
3015         // Conditionally launch add field variant.
3016         if (!$dbman->field_exists($table, $field)) {
3017             $dbman->add_field($table, $field);
3018         }
3020         // Main savepoint reached.
3021         upgrade_main_savepoint(true, 2014021300.02);
3022     }
3024     if ($oldversion < 2014021800.00) {
3026         // Define field queued to be added to portfolio_tempdata.
3027         $table = new xmldb_table('portfolio_tempdata');
3028         $field = new xmldb_field('queued', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'instance');
3030         // Conditionally launch add field queued.
3031         if (!$dbman->field_exists($table, $field)) {
3032             $dbman->add_field($table, $field);
3033         }
3035         // Main savepoint reached.
3036         upgrade_main_savepoint(true, 2014021800.00);
3037     }
3039     if ($oldversion < 2014021900.01) {
3040         // Force uninstall of deleted tool.
3042         // Normally, in this sort of situation, we would do a file_exists check,
3043         // in case the plugin had been added back as an add-on. However, this
3044         // plugin is completely useless after Moodle 2.6, so we check that the
3045         // files have been removed in upgrade_stale_php_files_present, and we
3046         // uninstall it unconditionally here.
3048         // Remove all associated config.
3049         unset_all_config_for_plugin('tool_qeupgradehelper');
3051         upgrade_main_savepoint(true, 2014021900.01);
3052     }
3054     if ($oldversion < 2014021900.02) {
3056         // Define table question_states to be dropped.
3057         $table = new xmldb_table('question_states');
3059         // Conditionally launch drop table for question_states.
3060         if ($dbman->table_exists($table)) {
3061             $dbman->drop_table($table);
3062         }
3064         // Main savepoint reached.
3065         upgrade_main_savepoint(true, 2014021900.02);
3066     }
3068     if ($oldversion < 2014021900.03) {
3070         // Define table question_sessions to be dropped.
3071         $table = new xmldb_table('question_sessions');
3073         // Conditionally launch drop table for question_sessions.
3074         if ($dbman->table_exists($table)) {
3075             $dbman->drop_table($table);
3076         }
3078         // Main savepoint reached.
3079         upgrade_main_savepoint(true, 2014021900.03);
3080     }
3082     if ($oldversion < 2014022600.00) {
3083         $table = new xmldb_table('task_scheduled');
3085         // Adding fields to table task_scheduled.
3086         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3087         $table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3088         $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3089         $table->add_field('lastruntime', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
3090         $table->add_field('nextruntime', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
3091         $table->add_field('blocking', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
3092         $table->add_field('minute', XMLDB_TYPE_CHAR, '25', null, XMLDB_NOTNULL, null, null);
3093         $table->add_field('hour', XMLDB_TYPE_CHAR, '25', null, XMLDB_NOTNULL, null, null);
3094         $table->add_field('day', XMLDB_TYPE_CHAR, '25', null, XMLDB_NOTNULL, null, null);
3095         $table->add_field('month', XMLDB_TYPE_CHAR, '25', null, XMLDB_NOTNULL, null, null);
3096         $table->add_field('dayofweek', XMLDB_TYPE_CHAR, '25', null, XMLDB_NOTNULL, null, null);
3097         $table->add_field('faildelay', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
3098         $table->add_field('customised', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
3099         $table->add_field('disabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
3101         // Adding keys to table task_scheduled.
3102         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3104         // Adding indexes to table task_scheduled.
3105         $table->add_index('classname_uniq', XMLDB_INDEX_UNIQUE, array('classname'));
3107         // Conditionally launch create table for task_scheduled.
3108         if (!$dbman->table_exists($table)) {
3109             $dbman->create_table($table);
3110         }
3112         // Define table task_adhoc to be created.
3113         $table = new xmldb_table('task_adhoc');
3115         // Adding fields to table task_adhoc.
3116         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3117         $table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3118         $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3119         $table->add_field('nextruntime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
3120         $table->add_field('faildelay', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
3121         $table->add_field('customdata', XMLDB_TYPE_TEXT, null, null, null, null, null);
3122         $table->add_field('blocking', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
3124         // Adding keys to table task_adhoc.
3125         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3127         // Adding indexes to table task_adhoc.
3128         $table->add_index('nextruntime_idx', XMLDB_INDEX_NOTUNIQUE, array('nextruntime'));
3130         // Conditionally launch create table for task_adhoc.
3131         if (!$dbman->table_exists($table)) {
3132             $dbman->create_table($table);
3133         }
3135         // Main savepoint reached.
3136         upgrade_main_savepoint(true, 2014022600.00);
3137     }
3139     if ($oldversion < 2014031400.02) {
3140         // Delete any cached stats to force recalculation later, then we can be sure that cached records will have the correct
3141         // field.
3142         $DB->delete_records('question_response_analysis');
3143         $DB->delete_records('question_statistics');
3144         $DB->delete_records('quiz_statistics');
3146         // Define field response to be dropped from question_response_analysis.
3147         $table = new xmldb_table('question_response_analysis');
3148         $field = new xmldb_field('rcount');
3150         // Conditionally launch drop field response.
3151         if ($dbman->field_exists($table, $field)) {
3152             $dbman->drop_field($table, $field);
3153         }
3155         // Main savepoint reached.
3156         upgrade_main_savepoint(true, 2014031400.02);
3157     }
3159     if ($oldversion < 2014031400.03) {
3161         // Define table question_response_count to be created.
3162         $table = new xmldb_table('question_response_count');
3164         // Adding fields to table question_response_count.
3165         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3166         $table->add_field('analysisid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
3167         $table->add_field('try', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
3168         $table->add_field('rcount', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
3170         // Adding keys to table question_response_count.
3171         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3172         $table->add_key('analysisid', XMLDB_KEY_FOREIGN, array('analysisid'), 'question_response_analysis', array('id'));
3174         // Conditionally launch create table for question_response_count.
3175         if (!$dbman->table_exists($table)) {
3176             $dbman->create_table($table);
3177         }
3179         // Main savepoint reached.
3180         upgrade_main_savepoint(true, 2014031400.03);
3181     }
3183     if ($oldversion < 2014031400.04) {
3185         // Define field whichtries to be added to question_response_analysis.
3186         $table = new xmldb_table('question_response_analysis');
3187         $field = new xmldb_field('whichtries', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'hashcode');
3189         // Conditionally launch add field whichtries.
3190         if (!$dbman->field_exists($table, $field)) {
3191             $dbman->add_field($table, $field);
3192         }
3194         // Main savepoint reached.
3195         upgrade_main_savepoint(true, 2014031400.04);
3196     }
3198     if ($oldversion < 2014032600.00) {
3199         // Removing the themes from core.
3200         $themes = array('afterburner', 'anomaly', 'arialist', 'binarius', 'boxxie', 'brick', 'formal_white', 'formfactor',
3201             'fusion', 'leatherbound', 'magazine', 'nimble', 'nonzero', 'overlay', 'serenity', 'sky_high', 'splash',
3202             'standard', 'standardold');
3204         foreach ($themes as $key => $theme) {
3205             if (check_dir_exists($CFG->dirroot . '/theme/' . $theme, false)) {
3206                 // Ignore the themes that have been re-downloaded.
3207                 unset($themes[$key]);
3208             }
3209         }
3211         // Check we actually have themes to remove.
3212         if (count($themes) > 0) {
3214             // Replace the theme configs.
3215             if (in_array(get_config('core', 'theme'), $themes)) {
3216                 set_config('theme', 'clean');
3217             }
3218             if (in_array(get_config('core', 'thememobile'), $themes)) {
3219                 set_config('thememobile', 'clean');
3220             }
3221             if (in_array(get_config('core', 'themelegacy'), $themes)) {
3222                 set_config('themelegacy', 'clean');
3223             }
3224             if (in_array(get_config('core', 'themetablet'), $themes)) {
3225                 set_config('themetablet', 'clean');
3226             }
3227         }
3229         // Main savepoint reached.
3230         upgrade_main_savepoint(true, 2014032600.00);
3231     }
3233     if ($oldversion < 2014032600.02) {
3234         // Add new fields to the 'tag_instance' table.
3235         $table = new xmldb_table('tag_instance');
3236         $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, false, null, null, 'tagid');
3237         if (!$dbman->field_exists($table, $field)) {
3238             $dbman->add_field($table, $field);
3239         }
3241         $field = new xmldb_field('contextid', XMLDB_TYPE_INTEGER, '10', null, false, null, null, 'itemid');
3242         // Define the 'contextid' foreign key to be added to the tag_instance table.
3243         $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
3244         if ($dbman->field_exists($table, $field)) {
3245             $dbman->drop_key($table, $key);
3246             $DB->set_field('tag_instance', 'contextid', null, array('contextid' => 0));
3247             $dbman->change_field_default($table, $field);
3248         } else {
3249             $dbman->add_field($table, $field);
3250         }
3251         $dbman->add_key($table, $key);
3253         $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'ordering');
3254         if (!$dbman->field_exists($table, $field)) {
3255             $dbman->add_field($table, $field);
3256         }
3258         $sql = "UPDATE {tag_instance}
3259                    SET timecreated = timemodified";
3260         $DB->execute($sql);
3262         // Update all the course tags.
3263         $sql = "UPDATE {tag_instance}
3264                    SET component = 'core',
3265                        contextid = (SELECT ctx.id
3266                                       FROM {context} ctx
3267                                      WHERE ctx.contextlevel = :contextlevel
3268                                        AND ctx.instanceid = {tag_instance}.itemid)
3269                  WHERE itemtype = 'course' AND contextid IS NULL";
3270         $DB->execute($sql, array('contextlevel' => CONTEXT_COURSE));
3272         // Update all the user tags.
3273         $sql = "UPDATE {tag_instance}
3274                    SET component = 'core',
3275                        contextid = (SELECT ctx.id
3276                                       FROM {context} ctx
3277                                      WHERE ctx.contextlevel = :contextlevel
3278                                        AND ctx.instanceid = {tag_instance}.itemid)
3279                  WHERE itemtype = 'user' AND contextid IS NULL";
3280         $DB->execute($sql, array('contextlevel' => CONTEXT_USER));
3282         // Update all the blog post tags.
3283         $sql = "UPDATE {tag_instance}
3284                    SET component = 'core',
3285                        contextid = (SELECT ctx.id
3286                                       FROM {context} ctx
3287                                       JOIN {post} p
3288                                         ON p.userid = ctx.instanceid
3289                                      WHERE ctx.contextlevel = :contextlevel
3290                                        AND p.id = {tag_instance}.itemid)
3291                  WHERE itemtype = 'post' AND contextid IS NULL";
3292         $DB->execute($sql, array('contextlevel' => CONTEXT_USER));
3294         // Update all the wiki page tags.
3295         $sql = "UPDATE {tag_instance}
3296                    SET component = 'mod_wiki',
3297                        contextid = (SELECT ctx.id
3298                                       FROM {context} ctx
3299                                       JOIN {course_modules} cm
3300                                         ON cm.id = ctx.instanceid
3301                                       JOIN {modules} m
3302                                         ON m.id = cm.module
3303                                       JOIN {wiki} w
3304                                         ON w.id = cm.instance
3305                                       JOIN {wiki_subwikis} sw
3306                                         ON sw.wikiid = w.id
3307                                       JOIN {wiki_pages} wp
3308                                         ON wp.subwikiid = sw.id
3309                                      WHERE m.name = 'wiki'
3310                                        AND ctx.contextlevel = :contextlevel
3311                                        AND wp.id = {tag_instance}.itemid)
3312                  WHERE itemtype = 'wiki_pages' AND contextid IS NULL";
3313         $DB->execute($sql, array('contextlevel' => CONTEXT_MODULE));
3315         // Update all the question tags.
3316         $sql = "UPDATE {tag_instance}
3317                    SET component = 'core_question',
3318                        contextid = (SELECT qc.contextid
3319                                       FROM {question} q
3320                                       JOIN {question_categories} qc
3321                                         ON q.category = qc.id
3322                                      WHERE q.id = {tag_instance}.itemid)
3323                  WHERE itemtype = 'question' AND contextid IS NULL";
3324         $DB->execute($sql);
3326         // Update all the tag tags.
3327         $sql = "UPDATE {tag_instance}
3328                    SET component = 'core',
3329                        contextid = :systemcontext
3330                  WHERE itemtype = 'tag' AND contextid IS NULL";
3331         $DB->execute($sql, array('systemcontext' => context_system::instance()->id));
3333         // Main savepoint reached.
3334         upgrade_main_savepoint(true, 2014032600.02);
3335     }
3337     if ($oldversion < 2014032700.01) {
3339         // Define field disabled to be added to task_scheduled.
3340         $table = new xmldb_table('task_scheduled');
3341         $field = new xmldb_field('disabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'customised');
3343         // Conditionally launch add field disabled.
3344         if (!$dbman->field_exists($table, $field)) {
3345             $dbman->add_field($table, $field);
3346         }
3348         // Main savepoint reached.
3349         upgrade_main_savepoint(true, 2014032700.01);
3350     }
3352     if ($oldversion < 2014032700.02) {
3354         // Update displayloginfailures setting.
3355         if (empty($CFG->displayloginfailures)) {
3356             set_config('displayloginfailures', 0);
3357         } else {
3358             set_config('displayloginfailures', 1);
3359         }
3361         // Main savepoint reached.
3362         upgrade_main_savepoint(true, 2014032700.02);
3363     }
3365     if ($oldversion < 2014040800.00) {
3367         // Define field availability to be added to course_modules.
3368         $table = new xmldb_table('course_modules');
3369         $field = new xmldb_field('availability', XMLDB_TYPE_TEXT, null, null, null, null, null, 'showdescription');
3371         // Conditionally launch add field availability.
3372         if (!$dbman->field_exists($table, $field)) {
3373             $dbman->add_field($table, $field);
3374         }
3376         // Define field availability to be added to course_sections.
3377         $table = new xmldb_table('course_sections');
3378         $field = new xmldb_field('availability', XMLDB_TYPE_TEXT, null, null, null, null, null, 'groupingid');
3380         // Conditionally launch add field availability.
3381         if (!$dbman->field_exists($table, $field)) {
3382             $dbman->add_field($table, $field);
3383         }