6d26f71f26bb9ed1394ff175d63f36e52e671eec
[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, $DB;
90     require_once($CFG->libdir.'/db/upgradelib.php'); // Core Upgrade-related functions.
92     $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
94     // Always keep this upgrade step with version being the minimum
95     // allowed version to upgrade from (v3.1.0 right now).
96     if ($oldversion < 2016052300) {
97         // Just in case somebody hacks upgrade scripts or env, we really can not continue.
98         echo("You need to upgrade to 3.1.x or higher first!\n");
99         exit(1);
100         // Note this savepoint is 100% unreachable, but needed to pass the upgrade checks.
101         upgrade_main_savepoint(true, 2016052300);
102     }
104     if ($oldversion < 2016081700.00) {
106         // If someone is emotionally attached to it let's leave the config (basically the version) there.
107         if (!file_exists($CFG->dirroot . '/report/search/classes/output/form.php')) {
108             unset_all_config_for_plugin('report_search');
109         }
111         // Savepoint reached.
112         upgrade_main_savepoint(true, 2016081700.00);
113     }
115     if ($oldversion < 2016081700.02) {
116         // Default schedule values.
117         $hour = 0;
118         $minute = 0;
120         // Get the old settings.
121         if (isset($CFG->statsruntimestarthour)) {
122             $hour = $CFG->statsruntimestarthour;
123         }
124         if (isset($CFG->statsruntimestartminute)) {
125             $minute = $CFG->statsruntimestartminute;
126         }
128         // Retrieve the scheduled task record first.
129         $stattask = $DB->get_record('task_scheduled', array('component' => 'moodle', 'classname' => '\core\task\stats_cron_task'));
131         // Don't touch customised scheduling.
132         if ($stattask && !$stattask->customised) {
134             $nextruntime = mktime($hour, $minute, 0, date('m'), date('d'), date('Y'));
135             if ($nextruntime < $stattask->lastruntime) {
136                 // Add 24 hours to the next run time.
137                 $newtime = new DateTime();
138                 $newtime->setTimestamp($nextruntime);
139                 $newtime->add(new DateInterval('P1D'));
140                 $nextruntime = $newtime->getTimestamp();
141             }
142             $stattask->nextruntime = $nextruntime;
143             $stattask->minute = $minute;
144             $stattask->hour = $hour;
145             $stattask->customised = 1;
146             $DB->update_record('task_scheduled', $stattask);
147         }
148         // These settings are no longer used.
149         unset_config('statsruntimestarthour');
150         unset_config('statsruntimestartminute');
151         unset_config('statslastexecution');
153         upgrade_main_savepoint(true, 2016081700.02);
154     }
156     if ($oldversion < 2016082200.00) {
157         // An upgrade step to remove any duplicate stamps, within the same context, in the question_categories table, and to
158         // add a unique index to (contextid, stamp) to avoid future stamp duplication. See MDL-54864.
160         // Extend the execution time limit of the script to 2 hours.
161         upgrade_set_timeout(7200);
163         // This SQL fetches the id of those records which have duplicate stamps within the same context.
164         // This doesn't return the original record within the context, from which the duplicate stamps were likely created.
165         $fromclause = "FROM (
166                         SELECT min(id) AS minid, contextid, stamp
167                             FROM {question_categories}
168                             GROUP BY contextid, stamp
169                         ) minid
170                         JOIN {question_categories} qc
171                             ON qc.contextid = minid.contextid AND qc.stamp = minid.stamp AND qc.id > minid.minid";
173         // Get the total record count - used for the progress bar.
174         $countduplicatessql = "SELECT count(qc.id) $fromclause";
175         $total = $DB->count_records_sql($countduplicatessql);
177         // Get the records themselves.
178         $getduplicatessql = "SELECT qc.id $fromclause ORDER BY minid";
179         $rs = $DB->get_recordset_sql($getduplicatessql);
181         // For each duplicate, update the stamp to a new random value.
182         $i = 0;
183         $pbar = new progress_bar('updatequestioncategorystamp', 500, true);
184         foreach ($rs as $record) {
185             // Generate a new, unique stamp and update the record.
186             do {
187                 $newstamp = make_unique_id_code();
188             } while (isset($usedstamps[$newstamp]));
189             $usedstamps[$newstamp] = 1;
190             $DB->set_field('question_categories', 'stamp', $newstamp, array('id' => $record->id));
192             // Update progress.
193             $i++;
194             $pbar->update($i, $total, "Updating duplicate question category stamp - $i/$total.");
195         }
196         $rs->close();
197         unset($usedstamps);
199         // The uniqueness of each (contextid, stamp) pair is now guaranteed, so add the unique index to stop future duplicates.
200         $table = new xmldb_table('question_categories');
201         $index = new xmldb_index('contextidstamp', XMLDB_INDEX_UNIQUE, array('contextid', 'stamp'));
202         if (!$dbman->index_exists($table, $index)) {
203             $dbman->add_index($table, $index);
204         }
206         // Savepoint reached.
207         upgrade_main_savepoint(true, 2016082200.00);
208     }
210     if ($oldversion < 2016091900.00) {
212         // Removing the themes from core.
213         $themes = array('base', 'canvas');
215         foreach ($themes as $key => $theme) {
216             if (check_dir_exists($CFG->dirroot . '/theme/' . $theme, false)) {
217                 // Ignore the themes that have been re-downloaded.
218                 unset($themes[$key]);
219             }
220         }
222         if (!empty($themes)) {
223             // Hacky emulation of plugin uninstallation.
224             foreach ($themes as $theme) {
225                 unset_all_config_for_plugin('theme_' . $theme);
226             }
227         }
229         // Main savepoint reached.
230         upgrade_main_savepoint(true, 2016091900.00);
231     }
233     if ($oldversion < 2016091900.02) {
235         // Define index attemptstepid-name (unique) to be dropped from question_attempt_step_data.
236         $table = new xmldb_table('question_attempt_step_data');
237         $index = new xmldb_index('attemptstepid-name', XMLDB_INDEX_UNIQUE, array('attemptstepid', 'name'));
239         // Conditionally launch drop index attemptstepid-name.
240         if ($dbman->index_exists($table, $index)) {
241             $dbman->drop_index($table, $index);
242         }
244         // Main savepoint reached.
245         upgrade_main_savepoint(true, 2016091900.02);
246     }
248     if ($oldversion < 2016100300.00) {
249         unset_config('enablecssoptimiser');
251         upgrade_main_savepoint(true, 2016100300.00);
252     }
254     if ($oldversion < 2016100501.00) {
256         // Define field enddate to be added to course.
257         $table = new xmldb_table('course');
258         $field = new xmldb_field('enddate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'startdate');
260         // Conditionally launch add field enddate.
261         if (!$dbman->field_exists($table, $field)) {
262             $dbman->add_field($table, $field);
263         }
265         // Main savepoint reached.
266         upgrade_main_savepoint(true, 2016100501.00);
267     }
269     if ($oldversion < 2016101100.00) {
270         // Define field component to be added to message.
271         $table = new xmldb_table('message');
272         $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'timeusertodeleted');
274         // Conditionally launch add field component.
275         if (!$dbman->field_exists($table, $field)) {
276             $dbman->add_field($table, $field);
277         }
279         // Define field eventtype to be added to message.
280         $field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
282         // Conditionally launch add field eventtype.
283         if (!$dbman->field_exists($table, $field)) {
284             $dbman->add_field($table, $field);
285         }
287         // Main savepoint reached.
288         upgrade_main_savepoint(true, 2016101100.00);
289     }
292     if ($oldversion < 2016101101.00) {
293         // Define field component to be added to message_read.
294         $table = new xmldb_table('message_read');
295         $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'timeusertodeleted');
297         // Conditionally launch add field component.
298         if (!$dbman->field_exists($table, $field)) {
299             $dbman->add_field($table, $field);
300         }
302         // Define field eventtype to be added to message_read.
303         $field = new xmldb_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
305         // Conditionally launch add field eventtype.
306         if (!$dbman->field_exists($table, $field)) {
307             $dbman->add_field($table, $field);
308         }
310         // Main savepoint reached.
311         upgrade_main_savepoint(true, 2016101101.00);
312     }
314     if ($oldversion < 2016101401.00) {
315         // Clean up repository_alfresco config unless plugin has been manually installed.
316         if (!file_exists($CFG->dirroot . '/repository/alfresco/lib.php')) {
317             // Remove capabilities.
318             capabilities_cleanup('repository_alfresco');
319             // Clean config.
320             unset_all_config_for_plugin('repository_alfresco');
321         }
323         // Savepoint reached.
324         upgrade_main_savepoint(true, 2016101401.00);
325     }
327     if ($oldversion < 2016101401.02) {
328         $table = new xmldb_table('external_tokens');
329         $field = new xmldb_field('privatetoken', XMLDB_TYPE_CHAR, '64', null, null, null, null);
331         // Conditionally add privatetoken field to the external_tokens table.
332         if (!$dbman->field_exists($table, $field)) {
333             $dbman->add_field($table, $field);
334         }
336         // Main savepoint reached.
337         upgrade_main_savepoint(true, 2016101401.02);
338     }
340     if ($oldversion < 2016110202.00) {
342         // Force uninstall of deleted authentication plugin.
343         if (!file_exists("$CFG->dirroot/auth/radius")) {
344             // Leave settings inplace if there are radius users.
345             if (!$DB->record_exists('user', array('auth' => 'radius', 'deleted' => 0))) {
346                 // Remove all other associated config.
347                 unset_all_config_for_plugin('auth/radius');
348                 // The version number for radius is in this format.
349                 unset_all_config_for_plugin('auth_radius');
350             }
351         }
352         upgrade_main_savepoint(true, 2016110202.00);
353     }
355     if ($oldversion < 2016110300.00) {
356         // Remove unused admin email setting.
357         unset_config('emailonlyfromreplyaddress');
359         // Main savepoint reached.
360         upgrade_main_savepoint(true, 2016110300.00);
361     }
363     if ($oldversion < 2016110500.00) {
365         $oldplayers = [
366             'vimeo' => null,
367             'mp3' => ['.mp3'],
368             'html5video' => ['.mov', '.mp4', '.m4v', '.mpeg', '.mpe', '.mpg', '.ogv', '.webm'],
369             'flv' => ['.flv', '.f4v'],
370             'html5audio' => ['.aac', '.flac', '.mp3', '.m4a', '.oga', '.ogg', '.wav'],
371             'youtube' => null,
372             'swf' => null,
373         ];
375         // Convert hardcoded media players to the settings of the new media player plugin type.
376         if (get_config('core', 'media_plugins_sortorder') === false) {
377             $enabledplugins = [];
378             $videoextensions = [];
379             $audioextensions = [];
380             foreach ($oldplayers as $oldplayer => $extensions) {
381                 $settingname = 'core_media_enable_'.$oldplayer;
382                 if (!empty($CFG->$settingname)) {
383                     if ($extensions) {
384                         // VideoJS will be used for all media files players that were used previously.
385                         $enabledplugins['videojs'] = 'videojs';
386                         if ($oldplayer === 'mp3' || $oldplayer === 'html5audio') {
387                             $audioextensions += array_combine($extensions, $extensions);
388                         } else {
389                             $videoextensions += array_combine($extensions, $extensions);
390                         }
391                     } else {
392                         // Enable youtube, vimeo and swf.
393                         $enabledplugins[$oldplayer] = $oldplayer;
394                     }
395                 }
396             }
398             set_config('media_plugins_sortorder', join(',', $enabledplugins));
400             // Configure VideoJS to match the existing players set up.
401             if ($enabledplugins['videojs']) {
402                 $enabledplugins[] = 'videojs';
403                 set_config('audioextensions', join(',', $audioextensions), 'media_videojs');
404                 set_config('videoextensions', join(',', $videoextensions), 'media_videojs');
405                 $useflash = !empty($CFG->core_media_enable_flv) || !empty($CFG->core_media_enable_mp3);
406                 set_config('useflash', $useflash, 'media_videojs');
407                 if (empty($CFG->core_media_enable_youtube)) {
408                     // Normally YouTube is enabled in videojs, but if youtube converter was disabled before upgrade
409                     // disable it in videojs as well.
410                     set_config('youtube', false, 'media_videojs');
411                 }
412             }
413         }
415         // Unset old settings.
416         foreach ($oldplayers as $oldplayer => $extensions) {
417             unset_config('core_media_enable_' . $oldplayer);
418         }
420         // Preset defaults if CORE_MEDIA_VIDEO_WIDTH and CORE_MEDIA_VIDEO_HEIGHT are specified in config.php .
421         // After this upgrade step these constants will not be used any more.
422         if (defined('CORE_MEDIA_VIDEO_WIDTH')) {
423             set_config('media_default_width', CORE_MEDIA_VIDEO_WIDTH);
424         }
425         if (defined('CORE_MEDIA_VIDEO_HEIGHT')) {
426             set_config('media_default_height', CORE_MEDIA_VIDEO_HEIGHT);
427         }
429         // Savepoint reached.
430         upgrade_main_savepoint(true, 2016110500.00);
431     }
433     if ($oldversion < 2016110600.00) {
434         // Define a field 'deletioninprogress' in the 'course_modules' table, to background deletion tasks.
435         $table = new xmldb_table('course_modules');
436         $field = new xmldb_field('deletioninprogress', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'availability');
438         // Conditionally launch add field 'deletioninprogress'.
439         if (!$dbman->field_exists($table, $field)) {
440             $dbman->add_field($table, $field);
441         }
443         // Main savepoint reached.
444         upgrade_main_savepoint(true, 2016110600.00);
445     }
447     if ($oldversion < 2016112200.01) {
449         // Define field requiredbytheme to be added to block_instances.
450         $table = new xmldb_table('block_instances');
451         $field = new xmldb_field('requiredbytheme', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0', 'showinsubcontexts');
453         // Conditionally launch add field requiredbytheme.
454         if (!$dbman->field_exists($table, $field)) {
455             $dbman->add_field($table, $field);
456         }
458         // Main savepoint reached.
459         upgrade_main_savepoint(true, 2016112200.01);
460     }
461     if ($oldversion < 2016112200.02) {
463         // Change the existing site level admin and settings blocks to be requiredbytheme which means they won't show in boost.
464         $context = context_system::instance();
465         $params = array('blockname' => 'settings', 'parentcontextid' => $context->id);
466         $DB->set_field('block_instances', 'requiredbytheme', 1, $params);
468         $params = array('blockname' => 'navigation', 'parentcontextid' => $context->id);
469         $DB->set_field('block_instances', 'requiredbytheme', 1, $params);
470         // Main savepoint reached.
471         upgrade_main_savepoint(true, 2016112200.02);
472     }
474     // Automatically generated Moodle v3.2.0 release upgrade line.
475     // Put any upgrade step following this.
477     if ($oldversion < 2016122800.00) {
478         // Find all roles with the coursecreator archetype.
479         $coursecreatorroleids = $DB->get_records('role', array('archetype' => 'coursecreator'), '', 'id');
481         $context = context_system::instance();
482         $capability = 'moodle/site:configview';
484         foreach ($coursecreatorroleids as $roleid => $notused) {
486             // Check that the capability has not already been assigned. If it has then it's either already set
487             // to allow or specifically set to prohibit or prevent.
488             if (!$DB->record_exists('role_capabilities', array('roleid' => $roleid, 'capability' => $capability))) {
489                 // Assign the capability.
490                 $cap = new stdClass();
491                 $cap->contextid    = $context->id;
492                 $cap->roleid       = $roleid;
493                 $cap->capability   = $capability;
494                 $cap->permission   = CAP_ALLOW;
495                 $cap->timemodified = time();
496                 $cap->modifierid   = 0;
498                 $DB->insert_record('role_capabilities', $cap);
499             }
500         }
502         // Main savepoint reached.
503         upgrade_main_savepoint(true, 2016122800.00);
504     }
506     if ($oldversion < 2017020200.01) {
508         // Define index useridfrom_timeuserfromdeleted_notification (not unique) to be added to message.
509         $table = new xmldb_table('message');
510         $index = new xmldb_index('useridfrom_timeuserfromdeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridfrom', 'timeuserfromdeleted', 'notification'));
512         // Conditionally launch add index useridfrom_timeuserfromdeleted_notification.
513         if (!$dbman->index_exists($table, $index)) {
514             $dbman->add_index($table, $index);
515         }
517         // Define index useridto_timeusertodeleted_notification (not unique) to be added to message.
518         $index = new xmldb_index('useridto_timeusertodeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridto', 'timeusertodeleted', 'notification'));
520         // Conditionally launch add index useridto_timeusertodeleted_notification.
521         if (!$dbman->index_exists($table, $index)) {
522             $dbman->add_index($table, $index);
523         }
525         $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
527         // Conditionally launch drop index useridto.
528         if ($dbman->index_exists($table, $index)) {
529             $dbman->drop_index($table, $index);
530         }
532         // Main savepoint reached.
533         upgrade_main_savepoint(true, 2017020200.01);
534     }
536     if ($oldversion < 2017020200.02) {
538         // Define index useridfrom_timeuserfromdeleted_notification (not unique) to be added to message_read.
539         $table = new xmldb_table('message_read');
540         $index = new xmldb_index('useridfrom_timeuserfromdeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridfrom', 'timeuserfromdeleted', 'notification'));
542         // Conditionally launch add index useridfrom_timeuserfromdeleted_notification.
543         if (!$dbman->index_exists($table, $index)) {
544             $dbman->add_index($table, $index);
545         }
547         // Define index useridto_timeusertodeleted_notification (not unique) to be added to message_read.
548         $index = new xmldb_index('useridto_timeusertodeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridto', 'timeusertodeleted', 'notification'));
550         // Conditionally launch add index useridto_timeusertodeleted_notification.
551         if (!$dbman->index_exists($table, $index)) {
552             $dbman->add_index($table, $index);
553         }
555         $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
557         // Conditionally launch drop index useridto.
558         if ($dbman->index_exists($table, $index)) {
559             $dbman->drop_index($table, $index);
560         }
562         // Main savepoint reached.
563         upgrade_main_savepoint(true, 2017020200.02);
564     }
566     if ($oldversion < 2017020901.00) {
568         // Delete "orphaned" block positions. Note, the query does not use indexes (because there are none),
569         // if it runs too long during upgrade you can comment this line - it will leave orphaned records
570         // in the database but they won't bother you.
571         upgrade_block_positions();
573         // Main savepoint reached.
574         upgrade_main_savepoint(true, 2017020901.00);
575     }
577     if ($oldversion < 2017021300.00) {
578         unset_config('loginpasswordautocomplete');
579         upgrade_main_savepoint(true, 2017021300.00);
580     }
582     if ($oldversion < 2017021400.00) {
583         // Define field visibleoncoursepage to be added to course_modules.
584         $table = new xmldb_table('course_modules');
585         $field = new xmldb_field('visibleoncoursepage', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'visible');
587         // Conditionally launch add field visibleoncoursepage.
588         if (!$dbman->field_exists($table, $field)) {
589             $dbman->add_field($table, $field);
590         }
592         // Main savepoint reached.
593         upgrade_main_savepoint(true, 2017021400.00);
594     }
596     if ($oldversion < 2017030700.00) {
598         // Define field priority to be added to event.
599         $table = new xmldb_table('event');
600         $field = new xmldb_field('priority', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'subscriptionid');
602         // Conditionally launch add field priority.
603         if (!$dbman->field_exists($table, $field)) {
604             $dbman->add_field($table, $field);
605         }
607         // Main savepoint reached.
608         upgrade_main_savepoint(true, 2017030700.00);
609     }
611     if ($oldversion < 2017031400.00) {
613         // Define table file_conversion to be created.
614         $table = new xmldb_table('file_conversion');
616         // Adding fields to table file_conversion.
617         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
618         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
619         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
620         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
621         $table->add_field('sourcefileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
622         $table->add_field('targetformat', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
623         $table->add_field('status', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
624         $table->add_field('statusmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
625         $table->add_field('converter', XMLDB_TYPE_CHAR, '255', null, null, null, null);
626         $table->add_field('destfileid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
627         $table->add_field('data', XMLDB_TYPE_TEXT, null, null, null, null, null);
629         // Adding keys to table file_conversion.
630         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
631         $table->add_key('sourcefileid', XMLDB_KEY_FOREIGN, array('sourcefileid'), 'files', array('id'));
632         $table->add_key('destfileid', XMLDB_KEY_FOREIGN, array('destfileid'), 'files', array('id'));
634         // Conditionally launch create table for file_conversion.
635         if (!$dbman->table_exists($table)) {
636             $dbman->create_table($table);
637         }
639         // Main savepoint reached.
640         upgrade_main_savepoint(true, 2017031400.00);
641     }
643     if ($oldversion < 2017040400.00) {
645         // If block_course_overview is no longer present, replace with block_myoverview.
646         if (!file_exists($CFG->dirroot . '/blocks/course_overview/block_course_overview.php')) {
647             $DB->set_field('block_instances', 'blockname', 'myoverview', array('blockname' => 'course_overview'));
648         }
650         upgrade_main_savepoint(true, 2017040400.00);
651     }
653     if ($oldversion < 2017040401.00) {
655         // If block_course_overview is no longer present, remove it.
656         // Note - we do not need to completely remove the block context etc because we
657         // have replaced all occurrences of block_course_overview with block_myoverview
658         // in the upgrade step above.
659         if (!file_exists($CFG->dirroot . '/blocks/course_overview/block_course_overview.php')) {
660             // Delete the block from the block table.
661             $DB->delete_records('block', array('name' => 'course_overview'));
662             // Remove capabilities.
663             capabilities_cleanup('block_course_overview');
664             // Clean config.
665             unset_all_config_for_plugin('block_course_overview');
666         }
668         upgrade_main_savepoint(true, 2017040401.00);
669     }
671     if ($oldversion < 2017040402.00) {
673         // Define fields to be added to the 'event' table.
674         $table = new xmldb_table('event');
675         $fieldtype = new xmldb_field('type', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 0, 'instance');
676         $fieldtimesort = new xmldb_field('timesort', XMLDB_TYPE_INTEGER, '10', null, false, null, null, 'timeduration');
678         // Conditionally launch add field.
679         if (!$dbman->field_exists($table, $fieldtype)) {
680             $dbman->add_field($table, $fieldtype);
681         }
683         // Conditionally launch add field.
684         if (!$dbman->field_exists($table, $fieldtimesort)) {
685             $dbman->add_field($table, $fieldtimesort);
686         }
688         // Now, define the index we will be adding.
689         $index = new xmldb_index('type-timesort', XMLDB_INDEX_NOTUNIQUE, array('type', 'timesort'));
691         // Conditionally launch add index.
692         if (!$dbman->index_exists($table, $index)) {
693             $dbman->add_index($table, $index);
694         }
696         upgrade_main_savepoint(true, 2017040402.00);
697     }
699     if ($oldversion < 2017040700.01) {
701         // Define table oauth2_issuer to be created.
702         $table = new xmldb_table('oauth2_issuer');
704         // Adding fields to table oauth2_issuer.
705         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
706         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
707         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
708         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
709         $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
710         $table->add_field('image', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
711         $table->add_field('baseurl', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
712         $table->add_field('clientid', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
713         $table->add_field('clientsecret', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
714         $table->add_field('loginscopes', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
715         $table->add_field('loginscopesoffline', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
716         $table->add_field('loginparams', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
717         $table->add_field('loginparamsoffline', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
718         $table->add_field('alloweddomains', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
719         $table->add_field('scopessupported', XMLDB_TYPE_TEXT, null, null, null, null, null);
720         $table->add_field('showonloginpage', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
721         $table->add_field('enabled', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
722         $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
724         // Adding keys to table oauth2_issuer.
725         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
727         // Conditionally launch create table for oauth2_issuer.
728         if (!$dbman->table_exists($table)) {
729             $dbman->create_table($table);
730         }
732         // Main savepoint reached.
733         upgrade_main_savepoint(true, 2017040700.01);
734     }
736     if ($oldversion < 2017040700.02) {
738         // Define table oauth2_endpoint to be created.
739         $table = new xmldb_table('oauth2_endpoint');
741         // Adding fields to table oauth2_endpoint.
742         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
743         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
744         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
745         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
746         $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
747         $table->add_field('url', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
748         $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
750         // Adding keys to table oauth2_endpoint.
751         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
752         $table->add_key('issuer_id_key', XMLDB_KEY_FOREIGN, array('issuerid'), 'oauth2_issuer', array('id'));
754         // Conditionally launch create table for oauth2_endpoint.
755         if (!$dbman->table_exists($table)) {
756             $dbman->create_table($table);
757         }
759         // Main savepoint reached.
760         upgrade_main_savepoint(true, 2017040700.02);
761     }
763     if ($oldversion < 2017040700.03) {
765         // Define table oauth2_system_account to be created.
766         $table = new xmldb_table('oauth2_system_account');
768         // Adding fields to table oauth2_system_account.
769         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
770         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
771         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
772         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
773         $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
774         $table->add_field('refreshtoken', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
775         $table->add_field('grantedscopes', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
776         $table->add_field('username', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
777         $table->add_field('email', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
779         // Adding keys to table oauth2_system_account.
780         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
781         $table->add_key('issueridkey', XMLDB_KEY_FOREIGN_UNIQUE, array('issuerid'), 'oauth2_issuer', array('id'));
783         // Conditionally launch create table for oauth2_system_account.
784         if (!$dbman->table_exists($table)) {
785             $dbman->create_table($table);
786         }
788         // Main savepoint reached.
789         upgrade_main_savepoint(true, 2017040700.03);
790     }
792     if ($oldversion < 2017040700.04) {
794         // Define table oauth2_user_field_mapping to be created.
795         $table = new xmldb_table('oauth2_user_field_mapping');
797         // Adding fields to table oauth2_user_field_mapping.
798         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
799         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
800         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
801         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
802         $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
803         $table->add_field('externalfield', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null);
804         $table->add_field('internalfield', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null);
806         // Adding keys to table oauth2_user_field_mapping.
807         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
808         $table->add_key('issuerkey', XMLDB_KEY_FOREIGN, array('issuerid'), 'oauth2_issuer', array('id'));
809         $table->add_key('uniqinternal', XMLDB_KEY_UNIQUE, array('issuerid', 'internalfield'));
811         // Conditionally launch create table for oauth2_user_field_mapping.
812         if (!$dbman->table_exists($table)) {
813             $dbman->create_table($table);
814         }
816         // Main savepoint reached.
817         upgrade_main_savepoint(true, 2017040700.04);
818     }
820     if ($oldversion < 2017041801.00) {
822         // Define table course_completion_defaults to be created.
823         $table = new xmldb_table('course_completion_defaults');
825         // Adding fields to table course_completion_defaults.
826         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
827         $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
828         $table->add_field('module', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
829         $table->add_field('completion', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
830         $table->add_field('completionview', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
831         $table->add_field('completionusegrade', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
832         $table->add_field('completionexpected', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
833         $table->add_field('customrules', XMLDB_TYPE_TEXT, null, null, null, null, null);
835         // Adding keys to table course_completion_defaults.
836         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
837         $table->add_key('module', XMLDB_KEY_FOREIGN, array('module'), 'modules', array('id'));
838         $table->add_key('course', XMLDB_KEY_FOREIGN, array('course'), 'course', array('id'));
840         // Adding indexes to table course_completion_defaults.
841         $table->add_index('coursemodule', XMLDB_INDEX_UNIQUE, array('course', 'module'));
843         // Conditionally launch create table for course_completion_defaults.
844         if (!$dbman->table_exists($table)) {
845             $dbman->create_table($table);
846         }
848         upgrade_main_savepoint(true, 2017041801.00);
849     }
851     if ($oldversion < 2017050500.01) {
852         // Get the list of parent event IDs.
853         $sql = "SELECT DISTINCT repeatid
854                            FROM {event}
855                           WHERE repeatid <> 0";
856         $parentids = array_keys($DB->get_records_sql($sql));
857         // Check if there are repeating events we need to process.
858         if (!empty($parentids)) {
859             // The repeat IDs of parent events should match their own ID.
860             // So we need to update parent events that have non-matching IDs and repeat IDs.
861             list($insql, $params) = $DB->get_in_or_equal($parentids);
862             $updatesql = "UPDATE {event}
863                              SET repeatid = id
864                            WHERE id <> repeatid
865                                  AND id $insql";
866             $DB->execute($updatesql, $params);
867         }
869         // Main savepoint reached.
870         upgrade_main_savepoint(true, 2017050500.01);
871     }
873     if ($oldversion < 2017050500.02) {
874         // MDL-58684:
875         // Remove all portfolio_tempdata records as these may contain serialized \file_system type objects, which are now unable to
876         // be unserialized because of changes to the file storage API made in MDL-46375. Portfolio now stores an id reference to
877         // files instead of the object.
878         // These records are normally removed after a successful export, however, can be left behind if the user abandons the
879         // export attempt (a stale record). Additionally, each stale record cannot be reused and is normally cleaned up by the cron
880         // task core\task\portfolio_cron_task. Since the cron task tries to unserialize them, and generates a warning, we'll remove
881         // all records here.
882         $DB->delete_records_select('portfolio_tempdata', 'id > ?', [0]);
884         // Main savepoint reached.
885         upgrade_main_savepoint(true, 2017050500.02);
886     }
888     if ($oldversion < 2017050900.01) {
889         // Create adhoc task for upgrading of existing calendar events.
890         $record = new \stdClass();
891         $record->classname = '\core\task\refresh_mod_calendar_events_task';
892         $record->component = 'core';
894         // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
895         $nextruntime = time() - 1;
896         $record->nextruntime = $nextruntime;
897         $DB->insert_record('task_adhoc', $record);
899         // Main savepoint reached.
900         upgrade_main_savepoint(true, 2017050900.01);
901     }
903     // Automatically generated Moodle v3.3.0 release upgrade line.
904     // Put any upgrade step following this.
906     if ($oldversion < 2017061201.00) {
907         $table = new xmldb_table('course_sections');
908         $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'availability');
910         // Define a field 'timemodified' in the 'course_sections' table.
911         if (!$dbman->field_exists($table, $field)) {
912             $dbman->add_field($table, $field);
913         }
915         upgrade_main_savepoint(true, 2017061201.00);
916     }
918     if ($oldversion < 2017061301.00) {
919         // Check if the value of 'navcourselimit' is set to the old default value, if so, change it to the new default.
920         if ($CFG->navcourselimit == 20) {
921             set_config('navcourselimit', 10);
922         }
924         // Main savepoint reached.
925         upgrade_main_savepoint(true, 2017061301.00);
926     }
928     if ($oldversion < 2017071000.00) {
930         // Define field requireconfirmation to be added to oauth2_issuer.
931         $table = new xmldb_table('oauth2_issuer');
932         $field = new xmldb_field('requireconfirmation', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1', 'sortorder');
934         // Conditionally launch add field requireconfirmation.
935         if (!$dbman->field_exists($table, $field)) {
936             $dbman->add_field($table, $field);
937         }
939         // Main savepoint reached.
940         upgrade_main_savepoint(true, 2017071000.00);
941     }
943     if ($oldversion < 2017071001.00) {
945         // Define field timemodified to be added to block_instances.
946         $table = new xmldb_table('block_instances');
947         $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null,
948                 null, null, 'configdata');
950         // Conditionally launch add field timemodified.
951         if (!$dbman->field_exists($table, $field)) {
952             $dbman->add_field($table, $field);
954             // Set field to current time.
955             $DB->set_field('block_instances', 'timemodified', time());
957             // Changing nullability of field timemodified on table block_instances to not null.
958             $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL,
959                     null, null, 'configdata');
961             // Launch change of nullability for field timemodified.
962             $dbman->change_field_notnull($table, $field);
964             // Define index timemodified (not unique) to be added to block_instances.
965             $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
967             // Conditionally launch add index timemodified.
968             if (!$dbman->index_exists($table, $index)) {
969                 $dbman->add_index($table, $index);
970             }
971         }
973         // Define field timecreated to be added to block_instances.
974         $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null,
975                 null, null, 'configdata');
977         // Conditionally launch add field timecreated.
978         if (!$dbman->field_exists($table, $field)) {
979             $dbman->add_field($table, $field);
981             // Set field to current time.
982             $DB->set_field('block_instances', 'timecreated', time());
984             // Changing nullability of field timecreated on table block_instances to not null.
985             $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL,
986                     null, null, 'configdata');
988             // Launch change of nullability for field timecreated.
989             $dbman->change_field_notnull($table, $field);
990         }
992         // Main savepoint reached.
993         upgrade_main_savepoint(true, 2017071001.00);
994     }
996     if ($oldversion < 2017071100.00 ) {
997         // Clean old upgrade setting not used anymore.
998         unset_config('upgrade_minmaxgradestepignored');
999         upgrade_main_savepoint(true, 2017071100.00);
1000     }
1002     if ($oldversion < 2017072000.02) {
1004         // Define table analytics_models to be created.
1005         $table = new xmldb_table('analytics_models');
1007         // Adding fields to table analytics_models.
1008         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1009         $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
1010         $table->add_field('trained', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
1011         $table->add_field('target', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1012         $table->add_field('indicators', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
1013         $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, null, null, null);
1014         $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1015         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
1016         $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1017         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1019         // Adding keys to table analytics_models.
1020         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1022         // Adding indexes to table analytics_models.
1023         $table->add_index('enabledandtrained', XMLDB_INDEX_NOTUNIQUE, array('enabled', 'trained'));
1025         // Conditionally launch create table for analytics_models.
1026         if (!$dbman->table_exists($table)) {
1027             $dbman->create_table($table);
1028         }
1030         // Define table analytics_models_log to be created.
1031         $table = new xmldb_table('analytics_models_log');
1033         // Adding fields to table analytics_models_log.
1034         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1035         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1036         $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1037         $table->add_field('target', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1038         $table->add_field('indicators', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
1039         $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, null, null, null);
1040         $table->add_field('score', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0');
1041         $table->add_field('info', XMLDB_TYPE_TEXT, null, null, null, null, null);
1042         $table->add_field('dir', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
1043         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1044         $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1046         // Adding keys to table analytics_models_log.
1047         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1049         // Adding indexes to table analytics_models_log.
1050         $table->add_index('modelid', XMLDB_INDEX_NOTUNIQUE, array('modelid'));
1052         // Conditionally launch create table for analytics_models_log.
1053         if (!$dbman->table_exists($table)) {
1054             $dbman->create_table($table);
1055         }
1057         // Define table analytics_predictions to be created.
1058         $table = new xmldb_table('analytics_predictions');
1060         // Adding fields to table analytics_predictions.
1061         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1062         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1063         $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1064         $table->add_field('sampleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1065         $table->add_field('rangeindex', XMLDB_TYPE_INTEGER, '5', null, XMLDB_NOTNULL, null, null);
1066         $table->add_field('prediction', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null);
1067         $table->add_field('predictionscore', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null);
1068         $table->add_field('calculations', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
1069         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1071         // Adding keys to table analytics_predictions.
1072         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1074         // Adding indexes to table analytics_predictions.
1075         $table->add_index('modelidandcontextid', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'contextid'));
1077         // Conditionally launch create table for analytics_predictions.
1078         if (!$dbman->table_exists($table)) {
1079             $dbman->create_table($table);
1080         }
1082         // Define table analytics_train_samples to be created.
1083         $table = new xmldb_table('analytics_train_samples');
1085         // Adding fields to table analytics_train_samples.
1086         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1087         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1088         $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1089         $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1090         $table->add_field('fileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1091         $table->add_field('sampleids', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
1092         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1094         // Adding keys to table analytics_train_samples.
1095         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1097         // Adding indexes to table analytics_train_samples.
1098         $table->add_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
1099             array('modelid', 'analysableid', 'timesplitting'));
1101         // Conditionally launch create table for analytics_train_samples.
1102         if (!$dbman->table_exists($table)) {
1103             $dbman->create_table($table);
1104         }
1106         // Define table analytics_predict_ranges to be created.
1107         $table = new xmldb_table('analytics_predict_ranges');
1109         // Adding fields to table analytics_predict_ranges.
1110         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1111         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1112         $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1113         $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1114         $table->add_field('rangeindex', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1115         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1117         // Adding keys to table analytics_predict_ranges.
1118         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1120         // Adding indexes to table analytics_predict_ranges.
1121         $table->add_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
1122             array('modelid', 'analysableid', 'timesplitting'));
1124         // Conditionally launch create table for analytics_predict_ranges.
1125         if (!$dbman->table_exists($table)) {
1126             $dbman->create_table($table);
1127         }
1129         // Define table analytics_used_files to be created.
1130         $table = new xmldb_table('analytics_used_files');
1132         // Adding fields to table analytics_used_files.
1133         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1134         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1135         $table->add_field('fileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1136         $table->add_field('action', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
1137         $table->add_field('time', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
1139         // Adding keys to table analytics_used_files.
1140         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1142         // Adding indexes to table analytics_used_files.
1143         $table->add_index('modelidandfileidandaction', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'fileid', 'action'));
1145         // Conditionally launch create table for analytics_used_files.
1146         if (!$dbman->table_exists($table)) {
1147             $dbman->create_table($table);
1148         }
1150         $now = time();
1151         $admin = get_admin();
1153         $targetname = '\core\analytics\target\course_dropout';
1154         if (!$DB->record_exists('analytics_models', array('target' => $targetname))) {
1155             // We can not use API calls to create the built-in models.
1156             $modelobj = new stdClass();
1157             $modelobj->target = $targetname;
1158             $modelobj->indicators = json_encode(array(
1159                 '\mod_assign\analytics\indicator\cognitive_depth',
1160                 '\mod_assign\analytics\indicator\social_breadth',
1161                 '\mod_book\analytics\indicator\cognitive_depth',
1162                 '\mod_book\analytics\indicator\social_breadth',
1163                 '\mod_chat\analytics\indicator\cognitive_depth',
1164                 '\mod_chat\analytics\indicator\social_breadth',
1165                 '\mod_choice\analytics\indicator\cognitive_depth',
1166                 '\mod_choice\analytics\indicator\social_breadth',
1167                 '\mod_data\analytics\indicator\cognitive_depth',
1168                 '\mod_data\analytics\indicator\social_breadth',
1169                 '\mod_feedback\analytics\indicator\cognitive_depth',
1170                 '\mod_feedback\analytics\indicator\social_breadth',
1171                 '\mod_folder\analytics\indicator\cognitive_depth',
1172                 '\mod_folder\analytics\indicator\social_breadth',
1173                 '\mod_forum\analytics\indicator\cognitive_depth',
1174                 '\mod_forum\analytics\indicator\social_breadth',
1175                 '\mod_glossary\analytics\indicator\cognitive_depth',
1176                 '\mod_glossary\analytics\indicator\social_breadth',
1177                 '\mod_imscp\analytics\indicator\cognitive_depth',
1178                 '\mod_imscp\analytics\indicator\social_breadth',
1179                 '\mod_label\analytics\indicator\cognitive_depth',
1180                 '\mod_label\analytics\indicator\social_breadth',
1181                 '\mod_lesson\analytics\indicator\cognitive_depth',
1182                 '\mod_lesson\analytics\indicator\social_breadth',
1183                 '\mod_lti\analytics\indicator\cognitive_depth',
1184                 '\mod_lti\analytics\indicator\social_breadth',
1185                 '\mod_page\analytics\indicator\cognitive_depth',
1186                 '\mod_page\analytics\indicator\social_breadth',
1187                 '\mod_quiz\analytics\indicator\cognitive_depth',
1188                 '\mod_quiz\analytics\indicator\social_breadth',
1189                 '\mod_resource\analytics\indicator\cognitive_depth',
1190                 '\mod_resource\analytics\indicator\social_breadth',
1191                 '\mod_scorm\analytics\indicator\cognitive_depth',
1192                 '\mod_scorm\analytics\indicator\social_breadth',
1193                 '\mod_survey\analytics\indicator\cognitive_depth',
1194                 '\mod_survey\analytics\indicator\social_breadth',
1195                 '\mod_url\analytics\indicator\cognitive_depth',
1196                 '\mod_url\analytics\indicator\social_breadth',
1197                 '\mod_wiki\analytics\indicator\cognitive_depth',
1198                 '\mod_wiki\analytics\indicator\social_breadth',
1199                 '\mod_workshop\analytics\indicator\cognitive_depth',
1200                 '\mod_workshop\analytics\indicator\social_breadth',
1201             ));
1202             $modelobj->version = $now;
1203             $modelobj->timecreated = $now;
1204             $modelobj->timemodified = $now;
1205             $modelobj->usermodified = $admin->id;
1206             $DB->insert_record('analytics_models', $modelobj);
1207         }
1209         $targetname = '\core\analytics\target\no_teaching';
1210         if (!$DB->record_exists('analytics_models', array('target' => $targetname))) {
1211             $modelobj = new stdClass();
1212             $modelobj->enabled = 1;
1213             $modelobj->trained = 1;
1214             $modelobj->target = $targetname;
1215             $modelobj->indicators = json_encode(array('\core_course\analytics\indicator\no_teacher'));
1216             $modelobj->timesplitting = '\core\analytics\time_splitting\single_range';
1217             $modelobj->version = $now;
1218             $modelobj->timecreated = $now;
1219             $modelobj->timemodified = $now;
1220             $modelobj->usermodified = $admin->id;
1221             $DB->insert_record('analytics_models', $modelobj);
1222         }
1224         // Main savepoint reached.
1225         upgrade_main_savepoint(true, 2017072000.02);
1226     }
1228     if ($oldversion < 2017072700.01) {
1229         // Changing nullability of field email on table oauth2_system_account to null.
1230         $table = new xmldb_table('oauth2_system_account');
1231         $field = new xmldb_field('email', XMLDB_TYPE_TEXT, null, null, null, null, null, 'grantedscopes');
1233         // Launch change of nullability for field email.
1234         $dbman->change_field_notnull($table, $field);
1236         // Main savepoint reached.
1237         upgrade_main_savepoint(true, 2017072700.01);
1238     }
1240     if ($oldversion < 2017072700.02) {
1242         // If the site was previously registered with http://hub.moodle.org change the registration to
1243         // point to https://moodle.net - this is the correct hub address using https protocol.
1244         $oldhuburl = "http://hub.moodle.org";
1245         $newhuburl = "https://moodle.net";
1246         $cleanoldhuburl = preg_replace('/[^A-Za-z0-9_-]/i', '', $oldhuburl);
1247         $cleannewhuburl = preg_replace('/[^A-Za-z0-9_-]/i', '', $newhuburl);
1249         // Update existing registration.
1250         $DB->execute("UPDATE {registration_hubs} SET hubname = ?, huburl = ? WHERE huburl = ?",
1251             ['Moodle.net', $newhuburl, $oldhuburl]);
1253         // Update settings of existing registration.
1254         $sqlnamelike = $DB->sql_like('name', '?');
1255         $entries = $DB->get_records_sql("SELECT * FROM {config_plugins} where plugin=? and " . $sqlnamelike,
1256             ['hub', '%' . $DB->sql_like_escape('_' . $cleanoldhuburl)]);
1257         foreach ($entries as $entry) {
1258             $newname = substr($entry->name, 0, -strlen($cleanoldhuburl)) . $cleannewhuburl;
1259             try {
1260                 $DB->update_record('config_plugins', ['id' => $entry->id, 'name' => $newname]);
1261             } catch (dml_exception $e) {
1262                 // Entry with new name already exists, remove the one with an old name.
1263                 $DB->delete_records('config_plugins', ['id' => $entry->id]);
1264             }
1265         }
1267         // Update published courses.
1268         $DB->execute('UPDATE {course_published} SET huburl = ? WHERE huburl = ?', [$newhuburl, $oldhuburl]);
1270         // Main savepoint reached.
1271         upgrade_main_savepoint(true, 2017072700.02);
1272     }
1274     if ($oldversion < 2017080700.01) {
1276         // Get the table by its previous name.
1277         $table = new xmldb_table('analytics_predict_ranges');
1278         if ($dbman->table_exists($table)) {
1280             // We can only accept this because we are in master.
1281             $DB->delete_records('analytics_predictions');
1282             $DB->delete_records('analytics_used_files', array('action' => 'predicted'));
1283             $DB->delete_records('analytics_predict_ranges');
1285             // Define field sampleids to be added to analytics_predict_ranges (renamed below to analytics_predict_samples).
1286             $field = new xmldb_field('sampleids', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'rangeindex');
1288             // Conditionally launch add field sampleids.
1289             if (!$dbman->field_exists($table, $field)) {
1290                 $dbman->add_field($table, $field);
1291             }
1293             // Define field timemodified to be added to analytics_predict_ranges (renamed below to analytics_predict_samples).
1294             $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
1296             // Conditionally launch add field timemodified.
1297             if (!$dbman->field_exists($table, $field)) {
1298                 $dbman->add_field($table, $field);
1299             }
1301             // Rename the table to its new name.
1302             $dbman->rename_table($table, 'analytics_predict_samples');
1303         }
1305         $table = new xmldb_table('analytics_predict_samples');
1307         $index = new xmldb_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
1308             array('modelid', 'analysableid', 'timesplitting'));
1310         // Conditionally launch drop index.
1311         if ($dbman->index_exists($table, $index)) {
1312             $dbman->drop_index($table, $index);
1313         }
1315         $index = new xmldb_index('modelidandanalysableidandtimesplittingandrangeindex', XMLDB_INDEX_NOTUNIQUE,
1316             array('modelid', 'analysableid', 'timesplitting', 'rangeindex'));
1318         // Conditionally launch add index.
1319         if (!$dbman->index_exists($table, $index)) {
1320             $dbman->add_index($table, $index);
1321         }
1323         // Main savepoint reached.
1324         upgrade_main_savepoint(true, 2017080700.01);
1325     }
1327     if ($oldversion < 2017082200.00) {
1328         $plugins = ['radius', 'fc', 'nntp', 'pam', 'pop3', 'imap'];
1330         foreach ($plugins as $plugin) {
1331             // Check to see if the plugin exists on disk.
1332             // If it does not, remove the config for it.
1333             if (!file_exists($CFG->dirroot . "/auth/{$plugin}/auth.php")) {
1334                 // Clean config.
1335                 unset_all_config_for_plugin("auth_{$plugin}");
1336             }
1337         }
1338         upgrade_main_savepoint(true, 2017082200.00);
1339     }
1341     if ($oldversion < 2017082200.01) {
1343         // Define table analytics_indicator_calc to be created.
1344         $table = new xmldb_table('analytics_indicator_calc');
1346         // Adding fields to table analytics_indicator_calc.
1347         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1348         $table->add_field('starttime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1349         $table->add_field('endtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1350         $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1351         $table->add_field('sampleorigin', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1352         $table->add_field('sampleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1353         $table->add_field('indicator', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1354         $table->add_field('value', XMLDB_TYPE_NUMBER, '10, 2', null, null, null, null);
1355         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1357         // Adding keys to table analytics_indicator_calc.
1358         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1360         // Adding indexes to table analytics_indicator_calc.
1361         $table->add_index('starttime-endtime-contextid', XMLDB_INDEX_NOTUNIQUE, array('starttime', 'endtime', 'contextid'));
1363         // Conditionally launch create table for analytics_indicator_calc.
1364         if (!$dbman->table_exists($table)) {
1365             $dbman->create_table($table);
1366         }
1368         // Main savepoint reached.
1369         upgrade_main_savepoint(true, 2017082200.01);
1370     }
1372     if ($oldversion < 2017082300.01) {
1374         // This script in included in each major version upgrade process so make sure we don't run it twice.
1375         if (empty($CFG->linkcoursesectionsupgradescriptwasrun)) {
1376             // Check if the site is using a boost-based theme.
1377             // If value of 'linkcoursesections' is set to the old default value, change it to the new default.
1378             if (upgrade_theme_is_from_family('boost', $CFG->theme)) {
1379                 set_config('linkcoursesections', 1);
1380             }
1381             set_config('linkcoursesectionsupgradescriptwasrun', 1);
1382         }
1384         // Main savepoint reached.
1385         upgrade_main_savepoint(true, 2017082300.01);
1386     }
1388     if ($oldversion < 2017082500.00) {
1389         // Handle FKs for the table 'analytics_models_log'.
1390         $table = new xmldb_table('analytics_models_log');
1392         // Remove the existing index before adding FK (which creates an index).
1393         $index = new xmldb_index('modelid', XMLDB_INDEX_NOTUNIQUE, array('modelid'));
1395         // Conditionally launch drop index.
1396         if ($dbman->index_exists($table, $index)) {
1397             $dbman->drop_index($table, $index);
1398         }
1400         // Now, add the FK.
1401         $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1402         $dbman->add_key($table, $key);
1404         // Handle FKs for the table 'analytics_predictions'.
1405         $table = new xmldb_table('analytics_predictions');
1406         $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1407         $dbman->add_key($table, $key);
1409         $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
1410         $dbman->add_key($table, $key);
1412         // Handle FKs for the table 'analytics_train_samples'.
1413         $table = new xmldb_table('analytics_train_samples');
1414         $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1415         $dbman->add_key($table, $key);
1417         $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, array('fileid'), 'files', array('id'));
1418         $dbman->add_key($table, $key);
1420         // Handle FKs for the table 'analytics_predict_samples'.
1421         $table = new xmldb_table('analytics_predict_samples');
1422         $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1423         $dbman->add_key($table, $key);
1425         // Handle FKs for the table 'analytics_used_files'.
1426         $table = new xmldb_table('analytics_used_files');
1427         $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1428         $dbman->add_key($table, $key);
1430         $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, array('fileid'), 'files', array('id'));
1431         $dbman->add_key($table, $key);
1433         // Handle FKs for the table 'analytics_indicator_calc'.
1434         $table = new xmldb_table('analytics_indicator_calc');
1435         $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
1436         $dbman->add_key($table, $key);
1438         // Main savepoint reached.
1439         upgrade_main_savepoint(true, 2017082500.00);
1440     }
1442     if ($oldversion < 2017082800.00) {
1444         // Changing type of field prediction on table analytics_predictions to number.
1445         $table = new xmldb_table('analytics_predictions');
1446         $field = new xmldb_field('prediction', XMLDB_TYPE_NUMBER, '10, 2', null, XMLDB_NOTNULL, null, null, 'rangeindex');
1448         // Launch change of type for field prediction.
1449         $dbman->change_field_type($table, $field);
1451         // Main savepoint reached.
1452         upgrade_main_savepoint(true, 2017082800.00);
1453     }
1455     if ($oldversion < 2017090700.01) {
1457         // Define table analytics_prediction_actions to be created.
1458         $table = new xmldb_table('analytics_prediction_actions');
1460         // Adding fields to table analytics_prediction_actions.
1461         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1462         $table->add_field('predictionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1463         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1464         $table->add_field('actionname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1465         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1467         // Adding keys to table analytics_prediction_actions.
1468         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1469         $table->add_key('predictionid', XMLDB_KEY_FOREIGN, array('predictionid'), 'analytics_predictions', array('id'));
1470         $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1472         // Adding indexes to table analytics_prediction_actions.
1473         $table->add_index('predictionidanduseridandactionname', XMLDB_INDEX_NOTUNIQUE,
1474             array('predictionid', 'userid', 'actionname'));
1476         // Conditionally launch create table for analytics_prediction_actions.
1477         if (!$dbman->table_exists($table)) {
1478             $dbman->create_table($table);
1479         }
1481         // Main savepoint reached.
1482         upgrade_main_savepoint(true, 2017090700.01);
1483     }
1485     if ($oldversion < 2017091200.00) {
1486         // Force all messages to be reindexed.
1487         set_config('core_message_message_sent_lastindexrun', '0', 'core_search');
1488         set_config('core_message_message_received_lastindexrun', '0', 'core_search');
1490         // Main savepoint reached.
1491         upgrade_main_savepoint(true, 2017091200.00);
1492     }
1494     if ($oldversion < 2017091201.00) {
1495         // Define field userid to be added to task_adhoc.
1496         $table = new xmldb_table('task_adhoc');
1497         $field = new xmldb_field('userid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customdata');
1499         // Conditionally launch add field userid.
1500         if (!$dbman->field_exists($table, $field)) {
1501             $dbman->add_field($table, $field);
1502         }
1504         $key = new xmldb_key('useriduser', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1506         // Launch add key userid_user.
1507         $dbman->add_key($table, $key);
1509         // Main savepoint reached.
1510         upgrade_main_savepoint(true, 2017091201.00);
1511     }
1513     if ($oldversion < 2017092201.00) {
1515         // Remove duplicate registrations.
1516         $newhuburl = "https://moodle.net";
1517         $registrations = $DB->get_records('registration_hubs', ['huburl' => $newhuburl], 'confirmed DESC, id ASC');
1518         if (count($registrations) > 1) {
1519             $reg = array_shift($registrations);
1520             $DB->delete_records_select('registration_hubs', 'huburl = ? AND id <> ?', [$newhuburl, $reg->id]);
1521         }
1523         // Main savepoint reached.
1524         upgrade_main_savepoint(true, 2017092201.00);
1525     }
1527     if ($oldversion < 2017092202.00) {
1529         if (!file_exists($CFG->dirroot . '/blocks/messages/block_messages.php')) {
1531             // Delete instances.
1532             $instances = $DB->get_records_list('block_instances', 'blockname', ['messages']);
1533             $instanceids = array_keys($instances);
1535             if (!empty($instanceids)) {
1536                 $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
1537                 $DB->delete_records_list('block_instances', 'id', $instanceids);
1538                 list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
1539                 $params['contextlevel'] = CONTEXT_BLOCK;
1540                 $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
1542                 $preferences = array();
1543                 foreach ($instances as $instanceid => $instance) {
1544                     $preferences[] = 'block' . $instanceid . 'hidden';
1545                     $preferences[] = 'docked_block_instance_' . $instanceid;
1546                 }
1547                 $DB->delete_records_list('user_preferences', 'name', $preferences);
1548             }
1550             // Delete the block from the block table.
1551             $DB->delete_records('block', array('name' => 'messages'));
1553             // Remove capabilities.
1554             capabilities_cleanup('block_messages');
1556             // Clean config.
1557             unset_all_config_for_plugin('block_messages');
1558         }
1560         // Main savepoint reached.
1561         upgrade_main_savepoint(true, 2017092202.00);
1562     }
1564     if ($oldversion < 2017092700.00) {
1566         // Rename several fields in registration data to match the names of the properties that are sent to moodle.net.
1567         $renames = [
1568             'site_address_httpsmoodlenet' => 'site_street_httpsmoodlenet',
1569             'site_region_httpsmoodlenet' => 'site_regioncode_httpsmoodlenet',
1570             'site_country_httpsmoodlenet' => 'site_countrycode_httpsmoodlenet'];
1571         foreach ($renames as $oldparamname => $newparamname) {
1572             try {
1573                 $DB->execute("UPDATE {config_plugins} SET name = ? WHERE name = ? AND plugin = ?",
1574                     [$newparamname, $oldparamname, 'hub']);
1575             } catch (dml_exception $e) {
1576                 // Exception can happen if the config value with the new name already exists, ignore it and move on.
1577             }
1578         }
1580         // Main savepoint reached.
1581         upgrade_main_savepoint(true, 2017092700.00);
1582     }
1584     if ($oldversion < 2017092900.00) {
1585         // Define field categoryid to be added to event.
1586         $table = new xmldb_table('event');
1587         $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'format');
1589         // Conditionally launch add field categoryid.
1590         if (!$dbman->field_exists($table, $field)) {
1591             $dbman->add_field($table, $field);
1592         }
1594         // Add the categoryid key.
1595         $key = new xmldb_key('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'course_categories', array('id'));
1596         $dbman->add_key($table, $key);
1598         // Add a new index for groupid/courseid/categoryid/visible/userid.
1599         // Do this before we remove the old index.
1600         $index = new xmldb_index('groupid-courseid-categoryid-visible-userid', XMLDB_INDEX_NOTUNIQUE, array('groupid', 'courseid', 'categoryid', 'visible', 'userid'));
1601         if (!$dbman->index_exists($table, $index)) {
1602             $dbman->add_index($table, $index);
1603         }
1605         // Drop the old index.
1606         $index = new xmldb_index('groupid-courseid-visible-userid', XMLDB_INDEX_NOTUNIQUE, array('groupid', 'courseid', 'visible', 'userid'));
1607         if ($dbman->index_exists($table, $index)) {
1608             $dbman->drop_index($table, $index);
1609         }
1611         // Main savepoint reached.
1612         upgrade_main_savepoint(true, 2017092900.00);
1613     }
1615     if ($oldversion < 2017100900.00) {
1616         // Add index on time modified to grade_outcomes_history, grade_categories_history,
1617         // grade_items_history, and scale_history.
1618         $table = new xmldb_table('grade_outcomes_history');
1619         $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1621         if (!$dbman->index_exists($table, $index)) {
1622             $dbman->add_index($table, $index);
1623         }
1625         $table = new xmldb_table('grade_items_history');
1626         $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1628         if (!$dbman->index_exists($table, $index)) {
1629             $dbman->add_index($table, $index);
1630         }
1632         $table = new xmldb_table('grade_categories_history');
1633         $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1635         if (!$dbman->index_exists($table, $index)) {
1636             $dbman->add_index($table, $index);
1637         }
1639         $table = new xmldb_table('scale_history');
1640         $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1642         if (!$dbman->index_exists($table, $index)) {
1643             $dbman->add_index($table, $index);
1644         }
1646         // Main savepoint reached.
1647         upgrade_main_savepoint(true, 2017100900.00);
1648     }
1650     if ($oldversion < 2017101000.00) {
1652         // Define table analytics_used_analysables to be created.
1653         $table = new xmldb_table('analytics_used_analysables');
1655         // Adding fields to table analytics_used_analysables.
1656         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1657         $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1658         $table->add_field('action', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
1659         $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1660         $table->add_field('timeanalysed', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1662         // Adding keys to table analytics_used_analysables.
1663         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1664         $table->add_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1666         // Adding indexes to table analytics_used_analysables.
1667         $table->add_index('modelid-action', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'action'));
1669         // Conditionally launch create table for analytics_used_analysables.
1670         if (!$dbman->table_exists($table)) {
1671             $dbman->create_table($table);
1672         }
1674         // Main savepoint reached.
1675         upgrade_main_savepoint(true, 2017101000.00);
1676     }
1678     if ($oldversion < 2017101000.01) {
1679         // Define field override to be added to course_modules_completion.
1680         $table = new xmldb_table('course_modules_completion');
1681         $field = new xmldb_field('overrideby', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'viewed');
1683         // Conditionally launch add field override.
1684         if (!$dbman->field_exists($table, $field)) {
1685             $dbman->add_field($table, $field);
1686         }
1688         // Main savepoint reached.
1689         upgrade_main_savepoint(true, 2017101000.01);
1690     }
1692     if ($oldversion < 2017101000.02) {
1693         // Define field 'timestart' to be added to 'analytics_predictions'.
1694         $table = new xmldb_table('analytics_predictions');
1695         $field = new xmldb_field('timestart', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'timecreated');
1697         // Conditionally launch add field 'timestart'.
1698         if (!$dbman->field_exists($table, $field)) {
1699             $dbman->add_field($table, $field);
1700         }
1702         // Define field 'timeend' to be added to 'analytics_predictions'.
1703         $field = new xmldb_field('timeend', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'timestart');
1705         // Conditionally launch add field 'timeend'.
1706         if (!$dbman->field_exists($table, $field)) {
1707             $dbman->add_field($table, $field);
1708         }
1710         // Main savepoint reached.
1711         upgrade_main_savepoint(true, 2017101000.02);
1712     }
1714     if ($oldversion < 2017101200.00) {
1715         // Define table search_index_requests to be created.
1716         $table = new xmldb_table('search_index_requests');
1718         // Adding fields to table search_index_requests.
1719         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1720         $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1721         $table->add_field('searcharea', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1722         $table->add_field('timerequested', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1723         $table->add_field('partialarea', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1724         $table->add_field('partialtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1726         // Adding keys to table search_index_requests.
1727         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1728         $table->add_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
1730         // Conditionally launch create table for search_index_requests.
1731         if (!$dbman->table_exists($table)) {
1732             $dbman->create_table($table);
1733         }
1735         // Main savepoint reached.
1736         upgrade_main_savepoint(true, 2017101200.00);
1737     }
1739     // Index modification upgrade step.
1740     if ($oldversion < 2017101300.01) {
1742         $table = new xmldb_table('analytics_used_files');
1744         // Define index modelidandfileidandaction (not unique) to be dropped form analytics_used_files.
1745         $index = new xmldb_index('modelidandfileidandaction', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'fileid', 'action'));
1747         // Conditionally launch drop index modelidandfileidandaction.
1748         if ($dbman->index_exists($table, $index)) {
1749             $dbman->drop_index($table, $index);
1750         }
1752         // Define index modelidandactionandfileid (not unique) to be dropped form analytics_used_files.
1753         $index = new xmldb_index('modelidandactionandfileid', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'action', 'fileid'));
1755         // Conditionally launch add index modelidandactionandfileid.
1756         if (!$dbman->index_exists($table, $index)) {
1757             $dbman->add_index($table, $index);
1758         }
1760         // Main savepoint reached.
1761         upgrade_main_savepoint(true, 2017101300.01);
1762     }
1764     if ($oldversion < 2017101900.01) {
1766         $fs = get_file_storage();
1767         $models = $DB->get_records('analytics_models');
1768         foreach ($models as $model) {
1769             $files = $fs->get_directory_files(\context_system::instance()->id, 'analytics', 'unlabelled', $model->id,
1770                 '/analysable/', true, true);
1771             foreach ($files as $file) {
1772                 $file->delete();
1773             }
1774         }
1776         // Main savepoint reached.
1777         upgrade_main_savepoint(true, 2017101900.01);
1778     }
1780     if ($oldversion < 2017101900.02) {
1781         // Create adhoc task for upgrading of existing calendar events.
1782         $record = new \stdClass();
1783         $record->classname = '\core\task\refresh_mod_calendar_events_task';
1784         $record->component = 'core';
1786         // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
1787         $nextruntime = time() - 1;
1788         $record->nextruntime = $nextruntime;
1789         $DB->insert_record('task_adhoc', $record);
1791         // Main savepoint reached.
1792         upgrade_main_savepoint(true, 2017101900.02);
1793     }
1795     if ($oldversion < 2017102100.01) {
1796         // We will need to force them onto ssl if loginhttps is set.
1797         if (!empty($CFG->loginhttps)) {
1798             set_config('overridetossl', 1);
1799         }
1800         // Loginhttps should no longer be set.
1801         unset_config('loginhttps');
1803         // Main savepoint reached.
1804         upgrade_main_savepoint(true, 2017102100.01);
1805     }
1807     if ($oldversion < 2017110300.01) {
1809         // Define field categoryid to be added to event_subscriptions.
1810         $table = new xmldb_table('event_subscriptions');
1811         $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'url');
1813         // Conditionally launch add field categoryid.
1814         if (!$dbman->field_exists($table, $field)) {
1815             $dbman->add_field($table, $field);
1816         }
1818         // Main savepoint reached.
1819         upgrade_main_savepoint(true, 2017110300.01);
1820     }
1822     // Automatically generated Moodle v3.4.0 release upgrade line.
1823     // Put any upgrade step following this.
1825     if ($oldversion < 2017111300.02) {
1827         // Define field basicauth to be added to oauth2_issuer.
1828         $table = new xmldb_table('oauth2_issuer');
1829         $field = new xmldb_field('basicauth', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'showonloginpage');
1831         // Conditionally launch add field basicauth.
1832         if (!$dbman->field_exists($table, $field)) {
1833             $dbman->add_field($table, $field);
1834         }
1836         // Main savepoint reached.
1837         upgrade_main_savepoint(true, 2017111300.02);
1838     }
1840     if ($oldversion < 2017121200.00) {
1842         // Define key subscriptionid (foreign) to be added to event.
1843         $table = new xmldb_table('event');
1844         $key = new xmldb_key('subscriptionid', XMLDB_KEY_FOREIGN, array('subscriptionid'), 'event_subscriptions', array('id'));
1846         // Launch add key subscriptionid.
1847         $dbman->add_key($table, $key);
1849         // Define index uuid (not unique) to be added to event.
1850         $table = new xmldb_table('event');
1851         $index = new xmldb_index('uuid', XMLDB_INDEX_NOTUNIQUE, array('uuid'));
1853         // Conditionally launch add index uuid.
1854         if (!$dbman->index_exists($table, $index)) {
1855             $dbman->add_index($table, $index);
1856         }
1858         // Main savepoint reached.
1859         upgrade_main_savepoint(true, 2017121200.00);
1860     }
1862     if ($oldversion < 2017121900.00) {
1864         // Define table role_allow_view to be created.
1865         $table = new xmldb_table('role_allow_view');
1867         // Adding fields to table role_allow_view.
1868         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1869         $table->add_field('roleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1870         $table->add_field('allowview', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1872         // Adding keys to table role_allow_view.
1873         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1874         $table->add_key('roleid', XMLDB_KEY_FOREIGN, array('roleid'), 'role', array('id'));
1875         $table->add_key('allowview', XMLDB_KEY_FOREIGN, array('allowview'), 'role', array('id'));
1877         // Conditionally launch create table for role_allow_view.
1878         if (!$dbman->table_exists($table)) {
1879             $dbman->create_table($table);
1880         }
1882         $index = new xmldb_index('roleid-allowview', XMLDB_INDEX_UNIQUE, array('roleid', 'allowview'));
1884         // Conditionally launch add index roleid.
1885         if (!$dbman->index_exists($table, $index)) {
1886             $dbman->add_index($table, $index);
1887         }
1889         $roles = $DB->get_records('role', array(), 'sortorder ASC');
1891         $DB->delete_records('role_allow_view');
1892         foreach ($roles as $role) {
1893             foreach ($roles as $allowedrole) {
1894                 $record = new stdClass();
1895                 $record->roleid      = $role->id;
1896                 $record->allowview = $allowedrole->id;
1897                 $DB->insert_record('role_allow_view', $record);
1898             }
1899         }
1901         // Main savepoint reached.
1902         upgrade_main_savepoint(true, 2017121900.00);
1903     }
1905     if ($oldversion < 2017122200.01) {
1907         // Define field indexpriority to be added to search_index_requests. Allow null initially.
1908         $table = new xmldb_table('search_index_requests');
1909         $field = new xmldb_field('indexpriority', XMLDB_TYPE_INTEGER, '10',
1910                 null, null, null, null, 'partialtime');
1912         // Conditionally add field.
1913         if (!$dbman->field_exists($table, $field)) {
1914             $dbman->add_field($table, $field);
1916             // Set existing values to 'normal' value (100).
1917             $DB->set_field('search_index_requests', 'indexpriority', 100);
1919             // Now make the field 'NOT NULL'.
1920             $field = new xmldb_field('indexpriority', XMLDB_TYPE_INTEGER, '10',
1921                     null, XMLDB_NOTNULL, null, null, 'partialtime');
1922             $dbman->change_field_notnull($table, $field);
1923         }
1925         // Define index indexprioritytimerequested (not unique) to be added to search_index_requests.
1926         $index = new xmldb_index('indexprioritytimerequested', XMLDB_INDEX_NOTUNIQUE,
1927                 array('indexpriority', 'timerequested'));
1929         // Conditionally launch add index indexprioritytimerequested.
1930         if (!$dbman->index_exists($table, $index)) {
1931             $dbman->add_index($table, $index);
1932         }
1934         // Main savepoint reached.
1935         upgrade_main_savepoint(true, 2017122200.01);
1936     }
1938     if ($oldversion < 2018020500.00) {
1940         $topcategory = new stdClass();
1941         $topcategory->name = 'top'; // A non-real name for the top category. It will be localised at the display time.
1942         $topcategory->info = '';
1943         $topcategory->parent = 0;
1944         $topcategory->sortorder = 0;
1946         // Get the total record count - used for the progress bar.
1947         $total = $DB->count_records_sql("SELECT COUNT(DISTINCT contextid) FROM {question_categories} WHERE parent = 0");
1949         // Get the records themselves - a list of contextids.
1950         $rs = $DB->get_recordset_sql("SELECT DISTINCT contextid FROM {question_categories} WHERE parent = 0");
1952         // For each context, create a single top-level category.
1953         $i = 0;
1954         $pbar = new progress_bar('createtopquestioncategories', 500, true);
1955         foreach ($rs as $contextid => $notused) {
1956             $topcategory->contextid = $contextid;
1957             $topcategory->stamp = make_unique_id_code();
1959             $topcategoryid = $DB->insert_record('question_categories', $topcategory);
1961             $DB->set_field_select('question_categories', 'parent', $topcategoryid,
1962                     'contextid = ? AND id <> ? AND parent = 0',
1963                     array($contextid, $topcategoryid));
1965             // Update progress.
1966             $i++;
1967             $pbar->update($i, $total, "Creating top-level question categories - $i/$total.");
1968         }
1970         $rs->close();
1972         // Main savepoint reached.
1973         upgrade_main_savepoint(true, 2018020500.00);
1974     }
1976     if ($oldversion < 2018022800.01) {
1977         // Fix old block configurations that use the deprecated (and now removed) object class.
1978         upgrade_fix_block_instance_configuration();
1980         // Main savepoint reached.
1981         upgrade_main_savepoint(true, 2018022800.01);
1982     }
1984     if ($oldversion < 2018022800.02) {
1985         // Define index taggeditem (unique) to be dropped form tag_instance.
1986         $table = new xmldb_table('tag_instance');
1987         $index = new xmldb_index('taggeditem', XMLDB_INDEX_UNIQUE, array('component',
1988             'itemtype', 'itemid', 'tiuserid', 'tagid'));
1990         // Conditionally launch drop index taggeditem.
1991         if ($dbman->index_exists($table, $index)) {
1992             $dbman->drop_index($table, $index);
1993         }
1995         $index = new xmldb_index('taggeditem', XMLDB_INDEX_UNIQUE, array('component',
1996             'itemtype', 'itemid', 'contextid', 'tiuserid', 'tagid'));
1998         // Conditionally launch add index taggeditem.
1999         if (!$dbman->index_exists($table, $index)) {
2000             $dbman->add_index($table, $index);
2001         }
2003         // Main savepoint reached.
2004         upgrade_main_savepoint(true, 2018022800.02);
2005     }
2007     if ($oldversion < 2018022800.03) {
2009         // Define field multiplecontexts to be added to tag_area.
2010         $table = new xmldb_table('tag_area');
2011         $field = new xmldb_field('multiplecontexts', XMLDB_TYPE_INTEGER, '1', null,
2012             XMLDB_NOTNULL, null, '0', 'showstandard');
2014         // Conditionally launch add field multiplecontexts.
2015         if (!$dbman->field_exists($table, $field)) {
2016             $dbman->add_field($table, $field);
2017         }
2019         // Main savepoint reached.
2020         upgrade_main_savepoint(true, 2018022800.03);
2021     }
2023     if ($oldversion < 2018032200.01) {
2024         // Define table 'messages' to be created.
2025         $table = new xmldb_table('messages');
2027         // Adding fields to table 'messages'.
2028         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2029         $table->add_field('useridfrom', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2030         $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2031         $table->add_field('subject', XMLDB_TYPE_TEXT, null, null, null, null, null);
2032         $table->add_field('fullmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
2033         $table->add_field('fullmessageformat', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0);
2034         $table->add_field('fullmessagehtml', XMLDB_TYPE_TEXT, null, null, null, null, null);
2035         $table->add_field('smallmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
2036         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2038         // Adding keys to table 'messages'.
2039         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2040         $table->add_key('useridfrom', XMLDB_KEY_FOREIGN, array('useridfrom'), 'user', array('id'));
2041         $table->add_key('conversationid', XMLDB_KEY_FOREIGN, array('conversationid'), 'message_conversations', array('id'));
2043         // Conditionally launch create table for 'messages'.
2044         if (!$dbman->table_exists($table)) {
2045             $dbman->create_table($table);
2046         }
2048         // Define table 'message_conversations' to be created.
2049         $table = new xmldb_table('message_conversations');
2051         // Adding fields to table 'message_conversations'.
2052         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2053         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2055         // Adding keys to table 'message_conversations'.
2056         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2058         // Conditionally launch create table for 'message_conversations'.
2059         if (!$dbman->table_exists($table)) {
2060             $dbman->create_table($table);
2061         }
2063         // Define table 'message_conversation_members' to be created.
2064         $table = new xmldb_table('message_conversation_members');
2066         // Adding fields to table 'message_conversation_members'.
2067         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2068         $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2069         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2070         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2072         // Adding keys to table 'message_conversation_members'.
2073         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2074         $table->add_key('conversationid', XMLDB_KEY_FOREIGN, array('conversationid'), 'message_conversations', array('id'));
2075         $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
2077         // Conditionally launch create table for 'message_conversation_members'.
2078         if (!$dbman->table_exists($table)) {
2079             $dbman->create_table($table);
2080         }
2082         // Define table 'message_user_actions' to be created.
2083         $table = new xmldb_table('message_user_actions');
2085         // Adding fields to table 'message_user_actions'.
2086         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2087         $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2088         $table->add_field('messageid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2089         $table->add_field('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2090         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2092         // Adding keys to table 'message_user_actions'.
2093         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2094         $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
2095         $table->add_key('messageid', XMLDB_KEY_FOREIGN, array('messageid'), 'messages', array('id'));
2097         // Conditionally launch create table for 'message_user_actions'.
2098         if (!$dbman->table_exists($table)) {
2099             $dbman->create_table($table);
2100         }
2102         // Define table 'notifications' to be created.
2103         $table = new xmldb_table('notifications');
2105         // Adding fields to table 'notifications'.
2106         $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2107         $table->add_field('useridfrom', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2108         $table->add_field('useridto', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2109         $table->add_field('subject', XMLDB_TYPE_TEXT, null, null, null, null, null);
2110         $table->add_field('fullmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
2111         $table->add_field('fullmessageformat', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0);
2112         $table->add_field('fullmessagehtml', XMLDB_TYPE_TEXT, null, null, null, null, null);
2113         $table->add_field('smallmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
2114         $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null);
2115         $table->add_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null);
2116         $table->add_field('contexturl', XMLDB_TYPE_TEXT, null, null, null, null, null);
2117         $table->add_field('contexturlname', XMLDB_TYPE_TEXT, null, null, null, null, null);
2118         $table->add_field('timeread', XMLDB_TYPE_INTEGER, '10', null, false, null, null);
2119         $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2121         // Adding keys to table 'notifications'.
2122         $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2123         $table->add_key('useridto', XMLDB_KEY_FOREIGN, array('useridto'), 'user', array('id'));
2125         // Conditionally launch create table for 'notifications'.
2126         if (!$dbman->table_exists($table)) {
2127             $dbman->create_table($table);
2128         }
2130         // Main savepoint reached.
2131         upgrade_main_savepoint(true, 2018032200.01);
2132     }
2134     if ($oldversion < 2018032200.04) {
2135         // Define table 'message_conversations' to be updated.
2136         $table = new xmldb_table('message_conversations');
2137         $field = new xmldb_field('convhash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, 'id');
2139         // Conditionally launch add field 'convhash'.
2140         if (!$dbman->field_exists($table, $field)) {
2141             $dbman->add_field($table, $field);
2142         }
2144         // Conditionally launch add index.
2145         $index = new xmldb_index('convhash', XMLDB_INDEX_UNIQUE, array('convhash'));
2146         if (!$dbman->index_exists($table, $index)) {
2147             $dbman->add_index($table, $index);
2148         }
2150         // Main savepoint reached.
2151         upgrade_main_savepoint(true, 2018032200.04);
2152     }
2154     if ($oldversion < 2018032200.05) {
2155         // Drop table that is no longer needed.
2156         $table = new xmldb_table('message_working');
2157         if ($dbman->table_exists($table)) {
2158             $dbman->drop_table($table);
2159         }
2161         // Main savepoint reached.
2162         upgrade_main_savepoint(true, 2018032200.05);
2163     }
2165     if ($oldversion < 2018032200.06) {
2166         // Define table 'message_user_actions' to add an index to.
2167         $table = new xmldb_table('message_user_actions');
2169         // Conditionally launch add index.
2170         $index = new xmldb_index('userid_messageid_action', XMLDB_INDEX_UNIQUE, array('userid, messageid, action'));
2171         if (!$dbman->index_exists($table, $index)) {
2172             $dbman->add_index($table, $index);
2173         }
2175         // Main savepoint reached.
2176         upgrade_main_savepoint(true, 2018032200.06);
2177     }
2179     if ($oldversion < 2018032200.07) {
2180         // Define table 'messages' to add an index to.
2181         $table = new xmldb_table('messages');
2183         // Conditionally launch add index.
2184         $index = new xmldb_index('conversationid_timecreated', XMLDB_INDEX_NOTUNIQUE, array('conversationid, timecreated'));
2185         if (!$dbman->index_exists($table, $index)) {
2186             $dbman->add_index($table, $index);
2187         }
2189         // Main savepoint reached.
2190         upgrade_main_savepoint(true, 2018032200.07);
2191     }
2193     if ($oldversion < 2018032700.00) {
2195         // Update default search engine to search_simpledb if global search is disabled and there is no solr index defined.
2196         if (empty($CFG->enableglobalsearch) && empty(get_config('search_solr', 'indexname'))) {
2197             set_config('searchengine', 'simpledb');
2198         }
2199         upgrade_main_savepoint(true, 2018032700.00);
2200     }
2202     return true;