See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 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 * 37 * @package core_install 38 * @category upgrade 39 * @copyright 2006 onwards Martin Dougiamas http://dougiamas.com 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 43 defined('MOODLE_INTERNAL') || die(); 44 45 /** 46 * Main upgrade tasks to be executed on Moodle version bump 47 * 48 * This function is automatically executed after one bump in the Moodle core 49 * version is detected. It's in charge of performing the required tasks 50 * to raise core from the previous version to the next one. 51 * 52 * It's a collection of ordered blocks of code, named "upgrade steps", 53 * each one performing one isolated (from the rest of steps) task. Usually 54 * tasks involve creating new DB objects or performing manipulation of the 55 * information for cleanup/fixup purposes. 56 * 57 * Each upgrade step has a fixed structure, that can be summarised as follows: 58 * 59 * if ($oldversion < XXXXXXXXXX.XX) { 60 * // Explanation of the update step, linking to issue in the Tracker if necessary 61 * upgrade_set_timeout(XX); // Optional for big tasks 62 * // Code to execute goes here, usually the XMLDB Editor will 63 * // help you here. See {@link https://moodledev.io/general/development/tools/xmldb}. 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 https://moodledev.io/general/development/policies/codingstyle/frankenstyle}, for example: 70 * - {@link xmldb_page_upgrade($oldversion)}. (modules don't require the plugintype ("mod_") to be used. 71 * - {@link xmldb_auth_manual_upgrade($oldversion)}. 72 * - {@link xmldb_workshopform_accumulative_upgrade($oldversion)}. 73 * - .... 74 * 75 * In order to keep the contents of this file reduced, it's allowed to create some helper 76 * functions to be used here in the {@link upgradelib.php} file at the same directory. Note 77 * that such a file must be manually included from upgrade.php, and there are some restrictions 78 * about what can be used within it. 79 * 80 * For more information, take a look to the documentation available: 81 * - Data definition API: {@link https://moodledev.io/docs/apis/core/dml/ddl} 82 * - Upgrade API: {@link https://moodledev.io/docs/guides/upgrade} 83 * 84 * @param int $oldversion 85 * @return bool always true 86 */ 87 function xmldb_main_upgrade($oldversion) { 88 global $CFG, $DB; 89 90 require_once($CFG->libdir.'/db/upgradelib.php'); // Core Upgrade-related functions. 91 92 $dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes. 93 94 // Always keep this upgrade step with version being the minimum 95 // allowed version to upgrade from (v3.9.0 right now). 96 if ($oldversion < 2020061500) { 97 // Just in case somebody hacks upgrade scripts or env, we really can not continue. 98 echo("You need to upgrade to 3.9.x or higher first!\n"); 99 exit(1); 100 // Note this savepoint is 100% unreachable, but needed to pass the upgrade checks. 101 upgrade_main_savepoint(true, 2020061500); 102 } 103 104 // Automatically generated Moodle v3.9.0 release upgrade line. 105 // Put any upgrade step following this. 106 107 if ($oldversion < 2020061500.02) { 108 // Update default digital age consent map according to the current legislation on each country. 109 110 // The default age of digital consent map for 38 and below. 111 $oldageofdigitalconsentmap = implode(PHP_EOL, [ 112 '*, 16', 113 'AT, 14', 114 'ES, 14', 115 'US, 13' 116 ]); 117 118 // Check if the current age of digital consent map matches the old one. 119 if (get_config('moodle', 'agedigitalconsentmap') === $oldageofdigitalconsentmap) { 120 // If the site is still using the old defaults, upgrade to the new default. 121 $ageofdigitalconsentmap = implode(PHP_EOL, [ 122 '*, 16', 123 'AT, 14', 124 'BE, 13', 125 'BG, 14', 126 'CY, 14', 127 'CZ, 15', 128 'DK, 13', 129 'EE, 13', 130 'ES, 14', 131 'FI, 13', 132 'FR, 15', 133 'GB, 13', 134 'GR, 15', 135 'IT, 14', 136 'LT, 14', 137 'LV, 13', 138 'MT, 13', 139 'NO, 13', 140 'PT, 13', 141 'SE, 13', 142 'US, 13' 143 ]); 144 set_config('agedigitalconsentmap', $ageofdigitalconsentmap); 145 } 146 147 upgrade_main_savepoint(true, 2020061500.02); 148 } 149 150 if ($oldversion < 2020062600.01) { 151 // Add index to the token field in the external_tokens table. 152 $table = new xmldb_table('external_tokens'); 153 $index = new xmldb_index('token', XMLDB_INDEX_NOTUNIQUE, ['token']); 154 155 if (!$dbman->index_exists($table, $index)) { 156 $dbman->add_index($table, $index); 157 } 158 159 upgrade_main_savepoint(true, 2020062600.01); 160 } 161 162 if ($oldversion < 2020071100.01) { 163 // Clean up completion criteria records referring to NULL course prerequisites. 164 $select = 'criteriatype = :type AND courseinstance IS NULL'; 165 $params = ['type' => 8]; // COMPLETION_CRITERIA_TYPE_COURSE. 166 167 $DB->delete_records_select('course_completion_criteria', $select, $params); 168 169 // Main savepoint reached. 170 upgrade_main_savepoint(true, 2020071100.01); 171 } 172 173 if ($oldversion < 2020072300.01) { 174 // Restore and set the guest user if it has been previously removed via GDPR, or set to an nonexistent 175 // user account. 176 $currentguestuser = $DB->get_record('user', array('id' => $CFG->siteguest)); 177 178 if (!$currentguestuser) { 179 if (!$guest = $DB->get_record('user', array('username' => 'guest', 'mnethostid' => $CFG->mnet_localhost_id))) { 180 // Create a guest user account. 181 $guest = new stdClass(); 182 $guest->auth = 'manual'; 183 $guest->username = 'guest'; 184 $guest->password = hash_internal_user_password('guest'); 185 $guest->firstname = get_string('guestuser'); 186 $guest->lastname = ' '; 187 $guest->email = 'root@localhost'; 188 $guest->description = get_string('guestuserinfo'); 189 $guest->mnethostid = $CFG->mnet_localhost_id; 190 $guest->confirmed = 1; 191 $guest->lang = $CFG->lang; 192 $guest->timemodified= time(); 193 $guest->id = $DB->insert_record('user', $guest); 194 } 195 // Set the guest user. 196 set_config('siteguest', $guest->id); 197 } 198 199 // Main savepoint reached. 200 upgrade_main_savepoint(true, 2020072300.01); 201 } 202 203 if ($oldversion < 2021052500.01) { 204 // Delete all user evidence files from users that have been deleted. 205 $sql = "SELECT DISTINCT f.* 206 FROM {files} f 207 LEFT JOIN {context} c ON f.contextid = c.id 208 WHERE f.component = :component 209 AND f.filearea = :filearea 210 AND c.id IS NULL"; 211 $stalefiles = $DB->get_records_sql($sql, ['component' => 'core_competency', 'filearea' => 'userevidence']); 212 213 $fs = get_file_storage(); 214 foreach ($stalefiles as $stalefile) { 215 $fs->get_file_instance($stalefile)->delete(); 216 } 217 218 upgrade_main_savepoint(true, 2021052500.01); 219 } 220 221 if ($oldversion < 2021052500.02) { 222 223 // Define field timecreated to be added to task_adhoc. 224 $table = new xmldb_table('task_adhoc'); 225 $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'blocking'); 226 227 // Conditionally launch add field timecreated. 228 if (!$dbman->field_exists($table, $field)) { 229 $dbman->add_field($table, $field); 230 } 231 232 // Main savepoint reached. 233 upgrade_main_savepoint(true, 2021052500.02); 234 } 235 236 if ($oldversion < 2021052500.04) { 237 // Define field metadatasettings to be added to h5p_libraries. 238 $table = new xmldb_table('h5p_libraries'); 239 $field = new xmldb_field('metadatasettings', XMLDB_TYPE_TEXT, null, null, null, null, null, 'coreminor'); 240 241 // Conditionally launch add field metadatasettings. 242 if (!$dbman->field_exists($table, $field)) { 243 $dbman->add_field($table, $field); 244 } 245 246 // Get installed library files that have no metadata settings value. 247 $params = [ 248 'component' => 'core_h5p', 249 'filearea' => 'libraries', 250 'filename' => 'library.json', 251 ]; 252 $sql = "SELECT l.id, f.id as fileid 253 FROM {files} f 254 LEFT JOIN {h5p_libraries} l ON f.itemid = l.id 255 WHERE f.component = :component 256 AND f.filearea = :filearea 257 AND f.filename = :filename"; 258 $libraries = $DB->get_records_sql($sql, $params); 259 260 // Update metadatasettings field when the attribute is present in the library.json file. 261 $fs = get_file_storage(); 262 foreach ($libraries as $library) { 263 $jsonfile = $fs->get_file_by_id($library->fileid); 264 $jsoncontent = json_decode($jsonfile->get_content()); 265 if (isset($jsoncontent->metadataSettings)) { 266 unset($library->fileid); 267 $library->metadatasettings = json_encode($jsoncontent->metadataSettings); 268 $DB->update_record('h5p_libraries', $library); 269 } 270 } 271 272 // Main savepoint reached. 273 upgrade_main_savepoint(true, 2021052500.04); 274 } 275 276 if ($oldversion < 2021052500.05) { 277 // Define fields to be added to task_scheduled. 278 $table = new xmldb_table('task_scheduled'); 279 $field = new xmldb_field('timestarted', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'disabled'); 280 if (!$dbman->field_exists($table, $field)) { 281 $dbman->add_field($table, $field); 282 } 283 $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timestarted'); 284 if (!$dbman->field_exists($table, $field)) { 285 $dbman->add_field($table, $field); 286 } 287 $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname'); 288 if (!$dbman->field_exists($table, $field)) { 289 $dbman->add_field($table, $field); 290 } 291 292 // Define fields to be added to task_adhoc. 293 $table = new xmldb_table('task_adhoc'); 294 $field = new xmldb_field('timestarted', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blocking'); 295 if (!$dbman->field_exists($table, $field)) { 296 $dbman->add_field($table, $field); 297 } 298 $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timestarted'); 299 if (!$dbman->field_exists($table, $field)) { 300 $dbman->add_field($table, $field); 301 } 302 $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname'); 303 if (!$dbman->field_exists($table, $field)) { 304 $dbman->add_field($table, $field); 305 } 306 307 // Define fields to be added to task_log. 308 $table = new xmldb_table('task_log'); 309 $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'output'); 310 if (!$dbman->field_exists($table, $field)) { 311 $dbman->add_field($table, $field); 312 } 313 $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname'); 314 if (!$dbman->field_exists($table, $field)) { 315 $dbman->add_field($table, $field); 316 } 317 318 // Main savepoint reached. 319 upgrade_main_savepoint(true, 2021052500.05); 320 } 321 322 if ($oldversion < 2021052500.06) { 323 // Define table to store virus infected details. 324 $table = new xmldb_table('infected_files'); 325 326 // Adding fields to table infected_files. 327 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 328 $table->add_field('filename', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 329 $table->add_field('quarantinedfile', XMLDB_TYPE_TEXT, null, null, null, null, null); 330 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 331 $table->add_field('reason', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 332 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 333 334 // Adding keys to table infected_files. 335 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 336 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']); 337 338 // Conditionally launch create table for infected_files. 339 if (!$dbman->table_exists($table)) { 340 $dbman->create_table($table); 341 } 342 upgrade_main_savepoint(true, 2021052500.06); 343 } 344 345 if ($oldversion < 2021052500.13) { 346 // Remove all the files with component='core_h5p' and filearea='editor' because they won't be used anymore. 347 $fs = get_file_storage(); 348 $syscontext = context_system::instance(); 349 $fs->delete_area_files($syscontext->id, 'core_h5p', 'editor'); 350 351 // Main savepoint reached. 352 upgrade_main_savepoint(true, 2021052500.13); 353 } 354 355 if ($oldversion < 2021052500.15) { 356 // Copy From id captures the id of the source course when a new course originates from a restore 357 // of another course on the same site. 358 $table = new xmldb_table('course'); 359 $field = new xmldb_field('originalcourseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 360 361 if (!$dbman->field_exists($table, $field)) { 362 $dbman->add_field($table, $field); 363 } 364 365 // Main savepoint reached. 366 upgrade_main_savepoint(true, 2021052500.15); 367 } 368 369 if ($oldversion < 2021052500.19) { 370 // Define table oauth2_refresh_token to be created. 371 $table = new xmldb_table('oauth2_refresh_token'); 372 373 // Adding fields to table oauth2_refresh_token. 374 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 375 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 376 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 377 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 378 $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 379 $table->add_field('token', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 380 $table->add_field('scopehash', XMLDB_TYPE_CHAR, 40, null, XMLDB_NOTNULL, null, null); 381 382 // Adding keys to table oauth2_refresh_token. 383 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 384 $table->add_key('issueridkey', XMLDB_KEY_FOREIGN, ['issuerid'], 'oauth2_issuer', ['id']); 385 $table->add_key('useridkey', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']); 386 387 // Adding indexes to table oauth2_refresh_token. 388 $table->add_index('userid-issuerid-scopehash', XMLDB_INDEX_UNIQUE, array('userid', 'issuerid', 'scopehash')); 389 390 // Conditionally launch create table for oauth2_refresh_token. 391 if (!$dbman->table_exists($table)) { 392 $dbman->create_table($table); 393 } 394 395 // Main savepoint reached. 396 upgrade_main_savepoint(true, 2021052500.19); 397 } 398 399 if ($oldversion < 2021052500.20) { 400 401 // Define index modulename-instance-eventtype (not unique) to be added to event. 402 $table = new xmldb_table('event'); 403 $index = new xmldb_index('modulename-instance-eventtype', XMLDB_INDEX_NOTUNIQUE, ['modulename', 'instance', 'eventtype']); 404 405 // Conditionally launch add index modulename-instance-eventtype. 406 if (!$dbman->index_exists($table, $index)) { 407 $dbman->add_index($table, $index); 408 } 409 410 // Define index modulename-instance (not unique) to be dropped form event. 411 $table = new xmldb_table('event'); 412 $index = new xmldb_index('modulename-instance', XMLDB_INDEX_NOTUNIQUE, ['modulename', 'instance']); 413 414 // Conditionally launch drop index modulename-instance. 415 if ($dbman->index_exists($table, $index)) { 416 $dbman->drop_index($table, $index); 417 } 418 419 // Main savepoint reached. 420 upgrade_main_savepoint(true, 2021052500.20); 421 } 422 423 if ($oldversion < 2021052500.24) { 424 // Define fields tutorial and example to be added to h5p_libraries. 425 $table = new xmldb_table('h5p_libraries'); 426 427 // Add tutorial field. 428 $field = new xmldb_field('tutorial', XMLDB_TYPE_TEXT, null, null, null, null, null, 'metadatasettings'); 429 if (!$dbman->field_exists($table, $field)) { 430 $dbman->add_field($table, $field); 431 } 432 433 // Add example field. 434 $field = new xmldb_field('example', XMLDB_TYPE_TEXT, null, null, null, null, null, 'tutorial'); 435 436 if (!$dbman->field_exists($table, $field)) { 437 $dbman->add_field($table, $field); 438 } 439 440 // Main savepoint reached. 441 upgrade_main_savepoint(true, 2021052500.24); 442 } 443 444 if ($oldversion < 2021052500.26) { 445 // Delete orphaned course_modules_completion rows; these were not deleted properly 446 // by remove_course_contents function. 447 $DB->delete_records_select('course_modules_completion', " 448 NOT EXISTS ( 449 SELECT 1 450 FROM {course_modules} cm 451 WHERE cm.id = {course_modules_completion}.coursemoduleid 452 )"); 453 upgrade_main_savepoint(true, 2021052500.26); 454 } 455 456 if ($oldversion < 2021052500.27) { 457 // Script to fix incorrect records of "hidden" field in existing grade items. 458 $sql = "SELECT cm.instance, cm.course 459 FROM {course_modules} cm 460 JOIN {modules} m ON m.id = cm.module 461 WHERE m.name = :module AND cm.visible = :visible"; 462 $hidequizlist = $DB->get_recordset_sql($sql, ['module' => 'quiz', 'visible' => 0]); 463 464 foreach ($hidequizlist as $hidequiz) { 465 $params = [ 466 'itemmodule' => 'quiz', 467 'courseid' => $hidequiz->course, 468 'iteminstance' => $hidequiz->instance, 469 ]; 470 471 $DB->set_field('grade_items', 'hidden', 1, $params); 472 } 473 $hidequizlist->close(); 474 475 upgrade_main_savepoint(true, 2021052500.27); 476 } 477 478 if ($oldversion < 2021052500.29) { 479 // Get the current guest user which is also set as 'deleted'. 480 $guestuser = $DB->get_record('user', ['id' => $CFG->siteguest, 'deleted' => 1]); 481 // If there is a deleted guest user, reset the user to not be deleted and make sure the related 482 // user context exists. 483 if ($guestuser) { 484 $guestuser->deleted = 0; 485 $DB->update_record('user', $guestuser); 486 487 // Get the guest user context. 488 $guestusercontext = $DB->get_record('context', 489 ['contextlevel' => CONTEXT_USER, 'instanceid' => $guestuser->id]); 490 491 // If the guest user context does not exist, create it. 492 if (!$guestusercontext) { 493 $record = new stdClass(); 494 $record->contextlevel = CONTEXT_USER; 495 $record->instanceid = $guestuser->id; 496 $record->depth = 0; 497 // The path is not known before insert. 498 $record->path = null; 499 $record->locked = 0; 500 501 $record->id = $DB->insert_record('context', $record); 502 503 // Update the path. 504 $record->path = '/' . SYSCONTEXTID . '/' . $record->id; 505 $record->depth = substr_count($record->path, '/'); 506 $DB->update_record('context', $record); 507 } 508 } 509 510 // Main savepoint reached. 511 upgrade_main_savepoint(true, 2021052500.29); 512 } 513 514 if ($oldversion < 2021052500.30) { 515 // Reset analytics model output dir if it's the default value. 516 $modeloutputdir = get_config('analytics', 'modeloutputdir'); 517 if (strcasecmp($modeloutputdir, $CFG->dataroot . DIRECTORY_SEPARATOR . 'models') == 0) { 518 set_config('modeloutputdir', '', 'analytics'); 519 } 520 521 // Main savepoint reached. 522 upgrade_main_savepoint(true, 2021052500.30); 523 } 524 525 if ($oldversion < 2021052500.32) { 526 // Define field downloadcontent to be added to course. 527 $table = new xmldb_table('course'); 528 $field = new xmldb_field('downloadcontent', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'visibleold'); 529 530 if (!$dbman->field_exists($table, $field)) { 531 $dbman->add_field($table, $field); 532 } 533 534 // Main savepoint reached. 535 upgrade_main_savepoint(true, 2021052500.32); 536 } 537 538 if ($oldversion < 2021052500.33) { 539 $table = new xmldb_table('badge_backpack'); 540 541 // There is no key_exists, so test the equivalent index. 542 $oldindex = new xmldb_index('backpackcredentials', XMLDB_KEY_UNIQUE, ['userid', 'externalbackpackid']); 543 if (!$dbman->index_exists($table, $oldindex)) { 544 // All external backpack providers/hosts are now exclusively stored in badge_external_backpack. 545 // All credentials are stored in badge_backpack and are unique per user, backpack. 546 $uniquekey = new xmldb_key('backpackcredentials', XMLDB_KEY_UNIQUE, ['userid', 'externalbackpackid']); 547 $dbman->add_key($table, $uniquekey); 548 } 549 550 // Drop the password field as this is moved to badge_backpack. 551 $table = new xmldb_table('badge_external_backpack'); 552 $field = new xmldb_field('password', XMLDB_TYPE_CHAR, '50'); 553 if ($dbman->field_exists($table, $field)) { 554 // If there is a current backpack set then copy it across to the new structure. 555 if ($CFG->badges_defaultissuercontact) { 556 // Get the currently used site backpacks. 557 $records = $DB->get_records_select('badge_external_backpack', "password IS NOT NULL AND password != ''"); 558 $backpack = [ 559 'userid' => '0', 560 'email' => $CFG->badges_defaultissuercontact, 561 'backpackuid' => -1 562 ]; 563 564 // Create records corresponding to the site backpacks. 565 foreach ($records as $record) { 566 $backpack['password'] = $record->password; 567 $backpack['externalbackpackid'] = $record->id; 568 $DB->insert_record('badge_backpack', (object) $backpack); 569 } 570 } 571 572 $dbman->drop_field($table, $field); 573 } 574 575 // Main savepoint reached. 576 upgrade_main_savepoint(true, 2021052500.33); 577 } 578 579 if ($oldversion < 2021052500.36) { 580 // Define table payment_accounts to be created. 581 $table = new xmldb_table('payment_accounts'); 582 583 // Adding fields to table payment_accounts. 584 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 585 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 586 $table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null); 587 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 588 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 589 $table->add_field('archived', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 590 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 591 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 592 593 // Adding keys to table payment_accounts. 594 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 595 596 // Conditionally launch create table for payment_accounts. 597 if (!$dbman->table_exists($table)) { 598 $dbman->create_table($table); 599 } 600 601 // Define table payment_gateways to be created. 602 $table = new xmldb_table('payment_gateways'); 603 604 // Adding fields to table payment_gateways. 605 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 606 $table->add_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 607 $table->add_field('gateway', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 608 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1'); 609 $table->add_field('config', XMLDB_TYPE_TEXT, null, null, null, null, null); 610 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 611 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 612 613 // Adding keys to table payment_gateways. 614 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 615 $table->add_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']); 616 617 // Conditionally launch create table for payment_gateways. 618 if (!$dbman->table_exists($table)) { 619 $dbman->create_table($table); 620 } 621 622 // Define table payments to be created. 623 $table = new xmldb_table('payments'); 624 625 // Adding fields to table payments. 626 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 627 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 628 $table->add_field('paymentarea', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null); 629 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 630 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 631 $table->add_field('amount', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null); 632 $table->add_field('currency', XMLDB_TYPE_CHAR, '3', null, XMLDB_NOTNULL, null, null); 633 $table->add_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 634 $table->add_field('gateway', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 635 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 636 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 637 638 // Adding keys to table payments. 639 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 640 $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']); 641 $table->add_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']); 642 643 // Adding indexes to table payments. 644 $table->add_index('gateway', XMLDB_INDEX_NOTUNIQUE, ['gateway']); 645 $table->add_index('component-paymentarea-itemid', XMLDB_INDEX_NOTUNIQUE, ['component', 'paymentarea', 'itemid']); 646 647 // Conditionally launch create table for payments. 648 if (!$dbman->table_exists($table)) { 649 $dbman->create_table($table); 650 } 651 652 // Main savepoint reached. 653 upgrade_main_savepoint(true, 2021052500.36); 654 } 655 656 if ($oldversion < 2021052500.42) { 657 // Get all lessons that are set with a completion criteria of 'requires grade' but with no grade type set. 658 $sql = "SELECT cm.id 659 FROM {course_modules} cm 660 JOIN {lesson} l ON l.id = cm.instance 661 JOIN {modules} m ON m.id = cm.module 662 WHERE m.name = :name AND cm.completiongradeitemnumber IS NOT NULL AND l.grade = :grade"; 663 664 do { 665 if ($invalidconfigrations = $DB->get_records_sql($sql, ['name' => 'lesson', 'grade' => 0], 0, 1000)) { 666 list($insql, $inparams) = $DB->get_in_or_equal(array_keys($invalidconfigrations), SQL_PARAMS_NAMED); 667 $DB->set_field_select('course_modules', 'completiongradeitemnumber', null, "id $insql", $inparams); 668 } 669 } while ($invalidconfigrations); 670 671 upgrade_main_savepoint(true, 2021052500.42); 672 } 673 674 if ($oldversion < 2021052500.55) { 675 $DB->delete_records_select('event', "eventtype = 'category' AND categoryid = 0 AND userid <> 0"); 676 677 upgrade_main_savepoint(true, 2021052500.55); 678 } 679 680 if ($oldversion < 2021052500.59) { 681 // Define field visibility to be added to contentbank_content. 682 $table = new xmldb_table('contentbank_content'); 683 $field = new xmldb_field('visibility', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'contextid'); 684 685 // Conditionally launch add field visibility. 686 if (!$dbman->field_exists($table, $field)) { 687 $dbman->add_field($table, $field); 688 } 689 690 // Main savepoint reached. 691 upgrade_main_savepoint(true, 2021052500.59); 692 } 693 694 if ($oldversion < 2021052500.60) { 695 696 // We are going to remove the field 'hidepicture' from the groups 697 // so we need to remove the pictures from those groups. But we prevent 698 // the execution twice because this could be executed again when upgrading 699 // to different versions. 700 if ($dbman->field_exists('groups', 'hidepicture')) { 701 702 $sql = "SELECT g.id, g.courseid, ctx.id AS contextid 703 FROM {groups} g 704 JOIN {context} ctx 705 ON ctx.instanceid = g.courseid 706 AND ctx.contextlevel = :contextlevel 707 WHERE g.hidepicture = 1"; 708 709 // Selecting all the groups that have hide picture enabled, and organising them by context. 710 $groupctx = []; 711 $records = $DB->get_recordset_sql($sql, ['contextlevel' => CONTEXT_COURSE]); 712 foreach ($records as $record) { 713 if (!isset($groupctx[$record->contextid])) { 714 $groupctx[$record->contextid] = []; 715 } 716 $groupctx[$record->contextid][] = $record->id; 717 } 718 $records->close(); 719 720 // Deleting the group files. 721 $fs = get_file_storage(); 722 foreach ($groupctx as $contextid => $groupids) { 723 list($in, $inparams) = $DB->get_in_or_equal($groupids, SQL_PARAMS_NAMED); 724 $fs->delete_area_files_select($contextid, 'group', 'icon', $in, $inparams); 725 } 726 727 // Updating the database to remove picture from all those groups. 728 $sql = "UPDATE {groups} SET picture = :pic WHERE hidepicture = :hide"; 729 $DB->execute($sql, ['pic' => 0, 'hide' => 1]); 730 } 731 732 // Define field hidepicture to be dropped from groups. 733 $table = new xmldb_table('groups'); 734 $field = new xmldb_field('hidepicture'); 735 736 // Conditionally launch drop field hidepicture. 737 if ($dbman->field_exists($table, $field)) { 738 $dbman->drop_field($table, $field); 739 } 740 741 // Main savepoint reached. 742 upgrade_main_savepoint(true, 2021052500.60); 743 } 744 745 if ($oldversion < 2021052500.64) { 746 // Get all the external backpacks and update the sortorder column, to avoid repeated/wrong values. As sortorder was not 747 // used since now, the id column will be the criteria to follow for re-ordering them with a valid value. 748 $i = 1; 749 $records = $DB->get_records('badge_external_backpack', null, 'id ASC'); 750 foreach ($records as $record) { 751 $record->sortorder = $i++; 752 $DB->update_record('badge_external_backpack', $record); 753 } 754 755 upgrade_main_savepoint(true, 2021052500.64); 756 } 757 758 if ($oldversion < 2021052500.67) { 759 // The $CFG->badges_site_backpack setting has been removed because it's not required anymore. From now, the default backpack 760 // will be the one with lower sortorder value. 761 unset_config('badges_site_backpack'); 762 763 upgrade_main_savepoint(true, 2021052500.67); 764 } 765 766 if ($oldversion < 2021052500.69) { 767 768 // Define field type to be added to oauth2_issuer. 769 $table = new xmldb_table('oauth2_issuer'); 770 $field = new xmldb_field('servicetype', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'requireconfirmation'); 771 772 // Conditionally launch add field type. 773 if (!$dbman->field_exists($table, $field)) { 774 $dbman->add_field($table, $field); 775 } 776 777 // Set existing values to the proper servicetype value. 778 // It's not critical if the servicetype column doesn't contain the proper value for Google, Microsoft, Facebook or 779 // Nextcloud services because, for now, this value is used for services using different discovery method. 780 // However, let's try to upgrade it using the default value for the baseurl or image. If any of these default values 781 // have been changed, the servicetype column will remain NULL. 782 $recordset = $DB->get_recordset('oauth2_issuer'); 783 foreach ($recordset as $record) { 784 if ($record->baseurl == 'https://accounts.google.com/') { 785 $record->servicetype = 'google'; 786 $DB->update_record('oauth2_issuer', $record); 787 } else if ($record->image == 'https://www.microsoft.com/favicon.ico') { 788 $record->servicetype = 'microsoft'; 789 $DB->update_record('oauth2_issuer', $record); 790 } else if ($record->image == 'https://facebookbrand.com/wp-content/uploads/2016/05/flogo_rgb_hex-brc-site-250.png') { 791 $record->servicetype = 'facebook'; 792 $DB->update_record('oauth2_issuer', $record); 793 } else if ($record->image == 'https://nextcloud.com/wp-content/themes/next/assets/img/common/favicon.png?x16328') { 794 $record->servicetype = 'nextcloud'; 795 $DB->update_record('oauth2_issuer', $record); 796 } 797 } 798 $recordset->close(); 799 800 // Main savepoint reached. 801 upgrade_main_savepoint(true, 2021052500.69); 802 } 803 804 if ($oldversion < 2021052500.74) { 805 // Define field 'showactivitydates' to be added to course table. 806 $table = new xmldb_table('course'); 807 $field = new xmldb_field('showactivitydates', XMLDB_TYPE_INTEGER, '1', null, 808 XMLDB_NOTNULL, null, '0', 'originalcourseid'); 809 810 if (!$dbman->field_exists($table, $field)) { 811 $dbman->add_field($table, $field); 812 } 813 814 // Main savepoint reached. 815 upgrade_main_savepoint(true, 2021052500.74); 816 } 817 818 if ($oldversion < 2021052500.75) { 819 // Define field 'showcompletionconditions' to be added to course. 820 $table = new xmldb_table('course'); 821 $field = new xmldb_field('showcompletionconditions', XMLDB_TYPE_INTEGER, '1', null, 822 XMLDB_NOTNULL, null, '1', 'completionnotify'); 823 824 if (!$dbman->field_exists($table, $field)) { 825 $dbman->add_field($table, $field); 826 } 827 828 // Main savepoint reached. 829 upgrade_main_savepoint(true, 2021052500.75); 830 } 831 832 if ($oldversion < 2021052500.78) { 833 834 // Define field enabled to be added to h5p_libraries. 835 $table = new xmldb_table('h5p_libraries'); 836 $field = new xmldb_field('enabled', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'example'); 837 838 // Conditionally launch add field enabled. 839 if (!$dbman->field_exists($table, $field)) { 840 $dbman->add_field($table, $field); 841 } 842 843 // Main savepoint reached. 844 upgrade_main_savepoint(true, 2021052500.78); 845 } 846 847 if ($oldversion < 2021052500.83) { 848 849 // Define field loginpagename to be added to oauth2_issuer. 850 $table = new xmldb_table('oauth2_issuer'); 851 $field = new xmldb_field('loginpagename', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'servicetype'); 852 853 // Conditionally launch add field loginpagename. 854 if (!$dbman->field_exists($table, $field)) { 855 $dbman->add_field($table, $field); 856 } 857 858 // Main savepoint reached. 859 upgrade_main_savepoint(true, 2021052500.83); 860 } 861 862 if ($oldversion < 2021052500.84) { 863 require_once($CFG->dirroot . '/user/profile/field/social/upgradelib.php'); 864 $table = new xmldb_table('user'); 865 $tablecolumns = ['icq', 'skype', 'aim', 'yahoo', 'msn', 'url']; 866 867 foreach ($tablecolumns as $column) { 868 $field = new xmldb_field($column); 869 if ($dbman->field_exists($table, $field)) { 870 user_profile_social_moveto_profilefield($column); 871 $dbman->drop_field($table, $field); 872 } 873 } 874 875 // Update all module availability if it relies on the old user fields. 876 user_profile_social_update_module_availability(); 877 878 // Remove field mapping for oauth2. 879 $DB->delete_records('oauth2_user_field_mapping', array('internalfield' => 'url')); 880 881 // Main savepoint reached. 882 upgrade_main_savepoint(true, 2021052500.84); 883 } 884 885 if ($oldversion < 2021052500.85) { 886 require_once($CFG->libdir . '/db/upgradelib.php'); 887 888 // Check if this site has executed the problematic upgrade steps. 889 $needsfixing = upgrade_calendar_site_status(false); 890 891 // Only queue the task if this site has been affected by the problematic upgrade step. 892 if ($needsfixing) { 893 894 // Create adhoc task to search and recover orphaned calendar events. 895 $record = new \stdClass(); 896 $record->classname = '\core\task\calendar_fix_orphaned_events'; 897 898 // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task(). 899 $nextruntime = time() - 1; 900 $record->nextruntime = $nextruntime; 901 $DB->insert_record('task_adhoc', $record); 902 } 903 904 // Main savepoint reached. 905 upgrade_main_savepoint(true, 2021052500.85); 906 } 907 908 if ($oldversion < 2021052500.87) { 909 // Changing the default of field showcompletionconditions on table course to 0. 910 $table = new xmldb_table('course'); 911 $field = new xmldb_field('showcompletionconditions', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'showactivitydates'); 912 913 // Launch change of nullability for field showcompletionconditions. 914 $dbman->change_field_notnull($table, $field); 915 916 // Launch change of default for field showcompletionconditions. 917 $dbman->change_field_default($table, $field); 918 919 // Set showcompletionconditions to null for courses which don't track completion. 920 $sql = "UPDATE {course} 921 SET showcompletionconditions = null 922 WHERE enablecompletion <> 1"; 923 $DB->execute($sql); 924 925 // Main savepoint reached. 926 upgrade_main_savepoint(true, 2021052500.87); 927 } 928 929 if ($oldversion < 2021052500.90) { 930 // Remove usemodchooser user preference for every user. 931 $DB->delete_records('user_preferences', ['name' => 'usemodchooser']); 932 933 // Main savepoint reached. 934 upgrade_main_savepoint(true, 2021052500.90); 935 } 936 937 if ($oldversion < 2021060200.00) { 938 939 // Define index name (not unique) to be added to user_preferences. 940 $table = new xmldb_table('user_preferences'); 941 $index = new xmldb_index('name', XMLDB_INDEX_NOTUNIQUE, ['name']); 942 943 // Conditionally launch add index name. 944 if (!$dbman->index_exists($table, $index)) { 945 $dbman->add_index($table, $index); 946 } 947 948 // Main savepoint reached. 949 upgrade_main_savepoint(true, 2021060200.00); 950 } 951 952 if ($oldversion < 2021060900.00) { 953 // Update the externalfield to be larger. 954 $table = new xmldb_table('oauth2_user_field_mapping'); 955 $field = new xmldb_field('externalfield', XMLDB_TYPE_CHAR, '500', null, XMLDB_NOTNULL, false, null, 'issuerid'); 956 $dbman->change_field_type($table, $field); 957 958 // Main savepoint reached. 959 upgrade_main_savepoint(true, 2021060900.00); 960 } 961 962 if ($oldversion < 2021072800.01) { 963 // Define table reportbuilder_report to be created. 964 $table = new xmldb_table('reportbuilder_report'); 965 966 // Adding fields to table reportbuilder_report. 967 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 968 $table->add_field('source', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 969 $table->add_field('type', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0'); 970 $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 971 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 972 $table->add_field('area', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 973 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 974 $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 975 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 976 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 977 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 978 979 // Adding keys to table reportbuilder_report. 980 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 981 $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']); 982 $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']); 983 $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']); 984 985 // Conditionally launch create table for reportbuilder_report. 986 if (!$dbman->table_exists($table)) { 987 $dbman->create_table($table); 988 } 989 990 // Main savepoint reached. 991 upgrade_main_savepoint(true, 2021072800.01); 992 } 993 994 if ($oldversion < 2021090200.01) { 995 // Remove qformat_webct (unless it has manually been added back). 996 if (!file_exists($CFG->dirroot . '/question/format/webct/format.php')) { 997 unset_all_config_for_plugin('qformat_webct'); 998 } 999 1000 // Main savepoint reached. 1001 upgrade_main_savepoint(true, 2021090200.01); 1002 } 1003 1004 if ($oldversion < 2021091100.01) { 1005 // If message_jabber is no longer present, remove it. 1006 if (!file_exists($CFG->dirroot . '/message/output/jabber/message_output_jabber.php')) { 1007 // Remove Jabber from the notification plugins list. 1008 $DB->delete_records('message_processors', ['name' => 'jabber']); 1009 1010 // Remove user preference settings. 1011 $DB->delete_records('user_preferences', ['name' => 'message_processor_jabber_jabberid']); 1012 $sql = 'SELECT * 1013 FROM {user_preferences} up 1014 WHERE ' . $DB->sql_like('up.name', ':name', false, false) . ' AND ' . 1015 $DB->sql_like('up.value', ':value', false, false); 1016 $params = [ 1017 'name' => 'message_provider_%', 1018 'value' => '%jabber%', 1019 ]; 1020 $jabbersettings = $DB->get_recordset_sql($sql, $params); 1021 foreach ($jabbersettings as $jabbersetting) { 1022 // Remove 'jabber' from the value. 1023 $jabbersetting->value = implode(',', array_diff(explode(',', $jabbersetting->value), ['jabber'])); 1024 $DB->update_record('user_preferences', $jabbersetting); 1025 } 1026 $jabbersettings->close(); 1027 1028 // Clean config settings. 1029 unset_config('jabberhost'); 1030 unset_config('jabberserver'); 1031 unset_config('jabberusername'); 1032 unset_config('jabberpassword'); 1033 unset_config('jabberport'); 1034 1035 // Remove default notification preferences. 1036 $like = $DB->sql_like('name', '?', true, true, false, '|'); 1037 $params = [$DB->sql_like_escape('jabber_provider_', '|') . '%']; 1038 $DB->delete_records_select('config_plugins', $like, $params); 1039 1040 // Clean config config settings. 1041 unset_all_config_for_plugin('message_jabber'); 1042 } 1043 1044 upgrade_main_savepoint(true, 2021091100.01); 1045 } 1046 1047 if ($oldversion < 2021091100.02) { 1048 // Set the description field to HTML format for the Default course category. 1049 $category = $DB->get_record('course_categories', ['id' => 1]); 1050 1051 if (!empty($category) && $category->descriptionformat == FORMAT_MOODLE) { 1052 // Format should be changed only if it's still set to FORMAT_MOODLE. 1053 if (!is_null($category->description)) { 1054 // If description is not empty, format the content to HTML. 1055 $category->description = format_text($category->description, FORMAT_MOODLE); 1056 } 1057 $category->descriptionformat = FORMAT_HTML; 1058 $DB->update_record('course_categories', $category); 1059 } 1060 1061 // Main savepoint reached. 1062 upgrade_main_savepoint(true, 2021091100.02); 1063 } 1064 1065 if ($oldversion < 2021091700.01) { 1066 // Default 'off' for existing sites as this is the behaviour they had earlier. 1067 set_config('enroladminnewcourse', false); 1068 1069 // Main savepoint reached. 1070 upgrade_main_savepoint(true, 2021091700.01); 1071 } 1072 1073 if ($oldversion < 2021091700.02) { 1074 // If portfolio_picasa is no longer present, remove it. 1075 if (!file_exists($CFG->dirroot . '/portfolio/picasa/version.php')) { 1076 $instance = $DB->get_record('portfolio_instance', ['plugin' => 'picasa']); 1077 if (!empty($instance)) { 1078 // Remove all records from portfolio_instance_config. 1079 $DB->delete_records('portfolio_instance_config', ['instance' => $instance->id]); 1080 // Remove all records from portfolio_instance_user. 1081 $DB->delete_records('portfolio_instance_user', ['instance' => $instance->id]); 1082 // Remove all records from portfolio_log. 1083 $DB->delete_records('portfolio_log', ['portfolio' => $instance->id]); 1084 // Remove all records from portfolio_tempdata. 1085 $DB->delete_records('portfolio_tempdata', ['instance' => $instance->id]); 1086 // Remove the record from the portfolio_instance table. 1087 $DB->delete_records('portfolio_instance', ['id' => $instance->id]); 1088 } 1089 1090 // Clean config. 1091 unset_all_config_for_plugin('portfolio_picasa'); 1092 } 1093 1094 upgrade_main_savepoint(true, 2021091700.02); 1095 } 1096 1097 if ($oldversion < 2021091700.03) { 1098 // If repository_picasa is no longer present, remove it. 1099 if (!file_exists($CFG->dirroot . '/repository/picasa/version.php')) { 1100 $instance = $DB->get_record('repository', ['type' => 'picasa']); 1101 if (!empty($instance)) { 1102 // Remove all records from repository_instance_config table. 1103 $DB->delete_records('repository_instance_config', ['instanceid' => $instance->id]); 1104 // Remove all records from repository_instances table. 1105 $DB->delete_records('repository_instances', ['typeid' => $instance->id]); 1106 // Remove the record from the repository table. 1107 $DB->delete_records('repository', ['id' => $instance->id]); 1108 } 1109 1110 // Clean config. 1111 unset_all_config_for_plugin('picasa'); 1112 1113 // Remove orphaned files. 1114 upgrade_delete_orphaned_file_records(); 1115 } 1116 1117 upgrade_main_savepoint(true, 2021091700.03); 1118 } 1119 1120 if ($oldversion < 2021091700.04) { 1121 // Remove media_swf (unless it has manually been added back). 1122 if (!file_exists($CFG->dirroot . '/media/player/swf/classes/plugin.php')) { 1123 unset_all_config_for_plugin('media_swf'); 1124 } 1125 1126 upgrade_main_savepoint(true, 2021091700.04); 1127 } 1128 1129 if ($oldversion < 2021092400.01) { 1130 // If tool_health is no longer present, remove it. 1131 if (!file_exists($CFG->dirroot . '/admin/tool/health/version.php')) { 1132 // Clean config. 1133 unset_all_config_for_plugin('tool_health'); 1134 } 1135 1136 // Main savepoint reached. 1137 upgrade_main_savepoint(true, 2021092400.01); 1138 } 1139 1140 if ($oldversion < 2021092400.03) { 1141 // Remove repository_picasa configuration (unless it has manually been added back). 1142 if (!file_exists($CFG->dirroot . '/repository/picasa/version.php')) { 1143 unset_all_config_for_plugin('repository_picasa'); 1144 } 1145 1146 upgrade_main_savepoint(true, 2021092400.03); 1147 } 1148 1149 if ($oldversion < 2021100300.01) { 1150 // Remove repository_skydrive (unless it has manually been added back). 1151 if (!file_exists($CFG->dirroot . '/repository/skydrive/lib.php')) { 1152 unset_all_config_for_plugin('repository_skydrive'); 1153 } 1154 1155 // Main savepoint reached. 1156 upgrade_main_savepoint(true, 2021100300.01); 1157 } 1158 1159 if ($oldversion < 2021100300.02) { 1160 // Remove filter_censor (unless it has manually been added back). 1161 if (!file_exists($CFG->dirroot . '/filter/censor/filter.php')) { 1162 unset_all_config_for_plugin('filter_censor'); 1163 } 1164 1165 // Main savepoint reached. 1166 upgrade_main_savepoint(true, 2021100300.02); 1167 } 1168 1169 if ($oldversion < 2021100600.01) { 1170 // Remove qformat_examview (unless it has manually been added back). 1171 if (!file_exists($CFG->dirroot . '/question/format/examview/format.php')) { 1172 unset_all_config_for_plugin('qformat_examview'); 1173 } 1174 1175 // Main savepoint reached. 1176 upgrade_main_savepoint(true, 2021100600.01); 1177 } 1178 1179 if ($oldversion < 2021100600.02) { 1180 $table = new xmldb_table('course_completion_defaults'); 1181 1182 // Adding fields to table course_completion_defaults. 1183 $field = new xmldb_field('completionpassgrade', XMLDB_TYPE_INTEGER, '1', null, 1184 XMLDB_NOTNULL, null, '0', 'completionusegrade'); 1185 1186 // Conditionally launch add field for course_completion_defaults. 1187 if (!$dbman->field_exists($table, $field)) { 1188 $dbman->add_field($table, $field); 1189 } 1190 1191 upgrade_main_savepoint(true, 2021100600.02); 1192 } 1193 1194 if ($oldversion < 2021100600.03) { 1195 $table = new xmldb_table('course_modules'); 1196 1197 // Adding new fields to table course_module table. 1198 $field = new xmldb_field('completionpassgrade', XMLDB_TYPE_INTEGER, '1', null, 1199 XMLDB_NOTNULL, null, '0', 'completionexpected'); 1200 // Conditionally launch create table for course_completion_defaults. 1201 if (!$dbman->field_exists($table, $field)) { 1202 $dbman->add_field($table, $field); 1203 } 1204 1205 upgrade_main_savepoint(true, 2021100600.03); 1206 } 1207 1208 if ($oldversion < 2021100600.04) { 1209 // Define index itemtype-mod-inst-course (not unique) to be added to grade_items. 1210 $table = new xmldb_table('grade_items'); 1211 $index = new xmldb_index('itemtype-mod-inst-course', XMLDB_INDEX_NOTUNIQUE, 1212 ['itemtype', 'itemmodule', 'iteminstance', 'courseid']); 1213 1214 // Conditionally launch add index itemtype-mod-inst-course. 1215 if (!$dbman->index_exists($table, $index)) { 1216 $dbman->add_index($table, $index); 1217 } 1218 1219 // Main savepoint reached. 1220 upgrade_main_savepoint(true, 2021100600.04); 1221 } 1222 1223 if ($oldversion < 2021101900.01) { 1224 $table = new xmldb_table('reportbuilder_report'); 1225 1226 // Define field name to be added to reportbuilder_report. 1227 $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'id'); 1228 if (!$dbman->field_exists($table, $field)) { 1229 $dbman->add_field($table, $field); 1230 } 1231 1232 // Define field conditiondata to be added to reportbuilder_report. 1233 $field = new xmldb_field('conditiondata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'type'); 1234 if (!$dbman->field_exists($table, $field)) { 1235 $dbman->add_field($table, $field); 1236 } 1237 1238 // Define table reportbuilder_column to be created. 1239 $table = new xmldb_table('reportbuilder_column'); 1240 1241 // Adding fields to table reportbuilder_column. 1242 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1243 $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1244 $table->add_field('uniqueidentifier', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1245 $table->add_field('aggregation', XMLDB_TYPE_CHAR, '32', null, null, null, null); 1246 $table->add_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null); 1247 $table->add_field('columnorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1248 $table->add_field('sortenabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 1249 $table->add_field('sortdirection', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null); 1250 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 1251 $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1252 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1253 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1254 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1255 1256 // Adding keys to table reportbuilder_column. 1257 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1258 $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']); 1259 $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']); 1260 $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']); 1261 1262 // Conditionally launch create table for reportbuilder_column. 1263 if (!$dbman->table_exists($table)) { 1264 $dbman->create_table($table); 1265 } 1266 1267 // Define table reportbuilder_filter to be created. 1268 $table = new xmldb_table('reportbuilder_filter'); 1269 1270 // Adding fields to table reportbuilder_filter. 1271 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1272 $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1273 $table->add_field('uniqueidentifier', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1274 $table->add_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null); 1275 $table->add_field('iscondition', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 1276 $table->add_field('filterorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1277 $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1278 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1279 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1280 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1281 1282 // Adding keys to table reportbuilder_filter. 1283 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1284 $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']); 1285 $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']); 1286 $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']); 1287 1288 // Conditionally launch create table for reportbuilder_filter. 1289 if (!$dbman->table_exists($table)) { 1290 $dbman->create_table($table); 1291 } 1292 1293 // Main savepoint reached. 1294 upgrade_main_savepoint(true, 2021101900.01); 1295 } 1296 1297 if ($oldversion < 2021102600.01) { 1298 // Remove block_quiz_results (unless it has manually been added back). 1299 if (!file_exists($CFG->dirroot . '/blocks/quiz_result/block_quiz_results.php')) { 1300 // Delete instances. 1301 $instances = $DB->get_records_list('block_instances', 'blockname', ['quiz_results']); 1302 $instanceids = array_keys($instances); 1303 1304 if (!empty($instanceids)) { 1305 blocks_delete_instances($instanceids); 1306 } 1307 1308 // Delete the block from the block table. 1309 $DB->delete_records('block', array('name' => 'quiz_results')); 1310 1311 // Remove capabilities. 1312 capabilities_cleanup('block_quiz_results'); 1313 // Clean config. 1314 unset_all_config_for_plugin('block_quiz_results'); 1315 1316 // Remove Moodle-level quiz_results based capabilities. 1317 $capabilitiestoberemoved = ['block/quiz_results:addinstance']; 1318 // Delete any role_capabilities for the old roles. 1319 $DB->delete_records_list('role_capabilities', 'capability', $capabilitiestoberemoved); 1320 // Delete the capability itself. 1321 $DB->delete_records_list('capabilities', 'name', $capabilitiestoberemoved); 1322 } 1323 1324 upgrade_main_savepoint(true, 2021102600.01); 1325 } 1326 1327 if ($oldversion < 2021102900.02) { 1328 // If portfolio_boxnet is no longer present, remove it. 1329 if (!file_exists($CFG->dirroot . '/portfolio/boxnet/version.php')) { 1330 $instance = $DB->get_record('portfolio_instance', ['plugin' => 'boxnet']); 1331 if (!empty($instance)) { 1332 // Remove all records from portfolio_instance_config. 1333 $DB->delete_records('portfolio_instance_config', ['instance' => $instance->id]); 1334 // Remove all records from portfolio_instance_user. 1335 $DB->delete_records('portfolio_instance_user', ['instance' => $instance->id]); 1336 // Remove all records from portfolio_log. 1337 $DB->delete_records('portfolio_log', ['portfolio' => $instance->id]); 1338 // Remove all records from portfolio_tempdata. 1339 $DB->delete_records('portfolio_tempdata', ['instance' => $instance->id]); 1340 // Remove the record from the portfolio_instance table. 1341 $DB->delete_records('portfolio_instance', ['id' => $instance->id]); 1342 } 1343 1344 // Clean config. 1345 unset_all_config_for_plugin('portfolio_boxnet'); 1346 } 1347 1348 // If repository_boxnet is no longer present, remove it. 1349 if (!file_exists($CFG->dirroot . '/repository/boxnet/version.php')) { 1350 $instance = $DB->get_record('repository', ['type' => 'boxnet']); 1351 if (!empty($instance)) { 1352 // Remove all records from repository_instance_config table. 1353 $DB->delete_records('repository_instance_config', ['instanceid' => $instance->id]); 1354 // Remove all records from repository_instances table. 1355 $DB->delete_records('repository_instances', ['typeid' => $instance->id]); 1356 // Remove the record from the repository table. 1357 $DB->delete_records('repository', ['id' => $instance->id]); 1358 } 1359 1360 // Clean config. 1361 unset_all_config_for_plugin('repository_boxnet'); 1362 1363 // The boxnet repository plugin stores some config in 'boxnet' incorrectly. 1364 unset_all_config_for_plugin('boxnet'); 1365 1366 // Remove orphaned files. 1367 upgrade_delete_orphaned_file_records(); 1368 } 1369 1370 upgrade_main_savepoint(true, 2021102900.02); 1371 } 1372 1373 if ($oldversion < 2021110100.00) { 1374 1375 // Define table reportbuilder_audience to be created. 1376 $table = new xmldb_table('reportbuilder_audience'); 1377 1378 // Adding fields to table reportbuilder_audience. 1379 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1380 $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1381 $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1382 $table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 1383 $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1384 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1385 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1386 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1387 1388 // Adding keys to table reportbuilder_audience. 1389 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1390 $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']); 1391 $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']); 1392 $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']); 1393 1394 // Conditionally launch create table for reportbuilder_audience. 1395 if (!$dbman->table_exists($table)) { 1396 $dbman->create_table($table); 1397 } 1398 1399 // Main savepoint reached. 1400 upgrade_main_savepoint(true, 2021110100.00); 1401 } 1402 1403 if ($oldversion < 2021110800.02) { 1404 // Define a field 'downloadcontent' in the 'course_modules' table. 1405 $table = new xmldb_table('course_modules'); 1406 $field = new xmldb_field('downloadcontent', XMLDB_TYPE_INTEGER, '1', null, null, null, 1, 'deletioninprogress'); 1407 1408 // Conditionally launch add field 'downloadcontent'. 1409 if (!$dbman->field_exists($table, $field)) { 1410 $dbman->add_field($table, $field); 1411 } 1412 1413 // Main savepoint reached. 1414 upgrade_main_savepoint(true, 2021110800.02); 1415 } 1416 1417 if ($oldversion < 2021110800.03) { 1418 1419 // Define field settingsdata to be added to reportbuilder_report. 1420 $table = new xmldb_table('reportbuilder_report'); 1421 $field = new xmldb_field('settingsdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'conditiondata'); 1422 1423 // Conditionally launch add field settingsdata. 1424 if (!$dbman->field_exists($table, $field)) { 1425 $dbman->add_field($table, $field); 1426 } 1427 1428 // Main savepoint reached. 1429 upgrade_main_savepoint(true, 2021110800.03); 1430 } 1431 1432 if ($oldversion < 2021111700.00) { 1433 $mycoursespage = new stdClass(); 1434 $mycoursespage->userid = null; 1435 $mycoursespage->name = '__courses'; 1436 $mycoursespage->private = 0; 1437 $mycoursespage->sortorder = 0; 1438 $DB->insert_record('my_pages', $mycoursespage); 1439 1440 upgrade_main_savepoint(true, 2021111700.00); 1441 } 1442 1443 if ($oldversion < 2021111700.01) { 1444 1445 // Define field uniquerows to be added to reportbuilder_report. 1446 $table = new xmldb_table('reportbuilder_report'); 1447 $field = new xmldb_field('uniquerows', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'type'); 1448 1449 // Conditionally launch add field uniquerows. 1450 if (!$dbman->field_exists($table, $field)) { 1451 $dbman->add_field($table, $field); 1452 } 1453 1454 // Main savepoint reached. 1455 upgrade_main_savepoint(true, 2021111700.01); 1456 } 1457 1458 if ($oldversion < 2021120100.01) { 1459 1460 // Get current configuration data. 1461 $currentcustomusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems); 1462 $lines = explode("\n", $currentcustomusermenuitems); 1463 $lines = array_map('trim', $lines); 1464 $calendarcustomusermenu = 'calendar,core_calendar|/calendar/view.php?view=month|i/calendar'; 1465 1466 if (!in_array($calendarcustomusermenu, $lines)) { 1467 // Add Calendar item to the menu. 1468 array_splice($lines, 1, 0, [$calendarcustomusermenu]); 1469 set_config('customusermenuitems', implode("\n", $lines)); 1470 } 1471 1472 // Main savepoint reached. 1473 upgrade_main_savepoint(true, 2021120100.01); 1474 } 1475 1476 if ($oldversion < 2021121400.01) { 1477 // The $CFG->grade_navmethod setting has been removed because it's not required anymore. This setting was used 1478 // to set the type of navigation (tabs or dropdown box) which will be displayed in gradebook. However, these 1479 // navigation methods are no longer used and replaced with tertiary navigation. 1480 unset_config('grade_navmethod'); 1481 1482 // Main savepoint reached. 1483 upgrade_main_savepoint(true, 2021121400.01); 1484 } 1485 1486 if ($oldversion < 2021121700.01) { 1487 // Get current support email setting value. 1488 $config = get_config('moodle', 'supportemail'); 1489 1490 // Check if support email setting is empty and then set it to null. 1491 // We must do that so the setting is displayed during the upgrade. 1492 if (empty($config)) { 1493 set_config('supportemail', null); 1494 } 1495 1496 // Main savepoint reached. 1497 upgrade_main_savepoint(true, 2021121700.01); 1498 } 1499 1500 if ($oldversion < 2021122100.00) { 1501 // Get current configuration data. 1502 $currentcustomusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems); 1503 1504 // The old default customusermenuitems config for 3.11 and below. 1505 $oldcustomusermenuitems = 'grades,grades|/grade/report/mygrades.php|t/grades 1506 calendar,core_calendar|/calendar/view.php?view=month|i/calendar 1507 messages,message|/message/index.php|t/message 1508 preferences,moodle|/user/preferences.php|t/preferences'; 1509 1510 // Check if the current customusermenuitems config matches the old customusermenuitems config. 1511 $samecustomusermenuitems = $currentcustomusermenuitems == $oldcustomusermenuitems; 1512 if ($samecustomusermenuitems) { 1513 // If the site is still using the old defaults, upgrade to the new default. 1514 $newcustomusermenuitems = 'profile,moodle|/user/profile.php 1515 grades,grades|/grade/report/mygrades.php 1516 calendar,core_calendar|/calendar/view.php?view=month 1517 privatefiles,moodle|/user/files.php'; 1518 // Set the new configuration back. 1519 set_config('customusermenuitems', $newcustomusermenuitems); 1520 } else { 1521 // If the site is not using the old defaults, only add necessary entries. 1522 $lines = preg_split('/\n/', $currentcustomusermenuitems, -1, PREG_SPLIT_NO_EMPTY); 1523 $lines = array_map(static function(string $line): string { 1524 // Previous format was "<langstring>|<url>[|<pixicon>]" - pix icon is no longer supported. 1525 $lineparts = explode('|', trim($line), 3); 1526 // Return first two parts of line. 1527 return implode('|', array_slice($lineparts, 0, 2)); 1528 }, $lines); 1529 1530 // Remove the Preference entry from the menu to prevent duplication 1531 // since it will be added again in user_get_user_navigation_info(). 1532 $lines = array_filter($lines, function($value) { 1533 return strpos($value, 'preferences,moodle|/user/preferences.php') === false; 1534 }); 1535 1536 $matches = preg_grep('/\|\/user\/files.php/i', $lines); 1537 if (!$matches) { 1538 // Add the Private files entry to the menu. 1539 $lines[] = 'privatefiles,moodle|/user/files.php'; 1540 } 1541 1542 $matches = preg_grep('/\|\/user\/profile.php/i', $lines); 1543 if (!$matches) { 1544 // Add the Profile entry to top of the menu. 1545 array_unshift($lines, 'profile,moodle|/user/profile.php'); 1546 } 1547 1548 // Set the new configuration back. 1549 set_config('customusermenuitems', implode("\n", $lines)); 1550 } 1551 1552 // Main savepoint reached. 1553 upgrade_main_savepoint(true, 2021122100.00); 1554 } 1555 1556 1557 if ($oldversion < 2021122100.01) { 1558 1559 // Define field heading to be added to reportbuilder_audience. 1560 $table = new xmldb_table('reportbuilder_audience'); 1561 $field = new xmldb_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'reportid'); 1562 1563 // Conditionally launch add field heading. 1564 if (!$dbman->field_exists($table, $field)) { 1565 $dbman->add_field($table, $field); 1566 } 1567 1568 // Main savepoint reached. 1569 upgrade_main_savepoint(true, 2021122100.01); 1570 } 1571 1572 if ($oldversion < 2021122100.02) { 1573 1574 // Define table reportbuilder_schedule to be created. 1575 $table = new xmldb_table('reportbuilder_schedule'); 1576 1577 // Adding fields to table reportbuilder_schedule. 1578 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1579 $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1580 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1581 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1'); 1582 $table->add_field('audiences', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 1583 $table->add_field('format', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1584 $table->add_field('subject', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1585 $table->add_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null); 1586 $table->add_field('messageformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1587 $table->add_field('userviewas', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1588 $table->add_field('timescheduled', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1589 $table->add_field('recurrence', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1590 $table->add_field('reportempty', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1591 $table->add_field('timelastsent', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1592 $table->add_field('timenextsend', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1593 $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1594 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1595 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1596 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1597 1598 // Adding keys to table reportbuilder_schedule. 1599 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1600 $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']); 1601 $table->add_key('userviewas', XMLDB_KEY_FOREIGN, ['userviewas'], 'user', ['id']); 1602 $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']); 1603 $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']); 1604 1605 // Conditionally launch create table for reportbuilder_schedule. 1606 if (!$dbman->table_exists($table)) { 1607 $dbman->create_table($table); 1608 } 1609 1610 // Main savepoint reached. 1611 upgrade_main_savepoint(true, 2021122100.02); 1612 } 1613 1614 if ($oldversion < 2021123000.01) { 1615 // The tool_admin_presets tables have been moved to core, because core_adminpresets component has been created, so 1616 // it can interact with the rest of core. 1617 // So the tool_admin_presetsXXX tables will be renamed to adminipresetsXXX if they exists; otherwise, they will be created. 1618 1619 $tooltable = new xmldb_table('tool_admin_presets'); 1620 $table = new xmldb_table('adminpresets'); 1621 if ($dbman->table_exists($tooltable)) { 1622 $dbman->rename_table($tooltable, 'adminpresets'); 1623 } else if (!$dbman->table_exists($table)) { 1624 // Adding fields to table adminpresets. 1625 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1626 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1627 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1628 $table->add_field('comments', XMLDB_TYPE_TEXT, null, null, null, null, null); 1629 $table->add_field('site', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1630 $table->add_field('author', XMLDB_TYPE_CHAR, '255', null, null, null, null); 1631 $table->add_field('moodleversion', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null); 1632 $table->add_field('moodlerelease', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 1633 $table->add_field('iscore', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 1634 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1635 $table->add_field('timeimported', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 1636 1637 // Adding keys to table adminpresets. 1638 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1639 1640 // Launch create table for adminpresets. 1641 $dbman->create_table($table); 1642 } 1643 1644 $tooltable = new xmldb_table('tool_admin_presets_it'); 1645 $table = new xmldb_table('adminpresets_it'); 1646 if ($dbman->table_exists($tooltable)) { 1647 $dbman->rename_table($tooltable, 'adminpresets_it'); 1648 } else if (!$dbman->table_exists($table)) { 1649 // Adding fields to table adminpresets_it. 1650 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1651 $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1652 $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null); 1653 $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 1654 $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null); 1655 1656 // Adding keys to table adminpresets_it. 1657 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1658 1659 // Adding indexes to table adminpresets_it. 1660 $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']); 1661 1662 // Launch create table for adminpresets_it. 1663 $dbman->create_table($table); 1664 } 1665 1666 $tooltable = new xmldb_table('tool_admin_presets_it_a'); 1667 $table = new xmldb_table('adminpresets_it_a'); 1668 if ($dbman->table_exists($tooltable)) { 1669 $dbman->rename_table($tooltable, 'adminpresets_it_a'); 1670 } else if (!$dbman->table_exists($table)) { 1671 // Adding fields to table adminpresets_it_a. 1672 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1673 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1674 $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 1675 $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null); 1676 1677 // Adding keys to table adminpresets_it_a. 1678 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1679 1680 // Adding indexes to table adminpresets_it_a. 1681 $table->add_index('itemid', XMLDB_INDEX_NOTUNIQUE, ['itemid']); 1682 1683 // Launch create table for adminpresets_it_a. 1684 $dbman->create_table($table); 1685 } 1686 1687 $tooltable = new xmldb_table('tool_admin_presets_app'); 1688 $table = new xmldb_table('adminpresets_app'); 1689 if ($dbman->table_exists($tooltable)) { 1690 $dbman->rename_table($tooltable, 'adminpresets_app'); 1691 } else if (!$dbman->table_exists($table)) { 1692 // Adding fields to table adminpresets_app. 1693 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1694 $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1695 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1696 $table->add_field('time', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1697 1698 // Adding keys to table adminpresets_app. 1699 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1700 1701 // Adding indexes to table adminpresets_app. 1702 $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']); 1703 1704 // Launch create table for adminpresets_app. 1705 $dbman->create_table($table); 1706 } 1707 1708 $tooltable = new xmldb_table('tool_admin_presets_app_it'); 1709 $table = new xmldb_table('adminpresets_app_it'); 1710 if ($dbman->table_exists($tooltable)) { 1711 $dbman->rename_table($tooltable, 'adminpresets_app_it'); 1712 } else if (!$dbman->table_exists($table)) { 1713 // Adding fields to table adminpresets_app_it. 1714 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1715 $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1716 $table->add_field('configlogid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1717 1718 // Adding keys to table adminpresets_app_it. 1719 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1720 1721 // Adding indexes to table adminpresets_app_it. 1722 $table->add_index('configlogid', XMLDB_INDEX_NOTUNIQUE, ['configlogid']); 1723 $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']); 1724 1725 // Launch create table for adminpresets_app_it. 1726 $dbman->create_table($table); 1727 } 1728 1729 $tooltable = new xmldb_table('tool_admin_presets_app_it_a'); 1730 $table = new xmldb_table('adminpresets_app_it_a'); 1731 if ($dbman->table_exists($tooltable)) { 1732 $dbman->rename_table($tooltable, 'adminpresets_app_it_a'); 1733 } else if (!$dbman->table_exists($table)) { 1734 // Adding fields to table adminpresets_app_it_a. 1735 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1736 $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1737 $table->add_field('configlogid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1738 $table->add_field('itemname', XMLDB_TYPE_CHAR, '100', null, null, null, null); 1739 1740 // Adding keys to table adminpresets_app_it_a. 1741 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1742 1743 // Adding indexes to table adminpresets_app_it_a. 1744 $table->add_index('configlogid', XMLDB_INDEX_NOTUNIQUE, ['configlogid']); 1745 $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']); 1746 1747 // Launch create table for adminpresets_app_it_a. 1748 $dbman->create_table($table); 1749 } 1750 1751 $tooltable = new xmldb_table('tool_admin_presets_plug'); 1752 $table = new xmldb_table('adminpresets_plug'); 1753 if ($dbman->table_exists($tooltable)) { 1754 $dbman->rename_table($tooltable, 'adminpresets_plug'); 1755 } else if (!$dbman->table_exists($table)) { 1756 // Adding fields to table adminpresets_plug. 1757 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1758 $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1759 $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null); 1760 $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 1761 $table->add_field('enabled', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0'); 1762 1763 // Adding keys to table adminpresets_plug. 1764 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1765 1766 // Adding indexes to table adminpresets_plug. 1767 $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']); 1768 1769 // Launch create table for adminpresets_plug. 1770 $dbman->create_table($table); 1771 } 1772 1773 $tooltable = new xmldb_table('tool_admin_presets_app_plug'); 1774 $table = new xmldb_table('adminpresets_app_plug'); 1775 if ($dbman->table_exists($tooltable)) { 1776 $dbman->rename_table($tooltable, 'adminpresets_app_plug'); 1777 } else if (!$dbman->table_exists($table)) { 1778 // Adding fields to table adminpresets_app_plug. 1779 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 1780 $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 1781 $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null); 1782 $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null); 1783 $table->add_field('value', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0'); 1784 $table->add_field('oldvalue', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0'); 1785 1786 // Adding keys to table adminpresets_app_plug. 1787 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 1788 1789 // Adding indexes to table adminpresets_app_plug. 1790 $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']); 1791 1792 // Launch create table for adminpresets_app_plug. 1793 if (!$dbman->table_exists($table)) { 1794 $dbman->create_table($table); 1795 } 1796 } 1797 1798 if ($DB->count_records('adminpresets', ['iscore' => 1]) == 0) { 1799 // Create default core site admin presets. 1800 require_once($CFG->dirroot . '/admin/presets/classes/helper.php'); 1801 \core_adminpresets\helper::create_default_presets(); 1802 } 1803 1804 // Main savepoint reached. 1805 upgrade_main_savepoint(true, 2021123000.01); 1806 } 1807 1808 if ($oldversion < 2021123000.02) { 1809 // If exists, migrate sensiblesettings admin settings from tool_admin_preset to adminpresets. 1810 if (get_config('tool_admin_presets', 'sensiblesettings') !== false) { 1811 set_config('sensiblesettings', get_config('tool_admin_presets', 'sensiblesettings'), 'adminpresets'); 1812 unset_config('sensiblesettings', 'tool_admin_presets'); 1813 } 1814 1815 // Main savepoint reached. 1816 upgrade_main_savepoint(true, 2021123000.02); 1817 } 1818 1819 if ($oldversion < 2021123000.03) { 1820 // If exists, migrate lastpresetapplied setting from tool_admin_preset to adminpresets. 1821 if (get_config('tool_admin_presets', 'lastpresetapplied') !== false) { 1822 set_config('lastpresetapplied', get_config('tool_admin_presets', 'lastpresetapplied'), 'adminpresets'); 1823 unset_config('lastpresetapplied', 'tool_admin_presets'); 1824 } 1825 1826 // Main savepoint reached. 1827 upgrade_main_savepoint(true, 2021123000.03); 1828 } 1829 1830 if ($oldversion < 2022011100.01) { 1831 // The following blocks have been hidden by default, so they shouldn't be enabled in the Full core preset: Course/site 1832 // summary, RSS feeds, Self completion and Feedback. 1833 $params = ['name' => get_string('fullpreset', 'core_adminpresets')]; 1834 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 1835 1836 if (!$fullpreset) { 1837 // Full admin preset might have been created using the English name. 1838 $name = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en'); 1839 $params['name'] = $name; 1840 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 1841 } 1842 if (!$fullpreset) { 1843 // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1. 1844 $sql = "SELECT preset.* 1845 FROM {adminpresets} preset 1846 INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid 1847 WHERE it.name = :name AND it.value = :value AND preset.iscore > 0"; 1848 $params = ['name' => 'usecomments', 'value' => '1']; 1849 $fullpreset = $DB->get_record_sql($sql, $params); 1850 } 1851 1852 if ($fullpreset) { 1853 $blocknames = ['course_summary', 'feedback', 'rss_client', 'selfcompletion']; 1854 list($blocksinsql, $blocksinparams) = $DB->get_in_or_equal($blocknames); 1855 1856 // Remove entries from the adminpresets_app_plug table (in case the preset has been applied). 1857 $appliedpresets = $DB->get_records('adminpresets_app', ['adminpresetid' => $fullpreset->id], '', 'id'); 1858 if ($appliedpresets) { 1859 list($appsinsql, $appsinparams) = $DB->get_in_or_equal(array_keys($appliedpresets)); 1860 $sql = "adminpresetapplyid $appsinsql AND plugin='block' AND name $blocksinsql"; 1861 $params = array_merge($appsinparams, $blocksinparams); 1862 $DB->delete_records_select('adminpresets_app_plug', $sql, $params); 1863 } 1864 1865 // Remove entries for these blocks from the adminpresets_plug table. 1866 $sql = "adminpresetid = ? AND plugin='block' AND name $blocksinsql"; 1867 $params = array_merge([$fullpreset->id], $blocksinparams); 1868 $DB->delete_records_select('adminpresets_plug', $sql, $params); 1869 } 1870 1871 // Main savepoint reached. 1872 upgrade_main_savepoint(true, 2022011100.01); 1873 } 1874 1875 if ($oldversion < 2022012100.02) { 1876 // Migrate default message output config. 1877 $preferences = get_config('message'); 1878 1879 $treatedprefs = []; 1880 1881 foreach ($preferences as $preference => $value) { 1882 // Extract provider and preference name from the setting name. 1883 // Example name: airnotifier_provider_enrol_imsenterprise_imsenterprise_enrolment_permitted 1884 // Provider: airnotifier 1885 // Preference: enrol_imsenterprise_imsenterprise_enrolment_permitted. 1886 $providerparts = explode('_provider_', $preference); 1887 if (count($providerparts) <= 1) { 1888 continue; 1889 } 1890 1891 $provider = $providerparts[0]; 1892 $preference = $providerparts[1]; 1893 1894 // Extract and remove last part of the preference previously extracted: ie. permitted. 1895 $parts = explode('_', $preference); 1896 $key = array_pop($parts); 1897 1898 if (in_array($key, ['permitted', 'loggedin', 'loggedoff'])) { 1899 if ($key == 'permitted') { 1900 // We will use provider name instead of permitted. 1901 $key = $provider; 1902 } else { 1903 // Logged in and logged off values are a csv of the enabled providers. 1904 $value = explode(',', $value); 1905 } 1906 1907 // Join the rest of the parts: ie enrol_imsenterprise_imsenterprise_enrolment. 1908 $prefname = implode('_', $parts); 1909 1910 if (!isset($treatedprefs[$prefname])) { 1911 $treatedprefs[$prefname] = []; 1912 } 1913 1914 // Save the value with the selected key. 1915 $treatedprefs[$prefname][$key] = $value; 1916 } 1917 } 1918 1919 // Now take every preference previous treated and its values. 1920 foreach ($treatedprefs as $prefname => $values) { 1921 $enabled = []; // List of providers enabled for each preference. 1922 1923 // Enable if one of those is enabled. 1924 $loggedin = isset($values['loggedin']) ? $values['loggedin'] : []; 1925 foreach ($loggedin as $provider) { 1926 $enabled[$provider] = 1; 1927 } 1928 $loggedoff = isset($values['loggedoff']) ? $values['loggedoff'] : []; 1929 foreach ($loggedoff as $provider) { 1930 $enabled[$provider] = 1; 1931 } 1932 1933 // Do not treat those values again. 1934 unset($values['loggedin']); 1935 unset($values['loggedoff']); 1936 1937 // Translate rest of values coming from permitted "key". 1938 foreach ($values as $provider => $value) { 1939 $locked = false; 1940 1941 switch ($value) { 1942 case 'forced': 1943 // Provider is enabled by force. 1944 $enabled[$provider] = 1; 1945 $locked = true; 1946 break; 1947 case 'disallowed': 1948 // Provider is disabled by force. 1949 unset($enabled[$provider]); 1950 $locked = true; 1951 break; 1952 default: 1953 // Provider is not forced (permitted) or invalid values. 1954 } 1955 1956 // Save locked. 1957 if ($locked) { 1958 set_config($provider.'_provider_'.$prefname.'_locked', 1, 'message'); 1959 } else { 1960 set_config($provider.'_provider_'.$prefname.'_locked', 0, 'message'); 1961 } 1962 // Remove old value. 1963 unset_config($provider.'_provider_'.$prefname.'_permitted', 'message'); 1964 } 1965 1966 // Save the new values. 1967 $value = implode(',', array_keys($enabled)); 1968 set_config('message_provider_'.$prefname.'_enabled', $value, 'message'); 1969 // Remove old values. 1970 unset_config('message_provider_'.$prefname.'_loggedin', 'message'); 1971 unset_config('message_provider_'.$prefname.'_loggedoff', 'message'); 1972 } 1973 1974 // Migrate user preferences. ie merging message_provider_moodle_instantmessage_loggedoff with 1975 // message_provider_moodle_instantmessage_loggedin to message_provider_moodle_instantmessage_enabled. 1976 1977 $allrecordsloggedoff = $DB->sql_like('name', ':loggedoff'); 1978 $total = $DB->count_records_select( 1979 'user_preferences', 1980 $allrecordsloggedoff, 1981 ['loggedoff' => 'message_provider_%_loggedoff'] 1982 ); 1983 $i = 0; 1984 if ($total == 0) { 1985 $total = 1; // Avoid division by zero. 1986 } 1987 1988 // Show a progress bar. 1989 $pbar = new progress_bar('upgradeusernotificationpreferences', 500, true); 1990 $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total."); 1991 1992 // We're migrating provider per provider to reduce memory usage. 1993 $providers = $DB->get_records('message_providers', null, 'name'); 1994 foreach ($providers as $provider) { 1995 // 60 minutes to migrate each provider. 1996 upgrade_set_timeout(3600); 1997 $componentproviderbase = 'message_provider_'.$provider->component.'_'.$provider->name; 1998 1999 $loggedinname = $componentproviderbase.'_loggedin'; 2000 $loggedoffname = $componentproviderbase.'_loggedoff'; 2001 2002 // Change loggedin to enabled. 2003 $enabledname = $componentproviderbase.'_enabled'; 2004 $DB->set_field('user_preferences', 'name', $enabledname, ['name' => $loggedinname]); 2005 2006 $selectparams = [ 2007 'enabled' => $enabledname, 2008 'loggedoff' => $loggedoffname, 2009 ]; 2010 $sql = 'SELECT m1.id loggedoffid, m1.value as loggedoff, m2.value as enabled, m2.id as enabledid 2011 FROM 2012 (SELECT id, userid, value FROM {user_preferences} WHERE name = :loggedoff) m1 2013 LEFT JOIN 2014 (SELECT id, userid, value FROM {user_preferences} WHERE name = :enabled) m2 2015 ON m1.userid = m2.userid'; 2016 2017 while (($rs = $DB->get_recordset_sql($sql, $selectparams, 0, 1000)) && $rs->valid()) { 2018 // 10 minutes for every chunk. 2019 upgrade_set_timeout(600); 2020 2021 $deleterecords = []; 2022 $changename = []; 2023 $changevalue = []; // Multidimensional array with possible values as key to reduce SQL queries. 2024 foreach ($rs as $record) { 2025 if (empty($record->enabledid)) { 2026 // Enabled does not exists, change the name. 2027 $changename[] = $record->loggedoffid; 2028 } else if ($record->enabledid != $record->loggedoff) { 2029 // Exist and values differ (checked on SQL), update the enabled record. 2030 2031 if ($record->enabled != 'none' && !empty($record->enabled)) { 2032 $enabledvalues = explode(',', $record->enabled); 2033 } else { 2034 $enabledvalues = []; 2035 } 2036 2037 if ($record->loggedoff != 'none' && !empty($record->loggedoff)) { 2038 $loggedoffvalues = explode(',', $record->loggedoff); 2039 } else { 2040 $loggedoffvalues = []; 2041 } 2042 2043 $values = array_unique(array_merge($enabledvalues, $loggedoffvalues)); 2044 sort($values); 2045 2046 $newvalue = empty($values) ? 'none' : implode(',', $values); 2047 if (!isset($changevalue[$newvalue])) { 2048 $changevalue[$newvalue] = []; 2049 } 2050 $changevalue[$newvalue][] = $record->enabledid; 2051 2052 $deleterecords[] = $record->loggedoffid; 2053 } else { 2054 // They are the same, just delete loggedoff one. 2055 $deleterecords[] = $record->loggedoffid; 2056 } 2057 $i++; 2058 } 2059 $rs->close(); 2060 2061 // Commit the changes. 2062 if (!empty($changename)) { 2063 $changenameparams = [ 2064 'name' => $loggedoffname, 2065 ]; 2066 $changenameselect = 'name = :name AND id IN (' . implode(',', $changename) . ')'; 2067 $DB->set_field_select('user_preferences', 'name', $enabledname, $changenameselect, $changenameparams); 2068 } 2069 2070 if (!empty($changevalue)) { 2071 $changevalueparams = [ 2072 'name' => $enabledname, 2073 ]; 2074 foreach ($changevalue as $value => $ids) { 2075 $changevalueselect = 'name = :name AND id IN (' . implode(',', $ids) . ')'; 2076 $DB->set_field_select('user_preferences', 'value', $value, $changevalueselect, $changevalueparams); 2077 } 2078 } 2079 2080 if (!empty($deleterecords)) { 2081 $deleteparams = [ 2082 'name' => $loggedoffname, 2083 ]; 2084 $deleteselect = 'name = :name AND id IN (' . implode(',', $deleterecords) . ')'; 2085 $DB->delete_records_select('user_preferences', $deleteselect, $deleteparams); 2086 } 2087 2088 // Update progress. 2089 $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total."); 2090 } 2091 $rs->close(); 2092 2093 // Delete the rest of loggedoff values (that are equal than enabled). 2094 $deleteparams = [ 2095 'name' => $loggedoffname, 2096 ]; 2097 $deleteselect = 'name = :name'; 2098 $i += $DB->count_records_select('user_preferences', $deleteselect, $deleteparams); 2099 $DB->delete_records_select('user_preferences', $deleteselect, $deleteparams); 2100 2101 // Update progress. 2102 $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total."); 2103 } 2104 2105 core_plugin_manager::reset_caches(); 2106 2107 // Delete the orphan records. 2108 $allrecordsparams = ['loggedin' => 'message_provider_%_loggedin', 'loggedoff' => 'message_provider_%_loggedoff']; 2109 $allrecordsloggedin = $DB->sql_like('name', ':loggedin'); 2110 $allrecordsloggedinoffsql = "$allrecordsloggedin OR $allrecordsloggedoff"; 2111 $DB->delete_records_select('user_preferences', $allrecordsloggedinoffsql, $allrecordsparams); 2112 2113 // Update progress. 2114 $pbar->update($total, $total, "Upgrading user notifications preferences - $total/$total."); 2115 2116 upgrade_main_savepoint(true, 2022012100.02); 2117 } 2118 2119 // Introduce question versioning to core. 2120 // First, create the new tables. 2121 if ($oldversion < 2022020200.01) { 2122 // Define table question_bank_entries to be created. 2123 $table = new xmldb_table('question_bank_entries'); 2124 2125 // Adding fields to table question_bank_entries. 2126 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 2127 $table->add_field('questioncategoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2128 $table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null); 2129 $table->add_field('ownerid', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 2130 2131 // Adding keys to table question_bank_entries. 2132 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 2133 $table->add_key('questioncategoryid', XMLDB_KEY_FOREIGN, ['questioncategoryid'], 'question_categories', ['id']); 2134 $table->add_key('ownerid', XMLDB_KEY_FOREIGN, ['ownerid'], 'user', ['id']); 2135 2136 // Conditionally launch create table for question_bank_entries. 2137 if (!$dbman->table_exists($table)) { 2138 $dbman->create_table($table); 2139 } 2140 2141 // Create category id and id number index. 2142 $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, ['questioncategoryid', 'idnumber']); 2143 2144 // Conditionally launch add index categoryidnumber. 2145 if (!$dbman->index_exists($table, $index)) { 2146 $dbman->add_index($table, $index); 2147 } 2148 2149 // Define table question_versions to be created. 2150 $table = new xmldb_table('question_versions'); 2151 2152 // Adding fields to table question_versions. 2153 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 2154 $table->add_field('questionbankentryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2155 $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 1); 2156 $table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2157 $table->add_field('status', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, 'ready'); 2158 2159 // Adding keys to table question_versions. 2160 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 2161 $table->add_key('questionbankentryid', XMLDB_KEY_FOREIGN, ['questionbankentryid'], 'question_bank_entries', ['id']); 2162 $table->add_key('questionid', XMLDB_KEY_FOREIGN, ['questionid'], 'question', ['id']); 2163 2164 // Conditionally launch create table for question_versions. 2165 if (!$dbman->table_exists($table)) { 2166 $dbman->create_table($table); 2167 } 2168 2169 // Define table question_references to be created. 2170 $table = new xmldb_table('question_references'); 2171 2172 // Adding fields to table question_references. 2173 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 2174 $table->add_field('usingcontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2175 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null); 2176 $table->add_field('questionarea', XMLDB_TYPE_CHAR, '50', null, null, null, null); 2177 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 2178 $table->add_field('questionbankentryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2179 $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 2180 2181 // Adding keys to table question_references. 2182 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 2183 $table->add_key('usingcontextid', XMLDB_KEY_FOREIGN, ['usingcontextid'], 'context', ['id']); 2184 $table->add_key('questionbankentryid', XMLDB_KEY_FOREIGN, ['questionbankentryid'], 'question_bank_entries', ['id']); 2185 2186 // Conditionally launch create table for question_references. 2187 if (!$dbman->table_exists($table)) { 2188 $dbman->create_table($table); 2189 } 2190 2191 // Define table question_set_references to be created. 2192 $table = new xmldb_table('question_set_references'); 2193 2194 // Adding fields to table question_set_references. 2195 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 2196 $table->add_field('usingcontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2197 $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null); 2198 $table->add_field('questionarea', XMLDB_TYPE_CHAR, '50', null, null, null, null); 2199 $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 2200 $table->add_field('questionscontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0); 2201 $table->add_field('filtercondition', XMLDB_TYPE_TEXT, null, null, null, null, null); 2202 2203 // Adding keys to table question_set_references. 2204 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 2205 $table->add_key('usingcontextid', XMLDB_KEY_FOREIGN, ['usingcontextid'], 'context', ['id']); 2206 $table->add_key('questionscontextid', XMLDB_KEY_FOREIGN, ['questionscontextid'], 'context', ['id']); 2207 2208 // Conditionally launch create table for question_set_references. 2209 if (!$dbman->table_exists($table)) { 2210 $dbman->create_table($table); 2211 } 2212 2213 // Main savepoint reached. 2214 upgrade_main_savepoint(true, 2022020200.01); 2215 } 2216 2217 if ($oldversion < 2022020200.02) { 2218 // Define a new temporary field in the question_bank_entries tables. 2219 // Creating temporary field questionid to populate the data in question version table. 2220 // This will make sure the appropriate question id is inserted the version table without making any complex joins. 2221 $table = new xmldb_table('question_bank_entries'); 2222 $field = new xmldb_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL); 2223 if (!$dbman->field_exists($table, $field)) { 2224 $dbman->add_field($table, $field); 2225 } 2226 2227 $transaction = $DB->start_delegated_transaction(); 2228 upgrade_set_timeout(3600); 2229 // Create the data for the question_bank_entries table with, including the new temporary field. 2230 $sql = <<<EOF 2231 INSERT INTO {question_bank_entries} 2232 (questionid, questioncategoryid, idnumber, ownerid) 2233 SELECT id, category, idnumber, createdby 2234 FROM {question} q 2235 EOF; 2236 2237 // Inserting question_bank_entries data. 2238 $DB->execute($sql); 2239 2240 $transaction->allow_commit(); 2241 2242 // Main savepoint reached. 2243 upgrade_main_savepoint(true, 2022020200.02); 2244 } 2245 2246 if ($oldversion < 2022020200.03) { 2247 $transaction = $DB->start_delegated_transaction(); 2248 upgrade_set_timeout(3600); 2249 // Create the question_versions using that temporary field. 2250 $sql = <<<EOF 2251 INSERT INTO {question_versions} 2252 (questionbankentryid, questionid, status) 2253 SELECT 2254 qbe.id, 2255 q.id, 2256 CASE 2257 WHEN q.hidden > 0 THEN 'hidden' 2258 ELSE 'ready' 2259 END 2260 FROM {question_bank_entries} qbe 2261 INNER JOIN {question} q ON qbe.questionid = q.id 2262 EOF; 2263 2264 // Inserting question_versions data. 2265 $DB->execute($sql); 2266 2267 $transaction->allow_commit(); 2268 2269 // Dropping temporary field questionid. 2270 $table = new xmldb_table('question_bank_entries'); 2271 $field = new xmldb_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL); 2272 if ($dbman->field_exists($table, $field)) { 2273 $dbman->drop_field($table, $field); 2274 } 2275 2276 // Main savepoint reached. 2277 upgrade_main_savepoint(true, 2022020200.03); 2278 } 2279 2280 if ($oldversion < 2022020200.04) { 2281 $transaction = $DB->start_delegated_transaction(); 2282 upgrade_set_timeout(3600); 2283 // Create the base data for the random questions in the set_references table. 2284 // This covers most of the hard work in one go. 2285 $concat = $DB->sql_concat("'{\"questioncategoryid\":\"'", 'q.category', "'\",\"includingsubcategories\":\"'", 2286 'qs.includingsubcategories', "'\"}'"); 2287 $sql = <<<EOF 2288 INSERT INTO {question_set_references} 2289 (usingcontextid, component, questionarea, itemid, questionscontextid, filtercondition) 2290 SELECT 2291 c.id, 2292 'mod_quiz', 2293 'slot', 2294 qs.id, 2295 qc.contextid, 2296 $concat 2297 FROM {question} q 2298 INNER JOIN {quiz_slots} qs on q.id = qs.questionid 2299 INNER JOIN {course_modules} cm ON cm.instance = qs.quizid AND cm.module = :quizmoduleid 2300 INNER JOIN {context} c ON cm.id = c.instanceid AND c.contextlevel = :contextmodule 2301 INNER JOIN {question_categories} qc ON qc.id = q.category 2302 WHERE q.qtype = :random 2303 EOF; 2304 2305 // Inserting question_set_references data. 2306 $DB->execute($sql, [ 2307 'quizmoduleid' => $DB->get_field('modules', 'id', ['name' => 'quiz']), 2308 'contextmodule' => CONTEXT_MODULE, 2309 'random' => 'random', 2310 ]); 2311 2312 $transaction->allow_commit(); 2313 2314 // Main savepoint reached. 2315 upgrade_main_savepoint(true, 2022020200.04); 2316 } 2317 2318 if ($oldversion < 2022020200.05) { 2319 $transaction = $DB->start_delegated_transaction(); 2320 upgrade_set_timeout(3600); 2321 2322 // Count all the slot tags to be migrated (for progress bar). 2323 $total = $DB->count_records('quiz_slot_tags'); 2324 $pbar = new progress_bar('migratequestiontags', 1000, true); 2325 $i = 0; 2326 // Updating slot_tags for random question tags. 2327 // Now fetch any quiz slot tags and update those slot details into the question_set_references. 2328 $slottags = $DB->get_recordset('quiz_slot_tags', [], 'slotid ASC'); 2329 2330 $tagstrings = []; 2331 $lastslot = null; 2332 $runinsert = function (int $lastslot, array $tagstrings) use ($DB) { 2333 $conditiondata = $DB->get_field('question_set_references', 'filtercondition', 2334 ['itemid' => $lastslot, 'component' => 'mod_quiz', 'questionarea' => 'slot']); 2335 2336 // It is possible to have leftover tags in the database, without a corresponding 2337 // slot, because of an old bugs (e.g. MDL-76193). Therefore, if the slot is not found, 2338 // we can safely discard these tags. 2339 if (!empty($conditiondata)) { 2340 $condition = json_decode($conditiondata); 2341 $condition->tags = $tagstrings; 2342 $DB->set_field('question_set_references', 'filtercondition', json_encode($condition), 2343 ['itemid' => $lastslot, 'component' => 'mod_quiz', 'questionarea' => 'slot']); 2344 } 2345 }; 2346 2347 foreach ($slottags as $tag) { 2348 upgrade_set_timeout(3600); 2349 if ($lastslot && $tag->slotid != $lastslot) { 2350 if (!empty($tagstrings)) { 2351 // Insert the data. 2352 $runinsert($lastslot, $tagstrings); 2353 } 2354 // Prepare for the next slot id. 2355 $tagstrings = []; 2356 } 2357 2358 $lastslot = $tag->slotid; 2359 $tagstrings[] = "{$tag->tagid},{$tag->tagname}"; 2360 // Update progress. 2361 $i++; 2362 $pbar->update($i, $total, "Migrating question tags - $i/$total."); 2363 } 2364 if ($tagstrings) { 2365 $runinsert($lastslot, $tagstrings); 2366 } 2367 $slottags->close(); 2368 2369 $transaction->allow_commit(); 2370 // Main savepoint reached. 2371 upgrade_main_savepoint(true, 2022020200.05); 2372 } 2373 2374 if ($oldversion < 2022020200.06) { 2375 $transaction = $DB->start_delegated_transaction(); 2376 upgrade_set_timeout(3600); 2377 // Create question_references record for each question. 2378 // Except if qtype is random. That case is handled by question_set_reference. 2379 $sql = "INSERT INTO {question_references} 2380 (usingcontextid, component, questionarea, itemid, questionbankentryid) 2381 SELECT c.id, 'mod_quiz', 'slot', qs.id, qv.questionbankentryid 2382 FROM {question} q 2383 JOIN {question_versions} qv ON q.id = qv.questionid 2384 JOIN {quiz_slots} qs ON q.id = qs.questionid 2385 JOIN {modules} m ON m.name = 'quiz' 2386 JOIN {course_modules} cm ON cm.module = m.id AND cm.instance = qs.quizid 2387 JOIN {context} c ON c.instanceid = cm.id AND c.contextlevel = " . CONTEXT_MODULE . " 2388 WHERE q.qtype <> 'random'"; 2389 2390 // Inserting question_references data. 2391 $DB->execute($sql); 2392 2393 $transaction->allow_commit(); 2394 // Main savepoint reached. 2395 upgrade_main_savepoint(true, 2022020200.06); 2396 } 2397 2398 // Finally, drop fields from question table. 2399 if ($oldversion < 2022020200.07) { 2400 // Define fields to be dropped from questions. 2401 $table = new xmldb_table('question'); 2402 2403 $field = new xmldb_field('version'); 2404 // Conditionally launch drop field version. 2405 if ($dbman->field_exists($table, $field)) { 2406 $dbman->drop_field($table, $field); 2407 } 2408 2409 $field = new xmldb_field('hidden'); 2410 // Conditionally launch drop field hidden. 2411 if ($dbman->field_exists($table, $field)) { 2412 $dbman->drop_field($table, $field); 2413 } 2414 2415 // Define index categoryidnumber (not unique) to be dropped form question. 2416 $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, ['category', 'idnumber']); 2417 2418 // Conditionally launch drop index categoryidnumber. 2419 if ($dbman->index_exists($table, $index)) { 2420 $dbman->drop_index($table, $index); 2421 } 2422 2423 // Define key category (foreign) to be dropped form questions. 2424 $key = new xmldb_key('category', XMLDB_KEY_FOREIGN, ['category'], 'question_categories', ['id']); 2425 2426 // Launch drop key category. 2427 $dbman->drop_key($table, $key); 2428 2429 $field = new xmldb_field('idnumber'); 2430 // Conditionally launch drop field idnumber. 2431 if ($dbman->field_exists($table, $field)) { 2432 $dbman->drop_field($table, $field); 2433 } 2434 2435 $field = new xmldb_field('category'); 2436 // Conditionally launch drop field category. 2437 if ($dbman->field_exists($table, $field)) { 2438 $dbman->drop_field($table, $field); 2439 } 2440 2441 // Main savepoint reached. 2442 upgrade_main_savepoint(true, 2022020200.07); 2443 } 2444 2445 if ($oldversion < 2022021100.01) { 2446 $sql = "SELECT preset.* 2447 FROM {adminpresets} preset 2448 INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid 2449 WHERE it.name = :name AND it.value = :value AND preset.iscore > 0"; 2450 // Some settings and plugins have been added/removed to the Starter and Full preset. Add them to the core presets if 2451 // they haven't been included yet. 2452 $params = ['name' => get_string('starterpreset', 'core_adminpresets'), 'iscore' => 1]; 2453 $starterpreset = $DB->get_record('adminpresets', $params); 2454 if (!$starterpreset) { 2455 // Starter admin preset might have been created using the English name. 2456 $name = get_string_manager()->get_string('starterpreset', 'core_adminpresets', null, 'en'); 2457 $params['name'] = $name; 2458 $starterpreset = $DB->get_record('adminpresets', $params); 2459 } 2460 if (!$starterpreset) { 2461 // We tried, but we didn't find starter by name. Let's find a core preset that sets 'usecomments' setting to 0. 2462 $params = ['name' => 'usecomments', 'value' => '0']; 2463 $starterpreset = $DB->get_record_sql($sql, $params); 2464 } 2465 2466 $params = ['name' => get_string('fullpreset', 'core_adminpresets')]; 2467 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 2468 if (!$fullpreset) { 2469 // Full admin preset might have been created using the English name. 2470 $name = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en'); 2471 $params['name'] = $name; 2472 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 2473 } 2474 if (!$fullpreset) { 2475 // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1. 2476 $params = ['name' => 'usecomments', 'value' => '1']; 2477 $fullpreset = $DB->get_record_sql($sql, $params); 2478 } 2479 2480 $settings = [ 2481 // Settings. Hide Guest login button for Starter preset (and back to show for Full). 2482 [ 2483 'presetid' => $starterpreset->id, 2484 'plugin' => 'none', 2485 'name' => 'guestloginbutton', 2486 'value' => '0', 2487 ], 2488 [ 2489 'presetid' => $fullpreset->id, 2490 'plugin' => 'none', 2491 'name' => 'guestloginbutton', 2492 'value' => '1', 2493 ], 2494 // Settings. Set Activity chooser tabs to "Starred, All, Recommended"(1) for Starter and back it to default(0) for Full. 2495 [ 2496 'presetid' => $starterpreset->id, 2497 'plugin' => 'none', 2498 'name' => 'activitychoosertabmode', 2499 'value' => '1', 2500 ], 2501 [ 2502 'presetid' => $fullpreset->id, 2503 'plugin' => 'none', 2504 'name' => 'activitychoosertabmode', 2505 'value' => '0', 2506 ], 2507 ]; 2508 foreach ($settings as $notused => $setting) { 2509 $params = ['adminpresetid' => $setting['presetid'], 'plugin' => $setting['plugin'], 'name' => $setting['name']]; 2510 if (!$DB->record_exists('adminpresets_it', $params)) { 2511 $record = new \stdClass(); 2512 $record->adminpresetid = $setting['presetid']; 2513 $record->plugin = $setting['plugin']; 2514 $record->name = $setting['name']; 2515 $record->value = $setting['value']; 2516 $DB->insert_record('adminpresets_it', $record); 2517 } 2518 } 2519 2520 $plugins = [ 2521 // Plugins. Blocks. Disable/enable Online users, Recently accessed courses and Starred courses. 2522 [ 2523 'presetid' => $starterpreset->id, 2524 'plugin' => 'block', 2525 'name' => 'online_users', 2526 'enabled' => '0', 2527 ], 2528 [ 2529 'presetid' => $fullpreset->id, 2530 'plugin' => 'block', 2531 'name' => 'online_users', 2532 'enabled' => '1', 2533 ], 2534 [ 2535 'presetid' => $starterpreset->id, 2536 'plugin' => 'block', 2537 'name' => 'recentlyaccessedcourses', 2538 'enabled' => '0', 2539 ], 2540 [ 2541 'presetid' => $fullpreset->id, 2542 'plugin' => 'block', 2543 'name' => 'recentlyaccessedcourses', 2544 'enabled' => '1', 2545 ], 2546 [ 2547 'presetid' => $starterpreset->id, 2548 'plugin' => 'block', 2549 'name' => 'starredcourses', 2550 'enabled' => '0', 2551 ], 2552 [ 2553 'presetid' => $fullpreset->id, 2554 'plugin' => 'block', 2555 'name' => 'starredcourses', 2556 'enabled' => '1', 2557 ], 2558 // Plugins. Enrolments. Disable/enable Guest access. 2559 [ 2560 'presetid' => $starterpreset->id, 2561 'plugin' => 'enrol', 2562 'name' => 'guest', 2563 'enabled' => '0', 2564 ], 2565 [ 2566 'presetid' => $fullpreset->id, 2567 'plugin' => 'enrol', 2568 'name' => 'guest', 2569 'enabled' => '1', 2570 ], 2571 ]; 2572 foreach ($plugins as $notused => $plugin) { 2573 $params = ['adminpresetid' => $plugin['presetid'], 'plugin' => $plugin['plugin'], 'name' => $plugin['name']]; 2574 if (!$DB->record_exists('adminpresets_plug', $params)) { 2575 $record = new \stdClass(); 2576 $record->adminpresetid = $plugin['presetid']; 2577 $record->plugin = $plugin['plugin']; 2578 $record->name = $plugin['name']; 2579 $record->enabled = $plugin['enabled']; 2580 $DB->insert_record('adminpresets_plug', $record); 2581 } 2582 } 2583 2584 // Settings: Remove customusermenuitems setting from Starter and Full presets. 2585 $sql = "(adminpresetid = ? OR adminpresetid = ?) AND plugin = 'none' AND name = 'customusermenuitems'"; 2586 $params = [$starterpreset->id, $fullpreset->id]; 2587 $DB->delete_records_select('adminpresets_it', $sql, $params); 2588 2589 // Plugins. Question types. Re-enable Description and Essay for Starter. 2590 $sql = "(adminpresetid = ? OR adminpresetid = ?) AND plugin = 'qtype' AND (name = 'description' OR name = 'essay')"; 2591 $DB->delete_records_select('adminpresets_plug', $sql, $params); 2592 2593 // Main savepoint reached. 2594 upgrade_main_savepoint(true, 2022021100.01); 2595 2596 } 2597 2598 if ($oldversion < 2022021100.02) { 2599 $table = new xmldb_table('task_scheduled'); 2600 2601 // Changing precision of field minute on table task_scheduled to (200). 2602 $field = new xmldb_field('minute', XMLDB_TYPE_CHAR, '200', null, XMLDB_NOTNULL, null, null, 'blocking'); 2603 $dbman->change_field_precision($table, $field); 2604 // Changing precision of field hour on table task_scheduled to (70). 2605 $field = new xmldb_field('hour', XMLDB_TYPE_CHAR, '70', null, XMLDB_NOTNULL, null, null, 'minute'); 2606 $dbman->change_field_precision($table, $field); 2607 // Changing precision of field day on table task_scheduled to (90). 2608 $field = new xmldb_field('day', XMLDB_TYPE_CHAR, '90', null, XMLDB_NOTNULL, null, null, 'hour'); 2609 $dbman->change_field_precision($table, $field); 2610 // Changing precision of field month on table task_scheduled to (30). 2611 $field = new xmldb_field('month', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, 'day'); 2612 $dbman->change_field_precision($table, $field); 2613 2614 // Main savepoint reached. 2615 upgrade_main_savepoint(true, 2022021100.02); 2616 } 2617 2618 if ($oldversion < 2022022600.01) { 2619 // Get all processor and existing preferences. 2620 $processors = $DB->get_records('message_processors'); 2621 $providers = $DB->get_records('message_providers', null, '', 'id, name, component'); 2622 $existingpreferences = get_config('message'); 2623 2624 foreach ($processors as $processor) { 2625 foreach ($providers as $provider) { 2626 // Setting default preference name. 2627 $componentproviderbase = $provider->component . '_' . $provider->name; 2628 $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_locked'; 2629 // If we do not have this setting yet, set it to 0. 2630 if (!isset($existingpreferences->{$preferencename})) { 2631 set_config($preferencename, 0, 'message'); 2632 } 2633 } 2634 } 2635 2636 upgrade_main_savepoint(true, 2022022600.01); 2637 } 2638 2639 if ($oldversion < 2022030100.00) { 2640 $sql = "SELECT preset.* 2641 FROM {adminpresets} preset 2642 INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid 2643 WHERE it.name = :name AND it.value = :value AND preset.iscore > 0"; 2644 2645 $name = get_string('starterpreset', 'core_adminpresets'); 2646 $params = ['name' => $name, 'iscore' => 1]; 2647 $starterpreset = $DB->get_record('adminpresets', $params); 2648 if (!$starterpreset) { 2649 // Starter admin preset might have been created using the English name. Let's change it to current language. 2650 $englishname = get_string_manager()->get_string('starterpreset', 'core_adminpresets', null, 'en'); 2651 $params['name'] = $englishname; 2652 $starterpreset = $DB->get_record('adminpresets', $params); 2653 } 2654 if (!$starterpreset) { 2655 // We tried, but we didn't find starter by name. Let's find a core preset that sets 'usecomments' setting to 0. 2656 $params = ['name' => 'usecomments', 'value' => '0']; 2657 $starterpreset = $DB->get_record_sql($sql, $params); 2658 } 2659 // The iscore field is already 1 for starterpreset, so we don't need to change it. 2660 // We only need to update the name and comment in case they are different to current language strings. 2661 if ($starterpreset && $starterpreset->name != $name) { 2662 $starterpreset->name = $name; 2663 $starterpreset->comments = get_string('starterpresetdescription', 'core_adminpresets'); 2664 $DB->update_record('adminpresets', $starterpreset); 2665 } 2666 2667 // Let's mark Full admin presets with current FULL_PRESETS value and change the name to current language. 2668 $name = get_string('fullpreset', 'core_adminpresets'); 2669 $params = ['name' => $name]; 2670 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 2671 if (!$fullpreset) { 2672 // Full admin preset might have been created using the English name. 2673 $englishname = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en'); 2674 $params['name'] = $englishname; 2675 $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params); 2676 } 2677 if (!$fullpreset) { 2678 // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1. 2679 $params = ['name' => 'usecomments', 'value' => '1']; 2680 $fullpreset = $DB->get_record_sql($sql, $params); 2681 } 2682 if ($fullpreset) { 2683 // We need to update iscore field value, whether the name is the same or not. 2684 $fullpreset->name = $name; 2685 $fullpreset->comments = get_string('fullpresetdescription', 'core_adminpresets'); 2686 $fullpreset->iscore = 2; 2687 $DB->update_record('adminpresets', $fullpreset); 2688 2689 // We are applying again changes made on 2022011100.01 upgrading step because of MDL-73953 bug. 2690 $blocknames = ['course_summary', 'feedback', 'rss_client', 'selfcompletion']; 2691 list($blocksinsql, $blocksinparams) = $DB->get_in_or_equal($blocknames); 2692 2693 // Remove entries from the adminpresets_app_plug table (in case the preset has been applied). 2694 $appliedpresets = $DB->get_records('adminpresets_app', ['adminpresetid' => $fullpreset->id], '', 'id'); 2695 if ($appliedpresets) { 2696 list($appsinsql, $appsinparams) = $DB->get_in_or_equal(array_keys($appliedpresets)); 2697 $sql = "adminpresetapplyid $appsinsql AND plugin='block' AND name $blocksinsql"; 2698 $params = array_merge($appsinparams, $blocksinparams); 2699 $DB->delete_records_select('adminpresets_app_plug', $sql, $params); 2700 } 2701 2702 // Remove entries for these blocks from the adminpresets_plug table. 2703 $sql = "adminpresetid = ? AND plugin='block' AND name $blocksinsql"; 2704 $params = array_merge([$fullpreset->id], $blocksinparams); 2705 $DB->delete_records_select('adminpresets_plug', $sql, $params); 2706 } 2707 2708 // Main savepoint reached. 2709 upgrade_main_savepoint(true, 2022030100.00); 2710 } 2711 2712 if ($oldversion < 2022031100.01) { 2713 $reportsusermenuitem = 'reports,core_reportbuilder|/reportbuilder/index.php'; 2714 upgrade_add_item_to_usermenu($reportsusermenuitem); 2715 // Main savepoint reached. 2716 upgrade_main_savepoint(true, 2022031100.01); 2717 } 2718 2719 if ($oldversion < 2022032200.01) { 2720 2721 // Define index to be added to question_references. 2722 $table = new xmldb_table('question_references'); 2723 $index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE, 2724 ['usingcontextid', 'component', 'questionarea', 'itemid']); 2725 2726 // Conditionally launch add field id. 2727 if (!$dbman->index_exists($table, $index)) { 2728 $dbman->add_index($table, $index); 2729 } 2730 2731 // Main savepoint reached. 2732 upgrade_main_savepoint(true, 2022032200.01); 2733 } 2734 2735 if ($oldversion < 2022032200.02) { 2736 2737 // Define index to be added to question_references. 2738 $table = new xmldb_table('question_set_references'); 2739 $index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE, 2740 ['usingcontextid', 'component', 'questionarea', 'itemid']); 2741 2742 // Conditionally launch add field id. 2743 if (!$dbman->index_exists($table, $index)) { 2744 $dbman->add_index($table, $index); 2745 } 2746 2747 // Main savepoint reached. 2748 upgrade_main_savepoint(true, 2022032200.02); 2749 } 2750 2751 if ($oldversion < 2022041200.01) { 2752 2753 // The original default admin presets "sensible settings" (those that should be treated as sensitive). 2754 $originalsensiblesettings = 'recaptchapublickey@@none, recaptchaprivatekey@@none, googlemapkey3@@none, ' . 2755 'secretphrase@@url, cronremotepassword@@none, smtpuser@@none, smtppass@none, proxypassword@@none, ' . 2756 'quizpassword@@quiz, allowedip@@none, blockedip@@none, dbpass@@logstore_database, messageinbound_hostpass@@none, ' . 2757 'bind_pw@@auth_cas, pass@@auth_db, bind_pw@@auth_ldap, dbpass@@enrol_database, bind_pw@@enrol_ldap, ' . 2758 'server_password@@search_solr, ssl_keypassword@@search_solr, alternateserver_password@@search_solr, ' . 2759 'alternatessl_keypassword@@search_solr, test_password@@cachestore_redis, password@@mlbackend_python'; 2760 2761 // Check if the current config matches the original default, upgrade to new default if so. 2762 if (get_config('adminpresets', 'sensiblesettings') === $originalsensiblesettings) { 2763 $newsensiblesettings = "{$originalsensiblesettings}, badges_badgesalt@@none, calendar_exportsalt@@none"; 2764 set_config('sensiblesettings', $newsensiblesettings, 'adminpresets'); 2765 } 2766 2767 // Main savepoint reached. 2768 upgrade_main_savepoint(true, 2022041200.01); 2769 } 2770 2771 // Automatically generated Moodle v4.0.0 release upgrade line. 2772 // Put any upgrade step following this. 2773 2774 if ($oldversion < 2022042900.01) { 2775 // Social custom fields could had been created linked to category id = 1. Let's check category 1 exists. 2776 if (!$DB->get_record('user_info_category', ['id' => 1])) { 2777 // Let's check if we have any custom field linked to category id = 1. 2778 $fields = $DB->get_records('user_info_field', ['categoryid' => 1]); 2779 if (!empty($fields)) { 2780 $categoryid = $DB->get_field_sql('SELECT min(id) from {user_info_category}'); 2781 foreach ($fields as $field) { 2782 $field->categoryid = $categoryid; 2783 $DB->update_record('user_info_field', $field); 2784 } 2785 } 2786 } 2787 2788 // Main savepoint reached. 2789 upgrade_main_savepoint(true, 2022042900.01); 2790 } 2791 2792 if ($oldversion < 2022051000.00) { 2793 // Add index to the sid field in the external_tokens table. 2794 $table = new xmldb_table('external_tokens'); 2795 $index = new xmldb_index('sid', XMLDB_INDEX_NOTUNIQUE, ['sid']); 2796 2797 if (!$dbman->index_exists($table, $index)) { 2798 $dbman->add_index($table, $index); 2799 } 2800 2801 upgrade_main_savepoint(true, 2022051000.00); 2802 } 2803 2804 if ($oldversion < 2022052500.00) { 2805 // Start an adhoc task to fix the file timestamps of restored files. 2806 $task = new core\task\fix_file_timestamps_task(); 2807 \core\task\manager::queue_adhoc_task($task); 2808 2809 // Main savepoint reached. 2810 upgrade_main_savepoint(true, 2022052500.00); 2811 } 2812 2813 if ($oldversion < 2022052700.01) { 2814 2815 // Define index timestarted_idx (not unique) to be added to task_adhoc. 2816 $table = new xmldb_table('task_adhoc'); 2817 $index = new xmldb_index('timestarted_idx', XMLDB_INDEX_NOTUNIQUE, ['timestarted']); 2818 2819 // Conditionally launch add index timestarted_idx. 2820 if (!$dbman->index_exists($table, $index)) { 2821 $dbman->add_index($table, $index); 2822 } 2823 2824 // Main savepoint reached. 2825 upgrade_main_savepoint(true, 2022052700.01); 2826 } 2827 2828 if ($oldversion < 2022052700.02) { 2829 2830 // Define index filename (not unique) to be added to files. 2831 $table = new xmldb_table('files'); 2832 $index = new xmldb_index('filename', XMLDB_INDEX_NOTUNIQUE, ['filename']); 2833 2834 // Conditionally launch add index filename. 2835 if (!$dbman->index_exists($table, $index)) { 2836 $dbman->add_index($table, $index); 2837 } 2838 2839 // Main savepoint reached. 2840 upgrade_main_savepoint(true, 2022052700.02); 2841 } 2842 2843 if ($oldversion < 2022060300.01) { 2844 2845 // Changing precision of field hidden on table grade_categories to (10). 2846 $table = new xmldb_table('grade_categories'); 2847 $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timemodified'); 2848 2849 // Launch change of precision for field hidden. 2850 $dbman->change_field_precision($table, $field); 2851 2852 // Changing precision of field hidden on table grade_categories_history to (10). 2853 $table = new xmldb_table('grade_categories_history'); 2854 $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'aggregatesubcats'); 2855 2856 // Launch change of precision for field hidden. 2857 $dbman->change_field_precision($table, $field); 2858 2859 // Main savepoint reached. 2860 upgrade_main_savepoint(true, 2022060300.01); 2861 } 2862 2863 if ($oldversion < 2022061000.01) { 2864 // Iterate over custom user menu items configuration, removing pix icon references. 2865 $customusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems); 2866 2867 $lines = preg_split('/\n/', $customusermenuitems, -1, PREG_SPLIT_NO_EMPTY); 2868 $lines = array_map(static function(string $line): string { 2869 // Previous format was "<langstring>|<url>[|<pixicon>]" - pix icon is no longer supported. 2870 $lineparts = explode('|', trim($line), 3); 2871 // Return first two parts of line. 2872 return implode('|', array_slice($lineparts, 0, 2)); 2873 }, $lines); 2874 2875 set_config('customusermenuitems', implode("\n", $lines)); 2876 2877 upgrade_main_savepoint(true, 2022061000.01); 2878 } 2879 2880 if ($oldversion < 2022061500.00) { 2881 // Remove drawer-open-nav user preference for every user. 2882 $DB->delete_records('user_preferences', ['name' => 'drawer-open-nav']); 2883 2884 // Main savepoint reached. 2885 upgrade_main_savepoint(true, 2022061500.00); 2886 2887 } 2888 2889 if ($oldversion < 2022072900.00) { 2890 // Call the helper function that updates the foreign keys and indexes in MDL-49795. 2891 upgrade_add_foreign_key_and_indexes(); 2892 2893 // Main savepoint reached. 2894 upgrade_main_savepoint(true, 2022072900.00); 2895 } 2896 2897 if ($oldversion < 2022081200.01) { 2898 2899 // Define field lang to be added to course_modules. 2900 $table = new xmldb_table('course_modules'); 2901 $field = new xmldb_field('lang', XMLDB_TYPE_CHAR, '30', null, null, null, null, 'downloadcontent'); 2902 2903 // Conditionally launch add field lang. 2904 if (!$dbman->field_exists($table, $field)) { 2905 $dbman->add_field($table, $field); 2906 } 2907 2908 // Main savepoint reached. 2909 upgrade_main_savepoint(true, 2022081200.01); 2910 } 2911 2912 if ($oldversion < 2022091000.01) { 2913 $table = new xmldb_table('h5p'); 2914 $indexpathnamehash = new xmldb_index('pathnamehash_idx', XMLDB_INDEX_NOTUNIQUE, ['pathnamehash']); 2915 2916 if (!$dbman->index_exists($table, $indexpathnamehash)) { 2917 $dbman->add_index($table, $indexpathnamehash); 2918 } 2919 // Main savepoint reached. 2920 upgrade_main_savepoint(true, 2022091000.01); 2921 } 2922 2923 if ($oldversion < 2022092200.01) { 2924 2925 // Remove any orphaned tag instance records (pointing to non-existing context). 2926 $DB->delete_records_select('tag_instance', 'NOT EXISTS ( 2927 SELECT ctx.id FROM {context} ctx WHERE ctx.id = {tag_instance}.contextid 2928 )'); 2929 2930 // Main savepoint reached. 2931 upgrade_main_savepoint(true, 2022092200.01); 2932 } 2933 2934 if ($oldversion < 2022101400.01) { 2935 $table = new xmldb_table('competency_modulecomp'); 2936 $field = new xmldb_field('overridegrade', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'ruleoutcome'); 2937 2938 if (!$dbman->field_exists($table, $field)) { 2939 $dbman->add_field($table, $field); 2940 } 2941 2942 // Main savepoint reached. 2943 upgrade_main_savepoint(true, 2022101400.01); 2944 } 2945 2946 if ($oldversion < 2022101400.03) { 2947 // Define table to store completion viewed. 2948 $table = new xmldb_table('course_modules_viewed'); 2949 2950 // Adding fields to table course_modules_viewed. 2951 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 2952 $table->add_field('coursemoduleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id'); 2953 $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'coursemoduleid'); 2954 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid'); 2955 2956 // Adding keys to table course_modules_viewed. 2957 $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 2958 2959 // Adding indexes to table course_modules_viewed. 2960 $table->add_index('coursemoduleid', XMLDB_INDEX_NOTUNIQUE, ['coursemoduleid']); 2961 $table->add_index('userid-coursemoduleid', XMLDB_INDEX_UNIQUE, ['userid', 'coursemoduleid']); 2962 2963 if (!$dbman->table_exists($table)) { 2964 $dbman->create_table($table); 2965 } 2966 2967 // Main savepoint reached. 2968 upgrade_main_savepoint(true, 2022101400.03); 2969 } 2970 2971 if ($oldversion < 2022101400.04) { 2972 // Add legacy data to the new table. 2973 $transaction = $DB->start_delegated_transaction(); 2974 upgrade_set_timeout(3600); 2975 $sql = "INSERT INTO {course_modules_viewed} 2976 (userid, coursemoduleid, timecreated) 2977 SELECT userid, coursemoduleid, timemodified 2978 FROM {course_modules_completion} 2979 WHERE viewed = 1"; 2980 $DB->execute($sql); 2981 $transaction->allow_commit(); 2982 2983 // Main savepoint reached. 2984 upgrade_main_savepoint(true, 2022101400.04); 2985 } 2986 2987 if ($oldversion < 2022101400.05) { 2988 // Define field viewed to be dropped from course_modules_completion. 2989 $table = new xmldb_table('course_modules_completion'); 2990 $field = new xmldb_field('viewed'); 2991 2992 // Conditionally launch drop field viewed. 2993 if ($dbman->field_exists($table, $field)) { 2994 $dbman->drop_field($table, $field); 2995 } 2996 2997 // Main savepoint reached. 2998 upgrade_main_savepoint(true, 2022101400.05); 2999 } 3000 3001 if ($oldversion < 2022102800.01) { 3002 // For sites with "contact site support" already available (4.0.x), maintain existing functionality. 3003 if ($oldversion >= 2022041900.00) { 3004 set_config('supportavailability', CONTACT_SUPPORT_ANYONE); 3005 } else { 3006 // Sites which did not previously have the "contact site support" feature default to it requiring authentication. 3007 set_config('supportavailability', CONTACT_SUPPORT_AUTHENTICATED); 3008 } 3009 3010 // Main savepoint reached. 3011 upgrade_main_savepoint(true, 2022102800.01); 3012 } 3013 3014 if ($oldversion < 2022110600.00) { 3015 // If webservice_xmlrpc isn't any longer installed, remove its configuration, 3016 // capabilities and presence in other settings. 3017 if (!file_exists($CFG->dirroot . '/webservice/xmlrpc/version.php')) { 3018 // No DB structures to delete in this plugin. 3019 3020 // Remove capabilities. 3021 capabilities_cleanup('webservice_xmlrpc'); 3022 3023 // Remove own configuration. 3024 unset_all_config_for_plugin('webservice_xmlrpc'); 3025 3026 // Remove it from the enabled protocols if it was there. 3027 $protos = get_config('core', 'webserviceprotocols'); 3028 $protoarr = explode(',', $protos); 3029 $protoarr = array_filter($protoarr, function($ele) { 3030 return trim($ele) !== 'xmlrpc'; 3031 }); 3032 $protos = implode(',', $protoarr); 3033 set_config('webserviceprotocols', $protos); 3034 } 3035 3036 // Main savepoint reached. 3037 upgrade_main_savepoint(true, 2022110600.00); 3038 } 3039 3040 // Automatically generated Moodle v4.1.0 release upgrade line. 3041 // Put any upgrade step following this. 3042 3043 if ($oldversion < 2022112800.03) { 3044 3045 // Remove any orphaned role assignment records (pointing to non-existing roles). 3046 $DB->delete_records_select('role_assignments', 'NOT EXISTS ( 3047 SELECT r.id FROM {role} r WHERE r.id = {role_assignments}.roleid 3048 )'); 3049 3050 // Main savepoint reached. 3051 upgrade_main_savepoint(true, 2022112800.03); 3052 } 3053 3054 if ($oldversion < 2022112803.03) { 3055 // Add public key field to user_devices table. 3056 $table = new xmldb_table('user_devices'); 3057 $field = new xmldb_field('publickey', XMLDB_TYPE_TEXT, null, null, null, null, null, 'uuid'); 3058 3059 if (!$dbman->field_exists($table, $field)) { 3060 $dbman->add_field($table, $field); 3061 } 3062 3063 // Main savepoint reached. 3064 upgrade_main_savepoint(true, 2022112803.03); 3065 } 3066 3067 if ($oldversion < 2022112804.09) { 3068 // Upgrade yaml mime type for existing yaml and yml files. 3069 $filetypes = [ 3070 '%.yaml' => 'application/yaml', 3071 '%.yml' => 'application/yaml,' 3072 ]; 3073 3074 $select = $DB->sql_like('filename', '?', false); 3075 foreach ($filetypes as $extension => $mimetype) { 3076 $DB->set_field_select( 3077 'files', 3078 'mimetype', 3079 $mimetype, 3080 $select, 3081 [$extension] 3082 ); 3083 } 3084 3085 // Main savepoint reached. 3086 upgrade_main_savepoint(true, 2022112804.09); 3087 } 3088 3089 if ($oldversion < 2022112805.03) { 3090 3091 // The previous default configuration had a typo, check for its presence and correct if necessary. 3092 $sensiblesettings = get_config('adminpresets', 'sensiblesettings'); 3093 if (strpos($sensiblesettings, 'smtppass@none') !== false) { 3094 $newsensiblesettings = str_replace('smtppass@none', 'smtppass@@none', $sensiblesettings); 3095 set_config('sensiblesettings', $newsensiblesettings, 'adminpresets'); 3096 } 3097 3098 // Main savepoint reached. 3099 upgrade_main_savepoint(true, 2022112805.03); 3100 } 3101 3102 if ($oldversion < 2022112805.11) { 3103 upgrade_core_licenses(); 3104 upgrade_main_savepoint(true, 2022112805.11); 3105 } 3106 3107 if ($oldversion < 2022112805.14) { 3108 // Delete datakey with datavalue -1. 3109 $DB->delete_records('messageinbound_datakeys', ['datavalue' => '-1']); 3110 // Main savepoint reached. 3111 upgrade_main_savepoint(true, 2022112805.14); 3112 } 3113 3114 return true; 3115 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body