<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file keeps track of upgrades to Moodle.
*
* Sometimes, changes between versions involve
* alterations to database structures and other
* major things that may break installations.
*
* The upgrade function in this file will attempt
* to perform all the necessary actions to upgrade
* your older installation to the current version.
*
* If there's something it cannot do itself, it
* will tell you what you need to do.
*
* The commands in here will all be database-neutral,
* using the methods of database_manager class
*
* Please do not forget to use upgrade_set_timeout()
* before any action that may take longer time to finish.
*
* @package core_install
* @category upgrade
* @copyright 2006 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Main upgrade tasks to be executed on Moodle version bump
*
* This function is automatically executed after one bump in the Moodle core
* version is detected. It's in charge of performing the required tasks
* to raise core from the previous version to the next one.
*
* It's a collection of ordered blocks of code, named "upgrade steps",
* each one performing one isolated (from the rest of steps) task. Usually
* tasks involve creating new DB objects or performing manipulation of the
* information for cleanup/fixup purposes.
*
* Each upgrade step has a fixed structure, that can be summarised as follows:
*
* if ($oldversion < XXXXXXXXXX.XX) {
* // Explanation of the update step, linking to issue in the Tracker if necessary
* upgrade_set_timeout(XX); // Optional for big tasks
* // Code to execute goes here, usually the XMLDB Editor will
< * // help you here. See {@link http://docs.moodle.org/dev/XMLDB_editor}.
> * // help you here. See {@link https://moodledev.io/general/development/tools/xmldb}.
* upgrade_main_savepoint(true, XXXXXXXXXX.XX);
* }
*
* All plugins within Moodle (modules, blocks, reports...) support the existence of
* their own upgrade.php file, using the "Frankenstyle" component name as
< * defined at {@link http://docs.moodle.org/dev/Frankenstyle}, for example:
> * defined at {@link https://moodledev.io/general/development/policies/codingstyle/frankenstyle}, for example:
* - {@link xmldb_page_upgrade($oldversion)}. (modules don't require the plugintype ("mod_") to be used.
* - {@link xmldb_auth_manual_upgrade($oldversion)}.
* - {@link xmldb_workshopform_accumulative_upgrade($oldversion)}.
* - ....
*
* In order to keep the contents of this file reduced, it's allowed to create some helper
* functions to be used here in the {@link upgradelib.php} file at the same directory. Note
* that such a file must be manually included from upgrade.php, and there are some restrictions
* about what can be used within it.
*
* For more information, take a look to the documentation available:
< * - Data definition API: {@link http://docs.moodle.org/dev/Data_definition_API}
< * - Upgrade API: {@link http://docs.moodle.org/dev/Upgrade_API}
> * - Data definition API: {@link https://moodledev.io/docs/apis/core/dml/ddl}
> * - Upgrade API: {@link https://moodledev.io/docs/guides/upgrade}
*
* @param int $oldversion
* @return bool always true
*/
function xmldb_main_upgrade($oldversion) {
global $CFG, $DB;
require_once($CFG->libdir.'/db/upgradelib.php'); // Core Upgrade-related functions.
$dbman = $DB->get_manager(); // Loads ddl manager and xmldb classes.
// Always keep this upgrade step with version being the minimum
< // allowed version to upgrade from (v3.5.0 right now).
< if ($oldversion < 2018051700) {
> // allowed version to upgrade from (v3.11.8 right now).
> if ($oldversion < 2021051708) {
// Just in case somebody hacks upgrade scripts or env, we really can not continue.
< echo("You need to upgrade to 3.5.x or higher first!\n");
> echo("You need to upgrade to 3.11.8 or higher first!\n");
exit(1);
// Note this savepoint is 100% unreachable, but needed to pass the upgrade checks.
< upgrade_main_savepoint(true, 2018051700);
> upgrade_main_savepoint(true, 2021051708);
}
< // Automatically generated Moodle v3.5.0 release upgrade line.
< // Put any upgrade step following this.
> if ($oldversion < 2021052500.01) {
> // Delete all user evidence files from users that have been deleted.
> $sql = "SELECT DISTINCT f.*
> FROM {files} f
> LEFT JOIN {context} c ON f.contextid = c.id
> WHERE f.component = :component
> AND f.filearea = :filearea
> AND c.id IS NULL";
> $stalefiles = $DB->get_records_sql($sql, ['component' => 'core_competency', 'filearea' => 'userevidence']);
< if ($oldversion < 2018062800.01) {
< // Add foreign key fk_user to the comments table.
< $table = new xmldb_table('comments');
< $key = new xmldb_key('fk_user', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
< $dbman->add_key($table, $key);
<
< upgrade_main_savepoint(true, 2018062800.01);
> $fs = get_file_storage();
> foreach ($stalefiles as $stalefile) {
> $fs->get_file_instance($stalefile)->delete();
}
< if ($oldversion < 2018062800.02) {
< // Add composite index ix_concomitem to the table comments.
< $table = new xmldb_table('comments');
< $index = new xmldb_index('ix_concomitem', XMLDB_INDEX_NOTUNIQUE, array('contextid', 'commentarea', 'itemid'));
<
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> upgrade_main_savepoint(true, 2021052500.01);
}
< upgrade_main_savepoint(true, 2018062800.02);
< }
> if ($oldversion < 2021052500.02) {
< if ($oldversion < 2018062800.03) {
< // Define field location to be added to event.
< $table = new xmldb_table('event');
< $field = new xmldb_field('location', XMLDB_TYPE_TEXT, null, null, null, null, null, 'priority');
> // Define field timecreated to be added to task_adhoc.
> $table = new xmldb_table('task_adhoc');
> $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'blocking');
< // Conditionally launch add field location.
> // Conditionally launch add field timecreated.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018062800.03);
> upgrade_main_savepoint(true, 2021052500.02);
}
< if ($oldversion < 2018072500.00) {
< // Find all duplicate top level categories per context.
< $duplicates = $DB->get_records_sql("SELECT qc1.*
< FROM {question_categories} qc1
< JOIN {question_categories} qc2
< ON qc1.contextid = qc2.contextid AND qc1.id <> qc2.id
< WHERE qc1.parent = 0 AND qc2.parent = 0
< ORDER BY qc1.contextid, qc1.id");
<
< // For each context, let the first top category to remain as top category and make the rest its children.
< $currentcontextid = 0;
< $chosentopid = 0;
< foreach ($duplicates as $duplicate) {
< if ($currentcontextid != $duplicate->contextid) {
< $currentcontextid = $duplicate->contextid;
< $chosentopid = $duplicate->id;
< } else {
< $DB->set_field('question_categories', 'parent', $chosentopid, ['id' => $duplicate->id]);
< }
< }
<
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2018072500.00);
< }
<
< if ($oldversion < 2018073000.00) {
< // Main savepoint reached.
< if (!file_exists($CFG->dirroot . '/admin/tool/assignmentupgrade/version.php')) {
< unset_all_config_for_plugin('tool_assignmentupgrade');
< }
< upgrade_main_savepoint(true, 2018073000.00);
< }
<
< if ($oldversion < 2018083100.01) {
< // Remove module associated blog posts for non-existent (deleted) modules.
< $sql = "SELECT ba.contextid as modcontextid
< FROM {blog_association} ba
< JOIN {post} p
< ON p.id = ba.blogid
< LEFT JOIN {context} c
< ON c.id = ba.contextid
< WHERE p.module = :module
< AND c.contextlevel IS NULL
< GROUP BY ba.contextid";
< if ($deletedmodules = $DB->get_records_sql($sql, array('module' => 'blog'))) {
< foreach ($deletedmodules as $module) {
< $assocblogids = $DB->get_fieldset_select('blog_association', 'blogid',
< 'contextid = :contextid', ['contextid' => $module->modcontextid]);
< list($sql, $params) = $DB->get_in_or_equal($assocblogids, SQL_PARAMS_NAMED);
> if ($oldversion < 2021052500.04) {
> // Define field metadatasettings to be added to h5p_libraries.
> $table = new xmldb_table('h5p_libraries');
> $field = new xmldb_field('metadatasettings', XMLDB_TYPE_TEXT, null, null, null, null, null, 'coreminor');
< $DB->delete_records_select('tag_instance', "itemid $sql", $params);
< $DB->delete_records_select('post', "id $sql AND module = :module",
< array_merge($params, ['module' => 'blog']));
< $DB->delete_records('blog_association', ['contextid' => $module->modcontextid]);
< }
> // Conditionally launch add field metadatasettings.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2018083100.01);
< }
> // Get installed library files that have no metadata settings value.
> $params = [
> 'component' => 'core_h5p',
> 'filearea' => 'libraries',
> 'filename' => 'library.json',
> ];
> $sql = "SELECT l.id, f.id as fileid
> FROM {files} f
> LEFT JOIN {h5p_libraries} l ON f.itemid = l.id
> WHERE f.component = :component
> AND f.filearea = :filearea
> AND f.filename = :filename";
> $libraries = $DB->get_records_sql($sql, $params);
< if ($oldversion < 2018091200.00) {
< if (!file_exists($CFG->dirroot . '/cache/stores/memcache/settings.php')) {
< unset_all_config_for_plugin('cachestore_memcache');
> // Update metadatasettings field when the attribute is present in the library.json file.
> $fs = get_file_storage();
> foreach ($libraries as $library) {
> $jsonfile = $fs->get_file_by_id($library->fileid);
> $jsoncontent = json_decode($jsonfile->get_content());
> if (isset($jsoncontent->metadataSettings)) {
> unset($library->fileid);
> $library->metadatasettings = json_encode($jsoncontent->metadataSettings);
> $DB->update_record('h5p_libraries', $library);
}
<
< upgrade_main_savepoint(true, 2018091200.00);
}
< if ($oldversion < 2018091700.01) {
< // Remove unused setting.
< unset_config('messaginghidereadnotifications');
<
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018091700.01);
> upgrade_main_savepoint(true, 2021052500.04);
}
< // Add idnumber fields to question and question_category tables.
< // This is done in four parts to aid error recovery during upgrade, should that occur.
< if ($oldversion < 2018092100.01) {
< $table = new xmldb_table('question');
< $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'modifiedby');
> if ($oldversion < 2021052500.05) {
> // Define fields to be added to task_scheduled.
> $table = new xmldb_table('task_scheduled');
> $field = new xmldb_field('timestarted', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'disabled');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< upgrade_main_savepoint(true, 2018092100.01);
< }
<
< if ($oldversion < 2018092100.02) {
< $table = new xmldb_table('question');
< $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, array('category', 'idnumber'));
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
< }
< upgrade_main_savepoint(true, 2018092100.02);
< }
<
< if ($oldversion < 2018092100.03) {
< $table = new xmldb_table('question_categories');
< $field = new xmldb_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'sortorder');
> $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timestarted');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< upgrade_main_savepoint(true, 2018092100.03);
> $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname');
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< if ($oldversion < 2018092100.04) {
< $table = new xmldb_table('question_categories');
< $index = new xmldb_index('contextididnumber', XMLDB_INDEX_UNIQUE, array('contextid', 'idnumber'));
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> // Define fields to be added to task_adhoc.
> $table = new xmldb_table('task_adhoc');
> $field = new xmldb_field('timestarted', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blocking');
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2018092100.04);
> $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timestarted');
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
<
< if ($oldversion < 2018092800.00) {
< // Alter the table 'message_contacts'.
< $table = new xmldb_table('message_contacts');
<
< // Remove index so we can alter the fields.
< $index = new xmldb_index('userid-contactid', XMLDB_INDEX_UNIQUE, ['userid', 'contactid']);
< if ($dbman->index_exists($table, $index)) {
< $dbman->drop_index($table, $index);
> $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname');
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< // Remove defaults of '0' from the 'userid' and 'contactid' fields.
< $field = new xmldb_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
< $dbman->change_field_default($table, $field);
<
< $field = new xmldb_field('contactid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
< $dbman->change_field_default($table, $field);
<
< // Add the missing FKs that will now be added to new installs.
< $key = new xmldb_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< $dbman->add_key($table, $key);
<
< $key = new xmldb_key('contactid', XMLDB_KEY_FOREIGN, ['contactid'], 'user', ['id']);
< $dbman->add_key($table, $key);
<
< // Re-add the index.
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> // Define fields to be added to task_log.
> $table = new xmldb_table('task_log');
> $field = new xmldb_field('hostname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'output');
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
<
< // Add the field 'timecreated'. Allow null, since existing records won't have an accurate value we can use.
< $field = new xmldb_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blocked');
> $field = new xmldb_field('pid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'hostname');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Create new 'message_contact_requests' table.
< $table = new xmldb_table('message_contact_requests');
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
< $table->add_field('requesteduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'requesteduserid');
<
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
< $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< $table->add_key('requesteduserid', XMLDB_KEY_FOREIGN, ['requesteduserid'], 'user', ['id']);
<
< $table->add_index('userid-requesteduserid', XMLDB_INDEX_UNIQUE, ['userid', 'requesteduserid']);
<
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.05);
}
< // Create new 'message_users_blocked' table.
< $table = new xmldb_table('message_users_blocked');
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
< $table->add_field('blockeduserid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
< // Allow NULLs in the 'timecreated' field because we will be moving existing data here that has no timestamp.
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'blockeduserid');
> if ($oldversion < 2021052500.06) {
> // Define table to store virus infected details.
> $table = new xmldb_table('infected_files');
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id'], null, null);
< $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< $table->add_key('blockeduserid', XMLDB_KEY_FOREIGN, ['blockeduserid'], 'user', ['id']);
> // Adding fields to table infected_files.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('filename', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> $table->add_field('quarantinedfile', XMLDB_TYPE_TEXT, null, null, null, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('reason', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_index('userid-blockeduserid', XMLDB_INDEX_UNIQUE, ['userid', 'blockeduserid']);
> // Adding keys to table infected_files.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
> // Conditionally launch create table for infected_files.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
<
< upgrade_main_savepoint(true, 2018092800.00);
> upgrade_main_savepoint(true, 2021052500.06);
}
< if ($oldversion < 2018092800.01) {
< // Move all the 'blocked' contacts to the new table 'message_users_blocked'.
< $updatesql = "INSERT INTO {message_users_blocked} (userid, blockeduserid, timecreated)
< SELECT userid, contactid, null as timecreated
< FROM {message_contacts}
< WHERE blocked = :blocked";
< $DB->execute($updatesql, ['blocked' => 1]);
<
< // Removed the 'blocked' column from 'message_contacts'.
< $table = new xmldb_table('message_contacts');
< $field = new xmldb_field('blocked');
< $dbman->drop_field($table, $field);
> if ($oldversion < 2021052500.13) {
> // Remove all the files with component='core_h5p' and filearea='editor' because they won't be used anymore.
> $fs = get_file_storage();
> $syscontext = context_system::instance();
> $fs->delete_area_files($syscontext->id, 'core_h5p', 'editor');
< upgrade_main_savepoint(true, 2018092800.01);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.13);
}
< if ($oldversion < 2018092800.02) {
< // Delete any contacts that are not mutual (meaning they both haven't added each other).
< do {
< $sql = "SELECT c1.id
< FROM {message_contacts} c1
< LEFT JOIN {message_contacts} c2
< ON c1.userid = c2.contactid
< AND c1.contactid = c2.userid
< WHERE c2.id IS NULL";
< if ($contacts = $DB->get_records_sql($sql, null, 0, 1000)) {
< list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
< $DB->delete_records_select('message_contacts', "id $insql", $inparams);
< }
< } while ($contacts);
<
< upgrade_main_savepoint(true, 2018092800.02);
< }
<
< if ($oldversion < 2018092800.03) {
< // Remove any duplicate rows - from now on adding contacts just requires 1 row.
< // The person who made the contact request (userid) and the person who approved
< // it (contactid). Upgrade the table so that the first person to add the contact
< // was the one who made the request.
< $sql = "SELECT c1.id
< FROM {message_contacts} c1
< INNER JOIN {message_contacts} c2
< ON c1.userid = c2.contactid
< AND c1.contactid = c2.userid
< WHERE c1.id > c2.id";
< if ($contacts = $DB->get_records_sql($sql)) {
< list($insql, $inparams) = $DB->get_in_or_equal(array_keys($contacts));
< $DB->delete_records_select('message_contacts', "id $insql", $inparams);
< }
<
< upgrade_main_savepoint(true, 2018092800.03);
< }
<
< if ($oldversion < 2018101700.01) {
< if (empty($CFG->keepmessagingallusersenabled)) {
< // When it is not set, $CFG->messagingallusers should be disabled by default.
< // When $CFG->messagingallusers = false, the default user preference is MESSAGE_PRIVACY_COURSEMEMBER
< // (contacted by users sharing a course).
< set_config('messagingallusers', false);
< } else {
< // When $CFG->keepmessagingallusersenabled is set to true, $CFG->messagingallusers is set to true.
< set_config('messagingallusers', true);
> if ($oldversion < 2021052500.15) {
> // Copy From id captures the id of the source course when a new course originates from a restore
> // of another course on the same site.
> $table = new xmldb_table('course');
> $field = new xmldb_field('originalcourseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< // When $CFG->messagingallusers = true, the default user preference is MESSAGE_PRIVACY_SITE
< // (contacted by all users site). So we need to set existing values from 0 (MESSAGE_PRIVACY_COURSEMEMBER)
< // to 2 (MESSAGE_PRIVACY_SITE).
< $DB->set_field(
< 'user_preferences',
< 'value',
< \core_message\api::MESSAGE_PRIVACY_SITE,
< array('name' => 'message_blocknoncontacts', 'value' => 0)
< );
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018101700.01);
> upgrade_main_savepoint(true, 2021052500.15);
}
< if ($oldversion < 2018101800.00) {
< // Define table 'favourite' to be created.
< $table = new xmldb_table('favourite');
> if ($oldversion < 2021052500.19) {
> // Define table oauth2_refresh_token to be created.
> $table = new xmldb_table('oauth2_refresh_token');
< // Adding fields to table favourite.
> // Adding fields to table oauth2_refresh_token.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('itemtype', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('ordering', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
// Adding keys to table favourite.
> $table->add_field('token', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_field('scopehash', XMLDB_TYPE_CHAR, 40, null, XMLDB_NOTNULL, null, null);
< // Adding keys to table favourite.
> // Adding keys to table oauth2_refresh_token.
< $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
< $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
> $table->add_key('issueridkey', XMLDB_KEY_FOREIGN, ['issuerid'], 'oauth2_issuer', ['id']);
> $table->add_key('useridkey', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< // Adding indexes to table favourite.
< $table->add_index('uniqueuserfavouriteitem', XMLDB_INDEX_UNIQUE, ['component', 'itemtype', 'itemid', 'contextid', 'userid']);
> // Adding indexes to table oauth2_refresh_token.
> $table->add_index('userid-issuerid-scopehash', XMLDB_INDEX_UNIQUE, array('userid', 'issuerid', 'scopehash'));
< // Conditionally launch create table for favourite.
> // Conditionally launch create table for oauth2_refresh_token.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018101800.00);
> upgrade_main_savepoint(true, 2021052500.19);
}
< if ($oldversion < 2018102200.00) {
< // Add field 'type' to 'message_conversations'.
< $table = new xmldb_table('message_conversations');
< $field = new xmldb_field('type', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 1, 'id');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
< }
> if ($oldversion < 2021052500.20) {
< // Add field 'name' to 'message_conversations'.
< $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'type');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
< }
> // Define index modulename-instance-eventtype (not unique) to be added to event.
> $table = new xmldb_table('event');
> $index = new xmldb_index('modulename-instance-eventtype', XMLDB_INDEX_NOTUNIQUE, ['modulename', 'instance', 'eventtype']);
< // Conditionally launch add index 'type'.
< $index = new xmldb_index('type', XMLDB_INDEX_NOTUNIQUE, ['type']);
> // Conditionally launch add index modulename-instance-eventtype.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
< // Define table 'message_conversations' to be updated.
< $table = new xmldb_table('message_conversations');
> // Define index modulename-instance (not unique) to be dropped form event.
> $table = new xmldb_table('event');
> $index = new xmldb_index('modulename-instance', XMLDB_INDEX_NOTUNIQUE, ['modulename', 'instance']);
< // Remove the unique 'convhash' index, change to null and add a new non unique index.
< $index = new xmldb_index('convhash', XMLDB_INDEX_UNIQUE, ['convhash']);
> // Conditionally launch drop index modulename-instance.
if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}
< $field = new xmldb_field('convhash', XMLDB_TYPE_CHAR, '40', null, null, null, null, 'name');
< $dbman->change_field_notnull($table, $field);
<
< $index = new xmldb_index('convhash', XMLDB_INDEX_NOTUNIQUE, ['convhash']);
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.20);
}
< upgrade_main_savepoint(true, 2018102200.00);
< }
> if ($oldversion < 2021052500.24) {
> // Define fields tutorial and example to be added to h5p_libraries.
> $table = new xmldb_table('h5p_libraries');
< if ($oldversion < 2018102300.02) {
< // Alter 'message_conversations' table to support groups.
< $table = new xmldb_table('message_conversations');
< $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'convhash');
> // Add tutorial field.
> $field = new xmldb_field('tutorial', XMLDB_TYPE_TEXT, null, null, null, null, null, 'metadatasettings');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< $field = new xmldb_field('itemtype', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'component');
> // Add example field.
> $field = new xmldb_field('example', XMLDB_TYPE_TEXT, null, null, null, null, null, 'tutorial');
>
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< $field = new xmldb_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'itemtype');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.24);
}
< $field = new xmldb_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'itemid');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> if ($oldversion < 2021052500.26) {
> // Delete orphaned course_modules_completion rows; these were not deleted properly
> // by remove_course_contents function.
> $DB->delete_records_select('course_modules_completion', "
> NOT EXISTS (
> SELECT 1
> FROM {course_modules} cm
> WHERE cm.id = {course_modules_completion}.coursemoduleid
> )");
> upgrade_main_savepoint(true, 2021052500.26);
}
< $field = new xmldb_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, 0, 'contextid');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> if ($oldversion < 2021052500.27) {
> // Script to fix incorrect records of "hidden" field in existing grade items.
> $sql = "SELECT cm.instance, cm.course
> FROM {course_modules} cm
> JOIN {modules} m ON m.id = cm.module
> WHERE m.name = :module AND cm.visible = :visible";
> $hidequizlist = $DB->get_recordset_sql($sql, ['module' => 'quiz', 'visible' => 0]);
>
> foreach ($hidequizlist as $hidequiz) {
> $params = [
> 'itemmodule' => 'quiz',
> 'courseid' => $hidequiz->course,
> 'iteminstance' => $hidequiz->instance,
> ];
>
> $DB->set_field('grade_items', 'hidden', 1, $params);
}
> $hidequizlist->close();
< $field = new xmldb_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'enabled');
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> upgrade_main_savepoint(true, 2021052500.27);
}
< // Add key.
< $key = new xmldb_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
< $dbman->add_key($table, $key);
> if ($oldversion < 2021052500.29) {
> // Get the current guest user which is also set as 'deleted'.
> $guestuser = $DB->get_record('user', ['id' => $CFG->siteguest, 'deleted' => 1]);
> // If there is a deleted guest user, reset the user to not be deleted and make sure the related
> // user context exists.
> if ($guestuser) {
> $guestuser->deleted = 0;
> $DB->update_record('user', $guestuser);
< // Add index.
< $index = new xmldb_index('component-itemtype-itemid-contextid', XMLDB_INDEX_NOTUNIQUE, ['component', 'itemtype',
< 'itemid', 'contextid']);
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> // Get the guest user context.
> $guestusercontext = $DB->get_record('context',
> ['contextlevel' => CONTEXT_USER, 'instanceid' => $guestuser->id]);
>
> // If the guest user context does not exist, create it.
> if (!$guestusercontext) {
> $record = new stdClass();
> $record->contextlevel = CONTEXT_USER;
> $record->instanceid = $guestuser->id;
> $record->depth = 0;
> // The path is not known before insert.
> $record->path = null;
> $record->locked = 0;
>
> $record->id = $DB->insert_record('context', $record);
>
> // Update the path.
> $record->path = '/' . SYSCONTEXTID . '/' . $record->id;
> $record->depth = substr_count($record->path, '/');
> $DB->update_record('context', $record);
> }
> }
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.29);
> }
>
> if ($oldversion < 2021052500.30) {
> // Reset analytics model output dir if it's the default value.
> $modeloutputdir = get_config('analytics', 'modeloutputdir');
> if (strcasecmp($modeloutputdir, $CFG->dataroot . DIRECTORY_SEPARATOR . 'models') == 0) {
> set_config('modeloutputdir', '', 'analytics');
}
< upgrade_main_savepoint(true, 2018102300.02);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.30);
}
< if ($oldversion < 2018102900.00) {
< // Define field predictionsprocessor to be added to analytics_models.
< $table = new xmldb_table('analytics_models');
< $field = new xmldb_field('predictionsprocessor', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'timesplitting');
> if ($oldversion < 2021052500.32) {
> // Define field downloadcontent to be added to course.
> $table = new xmldb_table('course');
> $field = new xmldb_field('downloadcontent', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'visibleold');
< // Conditionally launch add field predictionsprocessor.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018102900.00);
> upgrade_main_savepoint(true, 2021052500.32);
}
< if ($oldversion < 2018110500.01) {
< // Define fields to be added to the 'badge' table.
< $tablebadge = new xmldb_table('badge');
< $fieldversion = new xmldb_field('version', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'nextcron');
< $fieldlanguage = new xmldb_field('language', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'version');
< $fieldimageauthorname = new xmldb_field('imageauthorname', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'language');
< $fieldimageauthoremail = new xmldb_field('imageauthoremail', XMLDB_TYPE_CHAR, '255', null, null,
< null, null, 'imageauthorname');
< $fieldimageauthorurl = new xmldb_field('imageauthorurl', XMLDB_TYPE_CHAR, '255', null, null,
< null, null, 'imageauthoremail');
< $fieldimagecaption = new xmldb_field('imagecaption', XMLDB_TYPE_TEXT, null, null, null, null, null, 'imageauthorurl');
> if ($oldversion < 2021052500.33) {
> $table = new xmldb_table('badge_backpack');
< if (!$dbman->field_exists($tablebadge, $fieldversion)) {
< $dbman->add_field($tablebadge, $fieldversion);
> // There is no key_exists, so test the equivalent index.
> $oldindex = new xmldb_index('backpackcredentials', XMLDB_KEY_UNIQUE, ['userid', 'externalbackpackid']);
> if (!$dbman->index_exists($table, $oldindex)) {
> // All external backpack providers/hosts are now exclusively stored in badge_external_backpack.
> // All credentials are stored in badge_backpack and are unique per user, backpack.
> $uniquekey = new xmldb_key('backpackcredentials', XMLDB_KEY_UNIQUE, ['userid', 'externalbackpackid']);
> $dbman->add_key($table, $uniquekey);
}
< if (!$dbman->field_exists($tablebadge, $fieldlanguage)) {
< $dbman->add_field($tablebadge, $fieldlanguage);
< }
< if (!$dbman->field_exists($tablebadge, $fieldimageauthorname)) {
< $dbman->add_field($tablebadge, $fieldimageauthorname);
>
> // Drop the password field as this is moved to badge_backpack.
> $table = new xmldb_table('badge_external_backpack');
> $field = new xmldb_field('password', XMLDB_TYPE_CHAR, '50');
> if ($dbman->field_exists($table, $field)) {
> // If there is a current backpack set then copy it across to the new structure.
> if ($CFG->badges_defaultissuercontact) {
> // Get the currently used site backpacks.
> $records = $DB->get_records_select('badge_external_backpack', "password IS NOT NULL AND password != ''");
> $backpack = [
> 'userid' => '0',
> 'email' => $CFG->badges_defaultissuercontact,
> 'backpackuid' => -1
> ];
>
> // Create records corresponding to the site backpacks.
> foreach ($records as $record) {
> $backpack['password'] = $record->password;
> $backpack['externalbackpackid'] = $record->id;
> $DB->insert_record('badge_backpack', (object) $backpack);
}
< if (!$dbman->field_exists($tablebadge, $fieldimageauthoremail)) {
< $dbman->add_field($tablebadge, $fieldimageauthoremail);
}
< if (!$dbman->field_exists($tablebadge, $fieldimageauthorurl)) {
< $dbman->add_field($tablebadge, $fieldimageauthorurl);
>
> $dbman->drop_field($table, $field);
}
< if (!$dbman->field_exists($tablebadge, $fieldimagecaption)) {
< $dbman->add_field($tablebadge, $fieldimagecaption);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.33);
}
< // Define table badge_endorsement to be created.
< $table = new xmldb_table('badge_endorsement');
> if ($oldversion < 2021052500.36) {
> // Define table payment_accounts to be created.
> $table = new xmldb_table('payment_accounts');
< // Adding fields to table badge_endorsement.
> // Adding fields to table payment_accounts.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('issuername', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('issuerurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('issueremail', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('claimid', XMLDB_TYPE_CHAR, '255', null, null, null, null);
< $table->add_field('claimcomment', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('dateissued', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('archived', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< // Adding keys to table badge_endorsement.
> // Adding keys to table payment_accounts.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('endorsementbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
< // Conditionally launch create table for badge_endorsement.
> // Conditionally launch create table for payment_accounts.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table badge_related to be created.
< $table = new xmldb_table('badge_related');
> // Define table payment_gateways to be created.
> $table = new xmldb_table('payment_gateways');
< // Adding fields to table badge_related.
> // Adding fields to table payment_gateways.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('relatedbadgeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('gateway', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1');
> $table->add_field('config', XMLDB_TYPE_TEXT, null, null, null, null, null);
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< // Adding keys to table badge_related.
> // Adding keys to table payment_gateways.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('badgeid', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
< $table->add_key('relatedbadgeid', XMLDB_KEY_FOREIGN, ['relatedbadgeid'], 'badge', ['id']);
< $table->add_key('badgeid-relatedbadgeid', XMLDB_KEY_UNIQUE, ['badgeid', 'relatedbadgeid']);
> $table->add_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']);
< // Conditionally launch create table for badge_related.
> // Conditionally launch create table for payment_gateways.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table badge_competencies to be created.
< $table = new xmldb_table('badge_competencies');
> // Define table payments to be created.
> $table = new xmldb_table('payments');
< // Adding fields to table badge_competencies.
> // Adding fields to table payments.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('targetname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('targeturl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('targetdescription', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('targetframework', XMLDB_TYPE_CHAR, '255', null, null, null, null);
< $table->add_field('targetcode', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('paymentarea', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('amount', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null);
> $table->add_field('currency', XMLDB_TYPE_CHAR, '3', null, XMLDB_NOTNULL, null, null);
> $table->add_field('accountid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('gateway', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< // Adding keys to table badge_competencies.
> // Adding keys to table payments.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('competenciesbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
> $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
> $table->add_key('accountid', XMLDB_KEY_FOREIGN, ['accountid'], 'payment_accounts', ['id']);
>
> // Adding indexes to table payments.
> $table->add_index('gateway', XMLDB_INDEX_NOTUNIQUE, ['gateway']);
> $table->add_index('component-paymentarea-itemid', XMLDB_INDEX_NOTUNIQUE, ['component', 'paymentarea', 'itemid']);
< // Conditionally launch create table for badge_competencies.
> // Conditionally launch create table for payments.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018110500.01);
> upgrade_main_savepoint(true, 2021052500.36);
}
< if ($oldversion < 2018110700.01) {
< // This config setting added and then removed.
< unset_config('showcourseimages', 'moodlecourse');
> if ($oldversion < 2021052500.42) {
> // Get all lessons that are set with a completion criteria of 'requires grade' but with no grade type set.
> $sql = "SELECT cm.id
> FROM {course_modules} cm
> JOIN {lesson} l ON l.id = cm.instance
> JOIN {modules} m ON m.id = cm.module
> WHERE m.name = :name AND cm.completiongradeitemnumber IS NOT NULL AND l.grade = :grade";
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2018110700.01);
> do {
> if ($invalidconfigrations = $DB->get_records_sql($sql, ['name' => 'lesson', 'grade' => 0], 0, 1000)) {
> list($insql, $inparams) = $DB->get_in_or_equal(array_keys($invalidconfigrations), SQL_PARAMS_NAMED);
> $DB->set_field_select('course_modules', 'completiongradeitemnumber', null, "id $insql", $inparams);
}
> } while ($invalidconfigrations);
< if ($oldversion < 2018111301.00) {
< // Define field locked to be added to context.
< $table = new xmldb_table('context');
< $field = new xmldb_field('locked', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'depth');
> upgrade_main_savepoint(true, 2021052500.42);
> }
< // Conditionally launch add field locked.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> if ($oldversion < 2021052500.55) {
> $DB->delete_records_select('event', "eventtype = 'category' AND categoryid = 0 AND userid <> 0");
>
> upgrade_main_savepoint(true, 2021052500.55);
}
< // Define field locked to be added to context_temp.
< $table = new xmldb_table('context_temp');
< $field = new xmldb_field('locked', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'depth');
> if ($oldversion < 2021052500.59) {
> // Define field visibility to be added to contentbank_content.
> $table = new xmldb_table('contentbank_content');
> $field = new xmldb_field('visibility', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'contextid');
< // Conditionally launch add field locked.
> // Conditionally launch add field visibility.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Note: This change also requires a bump in is_major_upgrade_required.
< upgrade_main_savepoint(true, 2018111301.00);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.59);
}
< if ($oldversion < 2018111900.00) {
< // Update favourited courses, so they are saved in the particular course context instead of the system.
< $favouritedcourses = $DB->get_records('favourite', ['component' => 'core_course', 'itemtype' => 'courses']);
> if ($oldversion < 2021052500.60) {
< foreach ($favouritedcourses as $fc) {
< $coursecontext = \context_course::instance($fc->itemid);
< $fc->contextid = $coursecontext->id;
< $DB->update_record('favourite', $fc);
< }
> // We are going to remove the field 'hidepicture' from the groups
> // so we need to remove the pictures from those groups. But we prevent
> // the execution twice because this could be executed again when upgrading
> // to different versions.
> if ($dbman->field_exists('groups', 'hidepicture')) {
>
> $sql = "SELECT g.id, g.courseid, ctx.id AS contextid
> FROM {groups} g
> JOIN {context} ctx
> ON ctx.instanceid = g.courseid
> AND ctx.contextlevel = :contextlevel
> WHERE g.hidepicture = 1";
< upgrade_main_savepoint(true, 2018111900.00);
> // Selecting all the groups that have hide picture enabled, and organising them by context.
> $groupctx = [];
> $records = $DB->get_recordset_sql($sql, ['contextlevel' => CONTEXT_COURSE]);
> foreach ($records as $record) {
> if (!isset($groupctx[$record->contextid])) {
> $groupctx[$record->contextid] = [];
> }
> $groupctx[$record->contextid][] = $record->id;
}
> $records->close();
< if ($oldversion < 2018111900.01) {
< // Define table oauth2_access_token to be created.
< $table = new xmldb_table('oauth2_access_token');
> // Deleting the group files.
> $fs = get_file_storage();
> foreach ($groupctx as $contextid => $groupids) {
> list($in, $inparams) = $DB->get_in_or_equal($groupids, SQL_PARAMS_NAMED);
> $fs->delete_area_files_select($contextid, 'group', 'icon', $in, $inparams);
> }
< // Adding fields to table oauth2_access_token.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('token', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
< $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('scope', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> // Updating the database to remove picture from all those groups.
> $sql = "UPDATE {groups} SET picture = :pic WHERE hidepicture = :hide";
> $DB->execute($sql, ['pic' => 0, 'hide' => 1]);
> }
< // Adding keys to table oauth2_access_token.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('issueridkey', XMLDB_KEY_FOREIGN_UNIQUE, ['issuerid'], 'oauth2_issuer', ['id']);
> // Define field hidepicture to be dropped from groups.
> $table = new xmldb_table('groups');
> $field = new xmldb_field('hidepicture');
< // Conditionally launch create table for oauth2_access_token.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Conditionally launch drop field hidepicture.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2018111900.01);
> upgrade_main_savepoint(true, 2021052500.60);
}
< if ($oldversion < 2018112000.00) {
< // Update favourited conversations, so they are saved in the proper context instead of the system.
< $sql = "SELECT f.*, mc.contextid as conversationctx
< FROM {favourite} f
< JOIN {message_conversations} mc
< ON mc.id = f.itemid";
< $favouritedconversations = $DB->get_records_sql($sql);
< foreach ($favouritedconversations as $fc) {
< if (empty($fc->conversationctx)) {
< $conversationidctx = \context_user::instance($fc->userid)->id;
< } else {
< $conversationidctx = $fc->conversationctx;
< }
<
< $DB->set_field('favourite', 'contextid', $conversationidctx, ['id' => $fc->id]);
> if ($oldversion < 2021052500.64) {
> // Get all the external backpacks and update the sortorder column, to avoid repeated/wrong values. As sortorder was not
> // used since now, the id column will be the criteria to follow for re-ordering them with a valid value.
> $i = 1;
> $records = $DB->get_records('badge_external_backpack', null, 'id ASC');
> foreach ($records as $record) {
> $record->sortorder = $i++;
> $DB->update_record('badge_external_backpack', $record);
}
< upgrade_main_savepoint(true, 2018112000.00);
> upgrade_main_savepoint(true, 2021052500.64);
}
< // Automatically generated Moodle v3.6.0 release upgrade line.
< // Put any upgrade step following this.
<
< if ($oldversion < 2018120300.01) {
< // Update the FB logo URL.
< $oldurl = 'https://facebookbrand.com/wp-content/themes/fb-branding/prj-fb-branding/assets/images/fb-art.png';
< $newurl = 'https://facebookbrand.com/wp-content/uploads/2016/05/flogo_rgb_hex-brc-site-250.png';
<
< $updatesql = "UPDATE {oauth2_issuer}
< SET image = :newimage
< WHERE " . $DB->sql_compare_text('image', 100). " = :oldimage";
< $params = [
< 'newimage' => $newurl,
< 'oldimage' => $oldurl
< ];
< $DB->execute($updatesql, $params);
> if ($oldversion < 2021052500.67) {
> // The $CFG->badges_site_backpack setting has been removed because it's not required anymore. From now, the default backpack
> // will be the one with lower sortorder value.
> unset_config('badges_site_backpack');
< upgrade_main_savepoint(true, 2018120300.01);
> upgrade_main_savepoint(true, 2021052500.67);
}
< if ($oldversion < 2018120300.02) {
< // Set all individual conversations to enabled.
< $updatesql = "UPDATE {message_conversations}
< SET enabled = :enabled
< WHERE type = :type";
< $DB->execute($updatesql, ['enabled' => 1, 'type' => 1]);
> if ($oldversion < 2021052500.69) {
< upgrade_main_savepoint(true, 2018120300.02);
< }
> // Define field type to be added to oauth2_issuer.
> $table = new xmldb_table('oauth2_issuer');
> $field = new xmldb_field('servicetype', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'requireconfirmation');
< if ($oldversion < 2018120301.02) {
< upgrade_delete_orphaned_file_records();
< upgrade_main_savepoint(true, 2018120301.02);
> // Conditionally launch add field type.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< if ($oldversion < 2019011500.00) {
< // Define table task_log to be created.
< $table = new xmldb_table('task_log');
<
< // Adding fields to table task_log.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('type', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
< $table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timestart', XMLDB_TYPE_NUMBER, '20, 10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timeend', XMLDB_TYPE_NUMBER, '20, 10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('dbreads', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('dbwrites', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('result', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, null);
<
< // Adding keys to table task_log.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
<
< // Adding indexes to table task_log.
< $table->add_index('classname', XMLDB_INDEX_NOTUNIQUE, ['classname']);
< $table->add_index('timestart', XMLDB_INDEX_NOTUNIQUE, ['timestart']);
<
< // Conditionally launch create table for task_log.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Set existing values to the proper servicetype value.
> // It's not critical if the servicetype column doesn't contain the proper value for Google, Microsoft, Facebook or
> // Nextcloud services because, for now, this value is used for services using different discovery method.
> // However, let's try to upgrade it using the default value for the baseurl or image. If any of these default values
> // have been changed, the servicetype column will remain NULL.
> $recordset = $DB->get_recordset('oauth2_issuer');
> foreach ($recordset as $record) {
> if ($record->baseurl == 'https://accounts.google.com/') {
> $record->servicetype = 'google';
> $DB->update_record('oauth2_issuer', $record);
> } else if ($record->image == 'https://www.microsoft.com/favicon.ico') {
> $record->servicetype = 'microsoft';
> $DB->update_record('oauth2_issuer', $record);
> } else if ($record->image == 'https://facebookbrand.com/wp-content/uploads/2016/05/flogo_rgb_hex-brc-site-250.png') {
> $record->servicetype = 'facebook';
> $DB->update_record('oauth2_issuer', $record);
> } else if ($record->image == 'https://nextcloud.com/wp-content/themes/next/assets/img/common/favicon.png?x16328') {
> $record->servicetype = 'nextcloud';
> $DB->update_record('oauth2_issuer', $record);
}
> }
> $recordset->close();
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019011500.00);
> upgrade_main_savepoint(true, 2021052500.69);
}
< if ($oldversion < 2019011501.00) {
< // Define field output to be added to task_log.
< $table = new xmldb_table('task_log');
< $field = new xmldb_field('output', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'result');
> if ($oldversion < 2021052500.74) {
> // Define field 'showactivitydates' to be added to course table.
> $table = new xmldb_table('course');
> $field = new xmldb_field('showactivitydates', XMLDB_TYPE_INTEGER, '1', null,
> XMLDB_NOTNULL, null, '0', 'originalcourseid');
< // Conditionally launch add field output.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019011501.00);
> upgrade_main_savepoint(true, 2021052500.74);
}
< if ($oldversion < 2019011801.00) {
<
< // Define table customfield_category to be created.
< $table = new xmldb_table('customfield_category');
<
< // Adding fields to table customfield_category.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('name', XMLDB_TYPE_CHAR, '400', null, XMLDB_NOTNULL, null, null);
< $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('descriptionformat', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('area', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
<
< // Adding keys to table customfield_category.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
<
< // Adding indexes to table customfield_category.
< $table->add_index('component_area_itemid', XMLDB_INDEX_NOTUNIQUE, ['component', 'area', 'itemid', 'sortorder']);
> if ($oldversion < 2021052500.75) {
> // Define field 'showcompletionconditions' to be added to course.
> $table = new xmldb_table('course');
> $field = new xmldb_field('showcompletionconditions', XMLDB_TYPE_INTEGER, '1', null,
> XMLDB_NOTNULL, null, '1', 'completionnotify');
< // Conditionally launch create table for customfield_category.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< // Define table customfield_field to be created.
< $table = new xmldb_table('customfield_field');
<
< // Adding fields to table customfield_field.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('shortname', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('name', XMLDB_TYPE_CHAR, '400', null, XMLDB_NOTNULL, null, null);
< $table->add_field('type', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('descriptionformat', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('categoryid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
<
< // Adding keys to table customfield_field.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('categoryid', XMLDB_KEY_FOREIGN, ['categoryid'], 'customfield_category', ['id']);
<
< // Adding indexes to table customfield_field.
< $table->add_index('categoryid_sortorder', XMLDB_INDEX_NOTUNIQUE, ['categoryid', 'sortorder']);
<
< // Conditionally launch create table for customfield_field.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.75);
}
< // Define table customfield_data to be created.
< $table = new xmldb_table('customfield_data');
<
< // Adding fields to table customfield_data.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('fieldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('instanceid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('intvalue', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('decvalue', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null);
< $table->add_field('shortcharvalue', XMLDB_TYPE_CHAR, '255', null, null, null, null);
< $table->add_field('charvalue', XMLDB_TYPE_CHAR, '1333', null, null, null, null);
< $table->add_field('value', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
< $table->add_field('valueformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> if ($oldversion < 2021052500.78) {
< // Adding keys to table customfield_data.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('fieldid', XMLDB_KEY_FOREIGN, ['fieldid'], 'customfield_field', ['id']);
< $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
<
< // Adding indexes to table customfield_data.
< $table->add_index('instanceid-fieldid', XMLDB_INDEX_UNIQUE, ['instanceid', 'fieldid']);
< $table->add_index('fieldid-intvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'intvalue']);
< $table->add_index('fieldid-shortcharvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'shortcharvalue']);
< $table->add_index('fieldid-decvalue', XMLDB_INDEX_NOTUNIQUE, ['fieldid', 'decvalue']);
> // Define field enabled to be added to h5p_libraries.
> $table = new xmldb_table('h5p_libraries');
> $field = new xmldb_field('enabled', XMLDB_TYPE_INTEGER, '1', null, null, null, '1', 'example');
< // Conditionally launch create table for customfield_data.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Conditionally launch add field enabled.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< upgrade_main_savepoint(true, 2019011801.00);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.78);
}
< if ($oldversion < 2019011801.01) {
> if ($oldversion < 2021052500.83) {
< // Delete all files that have been used in sections, which are already deleted.
< $sql = "SELECT DISTINCT f.itemid as sectionid, f.contextid
< FROM {files} f
< LEFT JOIN {course_sections} s ON f.itemid = s.id
< WHERE f.component = :component AND f.filearea = :filearea AND s.id IS NULL ";
> // Define field loginpagename to be added to oauth2_issuer.
> $table = new xmldb_table('oauth2_issuer');
> $field = new xmldb_field('loginpagename', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'servicetype');
< $params = [
< 'component' => 'course',
< 'filearea' => 'section'
< ];
<
< $stalefiles = $DB->get_recordset_sql($sql, $params);
<
< $fs = get_file_storage();
< foreach ($stalefiles as $stalefile) {
< $fs->delete_area_files($stalefile->contextid, 'course', 'section', $stalefile->sectionid);
> // Conditionally launch add field loginpagename.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< $stalefiles->close();
< upgrade_main_savepoint(true, 2019011801.01);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.83);
}
< if ($oldversion < 2019011801.02) {
< // Add index 'useridfrom' to the table 'notifications'.
< $table = new xmldb_table('notifications');
< $index = new xmldb_index('useridfrom', XMLDB_INDEX_NOTUNIQUE, ['useridfrom']);
> if ($oldversion < 2021052500.84) {
> require_once($CFG->dirroot . '/user/profile/field/social/upgradelib.php');
> $table = new xmldb_table('user');
> $tablecolumns = ['icq', 'skype', 'aim', 'yahoo', 'msn', 'url'];
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> foreach ($tablecolumns as $column) {
> $field = new xmldb_field($column);
> if ($dbman->field_exists($table, $field)) {
> user_profile_social_moveto_profilefield($column);
> $dbman->drop_field($table, $field);
}
<
< upgrade_main_savepoint(true, 2019011801.02);
}
< if ($oldversion < 2019011801.03) {
< // Remove duplicate entries from group memberships.
< // Find records with multiple userid/groupid combinations and find the highest ID.
< // Later we will remove all those entries.
< $sql = "
< SELECT MIN(id) as minid, userid, groupid
< FROM {groups_members}
< GROUP BY userid, groupid
< HAVING COUNT(id) > 1";
< if ($duplicatedrows = $DB->get_recordset_sql($sql)) {
< foreach ($duplicatedrows as $row) {
< $DB->delete_records_select('groups_members',
< 'userid = :userid AND groupid = :groupid AND id <> :minid', (array)$row);
< }
< }
< $duplicatedrows->close();
> // Update all module availability if it relies on the old user fields.
> user_profile_social_update_module_availability();
>
> // Remove field mapping for oauth2.
> $DB->delete_records('oauth2_user_field_mapping', array('internalfield' => 'url'));
< // Define key useridgroupid (unique) to be added to group_members.
< $table = new xmldb_table('groups_members');
< $key = new xmldb_key('useridgroupid', XMLDB_KEY_UNIQUE, array('userid', 'groupid'));
< // Launch add key useridgroupid.
< $dbman->add_key($table, $key);
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019011801.03);
> upgrade_main_savepoint(true, 2021052500.84);
}
< if ($oldversion < 2019021500.01) {
< $insights = $DB->get_record('message_providers', ['component' => 'moodle', 'name' => 'insights']);
< if (!empty($insights)) {
< $insights->capability = null;
< $DB->update_record('message_providers', $insights);
< }
< upgrade_main_savepoint(true, 2019021500.01);
< }
> if ($oldversion < 2021052500.85) {
> require_once($CFG->libdir . '/db/upgradelib.php');
< if ($oldversion < 2019021500.02) {
< // Default 'off' for existing sites as this is the behaviour they had earlier.
< set_config('messagingdefaultpressenter', false);
> // Check if this site has executed the problematic upgrade steps.
> $needsfixing = upgrade_calendar_site_status(false);
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019021500.02);
< }
> // Only queue the task if this site has been affected by the problematic upgrade step.
> if ($needsfixing) {
< if ($oldversion < 2019030100.01) {
< // Create adhoc task to delete renamed My Course search area (ID core_course-mycourse).
> // Create adhoc task to search and recover orphaned calendar events.
$record = new \stdClass();
< $record->classname = '\core\task\clean_up_deleted_search_area_task';
< $record->component = 'core';
> $record->classname = '\core\task\calendar_fix_orphaned_events';
// Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
$nextruntime = time() - 1;
$record->nextruntime = $nextruntime;
< $record->customdata = json_encode('core_course-mycourse');
<
$DB->insert_record('task_adhoc', $record);
> }
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019030100.01);
> upgrade_main_savepoint(true, 2021052500.85);
}
< if ($oldversion < 2019030700.01) {
<
< // Define field evaluationmode to be added to analytics_models_log.
< $table = new xmldb_table('analytics_models_log');
< $field = new xmldb_field('evaluationmode', XMLDB_TYPE_CHAR, '50', null, null, null,
< null, 'version');
> if ($oldversion < 2021052500.87) {
> // Changing the default of field showcompletionconditions on table course to 0.
> $table = new xmldb_table('course');
> $field = new xmldb_field('showcompletionconditions', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'showactivitydates');
< // Conditionally launch add field evaluationmode.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Launch change of nullability for field showcompletionconditions.
> $dbman->change_field_notnull($table, $field);
< $updatesql = "UPDATE {analytics_models_log}
< SET evaluationmode = 'configuration'";
< $DB->execute($updatesql, []);
> // Launch change of default for field showcompletionconditions.
> $dbman->change_field_default($table, $field);
< // Changing nullability of field evaluationmode on table block_instances to not null.
< $field = new xmldb_field('evaluationmode', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL,
< null, null, 'version');
> // Set showcompletionconditions to null for courses which don't track completion.
> $sql = "UPDATE {course}
> SET showcompletionconditions = null
> WHERE enablecompletion <> 1";
> $DB->execute($sql);
< // Launch change of nullability for field evaluationmode.
< $dbman->change_field_notnull($table, $field);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021052500.87);
}
> if ($oldversion < 2021052500.90) {
// Main savepoint reached.
> // Remove usemodchooser user preference for every user.
upgrade_main_savepoint(true, 2019030700.01);
> $DB->delete_records('user_preferences', ['name' => 'usemodchooser']);
}
>
< upgrade_main_savepoint(true, 2019030700.01);
> upgrade_main_savepoint(true, 2021052500.90);
< if ($oldversion < 2019030800.00) {
< // Define table 'message_conversation_actions' to be created.
< // Note - I would have preferred 'message_conversation_user_actions' but due to Oracle we can't. Boo.
< $table = new xmldb_table('message_conversation_actions');
> if ($oldversion < 2021060200.00) {
< // Adding fields to table 'message_conversation_actions'.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('conversationid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> // Define index name (not unique) to be added to user_preferences.
> $table = new xmldb_table('user_preferences');
> $index = new xmldb_index('name', XMLDB_INDEX_NOTUNIQUE, ['name']);
< // Adding keys to table 'message_conversation_actions'.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< $table->add_key('conversationid', XMLDB_KEY_FOREIGN, ['conversationid'], 'message_conversations', ['id']);
<
< // Conditionally launch create table for 'message_conversation_actions'.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Conditionally launch add index name.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019030800.00);
> upgrade_main_savepoint(true, 2021060200.00);
}
< if ($oldversion < 2019030800.02) {
< // Remove any conversations and their members associated with non-existent groups.
< $sql = "SELECT mc.id
< FROM {message_conversations} mc
< LEFT JOIN {groups} g
< ON mc.itemid = g.id
< WHERE mc.component = :component
< AND mc.itemtype = :itemtype
< AND g.id is NULL";
< $conversations = $DB->get_records_sql($sql, ['component' => 'core_group', 'itemtype' => 'groups']);
> if ($oldversion < 2021060900.00) {
> // Update the externalfield to be larger.
> $table = new xmldb_table('oauth2_user_field_mapping');
> $field = new xmldb_field('externalfield', XMLDB_TYPE_CHAR, '500', null, XMLDB_NOTNULL, false, null, 'issuerid');
> $dbman->change_field_type($table, $field);
< if ($conversations) {
< $conversationids = array_keys($conversations);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021060900.00);
> }
< $DB->delete_records_list('message_conversations', 'id', $conversationids);
< $DB->delete_records_list('message_conversation_members', 'conversationid', $conversationids);
< $DB->delete_records_list('message_conversation_actions', 'conversationid', $conversationids);
> if ($oldversion < 2021072800.01) {
> // Define table reportbuilder_report to be created.
> $table = new xmldb_table('reportbuilder_report');
< // Now, go through each conversation and delete any messages and related message actions.
< foreach ($conversationids as $conversationid) {
< if ($messages = $DB->get_records('messages', ['conversationid' => $conversationid])) {
< $messageids = array_keys($messages);
> // Adding fields to table reportbuilder_report.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('source', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('type', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('area', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< // Delete the actions.
< list($insql, $inparams) = $DB->get_in_or_equal($messageids);
< $DB->delete_records_select('message_user_actions', "messageid $insql", $inparams);
> // Adding keys to table reportbuilder_report.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
> $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
< // Delete the messages.
< $DB->delete_records('messages', ['conversationid' => $conversationid]);
> // Conditionally launch create table for reportbuilder_report.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
}
>
}
> // Main savepoint reached.
}
> upgrade_main_savepoint(true, 2021072800.01);
>
// Main savepoint reached.
> if ($oldversion < 2021090200.01) {
upgrade_main_savepoint(true, 2019030800.02);
> // Remove qformat_webct (unless it has manually been added back).
}
> if (!file_exists($CFG->dirroot . '/question/format/webct/format.php')) {
> unset_all_config_for_plugin('qformat_webct');
< upgrade_main_savepoint(true, 2019030800.02);
> upgrade_main_savepoint(true, 2021090200.01);
< if ($oldversion < 2019030800.03) {
> if ($oldversion < 2021091100.01) {
> // If message_jabber is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/message/output/jabber/message_output_jabber.php')) {
> // Remove Jabber from the notification plugins list.
> $DB->delete_records('message_processors', ['name' => 'jabber']);
< // Add missing indicators to course_dropout.
> // Remove user preference settings.
> $DB->delete_records('user_preferences', ['name' => 'message_processor_jabber_jabberid']);
> $sql = 'SELECT *
> FROM {user_preferences} up
> WHERE ' . $DB->sql_like('up.name', ':name', false, false) . ' AND ' .
> $DB->sql_like('up.value', ':value', false, false);
$params = [
< 'target' => '\core\analytics\target\course_dropout',
< 'trained' => 0,
< 'enabled' => 0,
< ];
< $models = $DB->get_records('analytics_models', $params);
< foreach ($models as $model) {
< $indicators = json_decode($model->indicators);
<
< $potentiallymissingindicators = [
< '\core_course\analytics\indicator\completion_enabled',
< '\core_course\analytics\indicator\potential_cognitive_depth',
< '\core_course\analytics\indicator\potential_social_breadth',
< '\core\analytics\indicator\any_access_after_end',
< '\core\analytics\indicator\any_access_before_start',
< '\core\analytics\indicator\any_write_action_in_course',
< '\core\analytics\indicator\read_actions'
> 'name' => 'message_provider_%',
> 'value' => '%jabber%',
];
<
< $missing = false;
< foreach ($potentiallymissingindicators as $potentiallymissingindicator) {
< if (!in_array($potentiallymissingindicator, $indicators)) {
< // Add the missing indicator to sites upgraded before 2017072000.02.
< $indicators[] = $potentiallymissingindicator;
< $missing = true;
< }
> $jabbersettings = $DB->get_recordset_sql($sql, $params);
> foreach ($jabbersettings as $jabbersetting) {
> // Remove 'jabber' from the value.
> $jabbersetting->value = implode(',', array_diff(explode(',', $jabbersetting->value), ['jabber']));
> $DB->update_record('user_preferences', $jabbersetting);
}
> $jabbersettings->close();
< if ($missing) {
< $model->indicators = json_encode($indicators);
< $model->version = time();
< $model->timemodified = time();
< $DB->update_record('analytics_models', $model);
< }
> // Clean config settings.
> unset_config('jabberhost');
> unset_config('jabberserver');
> unset_config('jabberusername');
> unset_config('jabberpassword');
> unset_config('jabberport');
>
> // Remove default notification preferences.
> $like = $DB->sql_like('name', '?', true, true, false, '|');
> $params = [$DB->sql_like_escape('jabber_provider_', '|') . '%'];
> $DB->delete_records_select('config_plugins', $like, $params);
>
> // Clean config config settings.
> unset_all_config_for_plugin('message_jabber');
}
< // Add missing indicators to no_teaching.
< $params = [
< 'target' => '\core\analytics\target\no_teaching',
< ];
< $models = $DB->get_records('analytics_models', $params);
< foreach ($models as $model) {
< $indicators = json_decode($model->indicators);
< if (!in_array('\core_course\analytics\indicator\no_student', $indicators)) {
< // Add the missing indicator to sites upgraded before 2017072000.02.
> upgrade_main_savepoint(true, 2021091100.01);
> }
< $indicators[] = '\core_course\analytics\indicator\no_student';
> if ($oldversion < 2021091100.02) {
> // Set the description field to HTML format for the Default course category.
> $category = $DB->get_record('course_categories', ['id' => 1]);
< $model->indicators = json_encode($indicators);
< $model->version = time();
< $model->timemodified = time();
< $DB->update_record('analytics_models', $model);
> if (!empty($category) && $category->descriptionformat == FORMAT_MOODLE) {
> // Format should be changed only if it's still set to FORMAT_MOODLE.
> if (!is_null($category->description)) {
> // If description is not empty, format the content to HTML.
> $category->description = format_text($category->description, FORMAT_MOODLE);
}
> $category->descriptionformat = FORMAT_HTML;
}
> $DB->update_record('course_categories', $category);
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019030800.03);
> upgrade_main_savepoint(true, 2021091100.02);
}
< if ($oldversion < 2019031500.01) {
<
< $defaulttimesplittings = get_config('analytics', 'timesplittings');
< if ($defaulttimesplittings !== false) {
< set_config('defaulttimesplittingsevaluation', $defaulttimesplittings, 'analytics');
< unset_config('timesplittings', 'analytics');
< }
> if ($oldversion < 2021091700.01) {
> // Default 'off' for existing sites as this is the behaviour they had earlier.
> set_config('enroladminnewcourse', false);
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019031500.01);
> upgrade_main_savepoint(true, 2021091700.01);
}
< if ($oldversion < 2019032200.02) {
< // The no_teaching model might have been marked as not-trained by mistake (static models are always trained).
< $DB->set_field('analytics_models', 'trained', 1, ['target' => '\core\analytics\target\no_teaching']);
< upgrade_main_savepoint(true, 2019032200.02);
> if ($oldversion < 2021091700.02) {
> // If portfolio_picasa is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/portfolio/picasa/version.php')) {
> $instance = $DB->get_record('portfolio_instance', ['plugin' => 'picasa']);
> if (!empty($instance)) {
> // Remove all records from portfolio_instance_config.
> $DB->delete_records('portfolio_instance_config', ['instance' => $instance->id]);
> // Remove all records from portfolio_instance_user.
> $DB->delete_records('portfolio_instance_user', ['instance' => $instance->id]);
> // Remove all records from portfolio_log.
> $DB->delete_records('portfolio_log', ['portfolio' => $instance->id]);
> // Remove all records from portfolio_tempdata.
> $DB->delete_records('portfolio_tempdata', ['instance' => $instance->id]);
> // Remove the record from the portfolio_instance table.
> $DB->delete_records('portfolio_instance', ['id' => $instance->id]);
}
< if ($oldversion < 2019032900.00) {
> // Clean config.
> unset_all_config_for_plugin('portfolio_picasa');
> }
< // Define table badge_competencies to be renamed to badge_alignment.
< $table = new xmldb_table('badge_competencies');
> upgrade_main_savepoint(true, 2021091700.02);
> }
< // Be careful if this step gets run twice.
< if ($dbman->table_exists($table)) {
< $key = new xmldb_key('competenciesbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
> if ($oldversion < 2021091700.03) {
> // If repository_picasa is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/repository/picasa/version.php')) {
> $instance = $DB->get_record('repository', ['type' => 'picasa']);
> if (!empty($instance)) {
> // Remove all records from repository_instance_config table.
> $DB->delete_records('repository_instance_config', ['instanceid' => $instance->id]);
> // Remove all records from repository_instances table.
> $DB->delete_records('repository_instances', ['typeid' => $instance->id]);
> // Remove the record from the repository table.
> $DB->delete_records('repository', ['id' => $instance->id]);
> }
< // Launch drop key competenciesbadge.
< $dbman->drop_key($table, $key);
> // Clean config.
> unset_all_config_for_plugin('picasa');
< $key = new xmldb_key('alignmentsbadge', XMLDB_KEY_FOREIGN, ['badgeid'], 'badge', ['id']);
> // Remove orphaned files.
> upgrade_delete_orphaned_file_records();
> }
< // Launch add key alignmentsbadge.
< $dbman->add_key($table, $key);
> upgrade_main_savepoint(true, 2021091700.03);
> }
< // Launch rename table for badge_alignment.
< $dbman->rename_table($table, 'badge_alignment');
> if ($oldversion < 2021091700.04) {
> // Remove media_swf (unless it has manually been added back).
> if (!file_exists($CFG->dirroot . '/media/player/swf/classes/plugin.php')) {
> unset_all_config_for_plugin('media_swf');
}
< upgrade_main_savepoint(true, 2019032900.00);
> upgrade_main_savepoint(true, 2021091700.04);
}
< if ($oldversion < 2019032900.01) {
< $sql = "UPDATE {task_scheduled}
< SET classname = ?
< WHERE component = ?
< AND classname = ?";
< $DB->execute($sql, [
< '\core\task\question_preview_cleanup_task',
< 'moodle',
< '\core\task\question_cron_task'
< ]);
> if ($oldversion < 2021092400.01) {
> // If tool_health is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/admin/tool/health/version.php')) {
> // Clean config.
> unset_all_config_for_plugin('tool_health');
> }
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019032900.01);
> upgrade_main_savepoint(true, 2021092400.01);
}
< if ($oldversion < 2019040200.01) {
< // Removing the themes BSB, Clean, More from core.
< // If these theme wish to be retained empty this array before upgrade.
< $themes = array('theme_bootstrapbase' => 'bootstrapbase',
< 'theme_clean' => 'clean', 'theme_more' => 'more');
< foreach ($themes as $key => $theme) {
< if (check_dir_exists($CFG->dirroot . '/theme/' . $theme, false)) {
< // Ignore the themes that have been re-downloaded.
< unset($themes[$key]);
> if ($oldversion < 2021092400.03) {
> // Remove repository_picasa configuration (unless it has manually been added back).
> if (!file_exists($CFG->dirroot . '/repository/picasa/version.php')) {
> unset_all_config_for_plugin('repository_picasa');
}
< }
< // Check we actually have themes to remove.
< if (count($themes) > 0) {
< list($insql, $inparams) = $DB->get_in_or_equal($themes, SQL_PARAMS_NAMED);
<
< // Replace the theme usage.
< $DB->set_field_select('course', 'theme', 'classic', "theme $insql", $inparams);
< $DB->set_field_select('course_categories', 'theme', 'classic', "theme $insql", $inparams);
< $DB->set_field_select('user', 'theme', 'classic', "theme $insql", $inparams);
< $DB->set_field_select('mnet_host', 'theme', 'classic', "theme $insql", $inparams);
< $DB->set_field_select('cohort', 'theme', 'classic', "theme $insql", $inparams);
< // Replace the theme configs.
< if (in_array(get_config('core', 'theme'), $themes)) {
< set_config('theme', 'classic');
> upgrade_main_savepoint(true, 2021092400.03);
}
< if (in_array(get_config('core', 'thememobile'), $themes)) {
< set_config('thememobile', 'classic');
< }
< if (in_array(get_config('core', 'themelegacy'), $themes)) {
< set_config('themelegacy', 'classic');
< }
< if (in_array(get_config('core', 'themetablet'), $themes)) {
< set_config('themetablet', 'classic');
>
> if ($oldversion < 2021100300.01) {
> // Remove repository_skydrive (unless it has manually been added back).
> if (!file_exists($CFG->dirroot . '/repository/skydrive/lib.php')) {
> unset_all_config_for_plugin('repository_skydrive');
}
< // Hacky emulation of plugin uninstallation.
< foreach ($themes as $key => $theme) {
< unset_all_config_for_plugin($key);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021100300.01);
}
>
}
> if ($oldversion < 2021100300.02) {
> // Remove filter_censor (unless it has manually been added back).
// Main savepoint reached.
> if (!file_exists($CFG->dirroot . '/filter/censor/filter.php')) {
upgrade_main_savepoint(true, 2019040200.01);
> unset_all_config_for_plugin('filter_censor');
< upgrade_main_savepoint(true, 2019040200.01);
> upgrade_main_savepoint(true, 2021100300.02);
< if ($oldversion < 2019040600.02) {
> if ($oldversion < 2021100600.01) {
> // Remove qformat_examview (unless it has manually been added back).
> if (!file_exists($CFG->dirroot . '/question/format/examview/format.php')) {
> unset_all_config_for_plugin('qformat_examview');
> }
< // Define key fileid (foreign) to be dropped form analytics_train_samples.
< $table = new xmldb_table('analytics_train_samples');
< $key = new xmldb_key('fileid', XMLDB_KEY_FOREIGN, ['fileid'], 'files', ['id']);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021100600.01);
> }
< // Launch drop key fileid.
< $dbman->drop_key($table, $key);
> if ($oldversion < 2021100600.02) {
> $table = new xmldb_table('course_completion_defaults');
< // Define field fileid to be dropped from analytics_train_samples.
< $table = new xmldb_table('analytics_train_samples');
< $field = new xmldb_field('fileid');
> // Adding fields to table course_completion_defaults.
> $field = new xmldb_field('completionpassgrade', XMLDB_TYPE_INTEGER, '1', null,
> XMLDB_NOTNULL, null, '0', 'completionusegrade');
< // Conditionally launch drop field fileid.
< if ($dbman->field_exists($table, $field)) {
< $dbman->drop_field($table, $field);
> // Conditionally launch add field for course_completion_defaults.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019040600.02);
> upgrade_main_savepoint(true, 2021100600.02);
}
< if ($oldversion < 2019040600.04) {
< // Define field and index to be added to backup_controllers.
< $table = new xmldb_table('backup_controllers');
< $field = new xmldb_field('progress', XMLDB_TYPE_NUMBER, '15, 14', null, XMLDB_NOTNULL, null, '0', 'timemodified');
< $index = new xmldb_index('useritem_ix', XMLDB_INDEX_NOTUNIQUE, ['userid', 'itemid']);
< // Conditionally launch add field progress.
> if ($oldversion < 2021100600.03) {
> $table = new xmldb_table('course_modules');
>
> // Adding new fields to table course_module table.
> $field = new xmldb_field('completionpassgrade', XMLDB_TYPE_INTEGER, '1', null,
> XMLDB_NOTNULL, null, '0', 'completionexpected');
> // Conditionally launch create table for course_completion_defaults.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Conditionally launch add index useritem_ix.
>
> upgrade_main_savepoint(true, 2021100600.03);
> }
>
> if ($oldversion < 2021100600.04) {
> // Define index itemtype-mod-inst-course (not unique) to be added to grade_items.
> $table = new xmldb_table('grade_items');
> $index = new xmldb_index('itemtype-mod-inst-course', XMLDB_INDEX_NOTUNIQUE,
> ['itemtype', 'itemmodule', 'iteminstance', 'courseid']);
>
> // Conditionally launch add index itemtype-mod-inst-course.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019040600.04);
> upgrade_main_savepoint(true, 2021100600.04);
}
< if ($oldversion < 2019041000.02) {
<
< // Define field fullmessagetrust to be added to messages.
< $table = new xmldb_table('messages');
< $field = new xmldb_field('fullmessagetrust', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'timecreated');
> if ($oldversion < 2021101900.01) {
> $table = new xmldb_table('reportbuilder_report');
< // Conditionally launch add field fullmessagetrust.
> // Define field name to be added to reportbuilder_report.
> $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'id');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019041000.02);
< }
<
< if ($oldversion < 2019041300.01) {
< // Add the field 'name' to the 'analytics_models' table.
< $table = new xmldb_table('analytics_models');
< $field = new xmldb_field('name', XMLDB_TYPE_CHAR, '1333', null, null, null, null, 'trained');
<
> // Define field conditiondata to be added to reportbuilder_report.
> $field = new xmldb_field('conditiondata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'type');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019041300.01);
< }
< if ($oldversion < 2019041800.01) {
< // STEP 1. For the existing and migrated self-conversations, set the type to the new MESSAGE_CONVERSATION_TYPE_SELF, update
< // the convhash and star them.
< $sql = "SELECT mcm.conversationid, mcm.userid, MAX(mcm.id) as maxid
< FROM {message_conversation_members} mcm
< INNER JOIN {user} u ON mcm.userid = u.id
< WHERE u.deleted = 0
< GROUP BY mcm.conversationid, mcm.userid
< HAVING COUNT(*) > 1";
< $selfconversationsrs = $DB->get_recordset_sql($sql);
< $maxids = [];
< foreach ($selfconversationsrs as $selfconversation) {
< $DB->update_record('message_conversations',
< ['id' => $selfconversation->conversationid,
< 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
< 'convhash' => \core_message\helper::get_conversation_hash([$selfconversation->userid])
< ]
< );
> // Define table reportbuilder_column to be created.
> $table = new xmldb_table('reportbuilder_column');
< // Star the existing self-conversation.
< $favouriterecord = new \stdClass();
< $favouriterecord->component = 'core_message';
< $favouriterecord->itemtype = 'message_conversations';
< $favouriterecord->itemid = $selfconversation->conversationid;
< $userctx = \context_user::instance($selfconversation->userid);
< $favouriterecord->contextid = $userctx->id;
< $favouriterecord->userid = $selfconversation->userid;
< if (!$DB->record_exists('favourite', (array)$favouriterecord)) {
< $favouriterecord->timecreated = time();
< $favouriterecord->timemodified = $favouriterecord->timecreated;
< $DB->insert_record('favourite', $favouriterecord);
< }
<
< // Set the self-conversation member with maxid to remove it later.
< $maxids[] = $selfconversation->maxid;
< }
< $selfconversationsrs->close();
<
< // Remove the repeated member with the higher id for all the existing self-conversations.
< if (!empty($maxids)) {
< list($insql, $inparams) = $DB->get_in_or_equal($maxids);
< $DB->delete_records_select('message_conversation_members', "id $insql", $inparams);
< }
<
< // STEP 2. Migrate existing self-conversation relying on old message tables, setting the type to the new
< // MESSAGE_CONVERSATION_TYPE_SELF and the convhash to the proper one. Star them also.
<
< // On the messaging legacy tables, self-conversations are only present in the 'message_read' table, so we don't need to
< // check the content in the 'message' table.
< $sql = "SELECT mr.*
< FROM {message_read} mr
< INNER JOIN {user} u ON mr.useridfrom = u.id
< WHERE mr.useridfrom = mr.useridto AND mr.notification = 0 AND u.deleted = 0";
< $legacyselfmessagesrs = $DB->get_recordset_sql($sql);
< foreach ($legacyselfmessagesrs as $message) {
< // Get the self-conversation or create and star it if doesn't exist.
< $conditions = [
< 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF,
< 'convhash' => \core_message\helper::get_conversation_hash([$message->useridfrom])
< ];
< $selfconversation = $DB->get_record('message_conversations', $conditions);
< if (empty($selfconversation)) {
< // Create the self-conversation.
< $selfconversation = new \stdClass();
< $selfconversation->type = \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF;
< $selfconversation->convhash = \core_message\helper::get_conversation_hash([$message->useridfrom]);
< $selfconversation->enabled = 1;
< $selfconversation->timecreated = time();
< $selfconversation->timemodified = $selfconversation->timecreated;
> // Adding fields to table reportbuilder_column.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('uniqueidentifier', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('aggregation', XMLDB_TYPE_CHAR, '32', null, null, null, null);
> $table->add_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('columnorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('sortenabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('sortdirection', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
> $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
>
> // Adding keys to table reportbuilder_column.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']);
> $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
>
> // Conditionally launch create table for reportbuilder_column.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
> }
< $selfconversation->id = $DB->insert_record('message_conversations', $selfconversation);
> // Define table reportbuilder_filter to be created.
> $table = new xmldb_table('reportbuilder_filter');
< // Add user to this self-conversation.
< $member = new \stdClass();
< $member->conversationid = $selfconversation->id;
< $member->userid = $message->useridfrom;
< $member->timecreated = time();
> // Adding fields to table reportbuilder_filter.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('uniqueidentifier', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('iscondition', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('filterorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $member->id = $DB->insert_record('message_conversation_members', $member);
> // Adding keys to table reportbuilder_filter.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']);
> $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
< // Star the self-conversation.
< $favouriterecord = new \stdClass();
< $favouriterecord->component = 'core_message';
< $favouriterecord->itemtype = 'message_conversations';
< $favouriterecord->itemid = $selfconversation->id;
< $userctx = \context_user::instance($message->useridfrom);
< $favouriterecord->contextid = $userctx->id;
< $favouriterecord->userid = $message->useridfrom;
< if (!$DB->record_exists('favourite', (array)$favouriterecord)) {
< $favouriterecord->timecreated = time();
< $favouriterecord->timemodified = $favouriterecord->timecreated;
< $DB->insert_record('favourite', $favouriterecord);
> // Conditionally launch create table for reportbuilder_filter.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
}
>
}
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021101900.01);
< // Create the object we will be inserting into the database.
< $tabledata = new \stdClass();
< $tabledata->useridfrom = $message->useridfrom;
< $tabledata->conversationid = $selfconversation->id;
< $tabledata->subject = $message->subject;
< $tabledata->fullmessage = $message->fullmessage;
< $tabledata->fullmessageformat = $message->fullmessageformat ?? FORMAT_MOODLE;
< $tabledata->fullmessagehtml = $message->fullmessagehtml;
< $tabledata->smallmessage = $message->smallmessage;
< $tabledata->timecreated = $message->timecreated;
> if ($oldversion < 2021102600.01) {
> // Remove block_quiz_results (unless it has manually been added back).
> if (!file_exists($CFG->dirroot . '/blocks/quiz_result/block_quiz_results.php')) {
> // Delete instances.
> $instances = $DB->get_records_list('block_instances', 'blockname', ['quiz_results']);
> $instanceids = array_keys($instances);
< $messageid = $DB->insert_record('messages', $tabledata);
> if (!empty($instanceids)) {
> blocks_delete_instances($instanceids);
> }
< // Check if we need to mark this message as deleted (self-conversations add this information on the
< // timeuserfromdeleted field.
< if ($message->timeuserfromdeleted) {
< $mua = new \stdClass();
< $mua->userid = $message->useridfrom;
< $mua->messageid = $messageid;
< $mua->action = \core_message\api::MESSAGE_ACTION_DELETED;
< $mua->timecreated = $message->timeuserfromdeleted;
> // Delete the block from the block table.
> $DB->delete_records('block', array('name' => 'quiz_results'));
< $DB->insert_record('message_user_actions', $mua);
> // Remove capabilities.
> capabilities_cleanup('block_quiz_results');
> // Clean config.
> unset_all_config_for_plugin('block_quiz_results');
>
> // Remove Moodle-level quiz_results based capabilities.
> $capabilitiestoberemoved = ['block/quiz_results:addinstance'];
> // Delete any role_capabilities for the old roles.
> $DB->delete_records_list('role_capabilities', 'capability', $capabilitiestoberemoved);
> // Delete the capability itself.
> $DB->delete_records_list('capabilities', 'name', $capabilitiestoberemoved);
}
< // Mark this message as read.
< $mua = new \stdClass();
< $mua->userid = $message->useridto;
< $mua->messageid = $messageid;
< $mua->action = \core_message\api::MESSAGE_ACTION_READ;
< $mua->timecreated = $message->timeread;
> upgrade_main_savepoint(true, 2021102600.01);
> }
< $DB->insert_record('message_user_actions', $mua);
> if ($oldversion < 2021102900.02) {
> // If portfolio_boxnet is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/portfolio/boxnet/version.php')) {
> $instance = $DB->get_record('portfolio_instance', ['plugin' => 'boxnet']);
> if (!empty($instance)) {
> // Remove all records from portfolio_instance_config.
> $DB->delete_records('portfolio_instance_config', ['instance' => $instance->id]);
> // Remove all records from portfolio_instance_user.
> $DB->delete_records('portfolio_instance_user', ['instance' => $instance->id]);
> // Remove all records from portfolio_log.
> $DB->delete_records('portfolio_log', ['portfolio' => $instance->id]);
> // Remove all records from portfolio_tempdata.
> $DB->delete_records('portfolio_tempdata', ['instance' => $instance->id]);
> // Remove the record from the portfolio_instance table.
> $DB->delete_records('portfolio_instance', ['id' => $instance->id]);
> }
< // The self-conversation message has been migrated. Delete the record from the legacy table as soon as possible
< // to avoid migrate it twice.
< $DB->delete_records('message_read', ['id' => $message->id]);
> // Clean config.
> unset_all_config_for_plugin('portfolio_boxnet');
}
< $legacyselfmessagesrs->close();
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019041800.01);
> // If repository_boxnet is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/repository/boxnet/version.php')) {
> $instance = $DB->get_record('repository', ['type' => 'boxnet']);
> if (!empty($instance)) {
> // Remove all records from repository_instance_config table.
> $DB->delete_records('repository_instance_config', ['instanceid' => $instance->id]);
> // Remove all records from repository_instances table.
> $DB->delete_records('repository_instances', ['typeid' => $instance->id]);
> // Remove the record from the repository table.
> $DB->delete_records('repository', ['id' => $instance->id]);
}
< if ($oldversion < 2019042200.01) {
> // Clean config.
> unset_all_config_for_plugin('repository_boxnet');
< // Define table role_sortorder to be dropped.
< $table = new xmldb_table('role_sortorder');
> // The boxnet repository plugin stores some config in 'boxnet' incorrectly.
> unset_all_config_for_plugin('boxnet');
< // Conditionally launch drop table for role_sortorder.
< if ($dbman->table_exists($table)) {
< $dbman->drop_table($table);
> // Remove orphaned files.
> upgrade_delete_orphaned_file_records();
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019042200.01);
> upgrade_main_savepoint(true, 2021102900.02);
}
< if ($oldversion < 2019042200.02) {
> if ($oldversion < 2021110100.00) {
< // Let's update all (old core) targets to their new (core_course) locations.
< $targets = [
< '\core\analytics\target\course_competencies' => '\core_course\analytics\target\course_competencies',
< '\core\analytics\target\course_completion' => '\core_course\analytics\target\course_completion',
< '\core\analytics\target\course_dropout' => '\core_course\analytics\target\course_dropout',
< '\core\analytics\target\course_gradetopass' => '\core_course\analytics\target\course_gradetopass',
< '\core\analytics\target\no_teaching' => '\core_course\analytics\target\no_teaching',
< ];
> // Define table reportbuilder_audience to be created.
> $table = new xmldb_table('reportbuilder_audience');
>
> // Adding fields to table reportbuilder_audience.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('classname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< foreach ($targets as $oldclass => $newclass) {
< $DB->set_field('analytics_models', 'target', $newclass, ['target' => $oldclass]);
> // Adding keys to table reportbuilder_audience.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']);
> $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
>
> // Conditionally launch create table for reportbuilder_audience.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019042200.02);
> upgrade_main_savepoint(true, 2021110100.00);
}
< if ($oldversion < 2019042300.01) {
< $sql = "UPDATE {capabilities}
< SET name = ?,
< contextlevel = ?
< WHERE name = ?";
< $DB->execute($sql, ['moodle/category:viewcourselist', CONTEXT_COURSECAT, 'moodle/course:browse']);
> if ($oldversion < 2021110800.02) {
> // Define a field 'downloadcontent' in the 'course_modules' table.
> $table = new xmldb_table('course_modules');
> $field = new xmldb_field('downloadcontent', XMLDB_TYPE_INTEGER, '1', null, null, null, 1, 'deletioninprogress');
< $sql = "UPDATE {role_capabilities}
< SET capability = ?
< WHERE capability = ?";
< $DB->execute($sql, ['moodle/category:viewcourselist', 'moodle/course:browse']);
> // Conditionally launch add field 'downloadcontent'.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
> }
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019042300.01);
> upgrade_main_savepoint(true, 2021110800.02);
}
< if ($oldversion < 2019042300.03) {
> if ($oldversion < 2021110800.03) {
< // Add new customdata field to message table.
< $table = new xmldb_table('message');
< $field = new xmldb_field('customdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'eventtype');
> // Define field settingsdata to be added to reportbuilder_report.
> $table = new xmldb_table('reportbuilder_report');
> $field = new xmldb_field('settingsdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'conditiondata');
< // Conditionally launch add field output.
> // Conditionally launch add field settingsdata.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Add new customdata field to notifications and messages table.
< $table = new xmldb_table('notifications');
< $field = new xmldb_field('customdata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'timecreated');
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021110800.03);
> }
< // Conditionally launch add field output.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> if ($oldversion < 2021111700.00) {
> $mycoursespage = new stdClass();
> $mycoursespage->userid = null;
> $mycoursespage->name = '__courses';
> $mycoursespage->private = 0;
> $mycoursespage->sortorder = 0;
> $DB->insert_record('my_pages', $mycoursespage);
>
> upgrade_main_savepoint(true, 2021111700.00);
}
< $table = new xmldb_table('messages');
< // Conditionally launch add field output.
> if ($oldversion < 2021111700.01) {
>
> // Define field uniquerows to be added to reportbuilder_report.
> $table = new xmldb_table('reportbuilder_report');
> $field = new xmldb_field('uniquerows', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'type');
>
> // Conditionally launch add field uniquerows.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019042300.03);
> upgrade_main_savepoint(true, 2021111700.01);
}
< if ($oldversion < 2019042700.01) {
> if ($oldversion < 2021120100.01) {
< // Define field firstanalysis to be added to analytics_used_analysables.
< $table = new xmldb_table('analytics_used_analysables');
> // Get current configuration data.
> $currentcustomusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems);
> $lines = explode("\n", $currentcustomusermenuitems);
> $lines = array_map('trim', $lines);
> $calendarcustomusermenu = 'calendar,core_calendar|/calendar/view.php?view=month|i/calendar';
< // Declaring it as null initially (although it is NOT NULL).
< $field = new xmldb_field('firstanalysis', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'analysableid');
> if (!in_array($calendarcustomusermenu, $lines)) {
> // Add Calendar item to the menu.
> array_splice($lines, 1, 0, [$calendarcustomusermenu]);
> set_config('customusermenuitems', implode("\n", $lines));
> }
< // Conditionally launch add field firstanalysis.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021120100.01);
> }
< // Set existing values to the current timeanalysed value.
< $recordset = $DB->get_recordset('analytics_used_analysables');
< foreach ($recordset as $record) {
< $record->firstanalysis = $record->timeanalysed;
< $DB->update_record('analytics_used_analysables', $record);
> if ($oldversion < 2021121400.01) {
> // The $CFG->grade_navmethod setting has been removed because it's not required anymore. This setting was used
> // to set the type of navigation (tabs or dropdown box) which will be displayed in gradebook. However, these
> // navigation methods are no longer used and replaced with tertiary navigation.
> unset_config('grade_navmethod');
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021121400.01);
}
< $recordset->close();
< // Now make the field 'NOT NULL'.
< $field = new xmldb_field('firstanalysis', XMLDB_TYPE_INTEGER, '10',
< null, XMLDB_NOTNULL, null, null, 'analysableid');
< $dbman->change_field_notnull($table, $field);
> if ($oldversion < 2021121700.01) {
> // Get current support email setting value.
> $config = get_config('moodle', 'supportemail');
>
> // Check if support email setting is empty and then set it to null.
> // We must do that so the setting is displayed during the upgrade.
> if (empty($config)) {
> set_config('supportemail', null);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019042700.01);
> upgrade_main_savepoint(true, 2021121700.01);
}
< if ($oldversion < 2019050300.01) {
< // Delete all stale favourite records which were left behind when a course was deleted.
< $params = ['component' => 'core_message', 'itemtype' => 'message_conversations'];
< $sql = "SELECT fav.id as id
< FROM {favourite} fav
< LEFT JOIN {context} ctx ON (ctx.id = fav.contextid)
< WHERE fav.component = :component
< AND fav.itemtype = :itemtype
< AND ctx.id IS NULL";
> if ($oldversion < 2021122100.00) {
> // Get current configuration data.
> $currentcustomusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems);
>
> // The old default customusermenuitems config for 3.11 and below.
> $oldcustomusermenuitems = 'grades,grades|/grade/report/mygrades.php|t/grades
> calendar,core_calendar|/calendar/view.php?view=month|i/calendar
> messages,message|/message/index.php|t/message
> preferences,moodle|/user/preferences.php|t/preferences';
>
> // Check if the current customusermenuitems config matches the old customusermenuitems config.
> $samecustomusermenuitems = $currentcustomusermenuitems == $oldcustomusermenuitems;
> if ($samecustomusermenuitems) {
> // If the site is still using the old defaults, upgrade to the new default.
> $newcustomusermenuitems = 'profile,moodle|/user/profile.php
> grades,grades|/grade/report/mygrades.php
> calendar,core_calendar|/calendar/view.php?view=month
> privatefiles,moodle|/user/files.php';
> // Set the new configuration back.
> set_config('customusermenuitems', $newcustomusermenuitems);
> } else {
> // If the site is not using the old defaults, only add necessary entries.
> $lines = preg_split('/\n/', $currentcustomusermenuitems, -1, PREG_SPLIT_NO_EMPTY);
> $lines = array_map(static function(string $line): string {
> // Previous format was "<langstring>|<url>[|<pixicon>]" - pix icon is no longer supported.
> $lineparts = explode('|', trim($line), 3);
> // Return first two parts of line.
> return implode('|', array_slice($lineparts, 0, 2));
> }, $lines);
>
> // Remove the Preference entry from the menu to prevent duplication
> // since it will be added again in user_get_user_navigation_info().
> $lines = array_filter($lines, function($value) {
> return strpos($value, 'preferences,moodle|/user/preferences.php') === false;
> });
< if ($records = $DB->get_fieldset_sql($sql, $params)) {
< // Just for safety, delete by chunks.
< $chunks = array_chunk($records, 1000);
< foreach ($chunks as $chunk) {
< list($insql, $inparams) = $DB->get_in_or_equal($chunk);
< $DB->delete_records_select('favourite', "id $insql", $inparams);
> $matches = preg_grep('/\|\/user\/files.php/i', $lines);
> if (!$matches) {
> // Add the Private files entry to the menu.
> $lines[] = 'privatefiles,moodle|/user/files.php';
}
>
}
> $matches = preg_grep('/\|\/user\/profile.php/i', $lines);
> if (!$matches) {
upgrade_main_savepoint(true, 2019050300.01);
> // Add the Profile entry to top of the menu.
}
> array_unshift($lines, 'profile,moodle|/user/profile.php');
< upgrade_main_savepoint(true, 2019050300.01);
> // Set the new configuration back.
> set_config('customusermenuitems', implode("\n", $lines));
< if ($oldversion < 2019050600.00) {
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021122100.00);
> }
< // Define field apiversion to be added to badge_backpack.
< $table = new xmldb_table('badge_backpack');
< $field = new xmldb_field('apiversion', XMLDB_TYPE_CHAR, '12', null, XMLDB_NOTNULL, null, '1.0', 'password');
< // Conditionally launch add field apiversion.
> if ($oldversion < 2021122100.01) {
>
> // Define field heading to be added to reportbuilder_audience.
> $table = new xmldb_table('reportbuilder_audience');
> $field = new xmldb_field('heading', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'reportid');
>
> // Conditionally launch add field heading.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Define table badge_external_backpack to be created.
< $table = new xmldb_table('badge_external_backpack');
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021122100.01);
> }
>
> if ($oldversion < 2021122100.02) {
>
> // Define table reportbuilder_schedule to be created.
> $table = new xmldb_table('reportbuilder_schedule');
< // Adding fields to table badge_external_backpack.
> // Adding fields to table reportbuilder_schedule.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('backpackapiurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('backpackweburl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('apiversion', XMLDB_TYPE_CHAR, '12', null, XMLDB_NOTNULL, null, '1.0');
< $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('password', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('reportid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('enabled', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1');
> $table->add_field('audiences', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> $table->add_field('format', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('subject', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
> $table->add_field('messageformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userviewas', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timescheduled', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('recurrence', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('reportempty', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timelastsent', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timenextsend', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< // Adding keys to table badge_external_backpack.
> // Adding keys to table reportbuilder_schedule.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('backpackapiurlkey', XMLDB_KEY_UNIQUE, ['backpackapiurl']);
< $table->add_key('backpackweburlkey', XMLDB_KEY_UNIQUE, ['backpackweburl']);
> $table->add_key('reportid', XMLDB_KEY_FOREIGN, ['reportid'], 'reportbuilder_report', ['id']);
> $table->add_key('userviewas', XMLDB_KEY_FOREIGN, ['userviewas'], 'user', ['id']);
> $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
< // Conditionally launch create table for badge_external_backpack.
> // Conditionally launch create table for reportbuilder_schedule.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define field entityid to be added to badge_external.
< $table = new xmldb_table('badge_external');
< $field = new xmldb_field('entityid', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'collectionid');
<
< // Conditionally launch add field entityid.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021122100.02);
}
< // Define table badge_external_identifier to be created.
< $table = new xmldb_table('badge_external_identifier');
> if ($oldversion < 2021123000.01) {
> // The tool_admin_presets tables have been moved to core, because core_adminpresets component has been created, so
> // it can interact with the rest of core.
> // So the tool_admin_presetsXXX tables will be renamed to adminipresetsXXX if they exists; otherwise, they will be created.
< // Adding fields to table badge_external_identifier.
> $tooltable = new xmldb_table('tool_admin_presets');
> $table = new xmldb_table('adminpresets');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('sitebackpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('internalid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null);
< $table->add_field('externalid', XMLDB_TYPE_CHAR, '128', null, XMLDB_NOTNULL, null, null);
< $table->add_field('type', XMLDB_TYPE_CHAR, '16', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('comments', XMLDB_TYPE_TEXT, null, null, null, null, null);
> $table->add_field('site', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('author', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('moodleversion', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null);
> $table->add_field('moodlerelease', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('iscore', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('timeimported', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< // Adding keys to table badge_external_identifier.
> // Adding keys to table adminpresets.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('fk_backpackid', XMLDB_KEY_FOREIGN, ['sitebackpackid'], 'badge_backpack', ['id']);
< $table->add_key('backpack-internal-external', XMLDB_KEY_UNIQUE, ['sitebackpackid', 'internalid', 'externalid', 'type']);
< // Conditionally launch create table for badge_external_identifier.
< if (!$dbman->table_exists($table)) {
> // Launch create table for adminpresets.
$dbman->create_table($table);
}
< // Define field externalbackpackid to be added to badge_backpack.
< $table = new xmldb_table('badge_backpack');
< $field = new xmldb_field('externalbackpackid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'password');
> $tooltable = new xmldb_table('tool_admin_presets_it');
> $table = new xmldb_table('adminpresets_it');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_it');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_it.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null);
< // Conditionally launch add field externalbackpackid.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Adding keys to table adminpresets_it.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
>
> // Adding indexes to table adminpresets_it.
> $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']);
>
> // Launch create table for adminpresets_it.
> $dbman->create_table($table);
}
< // Define key externalbackpack (foreign) to be added to badge_backpack.
< $key = new xmldb_key('externalbackpack', XMLDB_KEY_FOREIGN, ['externalbackpackid'], 'badge_external_backpack', ['id']);
> $tooltable = new xmldb_table('tool_admin_presets_it_a');
> $table = new xmldb_table('adminpresets_it_a');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_it_a');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_it_a.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('value', XMLDB_TYPE_TEXT, null, null, null, null, null);
< // Launch add key externalbackpack.
< $dbman->add_key($table, $key);
> // Adding keys to table adminpresets_it_a.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $field = new xmldb_field('apiversion');
> // Adding indexes to table adminpresets_it_a.
> $table->add_index('itemid', XMLDB_INDEX_NOTUNIQUE, ['itemid']);
< // Conditionally launch drop field apiversion.
< if ($dbman->field_exists($table, $field)) {
< $dbman->drop_field($table, $field);
> // Launch create table for adminpresets_it_a.
> $dbman->create_table($table);
}
< $field = new xmldb_field('backpackurl');
> $tooltable = new xmldb_table('tool_admin_presets_app');
> $table = new xmldb_table('adminpresets_app');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_app');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_app.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('time', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< // Conditionally launch drop field backpackurl.
< if ($dbman->field_exists($table, $field)) {
< $dbman->drop_field($table, $field);
< }
> // Adding keys to table adminpresets_app.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< // Add default backpacks.
< require_once($CFG->dirroot . '/badges/upgradelib.php'); // Core install and upgrade related functions only for badges.
< badges_install_default_backpacks();
> // Adding indexes to table adminpresets_app.
> $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']);
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019050600.00);
> // Launch create table for adminpresets_app.
> $dbman->create_table($table);
}
< if ($oldversion < 2019051300.01) {
< $DB->set_field('analytics_models', 'enabled', '1', ['target' => '\core_user\analytics\target\upcoming_activities_due']);
> $tooltable = new xmldb_table('tool_admin_presets_app_it');
> $table = new xmldb_table('adminpresets_app_it');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_app_it');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_app_it.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('configlogid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019051300.01);
> // Adding keys to table adminpresets_app_it.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
>
> // Adding indexes to table adminpresets_app_it.
> $table->add_index('configlogid', XMLDB_INDEX_NOTUNIQUE, ['configlogid']);
> $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']);
>
> // Launch create table for adminpresets_app_it.
> $dbman->create_table($table);
}
< // Automatically generated Moodle v3.7.0 release upgrade line.
< // Put any upgrade step following this.
> $tooltable = new xmldb_table('tool_admin_presets_app_it_a');
> $table = new xmldb_table('adminpresets_app_it_a');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_app_it_a');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_app_it_a.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('configlogid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('itemname', XMLDB_TYPE_CHAR, '100', null, null, null, null);
>
> // Adding keys to table adminpresets_app_it_a.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< if ($oldversion < 2019060600.02) {
< // Renaming 'opentogoogle' config to 'opentowebcrawlers'.
< $opentogooglevalue = get_config('core', 'opentogoogle');
> // Adding indexes to table adminpresets_app_it_a.
> $table->add_index('configlogid', XMLDB_INDEX_NOTUNIQUE, ['configlogid']);
> $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']);
< // Move the value over if it was previously configured.
< if ($opentogooglevalue !== false) {
< set_config('opentowebcrawlers', $opentogooglevalue);
> // Launch create table for adminpresets_app_it_a.
> $dbman->create_table($table);
}
< // Remove the now unused value.
< unset_config('opentogoogle');
> $tooltable = new xmldb_table('tool_admin_presets_plug');
> $table = new xmldb_table('adminpresets_plug');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_plug');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_plug.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('enabled', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0');
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019060600.02);
< }
> // Adding keys to table adminpresets_plug.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< if ($oldversion < 2019062900.00) {
< // Debugsmtp is now only available via config.php.
< $DB->delete_records('config', array('name' => 'debugsmtp'));
> // Adding indexes to table adminpresets_plug.
> $table->add_index('adminpresetid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetid']);
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019062900.00);
> // Launch create table for adminpresets_plug.
> $dbman->create_table($table);
}
< if ($oldversion < 2019070400.01) {
> $tooltable = new xmldb_table('tool_admin_presets_app_plug');
> $table = new xmldb_table('adminpresets_app_plug');
> if ($dbman->table_exists($tooltable)) {
> $dbman->rename_table($tooltable, 'adminpresets_app_plug');
> } else if (!$dbman->table_exists($table)) {
> // Adding fields to table adminpresets_app_plug.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('adminpresetapplyid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('plugin', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('name', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
> $table->add_field('value', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('oldvalue', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0');
< $basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894',
< '#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
> // Adding keys to table adminpresets_app_plug.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $colornr = 1;
< foreach ($basecolors as $color) {
< set_config('coursecolor' . $colornr, $color, 'core_admin');
< $colornr++;
< }
> // Adding indexes to table adminpresets_app_plug.
> $table->add_index('adminpresetapplyid', XMLDB_INDEX_NOTUNIQUE, ['adminpresetapplyid']);
< upgrade_main_savepoint(true, 2019070400.01);
> // Launch create table for adminpresets_app_plug.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
> }
}
< if ($oldversion < 2019072200.00) {
> if ($DB->count_records('adminpresets', ['iscore' => 1]) == 0) {
> // Create default core site admin presets.
> require_once($CFG->dirroot . '/admin/presets/classes/helper.php');
> \core_adminpresets\helper::create_default_presets();
> }
< // Define field relativedatesmode to be added to course.
< $table = new xmldb_table('course');
< $field = new xmldb_field('relativedatesmode', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'enddate');
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021123000.01);
> }
< // Conditionally launch add field relativedatesmode.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> if ($oldversion < 2021123000.02) {
> // If exists, migrate sensiblesettings admin settings from tool_admin_preset to adminpresets.
> if (get_config('tool_admin_presets', 'sensiblesettings') !== false) {
> set_config('sensiblesettings', get_config('tool_admin_presets', 'sensiblesettings'), 'adminpresets');
> unset_config('sensiblesettings', 'tool_admin_presets');
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019072200.00);
> upgrade_main_savepoint(true, 2021123000.02);
}
< if ($oldversion < 2019072500.01) {
< // Remove the "popup" processor from the list of default processors for the messagecontactrequests notification.
< $oldloggedinconfig = get_config('message', 'message_provider_moodle_messagecontactrequests_loggedin');
< $oldloggedoffconfig = get_config('message', 'message_provider_moodle_messagecontactrequests_loggedoff');
< $newloggedinconfig = implode(',', array_filter(explode(',', $oldloggedinconfig), function($value) {
< return $value != 'popup';
< }));
< $newloggedoffconfig = implode(',', array_filter(explode(',', $oldloggedoffconfig), function($value) {
< return $value != 'popup';
< }));
< set_config('message_provider_moodle_messagecontactrequests_loggedin', $newloggedinconfig, 'message');
< set_config('message_provider_moodle_messagecontactrequests_loggedoff', $newloggedoffconfig, 'message');
> if ($oldversion < 2021123000.03) {
> // If exists, migrate lastpresetapplied setting from tool_admin_preset to adminpresets.
> if (get_config('tool_admin_presets', 'lastpresetapplied') !== false) {
> set_config('lastpresetapplied', get_config('tool_admin_presets', 'lastpresetapplied'), 'adminpresets');
> unset_config('lastpresetapplied', 'tool_admin_presets');
> }
< upgrade_main_savepoint(true, 2019072500.01);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2021123000.03);
}
< if ($oldversion < 2019072500.03) {
< unset_config('httpswwwroot');
> if ($oldversion < 2022011100.01) {
> // The following blocks have been hidden by default, so they shouldn't be enabled in the Full core preset: Course/site
> // summary, RSS feeds, Self completion and Feedback.
> $params = ['name' => get_string('fullpreset', 'core_adminpresets')];
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
< upgrade_main_savepoint(true, 2019072500.03);
> if (!$fullpreset) {
> // Full admin preset might have been created using the English name.
> $name = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $name;
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> }
> if (!$fullpreset) {
> // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1.
> $sql = "SELECT preset.*
> FROM {adminpresets} preset
> INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid
> WHERE it.name = :name AND it.value = :value AND preset.iscore > 0";
> $params = ['name' => 'usecomments', 'value' => '1'];
> $fullpreset = $DB->get_record_sql($sql, $params);
}
< if ($oldversion < 2019073100.00) {
< // Update the empty tag instructions to null.
< $instructions = get_config('core', 'auth_instructions');
> if ($fullpreset) {
> $blocknames = ['course_summary', 'feedback', 'rss_client', 'selfcompletion'];
> list($blocksinsql, $blocksinparams) = $DB->get_in_or_equal($blocknames);
< if (trim(html_to_text($instructions)) === '') {
< set_config('auth_instructions', '');
> // Remove entries from the adminpresets_app_plug table (in case the preset has been applied).
> $appliedpresets = $DB->get_records('adminpresets_app', ['adminpresetid' => $fullpreset->id], '', 'id');
> if ($appliedpresets) {
> list($appsinsql, $appsinparams) = $DB->get_in_or_equal(array_keys($appliedpresets));
> $sql = "adminpresetapplyid $appsinsql AND plugin='block' AND name $blocksinsql";
> $params = array_merge($appsinparams, $blocksinparams);
> $DB->delete_records_select('adminpresets_app_plug', $sql, $params);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019073100.00);
> // Remove entries for these blocks from the adminpresets_plug table.
> $sql = "adminpresetid = ? AND plugin='block' AND name $blocksinsql";
> $params = array_merge([$fullpreset->id], $blocksinparams);
> $DB->delete_records_select('adminpresets_plug', $sql, $params);
}
< if ($oldversion < 2019083000.01) {
<
< // If block_community is no longer present, remove it.
< if (!file_exists($CFG->dirroot . '/blocks/community/communitycourse.php')) {
< // Drop table that is no longer needed.
< $table = new xmldb_table('block_community');
< if ($dbman->table_exists($table)) {
< $dbman->drop_table($table);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022011100.01);
}
< // Delete instances.
< $instances = $DB->get_records_list('block_instances', 'blockname', ['community']);
< $instanceids = array_keys($instances);
> if ($oldversion < 2022012100.02) {
> // Migrate default message output config.
> $preferences = get_config('message');
< if (!empty($instanceids)) {
< $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
< $DB->delete_records_list('block_instances', 'id', $instanceids);
< list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
< $params['contextlevel'] = CONTEXT_BLOCK;
< $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
<
< $preferences = array();
< foreach ($instances as $instanceid => $instance) {
< $preferences[] = 'block' . $instanceid . 'hidden';
< $preferences[] = 'docked_block_instance_' . $instanceid;
< }
< $DB->delete_records_list('user_preferences', 'name', $preferences);
> $treatedprefs = [];
>
> foreach ($preferences as $preference => $value) {
> // Extract provider and preference name from the setting name.
> // Example name: airnotifier_provider_enrol_imsenterprise_imsenterprise_enrolment_permitted
> // Provider: airnotifier
> // Preference: enrol_imsenterprise_imsenterprise_enrolment_permitted.
> $providerparts = explode('_provider_', $preference);
> if (count($providerparts) <= 1) {
> continue;
}
< // Delete the block from the block table.
< $DB->delete_records('block', array('name' => 'community'));
> $provider = $providerparts[0];
> $preference = $providerparts[1];
< // Remove capabilities.
< capabilities_cleanup('block_community');
< // Clean config.
< unset_all_config_for_plugin('block_community');
> // Extract and remove last part of the preference previously extracted: ie. permitted.
> $parts = explode('_', $preference);
> $key = array_pop($parts);
< // Remove Moodle-level community based capabilities.
< $capabilitiestoberemoved = ['block/community:addinstance', 'block/community:myaddinstance'];
< // Delete any role_capabilities for the old roles.
< $DB->delete_records_list('role_capabilities', 'capability', $capabilitiestoberemoved);
< // Delete the capability itself.
< $DB->delete_records_list('capabilities', 'name', $capabilitiestoberemoved);
> if (in_array($key, ['permitted', 'loggedin', 'loggedoff'])) {
> if ($key == 'permitted') {
> // We will use provider name instead of permitted.
> $key = $provider;
> } else {
> // Logged in and logged off values are a csv of the enabled providers.
> $value = explode(',', $value);
}
< upgrade_main_savepoint(true, 2019083000.01);
> // Join the rest of the parts: ie enrol_imsenterprise_imsenterprise_enrolment.
> $prefname = implode('_', $parts);
>
> if (!isset($treatedprefs[$prefname])) {
> $treatedprefs[$prefname] = [];
}
< if ($oldversion < 2019083000.02) {
< // Remove unused config.
< unset_config('enablecoursepublishing');
< upgrade_main_savepoint(true, 2019083000.02);
> // Save the value with the selected key.
> $treatedprefs[$prefname][$key] = $value;
> }
}
< if ($oldversion < 2019083000.04) {
< // Delete "orphaned" subscriptions.
< $sql = "SELECT DISTINCT es.userid
< FROM {event_subscriptions} es
< LEFT JOIN {user} u ON u.id = es.userid
< WHERE u.deleted = 1 OR u.id IS NULL";
< $deletedusers = $DB->get_fieldset_sql($sql);
< if ($deletedusers) {
< list($sql, $params) = $DB->get_in_or_equal($deletedusers);
> // Now take every preference previous treated and its values.
> foreach ($treatedprefs as $prefname => $values) {
> $enabled = []; // List of providers enabled for each preference.
< // Delete orphaned subscriptions.
< $DB->execute("DELETE FROM {event_subscriptions} WHERE userid " . $sql, $params);
> // Enable if one of those is enabled.
> $loggedin = isset($values['loggedin']) ? $values['loggedin'] : [];
> foreach ($loggedin as $provider) {
> $enabled[$provider] = 1;
}
<
< upgrade_main_savepoint(true, 2019083000.04);
> $loggedoff = isset($values['loggedoff']) ? $values['loggedoff'] : [];
> foreach ($loggedoff as $provider) {
> $enabled[$provider] = 1;
}
< if ($oldversion < 2019090500.01) {
> // Do not treat those values again.
> unset($values['loggedin']);
> unset($values['loggedoff']);
< // Define index analysableid (not unique) to be added to analytics_used_analysables.
< $table = new xmldb_table('analytics_used_analysables');
< $index = new xmldb_index('analysableid', XMLDB_INDEX_NOTUNIQUE, ['analysableid']);
> // Translate rest of values coming from permitted "key".
> foreach ($values as $provider => $value) {
> $locked = false;
< // Conditionally launch add index analysableid.
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> switch ($value) {
> case 'forced':
> // Provider is enabled by force.
> $enabled[$provider] = 1;
> $locked = true;
> break;
> case 'disallowed':
> // Provider is disabled by force.
> unset($enabled[$provider]);
> $locked = true;
> break;
> default:
> // Provider is not forced (permitted) or invalid values.
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019090500.01);
> // Save locked.
> if ($locked) {
> set_config($provider.'_provider_'.$prefname.'_locked', 1, 'message');
> } else {
> set_config($provider.'_provider_'.$prefname.'_locked', 0, 'message');
> }
> // Remove old value.
> unset_config($provider.'_provider_'.$prefname.'_permitted', 'message');
}
< if ($oldversion < 2019092700.01) {
< upgrade_rename_prediction_actions_useful_incorrectly_flagged();
< upgrade_main_savepoint(true, 2019092700.01);
> // Save the new values.
> $value = implode(',', array_keys($enabled));
> set_config('message_provider_'.$prefname.'_enabled', $value, 'message');
> // Remove old values.
> unset_config('message_provider_'.$prefname.'_loggedin', 'message');
> unset_config('message_provider_'.$prefname.'_loggedoff', 'message');
}
< if ($oldversion < 2019100800.02) {
< // Rename the official moodle sites directory the site is registered with.
< $DB->execute("UPDATE {registration_hubs}
< SET hubname = ?, huburl = ?
< WHERE huburl = ?", ['moodle', 'https://stats.moodle.org', 'https://moodle.net']);
> // Migrate user preferences. ie merging message_provider_moodle_instantmessage_loggedoff with
> // message_provider_moodle_instantmessage_loggedin to message_provider_moodle_instantmessage_enabled.
< // Convert the hub site specific settings to the new naming format without the hub URL in the name.
< $hubconfig = get_config('hub');
> $allrecordsloggedoff = $DB->sql_like('name', ':loggedoff');
> $total = $DB->count_records_select(
> 'user_preferences',
> $allrecordsloggedoff,
> ['loggedoff' => 'message_provider_%_loggedoff']
> );
> $i = 0;
> if ($total == 0) {
> $total = 1; // Avoid division by zero.
> }
>
> // Show a progress bar.
> $pbar = new progress_bar('upgradeusernotificationpreferences', 500, true);
> $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total.");
>
> // We're migrating provider per provider to reduce memory usage.
> $providers = $DB->get_records('message_providers', null, 'name');
> foreach ($providers as $provider) {
> // 60 minutes to migrate each provider.
> upgrade_set_timeout(3600);
> $componentproviderbase = 'message_provider_'.$provider->component.'_'.$provider->name;
>
> $loggedinname = $componentproviderbase.'_loggedin';
> $loggedoffname = $componentproviderbase.'_loggedoff';
>
> // Change loggedin to enabled.
> $enabledname = $componentproviderbase.'_enabled';
> $DB->set_field('user_preferences', 'name', $enabledname, ['name' => $loggedinname]);
>
> $selectparams = [
> 'enabled' => $enabledname,
> 'loggedoff' => $loggedoffname,
> ];
> $sql = 'SELECT m1.id loggedoffid, m1.value as loggedoff, m2.value as enabled, m2.id as enabledid
> FROM
> (SELECT id, userid, value FROM {user_preferences} WHERE name = :loggedoff) m1
> LEFT JOIN
> (SELECT id, userid, value FROM {user_preferences} WHERE name = :enabled) m2
> ON m1.userid = m2.userid';
>
> while (($rs = $DB->get_recordset_sql($sql, $selectparams, 0, 1000)) && $rs->valid()) {
> // 10 minutes for every chunk.
> upgrade_set_timeout(600);
>
> $deleterecords = [];
> $changename = [];
> $changevalue = []; // Multidimensional array with possible values as key to reduce SQL queries.
> foreach ($rs as $record) {
> if (empty($record->enabledid)) {
> // Enabled does not exists, change the name.
> $changename[] = $record->loggedoffid;
> } else if ($record->enabledid != $record->loggedoff) {
> // Exist and values differ (checked on SQL), update the enabled record.
< if (!empty($hubconfig)) {
< foreach (upgrade_convert_hub_config_site_param_names($hubconfig, 'https://moodle.net') as $name => $value) {
< set_config($name, $value, 'hub');
< }
> if ($record->enabled != 'none' && !empty($record->enabled)) {
> $enabledvalues = explode(',', $record->enabled);
> } else {
> $enabledvalues = [];
}
< upgrade_main_savepoint(true, 2019100800.02);
> if ($record->loggedoff != 'none' && !empty($record->loggedoff)) {
> $loggedoffvalues = explode(',', $record->loggedoff);
> } else {
> $loggedoffvalues = [];
}
< if ($oldversion < 2019100900.00) {
< // If block_participants is no longer present, remove it.
< if (!file_exists($CFG->dirroot . '/blocks/participants/block_participants.php')) {
< // Delete instances.
< $instances = $DB->get_records_list('block_instances', 'blockname', ['participants']);
< $instanceids = array_keys($instances);
> $values = array_unique(array_merge($enabledvalues, $loggedoffvalues));
> sort($values);
< if (!empty($instanceids)) {
< $DB->delete_records_list('block_positions', 'blockinstanceid', $instanceids);
< $DB->delete_records_list('block_instances', 'id', $instanceids);
< list($sql, $params) = $DB->get_in_or_equal($instanceids, SQL_PARAMS_NAMED);
< $params['contextlevel'] = CONTEXT_BLOCK;
< $DB->delete_records_select('context', "contextlevel=:contextlevel AND instanceid " . $sql, $params);
<
< $preferences = array();
< foreach ($instances as $instanceid => $instance) {
< $preferences[] = 'block' . $instanceid . 'hidden';
< $preferences[] = 'docked_block_instance_' . $instanceid;
< }
< $DB->delete_records_list('user_preferences', 'name', $preferences);
> $newvalue = empty($values) ? 'none' : implode(',', $values);
> if (!isset($changevalue[$newvalue])) {
> $changevalue[$newvalue] = [];
}
> $changevalue[$newvalue][] = $record->enabledid;
< // Delete the block from the block table.
< $DB->delete_records('block', array('name' => 'participants'));
> $deleterecords[] = $record->loggedoffid;
> } else {
> // They are the same, just delete loggedoff one.
> $deleterecords[] = $record->loggedoffid;
> }
> $i++;
> }
> $rs->close();
< // Remove capabilities.
< capabilities_cleanup('block_participants');
> // Commit the changes.
> if (!empty($changename)) {
> $changenameparams = [
> 'name' => $loggedoffname,
> ];
> $changenameselect = 'name = :name AND id IN (' . implode(',', $changename) . ')';
> $DB->set_field_select('user_preferences', 'name', $enabledname, $changenameselect, $changenameparams);
> }
< // Clean config.
< unset_all_config_for_plugin('block_participants');
> if (!empty($changevalue)) {
> $changevalueparams = [
> 'name' => $enabledname,
> ];
> foreach ($changevalue as $value => $ids) {
> $changevalueselect = 'name = :name AND id IN (' . implode(',', $ids) . ')';
> $DB->set_field_select('user_preferences', 'value', $value, $changevalueselect, $changevalueparams);
> }
}
< upgrade_main_savepoint(true, 2019100900.00);
> if (!empty($deleterecords)) {
> $deleteparams = [
> 'name' => $loggedoffname,
> ];
> $deleteselect = 'name = :name AND id IN (' . implode(',', $deleterecords) . ')';
> $DB->delete_records_select('user_preferences', $deleteselect, $deleteparams);
}
< if ($oldversion < 2019101600.01) {
> // Update progress.
> $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total.");
> }
> $rs->close();
< // Change the setting $CFG->requestcategoryselection into $CFG->lockrequestcategory with opposite value.
< set_config('lockrequestcategory', empty($CFG->requestcategoryselection));
> // Delete the rest of loggedoff values (that are equal than enabled).
> $deleteparams = [
> 'name' => $loggedoffname,
> ];
> $deleteselect = 'name = :name';
> $i += $DB->count_records_select('user_preferences', $deleteselect, $deleteparams);
> $DB->delete_records_select('user_preferences', $deleteselect, $deleteparams);
< upgrade_main_savepoint(true, 2019101600.01);
> // Update progress.
> $pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total.");
}
< if ($oldversion < 2019101800.02) {
> core_plugin_manager::reset_caches();
< // Get the table by its previous name.
< $table = new xmldb_table('analytics_models');
< if ($dbman->table_exists($table)) {
> // Delete the orphan records.
> $allrecordsparams = ['loggedin' => 'message_provider_%_loggedin', 'loggedoff' => 'message_provider_%_loggedoff'];
> $allrecordsloggedin = $DB->sql_like('name', ':loggedin');
> $allrecordsloggedinoffsql = "$allrecordsloggedin OR $allrecordsloggedoff";
> $DB->delete_records_select('user_preferences', $allrecordsloggedinoffsql, $allrecordsparams);
< // Define field contextids to be added to analytics_models.
< $field = new xmldb_field('contextids', XMLDB_TYPE_TEXT, null, null, null, null, null, 'version');
<
< // Conditionally launch add field contextids.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
< }
< }
> // Update progress.
> $pbar->update($total, $total, "Upgrading user notifications preferences - $total/$total.");
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2019101800.02);
> upgrade_main_savepoint(true, 2022012100.02);
}
< if ($oldversion < 2019102500.04) {
< // Define table h5p_libraries to be created.
< $table = new xmldb_table('h5p_libraries');
> // Introduce question versioning to core.
> // First, create the new tables.
> if ($oldversion < 2022020200.01) {
> // Define table question_bank_entries to be created.
> $table = new xmldb_table('question_bank_entries');
< // Adding fields to table h5p_libraries.
> // Adding fields to table question_bank_entries.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('machinename', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('title', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('majorversion', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
< $table->add_field('minorversion', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
< $table->add_field('patchversion', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null);
< $table->add_field('runnable', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
< $table->add_field('fullscreen', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('embedtypes', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('preloadedjs', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('preloadedcss', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('droplibrarycss', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('semantics', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('addto', XMLDB_TYPE_TEXT, null, null, null, null, null);
<
< // Adding keys to table h5p_libraries.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
<
< // Adding indexes to table h5p_libraries.
< $table->add_index('machinemajorminorpatch', XMLDB_INDEX_NOTUNIQUE,
< ['machinename', 'majorversion', 'minorversion', 'patchversion', 'runnable']);
> $table->add_field('questioncategoryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('ownerid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
>
> // Adding keys to table question_bank_entries.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
> $table->add_key('questioncategoryid', XMLDB_KEY_FOREIGN, ['questioncategoryid'], 'question_categories', ['id']);
> $table->add_key('ownerid', XMLDB_KEY_FOREIGN, ['ownerid'], 'user', ['id']);
< // Conditionally launch create table for h5p_libraries.
> // Conditionally launch create table for question_bank_entries.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table h5p_library_dependencies to be created.
< $table = new xmldb_table('h5p_library_dependencies');
> // Create category id and id number index.
> $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, ['questioncategoryid', 'idnumber']);
>
> // Conditionally launch add index categoryidnumber.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
> }
>
> // Define table question_versions to be created.
> $table = new xmldb_table('question_versions');
< // Adding fields to table h5p_library_dependencies.
> // Adding fields to table question_versions.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('libraryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('requiredlibraryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('dependencytype', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('questionbankentryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 1);
> $table->add_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('status', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, 'ready');
< // Adding keys to table h5p_library_dependencies.
> // Adding keys to table question_versions.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('libraryid', XMLDB_KEY_FOREIGN, ['libraryid'], 'h5p_libraries', ['id']);
< $table->add_key('requiredlibraryid', XMLDB_KEY_FOREIGN, ['requiredlibraryid'], 'h5p_libraries', ['id']);
> $table->add_key('questionbankentryid', XMLDB_KEY_FOREIGN, ['questionbankentryid'], 'question_bank_entries', ['id']);
> $table->add_key('questionid', XMLDB_KEY_FOREIGN, ['questionid'], 'question', ['id']);
< // Conditionally launch create table for h5p_library_dependencies.
> // Conditionally launch create table for question_versions.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table h5p to be created.
< $table = new xmldb_table('h5p');
> // Define table question_references to be created.
> $table = new xmldb_table('question_references');
< // Adding fields to table h5p.
> // Adding fields to table question_references.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('jsoncontent', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
< $table->add_field('mainlibraryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('displayoptions', XMLDB_TYPE_INTEGER, '4', null, null, null, null);
< $table->add_field('pathnamehash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
< $table->add_field('contenthash', XMLDB_TYPE_CHAR, '40', null, XMLDB_NOTNULL, null, null);
< $table->add_field('filtered', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
> $table->add_field('usingcontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('questionarea', XMLDB_TYPE_CHAR, '50', null, null, null, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('questionbankentryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('version', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< // Adding keys to table h5p.
> // Adding keys to table question_references.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('mainlibraryid', XMLDB_KEY_FOREIGN, ['mainlibraryid'], 'h5p_libraries', ['id']);
> $table->add_key('usingcontextid', XMLDB_KEY_FOREIGN, ['usingcontextid'], 'context', ['id']);
> $table->add_key('questionbankentryid', XMLDB_KEY_FOREIGN, ['questionbankentryid'], 'question_bank_entries', ['id']);
< // Conditionally launch create table for h5p.
> // Conditionally launch create table for question_references.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table h5p_contents_libraries to be created.
< $table = new xmldb_table('h5p_contents_libraries');
> // Define table question_set_references to be created.
> $table = new xmldb_table('question_set_references');
< // Adding fields to table h5p_contents_libraries.
> // Adding fields to table question_set_references.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('h5pid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('libraryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('dependencytype', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('dropcss', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
< $table->add_field('weight', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('usingcontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null);
> $table->add_field('questionarea', XMLDB_TYPE_CHAR, '50', null, null, null, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('questionscontextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, 0);
> $table->add_field('filtercondition', XMLDB_TYPE_TEXT, null, null, null, null, null);
< // Adding keys to table h5p_contents_libraries.
> // Adding keys to table question_set_references.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('h5pid', XMLDB_KEY_FOREIGN, ['h5pid'], 'h5p', ['id']);
< $table->add_key('libraryid', XMLDB_KEY_FOREIGN, ['libraryid'], 'h5p_libraries', ['id']);
> $table->add_key('usingcontextid', XMLDB_KEY_FOREIGN, ['usingcontextid'], 'context', ['id']);
> $table->add_key('questionscontextid', XMLDB_KEY_FOREIGN, ['questionscontextid'], 'context', ['id']);
< // Conditionally launch create table for h5p_contents_libraries.
> // Conditionally launch create table for question_set_references.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
< // Define table h5p_libraries_cachedassets to be created.
< $table = new xmldb_table('h5p_libraries_cachedassets');
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022020200.01);
> }
< // Adding fields to table h5p_libraries_cachedassets.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('libraryid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('hash', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> if ($oldversion < 2022020200.02) {
> // Define a new temporary field in the question_bank_entries tables.
> // Creating temporary field questionid to populate the data in question version table.
> // This will make sure the appropriate question id is inserted the version table without making any complex joins.
> $table = new xmldb_table('question_bank_entries');
> $field = new xmldb_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL);
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
> }
< // Adding keys to table h5p_libraries_cachedassets.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('libraryid', XMLDB_KEY_FOREIGN, ['libraryid'], 'h5p_libraries_cachedassets', ['id']);
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
> // Create the data for the question_bank_entries table with, including the new temporary field.
> $sql = <<<EOF
> INSERT INTO {question_bank_entries}
> (questionid, questioncategoryid, idnumber, ownerid)
> SELECT id, category, idnumber, createdby
> FROM {question} q
> EOF;
< // Conditionally launch create table for h5p_libraries_cachedassets.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Inserting question_bank_entries data.
> $DB->execute($sql);
>
> $transaction->allow_commit();
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022020200.02);
> }
>
> if ($oldversion < 2022020200.03) {
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
> // Create the question_versions using that temporary field.
> $sql = <<<EOF
> INSERT INTO {question_versions}
> (questionbankentryid, questionid, status)
> SELECT
> qbe.id,
> q.id,
> CASE
> WHEN q.hidden > 0 THEN 'hidden'
> ELSE 'ready'
> END
> FROM {question_bank_entries} qbe
> INNER JOIN {question} q ON qbe.questionid = q.id
> EOF;
>
> // Inserting question_versions data.
> $DB->execute($sql);
>
> $transaction->allow_commit();
>
> // Dropping temporary field questionid.
> $table = new xmldb_table('question_bank_entries');
> $field = new xmldb_field('questionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL);
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019102500.04);
> upgrade_main_savepoint(true, 2022020200.03);
}
< if ($oldversion < 2019103000.13) {
> if ($oldversion < 2022020200.04) {
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
> // Create the base data for the random questions in the set_references table.
> // This covers most of the hard work in one go.
> $concat = $DB->sql_concat("'{\"questioncategoryid\":\"'", 'q.category', "'\",\"includingsubcategories\":\"'",
> 'qs.includingsubcategories', "'\"}'");
> $sql = <<<EOF
> INSERT INTO {question_set_references}
> (usingcontextid, component, questionarea, itemid, questionscontextid, filtercondition)
> SELECT
> c.id,
> 'mod_quiz',
> 'slot',
> qs.id,
> qc.contextid,
> $concat
> FROM {question} q
> INNER JOIN {quiz_slots} qs on q.id = qs.questionid
> INNER JOIN {course_modules} cm ON cm.instance = qs.quizid AND cm.module = :quizmoduleid
> INNER JOIN {context} c ON cm.id = c.instanceid AND c.contextlevel = :contextmodule
> INNER JOIN {question_categories} qc ON qc.id = q.category
> WHERE q.qtype = :random
> EOF;
>
> // Inserting question_set_references data.
> $DB->execute($sql, [
> 'quizmoduleid' => $DB->get_field('modules', 'id', ['name' => 'quiz']),
> 'contextmodule' => CONTEXT_MODULE,
> 'random' => 'random',
> ]);
< upgrade_analytics_fix_contextids_defaults();
> $transaction->allow_commit();
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019103000.13);
> upgrade_main_savepoint(true, 2022020200.04);
}
< if ($oldversion < 2019111300.00) {
> if ($oldversion < 2022020200.05) {
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
< // Define field coremajor to be added to h5p_libraries.
< $table = new xmldb_table('h5p_libraries');
< $field = new xmldb_field('coremajor', XMLDB_TYPE_INTEGER, '4', null, null, null, null, 'addto');
> // Count all the slot tags to be migrated (for progress bar).
> $total = $DB->count_records('quiz_slot_tags');
> $pbar = new progress_bar('migratequestiontags', 1000, true);
> $i = 0;
> // Updating slot_tags for random question tags.
> // Now fetch any quiz slot tags and update those slot details into the question_set_references.
> $slottags = $DB->get_recordset('quiz_slot_tags', [], 'slotid ASC');
< // Conditionally launch add field coremajor.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> $tagstrings = [];
> $lastslot = null;
> $runinsert = function (int $lastslot, array $tagstrings) use ($DB) {
> $conditiondata = $DB->get_field('question_set_references', 'filtercondition',
> ['itemid' => $lastslot, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
>
> // It is possible to have leftover tags in the database, without a corresponding
> // slot, because of an old bugs (e.g. MDL-76193). Therefore, if the slot is not found,
> // we can safely discard these tags.
> if (!empty($conditiondata)) {
> $condition = json_decode($conditiondata);
> $condition->tags = $tagstrings;
> $DB->set_field('question_set_references', 'filtercondition', json_encode($condition),
> ['itemid' => $lastslot, 'component' => 'mod_quiz', 'questionarea' => 'slot']);
}
> };
< $field = new xmldb_field('coreminor', XMLDB_TYPE_INTEGER, '4', null, null, null, null, 'coremajor');
> foreach ($slottags as $tag) {
> upgrade_set_timeout(3600);
> if ($lastslot && $tag->slotid != $lastslot) {
> if (!empty($tagstrings)) {
> // Insert the data.
> $runinsert($lastslot, $tagstrings);
> }
> // Prepare for the next slot id.
> $tagstrings = [];
> }
< // Conditionally launch add field coreminor.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> $lastslot = $tag->slotid;
> $tagstrings[] = "{$tag->tagid},{$tag->tagname}";
> // Update progress.
> $i++;
> $pbar->update($i, $total, "Migrating question tags - $i/$total.");
> }
> if ($tagstrings) {
> $runinsert($lastslot, $tagstrings);
}
> $slottags->close();
> $transaction->allow_commit();
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019111300.00);
> upgrade_main_savepoint(true, 2022020200.05);
}
< // Automatically generated Moodle v3.8.0 release upgrade line.
< // Put any upgrade step following this.
> if ($oldversion < 2022020200.06) {
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
> // Create question_references record for each question.
> // Except if qtype is random. That case is handled by question_set_reference.
> $sql = "INSERT INTO {question_references}
> (usingcontextid, component, questionarea, itemid, questionbankentryid)
> SELECT c.id, 'mod_quiz', 'slot', qs.id, qv.questionbankentryid
> FROM {question} q
> JOIN {question_versions} qv ON q.id = qv.questionid
> JOIN {quiz_slots} qs ON q.id = qs.questionid
> JOIN {modules} m ON m.name = 'quiz'
> JOIN {course_modules} cm ON cm.module = m.id AND cm.instance = qs.quizid
> JOIN {context} c ON c.instanceid = cm.id AND c.contextlevel = " . CONTEXT_MODULE . "
> WHERE q.qtype <> 'random'";
< if ($oldversion < 2019120500.01) {
< // Delete any role assignments for roles which no longer exist.
< $DB->delete_records_select('role_assignments', "roleid NOT IN (SELECT id FROM {role})");
> // Inserting question_references data.
> $DB->execute($sql);
> $transaction->allow_commit();
// Main savepoint reached.
< upgrade_main_savepoint(true, 2019120500.01);
> upgrade_main_savepoint(true, 2022020200.06);
}
< if ($oldversion < 2019121800.00) {
< // Upgrade MIME types for existing streaming files.
< $filetypes = array(
< '%.fmp4' => 'video/mp4',
< '%.ts' => 'video/MP2T',
< '%.mpd' => 'application/dash+xml',
< '%.m3u8' => 'application/x-mpegURL',
< );
> // Finally, drop fields from question table.
> if ($oldversion < 2022020200.07) {
> // Define fields to be dropped from questions.
> $table = new xmldb_table('question');
< $select = $DB->sql_like('filename', '?', false);
< foreach ($filetypes as $extension => $mimetype) {
< $DB->set_field_select(
< 'files',
< 'mimetype',
< $mimetype,
< $select,
< array($extension)
< );
> $field = new xmldb_field('version');
> // Conditionally launch drop field version.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
< upgrade_main_savepoint(true, 2019121800.00);
> $field = new xmldb_field('hidden');
> // Conditionally launch drop field hidden.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
< if ($oldversion < 2019122000.01) {
< // Clean old upgrade setting not used anymore.
< unset_config('linkcoursesectionsupgradescriptwasrun');
< upgrade_main_savepoint(true, 2019122000.01);
> // Define index categoryidnumber (not unique) to be dropped form question.
> $index = new xmldb_index('categoryidnumber', XMLDB_INDEX_UNIQUE, ['category', 'idnumber']);
>
> // Conditionally launch drop index categoryidnumber.
> if ($dbman->index_exists($table, $index)) {
> $dbman->drop_index($table, $index);
}
< if ($oldversion < 2020010900.02) {
< $table = new xmldb_table('event');
> // Define key category (foreign) to be dropped form questions.
> $key = new xmldb_key('category', XMLDB_KEY_FOREIGN, ['category'], 'question_categories', ['id']);
< // This index will improve the performance when the Events API retrieves category and group events.
< $index = new xmldb_index('eventtype', XMLDB_INDEX_NOTUNIQUE, ['eventtype']);
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> // Launch drop key category.
> $dbman->drop_key($table, $key);
>
> $field = new xmldb_field('idnumber');
> // Conditionally launch drop field idnumber.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
< // This index improves the performance of backups, deletion and visibilty changes on activities.
< $index = new xmldb_index('modulename-instance', XMLDB_INDEX_NOTUNIQUE, ['modulename', 'instance']);
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> $field = new xmldb_field('category');
> // Conditionally launch drop field category.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
< upgrade_main_savepoint(true, 2020010900.02);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022020200.07);
}
< if ($oldversion < 2020011700.02) {
< // Delete all orphaned subscription events.
< $select = "subscriptionid IS NOT NULL
< AND subscriptionid NOT IN (SELECT id from {event_subscriptions})";
< $DB->delete_records_select('event', $select);
> if ($oldversion < 2022021100.01) {
> $sql = "SELECT preset.*
> FROM {adminpresets} preset
> INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid
> WHERE it.name = :name AND it.value = :value AND preset.iscore > 0";
> // Some settings and plugins have been added/removed to the Starter and Full preset. Add them to the core presets if
> // they haven't been included yet.
> $params = ['name' => get_string('starterpreset', 'core_adminpresets'), 'iscore' => 1];
> $starterpreset = $DB->get_record('adminpresets', $params);
> if (!$starterpreset) {
> // Starter admin preset might have been created using the English name.
> $name = get_string_manager()->get_string('starterpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $name;
> $starterpreset = $DB->get_record('adminpresets', $params);
> }
> if (!$starterpreset) {
> // We tried, but we didn't find starter by name. Let's find a core preset that sets 'usecomments' setting to 0.
> $params = ['name' => 'usecomments', 'value' => '0'];
> $starterpreset = $DB->get_record_sql($sql, $params);
> }
>
> $params = ['name' => get_string('fullpreset', 'core_adminpresets')];
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> if (!$fullpreset) {
> // Full admin preset might have been created using the English name.
> $name = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $name;
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> }
> if (!$fullpreset) {
> // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1.
> $params = ['name' => 'usecomments', 'value' => '1'];
> $fullpreset = $DB->get_record_sql($sql, $params);
> }
>
> $settings = [
> // Settings. Hide Guest login button for Starter preset (and back to show for Full).
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'none',
> 'name' => 'guestloginbutton',
> 'value' => '0',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'none',
> 'name' => 'guestloginbutton',
> 'value' => '1',
> ],
> // Settings. Set Activity chooser tabs to "Starred, All, Recommended"(1) for Starter and back it to default(0) for Full.
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'none',
> 'name' => 'activitychoosertabmode',
> 'value' => '1',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'none',
> 'name' => 'activitychoosertabmode',
> 'value' => '0',
> ],
> ];
> foreach ($settings as $notused => $setting) {
> $params = ['adminpresetid' => $setting['presetid'], 'plugin' => $setting['plugin'], 'name' => $setting['name']];
> if (!$DB->record_exists('adminpresets_it', $params)) {
> $record = new \stdClass();
> $record->adminpresetid = $setting['presetid'];
> $record->plugin = $setting['plugin'];
> $record->name = $setting['name'];
> $record->value = $setting['value'];
> $DB->insert_record('adminpresets_it', $record);
> }
> }
< upgrade_main_savepoint(true, 2020011700.02);
> $plugins = [
> // Plugins. Blocks. Disable/enable Online users, Recently accessed courses and Starred courses.
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'block',
> 'name' => 'online_users',
> 'enabled' => '0',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'block',
> 'name' => 'online_users',
> 'enabled' => '1',
> ],
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'block',
> 'name' => 'recentlyaccessedcourses',
> 'enabled' => '0',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'block',
> 'name' => 'recentlyaccessedcourses',
> 'enabled' => '1',
> ],
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'block',
> 'name' => 'starredcourses',
> 'enabled' => '0',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'block',
> 'name' => 'starredcourses',
> 'enabled' => '1',
> ],
> // Plugins. Enrolments. Disable/enable Guest access.
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'enrol',
> 'name' => 'guest',
> 'enabled' => '0',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'enrol',
> 'name' => 'guest',
> 'enabled' => '1',
> ],
> ];
> foreach ($plugins as $notused => $plugin) {
> $params = ['adminpresetid' => $plugin['presetid'], 'plugin' => $plugin['plugin'], 'name' => $plugin['name']];
> if (!$DB->record_exists('adminpresets_plug', $params)) {
> $record = new \stdClass();
> $record->adminpresetid = $plugin['presetid'];
> $record->plugin = $plugin['plugin'];
> $record->name = $plugin['name'];
> $record->enabled = $plugin['enabled'];
> $DB->insert_record('adminpresets_plug', $record);
> }
}
< if ($oldversion < 2020013000.01) {
< global $DB;
< // Delete any associated files.
< $fs = get_file_storage();
< $sql = "SELECT cuc.id, cuc.userid
< FROM {competency_usercomp} cuc
< LEFT JOIN {user} u ON cuc.userid = u.id
< WHERE u.deleted = 1";
< $usercompetencies = $DB->get_records_sql($sql);
< foreach ($usercompetencies as $usercomp) {
< $DB->delete_records('competency_evidence', ['usercompetencyid' => $usercomp->id]);
< $DB->delete_records('competency_usercompcourse', ['userid' => $usercomp->userid]);
< $DB->delete_records('competency_usercompplan', ['userid' => $usercomp->userid]);
< $DB->delete_records('competency_usercomp', ['userid' => $usercomp->userid]);
> // Settings: Remove customusermenuitems setting from Starter and Full presets.
> $sql = "(adminpresetid = ? OR adminpresetid = ?) AND plugin = 'none' AND name = 'customusermenuitems'";
> $params = [$starterpreset->id, $fullpreset->id];
> $DB->delete_records_select('adminpresets_it', $sql, $params);
>
> // Plugins. Question types. Re-enable Description and Essay for Starter.
> $sql = "(adminpresetid = ? OR adminpresetid = ?) AND plugin = 'qtype' AND (name = 'description' OR name = 'essay')";
> $DB->delete_records_select('adminpresets_plug', $sql, $params);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022021100.01);
>
}
< $sql = "SELECT cue.id, cue.userid
< FROM {competency_userevidence} cue
< LEFT JOIN {user} u ON cue.userid = u.id
< WHERE u.deleted = 1";
< $userevidences = $DB->get_records_sql($sql);
< foreach ($userevidences as $userevidence) {
< $DB->delete_records('competency_userevidencecomp', ['userevidenceid' => $userevidence->id]);
< $DB->delete_records('competency_userevidence', ['id' => $userevidence->id]);
> if ($oldversion < 2022021100.02) {
> $table = new xmldb_table('task_scheduled');
>
> // Changing precision of field minute on table task_scheduled to (200).
> $field = new xmldb_field('minute', XMLDB_TYPE_CHAR, '200', null, XMLDB_NOTNULL, null, null, 'blocking');
> $dbman->change_field_precision($table, $field);
> // Changing precision of field hour on table task_scheduled to (70).
> $field = new xmldb_field('hour', XMLDB_TYPE_CHAR, '70', null, XMLDB_NOTNULL, null, null, 'minute');
> $dbman->change_field_precision($table, $field);
> // Changing precision of field day on table task_scheduled to (90).
> $field = new xmldb_field('day', XMLDB_TYPE_CHAR, '90', null, XMLDB_NOTNULL, null, null, 'hour');
> $dbman->change_field_precision($table, $field);
> // Changing precision of field month on table task_scheduled to (30).
> $field = new xmldb_field('month', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, 'day');
> $dbman->change_field_precision($table, $field);
< if ($record = $DB->get_record('context', ['contextlevel' => CONTEXT_USER, 'instanceid' => $userevidence->userid],
< '*', IGNORE_MISSING)) {
< // Delete all orphaned user evidences files.
< $fs->delete_area_files($record->id, 'core_competency', 'userevidence', $userevidence->userid);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022021100.02);
> }
>
> if ($oldversion < 2022022600.01) {
> // Get all processor and existing preferences.
> $processors = $DB->get_records('message_processors');
> $providers = $DB->get_records('message_providers', null, '', 'id, name, component');
> $existingpreferences = get_config('message');
>
> foreach ($processors as $processor) {
> foreach ($providers as $provider) {
> // Setting default preference name.
> $componentproviderbase = $provider->component . '_' . $provider->name;
> $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_locked';
> // If we do not have this setting yet, set it to 0.
> if (!isset($existingpreferences->{$preferencename})) {
> set_config($preferencename, 0, 'message');
> }
}
}
< $sql = "SELECT cp.id
< FROM {competency_plan} cp
< LEFT JOIN {user} u ON cp.userid = u.id
< WHERE u.deleted = 1";
< $userplans = $DB->get_records_sql($sql);
< foreach ($userplans as $userplan) {
< $DB->delete_records('competency_plancomp', ['planid' => $userplan->id]);
< $DB->delete_records('competency_plan', ['id' => $userplan->id]);
> upgrade_main_savepoint(true, 2022022600.01);
}
< // Main savepoint reached.
< upgrade_main_savepoint(true, 2020013000.01);
> if ($oldversion < 2022030100.00) {
> $sql = "SELECT preset.*
> FROM {adminpresets} preset
> INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid
> WHERE it.name = :name AND it.value = :value AND preset.iscore > 0";
>
> $name = get_string('starterpreset', 'core_adminpresets');
> $params = ['name' => $name, 'iscore' => 1];
> $starterpreset = $DB->get_record('adminpresets', $params);
> if (!$starterpreset) {
> // Starter admin preset might have been created using the English name. Let's change it to current language.
> $englishname = get_string_manager()->get_string('starterpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $englishname;
> $starterpreset = $DB->get_record('adminpresets', $params);
> }
> if (!$starterpreset) {
> // We tried, but we didn't find starter by name. Let's find a core preset that sets 'usecomments' setting to 0.
> $params = ['name' => 'usecomments', 'value' => '0'];
> $starterpreset = $DB->get_record_sql($sql, $params);
> }
> // The iscore field is already 1 for starterpreset, so we don't need to change it.
> // We only need to update the name and comment in case they are different to current language strings.
> if ($starterpreset && $starterpreset->name != $name) {
> $starterpreset->name = $name;
> $starterpreset->comments = get_string('starterpresetdescription', 'core_adminpresets');
> $DB->update_record('adminpresets', $starterpreset);
}
< if ($oldversion < 2020040200.01) {
< // Clean up completion criteria records referring to courses that no longer exist.
< $select = 'criteriatype = :type AND courseinstance NOT IN (SELECT id FROM {course})';
< $params = ['type' => 8]; // COMPLETION_CRITERIA_TYPE_COURSE.
> // Let's mark Full admin presets with current FULL_PRESETS value and change the name to current language.
> $name = get_string('fullpreset', 'core_adminpresets');
> $params = ['name' => $name];
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> if (!$fullpreset) {
> // Full admin preset might have been created using the English name.
> $englishname = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $englishname;
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> }
> if (!$fullpreset) {
> // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1.
> $params = ['name' => 'usecomments', 'value' => '1'];
> $fullpreset = $DB->get_record_sql($sql, $params);
> }
> if ($fullpreset) {
> // We need to update iscore field value, whether the name is the same or not.
> $fullpreset->name = $name;
> $fullpreset->comments = get_string('fullpresetdescription', 'core_adminpresets');
> $fullpreset->iscore = 2;
> $DB->update_record('adminpresets', $fullpreset);
>
> // We are applying again changes made on 2022011100.01 upgrading step because of MDL-73953 bug.
> $blocknames = ['course_summary', 'feedback', 'rss_client', 'selfcompletion'];
> list($blocksinsql, $blocksinparams) = $DB->get_in_or_equal($blocknames);
>
> // Remove entries from the adminpresets_app_plug table (in case the preset has been applied).
> $appliedpresets = $DB->get_records('adminpresets_app', ['adminpresetid' => $fullpreset->id], '', 'id');
> if ($appliedpresets) {
> list($appsinsql, $appsinparams) = $DB->get_in_or_equal(array_keys($appliedpresets));
> $sql = "adminpresetapplyid $appsinsql AND plugin='block' AND name $blocksinsql";
> $params = array_merge($appsinparams, $blocksinparams);
> $DB->delete_records_select('adminpresets_app_plug', $sql, $params);
> }
>
> // Remove entries for these blocks from the adminpresets_plug table.
> $sql = "adminpresetid = ? AND plugin='block' AND name $blocksinsql";
> $params = array_merge([$fullpreset->id], $blocksinparams);
> $DB->delete_records_select('adminpresets_plug', $sql, $params);
> }
< $DB->delete_records_select('course_completion_criteria', $select, $params);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022030100.00);
> }
> if ($oldversion < 2022031100.01) {
// Main savepoint reached.
> $reportsusermenuitem = 'reports,core_reportbuilder|/reportbuilder/index.php';
upgrade_main_savepoint(true, 2020040200.01);
> upgrade_add_item_to_usermenu($reportsusermenuitem);
< upgrade_main_savepoint(true, 2020040200.01);
> upgrade_main_savepoint(true, 2022031100.01);
< if ($oldversion < 2020040700.00) {
< // Remove deprecated Mozilla OpenBadges backpack.
< $url = 'https://backpack.openbadges.org';
< $bp = $DB->get_record('badge_external_backpack', ['backpackapiurl' => $url]);
< if ($bp) {
< // Remove connections for users to this backpack.
< $sql = "SELECT DISTINCT bb.id
< FROM {badge_backpack} bb
< LEFT JOIN {badge_external} be ON be. backpackid = bb.externalbackpackid
< WHERE bb.externalbackpackid = :backpackid";
< $params = ['backpackid' => $bp->id];
< $externalbackpacks = $DB->get_fieldset_sql($sql, $params);
< if ($externalbackpacks) {
< list($sql, $params) = $DB->get_in_or_equal($externalbackpacks);
> if ($oldversion < 2022032200.01) {
>
> // Define index to be added to question_references.
> $table = new xmldb_table('question_references');
> $index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE,
> ['usingcontextid', 'component', 'questionarea', 'itemid']);
< // Delete user external collections references to this backpack.
< $DB->execute("DELETE FROM {badge_external} WHERE backpackid " . $sql, $params);
> // Conditionally launch add field id.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
}
< $DB->delete_records('badge_backpack', ['externalbackpackid' => $bp->id]);
< // Delete deprecated backpack entry.
< $DB->delete_records('badge_external_backpack', ['backpackapiurl' => $url]);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022032200.01);
}
< // Set active external backpack to Badgr.io.
< $url = 'https://api.badgr.io/v2';
< if ($bp = $DB->get_record('badge_external_backpack', ['backpackapiurl' => $url])) {
< set_config('badges_site_backpack', $bp->id);
< } else {
< unset_config('badges_site_backpack');
> if ($oldversion < 2022032200.02) {
>
> // Define index to be added to question_references.
> $table = new xmldb_table('question_set_references');
> $index = new xmldb_index('context-component-area-itemid', XMLDB_INDEX_UNIQUE,
> ['usingcontextid', 'component', 'questionarea', 'itemid']);
>
> // Conditionally launch add field id.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
}
< upgrade_main_savepoint(true, 2020040700.00);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022032200.02);
}
< if ($oldversion < 2020041500.00) {
< // Define table to store contentbank contents.
< $table = new xmldb_table('contentbank_content');
> if ($oldversion < 2022041200.01) {
< // Adding fields to table content_bank.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
< $table->add_field('contenttype', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null);
< $table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('instanceid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('configdata', XMLDB_TYPE_TEXT, null, null, null, null, null);
< $table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
> // The original default admin presets "sensible settings" (those that should be treated as sensitive).
> $originalsensiblesettings = 'recaptchapublickey@@none, recaptchaprivatekey@@none, googlemapkey3@@none, ' .
> 'secretphrase@@url, cronremotepassword@@none, smtpuser@@none, smtppass@none, proxypassword@@none, ' .
> 'quizpassword@@quiz, allowedip@@none, blockedip@@none, dbpass@@logstore_database, messageinbound_hostpass@@none, ' .
> 'bind_pw@@auth_cas, pass@@auth_db, bind_pw@@auth_ldap, dbpass@@enrol_database, bind_pw@@enrol_ldap, ' .
> 'server_password@@search_solr, ssl_keypassword@@search_solr, alternateserver_password@@search_solr, ' .
> 'alternatessl_keypassword@@search_solr, test_password@@cachestore_redis, password@@mlbackend_python';
< // Adding keys to table contentbank_content.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('contextid', XMLDB_KEY_FOREIGN, ['contextid'], 'context', ['id']);
< $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
< $table->add_key('usercreated', XMLDB_KEY_FOREIGN, ['usercreated'], 'user', ['id']);
> // Check if the current config matches the original default, upgrade to new default if so.
> if (get_config('adminpresets', 'sensiblesettings') === $originalsensiblesettings) {
> $newsensiblesettings = "{$originalsensiblesettings}, badges_badgesalt@@none, calendar_exportsalt@@none";
> set_config('sensiblesettings', $newsensiblesettings, 'adminpresets');
> }
< // Adding indexes to table contentbank_content.
< $table->add_index('name', XMLDB_INDEX_NOTUNIQUE, ['name']);
< $table->add_index('instance', XMLDB_INDEX_NOTUNIQUE, ['contextid', 'contenttype', 'instanceid']);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022041200.01);
> }
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Automatically generated Moodle v4.0.0 release upgrade line.
> // Put any upgrade step following this.
>
> if ($oldversion < 2022042900.01) {
> // Social custom fields could had been created linked to category id = 1. Let's check category 1 exists.
> if (!$DB->get_record('user_info_category', ['id' => 1])) {
> // Let's check if we have any custom field linked to category id = 1.
> $fields = $DB->get_records('user_info_field', ['categoryid' => 1]);
> if (!empty($fields)) {
> $categoryid = $DB->get_field_sql('SELECT min(id) from {user_info_category}');
> foreach ($fields as $field) {
> $field->categoryid = $categoryid;
> $DB->update_record('user_info_field', $field);
> }
> }
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020041500.00);
> upgrade_main_savepoint(true, 2022042900.01);
}
< if ($oldversion < 2020041700.01) {
< // Upgrade h5p MIME type for existing h5p files.
< $select = $DB->sql_like('filename', '?', false);
< $DB->set_field_select(
< 'files',
< 'mimetype',
< 'application/zip.h5p',
< $select,
< array('%.h5p')
< );
> if ($oldversion < 2022051000.00) {
> // Add index to the sid field in the external_tokens table.
> $table = new xmldb_table('external_tokens');
> $index = new xmldb_index('sid', XMLDB_INDEX_NOTUNIQUE, ['sid']);
>
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
> }
< upgrade_main_savepoint(true, 2020041700.01);
> upgrade_main_savepoint(true, 2022051000.00);
}
< if ($oldversion < 2020042800.01) {
< // Delete obsolete config value.
< unset_config('enablesafebrowserintegration');
< // Clean up config of the old plugin.
< unset_all_config_for_plugin('quizaccess_safebrowser');
> if ($oldversion < 2022052500.00) {
> // Start an adhoc task to fix the file timestamps of restored files.
> $task = new core\task\fix_file_timestamps_task();
> \core\task\manager::queue_adhoc_task($task);
< upgrade_main_savepoint(true, 2020042800.01);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022052500.00);
}
< if ($oldversion < 2020051900.01) {
< // Define field component to be added to event.
< $table = new xmldb_table('event');
< $field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, null, null, null, 'repeatid');
> if ($oldversion < 2022052700.01) {
< // Conditionally launch add field component.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Define index timestarted_idx (not unique) to be added to task_adhoc.
> $table = new xmldb_table('task_adhoc');
> $index = new xmldb_index('timestarted_idx', XMLDB_INDEX_NOTUNIQUE, ['timestarted']);
>
> // Conditionally launch add index timestarted_idx.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
}
< // Define index component (not unique) to be added to event.
< $table = new xmldb_table('event');
< $index = new xmldb_index('component', XMLDB_INDEX_NOTUNIQUE, ['component', 'eventtype', 'instance']);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022052700.01);
> }
>
> if ($oldversion < 2022052700.02) {
>
> // Define index filename (not unique) to be added to files.
> $table = new xmldb_table('files');
> $index = new xmldb_index('filename', XMLDB_INDEX_NOTUNIQUE, ['filename']);
< // Conditionally launch add index component.
> // Conditionally launch add index filename.
if (!$dbman->index_exists($table, $index)) {
$dbman->add_index($table, $index);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020051900.01);
> upgrade_main_savepoint(true, 2022052700.02);
}
< if ($oldversion < 2020052000.00) {
< // Define table badge_backpack_oauth2 to be created.
< $table = new xmldb_table('badge_backpack_oauth2');
> if ($oldversion < 2022060300.01) {
< // Adding fields to table badge_backpack_oauth2.
< $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
< $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
< $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('externalbackpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
< $table->add_field('token', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
< $table->add_field('refreshtoken', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null);
< $table->add_field('expires', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< $table->add_field('scope', XMLDB_TYPE_TEXT, null, null, null, null, null);
> // Changing precision of field hidden on table grade_categories to (10).
> $table = new xmldb_table('grade_categories');
> $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timemodified');
< // Adding keys to table badge_backpack_oauth2.
< $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
< $table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
< $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']);
< $table->add_key('issuerid', XMLDB_KEY_FOREIGN, ['issuerid'], 'oauth2_issuer', ['id']);
< $table->add_key('externalbackpackid', XMLDB_KEY_FOREIGN, ['externalbackpackid'], 'badge_external_backpack', ['id']);
< // Conditionally launch create table for badge_backpack_oauth2.
< if (!$dbman->table_exists($table)) {
< $dbman->create_table($table);
> // Launch change of precision for field hidden.
> $dbman->change_field_precision($table, $field);
>
> // Changing precision of field hidden on table grade_categories_history to (10).
> $table = new xmldb_table('grade_categories_history');
> $field = new xmldb_field('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'aggregatesubcats');
>
> // Launch change of precision for field hidden.
> $dbman->change_field_precision($table, $field);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022060300.01);
}
< // Define field oauth2_issuerid to be added to badge_external_backpack.
< $tablebadgeexternalbackpack = new xmldb_table('badge_external_backpack');
< $fieldoauth2issuerid = new xmldb_field('oauth2_issuerid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'password');
< $keybackpackoauth2key = new xmldb_key('backpackoauth2key', XMLDB_KEY_FOREIGN, ['oauth2_issuerid'], 'oauth2_issuer', ['id']);
> if ($oldversion < 2022061000.01) {
> // Iterate over custom user menu items configuration, removing pix icon references.
> $customusermenuitems = str_replace(["\r\n", "\r"], "\n", $CFG->customusermenuitems);
>
> $lines = preg_split('/\n/', $customusermenuitems, -1, PREG_SPLIT_NO_EMPTY);
> $lines = array_map(static function(string $line): string {
> // Previous format was "<langstring>|<url>[|<pixicon>]" - pix icon is no longer supported.
> $lineparts = explode('|', trim($line), 3);
> // Return first two parts of line.
> return implode('|', array_slice($lineparts, 0, 2));
> }, $lines);
< // Conditionally launch add field oauth2_issuerid.
< if (!$dbman->field_exists($tablebadgeexternalbackpack, $fieldoauth2issuerid)) {
< $dbman->add_field($tablebadgeexternalbackpack, $fieldoauth2issuerid);
> set_config('customusermenuitems', implode("\n", $lines));
< // Launch add key backpackoauth2key.
< $dbman->add_key($tablebadgeexternalbackpack, $keybackpackoauth2key);
> upgrade_main_savepoint(true, 2022061000.01);
}
< // Define field assertion to be added to badge_external.
< $tablebadgeexternal = new xmldb_table('badge_external');
< $fieldassertion = new xmldb_field('assertion', XMLDB_TYPE_TEXT, null, null, null, null, null, 'entityid');
> if ($oldversion < 2022061500.00) {
> // Remove drawer-open-nav user preference for every user.
> $DB->delete_records('user_preferences', ['name' => 'drawer-open-nav']);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022061500.00);
< // Conditionally launch add field assertion.
< if (!$dbman->field_exists($tablebadgeexternal, $fieldassertion)) {
< $dbman->add_field($tablebadgeexternal, $fieldassertion);
}
> if ($oldversion < 2022072900.00) {
// Main savepoint reached.
> // Call the helper function that updates the foreign keys and indexes in MDL-49795.
upgrade_main_savepoint(true, 2020052000.00);
> upgrade_add_foreign_key_and_indexes();
}
>
< upgrade_main_savepoint(true, 2020052000.00);
> upgrade_main_savepoint(true, 2022072900.00);
< if ($oldversion < 2020052200.01) {
> if ($oldversion < 2022081200.01) {
< // Define field custom to be added to license.
< $table = new xmldb_table('license');
< $field = new xmldb_field('custom', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0');
> // Define field lang to be added to course_modules.
> $table = new xmldb_table('course_modules');
> $field = new xmldb_field('lang', XMLDB_TYPE_CHAR, '30', null, null, null, null, 'downloadcontent');
< // Conditionally launch add field custom.
> // Conditionally launch add field lang.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Define field sortorder to be added to license.
< $field = new xmldb_field('sortorder', XMLDB_TYPE_INTEGER, '5', null, XMLDB_NOTNULL, null, '0');
<
< // Conditionally launch add field sortorder.
< if (!$dbman->field_exists($table, $field)) {
< $dbman->add_field($table, $field);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022081200.01);
}
< // Define index license (not unique) to be added to files.
< $table = new xmldb_table('files');
< $index = new xmldb_index('license', XMLDB_INDEX_NOTUNIQUE, ['license']);
> if ($oldversion < 2022091000.01) {
> $table = new xmldb_table('h5p');
> $indexpathnamehash = new xmldb_index('pathnamehash_idx', XMLDB_INDEX_NOTUNIQUE, ['pathnamehash']);
< // Conditionally launch add index license.
< if (!$dbman->index_exists($table, $index)) {
< $dbman->add_index($table, $index);
> if (!$dbman->index_exists($table, $indexpathnamehash)) {
> $dbman->add_index($table, $indexpathnamehash);
> }
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022091000.01);
}
< // Upgrade the core license details.
< upgrade_core_licenses();
> if ($oldversion < 2022092200.01) {
>
> // Remove any orphaned tag instance records (pointing to non-existing context).
> $DB->delete_records_select('tag_instance', 'NOT EXISTS (
> SELECT ctx.id FROM {context} ctx WHERE ctx.id = {tag_instance}.contextid
> )');
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020052200.01);
> upgrade_main_savepoint(true, 2022092200.01);
}
< if ($oldversion < 2020060500.01) {
< // Define field moodlenetprofile to be added to user.
< $table = new xmldb_table('user');
< $field = new xmldb_field('moodlenetprofile', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'alternatename');
> if ($oldversion < 2022101400.01) {
> $table = new xmldb_table('competency_modulecomp');
> $field = new xmldb_field('overridegrade', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'ruleoutcome');
< // Conditionally launch add field moodlenetprofile.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020060500.01);
> upgrade_main_savepoint(true, 2022101400.01);
}
< // Automatically generated Moodle v3.9.0 release upgrade line.
< // Put any upgrade step following this.
< if ($oldversion < 2020061500.02) {
< // Update default digital age consent map according to the current legislation on each country.
> if ($oldversion < 2022101400.03) {
> // Define table to store completion viewed.
> $table = new xmldb_table('course_modules_viewed');
< // The default age of digital consent map for 38 and below.
< $oldageofdigitalconsentmap = implode(PHP_EOL, [
< '*, 16',
< 'AT, 14',
< 'ES, 14',
< 'US, 13'
< ]);
> // Adding fields to table course_modules_viewed.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('coursemoduleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'coursemoduleid');
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
< // Check if the current age of digital consent map matches the old one.
< if (get_config('moodle', 'agedigitalconsentmap') === $oldageofdigitalconsentmap) {
< // If the site is still using the old defaults, upgrade to the new default.
< $ageofdigitalconsentmap = implode(PHP_EOL, [
< '*, 16',
< 'AT, 14',
< 'BE, 13',
< 'BG, 14',
< 'CY, 14',
< 'CZ, 15',
< 'DK, 13',
< 'EE, 13',
< 'ES, 14',
< 'FI, 13',
< 'FR, 15',
< 'GB, 13',
< 'GR, 15',
< 'IT, 14',
< 'LT, 14',
< 'LV, 13',
< 'MT, 13',
< 'NO, 13',
< 'PT, 13',
< 'SE, 13',
< 'US, 13'
< ]);
< set_config('agedigitalconsentmap', $ageofdigitalconsentmap);
> // Adding keys to table course_modules_viewed.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
>
> // Adding indexes to table course_modules_viewed.
> $table->add_index('coursemoduleid', XMLDB_INDEX_NOTUNIQUE, ['coursemoduleid']);
> $table->add_index('userid-coursemoduleid', XMLDB_INDEX_UNIQUE, ['userid', 'coursemoduleid']);
>
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
}
< upgrade_main_savepoint(true, 2020061500.02);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022101400.03);
> }
>
> if ($oldversion < 2022101400.04) {
> // Add legacy data to the new table.
> $transaction = $DB->start_delegated_transaction();
> upgrade_set_timeout(3600);
> $sql = "INSERT INTO {course_modules_viewed}
> (userid, coursemoduleid, timecreated)
> SELECT userid, coursemoduleid, timemodified
> FROM {course_modules_completion}
> WHERE viewed = 1";
> $DB->execute($sql);
> $transaction->allow_commit();
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022101400.04);
> }
>
> if ($oldversion < 2022101400.05) {
> // Define field viewed to be dropped from course_modules_completion.
> $table = new xmldb_table('course_modules_completion');
> $field = new xmldb_field('viewed');
>
> // Conditionally launch drop field viewed.
> if ($dbman->field_exists($table, $field)) {
> $dbman->drop_field($table, $field);
}
< if ($oldversion < 2020061501.01) {
< // Clean up completion criteria records referring to NULL course prerequisites.
< $select = 'criteriatype = :type AND courseinstance IS NULL';
< $params = ['type' => 8]; // COMPLETION_CRITERIA_TYPE_COURSE.
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022101400.05);
> }
< $DB->delete_records_select('course_completion_criteria', $select, $params);
> if ($oldversion < 2022102800.01) {
> // For sites with "contact site support" already available (4.0.x), maintain existing functionality.
> if ($oldversion >= 2022041900.00) {
> set_config('supportavailability', CONTACT_SUPPORT_ANYONE);
> } else {
> // Sites which did not previously have the "contact site support" feature default to it requiring authentication.
> set_config('supportavailability', CONTACT_SUPPORT_AUTHENTICATED);
> }
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020061501.01);
> upgrade_main_savepoint(true, 2022102800.01);
}
< if ($oldversion < 2020061501.04) {
< // Restore and set the guest user if it has been previously removed via GDPR, or set to an nonexistent
< // user account.
< $currentguestuser = $DB->get_record('user', array('id' => $CFG->siteguest));
> if ($oldversion < 2022110600.00) {
> // If webservice_xmlrpc isn't any longer installed, remove its configuration,
> // capabilities and presence in other settings.
> if (!file_exists($CFG->dirroot . '/webservice/xmlrpc/version.php')) {
> // No DB structures to delete in this plugin.
< if (!$currentguestuser) {
< if (!$guest = $DB->get_record('user', array('username' => 'guest', 'mnethostid' => $CFG->mnet_localhost_id))) {
< // Create a guest user account.
< $guest = new stdClass();
< $guest->auth = 'manual';
< $guest->username = 'guest';
< $guest->password = hash_internal_user_password('guest');
< $guest->firstname = get_string('guestuser');
< $guest->lastname = ' ';
< $guest->email = 'root@localhost';
< $guest->description = get_string('guestuserinfo');
< $guest->mnethostid = $CFG->mnet_localhost_id;
< $guest->confirmed = 1;
< $guest->lang = $CFG->lang;
< $guest->timemodified= time();
< $guest->id = $DB->insert_record('user', $guest);
> // Remove capabilities.
> capabilities_cleanup('webservice_xmlrpc');
>
> // Remove own configuration.
> unset_all_config_for_plugin('webservice_xmlrpc');
>
> // Remove it from the enabled protocols if it was there.
> $protos = get_config('core', 'webserviceprotocols');
> $protoarr = explode(',', $protos);
> $protoarr = array_filter($protoarr, function($ele) {
> return trim($ele) !== 'xmlrpc';
> });
> $protos = implode(',', $protoarr);
> set_config('webserviceprotocols', $protos);
}
< // Set the guest user.
< set_config('siteguest', $guest->id);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022110600.00);
}
> // Automatically generated Moodle v4.1.0 release upgrade line.
// Main savepoint reached.
> // Put any upgrade step following this.
upgrade_main_savepoint(true, 2020061501.04);
>
}
> if ($oldversion < 2022120900.01) {
>
if ($oldversion < 2020061501.09) {
> // Remove any orphaned role assignment records (pointing to non-existing roles).
// Delete all user evidence files from users that have been deleted.
> $DB->delete_records_select('role_assignments', 'NOT EXISTS (
$sql = "SELECT DISTINCT f.*
> SELECT r.id FROM {role} r WHERE r.id = {role_assignments}.roleid
FROM {files} f
> )');
LEFT JOIN {context} c ON f.contextid = c.id
>
< upgrade_main_savepoint(true, 2020061501.04);
> upgrade_main_savepoint(true, 2022120900.01);
< if ($oldversion < 2020061501.09) {
< // Delete all user evidence files from users that have been deleted.
< $sql = "SELECT DISTINCT f.*
< FROM {files} f
< LEFT JOIN {context} c ON f.contextid = c.id
< WHERE f.component = :component
< AND f.filearea = :filearea
< AND c.id IS NULL";
< $stalefiles = $DB->get_records_sql($sql, ['component' => 'core_competency', 'filearea' => 'userevidence']);
> if ($oldversion < 2022121600.01) {
> // Define index blocknameindex (not unique) to be added to block_instances.
> $table = new xmldb_table('block_instances');
> $index = new xmldb_index('blocknameindex', XMLDB_INDEX_NOTUNIQUE, ['blockname']);
< $fs = get_file_storage();
< foreach ($stalefiles as $stalefile) {
< $fs->get_file_instance($stalefile)->delete();
> // Conditionally launch add index blocknameindex.
> if (!$dbman->index_exists($table, $index)) {
> $dbman->add_index($table, $index);
> }
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2022121600.01);
< upgrade_main_savepoint(true, 2020061501.09);
> if ($oldversion < 2023010300.00) {
> // The useexternalyui setting has been removed.
> unset_config('useexternalyui');
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023010300.00);
< if ($oldversion < 2020061501.11) {
> if ($oldversion < 2023020800.00) {
> // If cachestore_memcached is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/cache/stores/memcached/version.php')) {
> // Clean config.
> unset_all_config_for_plugin('cachestore_memcached');
> }
< // Define field metadatasettings to be added to h5p_libraries.
< $table = new xmldb_table('h5p_libraries');
< $field = new xmldb_field('metadatasettings', XMLDB_TYPE_TEXT, null, null, null, null, null, 'coreminor');
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023020800.00);
> }
< // Conditionally launch add field metadatasettings.
> if ($oldversion < 2023021700.01) {
> // Define field pdfexportfont to be added to course.
> $table = new xmldb_table('course');
> $field = new xmldb_field('pdfexportfont', XMLDB_TYPE_CHAR, '50', null, false, false, null, 'showcompletionconditions');
>
> // Conditionally launch add field pdfexportfont.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
< // Get installed library files that have no metadata settings value.
< $params = [
< 'component' => 'core_h5p',
< 'filearea' => 'libraries',
< 'filename' => 'library.json',
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023021700.01);
> }
>
> if ($oldversion < 2023022000.00) {
> // Remove grade_report_showquickfeedback, grade_report_enableajax, grade_report_showeyecons,
> // grade_report_showlocks, grade_report_showanalysisicon preferences for every user.
> $DB->delete_records('user_preferences', ['name' => 'grade_report_showquickfeedback']);
> $DB->delete_records('user_preferences', ['name' => 'grade_report_enableajax']);
> $DB->delete_records('user_preferences', ['name' => 'grade_report_showeyecons']);
> $DB->delete_records('user_preferences', ['name' => 'grade_report_showlocks']);
> $DB->delete_records('user_preferences', ['name' => 'grade_report_showanalysisicon']);
>
> // The grade_report_showquickfeedback, grade_report_enableajax, grade_report_showeyecons,
> // grade_report_showlocks, grade_report_showanalysisicon settings have been removed.
> unset_config('grade_report_showquickfeedback');
> unset_config('grade_report_enableajax');
> unset_config('grade_report_showeyecons');
> unset_config('grade_report_showlocks');
> unset_config('grade_report_showanalysisicon');
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023022000.00);
> }
>
> if ($oldversion < 2023030300.01) {
> $sql = "SELECT preset.*
> FROM {adminpresets} preset
> INNER JOIN {adminpresets_it} it ON preset.id = it.adminpresetid
> WHERE it.name = :name AND it.value = :value AND preset.iscore > 0";
> // Some settings and plugins have been added/removed to the Starter and Full preset. Add them to the core presets if
> // they haven't been included yet.
> $params = ['name' => get_string('starterpreset', 'core_adminpresets'), 'iscore' => 1];
> $starterpreset = $DB->get_record('adminpresets', $params);
> if (!$starterpreset) {
> // Starter admin preset might have been created using the English name.
> $name = get_string_manager()->get_string('starterpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $name;
> $starterpreset = $DB->get_record('adminpresets', $params);
> }
> if (!$starterpreset) {
> // We tried, but we didn't find starter by name. Let's find a core preset that sets 'usecomments' setting to 0.
> $params = ['name' => 'usecomments', 'value' => '0'];
> $starterpreset = $DB->get_record_sql($sql, $params);
> }
>
> $params = ['name' => get_string('fullpreset', 'core_adminpresets')];
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> if (!$fullpreset) {
> // Full admin preset might have been created using the English name.
> $name = get_string_manager()->get_string('fullpreset', 'core_adminpresets', null, 'en');
> $params['name'] = $name;
> $fullpreset = $DB->get_record_select('adminpresets', 'name = :name and iscore > 0', $params);
> }
> if (!$fullpreset) {
> // We tried, but we didn't find full by name. Let's find a core preset that sets 'usecomments' setting to 1.
> $params = ['name' => 'usecomments', 'value' => '1'];
> $fullpreset = $DB->get_record_sql($sql, $params);
> }
>
> $settings = [
> // Settings. Set Activity chooser tabs to "Starred, Recommended, All"(5) for Starter and back it to default(3) for Full.
> [
> 'presetid' => $starterpreset->id,
> 'plugin' => 'none',
> 'name' => 'activitychoosertabmode',
> 'value' => '4',
> ],
> [
> 'presetid' => $fullpreset->id,
> 'plugin' => 'none',
> 'name' => 'activitychoosertabmode',
> 'value' => '3',
> ],
];
< $sql = "SELECT l.id, f.id as fileid
< FROM {files} f
< LEFT JOIN {h5p_libraries} l ON f.itemid = l.id
< WHERE f.component = :component
< AND f.filearea = :filearea
< AND f.filename = :filename";
< $libraries = $DB->get_records_sql($sql, $params);
> foreach ($settings as $notused => $setting) {
> $params = ['adminpresetid' => $setting['presetid'], 'plugin' => $setting['plugin'], 'name' => $setting['name']];
> if (!$record = $DB->get_record('adminpresets_it', $params)) {
> $record = new \stdClass();
> $record->adminpresetid = $setting['presetid'];
> $record->plugin = $setting['plugin'];
> $record->name = $setting['name'];
> $record->value = $setting['value'];
> $DB->insert_record('adminpresets_it', $record);
> } else {
> $record->value = $setting['value'];
> $DB->update_record('adminpresets_it', $record);
> }
> }
< // Update metadatasettings field when the attribute is present in the library.json file.
< $fs = get_file_storage();
< foreach ($libraries as $library) {
< $jsonfile = $fs->get_file_by_id($library->fileid);
< $jsoncontent = json_decode($jsonfile->get_content());
< if (isset($jsoncontent->metadataSettings)) {
< unset($library->fileid);
< $library->metadatasettings = json_encode($jsoncontent->metadataSettings);
< $DB->update_record('h5p_libraries', $library);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023030300.01);
}
>
}
> if ($oldversion < 2023030300.02) {
> // If cachestore_mongodb is no longer present, remove it.
// Main savepoint reached.
> if (!file_exists($CFG->dirroot . '/cache/stores/mongodb/version.php')) {
upgrade_main_savepoint(true, 2020061501.11);
> // Clean config.
}
> unset_all_config_for_plugin('cachestore_mongodb');
< upgrade_main_savepoint(true, 2020061501.11);
> upgrade_main_savepoint(true, 2023030300.02);
< if ($oldversion < 2020061502.09) {
< // Delete orphaned course_modules_completion rows; these were not deleted properly
< // by remove_course_contents function.
< $DB->delete_records_select('course_modules_completion', "
< NOT EXISTS (
< SELECT 1
< FROM {course_modules} cm
< WHERE cm.id = {course_modules_completion}.coursemoduleid
< )");
< upgrade_main_savepoint(true, 2020061502.09);
> if ($oldversion < 2023030300.03) {
> // If editor_tinymce is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/lib/editor/tinymce/version.php')) {
> // Clean config.
> uninstall_plugin('editor', 'tinymce');
> $DB->delete_records('user_preferences', [
> 'name' => 'htmleditor',
> 'value' => 'tinymce',
> ]);
>
> if ($editors = get_config('core', 'texteditors')) {
> $editors = array_flip(explode(',', $editors));
> unset($editors['tinymce']);
> set_config('texteditors', implode(',', array_flip($editors)));
> }
> }
> upgrade_main_savepoint(true, 2023030300.03);
> }
>
> if ($oldversion < 2023031000.02) {
> // If editor_tinymce is no longer present, remove it's sub-plugins too.
> if (!file_exists($CFG->dirroot . '/lib/editor/tinymce/version.php')) {
> $DB->delete_records_select(
> 'config_plugins',
> $DB->sql_like('plugin', ':plugin'),
> ['plugin' => $DB->sql_like_escape('tinymce_') . '%']
> );
}
< if ($oldversion < 2020061502.10) {
< // Script to fix incorrect records of "hidden" field in existing grade items.
< $sql = "SELECT cm.instance, cm.course
< FROM {course_modules} cm
< JOIN {modules} m ON m.id = cm.module
< WHERE m.name = :module AND cm.visible = :visible";
< $hidequizlist = $DB->get_recordset_sql($sql, ['module' => 'quiz', 'visible' => 0]);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023031000.02);
> }
< foreach ($hidequizlist as $hidequiz) {
< $params = [
< 'itemmodule' => 'quiz',
< 'courseid' => $hidequiz->course,
< 'iteminstance' => $hidequiz->instance,
< ];
> if ($oldversion < 2023031400.01) {
> // Define field id to be added to groups.
> $table = new xmldb_table('groups');
> $field = new xmldb_field('visibility', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'picture');
< $DB->set_field('grade_items', 'hidden', 1, $params);
> // Conditionally launch add field visibility.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< $hidequizlist->close();
< upgrade_main_savepoint(true, 2020061502.10);
> // Define field participation to be added to groups.
> $field = new xmldb_field('participation', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'visibility');
>
> // Conditionally launch add field participation.
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
}
< if ($oldversion < 2020061502.12) {
< // Get the current guest user which is also set as 'deleted'.
< $guestuser = $DB->get_record('user', ['id' => $CFG->siteguest, 'deleted' => 1]);
< // If there is a deleted guest user, reset the user to not be deleted and make sure the related
< // user context exists.
< if ($guestuser) {
< $guestuser->deleted = 0;
< $DB->update_record('user', $guestuser);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023031400.01);
> }
< // Get the guest user context.
< $guestusercontext = $DB->get_record('context',
< ['contextlevel' => CONTEXT_USER, 'instanceid' => $guestuser->id]);
> if ($oldversion < 2023031400.02) {
< // If the guest user context does not exist, create it.
< if (!$guestusercontext) {
< $record = new stdClass();
< $record->contextlevel = CONTEXT_USER;
< $record->instanceid = $guestuser->id;
< $record->depth = 0;
< // The path is not known before insert.
< $record->path = null;
< $record->locked = 0;
> // Define table xapi_states to be created.
> $table = new xmldb_table('xapi_states');
< $record->id = $DB->insert_record('context', $record);
> // Adding fields to table xapi_states.
> $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
> $table->add_field('component', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
> $table->add_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('stateid', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
> $table->add_field('statedata', XMLDB_TYPE_TEXT, null, null, null, null, null);
> $table->add_field('registration', XMLDB_TYPE_CHAR, '255', null, null, null, null);
> $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
> $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
< // Update the path.
< $record->path = '/' . SYSCONTEXTID . '/' . $record->id;
< $record->depth = substr_count($record->path, '/');
< $DB->update_record('context', $record);
> // Adding keys to table xapi_states.
> $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
>
> // Adding indexes to table xapi_states.
> $table->add_index('component-itemid', XMLDB_INDEX_NOTUNIQUE, ['component', 'itemid']);
> $table->add_index('userid', XMLDB_INDEX_NOTUNIQUE, ['userid']);
> $table->add_index('timemodified', XMLDB_INDEX_NOTUNIQUE, ['timemodified']);
>
> // Conditionally launch create table for xapi_states.
> if (!$dbman->table_exists($table)) {
> $dbman->create_table($table);
}
>
}
> if (!isset($CFG->xapicleanupperiod)) {
> set_config('xapicleanupperiod', WEEKSECS * 8);
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020061502.12);
> upgrade_main_savepoint(true, 2023031400.02);
}
< if ($oldversion < 2020061502.13) {
< // Reset analytics model output dir if it's the default value.
< $modeloutputdir = get_config('analytics', 'modeloutputdir');
< if (strcasecmp($modeloutputdir, $CFG->dataroot . DIRECTORY_SEPARATOR . 'models') == 0) {
< set_config('modeloutputdir', '', 'analytics');
> if ($oldversion < 2023040600.01) {
> // If logstore_legacy is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/admin/tool/log/store/legacy/version.php')) {
> uninstall_plugin('logstore', 'legacy');
}
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020061502.13);
> upgrade_main_savepoint(true, 2023040600.01);
}
< if ($oldversion < 2020061502.14) {
< // Remove all the files with component='core_h5p' and filearea='editor' because they won't be used anymore.
< $fs = get_file_storage();
< $syscontext = context_system::instance();
< $fs->delete_area_files($syscontext->id, 'core_h5p', 'editor');
> if ($oldversion < 2023041100.00) {
> // Add public key field to user_devices table.
> $table = new xmldb_table('user_devices');
> $field = new xmldb_field('publickey', XMLDB_TYPE_TEXT, null, null, null, null, null, 'uuid');
>
> if (!$dbman->field_exists($table, $field)) {
> $dbman->add_field($table, $field);
> }
// Main savepoint reached.
< upgrade_main_savepoint(true, 2020061502.14);
> upgrade_main_savepoint(true, 2023041100.00);
}
< if ($oldversion < 2020061503.01) {
< // Get all lessons that are set with a completion criteria of 'requires grade' but with no grade type set.
< $sql = "SELECT cm.id
< FROM {course_modules} cm
< JOIN {lesson} l ON l.id = cm.instance
< JOIN {modules} m ON m.id = cm.module
< WHERE m.name = :name AND cm.completiongradeitemnumber IS NOT NULL AND l.grade = :grade";
> if ($oldversion < 2023042000.00) {
> // If mod_assignment is no longer present, remove it.
> if (!file_exists($CFG->dirroot . '/mod/assignment/version.php')) {
> // Delete all mod_assignment grade_grades orphaned data.
> $DB->delete_records_select(
> 'grade_grades', "itemid IN (SELECT id FROM {grade_items} WHERE itemtype = 'mod' AND itemmodule = 'assignment')"
> );
< do {
< if ($invalidconfigrations = $DB->get_records_sql($sql, ['name' => 'lesson', 'grade' => 0], 0, 1000)) {
< list($insql, $inparams) = $DB->get_in_or_equal(array_keys($invalidconfigrations), SQL_PARAMS_NAMED);
< $DB->set_field_select('course_modules', 'completiongradeitemnumber', null, "id $insql", $inparams);
> // Delete all mod_assignment grade_grades_history orphaned data.
> $DB->delete_records('grade_grades_history', ['source' => 'mod/assignment']);
>
> // Delete all mod_assignment grade_items orphaned data.
> $DB->delete_records('grade_items', ['itemtype' => 'mod', 'itemmodule' => 'assignment']);
>
> // Delete all mod_assignment grade_items_history orphaned data.
> $DB->delete_records('grade_items_history', ['itemtype' => 'mod', 'itemmodule' => 'assignment']);
>
> // Delete core mod_assignment subplugins.
> uninstall_plugin('assignment', 'offline');
> uninstall_plugin('assignment', 'online');
> uninstall_plugin('assignment', 'upload');
> uninstall_plugin('assignment', 'uploadsingle');
>
> // Delete other mod_assignment subplugins.
> $pluginnamelike = $DB->sql_like('plugin', ':pluginname');
> $subplugins = $DB->get_fieldset_select('config_plugins', 'plugin', "$pluginnamelike AND name = :name", [
> 'pluginname' => $DB->sql_like_escape('assignment_') . '%',
> 'name' => 'version',
> ]);
> foreach ($subplugins as $subplugin) {
> [$plugin, $subpluginname] = explode('_', $subplugin, 2);
> uninstall_plugin($plugin, $subpluginname);
}
< } while ($invalidconfigrations);
< upgrade_main_savepoint(true, 2020061503.01);
> // Delete mod_assignment.
> uninstall_plugin('mod', 'assignment');
}
< if ($oldversion < 2020061504.07) {
< // Get all the external backpacks and update the sortorder column, to avoid repeated/wrong values. As sortorder was not
< // used since now, the id column will be the criteria to follow for re-ordering them with a valid value.
< $i = 1;
< $records = $DB->get_records('badge_external_backpack', null, 'id ASC');
< foreach ($records as $record) {
< $record->sortorder = $i++;
< $DB->update_record('badge_external_backpack', $record);
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023042000.00);
}
< upgrade_main_savepoint(true, 2020061504.07);
> // Automatically generated Moodle v4.2.0 release upgrade line.
> // Put any upgrade step following this.
>
> if ($oldversion < 2023042400.03) {
>
> // Remove any orphaned role assignment records (pointing to non-existing roles).
> $DB->set_field('task_scheduled', 'disabled', 1, ['classname' => '\core\task\question_stats_cleanup_task']);
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023042400.03);
}
< if ($oldversion < 2020061506.05) {
< require_once($CFG->libdir . '/db/upgradelib.php');
> if ($oldversion < 2023042401.09) {
> // Upgrade yaml mime type for existing yaml and yml files.
> $filetypes = [
> '%.yaml' => 'application/yaml',
> '%.yml' => 'application/yaml,'
> ];
< // Check if this site has executed the problematic upgrade steps.
< $needsfixing = upgrade_calendar_site_status(false);
> $select = $DB->sql_like('filename', '?', false);
> foreach ($filetypes as $extension => $mimetype) {
> $DB->set_field_select(
> 'files',
> 'mimetype',
> $mimetype,
> $select,
> [$extension]
> );
> }
< // Only queue the task if this site has been affected by the problematic upgrade step.
< if ($needsfixing) {
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023042401.09);
> }
< // Create adhoc task to search and recover orphaned calendar events.
< $record = new \stdClass();
< $record->classname = '\core\task\calendar_fix_orphaned_events';
> if ($oldversion < 2023042402.03) {
< // Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
< $nextruntime = time() - 1;
< $record->nextruntime = $nextruntime;
< $DB->insert_record('task_adhoc', $record);
> // The previous default configuration had a typo, check for its presence and correct if necessary.
> $sensiblesettings = get_config('adminpresets', 'sensiblesettings');
> if (strpos($sensiblesettings, 'smtppass@none') !== false) {
> $newsensiblesettings = str_replace('smtppass@none', 'smtppass@@none', $sensiblesettings);
> set_config('sensiblesettings', $newsensiblesettings, 'adminpresets');
> }
>
> // Main savepoint reached.
> upgrade_main_savepoint(true, 2023042402.03);
> }
>
> if ($oldversion < 2023042402.11) {
> upgrade_core_licenses();
> upgrade_main_savepoint(true, 2023042402.11);
}
> if ($oldversion < 2023042402.14) {
// Main savepoint reached.
> // Delete datakey with datavalue -1.
upgrade_main_savepoint(true, 2020061506.05);
> $DB->delete_records('messageinbound_datakeys', ['datavalue' => '-1']);
< upgrade_main_savepoint(true, 2020061506.05);
> upgrade_main_savepoint(true, 2023042402.14);
return true;
}