weekly release 3.9dev
[moodle.git] / lib / db / upgrade.php
CommitLineData
5b4a78e2 1<?php
5b4a78e2 2// This file is part of Moodle - http://moodle.org/
4e423cbf 3//
5b4a78e2
PS
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.
4e423cbf 8//
5b4a78e2
PS
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.
4e423cbf 13//
5b4a78e2
PS
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/>.
16
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 *
39b90b51
EL
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
5b4a78e2
PS
41 */
42
43defined('MOODLE_INTERNAL') || die();
4e423cbf 44
3406acde 45/**
39b90b51
EL
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
f9488a6f 49 * version is detected. It's in charge of performing the required tasks
39b90b51
EL
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",
f9488a6f 53 * each one performing one isolated (from the rest of steps) task. Usually
39b90b51
EL
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) {
f9488a6f 60 * // Explanation of the update step, linking to issue in the Tracker if necessary
39b90b51
EL
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
f9488a6f 77 * that such a file must be manually included from upgrade.php, and there are some restrictions
39b90b51
EL
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}
3406acde 83 *
3406acde 84 * @param int $oldversion
5b4a78e2 85 * @return bool always true
3406acde 86 */
775f811a 87function xmldb_main_upgrade($oldversion) {
e8c82aac 88 global $CFG, $DB;
4e423cbf 89
e8c82aac 90 require_once($CFG->libdir.'/db/upgradelib.php'); // Core Upgrade-related functions.
13a0d3d3 91
e8c82aac 92 $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
f33e1ed4 93
e8c82aac 94 // Always keep this upgrade step with version being the minimum
a12207be
EL
95 // allowed version to upgrade from (v3.2.0 right now).
96 if ($oldversion < 2016120500) {
e8c82aac 97 // Just in case somebody hacks upgrade scripts or env, we really can not continue.
a12207be 98 echo("You need to upgrade to 3.2.x or higher first!\n");
5c79b8ed 99 exit(1);
e8c82aac 100 // Note this savepoint is 100% unreachable, but needed to pass the upgrade checks.
a12207be 101 upgrade_main_savepoint(true, 2016120500);
5c79b8ed
PS
102 }
103
66b68d63 104 if ($oldversion < 2016122800.00) {
b1eb88a4
AG
105 // Find all roles with the coursecreator archetype.
106 $coursecreatorroleids = $DB->get_records('role', array('archetype' => 'coursecreator'), '', 'id');
107
108 $context = context_system::instance();
109 $capability = 'moodle/site:configview';
110
111 foreach ($coursecreatorroleids as $roleid => $notused) {
112
113 // Check that the capability has not already been assigned. If it has then it's either already set
114 // to allow or specifically set to prohibit or prevent.
115 if (!$DB->record_exists('role_capabilities', array('roleid' => $roleid, 'capability' => $capability))) {
116 // Assign the capability.
117 $cap = new stdClass();
118 $cap->contextid = $context->id;
119 $cap->roleid = $roleid;
120 $cap->capability = $capability;
121 $cap->permission = CAP_ALLOW;
122 $cap->timemodified = time();
123 $cap->modifierid = 0;
124
125 $DB->insert_record('role_capabilities', $cap);
126 }
127 }
b1eb88a4
AG
128
129 // Main savepoint reached.
66b68d63 130 upgrade_main_savepoint(true, 2016122800.00);
b1eb88a4
AG
131 }
132
98be2d20
RW
133 if ($oldversion < 2017020200.01) {
134
135 // Define index useridfrom_timeuserfromdeleted_notification (not unique) to be added to message.
136 $table = new xmldb_table('message');
137 $index = new xmldb_index('useridfrom_timeuserfromdeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridfrom', 'timeuserfromdeleted', 'notification'));
138
139 // Conditionally launch add index useridfrom_timeuserfromdeleted_notification.
140 if (!$dbman->index_exists($table, $index)) {
141 $dbman->add_index($table, $index);
142 }
143
144 // Define index useridto_timeusertodeleted_notification (not unique) to be added to message.
145 $index = new xmldb_index('useridto_timeusertodeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridto', 'timeusertodeleted', 'notification'));
146
147 // Conditionally launch add index useridto_timeusertodeleted_notification.
148 if (!$dbman->index_exists($table, $index)) {
149 $dbman->add_index($table, $index);
150 }
151
152 $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
153
154 // Conditionally launch drop index useridto.
155 if ($dbman->index_exists($table, $index)) {
156 $dbman->drop_index($table, $index);
157 }
158
159 // Main savepoint reached.
160 upgrade_main_savepoint(true, 2017020200.01);
161 }
162
163 if ($oldversion < 2017020200.02) {
164
165 // Define index useridfrom_timeuserfromdeleted_notification (not unique) to be added to message_read.
166 $table = new xmldb_table('message_read');
167 $index = new xmldb_index('useridfrom_timeuserfromdeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridfrom', 'timeuserfromdeleted', 'notification'));
168
169 // Conditionally launch add index useridfrom_timeuserfromdeleted_notification.
170 if (!$dbman->index_exists($table, $index)) {
171 $dbman->add_index($table, $index);
172 }
173
174 // Define index useridto_timeusertodeleted_notification (not unique) to be added to message_read.
175 $index = new xmldb_index('useridto_timeusertodeleted_notification', XMLDB_INDEX_NOTUNIQUE, array('useridto', 'timeusertodeleted', 'notification'));
176
177 // Conditionally launch add index useridto_timeusertodeleted_notification.
178 if (!$dbman->index_exists($table, $index)) {
179 $dbman->add_index($table, $index);
180 }
181
182 $index = new xmldb_index('useridto', XMLDB_INDEX_NOTUNIQUE, array('useridto'));
183
184 // Conditionally launch drop index useridto.
185 if ($dbman->index_exists($table, $index)) {
186 $dbman->drop_index($table, $index);
187 }
188
189 // Main savepoint reached.
190 upgrade_main_savepoint(true, 2017020200.02);
191 }
192
a5722727
MG
193 if ($oldversion < 2017020901.00) {
194
195 // Delete "orphaned" block positions. Note, the query does not use indexes (because there are none),
196 // if it runs too long during upgrade you can comment this line - it will leave orphaned records
197 // in the database but they won't bother you.
198 upgrade_block_positions();
199
200 // Main savepoint reached.
201 upgrade_main_savepoint(true, 2017020901.00);
202 }
203
f5af2e68 204 if ($oldversion < 2017021300.00) {
83806582 205 unset_config('loginpasswordautocomplete');
f5af2e68 206 upgrade_main_savepoint(true, 2017021300.00);
83806582
JT
207 }
208
8341055e
MG
209 if ($oldversion < 2017021400.00) {
210 // Define field visibleoncoursepage to be added to course_modules.
211 $table = new xmldb_table('course_modules');
212 $field = new xmldb_field('visibleoncoursepage', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'visible');
213
214 // Conditionally launch add field visibleoncoursepage.
215 if (!$dbman->field_exists($table, $field)) {
216 $dbman->add_field($table, $field);
217 }
218
219 // Main savepoint reached.
220 upgrade_main_savepoint(true, 2017021400.00);
221 }
222
342af35a 223 if ($oldversion < 2017030700.00) {
ca75ec4f
JP
224
225 // Define field priority to be added to event.
226 $table = new xmldb_table('event');
227 $field = new xmldb_field('priority', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'subscriptionid');
228
229 // Conditionally launch add field priority.
230 if (!$dbman->field_exists($table, $field)) {
231 $dbman->add_field($table, $field);
232 }
233
ca75ec4f 234 // Main savepoint reached.
342af35a 235 upgrade_main_savepoint(true, 2017030700.00);
ca75ec4f
JP
236 }
237
732bd131
DP
238 if ($oldversion < 2017031400.00) {
239
34df779a
AN
240 // Define table file_conversion to be created.
241 $table = new xmldb_table('file_conversion');
242
243 // Adding fields to table file_conversion.
244 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
245 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
246 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
247 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
248 $table->add_field('sourcefileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
249 $table->add_field('targetformat', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
250 $table->add_field('status', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
251 $table->add_field('statusmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
252 $table->add_field('converter', XMLDB_TYPE_CHAR, '255', null, null, null, null);
253 $table->add_field('destfileid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
254 $table->add_field('data', XMLDB_TYPE_TEXT, null, null, null, null, null);
255
256 // Adding keys to table file_conversion.
257 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
258 $table->add_key('sourcefileid', XMLDB_KEY_FOREIGN, array('sourcefileid'), 'files', array('id'));
259 $table->add_key('destfileid', XMLDB_KEY_FOREIGN, array('destfileid'), 'files', array('id'));
260
261 // Conditionally launch create table for file_conversion.
262 if (!$dbman->table_exists($table)) {
263 $dbman->create_table($table);
264 }
265
266 // Main savepoint reached.
732bd131 267 upgrade_main_savepoint(true, 2017031400.00);
34df779a
AN
268 }
269
2f090f46
EL
270 if ($oldversion < 2017040400.00) {
271
4671ae63 272 // If block_course_overview is no longer present, replace with block_myoverview.
2f090f46
EL
273 if (!file_exists($CFG->dirroot . '/blocks/course_overview/block_course_overview.php')) {
274 $DB->set_field('block_instances', 'blockname', 'myoverview', array('blockname' => 'course_overview'));
275 }
276
277 upgrade_main_savepoint(true, 2017040400.00);
278 }
279
280 if ($oldversion < 2017040401.00) {
281
4671ae63 282 // If block_course_overview is no longer present, remove it.
2f090f46 283 // Note - we do not need to completely remove the block context etc because we
4671ae63
RW
284 // have replaced all occurrences of block_course_overview with block_myoverview
285 // in the upgrade step above.
2f090f46
EL
286 if (!file_exists($CFG->dirroot . '/blocks/course_overview/block_course_overview.php')) {
287 // Delete the block from the block table.
288 $DB->delete_records('block', array('name' => 'course_overview'));
289 // Remove capabilities.
290 capabilities_cleanup('block_course_overview');
291 // Clean config.
292 unset_all_config_for_plugin('block_course_overview');
293 }
294
295 upgrade_main_savepoint(true, 2017040401.00);
296 }
297
298 if ($oldversion < 2017040402.00) {
299
300 // Define fields to be added to the 'event' table.
301 $table = new xmldb_table('event');
302 $fieldtype = new xmldb_field('type', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, 0, 'instance');
303 $fieldtimesort = new xmldb_field('timesort', XMLDB_TYPE_INTEGER, '10', null, false, null, null, 'timeduration');
304
305 // Conditionally launch add field.
306 if (!$dbman->field_exists($table, $fieldtype)) {
307 $dbman->add_field($table, $fieldtype);
308 }
309
310 // Conditionally launch add field.
311 if (!$dbman->field_exists($table, $fieldtimesort)) {
312 $dbman->add_field($table, $fieldtimesort);
313 }
314
315 // Now, define the index we will be adding.
316 $index = new xmldb_index('type-timesort', XMLDB_INDEX_NOTUNIQUE, array('type', 'timesort'));
317
318 // Conditionally launch add index.
319 if (!$dbman->index_exists($table, $index)) {
320 $dbman->add_index($table, $index);
321 }
322
323 upgrade_main_savepoint(true, 2017040402.00);
324 }
325
2f090f46 326 if ($oldversion < 2017040700.01) {
60237253 327
2b09b2da 328 // Define table oauth2_issuer to be created.
60237253
DW
329 $table = new xmldb_table('oauth2_issuer');
330
331 // Adding fields to table oauth2_issuer.
332 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
333 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
334 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
335 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
336 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
337 $table->add_field('image', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
338 $table->add_field('baseurl', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
339 $table->add_field('clientid', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
340 $table->add_field('clientsecret', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
485a22fc
DW
341 $table->add_field('loginscopes', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
342 $table->add_field('loginscopesoffline', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
343 $table->add_field('loginparams', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
344 $table->add_field('loginparamsoffline', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
c21a66e4 345 $table->add_field('alloweddomains', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
60237253
DW
346 $table->add_field('scopessupported', XMLDB_TYPE_TEXT, null, null, null, null, null);
347 $table->add_field('showonloginpage', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
eca128bf 348 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
60237253
DW
349 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
350
351 // Adding keys to table oauth2_issuer.
352 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
353
354 // Conditionally launch create table for oauth2_issuer.
355 if (!$dbman->table_exists($table)) {
356 $dbman->create_table($table);
357 }
358
359 // Main savepoint reached.
2f090f46 360 upgrade_main_savepoint(true, 2017040700.01);
60237253
DW
361 }
362
2f090f46 363 if ($oldversion < 2017040700.02) {
60237253
DW
364
365 // Define table oauth2_endpoint to be created.
366 $table = new xmldb_table('oauth2_endpoint');
367
368 // Adding fields to table oauth2_endpoint.
369 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
370 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
371 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
372 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
373 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
374 $table->add_field('url', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
375 $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
376
377 // Adding keys to table oauth2_endpoint.
378 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
379 $table->add_key('issuer_id_key', XMLDB_KEY_FOREIGN, array('issuerid'), 'oauth2_issuer', array('id'));
380
381 // Conditionally launch create table for oauth2_endpoint.
382 if (!$dbman->table_exists($table)) {
383 $dbman->create_table($table);
384 }
385
386 // Main savepoint reached.
2f090f46 387 upgrade_main_savepoint(true, 2017040700.02);
60237253
DW
388 }
389
2f090f46 390 if ($oldversion < 2017040700.03) {
60237253
DW
391
392 // Define table oauth2_system_account to be created.
393 $table = new xmldb_table('oauth2_system_account');
394
395 // Adding fields to table oauth2_system_account.
396 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
397 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
398 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
399 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
400 $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
401 $table->add_field('refreshtoken', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
402 $table->add_field('grantedscopes', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
28dddbc1
DW
403 $table->add_field('username', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
404 $table->add_field('email', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
60237253
DW
405
406 // Adding keys to table oauth2_system_account.
407 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
408 $table->add_key('issueridkey', XMLDB_KEY_FOREIGN_UNIQUE, array('issuerid'), 'oauth2_issuer', array('id'));
409
410 // Conditionally launch create table for oauth2_system_account.
411 if (!$dbman->table_exists($table)) {
412 $dbman->create_table($table);
413 }
414
415 // Main savepoint reached.
2f090f46 416 upgrade_main_savepoint(true, 2017040700.03);
60237253
DW
417 }
418
2f090f46 419 if ($oldversion < 2017040700.04) {
60237253 420
2b09b2da 421 // Define table oauth2_user_field_mapping to be created.
8445556b
DW
422 $table = new xmldb_table('oauth2_user_field_mapping');
423
424 // Adding fields to table oauth2_user_field_mapping.
425 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
426 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
427 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
428 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
429 $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
430 $table->add_field('externalfield', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null);
431 $table->add_field('internalfield', XMLDB_TYPE_CHAR, '64', null, XMLDB_NOTNULL, null, null);
432
433 // Adding keys to table oauth2_user_field_mapping.
434 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
435 $table->add_key('issuerkey', XMLDB_KEY_FOREIGN, array('issuerid'), 'oauth2_issuer', array('id'));
8445556b
DW
436 $table->add_key('uniqinternal', XMLDB_KEY_UNIQUE, array('issuerid', 'internalfield'));
437
438 // Conditionally launch create table for oauth2_user_field_mapping.
439 if (!$dbman->table_exists($table)) {
440 $dbman->create_table($table);
441 }
442
60237253 443 // Main savepoint reached.
2f090f46 444 upgrade_main_savepoint(true, 2017040700.04);
e6661428
JP
445 }
446
7f53e8aa
MG
447 if ($oldversion < 2017041801.00) {
448
449 // Define table course_completion_defaults to be created.
450 $table = new xmldb_table('course_completion_defaults');
451
452 // Adding fields to table course_completion_defaults.
453 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
454 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
455 $table->add_field('module', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
456 $table->add_field('completion', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
457 $table->add_field('completionview', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
458 $table->add_field('completionusegrade', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
459 $table->add_field('completionexpected', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
460 $table->add_field('customrules', XMLDB_TYPE_TEXT, null, null, null, null, null);
461
462 // Adding keys to table course_completion_defaults.
463 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
464 $table->add_key('module', XMLDB_KEY_FOREIGN, array('module'), 'modules', array('id'));
465 $table->add_key('course', XMLDB_KEY_FOREIGN, array('course'), 'course', array('id'));
466
467 // Adding indexes to table course_completion_defaults.
468 $table->add_index('coursemodule', XMLDB_INDEX_UNIQUE, array('course', 'module'));
469
470 // Conditionally launch create table for course_completion_defaults.
471 if (!$dbman->table_exists($table)) {
472 $dbman->create_table($table);
473 }
474
475 upgrade_main_savepoint(true, 2017041801.00);
476 }
477
c3b1178d
JP
478 if ($oldversion < 2017050500.01) {
479 // Get the list of parent event IDs.
480 $sql = "SELECT DISTINCT repeatid
481 FROM {event}
482 WHERE repeatid <> 0";
483 $parentids = array_keys($DB->get_records_sql($sql));
484 // Check if there are repeating events we need to process.
485 if (!empty($parentids)) {
486 // The repeat IDs of parent events should match their own ID.
487 // So we need to update parent events that have non-matching IDs and repeat IDs.
488 list($insql, $params) = $DB->get_in_or_equal($parentids);
489 $updatesql = "UPDATE {event}
490 SET repeatid = id
491 WHERE id <> repeatid
492 AND id $insql";
493 $DB->execute($updatesql, $params);
494 }
495
496 // Main savepoint reached.
497 upgrade_main_savepoint(true, 2017050500.01);
498 }
499
021a1439
JD
500 if ($oldversion < 2017050500.02) {
501 // MDL-58684:
502 // Remove all portfolio_tempdata records as these may contain serialized \file_system type objects, which are now unable to
503 // be unserialized because of changes to the file storage API made in MDL-46375. Portfolio now stores an id reference to
504 // files instead of the object.
505 // These records are normally removed after a successful export, however, can be left behind if the user abandons the
506 // export attempt (a stale record). Additionally, each stale record cannot be reused and is normally cleaned up by the cron
507 // task core\task\portfolio_cron_task. Since the cron task tries to unserialize them, and generates a warning, we'll remove
508 // all records here.
509 $DB->delete_records_select('portfolio_tempdata', 'id > ?', [0]);
510
511 // Main savepoint reached.
512 upgrade_main_savepoint(true, 2017050500.02);
513 }
514
79b80ee5
CB
515 if ($oldversion < 2017050900.01) {
516 // Create adhoc task for upgrading of existing calendar events.
517 $record = new \stdClass();
518 $record->classname = '\core\task\refresh_mod_calendar_events_task';
519 $record->component = 'core';
520
521 // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
522 $nextruntime = time() - 1;
523 $record->nextruntime = $nextruntime;
524 $DB->insert_record('task_adhoc', $record);
525
526 // Main savepoint reached.
527 upgrade_main_savepoint(true, 2017050900.01);
528 }
529
5e272283
EL
530 // Automatically generated Moodle v3.3.0 release upgrade line.
531 // Put any upgrade step following this.
532
a52d3abb 533 if ($oldversion < 2017061201.00) {
4ddf7c60
DG
534 $table = new xmldb_table('course_sections');
535 $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'availability');
536
f25e2b1d 537 // Define a field 'timemodified' in the 'course_sections' table.
4ddf7c60
DG
538 if (!$dbman->field_exists($table, $field)) {
539 $dbman->add_field($table, $field);
540 }
541
a52d3abb 542 upgrade_main_savepoint(true, 2017061201.00);
4ddf7c60
DG
543 }
544
56990700 545 if ($oldversion < 2017061301.00) {
c8f2e0e9
MN
546 // Check if the value of 'navcourselimit' is set to the old default value, if so, change it to the new default.
547 if ($CFG->navcourselimit == 20) {
548 set_config('navcourselimit', 10);
549 }
550
551 // Main savepoint reached.
56990700 552 upgrade_main_savepoint(true, 2017061301.00);
c8f2e0e9
MN
553 }
554
04d1f776 555 if ($oldversion < 2017071000.00) {
859e2033
DW
556
557 // Define field requireconfirmation to be added to oauth2_issuer.
558 $table = new xmldb_table('oauth2_issuer');
559 $field = new xmldb_field('requireconfirmation', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1', 'sortorder');
560
561 // Conditionally launch add field requireconfirmation.
562 if (!$dbman->field_exists($table, $field)) {
563 $dbman->add_field($table, $field);
564 }
565
566 // Main savepoint reached.
04d1f776 567 upgrade_main_savepoint(true, 2017071000.00);
859e2033
DW
568 }
569
1a54672f 570 if ($oldversion < 2017071001.00) {
557554f9 571
572 // Define field timemodified to be added to block_instances.
573 $table = new xmldb_table('block_instances');
574 $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null,
575 null, null, 'configdata');
576
577 // Conditionally launch add field timemodified.
578 if (!$dbman->field_exists($table, $field)) {
579 $dbman->add_field($table, $field);
580
581 // Set field to current time.
582 $DB->set_field('block_instances', 'timemodified', time());
583
584 // Changing nullability of field timemodified on table block_instances to not null.
585 $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL,
586 null, null, 'configdata');
587
588 // Launch change of nullability for field timemodified.
589 $dbman->change_field_notnull($table, $field);
590
591 // Define index timemodified (not unique) to be added to block_instances.
592 $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
593
594 // Conditionally launch add index timemodified.
595 if (!$dbman->index_exists($table, $index)) {
596 $dbman->add_index($table, $index);
597 }
598 }
599
600 // Define field timecreated to be added to block_instances.
601 $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null,
602 null, null, 'configdata');
603
604 // Conditionally launch add field timecreated.
605 if (!$dbman->field_exists($table, $field)) {
606 $dbman->add_field($table, $field);
607
608 // Set field to current time.
609 $DB->set_field('block_instances', 'timecreated', time());
610
611 // Changing nullability of field timecreated on table block_instances to not null.
612 $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL,
613 null, null, 'configdata');
614
615 // Launch change of nullability for field timecreated.
616 $dbman->change_field_notnull($table, $field);
617 }
618
619 // Main savepoint reached.
1a54672f 620 upgrade_main_savepoint(true, 2017071001.00);
557554f9 621 }
622
f84bdb43 623 if ($oldversion < 2017071100.00 ) {
f83d212b
EL
624 // Clean old upgrade setting not used anymore.
625 unset_config('upgrade_minmaxgradestepignored');
f84bdb43 626 upgrade_main_savepoint(true, 2017071100.00);
f83d212b
EL
627 }
628
e10b29ed 629 if ($oldversion < 2017072000.02) {
8473b735
DM
630
631 // Define table analytics_models to be created.
632 $table = new xmldb_table('analytics_models');
633
634 // Adding fields to table analytics_models.
635 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
636 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
637 $table->add_field('trained', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
638 $table->add_field('target', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
639 $table->add_field('indicators', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
640 $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, null, null, null);
641 $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
642 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
643 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
644 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
645
646 // Adding keys to table analytics_models.
647 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
648
649 // Adding indexes to table analytics_models.
650 $table->add_index('enabledandtrained', XMLDB_INDEX_NOTUNIQUE, array('enabled', 'trained'));
651
652 // Conditionally launch create table for analytics_models.
653 if (!$dbman->table_exists($table)) {
654 $dbman->create_table($table);
655 }
656
657 // Define table analytics_models_log to be created.
658 $table = new xmldb_table('analytics_models_log');
659
660 // Adding fields to table analytics_models_log.
661 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
662 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
663 $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
664 $table->add_field('target', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
665 $table->add_field('indicators', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
666 $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, null, null, null);
667 $table->add_field('score', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, '0');
668 $table->add_field('info', XMLDB_TYPE_TEXT, null, null, null, null, null);
669 $table->add_field('dir', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
670 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
671 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
672
673 // Adding keys to table analytics_models_log.
674 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
675
676 // Adding indexes to table analytics_models_log.
677 $table->add_index('modelid', XMLDB_INDEX_NOTUNIQUE, array('modelid'));
678
679 // Conditionally launch create table for analytics_models_log.
680 if (!$dbman->table_exists($table)) {
681 $dbman->create_table($table);
682 }
683
684 // Define table analytics_predictions to be created.
685 $table = new xmldb_table('analytics_predictions');
686
687 // Adding fields to table analytics_predictions.
688 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
689 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
690 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
691 $table->add_field('sampleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
692 $table->add_field('rangeindex', XMLDB_TYPE_INTEGER, '5', null, XMLDB_NOTNULL, null, null);
693 $table->add_field('prediction', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null);
694 $table->add_field('predictionscore', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null);
695 $table->add_field('calculations', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
696 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
697
698 // Adding keys to table analytics_predictions.
699 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
700
701 // Adding indexes to table analytics_predictions.
702 $table->add_index('modelidandcontextid', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'contextid'));
703
704 // Conditionally launch create table for analytics_predictions.
705 if (!$dbman->table_exists($table)) {
706 $dbman->create_table($table);
707 }
708
709 // Define table analytics_train_samples to be created.
710 $table = new xmldb_table('analytics_train_samples');
711
712 // Adding fields to table analytics_train_samples.
713 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
714 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
715 $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2834ea96 716 $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
8473b735
DM
717 $table->add_field('fileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
718 $table->add_field('sampleids', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
719 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
720
721 // Adding keys to table analytics_train_samples.
722 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
723
724 // Adding indexes to table analytics_train_samples.
413f19bc
DM
725 $table->add_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
726 array('modelid', 'analysableid', 'timesplitting'));
8473b735
DM
727
728 // Conditionally launch create table for analytics_train_samples.
729 if (!$dbman->table_exists($table)) {
730 $dbman->create_table($table);
731 }
732
733 // Define table analytics_predict_ranges to be created.
734 $table = new xmldb_table('analytics_predict_ranges');
735
736 // Adding fields to table analytics_predict_ranges.
737 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
738 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
739 $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2834ea96 740 $table->add_field('timesplitting', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
8473b735
DM
741 $table->add_field('rangeindex', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
742 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
743
744 // Adding keys to table analytics_predict_ranges.
745 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
746
747 // Adding indexes to table analytics_predict_ranges.
413f19bc
DM
748 $table->add_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
749 array('modelid', 'analysableid', 'timesplitting'));
8473b735
DM
750
751 // Conditionally launch create table for analytics_predict_ranges.
752 if (!$dbman->table_exists($table)) {
753 $dbman->create_table($table);
754 }
755
756 // Define table analytics_used_files to be created.
757 $table = new xmldb_table('analytics_used_files');
758
759 // Adding fields to table analytics_used_files.
760 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
761 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
762 $table->add_field('fileid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
763 $table->add_field('action', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
764 $table->add_field('time', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
765
766 // Adding keys to table analytics_used_files.
767 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
768
769 // Adding indexes to table analytics_used_files.
770 $table->add_index('modelidandfileidandaction', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'fileid', 'action'));
771
772 // Conditionally launch create table for analytics_used_files.
773 if (!$dbman->table_exists($table)) {
774 $dbman->create_table($table);
775 }
776
777 // Main savepoint reached.
e10b29ed 778 upgrade_main_savepoint(true, 2017072000.02);
8473b735
DM
779 }
780
3fa588c6
JD
781 if ($oldversion < 2017072700.01) {
782 // Changing nullability of field email on table oauth2_system_account to null.
783 $table = new xmldb_table('oauth2_system_account');
784 $field = new xmldb_field('email', XMLDB_TYPE_TEXT, null, null, null, null, null, 'grantedscopes');
785
786 // Launch change of nullability for field email.
787 $dbman->change_field_notnull($table, $field);
788
789 // Main savepoint reached.
790 upgrade_main_savepoint(true, 2017072700.01);
791 }
792
2c04945c 793 if ($oldversion < 2017072700.02) {
7d792aee
MG
794
795 // If the site was previously registered with http://hub.moodle.org change the registration to
796 // point to https://moodle.net - this is the correct hub address using https protocol.
797 $oldhuburl = "http://hub.moodle.org";
798 $newhuburl = "https://moodle.net";
799 $cleanoldhuburl = preg_replace('/[^A-Za-z0-9_-]/i', '', $oldhuburl);
800 $cleannewhuburl = preg_replace('/[^A-Za-z0-9_-]/i', '', $newhuburl);
801
802 // Update existing registration.
803 $DB->execute("UPDATE {registration_hubs} SET hubname = ?, huburl = ? WHERE huburl = ?",
804 ['Moodle.net', $newhuburl, $oldhuburl]);
805
806 // Update settings of existing registration.
807 $sqlnamelike = $DB->sql_like('name', '?');
808 $entries = $DB->get_records_sql("SELECT * FROM {config_plugins} where plugin=? and " . $sqlnamelike,
809 ['hub', '%' . $DB->sql_like_escape('_' . $cleanoldhuburl)]);
810 foreach ($entries as $entry) {
811 $newname = substr($entry->name, 0, -strlen($cleanoldhuburl)) . $cleannewhuburl;
9d18cfd0
MG
812 try {
813 $DB->update_record('config_plugins', ['id' => $entry->id, 'name' => $newname]);
814 } catch (dml_exception $e) {
815 // Entry with new name already exists, remove the one with an old name.
816 $DB->delete_records('config_plugins', ['id' => $entry->id]);
817 }
7d792aee
MG
818 }
819
820 // Update published courses.
821 $DB->execute('UPDATE {course_published} SET huburl = ? WHERE huburl = ?', [$newhuburl, $oldhuburl]);
822
823 // Main savepoint reached.
2c04945c 824 upgrade_main_savepoint(true, 2017072700.02);
7d792aee
MG
825 }
826
d5a99c45 827 if ($oldversion < 2017080700.01) {
00da1e60
DM
828
829 // Get the table by its previous name.
830 $table = new xmldb_table('analytics_predict_ranges');
831 if ($dbman->table_exists($table)) {
832
833 // We can only accept this because we are in master.
834 $DB->delete_records('analytics_predictions');
835 $DB->delete_records('analytics_used_files', array('action' => 'predicted'));
836 $DB->delete_records('analytics_predict_ranges');
837
838 // Define field sampleids to be added to analytics_predict_ranges (renamed below to analytics_predict_samples).
839 $field = new xmldb_field('sampleids', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'rangeindex');
840
841 // Conditionally launch add field sampleids.
842 if (!$dbman->field_exists($table, $field)) {
843 $dbman->add_field($table, $field);
844 }
845
846 // Define field timemodified to be added to analytics_predict_ranges (renamed below to analytics_predict_samples).
847 $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
848
849 // Conditionally launch add field timemodified.
850 if (!$dbman->field_exists($table, $field)) {
851 $dbman->add_field($table, $field);
852 }
853
854 // Rename the table to its new name.
855 $dbman->rename_table($table, 'analytics_predict_samples');
856 }
857
d5a99c45
DM
858 $table = new xmldb_table('analytics_predict_samples');
859
860 $index = new xmldb_index('modelidandanalysableidandtimesplitting', XMLDB_INDEX_NOTUNIQUE,
861 array('modelid', 'analysableid', 'timesplitting'));
862
863 // Conditionally launch drop index.
864 if ($dbman->index_exists($table, $index)) {
865 $dbman->drop_index($table, $index);
866 }
867
868 $index = new xmldb_index('modelidandanalysableidandtimesplittingandrangeindex', XMLDB_INDEX_NOTUNIQUE,
869 array('modelid', 'analysableid', 'timesplitting', 'rangeindex'));
870
871 // Conditionally launch add index.
872 if (!$dbman->index_exists($table, $index)) {
873 $dbman->add_index($table, $index);
874 }
875
00da1e60 876 // Main savepoint reached.
d5a99c45 877 upgrade_main_savepoint(true, 2017080700.01);
00da1e60
DM
878 }
879
1bf96e23
AN
880 if ($oldversion < 2017082200.00) {
881 $plugins = ['radius', 'fc', 'nntp', 'pam', 'pop3', 'imap'];
882
883 foreach ($plugins as $plugin) {
884 // Check to see if the plugin exists on disk.
885 // If it does not, remove the config for it.
886 if (!file_exists($CFG->dirroot . "/auth/{$plugin}/auth.php")) {
887 // Clean config.
888 unset_all_config_for_plugin("auth_{$plugin}");
889 }
890 }
891 upgrade_main_savepoint(true, 2017082200.00);
892 }
893
a7417383 894 if ($oldversion < 2017082200.01) {
0690a271
DM
895
896 // Define table analytics_indicator_calc to be created.
897 $table = new xmldb_table('analytics_indicator_calc');
898
899 // Adding fields to table analytics_indicator_calc.
900 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
901 $table->add_field('starttime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
902 $table->add_field('endtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
903 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
904 $table->add_field('sampleorigin', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
905 $table->add_field('sampleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
906 $table->add_field('indicator', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
907 $table->add_field('value', XMLDB_TYPE_NUMBER, '10, 2', null, null, null, null);
908 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
909
910 // Adding keys to table analytics_indicator_calc.
911 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
912
913 // Adding indexes to table analytics_indicator_calc.
914 $table->add_index('starttime-endtime-contextid', XMLDB_INDEX_NOTUNIQUE, array('starttime', 'endtime', 'contextid'));
915
916 // Conditionally launch create table for analytics_indicator_calc.
917 if (!$dbman->table_exists($table)) {
918 $dbman->create_table($table);
919 }
920
921 // Main savepoint reached.
a7417383 922 upgrade_main_savepoint(true, 2017082200.01);
0690a271
DM
923 }
924
fc7467e5 925 if ($oldversion < 2017082300.01) {
e46fde42
JO
926
927 // This script in included in each major version upgrade process so make sure we don't run it twice.
928 if (empty($CFG->linkcoursesectionsupgradescriptwasrun)) {
929 // Check if the site is using a boost-based theme.
930 // If value of 'linkcoursesections' is set to the old default value, change it to the new default.
931 if (upgrade_theme_is_from_family('boost', $CFG->theme)) {
932 set_config('linkcoursesections', 1);
933 }
934 set_config('linkcoursesectionsupgradescriptwasrun', 1);
935 }
936
937 // Main savepoint reached.
fc7467e5 938 upgrade_main_savepoint(true, 2017082300.01);
e46fde42
JO
939 }
940
7948dae1
MN
941 if ($oldversion < 2017082500.00) {
942 // Handle FKs for the table 'analytics_models_log'.
943 $table = new xmldb_table('analytics_models_log');
944
945 // Remove the existing index before adding FK (which creates an index).
946 $index = new xmldb_index('modelid', XMLDB_INDEX_NOTUNIQUE, array('modelid'));
947
948 // Conditionally launch drop index.
949 if ($dbman->index_exists($table, $index)) {
950 $dbman->drop_index($table, $index);
951 }
952
953 // Now, add the FK.
954 $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
955 $dbman->add_key($table, $key);
956
957 // Handle FKs for the table 'analytics_predictions'.
958 $table = new xmldb_table('analytics_predictions');
959 $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
960 $dbman->add_key($table, $key);
961
962 $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
963 $dbman->add_key($table, $key);
964
965 // Handle FKs for the table 'analytics_train_samples'.
966 $table = new xmldb_table('analytics_train_samples');
967 $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
968 $dbman->add_key($table, $key);
969
970 $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, array('fileid'), 'files', array('id'));
971 $dbman->add_key($table, $key);
972
973 // Handle FKs for the table 'analytics_predict_samples'.
974 $table = new xmldb_table('analytics_predict_samples');
975 $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
976 $dbman->add_key($table, $key);
977
978 // Handle FKs for the table 'analytics_used_files'.
979 $table = new xmldb_table('analytics_used_files');
980 $key = new xmldb_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
981 $dbman->add_key($table, $key);
982
983 $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, array('fileid'), 'files', array('id'));
984 $dbman->add_key($table, $key);
985
986 // Handle FKs for the table 'analytics_indicator_calc'.
987 $table = new xmldb_table('analytics_indicator_calc');
988 $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
989 $dbman->add_key($table, $key);
990
991 // Main savepoint reached.
992 upgrade_main_savepoint(true, 2017082500.00);
993 }
994
25f24df7 995 if ($oldversion < 2017082800.00) {
0f5fa169
DM
996
997 // Changing type of field prediction on table analytics_predictions to number.
998 $table = new xmldb_table('analytics_predictions');
999 $field = new xmldb_field('prediction', XMLDB_TYPE_NUMBER, '10, 2', null, XMLDB_NOTNULL, null, null, 'rangeindex');
1000
1001 // Launch change of type for field prediction.
1002 $dbman->change_field_type($table, $field);
1003
1004 // Main savepoint reached.
25f24df7 1005 upgrade_main_savepoint(true, 2017082800.00);
0f5fa169
DM
1006 }
1007
025363d1
DM
1008 if ($oldversion < 2017090700.01) {
1009
1010 // Define table analytics_prediction_actions to be created.
1011 $table = new xmldb_table('analytics_prediction_actions');
1012
1013 // Adding fields to table analytics_prediction_actions.
1014 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1015 $table->add_field('predictionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1016 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1017 $table->add_field('actionname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1018 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1019
1020 // Adding keys to table analytics_prediction_actions.
1021 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1022 $table->add_key('predictionid', XMLDB_KEY_FOREIGN, array('predictionid'), 'analytics_predictions', array('id'));
1023 $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1024
1025 // Adding indexes to table analytics_prediction_actions.
1026 $table->add_index('predictionidanduseridandactionname', XMLDB_INDEX_NOTUNIQUE,
1027 array('predictionid', 'userid', 'actionname'));
1028
1029 // Conditionally launch create table for analytics_prediction_actions.
1030 if (!$dbman->table_exists($table)) {
1031 $dbman->create_table($table);
1032 }
1033
1034 // Main savepoint reached.
1035 upgrade_main_savepoint(true, 2017090700.01);
1036 }
1037
77d2c7b9 1038 if ($oldversion < 2017091200.00) {
d08f1770
DM
1039 // Force all messages to be reindexed.
1040 set_config('core_message_message_sent_lastindexrun', '0', 'core_search');
1041 set_config('core_message_message_received_lastindexrun', '0', 'core_search');
1042
1043 // Main savepoint reached.
77d2c7b9 1044 upgrade_main_savepoint(true, 2017091200.00);
d08f1770
DM
1045 }
1046
59f431e8 1047 if ($oldversion < 2017091201.00) {
7e4c4b6f
AN
1048 // Define field userid to be added to task_adhoc.
1049 $table = new xmldb_table('task_adhoc');
1050 $field = new xmldb_field('userid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'customdata');
1051
1052 // Conditionally launch add field userid.
1053 if (!$dbman->field_exists($table, $field)) {
1054 $dbman->add_field($table, $field);
1055 }
1056
1057 $key = new xmldb_key('useriduser', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1058
1059 // Launch add key userid_user.
1060 $dbman->add_key($table, $key);
1061
1062 // Main savepoint reached.
59f431e8 1063 upgrade_main_savepoint(true, 2017091201.00);
7e4c4b6f
AN
1064 }
1065
9d18cfd0
MG
1066 if ($oldversion < 2017092201.00) {
1067
1068 // Remove duplicate registrations.
1069 $newhuburl = "https://moodle.net";
1070 $registrations = $DB->get_records('registration_hubs', ['huburl' => $newhuburl], 'confirmed DESC, id ASC');
1071 if (count($registrations) > 1) {
1072 $reg = array_shift($registrations);
1073 $DB->delete_records_select('registration_hubs', 'huburl = ? AND id <> ?', [$newhuburl, $reg->id]);
1074 }
1075
1076 // Main savepoint reached.
1077 upgrade_main_savepoint(true, 2017092201.00);
1078 }
1079
18348b07 1080 if ($oldversion < 2017092202.00) {
f3a3e234
AA
1081
1082 if (!file_exists($CFG->dirroot . '/blocks/messages/block_messages.php')) {
1083
1084 // Delete instances.
1085 $instances = $DB->get_records_list('block_instances', 'blockname', ['messages']);
1086 $instanceids = array_keys($instances);
1087
1088 if (!empty($instanceids)) {
1089 $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
1090 $DB->delete_records_list('block_instances', 'id', $instanceids);
1091 list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
1092 $params['contextlevel'] = CONTEXT_BLOCK;
1093 $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
1094
1095 $preferences = array();
1096 foreach ($instances as $instanceid => $instance) {
1097 $preferences[] = 'block' . $instanceid . 'hidden';
1098 $preferences[] = 'docked_block_instance_' . $instanceid;
1099 }
1100 $DB->delete_records_list('user_preferences', 'name', $preferences);
1101 }
1102
1103 // Delete the block from the block table.
1104 $DB->delete_records('block', array('name' => 'messages'));
1105
1106 // Remove capabilities.
1107 capabilities_cleanup('block_messages');
1108
1109 // Clean config.
1110 unset_all_config_for_plugin('block_messages');
1111 }
1112
839aa86f 1113 // Main savepoint reached.
18348b07 1114 upgrade_main_savepoint(true, 2017092202.00);
f3a3e234
AA
1115 }
1116
839aa86f
AN
1117 if ($oldversion < 2017092700.00) {
1118
ef467fff
MG
1119 // Rename several fields in registration data to match the names of the properties that are sent to moodle.net.
1120 $renames = [
1121 'site_address_httpsmoodlenet' => 'site_street_httpsmoodlenet',
1122 'site_region_httpsmoodlenet' => 'site_regioncode_httpsmoodlenet',
1123 'site_country_httpsmoodlenet' => 'site_countrycode_httpsmoodlenet'];
1124 foreach ($renames as $oldparamname => $newparamname) {
1125 try {
1126 $DB->execute("UPDATE {config_plugins} SET name = ? WHERE name = ? AND plugin = ?",
1127 [$newparamname, $oldparamname, 'hub']);
1128 } catch (dml_exception $e) {
1129 // Exception can happen if the config value with the new name already exists, ignore it and move on.
1130 }
1131 }
1132
1133 // Main savepoint reached.
839aa86f 1134 upgrade_main_savepoint(true, 2017092700.00);
ef467fff
MG
1135 }
1136
7b1e5e6f
AN
1137 if ($oldversion < 2017092900.00) {
1138 // Define field categoryid to be added to event.
1139 $table = new xmldb_table('event');
1140 $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'format');
1141
1142 // Conditionally launch add field categoryid.
1143 if (!$dbman->field_exists($table, $field)) {
1144 $dbman->add_field($table, $field);
1145 }
1146
1147 // Add the categoryid key.
1148 $key = new xmldb_key('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'course_categories', array('id'));
1149 $dbman->add_key($table, $key);
1150
1151 // Add a new index for groupid/courseid/categoryid/visible/userid.
1152 // Do this before we remove the old index.
1153 $index = new xmldb_index('groupid-courseid-categoryid-visible-userid', XMLDB_INDEX_NOTUNIQUE, array('groupid', 'courseid', 'categoryid', 'visible', 'userid'));
1154 if (!$dbman->index_exists($table, $index)) {
1155 $dbman->add_index($table, $index);
1156 }
1157
1158 // Drop the old index.
1159 $index = new xmldb_index('groupid-courseid-visible-userid', XMLDB_INDEX_NOTUNIQUE, array('groupid', 'courseid', 'visible', 'userid'));
1160 if ($dbman->index_exists($table, $index)) {
1161 $dbman->drop_index($table, $index);
1162 }
1163
1164 // Main savepoint reached.
1165 upgrade_main_savepoint(true, 2017092900.00);
1166 }
1167
2e30e9aa 1168 if ($oldversion < 2017100900.00) {
a8fe168e
DH
1169 // Add index on time modified to grade_outcomes_history, grade_categories_history,
1170 // grade_items_history, and scale_history.
1171 $table = new xmldb_table('grade_outcomes_history');
1172 $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1173
1174 if (!$dbman->index_exists($table, $index)) {
1175 $dbman->add_index($table, $index);
1176 }
1177
1178 $table = new xmldb_table('grade_items_history');
1179 $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1180
1181 if (!$dbman->index_exists($table, $index)) {
1182 $dbman->add_index($table, $index);
1183 }
1184
1185 $table = new xmldb_table('grade_categories_history');
1186 $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1187
1188 if (!$dbman->index_exists($table, $index)) {
1189 $dbman->add_index($table, $index);
1190 }
1191
1192 $table = new xmldb_table('scale_history');
1193 $index = new xmldb_index('timemodified', XMLDB_INDEX_NOTUNIQUE, array('timemodified'));
1194
1195 if (!$dbman->index_exists($table, $index)) {
1196 $dbman->add_index($table, $index);
1197 }
1198
1199 // Main savepoint reached.
2e30e9aa 1200 upgrade_main_savepoint(true, 2017100900.00);
a8fe168e
DH
1201 }
1202
69ed35c9 1203 if ($oldversion < 2017101000.00) {
dd13fc22
DM
1204
1205 // Define table analytics_used_analysables to be created.
1206 $table = new xmldb_table('analytics_used_analysables');
1207
1208 // Adding fields to table analytics_used_analysables.
1209 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1210 $table->add_field('modelid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1211 $table->add_field('action', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
1212 $table->add_field('analysableid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1213 $table->add_field('timeanalysed', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1214
1215 // Adding keys to table analytics_used_analysables.
1216 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1217 $table->add_key('modelid', XMLDB_KEY_FOREIGN, array('modelid'), 'analytics_models', array('id'));
1218
1219 // Adding indexes to table analytics_used_analysables.
1220 $table->add_index('modelid-action', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'action'));
1221
1222 // Conditionally launch create table for analytics_used_analysables.
1223 if (!$dbman->table_exists($table)) {
1224 $dbman->create_table($table);
1225 }
1226
1227 // Main savepoint reached.
69ed35c9 1228 upgrade_main_savepoint(true, 2017101000.00);
dd13fc22
DM
1229 }
1230
f4594a22 1231 if ($oldversion < 2017101000.01) {
a39918da
EEAK
1232 // Define field override to be added to course_modules_completion.
1233 $table = new xmldb_table('course_modules_completion');
1234 $field = new xmldb_field('overrideby', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'viewed');
1235
1236 // Conditionally launch add field override.
1237 if (!$dbman->field_exists($table, $field)) {
1238 $dbman->add_field($table, $field);
1239 }
1240
1241 // Main savepoint reached.
f4594a22 1242 upgrade_main_savepoint(true, 2017101000.01);
7f1b75ba 1243 }
0ce90263 1244
7f1b75ba 1245 if ($oldversion < 2017101000.02) {
235da74e
MN
1246 // Define field 'timestart' to be added to 'analytics_predictions'.
1247 $table = new xmldb_table('analytics_predictions');
1248 $field = new xmldb_field('timestart', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'timecreated');
1249
1250 // Conditionally launch add field 'timestart'.
1251 if (!$dbman->field_exists($table, $field)) {
1252 $dbman->add_field($table, $field);
1253 }
1254
1255 // Define field 'timeend' to be added to 'analytics_predictions'.
1256 $field = new xmldb_field('timeend', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'timestart');
1257
1258 // Conditionally launch add field 'timeend'.
1259 if (!$dbman->field_exists($table, $field)) {
1260 $dbman->add_field($table, $field);
1261 }
1262
1263 // Main savepoint reached.
0ce90263 1264 upgrade_main_savepoint(true, 2017101000.02);
a39918da
EEAK
1265 }
1266
e61ad18e 1267 if ($oldversion < 2017101200.00) {
eacb2bd1 1268 // Define table search_index_requests to be created.
1269 $table = new xmldb_table('search_index_requests');
1270
1271 // Adding fields to table search_index_requests.
1272 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1273 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1274 $table->add_field('searcharea', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1275 $table->add_field('timerequested', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1276 $table->add_field('partialarea', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
1277 $table->add_field('partialtime', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1278
1279 // Adding keys to table search_index_requests.
1280 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1281 $table->add_key('contextid', XMLDB_KEY_FOREIGN, array('contextid'), 'context', array('id'));
1282
1283 // Conditionally launch create table for search_index_requests.
1284 if (!$dbman->table_exists($table)) {
1285 $dbman->create_table($table);
1286 }
1287
1288 // Main savepoint reached.
e61ad18e 1289 upgrade_main_savepoint(true, 2017101200.00);
eacb2bd1 1290 }
1291
2dca1339
DM
1292 // Index modification upgrade step.
1293 if ($oldversion < 2017101300.01) {
1294
1295 $table = new xmldb_table('analytics_used_files');
1296
1297 // Define index modelidandfileidandaction (not unique) to be dropped form analytics_used_files.
1298 $index = new xmldb_index('modelidandfileidandaction', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'fileid', 'action'));
1299
1300 // Conditionally launch drop index modelidandfileidandaction.
1301 if ($dbman->index_exists($table, $index)) {
1302 $dbman->drop_index($table, $index);
1303 }
1304
1305 // Define index modelidandactionandfileid (not unique) to be dropped form analytics_used_files.
1306 $index = new xmldb_index('modelidandactionandfileid', XMLDB_INDEX_NOTUNIQUE, array('modelid', 'action', 'fileid'));
1307
1308 // Conditionally launch add index modelidandactionandfileid.
1309 if (!$dbman->index_exists($table, $index)) {
1310 $dbman->add_index($table, $index);
1311 }
1312
1313 // Main savepoint reached.
1314 upgrade_main_savepoint(true, 2017101300.01);
1315 }
28c97d1b
DM
1316
1317 if ($oldversion < 2017101900.01) {
1318
1319 $fs = get_file_storage();
1320 $models = $DB->get_records('analytics_models');
1321 foreach ($models as $model) {
1322 $files = $fs->get_directory_files(\context_system::instance()->id, 'analytics', 'unlabelled', $model->id,
1323 '/analysable/', true, true);
1324 foreach ($files as $file) {
1325 $file->delete();
1326 }
1327 }
1328
1329 // Main savepoint reached.
1330 upgrade_main_savepoint(true, 2017101900.01);
1331 }
1332
6b7194a7 1333 if ($oldversion < 2017101900.02) {
f10721d6
AN
1334 // Create adhoc task for upgrading of existing calendar events.
1335 $record = new \stdClass();
1336 $record->classname = '\core\task\refresh_mod_calendar_events_task';
1337 $record->component = 'core';
1338
1339 // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
1340 $nextruntime = time() - 1;
1341 $record->nextruntime = $nextruntime;
1342 $DB->insert_record('task_adhoc', $record);
1343
1344 // Main savepoint reached.
6b7194a7 1345 upgrade_main_savepoint(true, 2017101900.02);
f10721d6
AN
1346 }
1347
141c4adb 1348 if ($oldversion < 2017102100.01) {
cd1eb7ce
JO
1349 // We will need to force them onto ssl if loginhttps is set.
1350 if (!empty($CFG->loginhttps)) {
1351 set_config('overridetossl', 1);
1352 }
1353 // Loginhttps should no longer be set.
1354 unset_config('loginhttps');
1355
1356 // Main savepoint reached.
141c4adb 1357 upgrade_main_savepoint(true, 2017102100.01);
cd1eb7ce
JO
1358 }
1359
eb354bde 1360 if ($oldversion < 2017110300.01) {
b9fd5164
AN
1361
1362 // Define field categoryid to be added to event_subscriptions.
1363 $table = new xmldb_table('event_subscriptions');
1364 $field = new xmldb_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'url');
1365
1366 // Conditionally launch add field categoryid.
1367 if (!$dbman->field_exists($table, $field)) {
1368 $dbman->add_field($table, $field);
1369 }
1370
1371 // Main savepoint reached.
eb354bde 1372 upgrade_main_savepoint(true, 2017110300.01);
b9fd5164
AN
1373 }
1374
6499085f
EL
1375 // Automatically generated Moodle v3.4.0 release upgrade line.
1376 // Put any upgrade step following this.
1377
e968cf1d 1378 if ($oldversion < 2017111300.02) {
b3235085 1379
1380 // Define field basicauth to be added to oauth2_issuer.
1381 $table = new xmldb_table('oauth2_issuer');
1382 $field = new xmldb_field('basicauth', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'showonloginpage');
1383
1384 // Conditionally launch add field basicauth.
1385 if (!$dbman->field_exists($table, $field)) {
1386 $dbman->add_field($table, $field);
1387 }
1388
1389 // Main savepoint reached.
e968cf1d 1390 upgrade_main_savepoint(true, 2017111300.02);
b3235085 1391 }
1392
8cdfa869 1393 if ($oldversion < 2017121200.00) {
9d27b68c
SR
1394
1395 // Define key subscriptionid (foreign) to be added to event.
1396 $table = new xmldb_table('event');
1397 $key = new xmldb_key('subscriptionid', XMLDB_KEY_FOREIGN, array('subscriptionid'), 'event_subscriptions', array('id'));
1398
1399 // Launch add key subscriptionid.
1400 $dbman->add_key($table, $key);
1401
1402 // Define index uuid (not unique) to be added to event.
1403 $table = new xmldb_table('event');
1404 $index = new xmldb_index('uuid', XMLDB_INDEX_NOTUNIQUE, array('uuid'));
1405
1406 // Conditionally launch add index uuid.
1407 if (!$dbman->index_exists($table, $index)) {
1408 $dbman->add_index($table, $index);
1409 }
1410
1411 // Main savepoint reached.
8cdfa869 1412 upgrade_main_savepoint(true, 2017121200.00);
9d27b68c
SR
1413 }
1414
a63cd3e2
AH
1415 if ($oldversion < 2017121900.00) {
1416
1417 // Define table role_allow_view to be created.
1418 $table = new xmldb_table('role_allow_view');
1419
1420 // Adding fields to table role_allow_view.
1421 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1422 $table->add_field('roleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1423 $table->add_field('allowview', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1424
1425 // Adding keys to table role_allow_view.
1426 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1427 $table->add_key('roleid', XMLDB_KEY_FOREIGN, array('roleid'), 'role', array('id'));
1428 $table->add_key('allowview', XMLDB_KEY_FOREIGN, array('allowview'), 'role', array('id'));
1429
1430 // Conditionally launch create table for role_allow_view.
1431 if (!$dbman->table_exists($table)) {
1432 $dbman->create_table($table);
1433 }
1434
1435 $index = new xmldb_index('roleid-allowview', XMLDB_INDEX_UNIQUE, array('roleid', 'allowview'));
1436
1437 // Conditionally launch add index roleid.
1438 if (!$dbman->index_exists($table, $index)) {
1439 $dbman->add_index($table, $index);
1440 }
1441
1442 $roles = $DB->get_records('role', array(), 'sortorder ASC');
1443
1444 $DB->delete_records('role_allow_view');
1445 foreach ($roles as $role) {
1446 foreach ($roles as $allowedrole) {
1447 $record = new stdClass();
1448 $record->roleid = $role->id;
1449 $record->allowview = $allowedrole->id;
1450 $DB->insert_record('role_allow_view', $record);
1451 }
1452 }
1453
1454 // Main savepoint reached.
1455 upgrade_main_savepoint(true, 2017121900.00);
1456 }
1457
8736fbc1 1458 if ($oldversion < 2017122200.01) {
1459
1460 // Define field indexpriority to be added to search_index_requests. Allow null initially.
1461 $table = new xmldb_table('search_index_requests');
1462 $field = new xmldb_field('indexpriority', XMLDB_TYPE_INTEGER, '10',
1463 null, null, null, null, 'partialtime');
1464
1465 // Conditionally add field.
1466 if (!$dbman->field_exists($table, $field)) {
1467 $dbman->add_field($table, $field);
1468
1469 // Set existing values to 'normal' value (100).
1470 $DB->set_field('search_index_requests', 'indexpriority', 100);
1471
1472 // Now make the field 'NOT NULL'.
1473 $field = new xmldb_field('indexpriority', XMLDB_TYPE_INTEGER, '10',
1474 null, XMLDB_NOTNULL, null, null, 'partialtime');
1475 $dbman->change_field_notnull($table, $field);
1476 }
1477
1478 // Define index indexprioritytimerequested (not unique) to be added to search_index_requests.
1479 $index = new xmldb_index('indexprioritytimerequested', XMLDB_INDEX_NOTUNIQUE,
1480 array('indexpriority', 'timerequested'));
1481
1482 // Conditionally launch add index indexprioritytimerequested.
1483 if (!$dbman->index_exists($table, $index)) {
1484 $dbman->add_index($table, $index);
1485 }
1486
1487 // Main savepoint reached.
1488 upgrade_main_savepoint(true, 2017122200.01);
1489 }
1490
d2c4ff10
SR
1491 if ($oldversion < 2018020500.00) {
1492
1493 $topcategory = new stdClass();
1494 $topcategory->name = 'top'; // A non-real name for the top category. It will be localised at the display time.
1495 $topcategory->info = '';
1496 $topcategory->parent = 0;
1497 $topcategory->sortorder = 0;
1498
1499 // Get the total record count - used for the progress bar.
1500 $total = $DB->count_records_sql("SELECT COUNT(DISTINCT contextid) FROM {question_categories} WHERE parent = 0");
1501
1502 // Get the records themselves - a list of contextids.
1503 $rs = $DB->get_recordset_sql("SELECT DISTINCT contextid FROM {question_categories} WHERE parent = 0");
1504
1505 // For each context, create a single top-level category.
1506 $i = 0;
1507 $pbar = new progress_bar('createtopquestioncategories', 500, true);
1508 foreach ($rs as $contextid => $notused) {
1509 $topcategory->contextid = $contextid;
1510 $topcategory->stamp = make_unique_id_code();
1511
1512 $topcategoryid = $DB->insert_record('question_categories', $topcategory);
1513
1514 $DB->set_field_select('question_categories', 'parent', $topcategoryid,
1515 'contextid = ? AND id <> ? AND parent = 0',
1516 array($contextid, $topcategoryid));
1517
1518 // Update progress.
1519 $i++;
1520 $pbar->update($i, $total, "Creating top-level question categories - $i/$total.");
1521 }
1522
1523 $rs->close();
1524
1525 // Main savepoint reached.
1526 upgrade_main_savepoint(true, 2018020500.00);
1527 }
1528
e78849e8 1529 if ($oldversion < 2018022800.01) {
e78849e8
AG
1530 // Fix old block configurations that use the deprecated (and now removed) object class.
1531 upgrade_fix_block_instance_configuration();
1532
1533 // Main savepoint reached.
1534 upgrade_main_savepoint(true, 2018022800.01);
1535 }
1536
5436b0ed
RW
1537 if ($oldversion < 2018022800.02) {
1538 // Define index taggeditem (unique) to be dropped form tag_instance.
1539 $table = new xmldb_table('tag_instance');
1540 $index = new xmldb_index('taggeditem', XMLDB_INDEX_UNIQUE, array('component',
1541 'itemtype', 'itemid', 'tiuserid', 'tagid'));
1542
1543 // Conditionally launch drop index taggeditem.
1544 if ($dbman->index_exists($table, $index)) {
1545 $dbman->drop_index($table, $index);
1546 }
1547
1548 $index = new xmldb_index('taggeditem', XMLDB_INDEX_UNIQUE, array('component',
1549 'itemtype', 'itemid', 'contextid', 'tiuserid', 'tagid'));
1550
1551 // Conditionally launch add index taggeditem.
1552 if (!$dbman->index_exists($table, $index)) {
1553 $dbman->add_index($table, $index);
1554 }
1555
1556 // Main savepoint reached.
1557 upgrade_main_savepoint(true, 2018022800.02);
1558 }
1559
1560 if ($oldversion < 2018022800.03) {
1561
1562 // Define field multiplecontexts to be added to tag_area.
1563 $table = new xmldb_table('tag_area');
1564 $field = new xmldb_field('multiplecontexts', XMLDB_TYPE_INTEGER, '1', null,
1565 XMLDB_NOTNULL, null, '0', 'showstandard');
1566
1567 // Conditionally launch add field multiplecontexts.
1568 if (!$dbman->field_exists($table, $field)) {
1569 $dbman->add_field($table, $field);
1570 }
1571
1572 // Main savepoint reached.
1573 upgrade_main_savepoint(true, 2018022800.03);
1574 }
1575
a63f9824
MN
1576 if ($oldversion < 2018032200.01) {
1577 // Define table 'messages' to be created.
1578 $table = new xmldb_table('messages');
1579
1580 // Adding fields to table 'messages'.
1581 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1582 $table->add_field('useridfrom', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1583 $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1584 $table->add_field('subject', XMLDB_TYPE_TEXT, null, null, null, null, null);
1585 $table->add_field('fullmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
1586 $table->add_field('fullmessageformat', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0);
1587 $table->add_field('fullmessagehtml', XMLDB_TYPE_TEXT, null, null, null, null, null);
1588 $table->add_field('smallmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
1589 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1590
1591 // Adding keys to table 'messages'.
1592 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1593 $table->add_key('useridfrom', XMLDB_KEY_FOREIGN, array('useridfrom'), 'user', array('id'));
1594 $table->add_key('conversationid', XMLDB_KEY_FOREIGN, array('conversationid'), 'message_conversations', array('id'));
1595
1596 // Conditionally launch create table for 'messages'.
1597 if (!$dbman->table_exists($table)) {
1598 $dbman->create_table($table);
1599 }
1600
1601 // Define table 'message_conversations' to be created.
1602 $table = new xmldb_table('message_conversations');
1603
1604 // Adding fields to table 'message_conversations'.
1605 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1606 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1607
1608 // Adding keys to table 'message_conversations'.
1609 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1610
1611 // Conditionally launch create table for 'message_conversations'.
1612 if (!$dbman->table_exists($table)) {
1613 $dbman->create_table($table);
1614 }
1615
1616 // Define table 'message_conversation_members' to be created.
1617 $table = new xmldb_table('message_conversation_members');
1618
1619 // Adding fields to table 'message_conversation_members'.
1620 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1621 $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1622 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1623 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1624
1625 // Adding keys to table 'message_conversation_members'.
1626 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1627 $table->add_key('conversationid', XMLDB_KEY_FOREIGN, array('conversationid'), 'message_conversations', array('id'));
1628 $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1629
1630 // Conditionally launch create table for 'message_conversation_members'.
1631 if (!$dbman->table_exists($table)) {
1632 $dbman->create_table($table);
1633 }
1634
1635 // Define table 'message_user_actions' to be created.
1636 $table = new xmldb_table('message_user_actions');
1637
1638 // Adding fields to table 'message_user_actions'.
1639 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1640 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1641 $table->add_field('messageid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1642 $table->add_field('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1643 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1644
1645 // Adding keys to table 'message_user_actions'.
1646 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1647 $table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1648 $table->add_key('messageid', XMLDB_KEY_FOREIGN, array('messageid'), 'messages', array('id'));
1649
1650 // Conditionally launch create table for 'message_user_actions'.
1651 if (!$dbman->table_exists($table)) {
1652 $dbman->create_table($table);
1653 }
1654
1655 // Define table 'notifications' to be created.
1656 $table = new xmldb_table('notifications');
1657
1658 // Adding fields to table 'notifications'.
1659 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1660 $table->add_field('useridfrom', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1661 $table->add_field('useridto', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1662 $table->add_field('subject', XMLDB_TYPE_TEXT, null, null, null, null, null);
1663 $table->add_field('fullmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
1664 $table->add_field('fullmessageformat', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0);
1665 $table->add_field('fullmessagehtml', XMLDB_TYPE_TEXT, null, null, null, null, null);
1666 $table->add_field('smallmessage', XMLDB_TYPE_TEXT, null, null, null, null, null);
1667 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null);
1668 $table->add_field('eventtype', XMLDB_TYPE_CHAR, '100', null, null, null, null);
1669 $table->add_field('contexturl', XMLDB_TYPE_TEXT, null, null, null, null, null);
1670 $table->add_field('contexturlname', XMLDB_TYPE_TEXT, null, null, null, null, null);
1671 $table->add_field('timeread', XMLDB_TYPE_INTEGER, '10', null, false, null, null);
1672 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1673
1674 // Adding keys to table 'notifications'.
1675 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1676 $table->add_key('useridto', XMLDB_KEY_FOREIGN, array('useridto'), 'user', array('id'));
1677
1678 // Conditionally launch create table for 'notifications'.
1679 if (!$dbman->table_exists($table)) {
1680 $dbman->create_table($table);
1681 }
1682
1683 // Main savepoint reached.
1684 upgrade_main_savepoint(true, 2018032200.01);
1685 }
1686
b2cd17e6
MN
1687 if ($oldversion < 2018032200.04) {
1688 // Define table 'message_conversations' to be updated.
1689 $table = new xmldb_table('message_conversations');
d5458014 1690 $field = new xmldb_field('convhash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null, 'id');
b2cd17e6
MN
1691
1692 // Conditionally launch add field 'convhash'.
1693 if (!$dbman->field_exists($table, $field)) {
1694 $dbman->add_field($table, $field);
1695 }
1696
1697 // Conditionally launch add index.
1698 $index = new xmldb_index('convhash', XMLDB_INDEX_UNIQUE, array('convhash'));
1699 if (!$dbman->index_exists($table, $index)) {
1700 $dbman->add_index($table, $index);
1701 }
1702
1703 // Main savepoint reached.
1704 upgrade_main_savepoint(true, 2018032200.04);
1705 }
1706
0d657cc9
MN
1707 if ($oldversion < 2018032200.05) {
1708 // Drop table that is no longer needed.
1709 $table = new xmldb_table('message_working');
1710 if ($dbman->table_exists($table)) {
1711 $dbman->drop_table($table);
1712 }
1713
1714 // Main savepoint reached.
1715 upgrade_main_savepoint(true, 2018032200.05);
1716 }
1717
2ccbb8ed
MN
1718 if ($oldversion < 2018032200.06) {
1719 // Define table 'message_user_actions' to add an index to.
1720 $table = new xmldb_table('message_user_actions');
1721
1722 // Conditionally launch add index.
0410cee6 1723 $index = new xmldb_index('userid_messageid_action', XMLDB_INDEX_UNIQUE, array('userid', 'messageid', 'action'));
2ccbb8ed
MN
1724 if (!$dbman->index_exists($table, $index)) {
1725 $dbman->add_index($table, $index);
1726 }
1727
1728 // Main savepoint reached.
1729 upgrade_main_savepoint(true, 2018032200.06);
1730 }
1731
e159b53b
MN
1732 if ($oldversion < 2018032200.07) {
1733 // Define table 'messages' to add an index to.
1734 $table = new xmldb_table('messages');
1735
1736 // Conditionally launch add index.
0410cee6 1737 $index = new xmldb_index('conversationid_timecreated', XMLDB_INDEX_NOTUNIQUE, array('conversationid', 'timecreated'));
e159b53b
MN
1738 if (!$dbman->index_exists($table, $index)) {
1739 $dbman->add_index($table, $index);
1740 }
1741
1742 // Main savepoint reached.
1743 upgrade_main_savepoint(true, 2018032200.07);
1744 }
1745
bdb22af9 1746 if ($oldversion < 2018032700.00) {
c2e97077
DM
1747 // Update default search engine to search_simpledb if global search is disabled and there is no solr index defined.
1748 if (empty($CFG->enableglobalsearch) && empty(get_config('search_solr', 'indexname'))) {
1749 set_config('searchengine', 'simpledb');
1750 }
83c64f78
EL
1751
1752 // Main savepoint reached.
bdb22af9 1753 upgrade_main_savepoint(true, 2018032700.00);
c2e97077
DM
1754 }
1755
88cb8b78
SA
1756 if ($oldversion < 2018040500.01) {
1757
d842d9a9 1758 // Define field cohort to be added to theme. Allow null initially.
88cb8b78
SA
1759 $table = new xmldb_table('cohort');
1760 $field = new xmldb_field('theme', XMLDB_TYPE_CHAR, '50',
1761 null, null, null, null, 'timemodified');
1762
1763 // Conditionally add field.
1764 if (!$dbman->field_exists($table, $field)) {
1765 $dbman->add_field($table, $field);
1766 }
1767
1768 // Main savepoint reached.
1769 upgrade_main_savepoint(true, 2018040500.01);
1770 }
1771
4033c2a1 1772 if ($oldversion < 2018050900.01) {
b1f1bd2e
SA
1773 // Update default digital age consent map according to the current legislation on each country.
1774 $ageofdigitalconsentmap = implode(PHP_EOL, [
1775 '*, 16',
1776 'AT, 14',
1777 'ES, 14',
b1f1bd2e
SA
1778 'US, 13'
1779 ]);
1780 set_config('agedigitalconsentmap', $ageofdigitalconsentmap);
1781
1782 // Main savepoint reached.
4033c2a1 1783 upgrade_main_savepoint(true, 2018050900.01);
b1f1bd2e
SA
1784 }
1785
00977e98
EL
1786 // Automatically generated Moodle v3.5.0 release upgrade line.
1787 // Put any upgrade step following this.
1788
82b7ad70
DM
1789 if ($oldversion < 2018062800.01) {
1790 // Add foreign key fk_user to the comments table.
1791 $table = new xmldb_table('comments');
1792 $key = new xmldb_key('fk_user', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
1793 $dbman->add_key($table, $key);
1794
1795 upgrade_main_savepoint(true, 2018062800.01);
1796 }
1797
1798 if ($oldversion < 2018062800.02) {
1799 // Add composite index ix_concomitem to the table comments.
1800 $table = new xmldb_table('comments');
1801 $index = new xmldb_index('ix_concomitem', XMLDB_INDEX_NOTUNIQUE, array('contextid', 'commentarea', 'itemid'));
1802
1803 if (!$dbman->index_exists($table, $index)) {
1804 $dbman->add_index($table, $index);
1805 }
1806
1807 upgrade_main_savepoint(true, 2018062800.02);
1808 }
1809
a746b6e8 1810 if ($oldversion < 2018062800.03) {
ef4e04ee
MH
1811 // Define field location to be added to event.
1812 $table = new xmldb_table('event');
1813 $field = new xmldb_field('location', XMLDB_TYPE_TEXT, null, null, null, null, null, 'priority');
1814
1815 // Conditionally launch add field location.
1816 if (!$dbman->field_exists($table, $field)) {
1817 $dbman->add_field($table, $field);
1818 }
1819
1820 // Main savepoint reached.
a746b6e8 1821 upgrade_main_savepoint(true, 2018062800.03);
ef4e04ee
MH
1822 }
1823
3f0a60e3
SR
1824 if ($oldversion < 2018072500.00) {
1825 // Find all duplicate top level categories per context.
1826 $duplicates = $DB->get_records_sql("SELECT qc1.*
1827 FROM {question_categories} qc1
1828 JOIN {question_categories} qc2
1829 ON qc1.contextid = qc2.contextid AND qc1.id <> qc2.id
1830 WHERE qc1.parent = 0 AND qc2.parent = 0
1831 ORDER BY qc1.contextid, qc1.id");
1832
1833 // For each context, let the first top category to remain as top category and make the rest its children.
1834 $currentcontextid = 0;
1835 $chosentopid = 0;
1836 foreach ($duplicates as $duplicate) {
1837 if ($currentcontextid != $duplicate->contextid) {
1838 $currentcontextid = $duplicate->contextid;
1839 $chosentopid = $duplicate->id;
1840 } else {
1841 $DB->set_field('question_categories', 'parent', $chosentopid, ['id' => $duplicate->id]);
1842 }
1843 }
1844
1845 // Main savepoint reached.
1846 upgrade_main_savepoint(true, 2018072500.00);
1847 }
1848
1ffa22bb 1849 if ($oldversion < 2018073000.00) {
3412b12c
DW
1850 // Main savepoint reached.
1851 if (!file_exists($CFG->dirroot . '/admin/tool/assignmentupgrade/version.php')) {
1852 unset_all_config_for_plugin('tool_assignmentupgrade');
1853 }
1ffa22bb 1854 upgrade_main_savepoint(true, 2018073000.00);
3412b12c
DW
1855 }
1856
c69a43f2
MG
1857 if ($oldversion < 2018083100.01) {
1858 // Remove module associated blog posts for non-existent (deleted) modules.
1859 $sql = "SELECT ba.contextid as modcontextid
1860 FROM {blog_association} ba
1861 JOIN {post} p
1862 ON p.id = ba.blogid
1863 LEFT JOIN {context} c
1864 ON c.id = ba.contextid
1865 WHERE p.module = :module
1866 AND c.contextlevel IS NULL
1867 GROUP BY ba.contextid";
1868 if ($deletedmodules = $DB->get_records_sql($sql, array('module' => 'blog'))) {
1869 foreach ($deletedmodules as $module) {
1870 $assocblogids = $DB->get_fieldset_select('blog_association', 'blogid',
1871 'contextid = :contextid', ['contextid' => $module->modcontextid]);
1872 list($sql, $params) = $DB->get_in_or_equal($assocblogids, SQL_PARAMS_NAMED);
1873
1874 $DB->delete_records_select('tag_instance', "itemid $sql", $params);
1875 $DB->delete_records_select('post', "id $sql AND module = :module",
1876 array_merge($params, ['module' => 'blog']));
1877 $DB->delete_records('blog_association', ['contextid' => $module->modcontextid]);
1878 }
1879 }
d842d9a9 1880
c69a43f2
MG
1881 // Main savepoint reached.
1882 upgrade_main_savepoint(true, 2018083100.01);
1883 }
1884
66619627 1885 if ($oldversion < 2018091200.00) {
fdb45f79 1886 if (!file_exists($CFG->dirroot . '/cache/stores/memcache/settings.php')) {
66619627
AN
1887 unset_all_config_for_plugin('cachestore_memcache');
1888 }
1889
1890 upgrade_main_savepoint(true, 2018091200.00);
1891 }
1892
0e5144fe 1893 if ($oldversion < 2018091700.01) {
cbc3833d
MN
1894 // Remove unused setting.
1895 unset_config('messaginghidereadnotifications');
1896
1897 // Main savepoint reached.
0e5144fe 1898 upgrade_main_savepoint(true, 2018091700.01);
cbc3833d
MN
1899 }
1900
6189fda4
JB
1901 // Add idnumber fields to question and question_category tables.
1902 // This is done in four parts to aid error recovery during upgrade, should that occur.
1903 if ($oldversion < 2018092100.01) {
1904 $table = new xmldb_table('question');
1905 $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'modifiedby');
1906 if (!$dbman->field_exists($table, $field)) {
1907 $dbman->add_field($table, $field);
1908 }
1909 upgrade_main_savepoint(true, 2018092100.01);
1910 }
1911
1912 if ($oldversion < 2018092100.02) {
1913 $table = new xmldb_table('question');
b79482f5 1914 $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, array('category', 'idnumber'));
6189fda4
JB
1915 if (!$dbman->index_exists($table, $index)) {
1916 $dbman->add_index($table, $index);
1917 }
1918 upgrade_main_savepoint(true, 2018092100.02);
1919 }
1920
1921 if ($oldversion < 2018092100.03) {
1922 $table = new xmldb_table('question_categories');
1923 $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'sortorder');
1924 if (!$dbman->field_exists($table, $field)) {
1925 $dbman->add_field($table, $field);
1926 }
1927 upgrade_main_savepoint(true, 2018092100.03);
1928 }
1929
1930 if ($oldversion < 2018092100.04) {
1931 $table = new xmldb_table('question_categories');
b79482f5 1932 $index = new xmldb_index('contextididnumber', XMLDB_INDEX_UNIQUE, array('contextid', 'idnumber'));
6189fda4
JB
1933 if (!$dbman->index_exists($table, $index)) {
1934 $dbman->add_index($table, $index);
1935 }
1936 // Main savepoint reached.
1937 upgrade_main_savepoint(true, 2018092100.04);
1938 }
1939
d842d9a9
MN
1940 if ($oldversion < 2018092800.00) {
1941 // Alter the table 'message_contacts'.
1942 $table = new xmldb_table('message_contacts');
1943
1944 // Remove index so we can alter the fields.
1945 $index = new xmldb_index('userid-contactid', XMLDB_INDEX_UNIQUE, ['userid', 'contactid']);
1946 if ($dbman->index_exists($table, $index)) {
1947 $dbman->drop_index($table, $index);
1948 }
1949
1950 // Remove defaults of '0' from the 'userid' and 'contactid' fields.
1951 $field = new xmldb_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
1952 $dbman->change_field_default($table, $field);
1953
1954 $field = new xmldb_field('contactid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
1955 $dbman->change_field_default($table, $field);
1956
1957 // Add the missing FKs that will now be added to new installs.
1958 $key = new xmldb_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
1959 $dbman->add_key($table, $key);
1960
1961 $key = new xmldb_key('contactid', XMLDB_KEY_FOREIGN, ['contactid'], 'user', ['id']);
1962 $dbman->add_key($table, $key);
1963
1964 // Re-add the index.
1965 if (!$dbman->index_exists($table, $index)) {
1966 $dbman->add_index($table, $index);
1967 }
1968
1969 // Add the field 'timecreated'. Allow null, since existing records won't have an accurate value we can use.
1970 $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blocked');
1971 if (!$dbman->field_exists($table, $field)) {
1972 $dbman->add_field($table, $field);
1973 }
1974
1975 // Create new 'message_contact_requests' table.
1976 $table = new xmldb_table('message_contact_requests');
1977 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1978 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
1979 $table->add_field('requesteduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
1980 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'requesteduserid');
1981
1982 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
1983 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
1984 $table->add_key('requesteduserid', XMLDB_KEY_FOREIGN, ['requesteduserid'], 'user', ['id']);
1985
1986 $table->add_index('userid-requesteduserid', XMLDB_INDEX_UNIQUE, ['userid', 'requesteduserid']);
1987
1988 if (!$dbman->table_exists($table)) {
1989 $dbman->create_table($table);
1990 }
1991
1992 // Create new 'message_users_blocked' table.
1993 $table = new xmldb_table('message_users_blocked');
1994 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
1995 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
1996 $table->add_field('blockeduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
1997 // Allow NULLs in the 'timecreated' field because we will be moving existing data here that has no timestamp.
1998 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blockeduserid');
1999
2000 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
2001 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
2002 $table->add_key('blockeduserid', XMLDB_KEY_FOREIGN, ['blockeduserid'], 'user', ['id']);
2003
2004 $table->add_index('userid-blockeduserid', XMLDB_INDEX_UNIQUE, ['userid', 'blockeduserid']);
2005
2006 if (!$dbman->table_exists($table)) {
2007 $dbman->create_table($table);
2008 }
2009
2010 upgrade_main_savepoint(true, 2018092800.00);
2011 }
2012
4428b042
MN
2013 if ($oldversion < 2018092800.01) {
2014 // Move all the 'blocked' contacts to the new table 'message_users_blocked'.
2015 $updatesql = "INSERT INTO {message_users_blocked} (userid, blockeduserid, timecreated)
2016 SELECT userid, contactid, null as timecreated
2017 FROM {message_contacts}
2018 WHERE blocked = :blocked";
2019 $DB->execute($updatesql, ['blocked' => 1]);
2020
2021 // Removed the 'blocked' column from 'message_contacts'.
2022 $table = new xmldb_table('message_contacts');
2023 $field = new xmldb_field('blocked');
2024 $dbman->drop_field($table, $field);
2025
2026 upgrade_main_savepoint(true, 2018092800.01);
2027 }
2028
3ec5c770
MN
2029 if ($oldversion < 2018092800.02) {
2030 // Delete any contacts that are not mutual (meaning they both haven't added each other).
9c7a5526
MG
2031 do {
2032 $sql = "SELECT c1.id
2033 FROM {message_contacts} c1
2034 LEFT JOIN {message_contacts} c2
2035 ON c1.userid = c2.contactid
2036 AND c1.contactid = c2.userid
2037 WHERE c2.id IS NULL";
2038 if ($contacts = $DB->get_records_sql($sql, null, 0, 1000)) {
2039 list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
2040 $DB->delete_records_select('message_contacts', "id $insql", $inparams);
2041 }
2042 } while ($contacts);
3ec5c770
MN
2043
2044 upgrade_main_savepoint(true, 2018092800.02);
2045 }
2046
b65bfc8a
MN
2047 if ($oldversion < 2018092800.03) {
2048 // Remove any duplicate rows - from now on adding contacts just requires 1 row.
2049 // The person who made the contact request (userid) and the person who approved
2050 // it (contactid). Upgrade the table so that the first person to add the contact
2051 // was the one who made the request.
2052 $sql = "SELECT c1.id
2053 FROM {message_contacts} c1
2054 INNER JOIN {message_contacts} c2
2055 ON c1.userid = c2.contactid
2056 AND c1.contactid = c2.userid
2057 WHERE c1.id > c2.id";
2058 if ($contacts = $DB->get_records_sql($sql)) {
2059 list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
2060 $DB->delete_records_select('message_contacts', "id $insql", $inparams);
2061 }
2062
2063 upgrade_main_savepoint(true, 2018092800.03);
2064 }
2065
32b01d2b 2066 if ($oldversion < 2018101700.01) {
32791416
SA
2067 if (empty($CFG->keepmessagingallusersenabled)) {
2068 // When it is not set, $CFG->messagingallusers should be disabled by default.
2069 // When $CFG->messagingallusers = false, the default user preference is MESSAGE_PRIVACY_COURSEMEMBER
2070 // (contacted by users sharing a course).
2071 set_config('messagingallusers', false);
2072 } else {
2073 // When $CFG->keepmessagingallusersenabled is set to true, $CFG->messagingallusers is set to true.
32791416 2074 set_config('messagingallusers', true);
f7dfa9ba
SA
2075
2076 // When $CFG->messagingallusers = true, the default user preference is MESSAGE_PRIVACY_SITE
2077 // (contacted by all users site). So we need to set existing values from 0 (MESSAGE_PRIVACY_COURSEMEMBER)
2078 // to 2 (MESSAGE_PRIVACY_SITE).
2079 $DB->set_field(
2080 'user_preferences',
2081 'value',
2082 \core_message\api::MESSAGE_PRIVACY_SITE,
2083 array('name' => 'message_blocknoncontacts', 'value' => 0)
2084 );
32791416
SA
2085 }
2086
2087 // Main savepoint reached.
32b01d2b 2088 upgrade_main_savepoint(true, 2018101700.01);
32791416
SA
2089 }
2090
2ac4ea89 2091 if ($oldversion < 2018101800.00) {
1cb94eab
JD
2092 // Define table 'favourite' to be created.
2093 $table = new xmldb_table('favourite');
2094
1f3c76f0 2095 // Adding fields to table favourite.
1cb94eab
JD
2096 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2097 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2098 $table->add_field('itemtype', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2099 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2100 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2101 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
1f3c76f0 2102 $table->add_field('ordering', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
1cb94eab
JD
2103 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2104 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2105
1f3c76f0
JD
2106 // Adding keys to table favourite.
2107 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2108 $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
2109 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
2110
2111 // Adding indexes to table favourite.
2112 $table->add_index('uniqueuserfavouriteitem', XMLDB_INDEX_UNIQUE, ['component', 'itemtype', 'itemid', 'contextid', 'userid']);
1cb94eab 2113
1f3c76f0 2114 // Conditionally launch create table for favourite.
1cb94eab
JD
2115 if (!$dbman->table_exists($table)) {
2116 $dbman->create_table($table);
2117 }
2118
1cb94eab 2119 // Main savepoint reached.
2ac4ea89 2120 upgrade_main_savepoint(true, 2018101800.00);
1cb94eab
JD
2121 }
2122
7b73fd18 2123 if ($oldversion < 2018102200.00) {
59fa0137
MN
2124 // Add field 'type' to 'message_conversations'.
2125 $table = new xmldb_table('message_conversations');
2126 $field = new xmldb_field('type', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 1, 'id');
2127 if (!$dbman->field_exists($table, $field)) {
2128 $dbman->add_field($table, $field);
2129 }
2130
2131 // Add field 'name' to 'message_conversations'.
2132 $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'type');
2133 if (!$dbman->field_exists($table, $field)) {
2134 $dbman->add_field($table, $field);
2135 }
2136
2137 // Conditionally launch add index 'type'.
2138 $index = new xmldb_index('type', XMLDB_INDEX_NOTUNIQUE, ['type']);
2139 if (!$dbman->index_exists($table, $index)) {
2140 $dbman->add_index($table, $index);
2141 }
2142
e2a687f6
AA
2143 // Define table 'message_conversations' to be updated.
2144 $table = new xmldb_table('message_conversations');
2145
2146 // Remove the unique 'convhash' index, change to null and add a new non unique index.
f0e137c5 2147 $index = new xmldb_index('convhash', XMLDB_INDEX_UNIQUE, ['convhash']);
e2a687f6
AA
2148 if ($dbman->index_exists($table, $index)) {
2149 $dbman->drop_index($table, $index);
2150 }
2151
2152 $field = new xmldb_field('convhash', XMLDB_TYPE_CHAR, '40', null, null, null, null, 'name');
2153 $dbman->change_field_notnull($table, $field);
2154
f0e137c5 2155 $index = new xmldb_index('convhash', XMLDB_INDEX_NOTUNIQUE, ['convhash']);
e2a687f6
AA
2156 if (!$dbman->index_exists($table, $index)) {
2157 $dbman->add_index($table, $index);
2158 }
2159
7b73fd18 2160 upgrade_main_savepoint(true, 2018102200.00);
e2a687f6
AA
2161 }
2162
f0e137c5 2163 if ($oldversion < 2018102300.02) {
76540bec
MN
2164 // Alter 'message_conversations' table to support groups.
2165 $table = new xmldb_table('message_conversations');
2166 $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'convhash');
2167 if (!$dbman->field_exists($table, $field)) {
2168 $dbman->add_field($table, $field);
2169 }
2170
2171 $field = new xmldb_field('itemtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
2172 if (!$dbman->field_exists($table, $field)) {
2173 $dbman->add_field($table, $field);
2174 }
2175
2176 $field = new xmldb_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'itemtype');
2177 if (!$dbman->field_exists($table, $field)) {
2178 $dbman->add_field($table, $field);
2179 }
2180
2181 $field = new xmldb_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'itemid');
2182 if (!$dbman->field_exists($table, $field)) {
2183 $dbman->add_field($table, $field);
2184 }
2185
2186 $field = new xmldb_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'contextid');
2187 if (!$dbman->field_exists($table, $field)) {
2188 $dbman->add_field($table, $field);
2189 }
2190
2191 $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'enabled');
2192 if (!$dbman->field_exists($table, $field)) {
2193 $dbman->add_field($table, $field);
2194 }
2195
2196 // Add key.
2197 $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
2198 $dbman->add_key($table, $key);
2199
2200 // Add index.
06cdb82d 2201 $index = new xmldb_index('component-itemtype-itemid-contextid', XMLDB_INDEX_NOTUNIQUE, ['component', 'itemtype',
76540bec
MN
2202 'itemid', 'contextid']);
2203 if (!$dbman->index_exists($table, $index)) {
2204 $dbman->add_index($table, $index);
55fda006 2205 }
2206
f0e137c5 2207 upgrade_main_savepoint(true, 2018102300.02);
55fda006 2208 }
2209
d4274bd9 2210 if ($oldversion < 2018102900.00) {
ed12ba6b
DM
2211 // Define field predictionsprocessor to be added to analytics_models.
2212 $table = new xmldb_table('analytics_models');
2213 $field = new xmldb_field('predictionsprocessor', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timesplitting');
2214
2215 // Conditionally launch add field predictionsprocessor.
b4c33348
EL
2216 if (!$dbman->field_exists($table, $field)) {
2217 $dbman->add_field($table, $field);
2218 }
2219
ed12ba6b 2220 // Main savepoint reached.
d4274bd9 2221 upgrade_main_savepoint(true, 2018102900.00);
ed12ba6b
DM
2222 }
2223
5c145757 2224 if ($oldversion < 2018110500.01) {
d363a5c2
TT
2225 // Define fields to be added to the 'badge' table.
2226 $tablebadge = new xmldb_table('badge');
2227 $fieldversion = new xmldb_field('version', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'nextcron');
2228 $fieldlanguage = new xmldb_field('language', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'version');
2229 $fieldimageauthorname = new xmldb_field('imageauthorname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'language');
5a1ea828
SA
2230 $fieldimageauthoremail = new xmldb_field('imageauthoremail', XMLDB_TYPE_CHAR, '255', null, null,
2231 null, null, 'imageauthorname');
2232 $fieldimageauthorurl = new xmldb_field('imageauthorurl', XMLDB_TYPE_CHAR, '255', null, null,
2233 null, null, 'imageauthoremail');
d363a5c2
TT
2234 $fieldimagecaption = new xmldb_field('imagecaption', XMLDB_TYPE_TEXT, null, null, null, null, null, 'imageauthorurl');
2235
2236 if (!$dbman->field_exists($tablebadge, $fieldversion)) {
2237 $dbman->add_field($tablebadge, $fieldversion);
2238 }
2239 if (!$dbman->field_exists($tablebadge, $fieldlanguage)) {
2240 $dbman->add_field($tablebadge, $fieldlanguage);
2241 }
2242 if (!$dbman->field_exists($tablebadge, $fieldimageauthorname)) {
2243 $dbman->add_field($tablebadge, $fieldimageauthorname);
2244 }
2245 if (!$dbman->field_exists($tablebadge, $fieldimageauthoremail)) {
2246 $dbman->add_field($tablebadge, $fieldimageauthoremail);
2247 }
2248 if (!$dbman->field_exists($tablebadge, $fieldimageauthorurl)) {
2249 $dbman->add_field($tablebadge, $fieldimageauthorurl);
2250 }
2251 if (!$dbman->field_exists($tablebadge, $fieldimagecaption)) {
2252 $dbman->add_field($tablebadge, $fieldimagecaption);
2253 }
2254
2255 // Define table badge_endorsement to be created.
2256 $table = new xmldb_table('badge_endorsement');
2257
2258 // Adding fields to table badge_endorsement.
2259 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2260 $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2261 $table->add_field('issuername', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2262 $table->add_field('issuerurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2263 $table->add_field('issueremail', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2264 $table->add_field('claimid', XMLDB_TYPE_CHAR, '255', null, null, null, null);
2265 $table->add_field('claimcomment', XMLDB_TYPE_TEXT, null, null, null, null, null);
2266 $table->add_field('dateissued', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2267
2268 // Adding keys to table badge_endorsement.
2269 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2270 $table->add_key('endorsementbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
2271
2272 // Conditionally launch create table for badge_endorsement.
2273 if (!$dbman->table_exists($table)) {
2274 $dbman->create_table($table);
2275 }
2276
2277 // Define table badge_related to be created.
2278 $table = new xmldb_table('badge_related');
2279
2280 // Adding fields to table badge_related.
2281 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2282 $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2283 $table->add_field('relatedbadgeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2284
2285 // Adding keys to table badge_related.
2286 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
5a1ea828
SA
2287 $table->add_key('badgeid', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
2288 $table->add_key('relatedbadgeid', XMLDB_KEY_FOREIGN, ['relatedbadgeid'], 'badge', ['id']);
2289 $table->add_key('badgeid-relatedbadgeid', XMLDB_KEY_UNIQUE, ['badgeid', 'relatedbadgeid']);
d363a5c2
TT
2290
2291 // Conditionally launch create table for badge_related.
2292 if (!$dbman->table_exists($table)) {
2293 $dbman->create_table($table);
2294 }
2295
2296 // Define table badge_competencies to be created.
2297 $table = new xmldb_table('badge_competencies');
2298
2299 // Adding fields to table badge_competencies.
2300 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2301 $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2302 $table->add_field('targetname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2303 $table->add_field('targeturl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2304 $table->add_field('targetdescription', XMLDB_TYPE_TEXT, null, null, null, null, null);
2305 $table->add_field('targetframework', XMLDB_TYPE_CHAR, '255', null, null, null, null);
2306 $table->add_field('targetcode', XMLDB_TYPE_CHAR, '255', null, null, null, null);
2307
2308 // Adding keys to table badge_competencies.
2309 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2310 $table->add_key('competenciesbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
2311
2312 // Conditionally launch create table for badge_competencies.
2313 if (!$dbman->table_exists($table)) {
2314 $dbman->create_table($table);
2315 }
2316
2317 // Main savepoint reached.
5c145757 2318 upgrade_main_savepoint(true, 2018110500.01);
d363a5c2
TT
2319 }
2320
f4120740
DW
2321 if ($oldversion < 2018110700.01) {
2322 // This config setting added and then removed.
2323 unset_config('showcourseimages', 'moodlecourse');
2324
2325 // Main savepoint reached.
2326 upgrade_main_savepoint(true, 2018110700.01);
2327 }
2328
d27e4944 2329 if ($oldversion < 2018111301.00) {
0616f045
AN
2330 // Define field locked to be added to context.
2331 $table = new xmldb_table('context');
2332 $field = new xmldb_field('locked', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'depth');
2333
2334 // Conditionally launch add field locked.
2335 if (!$dbman->field_exists($table, $field)) {
2336 $dbman->add_field($table, $field);
2337 }
2338
2339 // Define field locked to be added to context_temp.
2340 $table = new xmldb_table('context_temp');
2341 $field = new xmldb_field('locked', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'depth');
2342
2343 // Conditionally launch add field locked.
2344 if (!$dbman->field_exists($table, $field)) {
2345 $dbman->add_field($table, $field);
2346 }
2347
2348 // Note: This change also requires a bump in is_major_upgrade_required.
d27e4944 2349 upgrade_main_savepoint(true, 2018111301.00);
0616f045
AN
2350 }
2351
18b94767 2352 if ($oldversion < 2018111900.00) {
329f1f23
MG
2353 // Update favourited courses, so they are saved in the particular course context instead of the system.
2354 $favouritedcourses = $DB->get_records('favourite', ['component' => 'core_course', 'itemtype' => 'courses']);
2355
2356 foreach ($favouritedcourses as $fc) {
2357 $coursecontext = \context_course::instance($fc->itemid);
2358 $fc->contextid = $coursecontext->id;
2359 $DB->update_record('favourite', $fc);
2360 }
2361
18b94767 2362 upgrade_main_savepoint(true, 2018111900.00);
329f1f23
MG
2363 }
2364
365dce5f 2365 if ($oldversion < 2018111900.01) {
f11a7d6a
JD
2366 // Define table oauth2_access_token to be created.
2367 $table = new xmldb_table('oauth2_access_token');
2368
2369 // Adding fields to table oauth2_access_token.
2370 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2371 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2372 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2373 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2374 $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2375 $table->add_field('token', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
2376 $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2377 $table->add_field('scope', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
2378
2379 // Adding keys to table oauth2_access_token.
2380 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2381 $table->add_key('issueridkey', XMLDB_KEY_FOREIGN_UNIQUE, ['issuerid'], 'oauth2_issuer', ['id']);
2382
2383 // Conditionally launch create table for oauth2_access_token.
2384 if (!$dbman->table_exists($table)) {
2385 $dbman->create_table($table);
2386 }
2387
2388 // Main savepoint reached.
365dce5f 2389 upgrade_main_savepoint(true, 2018111900.01);
f11a7d6a
JD
2390 }
2391
08cd1565 2392 if ($oldversion < 2018112000.00) {
6b036d04
SA
2393 // Update favourited conversations, so they are saved in the proper context instead of the system.
2394 $sql = "SELECT f.*, mc.contextid as conversationctx
2395 FROM {favourite} f
2396 JOIN {message_conversations} mc
2397 ON mc.id = f.itemid";
2398 $favouritedconversations = $DB->get_records_sql($sql);
2399 foreach ($favouritedconversations as $fc) {
2400 if (empty($fc->conversationctx)) {
2401 $conversationidctx = \context_user::instance($fc->userid)->id;
2402 } else {
2403 $conversationidctx = $fc->conversationctx;
2404 }
2405
2406 $DB->set_field('favourite', 'contextid', $conversationidctx, ['id' => $fc->id]);
2407 }
2408
08cd1565 2409 upgrade_main_savepoint(true, 2018112000.00);
6b036d04
SA
2410 }
2411
f47c8f35
EL
2412 // Automatically generated Moodle v3.6.0 release upgrade line.
2413 // Put any upgrade step following this.
2414
4b0cf053
MN
2415 if ($oldversion < 2018120300.01) {
2416 // Update the FB logo URL.
2417 $oldurl = 'https://facebookbrand.com/wp-content/themes/fb-branding/prj-fb-branding/assets/images/fb-art.png';
2418 $newurl = 'https://facebookbrand.com/wp-content/uploads/2016/05/flogo_rgb_hex-brc-site-250.png';
2419
2420 $updatesql = "UPDATE {oauth2_issuer}
2421 SET image = :newimage
607a6ca9 2422 WHERE " . $DB->sql_compare_text('image', 100). " = :oldimage";
4b0cf053
MN
2423 $params = [
2424 'newimage' => $newurl,
2425 'oldimage' => $oldurl
2426 ];
2427 $DB->execute($updatesql, $params);
2428
2429 upgrade_main_savepoint(true, 2018120300.01);
2430 }
2431
7bb22a29
MN
2432 if ($oldversion < 2018120300.02) {
2433 // Set all individual conversations to enabled.
2434 $updatesql = "UPDATE {message_conversations}
2435 SET enabled = :enabled
2436 WHERE type = :type";
2437 $DB->execute($updatesql, ['enabled' => 1, 'type' => 1]);
2438
2439 upgrade_main_savepoint(true, 2018120300.02);
2440 }
2441
f408e1f8
IT
2442 if ($oldversion < 2018120301.02) {
2443 upgrade_delete_orphaned_file_records();
2444 upgrade_main_savepoint(true, 2018120301.02);
2445 }
2446
af540d42
AN
2447 if ($oldversion < 2019011500.00) {
2448 // Define table task_log to be created.
2449 $table = new xmldb_table('task_log');
2450
2451 // Adding fields to table task_log.
2452 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2453 $table->add_field('type', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
2454 $table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2455 $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
2456 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2457 $table->add_field('timestart', XMLDB_TYPE_NUMBER, '20, 10', null, XMLDB_NOTNULL, null, null);
2458 $table->add_field('timeend', XMLDB_TYPE_NUMBER, '20, 10', null, XMLDB_NOTNULL, null, null);
2459 $table->add_field('dbreads', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2460 $table->add_field('dbwrites', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2461 $table->add_field('result', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null);
2462
2463 // Adding keys to table task_log.
2464 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2465
2466 // Adding indexes to table task_log.
2467 $table->add_index('classname', XMLDB_INDEX_NOTUNIQUE, ['classname']);
2468 $table->add_index('timestart', XMLDB_INDEX_NOTUNIQUE, ['timestart']);
2469
2470 // Conditionally launch create table for task_log.
2471 if (!$dbman->table_exists($table)) {
2472 $dbman->create_table($table);
2473 }
2474
2475 // Main savepoint reached.
2476 upgrade_main_savepoint(true, 2019011500.00);
2477 }
2478
4b71596f
AN
2479 if ($oldversion < 2019011501.00) {
2480 // Define field output to be added to task_log.
2481 $table = new xmldb_table('task_log');
2482 $field = new xmldb_field('output', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'result');
2483
2484 // Conditionally launch add field output.
2485 if (!$dbman->field_exists($table, $field)) {
2486 $dbman->add_field($table, $field);
2487 }
2488
2489 // Main savepoint reached.
2490 upgrade_main_savepoint(true, 2019011501.00);
2491 }
2492
1eeb465a
TBM
2493 if ($oldversion < 2019011801.00) {
2494
2495 // Define table customfield_category to be created.
2496 $table = new xmldb_table('customfield_category');
2497
2498 // Adding fields to table customfield_category.
2499 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2500 $table->add_field('name', XMLDB_TYPE_CHAR, '400', null, XMLDB_NOTNULL, null, null);
2501 $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null);
2502 $table->add_field('descriptionformat', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2503 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2504 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2505 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2506 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2507 $table->add_field('area', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2508 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
2509 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2510
2511 // Adding keys to table customfield_category.
2512 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2513 $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
2514
2515 // Adding indexes to table customfield_category.
2516 $table->add_index('component_area_itemid', XMLDB_INDEX_NOTUNIQUE, ['component', 'area', 'itemid', 'sortorder']);
2517
2518 // Conditionally launch create table for customfield_category.
2519 if (!$dbman->table_exists($table)) {
2520 $dbman->create_table($table);
2521 }
2522
2523 // Define table customfield_field to be created.
2524 $table = new xmldb_table('customfield_field');
2525
2526 // Adding fields to table customfield_field.
2527 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2528 $table->add_field('shortname', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2529 $table->add_field('name', XMLDB_TYPE_CHAR, '400', null, XMLDB_NOTNULL, null, null);
2530 $table->add_field('type', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
2531 $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null);
2532 $table->add_field('descriptionformat', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2533 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2534 $table->add_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2535 $table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, null, null, null);
2536 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2537 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2538
2539 // Adding keys to table customfield_field.
2540 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2541 $table->add_key('categoryid', XMLDB_KEY_FOREIGN, ['categoryid'], 'customfield_category', ['id']);
2542
2543 // Adding indexes to table customfield_field.
2544 $table->add_index('categoryid_sortorder', XMLDB_INDEX_NOTUNIQUE, ['categoryid', 'sortorder']);
2545
2546 // Conditionally launch create table for customfield_field.
2547 if (!$dbman->table_exists($table)) {
2548 $dbman->create_table($table);
2549 }
2550
2551 // Define table customfield_data to be created.
2552 $table = new xmldb_table('customfield_data');
2553
2554 // Adding fields to table customfield_data.
2555 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2556 $table->add_field('fieldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2557 $table->add_field('instanceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2558 $table->add_field('intvalue', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2559 $table->add_field('decvalue', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null);
2560 $table->add_field('shortcharvalue', XMLDB_TYPE_CHAR, '255', null, null, null, null);
2561 $table->add_field('charvalue', XMLDB_TYPE_CHAR, '1333', null, null, null, null);
2562 $table->add_field('value', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
2563 $table->add_field('valueformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2564 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2565 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2566 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
2567
2568 // Adding keys to table customfield_data.
2569 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2570 $table->add_key('fieldid', XMLDB_KEY_FOREIGN, ['fieldid'], 'customfield_field', ['id']);
2571 $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
2572
2573 // Adding indexes to table customfield_data.
2574 $table->add_index('instanceid-fieldid', XMLDB_INDEX_UNIQUE, ['instanceid', 'fieldid']);
2575 $table->add_index('fieldid-intvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'intvalue']);
2576 $table->add_index('fieldid-shortcharvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'shortcharvalue']);
2577 $table->add_index('fieldid-decvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'decvalue']);
2578
2579 // Conditionally launch create table for customfield_data.
2580 if (!$dbman->table_exists($table)) {
2581 $dbman->create_table($table);
2582 }
2583
2584 upgrade_main_savepoint(true, 2019011801.00);
2585 }
2586
85e62192 2587 if ($oldversion < 2019011801.01) {
d5ef6852
AW
2588
2589 // Delete all files that have been used in sections, which are already deleted.
2590 $sql = "SELECT DISTINCT f.itemid as sectionid, f.contextid
2591 FROM {files} f
2592 LEFT JOIN {course_sections} s ON f.itemid = s.id
2593 WHERE f.component = :component AND f.filearea = :filearea AND s.id IS NULL ";
2594
2595 $params = [
2596 'component' => 'course',
2597 'filearea' => 'section'
2598 ];
2599
2600 $stalefiles = $DB->get_recordset_sql($sql, $params);
2601
2602 $fs = get_file_storage();
2603 foreach ($stalefiles as $stalefile) {
2604 $fs->delete_area_files($stalefile->contextid, 'course', 'section', $stalefile->sectionid);
2605 }
2606 $stalefiles->close();
2607
85e62192 2608 upgrade_main_savepoint(true, 2019011801.01);
d5ef6852
AW
2609 }
2610
c5944a1d
DM
2611 if ($oldversion < 2019011801.02) {
2612 // Add index 'useridfrom' to the table 'notifications'.
2613 $table = new xmldb_table('notifications');
2614 $index = new xmldb_index('useridfrom', XMLDB_INDEX_NOTUNIQUE, ['useridfrom']);
2615
2616 if (!$dbman->index_exists($table, $index)) {
2617 $dbman->add_index($table, $index);
2618 }
2619
2620 upgrade_main_savepoint(true, 2019011801.02);
2621 }
2622
8516febd
JD
2623 if ($oldversion < 2019011801.03) {
2624 // Remove duplicate entries from group memberships.
2625 // Find records with multiple userid/groupid combinations and find the highest ID.
2626 // Later we will remove all those entries.
2627 $sql = "
2628 SELECT MIN(id) as minid, userid, groupid
2629 FROM {groups_members}
2630 GROUP BY userid, groupid
2631 HAVING COUNT(id) > 1";
2632 if ($duplicatedrows = $DB->get_recordset_sql($sql)) {
2633 foreach ($duplicatedrows as $row) {
2634 $DB->delete_records_select('groups_members',
2635 'userid = :userid AND groupid = :groupid AND id <> :minid', (array)$row);
2636 }
2637 }
2638 $duplicatedrows->close();
2639
2640 // Define key useridgroupid (unique) to be added to group_members.
2641 $table = new xmldb_table('groups_members');
2642 $key = new xmldb_key('useridgroupid', XMLDB_KEY_UNIQUE, array('userid', 'groupid'));
2643 // Launch add key useridgroupid.
2644 $dbman->add_key($table, $key);
8516febd
JD
2645 // Main savepoint reached.
2646 upgrade_main_savepoint(true, 2019011801.03);
2647 }
2648
b5b112f6
DM
2649 if ($oldversion < 2019021500.01) {
2650 $insights = $DB->get_record('message_providers', ['component' => 'moodle', 'name' => 'insights']);
6d6a83e9
AG
2651 if (!empty($insights)) {
2652 $insights->capability = null;
2653 $DB->update_record('message_providers', $insights);
2654 }
b5b112f6
DM
2655 upgrade_main_savepoint(true, 2019021500.01);
2656 }
2657
df4a17c7 2658 if ($oldversion < 2019021500.02) {
46014b83
MN
2659 // Default 'off' for existing sites as this is the behaviour they had earlier.
2660 set_config('messagingdefaultpressenter', false);
2661
2662 // Main savepoint reached.
df4a17c7 2663 upgrade_main_savepoint(true, 2019021500.02);
46014b83
MN
2664 }
2665
05506ead 2666 if ($oldversion < 2019030100.01) {
2085e860
DM
2667 // Create adhoc task to delete renamed My Course search area (ID core_course-mycourse).
2668 $record = new \stdClass();
2669 $record->classname = '\core\task\clean_up_deleted_search_area_task';
2670 $record->component = 'core';
2671
2672 // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
2673 $nextruntime = time() - 1;
2674 $record->nextruntime = $nextruntime;
2675 $record->customdata = json_encode('core_course-mycourse');
2676
2677 $DB->insert_record('task_adhoc', $record);
2678
2679 // Main savepoint reached.
05506ead 2680 upgrade_main_savepoint(true, 2019030100.01);
2085e860
DM
2681 }
2682
e97dfff7
DM
2683 if ($oldversion < 2019030700.01) {
2684
2685 // Define field evaluationmode to be added to analytics_models_log.
2686 $table = new xmldb_table('analytics_models_log');
2687 $field = new xmldb_field('evaluationmode', XMLDB_TYPE_CHAR, '50', null, null, null,
2688 null, 'version');
2689
2690 // Conditionally launch add field evaluationmode.
2691 if (!$dbman->field_exists($table, $field)) {
2692 $dbman->add_field($table, $field);
2693
2694 $updatesql = "UPDATE {analytics_models_log}
2695 SET evaluationmode = 'configuration'";
2696 $DB->execute($updatesql, []);
2697
2698 // Changing nullability of field evaluationmode on table block_instances to not null.
2699 $field = new xmldb_field('evaluationmode', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL,
2700 null, null, 'version');
2701
2702 // Launch change of nullability for field evaluationmode.
2703 $dbman->change_field_notnull($table, $field);
2704 }
2705
2706 // Main savepoint reached.
2707 upgrade_main_savepoint(true, 2019030700.01);
2708 }
2709
1fadad46
MN
2710 if ($oldversion < 2019030800.00) {
2711 // Define table 'message_conversation_actions' to be created.
2712 // Note - I would have preferred 'message_conversation_user_actions' but due to Oracle we can't. Boo.
2713 $table = new xmldb_table('message_conversation_actions');
2714
2715 // Adding fields to table 'message_conversation_actions'.
2716 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2717 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2718 $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2719 $table->add_field('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2720 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
2721
2722 // Adding keys to table 'message_conversation_actions'.
2723 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
2724 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
2725 $table->add_key('conversationid', XMLDB_KEY_FOREIGN, ['conversationid'], 'message_conversations', ['id']);
2726
2727 // Conditionally launch create table for 'message_conversation_actions'.
2728 if (!$dbman->table_exists($table)) {
2729 $dbman->create_table($table);
2730 }
2731
2732 // Main savepoint reached.
2733 upgrade_main_savepoint(true, 2019030800.00);
2734 }
2735
07a4698d
MN
2736 if ($oldversion < 2019030800.02) {
2737 // Remove any conversations and their members associated with non-existent groups.
2738 $sql = "SELECT mc.id
2739 FROM {message_conversations} mc
2740 LEFT JOIN {groups} g
2741 ON mc.itemid = g.id
2742 WHERE mc.component = :component
2743 AND mc.itemtype = :itemtype
2744 AND g.id is NULL";
2745 $conversations = $DB->get_records_sql($sql, ['component' => 'core_group', 'itemtype' => 'groups']);
2746
2747 if ($conversations) {
2748 $conversationids = array_keys($conversations);
2749
2750 $DB->delete_records_list('message_conversations', 'id', $conversationids);
2751 $DB->delete_records_list('message_conversation_members', 'conversationid', $conversationids);
2752 $DB->delete_records_list('message_conversation_actions', 'conversationid', $conversationids);
2753
2754 // Now, go through each conversation and delete any messages and related message actions.
2755 foreach ($conversationids as $conversationid) {
2756 if ($messages = $DB->get_records('messages', ['conversationid' => $conversationid])) {
2757 $messageids = array_keys($messages);
2758
2759 // Delete the actions.
2760 list($insql, $inparams) = $DB->get_in_or_equal($messageids);
2761 $DB->delete_records_select('message_user_actions', "messageid $insql", $inparams);
2762
2763 // Delete the messages.
2764 $DB->delete_records('messages', ['conversationid' => $conversationid]);
2765 }
2766 }
2767 }
2768
2769 // Main savepoint reached.
2770 upgrade_main_savepoint(true, 2019030800.02);
2771 }
2772
bd9fb479
EL
2773 if ($oldversion < 2019030800.03) {
2774
9b3580f4
DM
2775 // Add missing indicators to course_dropout.
2776 $params = [
2777 'target' => '\core\analytics\target\course_dropout',
2778 'trained' => 0,
2779 'enabled' => 0,
2780 ];
2781 $models = $DB->get_records('analytics_models', $params);
2782 foreach ($models as $model) {
2783 $indicators = json_decode($model->indicators);
2784
2785 $potentiallymissingindicators = [
2786 '\core_course\analytics\indicator\completion_enabled',
2787 '\core_course\analytics\indicator\potential_cognitive_depth',
2788 '\core_course\analytics\indicator\potential_social_breadth',
2789 '\core\analytics\indicator\any_access_after_end',
2790 '\core\analytics\indicator\any_access_before_start',
2791 '\core\analytics\indicator\any_write_action_in_course',
2792 '\core\analytics\indicator\read_actions'
2793 ];
2794
2795 $missing = false;
2796 foreach ($potentiallymissingindicators as $potentiallymissingindicator) {
2797 if (!in_array($potentiallymissingindicator, $indicators)) {
2798 // Add the missing indicator to sites upgraded before 2017072000.02.
2799 $indicators[] = $potentiallymissingindicator;
2800 $missing = true;
2801 }
2802 }
2803
2804 if ($missing) {
2805 $model->indicators = json_encode($indicators);
2806 $model->version = time();
2807 $model->timemodified = time();
2808 $DB->update_record('analytics_models', $model);
2809 }
2810 }
2811
2812 // Add missing indicators to no_teaching.
2813 $params = [
2814 'target' => '\core\analytics\target\no_teaching',
2815 ];
2816 $models = $DB->get_records('analytics_models', $params);
2817 foreach ($models as $model) {
2818 $indicators = json_decode($model->indicators);
2819 if (!in_array('\core_course\analytics\indicator\no_student', $indicators)) {
2820 // Add the missing indicator to sites upgraded before 2017072000.02.
2821
2822 $indicators[] = '\core_course\analytics\indicator\no_student';
2823
2824 $model->indicators = json_encode($indicators);
2825 $model->version = time();
2826 $model->timemodified = time();
2827 $DB->update_record('analytics_models', $model);
2828 }
2829 }
2830
2831 // Main savepoint reached.
bd9fb479 2832 upgrade_main_savepoint(true, 2019030800.03);
9b3580f4
DM
2833 }
2834
3576b66b
DM
2835 if ($oldversion < 2019031500.01) {
2836
2837 $defaulttimesplittings = get_config('analytics', 'timesplittings');
2838 if ($defaulttimesplittings !== false) {
2839 set_config('defaulttimesplittingsevaluation', $defaulttimesplittings, 'analytics');
2840 unset_config('timesplittings', 'analytics');
2841 }
2842
2843 // Main savepoint reached.
2844 upgrade_main_savepoint(true, 2019031500.01);
2845 }
2846
340f5c9e 2847 if ($oldversion < 2019032200.02) {
b29cfc58
DM
2848 // The no_teaching model might have been marked as not-trained by mistake (static models are always trained).
2849 $DB->set_field('analytics_models', 'trained', 1, ['target' => '\core\analytics\target\no_teaching']);
340f5c9e 2850 upgrade_main_savepoint(true, 2019032200.02);
b29cfc58
DM
2851 }
2852
e8bfd9b4
DW
2853 if ($oldversion < 2019032900.00) {
2854
2855 // Define table badge_competencies to be renamed to badge_alignment.
2856 $table = new xmldb_table('badge_competencies');
2857
2858 // Be careful if this step gets run twice.
2859 if ($dbman->table_exists($table)) {
2860 $key = new xmldb_key('competenciesbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
2861
2862 // Launch drop key competenciesbadge.
2863 $dbman->drop_key($table, $key);
2864
2865 $key = new xmldb_key('alignmentsbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
2866
2867 // Launch add key alignmentsbadge.
2868 $dbman->add_key($table, $key);
2869
2870 // Launch rename table for badge_alignment.
2871 $dbman->rename_table($table, 'badge_alignment');
2872 }
2873
2874 upgrade_main_savepoint(true, 2019032900.00);
2875 }
2876
d15b5340 2877 if ($oldversion < 2019032900.01) {
5a01c240
SL
2878 $sql = "UPDATE {task_scheduled}
2879 SET classname = ?
2880 WHERE component = ?
2881 AND classname = ?";
2882 $DB->execute($sql, [
2883 '\core\task\question_preview_cleanup_task',
2884 'moodle',
2885 '\core\task\question_cron_task'
2886 ]);
2887
2888 // Main savepoint reached.
d15b5340 2889 upgrade_main_savepoint(true, 2019032900.01);
0e133245
MM
2890 }
2891
2892 if ($oldversion < 2019040200.01) {
2893 // Removing the themes BSB, Clean, More from core.
2894 // If these theme wish to be retained empty this array before upgrade.
2895 $themes = array('theme_bootstrapbase' => 'bootstrapbase',
2896 'theme_clean' => 'clean', 'theme_more' => 'more');
2897 foreach ($themes as $key => $theme) {
2898 if (check_dir_exists($CFG->dirroot . '/theme/' . $theme, false)) {
2899 // Ignore the themes that have been re-downloaded.
2900 unset($themes[$key]);
2901 }
2902 }
2903 // Check we actually have themes to remove.
2904 if (count($themes) > 0) {
2905 list($insql, $inparams) = $DB->get_in_or_equal($themes, SQL_PARAMS_NAMED);
2906
2907 // Replace the theme usage.
2908 $DB->set_field_select('course', 'theme', 'classic', "theme $insql", $inparams);
2909 $DB->set_field_select('course_categories', 'theme', 'classic', "theme $insql", $inparams);
2910 $DB->set_field_select('user', 'theme', 'classic', "theme $insql", $inparams);
2911 $DB->set_field_select('mnet_host', 'theme', 'classic', "theme $insql", $inparams);
2912 $DB->set_field_select('cohort', 'theme', 'classic', "theme $insql", $inparams);
2913
2914 // Replace the theme configs.
2915 if (in_array(get_config('core', 'theme'), $themes)) {
2916 set_config('theme', 'classic');
2917 }
2918 if (in_array(get_config('core', 'thememobile'), $themes)) {
2919 set_config('thememobile', 'classic');
2920 }
2921 if (in_array(get_config('core', 'themelegacy'), $themes)) {
2922 set_config('themelegacy', 'classic');
2923 }
2924 if (in_array(get_config('core', 'themetablet'), $themes)) {
2925 set_config('themetablet', 'classic');
2926 }
2927
2928 // Hacky emulation of plugin uninstallation.
2929 foreach ($themes as $key => $theme) {
2930 unset_all_config_for_plugin($key);
2931 }
2932 }
2933
2934 // Main savepoint reached.
2935 upgrade_main_savepoint(true, 2019040200.01);
5a01c240
SL
2936 }
2937
9f690999
DM
2938 if ($oldversion < 2019040600.02) {
2939
2940 // Define key fileid (foreign) to be dropped form analytics_train_samples.
2941 $table = new xmldb_table('analytics_train_samples');
2942 $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, ['fileid'], 'files', ['id']);
2943
2944 // Launch drop key fileid.
2945 $dbman->drop_key($table, $key);
2946
2947 // Define field fileid to be dropped from analytics_train_samples.
2948 $table = new xmldb_table('analytics_train_samples');
2949 $field = new xmldb_field('fileid');
2950
2951 // Conditionally launch drop field fileid.
2952 if ($dbman->field_exists($table, $field)) {
2953 $dbman->drop_field($table, $field);
2954 }
2955
2956 // Main savepoint reached.
2957 upgrade_main_savepoint(true, 2019040600.02);
2958 }
2959
29bc29ed 2960 if ($oldversion < 2019040600.04) {
2cd901a4
MP
2961 // Define field and index to be added to backup_controllers.
2962 $table = new xmldb_table('backup_controllers');
2963 $field = new xmldb_field('progress', XMLDB_TYPE_NUMBER, '15, 14', null, XMLDB_NOTNULL, null, '0', 'timemodified');
2964 $index = new xmldb_index('useritem_ix', XMLDB_INDEX_NOTUNIQUE, ['userid', 'itemid']);
2965 // Conditionally launch add field progress.
2966 if (!$dbman->field_exists($table, $field)) {
2967 $dbman->add_field($table, $field);
2968 }
2969 // Conditionally launch add index useritem_ix.
2970 if (!$dbman->index_exists($table, $index)) {
2971 $dbman->add_index($table, $index);
2972 }
2973
2974 // Main savepoint reached.
29bc29ed 2975 upgrade_main_savepoint(true, 2019040600.04);
2cd901a4
MP
2976 }
2977
8fa61e52 2978 if ($oldversion < 2019041000.02) {
3a5afbf5 2979
2980 // Define field fullmessagetrust to be added to messages.
2981 $table = new xmldb_table('messages');
2982 $field = new xmldb_field('fullmessagetrust', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'timecreated');
2983
2984 // Conditionally launch add field fullmessagetrust.
2985 if (!$dbman->field_exists($table, $field)) {
2986 $dbman->add_field($table, $field);
2987 }
2988
2989 // Main savepoint reached.
8fa61e52 2990 upgrade_main_savepoint(true, 2019041000.02);
3a5afbf5 2991 }
2992
64827346
DM
2993 if ($oldversion < 2019041300.01) {
2994 // Add the field 'name' to the 'analytics_models' table.
2995 $table = new xmldb_table('analytics_models');
2996 $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '1333', null, null, null, null, 'trained');
2997
2998 if (!$dbman->field_exists($table, $field)) {
2999 $dbman->add_field($table, $field);
3000 }
862a9b1d 3001 // Main savepoint reached.
64827346
DM
3002 upgrade_main_savepoint(true, 2019041300.01);
3003 }
3004
862a9b1d 3005 if ($oldversion < 2019041800.01) {
734b198f
SA
3006 // STEP 1. For the existing and migrated self-conversations, set the type to the new MESSAGE_CONVERSATION_TYPE_SELF, update
3007 // the convhash and star them.
3008 $sql = "SELECT mcm.conversationid, mcm.userid, MAX(mcm.id) as maxid
3009 FROM {message_conversation_members} mcm
deef5860
SA
3010 INNER JOIN {user} u ON mcm.userid = u.id
3011 WHERE u.deleted = 0
734b198f
SA
3012 GROUP BY mcm.conversationid, mcm.userid
3013 HAVING COUNT(*) > 1";
3014 $selfconversationsrs = $DB->get_recordset_sql($sql);
3015 $maxids = [];
3016 foreach ($selfconversationsrs as $selfconversation) {
3017 $DB->update_record('message_conversations',
3018 ['id' => $selfconversation->conversationid,
3019 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
3020 'convhash' => \core_message\helper::get_conversation_hash([$selfconversation->userid])
3021 ]
3022 );
3023
3024 // Star the existing self-conversation.
3025 $favouriterecord = new \stdClass();
3026 $favouriterecord->component = 'core_message';
3027 $favouriterecord->itemtype = 'message_conversations';
3028 $favouriterecord->itemid = $selfconversation->conversationid;
3029 $userctx = \context_user::instance($selfconversation->userid);
3030 $favouriterecord->contextid = $userctx->id;
3031 $favouriterecord->userid = $selfconversation->userid;
deef5860
SA
3032 if (!$DB->record_exists('favourite', (array)$favouriterecord)) {
3033 $favouriterecord->timecreated = time();
3034 $favouriterecord->timemodified = $favouriterecord->timecreated;
3035 $DB->insert_record('favourite', $favouriterecord);
3036 }
734b198f
SA
3037
3038 // Set the self-conversation member with maxid to remove it later.
3039 $maxids[] = $selfconversation->maxid;
3040 }
3041 $selfconversationsrs->close();
3042
3043 // Remove the repeated member with the higher id for all the existing self-conversations.
3044 if (!empty($maxids)) {
3045 list($insql, $inparams) = $DB->get_in_or_equal($maxids);
3046 $DB->delete_records_select('message_conversation_members', "id $insql", $inparams);
3047 }
3048
3049 // STEP 2. Migrate existing self-conversation relying on old message tables, setting the type to the new
3050 // MESSAGE_CONVERSATION_TYPE_SELF and the convhash to the proper one. Star them also.
3051
3052 // On the messaging legacy tables, self-conversations are only present in the 'message_read' table, so we don't need to
3053 // check the content in the 'message' table.
deef5860
SA
3054 $sql = "SELECT mr.*
3055 FROM {message_read} mr
3056 INNER JOIN {user} u ON mr.useridfrom = u.id
3057 WHERE mr.useridfrom = mr.useridto AND mr.notification = 0 AND u.deleted = 0";
3058 $legacyselfmessagesrs = $DB->get_recordset_sql($sql);
734b198f
SA
3059 foreach ($legacyselfmessagesrs as $message) {
3060 // Get the self-conversation or create and star it if doesn't exist.
3061 $conditions = [
3062 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
3063 'convhash' => \core_message\helper::get_conversation_hash([$message->useridfrom])
3064 ];
3065 $selfconversation = $DB->get_record('message_conversations', $conditions);
3066 if (empty($selfconversation)) {
3067 // Create the self-conversation.
3068 $selfconversation = new \stdClass();
3069 $selfconversation->type = \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF;
3070 $selfconversation->convhash = \core_message\helper::get_conversation_hash([$message->useridfrom]);
3071 $selfconversation->enabled = 1;
3072 $selfconversation->timecreated = time();
3073 $selfconversation->timemodified = $selfconversation->timecreated;
3074
3075 $selfconversation->id = $DB->insert_record('message_conversations', $selfconversation);
3076
3077 // Add user to this self-conversation.
3078 $member = new \stdClass();
3079 $member->conversationid = $selfconversation->id;
3080 $member->userid = $message->useridfrom;
3081 $member->timecreated = time();
3082
3083 $member->id = $DB->insert_record('message_conversation_members', $member);
3084
3085 // Star the self-conversation.
3086 $favouriterecord = new \stdClass();
3087 $favouriterecord->component = 'core_message';
3088 $favouriterecord->itemtype = 'message_conversations';
3089 $favouriterecord->itemid = $selfconversation->id;
3090 $userctx = \context_user::instance($message->useridfrom);
3091 $favouriterecord->contextid = $userctx->id;
3092 $favouriterecord->userid = $message->useridfrom;
deef5860
SA
3093 if (!$DB->record_exists('favourite', (array)$favouriterecord)) {
3094 $favouriterecord->timecreated = time();
3095 $favouriterecord->timemodified = $favouriterecord->timecreated;
3096 $DB->insert_record('favourite', $favouriterecord);
3097 }
734b198f
SA
3098 }
3099
3100 // Create the object we will be inserting into the database.
3101 $tabledata = new \stdClass();
3102 $tabledata->useridfrom = $message->useridfrom;
3103 $tabledata->conversationid = $selfconversation->id;
3104 $tabledata->subject = $message->subject;
3105 $tabledata->fullmessage = $message->fullmessage;
3106 $tabledata->fullmessageformat = $message->fullmessageformat ?? FORMAT_MOODLE;
3107 $tabledata->fullmessagehtml = $message->fullmessagehtml;
3108 $tabledata->smallmessage = $message->smallmessage;
3109 $tabledata->timecreated = $message->timecreated;
3110
3111 $messageid = $DB->insert_record('messages', $tabledata);
3112
3113 // Check if we need to mark this message as deleted (self-conversations add this information on the
3114 // timeuserfromdeleted field.
3115 if ($message->timeuserfromdeleted) {
3116 $mua = new \stdClass();
3117 $mua->userid = $message->useridfrom;
3118 $mua->messageid = $messageid;
3119 $mua->action = \core_message\api::MESSAGE_ACTION_DELETED;
3120 $mua->timecreated = $message->timeuserfromdeleted;
3121
3122 $DB->insert_record('message_user_actions', $mua);
3123 }
3124
3125 // Mark this message as read.
3126 $mua = new \stdClass();
3127 $mua->userid = $message->useridto;
3128 $mua->messageid = $messageid;
3129 $mua->action = \core_message\api::MESSAGE_ACTION_READ;
3130 $mua->timecreated = $message->timeread;
3131
3132 $DB->insert_record('message_user_actions', $mua);
50255ba9
SA
3133
3134 // The self-conversation message has been migrated. Delete the record from the legacy table as soon as possible
3135 // to avoid migrate it twice.
3136 $DB->delete_records('message_read', ['id' => $message->id]);
734b198f
SA
3137 }
3138 $legacyselfmessagesrs->close();
3139
734b198f 3140 // Main savepoint reached.
862a9b1d 3141 upgrade_main_savepoint(true, 2019041800.01);
734b198f
SA
3142 }
3143
5dec930f 3144 if ($oldversion < 2019042200.01) {
59471712
EL
3145
3146 // Define table role_sortorder to be dropped.
3147 $table = new xmldb_table('role_sortorder');
3148
3149 // Conditionally launch drop table for role_sortorder.
3150 if ($dbman->table_exists($table)) {
3151 $dbman->drop_table($table);
3152 }
3153
3154 // Main savepoint reached.
5dec930f 3155 upgrade_main_savepoint(true, 2019042200.01);
59471712
EL
3156 }
3157
1f39068e 3158 if ($oldversion < 2019042200.02) {
9c0edd12
EL
3159
3160 // Let's update all (old core) targets to their new (core_course) locations.
3161 $targets = [
3162 '\core\analytics\target\course_competencies' => '\core_course\analytics\target\course_competencies',
3163 '\core\analytics\target\course_completion' => '\core_course\analytics\target\course_completion',
3164 '\core\analytics\target\course_dropout' => '\core_course\analytics\target\course_dropout',
3165 '\core\analytics\target\course_gradetopass' => '\core_course\analytics\target\course_gradetopass',
3166 '\core\analytics\target\no_teaching' => '\core_course\analytics\target\no_teaching',
7063b665 3167 ];
7063b665 3168
9c0edd12
EL
3169 foreach ($targets as $oldclass => $newclass) {
3170 $DB->set_field('analytics_models', 'target', $newclass, ['target' => $oldclass]);
7063b665
DM
3171 }
3172
3173 // Main savepoint reached.
1f39068e 3174 upgrade_main_savepoint(true, 2019042200.02);
7063b665
DM
3175 }
3176
1470cfc2 3177 if ($oldversion < 2019042300.01) {
d26749b7
SL
3178 $sql = "UPDATE {capabilities}
3179 SET name = ?,
3180 contextlevel = ?
3181 WHERE name = ?";
3182 $DB->execute($sql, ['moodle/category:viewcourselist', CONTEXT_COURSECAT, 'moodle/course:browse']);
3183
3184 $sql = "UPDATE {role_capabilities}
3185 SET capability = ?
3186 WHERE capability = ?";
3187 $DB->execute($sql, ['moodle/category:viewcourselist', 'moodle/course:browse']);
3188
3189 // Main savepoint reached.
1470cfc2 3190 upgrade_main_savepoint(true, 2019042300.01);
d26749b7 3191 }
1470cfc2 3192
b63c0b90
DM
3193 if ($oldversion < 2019042300.03) {
3194
333d11c9
JL
3195 // Add new customdata field to message table.
3196 $table = new xmldb_table('message');
3197 $field = new xmldb_field('customdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'eventtype');
3198
3199 // Conditionally launch add field output.
3200 if (!$dbman->field_exists($table, $field)) {
3201 $dbman->add_field($table, $field);
3202 }
3203
3204 // Add new customdata field to notifications and messages table.
3205 $table = new xmldb_table('notifications');
3206 $field = new xmldb_field('customdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'timecreated');
3207
3208 // Conditionally launch add field output.
3209 if (!$dbman->field_exists($table, $field)) {
3210 $dbman->add_field($table, $field);
3211 }
3212
3213 $table = new xmldb_table('messages');
3214 // Conditionally launch add field output.
3215 if (!$dbman->field_exists($table, $field)) {
3216 $dbman->add_field($table, $field);
3217 }
3218
3219 // Main savepoint reached.
b63c0b90 3220 upgrade_main_savepoint(true, 2019042300.03);
333d11c9
JL
3221 }
3222
352ab746
DM
3223 if ($oldversion < 2019042700.01) {
3224
3225 // Define field firstanalysis to be added to analytics_used_analysables.
3226 $table = new xmldb_table('analytics_used_analysables');
3227
3228 // Declaring it as null initially (although it is NOT NULL).
3229 $field = new xmldb_field('firstanalysis', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'analysableid');
3230
3231 // Conditionally launch add field firstanalysis.
3232 if (!$dbman->field_exists($table, $field)) {
3233 $dbman->add_field($table, $field);
3234
3235 // Set existing values to the current timeanalysed value.
3236 $recordset = $DB->get_recordset('analytics_used_analysables');
3237 foreach ($recordset as $record) {
3238 $record->firstanalysis = $record->timeanalysed;
3239 $DB->update_record('analytics_used_analysables', $record);
3240 }
3241 $recordset->close();
3242
3243 // Now make the field 'NOT NULL'.
3244 $field = new xmldb_field('firstanalysis', XMLDB_TYPE_INTEGER, '10',
3245 null, XMLDB_NOTNULL, null, null, 'analysableid');
3246 $dbman->change_field_notnull($table, $field);
3247 }
3248
3249 // Main savepoint reached.
3250 upgrade_main_savepoint(true, 2019042700.01);
3251 }
3252
903ec849
JD
3253 if ($oldversion < 2019050300.01) {
3254 // Delete all stale favourite records which were left behind when a course was deleted.
903ec849 3255 $params = ['component' => 'core_message', 'itemtype' => 'message_conversations'];
0eab8a42
JP
3256 $sql = "SELECT fav.id as id
3257 FROM {favourite} fav
3258 LEFT JOIN {context} ctx ON (ctx.id = fav.contextid)
3259 WHERE fav.component = :component
3260 AND fav.itemtype = :itemtype
3261 AND ctx.id IS NULL";
3262
3263 if ($records = $DB->get_fieldset_sql($sql, $params)) {
3264 // Just for safety, delete by chunks.
3265 $chunks = array_chunk($records, 1000);
3266 foreach ($chunks as $chunk) {
3267 list($insql, $inparams) = $DB->get_in_or_equal($chunk);
3268 $DB->delete_records_select('favourite', "id $insql", $inparams);
3269 }
3270 }
903ec849
JD
3271
3272 upgrade_main_savepoint(true, 2019050300.01);
3273 }
3274
7726bec6 3275 if ($oldversion < 2019050600.00) {
aae219ac
DW
3276
3277 // Define field apiversion to be added to badge_backpack.
3278 $table = new xmldb_table('badge_backpack');
3279 $field = new xmldb_field('apiversion', XMLDB_TYPE_CHAR, '12', null, XMLDB_NOTNULL, null, '1.0', 'password');
3280
3281 // Conditionally launch add field apiversion.
3282 if (!$dbman->field_exists($table, $field)) {
3283 $dbman->add_field($table, $field);
3284 }
3285
3286 // Define table badge_external_backpack to be created.
3287 $table = new xmldb_table('badge_external_backpack');
3288
3289 // Adding fields to table badge_external_backpack.
3290 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3291 $table->add_field('backpackapiurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3292 $table->add_field('backpackweburl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
3293 $table->add_field('apiversion', XMLDB_TYPE_CHAR, '12', null, XMLDB_NOTNULL, null, '1.0');
3294 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
3295 $table->add_field('password', XMLDB_TYPE_CHAR, '255', null, null, null, null);
3296
3297 // Adding keys to table badge_external_backpack.
3298 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
3299 $table->add_key('backpackapiurlkey', XMLDB_KEY_UNIQUE, ['backpackapiurl']);
3300 $table->add_key('backpackweburlkey', XMLDB_KEY_UNIQUE, ['backpackweburl']);
3301
3302 // Conditionally launch create table for badge_external_backpack.
3303 if (!$dbman->table_exists($table)) {
3304 $dbman->create_table($table);
3305 }
3306
3307 // Define field entityid to be added to badge_external.
3308 $table = new xmldb_table('badge_external');
3309 $field = new xmldb_field('entityid', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'collectionid');
3310
3311 // Conditionally launch add field entityid.
3312 if (!$dbman->field_exists($table, $field)) {
3313 $dbman->add_field($table, $field);
3314 }
3315
7444ba74 3316 // Define table badge_external_identifier to be created.
aae219ac
DW
3317 $table = new xmldb_table('badge_external_identifier');
3318
3319 // Adding fields to table badge_external_identifier.
3320 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3321 $table->add_field('sitebackpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
3322 $table->add_field('internalid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null);
3323 $table->add_field('externalid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null);
3324 $table->add_field('type', XMLDB_TYPE_CHAR, '16', null, XMLDB_NOTNULL, null, null);
3325
3326 // Adding keys to table badge_external_identifier.
3327 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
3328 $table->add_key('fk_backpackid', XMLDB_KEY_FOREIGN, ['sitebackpackid'], 'badge_backpack', ['id']);
3329 $table->add_key('backpack-internal-external', XMLDB_KEY_UNIQUE, ['sitebackpackid', 'internalid', 'externalid', 'type']);
3330
3331 // Conditionally launch create table for badge_external_identifier.
3332 if (!$dbman->table_exists($table)) {
3333 $dbman->create_table($table);
3334 }
7444ba74
DW
3335
3336 // Define field externalbackpackid to be added to badge_backpack.
3337 $table = new xmldb_table('badge_backpack');
3338 $field = new xmldb_field('externalbackpackid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'password');
3339
3340 // Conditionally launch add field externalbackpackid.
3341 if (!$dbman->field_exists($table, $field)) {
3342 $dbman->add_field($table, $field);
3343 }
3344
3345 // Define key externalbackpack (foreign) to be added to badge_backpack.
3346 $key = new xmldb_key('externalbackpack', XMLDB_KEY_FOREIGN, ['externalbackpackid'], 'badge_external_backpack', ['id']);
3347
3348 // Launch add key externalbackpack.
3349 $dbman->add_key($table, $key);
3350
3351 $field = new xmldb_field('apiversion');
3352
3353 // Conditionally launch drop field apiversion.
3354 if ($dbman->field_exists($table, $field)) {
3355 $dbman->drop_field($table, $field);
3356 }
3357
3358 $field = new xmldb_field('backpackurl');
3359
3360 // Conditionally launch drop field backpackurl.
3361 if ($dbman->field_exists($table, $field)) {
3362 $dbman->drop_field($table, $field);
3363 }
3364
3365 // Add default backpacks.
9ad5cff4 3366 require_once($CFG->dirroot . '/badges/upgradelib.php'); // Core install and upgrade related functions only for badges.
7444ba74
DW
3367 badges_install_default_backpacks();
3368
aae219ac 3369 // Main savepoint reached.
7726bec6 3370 upgrade_main_savepoint(true, 2019050600.00);
aae219ac
DW
3371 }
3372
d9b6bd95 3373 if ($oldversion < 2019051300.01) {
bc2f679b
DM
3374 $DB->set_field('analytics_models', 'enabled', '1', ['target' => '\core_user\analytics\target\upcoming_activities_due']);
3375
3376 // Main savepoint reached.
d9b6bd95 3377 upgrade_main_savepoint(true, 2019051300.01);
bc2f679b
DM
3378 }
3379
3572a25c
EL
3380 // Automatically generated Moodle v3.7.0 release upgrade line.
3381 // Put any upgrade step following this.
3382
76d0192e
MH
3383 if ($oldversion < 2019060600.02) {
3384 // Renaming 'opentogoogle' config to 'opentowebcrawlers'.
3385 $opentogooglevalue = get_config('core', 'opentogoogle');
3386
3387 // Move the value over if it was previously configured.
3388 if ($opentogooglevalue !== false) {
3389 set_config('opentowebcrawlers', $opentogooglevalue);
3390 }
3391
3392 // Remove the now unused value.
3393 unset_config('opentogoogle');
3394
3395 // Main savepoint reached.
3396 upgrade_main_savepoint(true, 2019060600.02);
3397 }
3398
22dfa6d3
DM
3399 if ($oldversion < 2019062900.00) {
3400 // Debugsmtp is now only available via config.php.
3401 $DB->delete_records('config', array('name' => 'debugsmtp'));
3402
3403 // Main savepoint reached.
3404 upgrade_main_savepoint(true, 2019062900.00);
3405 }
3406
c5b2ab47
BB
3407 if ($oldversion < 2019070400.01) {
3408
3409 $basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894',
3410 '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
3411
3412 $colornr = 1;
3413 foreach ($basecolors as $color) {
3414 set_config('coursecolor' . $colornr, $color, 'core_admin');
3415 $colornr++;
3416 }
3417
3418 upgrade_main_savepoint(true, 2019070400.01);
3419 }
3420
9d8cdb9b
JP
3421 if ($oldversion < 2019072200.00) {
3422
3423 // Define field relativedatesmode to be added to course.
3424 $table = new xmldb_table('course');
3425 $field = new xmldb_field('relativedatesmode', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'enddate');
3426
3427 // Conditionally launch add field relativedatesmode.
3428 if (!$dbman->field_exists($table, $field)) {
3429 $dbman->add_field($table, $field);
3430 }
3431
3432 // Main savepoint reached.
3433 upgrade_main_savepoint(true, 2019072200.00);
3434 }
3435
1f16f411 3436 if ($oldversion < 2019072500.01) {
5d61b3b3
RW
3437 // Remove the "popup" processor from the list of default processors for the messagecontactrequests notification.
3438 $oldloggedinconfig = get_config('message', 'message_provider_moodle_messagecontactrequests_loggedin');
3439 $oldloggedoffconfig = get_config('message', 'message_provider_moodle_messagecontactrequests_loggedoff');
3440 $newloggedinconfig = implode(',', array_filter(explode(',', $oldloggedinconfig), function($value) {
3441 return $value != 'popup';
3442 }));
3443 $newloggedoffconfig = implode(',', array_filter(explode(',', $oldloggedoffconfig), function($value) {
3444 return $value != 'popup';
3445 }));
3446 set_config('message_provider_moodle_messagecontactrequests_loggedin', $newloggedinconfig, 'message');
3447 set_config('message_provider_moodle_messagecontactrequests_loggedoff', $newloggedoffconfig, 'message');
3448
1f16f411 3449 upgrade_main_savepoint(true, 2019072500.01);
5d61b3b3
RW
3450 }
3451
a12f9f93
JD
3452 if ($oldversion < 2019072500.03) {
3453 unset_config('httpswwwroot');
3454
3455 upgrade_main_savepoint(true, 2019072500.03);
3456 }
3457
d8b3c365 3458 if ($oldversion < 2019073100.00) {
0c187454
MM
3459 // Update the empty tag instructions to null.
3460 $instructions = get_config('core', 'auth_instructions');
3461
3462 if (trim(html_to_text($instructions)) === '') {
3463 set_config('auth_instructions', '');
3464 }
3465
3466 // Main savepoint reached.
d8b3c365 3467 upgrade_main_savepoint(true, 2019073100.00);
0c187454 3468 }
1d6f041a 3469
3213963f 3470 if ($oldversion < 2019083000.01) {
1d6f041a
P
3471
3472 // If block_community is no longer present, remove it.
3473 if (!file_exists($CFG->dirroot . '/blocks/community/communitycourse.php')) {
3474 // Drop table that is no longer needed.
3475 $table = new xmldb_table('block_community');
3476 if ($dbman->table_exists($table)) {
3477 $dbman->drop_table($table);
3478 }
3479
3480 // Delete instances.
3481 $instances = $DB->get_records_list('block_instances', 'blockname', ['community']);
3482 $instanceids = array_keys($instances);
3483
3484 if (!empty($instanceids)) {
3485 $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
3486 $DB->delete_records_list('block_instances', 'id', $instanceids);
3487 list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
3488 $params['contextlevel'] = CONTEXT_BLOCK;
3489 $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
3490
3491 $preferences = array();
3492 foreach ($instances as $instanceid => $instance) {
3493 $preferences[] = 'block' . $instanceid . 'hidden';
3494 $preferences[] = 'docked_block_instance_' . $instanceid;
3495 }
3496 $DB->delete_records_list('user_preferences', 'name', $preferences);
3497 }
3498
3499 // Delete the block from the block table.
3500 $DB->delete_records('block', array('name' => 'community'));
3501
3502 // Remove capabilities.
3503 capabilities_cleanup('block_community');
3504 // Clean config.
3505 unset_all_config_for_plugin('block_community');
3506
3507 // Remove Moodle-level community based capabilities.
3508 $capabilitiestoberemoved = ['block/community:addinstance', 'block/community:myaddinstance'];
3509 // Delete any role_capabilities for the old roles.
3510 $DB->delete_records_list('role_capabilities', 'capability', $capabilitiestoberemoved);
3511 // Delete the capability itself.
3512 $DB->delete_records_list('capabilities', 'name', $capabilitiestoberemoved);
3513 }
3514
3213963f 3515 upgrade_main_savepoint(true, 2019083000.01);
1d6f041a
P
3516 }
3517
020bad73
P
3518 if ($oldversion < 2019083000.02) {
3519 // Remove unused config.
3520 unset_config('enablecoursepublishing');
3521 upgrade_main_savepoint(true, 2019083000.02);
3522 }
3523
cd1bdc79 3524 if ($oldversion < 2019083000.04) {
8c07d7d7
SL
3525 // Delete "orphaned" subscriptions.
3526 $sql = "SELECT DISTINCT es.userid
3527 FROM {event_subscriptions} es
3528 LEFT JOIN {user} u ON u.id = es.userid
3529 WHERE u.deleted = 1 OR u.id IS NULL";
3530 $deletedusers = $DB->get_field_sql($sql);
3531 if ($deletedusers) {
3532 list($sql, $params) = $DB->get_in_or_equal($deletedusers);
3533
3534 // Delete orphaned subscriptions.
3535 $DB->execute("DELETE FROM {event_subscriptions} WHERE userid " . $sql, $params);
3536 }
3537
cd1bdc79 3538 upgrade_main_savepoint(true, 2019083000.04);
8c07d7d7
SL
3539 }
3540
f5583e97
DM
3541 if ($oldversion < 2019090500.01) {
3542
3543 // Define index analysableid (not unique) to be added to analytics_used_analysables.
3544 $table = new xmldb_table('analytics_used_analysables');
3545 $index = new xmldb_index('analysableid', XMLDB_INDEX_NOTUNIQUE, ['analysableid']);
3546
3547 // Conditionally launch add index analysableid.
3548 if (!$dbman->index_exists($table, $index)) {
3549 $dbman->add_index($table, $index);
3550 }
3551
3552 // Main savepoint reached.
3553 upgrade_main_savepoint(true, 2019090500.01);
3554 }
3555
386d1091
DM
3556 if ($oldversion < 2019092700.01) {
3557 upgrade_rename_prediction_actions_useful_incorrectly_flagged();
3558 upgrade_main_savepoint(true, 2019092700.01);
3559 }
3560
13ef95e3 3561 if ($oldversion < 2019100800.02) {
ecc9960e
DM
3562 // Rename the official moodle sites directory the site is registered with.
3563 $DB->execute("UPDATE {registration_hubs}
3564 SET hubname = ?, huburl = ?
3565 WHERE huburl = ?", ['moodle', 'https://stats.moodle.org', 'https://moodle.net']);
3566
3567 // Convert the hub site specific settings to the new naming format without the hub URL in the name.
3568 $hubconfig = get_config('hub');
3569
3570 if (!empty($hubconfig)) {
3571 foreach (upgrade_convert_hub_config_site_param_names($hubconfig, 'https://moodle.net') as $name => $value) {
3572 set_config($name, $value, 'hub');
3573 }
3574 }
3575
13ef95e3 3576 upgrade_main_savepoint(true, 2019100800.02);
ecc9960e
DM
3577 }
3578
d31b5c43 3579 if ($oldversion < 2019100900.00) {
7ce941a4
AB
3580 // If block_participants is no longer present, remove it.
3581 if (!file_exists($CFG->dirroot . '/blocks/participants/block_participants.php')) {
3582 // Delete instances.
3583 $instances = $DB->get_records_list('block_instances', 'blockname', ['participants']);
3584 $instanceids = array_keys($instances);
3585
3586 if (!empty($instanceids)) {
3587 $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
3588 $DB->delete_records_list('block_instances', 'id', $instanceids);
3589 list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
3590 $params['contextlevel'] = CONTEXT_BLOCK;
3591 $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
3592
3593 $preferences = array();
3594 foreach ($instances as $instanceid => $instance) {
3595 $preferences[] = 'block' . $instanceid . 'hidden';
3596 $preferences[] = 'docked_block_instance_' . $instanceid;
3597 }
3598 $DB->delete_records_list('user_preferences', 'name', $preferences);
3599 }
3600
3601 // Delete the block from the block table.
3602 $DB->delete_records('block', array('name' => 'participants'));
3603
3604 // Remove capabilities.
3605 capabilities_cleanup('block_participants');
3606
3607 // Clean config.
3608 unset_all_config_for_plugin('block_participants');
3609 }
3610
d31b5c43 3611 upgrade_main_savepoint(true, 2019100900.00);
7ce941a4
AB
3612 }
3613
6d98de3f 3614 if ($oldversion < 2019101600.01) {
959e4f0e
MG
3615
3616 // Change the setting $CFG->requestcategoryselection into $CFG->lockrequestcategory with opposite value.
25676441 3617 set_config('lockrequestcategory', empty($CFG->requestcategoryselection));
959e4f0e 3618
6d98de3f 3619 upgrade_main_savepoint(true, 2019101600.01);
959e4f0e
MG
3620 }
3621
7ba9c635 3622 if ($oldversion < 2019101800.02) {
c345aa72
MM
3623
3624 // Get the table by its previous name.
3625 $table = new xmldb_table('analytics_models');
3626 if ($dbman->table_exists($table)) {