Skip to content

Commit

Permalink
MDL-67853 message: Update notification config and preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
crazyserver committed Jan 27, 2022
1 parent e63604f commit e8ad1ea
Show file tree
Hide file tree
Showing 2 changed files with 243 additions and 1 deletion.
242 changes: 242 additions & 0 deletions lib/db/upgrade.php
Expand Up @@ -3567,5 +3567,247 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2022011100.01);
}

if ($oldversion < 2022012500.00) {
// Migrate default message output config.
$preferences = get_config('message');

$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;
}

$provider = $providerparts[0];
$preference = $providerparts[1];

// Extract and remove last part of the preference previously extracted: ie. permitted.
$parts = explode('_', $preference);
$key = array_pop($parts);

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);
}

// Join the rest of the parts: ie enrol_imsenterprise_imsenterprise_enrolment.
$prefname = implode('_', $parts);

if (!isset($treatedprefs[$prefname])) {
$treatedprefs[$prefname] = [];
}

// Save the value with the selected key.
$treatedprefs[$prefname][$key] = $value;
}
}

// Now take every preference previous treated and its values.
foreach ($treatedprefs as $prefname => $values) {
$enabled = []; // List of providers enabled for each preference.

// Enable if one of those is enabled.
$loggedin = isset($values['loggedin']) ? $values['loggedin'] : [];
foreach ($loggedin as $provider) {
$enabled[$provider] = 1;
}
$loggedoff = isset($values['loggedoff']) ? $values['loggedoff'] : [];
foreach ($loggedoff as $provider) {
$enabled[$provider] = 1;
}

// Do not treat those values again.
unset($values['loggedin']);
unset($values['loggedoff']);

// Translate rest of values coming from permitted "key".
foreach ($values as $provider => $value) {
$locked = false;

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.
}

// Save locked.
if ($locked) {
set_config($provider.'_provider_'.$prefname.'_locked', 1, 'message');
}
// Remove old value.
unset_config($provider.'_provider_'.$prefname.'_permitted', 'message');
}

// 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');
}

// Migrate user preferences. ie merging message_provider_moodle_instantmessage_loggedoff with
// message_provider_moodle_instantmessage_loggedin to message_provider_moodle_instantmessage_enabled.

$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 ($record->enabled != 'none' && !empty($record->enabled)) {
$enabledvalues = explode(',', $record->enabled);
} else {
$enabledvalues = [];
}

if ($record->loggedoff != 'none' && !empty($record->loggedoff)) {
$loggedoffvalues = explode(',', $record->loggedoff);
} else {
$loggedoffvalues = [];
}

$values = array_unique(array_merge($enabledvalues, $loggedoffvalues));
sort($values);

$newvalue = empty($values) ? 'none' : implode(',', $values);
if (!isset($changevalue[$newvalue])) {
$changevalue[$newvalue] = [];
}
$changevalue[$newvalue][] = $record->enabledid;

$deleterecords[] = $record->loggedoffid;
} else {
// They are the same, just delete loggedoff one.
$deleterecords[] = $record->loggedoffid;
}
$i++;
}
$rs->close();

// 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);
}

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);
}
}

if (!empty($deleterecords)) {
$deleteparams = [
'name' => $loggedoffname,
];
$deleteselect = 'name = :name AND id IN (' . implode(',', $deleterecords) . ')';
$DB->delete_records_select('user_preferences', $deleteselect, $deleteparams);
}

// Update progress.
$pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total.");
}
$rs->close();

// 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);

// Update progress.
$pbar->update($i, $total, "Upgrading user notifications preferences - $i/$total.");
}

core_plugin_manager::reset_caches();

// 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);

// Update progress.
$pbar->update($total, $total, "Upgrading user notifications preferences - $total/$total.");

upgrade_main_savepoint(true, 2022012500.00);
}

return true;
}
2 changes: 1 addition & 1 deletion version.php
Expand Up @@ -29,7 +29,7 @@

defined('MOODLE_INTERNAL') || die();

$version = 2022012100.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2022012500.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.
$release = '4.0dev+ (Build: 20220121)'; // Human-friendly version name
Expand Down

0 comments on commit e8ad1ea

Please sign in to comment.