diff --git a/admin/message.php b/admin/message.php index 69b293c22e0..1178a574f45 100644 --- a/admin/message.php +++ b/admin/message.php @@ -48,69 +48,52 @@ if (($form = data_submitted()) && confirm_sesskey()) { foreach ($providers as $provider) { $componentproviderbase = $provider->component.'_'.$provider->name; $disableprovidersetting = $componentproviderbase.'_disable'; - $providerdisabled = false; if (!isset($form->$disableprovidersetting)) { - $providerdisabled = true; $newpreferences[$disableprovidersetting] = 1; } else { $newpreferences[$disableprovidersetting] = 0; } - foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) { - $value = null; - $componentprovidersetting = $componentproviderbase.'_'.$setting; - if ($setting == 'permitted') { - // If we deal with permitted select element, we need to create individual - // setting for each possible processor. Note that this block will - // always be processed first after entring parental foreach iteration - // so we can change form values on this stage. - foreach ($processors as $processor) { - $value = ''; - if (isset($form->{$componentprovidersetting}[$processor->name])) { - $value = $form->{$componentprovidersetting}[$processor->name]; - } - // Ensure that loggedin loggedoff options are set correctly for this permission. - if (($value == 'disallowed') || $providerdisabled) { - // It might be better to unset them, but I can't figure out why that cause error. - $form->{$componentproviderbase.'_loggedin'}[$processor->name] = 0; - $form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 0; - } else if ($value == 'forced') { - $form->{$componentproviderbase.'_loggedin'}[$processor->name] = 1; - $form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 1; - } - // Record the site preference. - $newpreferences[$processor->name.'_provider_'.$componentprovidersetting] = $value; - } - } else { - $newsettings = array(); - if (property_exists($form, $componentprovidersetting)) { - // We must be processing loggedin or loggedoff checkboxes. - // Store defained comma-separated processors as setting value. - // Using array_filter eliminates elements set to 0 above. - $newsettings = array_keys(array_filter($form->{$componentprovidersetting})); - } - - // Let's join existing setting values for disabled processors. - $property = 'message_provider_'.$componentprovidersetting; - if (property_exists($preferences, $property)) { - $existingsetting = $preferences->$property; - foreach ($disabledprocessors as $disable) { - if (strpos($existingsetting, $disable->name) > -1) { - $newsettings[] = $disable->name; - } - } - } - - $value = join(',', $newsettings); - if (empty($value)) { - $value = null; + $componentprovidersetting = $componentproviderbase.'_locked'; + foreach ($processors as $processor) { + $value = 0; + if (isset($form->{$componentprovidersetting}[$processor->name])) { + $value = $form->{$componentprovidersetting}[$processor->name]; + if ($value == 'on') { + $value = 1; } } - if ($setting != 'permitted') { - // We have already recoded site preferences for 'permitted' type. - $newpreferences['message_provider_'.$componentprovidersetting] = $value; + + // Record the site preference. + $newpreferences[$processor->name.'_provider_'.$componentprovidersetting] = $value; + } + + $componentprovidersetting = $componentproviderbase.'_enabled'; + $newsettings = []; + if (isset($form->$componentprovidersetting)) { + // Store defined comma-separated processors as setting value. + // Using array_filter eliminates elements set to 0 above. + $newsettings = array_keys(array_filter($form->{$componentprovidersetting})); + } + + // Let's join existing setting values for disabled processors. + $property = 'message_provider_'.$componentprovidersetting; + if (property_exists($preferences, $property)) { + $existingsetting = $preferences->$property; + foreach ($disabledprocessors as $disable) { + if (strpos($existingsetting, $disable->name) > -1) { + $newsettings[] = $disable->name; + } } } + + $value = join(',', $newsettings); + if (empty($value)) { + $value = null; + } + + // Record the site preference. + $newpreferences['message_provider_'.$componentprovidersetting] = $value; } // Update database. @@ -142,8 +125,6 @@ if (($form = data_submitted()) && confirm_sesskey()) { // Page settings $PAGE->set_context(context_system::instance()); -$PAGE->requires->js_init_call('M.core_message.init_defaultoutputs'); - $renderer = $PAGE->get_renderer('core', 'message'); // Display the page. diff --git a/admin/tool/dataprivacy/db/messages.php b/admin/tool/dataprivacy/db/messages.php index 2c1d239d4a0..25f3a7f140a 100644 --- a/admin/tool/dataprivacy/db/messages.php +++ b/admin/tool/dataprivacy/db/messages.php @@ -28,8 +28,8 @@ $messageproviders = [ // Notify Data Protection Officer about incoming data requests. 'contactdataprotectionofficer' => [ 'defaults' => [ - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ], 'capability' => 'tool/dataprivacy:managedatarequests' ], @@ -37,15 +37,15 @@ $messageproviders = [ // Notify user about the processing results of their data request. 'datarequestprocessingresults' => [ 'defaults' => [ - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ] ], // Notify Data Protection Officer about exceptions. 'notifyexceptions' => [ 'defaults' => [ - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ], 'capability' => 'tool/dataprivacy:managedatarequests' ], diff --git a/admin/tool/mobile/tests/api_test.php b/admin/tool/mobile/tests/api_test.php index 9099b12ee45..fa2a22aa15d 100644 --- a/admin/tool/mobile/tests/api_test.php +++ b/admin/tool/mobile/tests/api_test.php @@ -107,7 +107,7 @@ class tool_mobile_api_testcase extends externallib_advanced_testcase { set_config('allowedemaildomains', 'example.com'); $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); // Extra content for all types of messages. $message = new \core\message\message(); diff --git a/admin/tool/monitor/tests/behat/subscription.feature b/admin/tool/monitor/tests/behat/subscription.feature index 3b881b4b625..d0ff66a9983 100644 --- a/admin/tool/monitor/tests/behat/subscription.feature +++ b/admin/tool/monitor/tests/behat/subscription.feature @@ -103,7 +103,7 @@ Feature: tool_monitor_subscriptions Given I log in as "admin" And I follow "Preferences" in the user menu And I click on "Notification preferences" "link" in the "#page-content" "css_element" - And I click on "//td[@data-processor-name='popup']//label[@data-state='loggedin']" "xpath_element" in the "Notifications of rule subscriptions" "table_row" + And I click on "//td[@data-processor-name='popup']//div[@class='preference-state']" "xpath_element" in the "Notifications of rule subscriptions" "table_row" And I wait until the page is ready And I follow "Preferences" in the user menu And I follow "Event monitoring" @@ -124,7 +124,7 @@ Feature: tool_monitor_subscriptions Given I log in as "teacher1" And I follow "Preferences" in the user menu And I click on "Notification preferences" "link" in the "#page-content" "css_element" - And I click on "//td[@data-processor-name='popup']//label[@data-state='loggedin']" "xpath_element" in the "Notifications of rule subscriptions" "table_row" + And I click on "//td[@data-processor-name='popup']//div[@class='preference-state']" "xpath_element" in the "Notifications of rule subscriptions" "table_row" And I wait until the page is ready And I follow "Preferences" in the user menu And I follow "Event monitoring" diff --git a/backup/util/dbops/restore_dbops.class.php b/backup/util/dbops/restore_dbops.class.php index fc0067ee771..435c101b9fc 100644 --- a/backup/util/dbops/restore_dbops.class.php +++ b/backup/util/dbops/restore_dbops.class.php @@ -1301,7 +1301,41 @@ abstract class restore_dbops { $preference = (object)$preference; // Prepare the record and insert it $preference->userid = $newuserid; - $status = $DB->insert_record('user_preferences', $preference); + + // Translate _loggedin / _loggedoff message user preferences to _enabled. (MDL-67853) + // This code cannot be removed. + if (preg_match('/message_provider_.*/', $preference->name)) { + $nameparts = explode('_', $preference->name); + $name = array_pop($nameparts); + + if ($name == 'loggedin' || $name == 'loggedoff') { + $preference->name = implode('_', $nameparts).'_enabled'; + + $existingpreference = $DB->get_record('user_preferences', + ['name' => $preference->name , 'userid' => $newuserid]); + // Merge both values. + if ($existingpreference) { + $values = []; + + if (!empty($existingpreference->value) && $existingpreference->value != 'none') { + $values = explode(',', $existingpreference->value); + } + + if (!empty($preference->value) && $preference->value != 'none') { + $values = array_merge(explode(',', $preference->value), $values); + $values = array_unique($values); + } + + $existingpreference->value = empty($values) ? 'none' : implode(',', $values); + + $DB->update_record('user_preferences', $existingpreference); + continue; + } + } + } + // End translating loggedin / loggedoff message user preferences. + + $DB->insert_record('user_preferences', $preference); } } // Special handling for htmleditor which was converted to a preference. @@ -1311,7 +1345,7 @@ abstract class restore_dbops { $preference->userid = $newuserid; $preference->name = 'htmleditor'; $preference->value = 'textarea'; - $status = $DB->insert_record('user_preferences', $preference); + $DB->insert_record('user_preferences', $preference); } } diff --git a/badges/tests/badgeslib_test.php b/badges/tests/badgeslib_test.php index 8becec48113..e1469437d45 100644 --- a/badges/tests/badgeslib_test.php +++ b/badges/tests/badgeslib_test.php @@ -305,7 +305,7 @@ class badgeslib_test extends advanced_testcase { $sink = $this->redirectMessages(); $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_badgerecipientnotice_loggedoff', 'email', $user1); + set_user_preference('message_provider_moodle_badgerecipientnotice_enabled', 'email', $user1); $badge->issue($user1->id, false); $this->assertDebuggingCalled(); // Expect debugging while baking a badge via phpunit. diff --git a/lang/en/deprecated.txt b/lang/en/deprecated.txt index 29f30a382fd..25f9ecbec5e 100644 --- a/lang/en/deprecated.txt +++ b/lang/en/deprecated.txt @@ -82,3 +82,10 @@ navmethod,core_grades dropdown,core_grades tabs,core_grades combo,core_grades +defaults,core_message +loggedin_help,core_message +loggedindescription,core_message +loggedoff_help,core_message +loggedoffdescription,core_message +sendingvia,core_message +sendingviawhen,core_message diff --git a/lang/en/message.php b/lang/en/message.php index 1a87799b52d..760d904c2a7 100644 --- a/lang/en/message.php +++ b/lang/en/message.php @@ -51,7 +51,6 @@ $string['contacts'] = 'Contacts'; $string['conversationactions'] = 'Conversation actions menu'; $string['decline'] = 'Decline'; $string['defaultmessageoutputs'] = 'Notification settings'; -$string['defaults'] = 'Defaults'; $string['deleteallconfirm'] = "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants."; $string['deleteallmessages'] = "Delete all messages"; $string['deleteallselfconfirm'] = "Are you sure you would like to delete this entire personal conversation?"; @@ -93,11 +92,7 @@ $string['info'] = 'User info'; $string['isnotinyourcontacts'] = '{$a} is not in your contacts'; $string['loadmore'] = 'Load more'; $string['loggedin'] = 'Online'; -$string['loggedin_help'] = 'Configure how you would like to receive notifications when you are logged into Moodle'; -$string['loggedindescription'] = 'When you are logged into Moodle'; $string['loggedoff'] = 'Offline'; -$string['loggedoff_help'] = 'Configure how you would like to receive notifications when you are not logged into Moodle'; -$string['loggedoffdescription'] = 'When you are not logged into Moodle'; $string['managemessageoutputs'] = 'Default notification preferences'; $string['messageoutputs'] = 'Notification plugins'; $string['messagepreferences'] = 'Message preferences'; @@ -213,6 +208,9 @@ $string['privacy:metadata:preference:core_message_settings'] = 'Settings related $string['privacy:request:preference:set'] = 'The value of the setting \'{$a->name}\' was \'{$a->value}\''; $string['privacy:export:conversationprefix'] = 'Conversation: '; $string['processorsettings'] = 'Processor settings'; +$string['providerenabled'] = 'Sending "{$a}" enabled status'; +$string['providerprocesorislocked'] = '"{$a->provider}" on "{$a->processor}" is locked'; +$string['providerprocesorisdisallowed'] = '"{$a->provider}" on "{$a->processor}" is disallowed'; $string['removecontact'] = 'Remove contact'; $string['removecontactconfirm'] = 'Are you sure you want to remove {$a} from your contacts?'; $string['removecoursefilter'] = 'Remove filter for course {$a}'; @@ -231,9 +229,9 @@ $string['selfconversation'] = 'Personal space'; $string['selfconversationdefaultmessage'] = 'Save draft messages, links, notes etc. to access later.'; $string['send'] = 'Send'; $string['sender'] = '{$a}:'; -$string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"'; -$string['sendingviawhen'] = 'Sending "{$a->provider}" via "{$a->processor}" when {$a->state}'; $string['sendcontactrequest'] = 'Send contact request'; +$string['sendingviaenabled'] = 'Sending "{$a->provider}" via "{$a->processor}" enabled status'; +$string['sendingvialocked'] = 'Sending "{$a->provider}" via "{$a->processor}" locked status'; $string['sendmessage'] = 'Send message'; $string['sendbulkmessage'] = 'Send message to {$a} people'; $string['sendbulkmessagesingle'] = 'Send message to 1 person'; @@ -279,3 +277,12 @@ $string['yourcontactrequestpending'] = 'Your contact request is pending with {$a // Deprecated since Moodle 3.9. $string['messagecontactrequestsnotification'] = '{$a} is requesting to be added as a contact.'; $string['messagecontactrequestsnotificationsubject'] = 'Contact request from {$a}'; + +// Deprecated since Moodle 4.0. +$string['defaults'] = 'Defaults'; +$string['loggedin_help'] = 'Configure how you would like to receive notifications when you are logged into Moodle'; +$string['loggedindescription'] = 'When you are logged into Moodle'; +$string['loggedoff_help'] = 'Configure how you would like to receive notifications when you are not logged into Moodle'; +$string['loggedoffdescription'] = 'When you are not logged into Moodle'; +$string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"'; +$string['sendingviawhen'] = 'Sending "{$a->provider}" via "{$a->processor}" when {$a->state}'; diff --git a/lib/classes/message/manager.php b/lib/classes/message/manager.php index 53fd9aeeefd..6f2aa9f561c 100644 --- a/lib/classes/message/manager.php +++ b/lib/classes/message/manager.php @@ -208,20 +208,6 @@ class manager { return false; } - // Set the online state. - if (isset($CFG->block_online_users_timetosee)) { - $timetoshowusers = $CFG->block_online_users_timetosee * 60; - } else { - $timetoshowusers = 300; - } - - // Work out if the user is logged in or not. - $userstate = 'loggedoff'; - if (!empty($localisedeventdata->userto->lastaccess) - && (time() - $timetoshowusers) < $localisedeventdata->userto->lastaccess) { - $userstate = 'loggedin'; - } - // Fill in the array of processors to be used based on default and user preferences. // Do not process muted conversations. $processorlist = []; @@ -233,23 +219,30 @@ class manager { } // First find out permissions. - $defaultpreference = $processor->name . '_provider_' . $preferencebase . '_permitted'; - if (isset($defaultpreferences->{$defaultpreference})) { - $permitted = $defaultpreferences->{$defaultpreference}; + $defaultlockedpreference = $processor->name . '_provider_' . $preferencebase . '_locked'; + $locked = false; + if (isset($defaultpreferences->{$defaultlockedpreference})) { + $locked = $defaultpreferences->{$defaultlockedpreference}; } else { // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't // exist in the message_provider table (thus there is no default settings for them). - $preferrormsg = "Could not load preference $defaultpreference. Make sure the component and name you supplied - to message_send() are valid."; + $preferrormsg = "Could not load preference $defaultlockedpreference. + Make sure the component and name you supplied to message_send() are valid."; throw new coding_exception($preferrormsg); } + $enabledpreference = 'message_provider_'.$preferencebase . '_enabled'; + $forced = false; + if ($locked && isset($defaultpreferences->{$enabledpreference})) { + $forced = $defaultpreferences->{$enabledpreference}; + } + // Find out if user has configured this output. // Some processors cannot function without settings from the user. $userisconfigured = $processor->object->is_user_configured($recipient); // DEBUG: notify if we are forcing unconfigured output. - if ($permitted == 'forced' && !$userisconfigured) { + if ($forced && !$userisconfigured) { debugging('Attempt to force message delivery to user who has "' . $processor->name . '" output unconfigured', DEBUG_NORMAL); } @@ -257,13 +250,13 @@ class manager { // Populate the list of processors we will be using. if (!$eventdata->notification && $processor->object->force_process_messages()) { $processorlist[] = $processor->name; - } else if ($permitted == 'forced' && $userisconfigured) { + } else if ($forced && $userisconfigured) { // An admin is forcing users to use this message processor. Use this processor unconditionally. $processorlist[] = $processor->name; - } else if ($permitted == 'permitted' && $userisconfigured && !$recipient->emailstop) { + } else if (!$locked && $userisconfigured && !$recipient->emailstop) { // User has not disabled notifications. // See if user set any notification preferences, otherwise use site default ones. - $userpreferencename = 'message_provider_' . $preferencebase . '_' . $userstate; + $userpreferencename = 'message_provider_' . $preferencebase . '_enabled'; if ($userpreference = get_user_preferences($userpreferencename, null, $recipient)) { if (in_array($processor->name, explode(',', $userpreference))) { $processorlist[] = $processor->name; diff --git a/lib/db/messages.php b/lib/db/messages.php index 8470c4f5566..a1fcbb4ec90 100644 --- a/lib/db/messages.php +++ b/lib/db/messages.php @@ -37,8 +37,8 @@ $messageproviders = array ( 'newlogin' => array ( 'defaults' => array( - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), @@ -56,15 +56,15 @@ $messageproviders = array ( 'availableupdate' => array( 'capability' => 'moodle/site:config', 'defaults' => array( - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED ), ), 'instantmessage' => array ( 'defaults' => array( - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), @@ -81,7 +81,7 @@ $messageproviders = array ( 'courserequestapproved' => array ( 'capability' => 'moodle/course:request', 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), @@ -89,28 +89,32 @@ $messageproviders = array ( 'courserequestrejected' => array ( 'capability' => 'moodle/course:request', 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), // Course completed. Requires course completion configured at course level. It does not work with just activity progress. - 'coursecompleted' => [], + 'coursecompleted' => [ + 'defaults' => [ + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + ], + ], // Course content updated. New content (activities or resources) has been created or existing content updated. 'coursecontentupdated' => array ( 'defaults' => array( - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), // Badge award notification to a badge recipient. 'badgerecipientnotice' => array ( 'defaults' => array( - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), 'capability' => 'moodle/badges:earnbadge' ), @@ -118,7 +122,7 @@ $messageproviders = array ( // Badge award notification to a badge creator (mostly cron-based). 'badgecreatornotice' => array ( 'defaults' => array( - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ) ), @@ -131,9 +135,9 @@ $messageproviders = array ( // User insights. 'insights' => array ( 'defaults' => [ - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ] ), @@ -142,23 +146,23 @@ $messageproviders = array ( 'defaults' => [ // We don't need to notify in the popup output here because the message drawer // already notifies users of contact requests. - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ] ], // Asyncronhous backup/restore notifications. 'asyncbackupnotification' => array( 'defaults' => array( - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ) ), 'gradenotifications' => [ 'defaults' => array( - 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, - 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, + 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, + 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ], diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index e2cb26d8867..c531c50163c 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -3567,5 +3567,247 @@ privatefiles,moodle|/user/files.php'; upgrade_main_savepoint(true, 2022011100.01); } + if ($oldversion < 2022012100.02) { + // 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, 2022012100.02); + } + return true; } diff --git a/lib/messagelib.php b/lib/messagelib.php index 9138c1577d5..a79b78c0c95 100644 --- a/lib/messagelib.php +++ b/lib/messagelib.php @@ -241,20 +241,6 @@ function message_send(\core\message\message $eventdata) { return false; } - //after how long inactive should the user be considered logged off? - if (isset($CFG->block_online_users_timetosee)) { - $timetoshowusers = $CFG->block_online_users_timetosee * 60; - } else { - $timetoshowusers = 300;//5 minutes - } - - // Work out if the user is logged in or not - if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) { - $userstate = 'loggedin'; - } else { - $userstate = 'loggedoff'; - } - // Check if we are creating a notification or message. $table = 'notifications'; @@ -299,40 +285,47 @@ function message_send(\core\message\message $eventdata) { } // First find out permissions - $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; - if (isset($defaultpreferences->{$defaultpreference})) { - $permitted = $defaultpreferences->{$defaultpreference}; + $defaultlockedpreference = $processor->name . '_provider_' . $preferencebase . '_locked'; + $locked = false; + if (isset($defaultpreferences->{$defaultlockedpreference})) { + $locked = $defaultpreferences->{$defaultlockedpreference}; } else { // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't // exist in the message_provider table (thus there is no default settings for them). - $preferrormsg = "Could not load preference $defaultpreference. Make sure the component and name you supplied + $preferrormsg = "Could not load preference $defaultlockedpreference. Make sure the component and name you supplied to message_send() are valid."; throw new coding_exception($preferrormsg); } + $preferencename = 'message_provider_'.$preferencebase.'_enabled'; + $forced = false; + if ($locked && isset($defaultpreferences->{$preferencename})) { + $userpreference = $defaultpreferences->{$preferencename}; + $forced = in_array($processor->name, explode(',', $userpreference)); + } + // Find out if user has configured this output // Some processors cannot function without settings from the user $userisconfigured = $processor->object->is_user_configured($eventdata->userto); // DEBUG: notify if we are forcing unconfigured output - if ($permitted == 'forced' && !$userisconfigured) { + if ($forced && !$userisconfigured) { debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL); } // Populate the list of processors we will be using - if ($permitted == 'forced' && $userisconfigured) { + if ($forced && $userisconfigured) { // An admin is forcing users to use this message processor. Use this processor unconditionally. $processorlist[] = $processor->name; - } else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) { + } else if (!$forced && !$locked && $userisconfigured && !$eventdata->userto->emailstop) { // User has not disabled notifications // See if user set any notification preferences, otherwise use site default ones - $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; - if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto)) { + if ($userpreference = get_user_preferences($preferencename, null, $eventdata->userto)) { if (in_array($processor->name, explode(',', $userpreference))) { $processorlist[] = $processor->name; } - } else if (isset($defaultpreferences->{$userpreferencename})) { - if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { + } else if (isset($defaultpreferences->{$preferencename})) { + if (in_array($processor->name, explode(',', $defaultpreferences->{$preferencename}))) { $processorlist[] = $processor->name; } } @@ -523,51 +516,37 @@ function message_set_default_message_preference($component, $messagename, $filep // Setting default preference $componentproviderbase = $component.'_'.$messagename; - $loggedinpref = array(); - $loggedoffpref = array(); - // set 'permitted' preference first for each messaging processor + $enabledpref = []; + // Set 'locked' preference first for each messaging processor. foreach ($processors as $processor) { - $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_permitted'; - // if we do not have this setting yet, set it + $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_locked'; + // If we do not have this setting yet, set it. if (!isset($defaultpreferences->{$preferencename})) { - // determine plugin default settings + // Determine plugin default settings. $plugindefault = 0; if (isset($fileprovider['defaults'][$processor->name])) { $plugindefault = $fileprovider['defaults'][$processor->name]; } - // get string values of the settings - list($permitted, $loggedin, $loggedoff) = translate_message_default_setting($plugindefault, $processor->name); - // store default preferences for current processor - set_config($preferencename, $permitted, 'message'); - // save loggedin/loggedoff settings - if ($loggedin) { - $loggedinpref[] = $processor->name; - } - if ($loggedoff) { - $loggedoffpref[] = $processor->name; + // Get string values of the settings. + list($locked, $enabled) = translate_message_default_setting($plugindefault, $processor->name); + // Store default preferences for current processor. + set_config($preferencename, $locked, 'message'); + // Save enabled settings. + if ($enabled) { + $enabledpref[] = $processor->name; } } } - // now set loggedin/loggedoff preferences - if (!empty($loggedinpref)) { - $preferencename = 'message_provider_'.$componentproviderbase.'_loggedin'; + // Now set enabled preferences. + if (!empty($enabledpref)) { + $preferencename = 'message_provider_'.$componentproviderbase.'_enabled'; if (isset($defaultpreferences->{$preferencename})) { // We have the default preferences for this message provider, which // likely means that we have been adding a new processor. Add defaults // to exisitng preferences. - $loggedinpref = array_merge($loggedinpref, explode(',', $defaultpreferences->{$preferencename})); + $enabledpref = array_merge($enabledpref, explode(',', $defaultpreferences->{$preferencename})); } - set_config($preferencename, join(',', $loggedinpref), 'message'); - } - if (!empty($loggedoffpref)) { - $preferencename = 'message_provider_'.$componentproviderbase.'_loggedoff'; - if (isset($defaultpreferences->{$preferencename})) { - // We have the default preferences for this message provider, which - // likely means that we have been adding a new processor. Add defaults - // to exisitng preferences. - $loggedoffpref = array_merge($loggedoffpref, explode(',', $defaultpreferences->{$preferencename})); - } - set_config($preferencename, join(',', $loggedoffpref), 'message'); + set_config($preferencename, join(',', $enabledpref), 'message'); } } @@ -754,8 +733,8 @@ function message_processor_uninstall($name) { $transaction = $DB->start_delegated_transaction(); $DB->delete_records('message_processors', array('name' => $name)); $DB->delete_records_select('config_plugins', "plugin = ?", array("message_{$name}")); - // delete permission preferences only, we do not care about loggedin/loggedoff - // defaults, they will be removed on the next attempt to update the preferences + // Delete permission preferences only, we do not care about enabled defaults, + // they will be removed on the next attempt to update the preferences. $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("{$name}_provider_%")); $transaction->allow_commit(); // Purge all messaging settings from the caches. They are stored by plugin so we have to clear all message settings. diff --git a/lib/tests/message_test.php b/lib/tests/message_test.php index eefd415a42d..b6e8fa2714d 100644 --- a/lib/tests/message_test.php +++ b/lib/tests/message_test.php @@ -144,7 +144,7 @@ class core_message_testcase extends advanced_testcase { $this->assertFileExists("$CFG->dirroot/message/output/popup/version.php"); $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); // Extra content for all types of messages. $message = new \core\message\message(); @@ -241,7 +241,7 @@ class core_message_testcase extends advanced_testcase { $this->assertFileExists("$CFG->dirroot/message/output/popup/version.php"); $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); // Check that prefix is ammended to the subject of the email. $message = new \core\message\message(); diff --git a/lib/tests/messagelib_test.php b/lib/tests/messagelib_test.php index b77b08f7b13..1f15471f29d 100644 --- a/lib/tests/messagelib_test.php +++ b/lib/tests/messagelib_test.php @@ -412,7 +412,7 @@ class core_messagelib_testcase extends advanced_testcase { $eventsink = $this->redirectEvents(); // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'none', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -500,7 +500,7 @@ class core_messagelib_testcase extends advanced_testcase { $eventsink->clear(); // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -533,7 +533,7 @@ class core_messagelib_testcase extends advanced_testcase { $user2->emailstop = '0'; // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -566,7 +566,7 @@ class core_messagelib_testcase extends advanced_testcase { $this->assertInstanceOf('\core\event\message_sent', $events[0]); $eventsink->clear(); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email,popup', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email,popup', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -600,7 +600,7 @@ class core_messagelib_testcase extends advanced_testcase { $this->assertInstanceOf('\core\event\message_sent', $events[0]); $eventsink->clear(); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'popup', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'popup', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -635,7 +635,7 @@ class core_messagelib_testcase extends advanced_testcase { $transaction->allow_commit(); // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'none', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'none', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -668,7 +668,7 @@ class core_messagelib_testcase extends advanced_testcase { $this->assertInstanceOf('\core\event\message_sent', $events[0]); // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); $message = new \core\message\message(); $message->courseid = 1; @@ -783,7 +783,7 @@ class core_messagelib_testcase extends advanced_testcase { // Ensure we're going to hit the email processor for this user. $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); // Now, send a message and verify the message processors (in this case, email) are hit. $sink = $this->redirectEmails(); @@ -869,7 +869,7 @@ class core_messagelib_testcase extends advanced_testcase { // Ensure we're going to hit the email processor for this user. $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user1); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user1); // Now, send a message and verify the message processors are empty (self-conversations are not processed for now). $sink = $this->redirectEmails(); @@ -941,8 +941,8 @@ class core_messagelib_testcase extends advanced_testcase { // Ensure the email processor is enabled for the recipient users. $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user3); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user3); // Now, send a message and verify the email processor are hit. $messageid = message_send($message); @@ -1016,8 +1016,8 @@ class core_messagelib_testcase extends advanced_testcase { $eventsink = $this->redirectEvents(); // Will always use the pop-up processor. - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user2); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user3); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user2); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user3); $message = new \core\message\message(); $message->courseid = 1; diff --git a/lib/upgrade.txt b/lib/upgrade.txt index a5a9d147d95..d554dd1c8a4 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -165,6 +165,12 @@ current value for a pluginname depending on its status (enabled, disabled, other This default applies both when there is no supplied coverage.php file, and is used to supplement any existing coverage configuration file if one is found. * New method get_unaddable_by_theme_block_types() has been added to block_manager class. It uses the 'unaddableblocks' theme setting value to get the list of blocks that won't be displayed for a theme. +* Loggedin / Loggedoff component settings on notification preferences have been merged to a single enabled switch: + MESSAGE_DEFAULT_LOGGEDIN and MESSAGE_DEFAULT_LOGGEDOFF are now deprecated, so plugins should be updated if db/messages.php is present and replace + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF to MESSAGE_DEFAULT_ENABLED. Backward compatibility will take any of both settings as enabled. + MESSAGE_DEFAULT_PERMITTED also deprecated. + core_message_get_user_notification_preferences and core_message_get_user_message_preferences Webservice are now returning enabled boolean on + components > notifications > processors. loggedin and loggedoff are deprecated but present for backward compatibility. === 3.11.4 === * A new option dontforcesvgdownload has been added to the $options parameter of the send_file() function. diff --git a/message/amd/build/default_notification_preferences.min.js b/message/amd/build/default_notification_preferences.min.js new file mode 100644 index 00000000000..a68f3092fdd --- /dev/null +++ b/message/amd/build/default_notification_preferences.min.js @@ -0,0 +1,2 @@ +define ("core_message/default_notification_preferences",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b={provider:".defaultmessageoutputs .provider_enabled",lockSetting:".locked_message_setting",enabledSetting:".enabled_message_setting",allSettings:".locked_message_setting, .enabled_message_setting"},c=function(){var a=function(a){var b=a.checked||!1,c=a.id.replace("_locked[","_enabled["),d=document.getElementById(c).closest("div.custom-control");d.classList.toggle("dimmed_text",b)},c=function(a){var c=a.checked||!1,d=a.closest("tr"),e=d.querySelectorAll(b.allSettings);e.forEach(function(a){a.toggleAttribute("disabled",!c)})},d=document.querySelector(".preferences-container");d.querySelectorAll(b.provider).forEach(function(a){if(!a.checked){c(a)}a.addEventListener("change",function(a){c(a.target)})});d.querySelectorAll(b.lockSetting).forEach(function(b){if(b.checked){a(b)}b.addEventListener("change",function(b){a(b.target)})})};a.default={init:function init(){c()}};return a.default}); +//# sourceMappingURL=default_notification_preferences.min.js.map diff --git a/message/amd/build/default_notification_preferences.min.js.map b/message/amd/build/default_notification_preferences.min.js.map new file mode 100644 index 00000000000..1d520108ee3 --- /dev/null +++ b/message/amd/build/default_notification_preferences.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/default_notification_preferences.js"],"names":["selectors","provider","lockSetting","enabledSetting","allSettings","registerEventListeners","toggleLockSetting","lockedElement","isEnabled","checked","enabledId","id","replace","enabledElement","document","getElementById","closest","classList","toggle","toggleEnableProviderSettings","providerEnabledElement","parentRow","elements","querySelectorAll","forEach","element","toggleAttribute","container","querySelector","addEventListener","e","target","init"],"mappings":"kKA0BMA,CAAAA,CAAS,CAAG,CACdC,QAAQ,CAAE,0CADI,CAEdC,WAAW,CAAE,yBAFC,CAGdC,cAAc,CAAE,0BAHF,CAIdC,WAAW,CAAE,mDAJC,C,CAUZC,CAAsB,CAAG,UAAM,IAO3BC,CAAAA,CAAiB,CAAG,SAACC,CAAD,CAAmB,IACnCC,CAAAA,CAAS,CAAGD,CAAa,CAACE,OAAd,IADuB,CAEnCC,CAAS,CAAGH,CAAa,CAACI,EAAd,CAAiBC,OAAjB,CAAyB,UAAzB,CAAqC,WAArC,CAFuB,CAInCC,CAAc,CAAGC,QAAQ,CAACC,cAAT,CAAwBL,CAAxB,EAAmCM,OAAnC,CAA2C,oBAA3C,CAJkB,CAKzCH,CAAc,CAACI,SAAf,CAAyBC,MAAzB,CAAgC,aAAhC,CAA+CV,CAA/C,CACH,CAbgC,CAoB3BW,CAA4B,CAAG,SAACC,CAAD,CAA4B,IACvDZ,CAAAA,CAAS,CAAGY,CAAsB,CAACX,OAAvB,IAD2C,CAEvDY,CAAS,CAAGD,CAAsB,CAACJ,OAAvB,CAA+B,IAA/B,CAF2C,CAIvDM,CAAQ,CAAGD,CAAS,CAACE,gBAAV,CAA2BvB,CAAS,CAACI,WAArC,CAJ4C,CAK7DkB,CAAQ,CAACE,OAAT,CAAiB,SAACC,CAAD,CAAa,CAC1BA,CAAO,CAACC,eAAR,CAAwB,UAAxB,CAAoC,CAAClB,CAArC,CACH,CAFD,CAGH,CA5BgC,CA8B3BmB,CAAS,CAAGb,QAAQ,CAACc,aAAT,CAAuB,wBAAvB,CA9Be,CAgCjCD,CAAS,CAACJ,gBAAV,CAA2BvB,CAAS,CAACC,QAArC,EAA+CuB,OAA/C,CAAuD,SAACJ,CAAD,CAA4B,CAE/E,GAAI,CAACA,CAAsB,CAACX,OAA5B,CAAqC,CACjCU,CAA4B,CAACC,CAAD,CAC/B,CAEDA,CAAsB,CAACS,gBAAvB,CAAwC,QAAxC,CAAkD,SAACC,CAAD,CAAO,CACrDX,CAA4B,CAACW,CAAC,CAACC,MAAH,CAC/B,CAFD,CAGH,CATD,EAWAJ,CAAS,CAACJ,gBAAV,CAA2BvB,CAAS,CAACE,WAArC,EAAkDsB,OAAlD,CAA0D,SAACjB,CAAD,CAAmB,CAEzE,GAAIA,CAAa,CAACE,OAAlB,CAA2B,CACvBH,CAAiB,CAACC,CAAD,CACpB,CAEDA,CAAa,CAACsB,gBAAd,CAA+B,QAA/B,CAAyC,SAACC,CAAD,CAAO,CAC5CxB,CAAiB,CAACwB,CAAC,CAACC,MAAH,CACpB,CAFD,CAGH,CATD,CAUH,C,WASc,CACXC,IAAI,CALK,QAAPA,CAAAA,IAAO,EAAM,CACf3B,CAAsB,EACzB,CAEc,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the default settings for the list of notification types on the\n * notifications admin page\n *\n * @module core_message/default_notification_preferences\n * @class default_notification_preferences\n * @copyright 2021 Moodle\n * @author Pau Ferrer OcaƱa \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst selectors = {\n provider: '.defaultmessageoutputs .provider_enabled',\n lockSetting: '.locked_message_setting',\n enabledSetting: '.enabled_message_setting',\n allSettings: '.locked_message_setting, .enabled_message_setting'\n};\n\n/**\n * Register event listeners for the default_notification_preferences page.\n */\nconst registerEventListeners = () => {\n\n /**\n * Update the dimmed status of the \"enabled\" toggle on the notification setting.\n *\n * @param {HTMLElement} lockedElement Element that receives the event.\n */\n const toggleLockSetting = (lockedElement) => {\n const isEnabled = lockedElement.checked || false;\n const enabledId = lockedElement.id.replace('_locked[', '_enabled[');\n\n const enabledElement = document.getElementById(enabledId).closest('div.custom-control');\n enabledElement.classList.toggle('dimmed_text', isEnabled);\n };\n\n /**\n * Enable/Disable all settings of the provider.\n *\n * @param {HTMLElement} providerEnabledElement Element that receives the event.\n */\n const toggleEnableProviderSettings = (providerEnabledElement) => {\n const isEnabled = providerEnabledElement.checked || false;\n const parentRow = providerEnabledElement.closest('tr');\n\n const elements = parentRow.querySelectorAll(selectors.allSettings);\n elements.forEach((element) => {\n element.toggleAttribute('disabled', !isEnabled);\n });\n };\n\n const container = document.querySelector('.preferences-container');\n\n container.querySelectorAll(selectors.provider).forEach((providerEnabledElement) => {\n // Set the initial statuses.\n if (!providerEnabledElement.checked) {\n toggleEnableProviderSettings(providerEnabledElement);\n }\n\n providerEnabledElement.addEventListener('change', (e) => {\n toggleEnableProviderSettings(e.target);\n });\n });\n\n container.querySelectorAll(selectors.lockSetting).forEach((lockedElement) => {\n // Set the initial statuses.\n if (lockedElement.checked) {\n toggleLockSetting(lockedElement);\n }\n\n lockedElement.addEventListener('change', (e) => {\n toggleLockSetting(e.target);\n });\n });\n};\n\n/**\n * Initialize the page.\n */\nconst init = () => {\n registerEventListeners();\n};\n\nexport default {\n init: init,\n};\n"],"file":"default_notification_preferences.min.js"} \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_settings.min.js b/message/amd/build/message_drawer_view_settings.min.js index 21e25770e5b..8b9a64094e9 100644 --- a/message/amd/build/message_drawer_view_settings.min.js +++ b/message/amd/build/message_drawer_view_settings.min.js @@ -1,2 +1,2 @@ -define ("core_message/message_drawer_view_settings",["jquery","core/notification","core/str","core/pubsub","core/templates","core_message/message_repository","core/custom_interaction_events","core_message/message_drawer_events"],function(a,b,c,d,e,f,g,h){var i={CHECKBOX:"input[type=\"checkbox\"]",SETTINGS:"[data-region=\"settings\"]",PRIVACY_PREFERENCE:"[data-preference=\"blocknoncontacts\"] input[type=\"radio\"]",NOTIFICATIONS_PREFERENCE:"[data-preference=\"notifications\"] input[type=\"checkbox\"]",ENTER_TO_SEND_PREFERENCE:"[data-preference=\"entertosend\"] input[type=\"checkbox\"]",NOTIFICATION_PREFERENCES_CONTAINER:"[data-region=\"notification-preference-container\"]",CONTENT_CONTAINER:"[data-region=\"content-container\"]",PLACEHOLDER_CONTAINER:"[data-region=\"placeholder-container\"]"},j={NOTIFICATION_PREFERENCES:"core_message/message_drawer_view_settings_body_content_notification_preferences"},k=function(b,c){var d=b.find(i.PRIVACY_PREFERENCE);d.each(function(b,d){d=a(d);if(d.val()==c){d.prop("checked",!0)}else{d.prop("checked",!1)}})},l=function(a,b){var c=a.find(i.ENTER_TO_SEND_PREFERENCE);if(b){c.prop("checked",!0)}else{c.prop("checked",!1)}},m=function(a,c){return f.savePreferences(a,c).then(function(){d.publish(h.PREFERENCES_UPDATED,c)}).catch(b.exception)},n=function(b,c){var d=b.find(i.SETTINGS);g.define(d,[g.events.activate]);d.on(g.events.activate,i.NOTIFICATIONS_PREFERENCE,function(b){var d=a(b.target).closest(i.NOTIFICATION_PREFERENCES_CONTAINER),e=d.find(i.CHECKBOX);if(!e.length){return}var f=e.toArray().reduce(function(b,c){c=a(c);if(c.prop("checked")){b.push(c.attr("data-name"))}return b},[]),g=f.length?f.join(","):"none";m(c,[{type:"message_provider_moodle_instantmessage_loggedoff",value:g},{type:"message_provider_moodle_instantmessage_loggedin",value:g}])});d.on("change",i.PRIVACY_PREFERENCE,function(b){var d=a(b.target).val();m(c,[{type:"message_blocknoncontacts",value:d}])});d.on(g.events.activate,i.ENTER_TO_SEND_PREFERENCE,function(b){var d=a(b.target).prop("checked");m(c,[{type:"message_entertosend",value:d}])})},o=function(a,c){f.getUserMessagePreferences(c).then(function(b){k(a,b.blocknoncontacts);l(a,b.entertosend);var c=[];if(b.preferences.components.length){b.preferences.components.forEach(function(a){if(a.notifications.length){var b=a.notifications.filter(function(a){return a.preferencekey=="message_provider_moodle_instantmessage"});if(b.length){var d=a.notifications[0];c=d.processors.map(function(a){var b=a.loggedin.checked||a.loggedoff.checked;return{displayname:a.displayname,name:a.name,checked:b,locked:a.locked,lockedmessage:a.lockedmessage||null}})}}})}var d=a.find(i.NOTIFICATION_PREFERENCES_CONTAINER);if(c.length){d.removeClass("hidden");return e.render(j.NOTIFICATION_PREFERENCES,{processors:c}).then(function(a){d.append(a);return a})}else{return!0}}).then(function(){a.find(i.CONTENT_CONTAINER).removeClass("hidden");a.find(i.PLACEHOLDER_CONTAINER).addClass("hidden");n(a,c)}).catch(b.exception)};return{show:function show(b,c,d,e,f){if(!d.attr("data-init")){o(d,f);d.attr("data-init",!0)}return a.Deferred().resolve().promise()},description:function description(){return c.get_string("messagedrawerviewsettings","core_message")}}}); +define ("core_message/message_drawer_view_settings",["jquery","core/notification","core/str","core/pubsub","core/templates","core_message/message_repository","core/custom_interaction_events","core_message/message_drawer_events"],function(a,b,c,d,e,f,g,h){var i={CHECKBOX:"input[type=\"checkbox\"]",SETTINGS:"[data-region=\"settings\"]",PRIVACY_PREFERENCE:"[data-preference=\"blocknoncontacts\"] input[type=\"radio\"]",NOTIFICATIONS_PREFERENCE:"[data-preference=\"notifications\"] input[type=\"checkbox\"]",ENTER_TO_SEND_PREFERENCE:"[data-preference=\"entertosend\"] input[type=\"checkbox\"]",NOTIFICATION_PREFERENCES_CONTAINER:"[data-region=\"notification-preference-container\"]",CONTENT_CONTAINER:"[data-region=\"content-container\"]",PLACEHOLDER_CONTAINER:"[data-region=\"placeholder-container\"]"},j={NOTIFICATION_PREFERENCES:"core_message/message_drawer_view_settings_body_content_notification_preferences"},k=function(b,c){var d=b.find(i.PRIVACY_PREFERENCE);d.each(function(b,d){d=a(d);if(d.val()==c){d.prop("checked",!0)}else{d.prop("checked",!1)}})},l=function(a,b){var c=a.find(i.ENTER_TO_SEND_PREFERENCE);if(b){c.prop("checked",!0)}else{c.prop("checked",!1)}},m=function(a,c){return f.savePreferences(a,c).then(function(){d.publish(h.PREFERENCES_UPDATED,c)}).catch(b.exception)},n=function(b,c){var d=b.find(i.SETTINGS);g.define(d,[g.events.activate]);d.on(g.events.activate,i.NOTIFICATIONS_PREFERENCE,function(b){var d=a(b.target).closest(i.NOTIFICATION_PREFERENCES_CONTAINER),e=d.find(i.CHECKBOX);if(!e.length){return}var f=e.toArray().reduce(function(b,c){c=a(c);if(c.prop("checked")){b.push(c.attr("data-name"))}return b},[]),g=f.length?f.join(","):"none";m(c,[{type:"message_provider_moodle_instantmessage_enabled",value:g}])});d.on("change",i.PRIVACY_PREFERENCE,function(b){var d=a(b.target).val();m(c,[{type:"message_blocknoncontacts",value:d}])});d.on(g.events.activate,i.ENTER_TO_SEND_PREFERENCE,function(b){var d=a(b.target).prop("checked");m(c,[{type:"message_entertosend",value:d}])})},o=function(a,c){f.getUserMessagePreferences(c).then(function(b){k(a,b.blocknoncontacts);l(a,b.entertosend);var c=[];if(b.preferences.components.length){b.preferences.components.forEach(function(a){if(a.notifications.length){var b=a.notifications.filter(function(a){return a.preferencekey=="message_provider_moodle_instantmessage"});if(b.length){var d=a.notifications[0];c=d.processors.map(function(a){var b=a.enabled;return{displayname:a.displayname,name:a.name,checked:b,locked:a.locked,lockedmessage:a.lockedmessage||null}})}}})}var d=a.find(i.NOTIFICATION_PREFERENCES_CONTAINER);if(c.length){d.removeClass("hidden");return e.render(j.NOTIFICATION_PREFERENCES,{processors:c}).then(function(a){d.append(a);return a})}else{return!0}}).then(function(){a.find(i.CONTENT_CONTAINER).removeClass("hidden");a.find(i.PLACEHOLDER_CONTAINER).addClass("hidden");n(a,c)}).catch(b.exception)};return{show:function show(b,c,d,e,f){if(!d.attr("data-init")){o(d,f);d.attr("data-init",!0)}return a.Deferred().resolve().promise()},description:function description(){return c.get_string("messagedrawerviewsettings","core_message")}}}); //# sourceMappingURL=message_drawer_view_settings.min.js.map diff --git a/message/amd/build/message_drawer_view_settings.min.js.map b/message/amd/build/message_drawer_view_settings.min.js.map index fc00026752a..2fa0f2a94b7 100644 --- a/message/amd/build/message_drawer_view_settings.min.js.map +++ b/message/amd/build/message_drawer_view_settings.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/message_drawer_view_settings.js"],"names":["define","$","Notification","Str","PubSub","Templates","Repository","CustomEvents","MessageDrawerEvents","SELECTORS","CHECKBOX","SETTINGS","PRIVACY_PREFERENCE","NOTIFICATIONS_PREFERENCE","ENTER_TO_SEND_PREFERENCE","NOTIFICATION_PREFERENCES_CONTAINER","CONTENT_CONTAINER","PLACEHOLDER_CONTAINER","TEMPLATES","NOTIFICATION_PREFERENCES","setPrivacyPreference","body","value","inputs","find","each","index","input","val","prop","setEnterToSend","checkbox","savePreferences","loggedInUserId","preferences","then","publish","PREFERENCES_UPDATED","catch","exception","registerEventListeners","settingsContainer","events","activate","on","e","container","target","closest","checkboxes","length","values","toArray","reduce","carry","push","attr","newValue","join","type","init","getUserMessagePreferences","response","blocknoncontacts","entertosend","notificationProcessors","components","forEach","component","notifications","notificationPreferences","filter","notification","preferencekey","configuration","processors","map","processor","checked","loggedin","loggedoff","displayname","name","locked","lockedmessage","removeClass","render","html","append","addClass","show","namespace","header","footer","Deferred","resolve","promise","description","get_string"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the settings page in the message drawer.\n *\n * @module core_message/message_drawer_view_settings\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n[\n 'jquery',\n 'core/notification',\n 'core/str',\n 'core/pubsub',\n 'core/templates',\n 'core_message/message_repository',\n 'core/custom_interaction_events',\n 'core_message/message_drawer_events'\n],\nfunction(\n $,\n Notification,\n Str,\n PubSub,\n Templates,\n Repository,\n CustomEvents,\n MessageDrawerEvents\n) {\n\n var SELECTORS = {\n CHECKBOX: 'input[type=\"checkbox\"]',\n SETTINGS: '[data-region=\"settings\"]',\n PRIVACY_PREFERENCE: '[data-preference=\"blocknoncontacts\"] input[type=\"radio\"]',\n NOTIFICATIONS_PREFERENCE: '[data-preference=\"notifications\"] input[type=\"checkbox\"]',\n ENTER_TO_SEND_PREFERENCE: '[data-preference=\"entertosend\"] input[type=\"checkbox\"]',\n NOTIFICATION_PREFERENCES_CONTAINER: '[data-region=\"notification-preference-container\"]',\n CONTENT_CONTAINER: '[data-region=\"content-container\"]',\n PLACEHOLDER_CONTAINER: '[data-region=\"placeholder-container\"]'\n };\n\n var TEMPLATES = {\n NOTIFICATION_PREFERENCES: 'core_message/message_drawer_view_settings_body_content_notification_preferences'\n };\n\n var NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage';\n\n /**\n * Select the correct radio button in the DOM for the privacy preference.\n *\n * @param {Object} body The settings body element.\n * @param {Number} value Which radio button should be set\n */\n var setPrivacyPreference = function(body, value) {\n var inputs = body.find(SELECTORS.PRIVACY_PREFERENCE);\n inputs.each(function(index, input) {\n input = $(input);\n if (input.val() == value) {\n input.prop('checked', true);\n } else {\n input.prop('checked', false);\n }\n });\n };\n\n /**\n * Set the \"enter to send\" checkbox to the correct value in the DOM.\n *\n * @param {Object} body The settings body element.\n * @param {Bool} value Whether enter to send is enabled or disabled.\n */\n var setEnterToSend = function(body, value) {\n var checkbox = body.find(SELECTORS.ENTER_TO_SEND_PREFERENCE);\n\n if (value) {\n checkbox.prop('checked', true);\n } else {\n checkbox.prop('checked', false);\n }\n };\n\n /**\n * Send a request to the server to save the given preferences. Also publish\n * a preferences updated event for the rest of the message drawer to\n * subscribe to.\n *\n * @param {Number} loggedInUserId The logged in user id.\n * @param {Array} preferences The preferences to set.\n * @return {Object} jQuery promise\n */\n var savePreferences = function(loggedInUserId, preferences) {\n return Repository.savePreferences(loggedInUserId, preferences)\n .then(function() {\n PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);\n return;\n })\n .catch(Notification.exception);\n };\n\n /**\n * Create all of the event listeners for the message preferences page.\n *\n * @method registerEventListeners\n * @param {Object} body The settings body element.\n * @param {Number} loggedInUserId The logged in user id.\n */\n var registerEventListeners = function(body, loggedInUserId) {\n var settingsContainer = body.find(SELECTORS.SETTINGS);\n\n CustomEvents.define(settingsContainer, [\n CustomEvents.events.activate\n ]);\n\n settingsContainer.on(CustomEvents.events.activate, SELECTORS.NOTIFICATIONS_PREFERENCE, function(e) {\n var container = $(e.target).closest(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);\n var checkboxes = container.find(SELECTORS.CHECKBOX);\n if (!checkboxes.length) {\n return;\n }\n // The preference value is all of the enabled processors, comma separated, so let's\n // see which ones are enabled.\n var values = checkboxes.toArray().reduce(function(carry, checkbox) {\n checkbox = $(checkbox);\n if (checkbox.prop('checked')) {\n carry.push(checkbox.attr('data-name'));\n }\n\n return carry;\n }, []);\n var newValue = values.length ? values.join(',') : 'none';\n var preferences = [\n {\n type: 'message_provider_moodle_instantmessage_loggedoff',\n value: newValue\n },\n {\n type: 'message_provider_moodle_instantmessage_loggedin',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n\n settingsContainer.on('change', SELECTORS.PRIVACY_PREFERENCE, function(e) {\n var newValue = $(e.target).val();\n var preferences = [\n {\n type: 'message_blocknoncontacts',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n\n settingsContainer.on(CustomEvents.events.activate, SELECTORS.ENTER_TO_SEND_PREFERENCE, function(e) {\n var newValue = $(e.target).prop('checked');\n var preferences = [\n {\n type: 'message_entertosend',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n };\n\n /**\n * Initialise the module by loading the user's messaging preferences from the server and\n * rendering them in the settings page.\n *\n * Moodle may have many (or no) message processors enabled to notify the user when they\n * receive messages. We need to dynamically build the settings page based on which processors\n * are configured for the user.\n *\n * @param {Object} body The settings body element.\n * @param {Number} loggedInUserId The logged in user id.\n */\n var init = function(body, loggedInUserId) {\n // Load the message preferences from the server.\n Repository.getUserMessagePreferences(loggedInUserId)\n .then(function(response) {\n // Set the values of the stright forward preferences.\n setPrivacyPreference(body, response.blocknoncontacts);\n setEnterToSend(body, response.entertosend);\n\n // Parse the list of other preferences into a more usable format.\n var notificationProcessors = [];\n if (response.preferences.components.length) {\n response.preferences.components.forEach(function(component) {\n if (component.notifications.length) {\n // Filter down to just the notification processors that work on instant\n // messaging. We don't care about another other ones.\n var notificationPreferences = component.notifications.filter(function(notification) {\n return notification.preferencekey == NOTIFICATION_PREFERENCES_KEY;\n });\n\n if (notificationPreferences.length) {\n // Messaging only has one config at the moment which is for notifications\n // on personal messages.\n var configuration = component.notifications[0];\n notificationProcessors = configuration.processors.map(function(processor) {\n // Consider the the processor enabled if either preference is set. This is\n // for backwards compatibility. Going forward they will be treated as one\n // setting.\n var checked = processor.loggedin.checked || processor.loggedoff.checked;\n return {\n displayname: processor.displayname,\n name: processor.name,\n checked: checked,\n // The admin can force processors to be enabled at a site level so\n // we need to check if this processor has been locked by the admin.\n locked: processor.locked,\n lockedmessage: processor.lockedmessage || null,\n };\n });\n }\n }\n });\n }\n\n var container = body.find(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);\n if (notificationProcessors.length) {\n // We have processors (i.e. email, mobile, jabber) to show.\n container.removeClass('hidden');\n // Render the processor options.\n return Templates.render(TEMPLATES.NOTIFICATION_PREFERENCES, {processors: notificationProcessors})\n .then(function(html) {\n container.append(html);\n return html;\n });\n } else {\n return true;\n }\n })\n .then(function() {\n // We're done loading so hide the loading placeholder and show the settings.\n body.find(SELECTORS.CONTENT_CONTAINER).removeClass('hidden');\n body.find(SELECTORS.PLACEHOLDER_CONTAINER).addClass('hidden');\n // Register the event listers for if the user wants to change the preferences.\n registerEventListeners(body, loggedInUserId);\n return;\n })\n .catch(Notification.exception);\n };\n\n /**\n * Initialise the settings page by adding event listeners to\n * the checkboxes.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} header The settings header element.\n * @param {Object} body The settings body element.\n * @param {Object} footer The footer body element.\n * @param {Number} loggedInUserId The logged in user id.\n * @return {Object} jQuery promise\n */\n var show = function(namespace, header, body, footer, loggedInUserId) {\n if (!body.attr('data-init')) {\n init(body, loggedInUserId);\n body.attr('data-init', true);\n }\n\n return $.Deferred().resolve().promise();\n };\n\n /**\n * String describing this page used for aria-labels.\n *\n * @return {Object} jQuery promise\n */\n var description = function() {\n return Str.get_string('messagedrawerviewsettings', 'core_message');\n };\n\n return {\n show: show,\n description: description,\n };\n});\n"],"file":"message_drawer_view_settings.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/message_drawer_view_settings.js"],"names":["define","$","Notification","Str","PubSub","Templates","Repository","CustomEvents","MessageDrawerEvents","SELECTORS","CHECKBOX","SETTINGS","PRIVACY_PREFERENCE","NOTIFICATIONS_PREFERENCE","ENTER_TO_SEND_PREFERENCE","NOTIFICATION_PREFERENCES_CONTAINER","CONTENT_CONTAINER","PLACEHOLDER_CONTAINER","TEMPLATES","NOTIFICATION_PREFERENCES","setPrivacyPreference","body","value","inputs","find","each","index","input","val","prop","setEnterToSend","checkbox","savePreferences","loggedInUserId","preferences","then","publish","PREFERENCES_UPDATED","catch","exception","registerEventListeners","settingsContainer","events","activate","on","e","container","target","closest","checkboxes","length","values","toArray","reduce","carry","push","attr","newValue","join","type","init","getUserMessagePreferences","response","blocknoncontacts","entertosend","notificationProcessors","components","forEach","component","notifications","notificationPreferences","filter","notification","preferencekey","configuration","processors","map","processor","checked","enabled","displayname","name","locked","lockedmessage","removeClass","render","html","append","addClass","show","namespace","header","footer","Deferred","resolve","promise","description","get_string"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the settings page in the message drawer.\n *\n * @module core_message/message_drawer_view_settings\n * @copyright 2018 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(\n[\n 'jquery',\n 'core/notification',\n 'core/str',\n 'core/pubsub',\n 'core/templates',\n 'core_message/message_repository',\n 'core/custom_interaction_events',\n 'core_message/message_drawer_events'\n],\nfunction(\n $,\n Notification,\n Str,\n PubSub,\n Templates,\n Repository,\n CustomEvents,\n MessageDrawerEvents\n) {\n\n var SELECTORS = {\n CHECKBOX: 'input[type=\"checkbox\"]',\n SETTINGS: '[data-region=\"settings\"]',\n PRIVACY_PREFERENCE: '[data-preference=\"blocknoncontacts\"] input[type=\"radio\"]',\n NOTIFICATIONS_PREFERENCE: '[data-preference=\"notifications\"] input[type=\"checkbox\"]',\n ENTER_TO_SEND_PREFERENCE: '[data-preference=\"entertosend\"] input[type=\"checkbox\"]',\n NOTIFICATION_PREFERENCES_CONTAINER: '[data-region=\"notification-preference-container\"]',\n CONTENT_CONTAINER: '[data-region=\"content-container\"]',\n PLACEHOLDER_CONTAINER: '[data-region=\"placeholder-container\"]'\n };\n\n var TEMPLATES = {\n NOTIFICATION_PREFERENCES: 'core_message/message_drawer_view_settings_body_content_notification_preferences'\n };\n\n var NOTIFICATION_PREFERENCES_KEY = 'message_provider_moodle_instantmessage';\n\n /**\n * Select the correct radio button in the DOM for the privacy preference.\n *\n * @param {Object} body The settings body element.\n * @param {Number} value Which radio button should be set\n */\n var setPrivacyPreference = function(body, value) {\n var inputs = body.find(SELECTORS.PRIVACY_PREFERENCE);\n inputs.each(function(index, input) {\n input = $(input);\n if (input.val() == value) {\n input.prop('checked', true);\n } else {\n input.prop('checked', false);\n }\n });\n };\n\n /**\n * Set the \"enter to send\" checkbox to the correct value in the DOM.\n *\n * @param {Object} body The settings body element.\n * @param {Bool} value Whether enter to send is enabled or disabled.\n */\n var setEnterToSend = function(body, value) {\n var checkbox = body.find(SELECTORS.ENTER_TO_SEND_PREFERENCE);\n\n if (value) {\n checkbox.prop('checked', true);\n } else {\n checkbox.prop('checked', false);\n }\n };\n\n /**\n * Send a request to the server to save the given preferences. Also publish\n * a preferences updated event for the rest of the message drawer to\n * subscribe to.\n *\n * @param {Number} loggedInUserId The logged in user id.\n * @param {Array} preferences The preferences to set.\n * @return {Object} jQuery promise\n */\n var savePreferences = function(loggedInUserId, preferences) {\n return Repository.savePreferences(loggedInUserId, preferences)\n .then(function() {\n PubSub.publish(MessageDrawerEvents.PREFERENCES_UPDATED, preferences);\n return;\n })\n .catch(Notification.exception);\n };\n\n /**\n * Create all of the event listeners for the message preferences page.\n *\n * @method registerEventListeners\n * @param {Object} body The settings body element.\n * @param {Number} loggedInUserId The logged in user id.\n */\n var registerEventListeners = function(body, loggedInUserId) {\n var settingsContainer = body.find(SELECTORS.SETTINGS);\n\n CustomEvents.define(settingsContainer, [\n CustomEvents.events.activate\n ]);\n\n settingsContainer.on(CustomEvents.events.activate, SELECTORS.NOTIFICATIONS_PREFERENCE, function(e) {\n var container = $(e.target).closest(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);\n var checkboxes = container.find(SELECTORS.CHECKBOX);\n if (!checkboxes.length) {\n return;\n }\n // The preference value is all of the enabled processors, comma separated, so let's\n // see which ones are enabled.\n var values = checkboxes.toArray().reduce(function(carry, checkbox) {\n checkbox = $(checkbox);\n if (checkbox.prop('checked')) {\n carry.push(checkbox.attr('data-name'));\n }\n\n return carry;\n }, []);\n var newValue = values.length ? values.join(',') : 'none';\n var preferences = [\n {\n type: 'message_provider_moodle_instantmessage_enabled',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n\n settingsContainer.on('change', SELECTORS.PRIVACY_PREFERENCE, function(e) {\n var newValue = $(e.target).val();\n var preferences = [\n {\n type: 'message_blocknoncontacts',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n\n settingsContainer.on(CustomEvents.events.activate, SELECTORS.ENTER_TO_SEND_PREFERENCE, function(e) {\n var newValue = $(e.target).prop('checked');\n var preferences = [\n {\n type: 'message_entertosend',\n value: newValue\n }\n ];\n\n savePreferences(loggedInUserId, preferences);\n });\n };\n\n /**\n * Initialise the module by loading the user's messaging preferences from the server and\n * rendering them in the settings page.\n *\n * Moodle may have many (or no) message processors enabled to notify the user when they\n * receive messages. We need to dynamically build the settings page based on which processors\n * are configured for the user.\n *\n * @param {Object} body The settings body element.\n * @param {Number} loggedInUserId The logged in user id.\n */\n var init = function(body, loggedInUserId) {\n // Load the message preferences from the server.\n Repository.getUserMessagePreferences(loggedInUserId)\n .then(function(response) {\n // Set the values of the stright forward preferences.\n setPrivacyPreference(body, response.blocknoncontacts);\n setEnterToSend(body, response.entertosend);\n\n // Parse the list of other preferences into a more usable format.\n var notificationProcessors = [];\n if (response.preferences.components.length) {\n response.preferences.components.forEach(function(component) {\n if (component.notifications.length) {\n // Filter down to just the notification processors that work on instant\n // messaging. We don't care about another other ones.\n var notificationPreferences = component.notifications.filter(function(notification) {\n return notification.preferencekey == NOTIFICATION_PREFERENCES_KEY;\n });\n\n if (notificationPreferences.length) {\n // Messaging only has one config at the moment which is for notifications\n // on personal messages.\n var configuration = component.notifications[0];\n notificationProcessors = configuration.processors.map(function(processor) {\n // Consider the the processor enabled if either preference is set. This is\n // for backwards compatibility. Going forward they will be treated as one\n // setting.\n var checked = processor.enabled;\n return {\n displayname: processor.displayname,\n name: processor.name,\n checked: checked,\n // The admin can force processors to be enabled at a site level so\n // we need to check if this processor has been locked by the admin.\n locked: processor.locked,\n lockedmessage: processor.lockedmessage || null,\n };\n });\n }\n }\n });\n }\n\n var container = body.find(SELECTORS.NOTIFICATION_PREFERENCES_CONTAINER);\n if (notificationProcessors.length) {\n // We have processors (i.e. email, mobile, jabber) to show.\n container.removeClass('hidden');\n // Render the processor options.\n return Templates.render(TEMPLATES.NOTIFICATION_PREFERENCES, {processors: notificationProcessors})\n .then(function(html) {\n container.append(html);\n return html;\n });\n } else {\n return true;\n }\n })\n .then(function() {\n // We're done loading so hide the loading placeholder and show the settings.\n body.find(SELECTORS.CONTENT_CONTAINER).removeClass('hidden');\n body.find(SELECTORS.PLACEHOLDER_CONTAINER).addClass('hidden');\n // Register the event listers for if the user wants to change the preferences.\n registerEventListeners(body, loggedInUserId);\n return;\n })\n .catch(Notification.exception);\n };\n\n /**\n * Initialise the settings page by adding event listeners to\n * the checkboxes.\n *\n * @param {string} namespace The route namespace.\n * @param {Object} header The settings header element.\n * @param {Object} body The settings body element.\n * @param {Object} footer The footer body element.\n * @param {Number} loggedInUserId The logged in user id.\n * @return {Object} jQuery promise\n */\n var show = function(namespace, header, body, footer, loggedInUserId) {\n if (!body.attr('data-init')) {\n init(body, loggedInUserId);\n body.attr('data-init', true);\n }\n\n return $.Deferred().resolve().promise();\n };\n\n /**\n * String describing this page used for aria-labels.\n *\n * @return {Object} jQuery promise\n */\n var description = function() {\n return Str.get_string('messagedrawerviewsettings', 'core_message');\n };\n\n return {\n show: show,\n description: description,\n };\n});\n"],"file":"message_drawer_view_settings.min.js"} \ No newline at end of file diff --git a/message/amd/build/notification_preference.min.js b/message/amd/build/notification_preference.min.js index 7ca6baed872..b9c28e60f7d 100644 --- a/message/amd/build/notification_preference.min.js +++ b/message/amd/build/notification_preference.min.js @@ -1,2 +1,2 @@ -define ("core_message/notification_preference",["jquery","core/ajax","core/notification","core_message/notification_processor"],function(a,b,c,d){var e={PROCESSOR:"[data-processor-name]",STATE_INPUTS:"[data-state] input"},f=function(b,c){this.root=a(b);this.userId=c};f.prototype.getPreferenceKey=function(){return this.root.attr("data-preference-key")};f.prototype.getLoggedInPreferenceKey=function(){return this.getPreferenceKey()+"_loggedin"};f.prototype.getLoggedOffPreferenceKey=function(){return this.getPreferenceKey()+"_loggedoff"};f.prototype.getProcessors=function(){return this.root.find(e.PROCESSOR).map(function(b,c){return new d(a(c))})};f.prototype.startLoading=function(){this.root.addClass("loading");this.root.find(e.STATE_INPUTS).prop("disabled",!0)};f.prototype.stopLoading=function(){this.root.removeClass("loading");this.root.find(e.STATE_INPUTS).prop("disabled",!1)};f.prototype.isLoading=function(){return this.root.hasClass("loading")};f.prototype.save=function(){if(this.isLoading()){return a.Deferred().resolve()}this.startLoading();var d="",e="";this.getProcessors().each(function(a,b){if(b.isLoggedInEnabled()){if(""===d){d=b.getName()}else{d+=","+b.getName()}}if(b.isLoggedOffEnabled()){if(""===e){e=b.getName()}else{e+=","+b.getName()}}});if(""===d){d="none"}if(""===e){e="none"}var f={userid:this.userId,preferences:[{type:this.getLoggedInPreferenceKey(),value:d},{type:this.getLoggedOffPreferenceKey(),value:e}]};return b.call([{methodname:"core_user_update_user_preferences",args:f}])[0].fail(c.exception).always(function(){this.stopLoading()}.bind(this))};return f}); +define ("core_message/notification_preference",["jquery","core/ajax","core/notification","core_message/notification_processor"],function(a,b,c,d){var e={PROCESSOR:"[data-processor-name]",STATE_INPUTS:"[data-state] input"},f=function(b,c){this.root=a(b);this.userId=c};f.prototype.getPreferenceKey=function(){return this.root.attr("data-preference-key")};f.prototype.getEnabledPreferenceKey=function(){return this.getPreferenceKey()+"_enabled"};f.prototype.getProcessors=function(){return this.root.find(e.PROCESSOR).map(function(b,c){return new d(a(c))})};f.prototype.startLoading=function(){this.root.addClass("loading");this.root.find(e.STATE_INPUTS).prop("disabled",!0)};f.prototype.stopLoading=function(){this.root.removeClass("loading");this.root.find(e.STATE_INPUTS).prop("disabled",!1)};f.prototype.isLoading=function(){return this.root.hasClass("loading")};f.prototype.save=function(){if(this.isLoading()){return a.Deferred().resolve()}this.startLoading();var d="";this.getProcessors().each(function(a,b){if(b.isEnabled()){if(""===d){d=b.getName()}else{d+=","+b.getName()}}});if(""===d){d="none"}var e={userid:this.userId,preferences:[{type:this.getEnabledPreferenceKey(),value:d}]};return b.call([{methodname:"core_user_update_user_preferences",args:e}])[0].fail(c.exception).always(function(){this.stopLoading()}.bind(this))};return f}); //# sourceMappingURL=notification_preference.min.js.map diff --git a/message/amd/build/notification_preference.min.js.map b/message/amd/build/notification_preference.min.js.map index e5f5b7e0b9a..a239bb9043d 100644 --- a/message/amd/build/notification_preference.min.js.map +++ b/message/amd/build/notification_preference.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/notification_preference.js"],"names":["define","$","Ajax","Notification","NotificationProcessor","SELECTORS","PROCESSOR","STATE_INPUTS","NotificationPreference","element","userId","root","prototype","getPreferenceKey","attr","getLoggedInPreferenceKey","getLoggedOffPreferenceKey","getProcessors","find","map","index","startLoading","addClass","prop","stopLoading","removeClass","isLoading","hasClass","save","Deferred","resolve","loggedInValue","loggedOffValue","each","processor","isLoggedInEnabled","getName","isLoggedOffEnabled","args","userid","preferences","type","value","call","methodname","fail","exception","always","bind"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the preference for an individual notification type on the\n * message preference page.\n *\n * @module core_message/notification_preference\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_processor'],\n function($, Ajax, Notification, NotificationProcessor) {\n\n var SELECTORS = {\n PROCESSOR: '[data-processor-name]',\n STATE_INPUTS: '[data-state] input',\n };\n\n /**\n * Constructor for the Preference.\n *\n * @class\n * @param {object} element jQuery object root element of the preference\n * @param {int} userId The current user id\n */\n var NotificationPreference = function(element, userId) {\n this.root = $(element);\n this.userId = userId;\n };\n\n /**\n * Get the unique prefix key that identifies this user preference.\n *\n * @method getPreferenceKey\n * @return {string}\n */\n NotificationPreference.prototype.getPreferenceKey = function() {\n return this.root.attr('data-preference-key');\n };\n\n /**\n * Get the unique key for the logged in preference.\n *\n * @method getLoggedInPreferenceKey\n * @return {string}\n */\n NotificationPreference.prototype.getLoggedInPreferenceKey = function() {\n return this.getPreferenceKey() + '_loggedin';\n };\n\n /**\n * Get the unique key for the logged off preference.\n *\n * @method getLoggedOffPreferenceKey\n * @return {string}\n */\n NotificationPreference.prototype.getLoggedOffPreferenceKey = function() {\n return this.getPreferenceKey() + '_loggedoff';\n };\n\n /**\n * Get the list of Processors available for this preference.\n *\n * @method getProcessors\n * @return {array}\n */\n NotificationPreference.prototype.getProcessors = function() {\n return this.root.find(SELECTORS.PROCESSOR).map(function(index, element) {\n return new NotificationProcessor($(element));\n });\n };\n\n /**\n * Flag the preference as loading.\n *\n * @method startLoading\n */\n NotificationPreference.prototype.startLoading = function() {\n this.root.addClass('loading');\n this.root.find(SELECTORS.STATE_INPUTS).prop('disabled', true);\n };\n\n /**\n * Remove the loading flag for this preference.\n *\n * @method stopLoading\n */\n NotificationPreference.prototype.stopLoading = function() {\n this.root.removeClass('loading');\n this.root.find(SELECTORS.STATE_INPUTS).prop('disabled', false);\n };\n\n /**\n * Check if the preference is loading.\n *\n * @method isLoading\n * @return {Boolean}\n */\n NotificationPreference.prototype.isLoading = function() {\n return this.root.hasClass('loading');\n };\n\n /**\n * Persist the current state of the processors for this preference.\n *\n * @method save\n * @return {object} jQuery promise\n */\n NotificationPreference.prototype.save = function() {\n if (this.isLoading()) {\n return $.Deferred().resolve();\n }\n\n this.startLoading();\n\n var loggedInValue = '';\n var loggedOffValue = '';\n\n this.getProcessors().each(function(index, processor) {\n if (processor.isLoggedInEnabled()) {\n if (loggedInValue === '') {\n loggedInValue = processor.getName();\n } else {\n loggedInValue += ',' + processor.getName();\n }\n }\n\n if (processor.isLoggedOffEnabled()) {\n if (loggedOffValue === '') {\n loggedOffValue = processor.getName();\n } else {\n loggedOffValue += ',' + processor.getName();\n }\n }\n });\n\n if (loggedInValue === '') {\n loggedInValue = 'none';\n }\n\n if (loggedOffValue === '') {\n loggedOffValue = 'none';\n }\n\n var args = {\n userid: this.userId,\n preferences: [\n {\n type: this.getLoggedInPreferenceKey(),\n value: loggedInValue,\n },\n {\n type: this.getLoggedOffPreferenceKey(),\n value: loggedOffValue,\n },\n ],\n };\n\n var request = {\n methodname: 'core_user_update_user_preferences',\n args: args,\n };\n\n return Ajax.call([request])[0]\n .fail(Notification.exception)\n .always(function() {\n this.stopLoading();\n }.bind(this));\n };\n\n return NotificationPreference;\n});\n"],"file":"notification_preference.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/notification_preference.js"],"names":["define","$","Ajax","Notification","NotificationProcessor","SELECTORS","PROCESSOR","STATE_INPUTS","NotificationPreference","element","userId","root","prototype","getPreferenceKey","attr","getEnabledPreferenceKey","getProcessors","find","map","index","startLoading","addClass","prop","stopLoading","removeClass","isLoading","hasClass","save","Deferred","resolve","enabledValue","each","processor","isEnabled","getName","args","userid","preferences","type","value","call","methodname","fail","exception","always","bind"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the preference for an individual notification type on the\n * message preference page.\n *\n * @module core_message/notification_preference\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_processor'],\n function($, Ajax, Notification, NotificationProcessor) {\n\n const SELECTORS = {\n PROCESSOR: '[data-processor-name]',\n STATE_INPUTS: '[data-state] input',\n };\n\n /**\n * Constructor for the Preference.\n *\n * @class\n * @param {object} element jQuery object root element of the preference\n * @param {int} userId The current user id\n */\n const NotificationPreference = function(element, userId) {\n this.root = $(element);\n this.userId = userId;\n };\n\n /**\n * Get the unique prefix key that identifies this user preference.\n *\n * @method getPreferenceKey\n * @return {string}\n */\n NotificationPreference.prototype.getPreferenceKey = function() {\n return this.root.attr('data-preference-key');\n };\n\n /**\n * Get the unique key for the enabled preference.\n *\n * @method getEnabledPreferenceKey\n * @return {string}\n */\n NotificationPreference.prototype.getEnabledPreferenceKey = function() {\n return this.getPreferenceKey() + '_enabled';\n };\n\n /**\n * Get the list of Processors available for this preference.\n *\n * @method getProcessors\n * @return {array}\n */\n NotificationPreference.prototype.getProcessors = function() {\n return this.root.find(SELECTORS.PROCESSOR).map(function(index, element) {\n return new NotificationProcessor($(element));\n });\n };\n\n /**\n * Flag the preference as loading.\n *\n * @method startLoading\n */\n NotificationPreference.prototype.startLoading = function() {\n this.root.addClass('loading');\n this.root.find(SELECTORS.STATE_INPUTS).prop('disabled', true);\n };\n\n /**\n * Remove the loading flag for this preference.\n *\n * @method stopLoading\n */\n NotificationPreference.prototype.stopLoading = function() {\n this.root.removeClass('loading');\n this.root.find(SELECTORS.STATE_INPUTS).prop('disabled', false);\n };\n\n /**\n * Check if the preference is loading.\n *\n * @method isLoading\n * @return {Boolean}\n */\n NotificationPreference.prototype.isLoading = function() {\n return this.root.hasClass('loading');\n };\n\n /**\n * Persist the current state of the processors for this preference.\n *\n * @method save\n * @return {object} jQuery promise\n */\n NotificationPreference.prototype.save = function() {\n if (this.isLoading()) {\n return $.Deferred().resolve();\n }\n\n this.startLoading();\n\n let enabledValue = '';\n\n this.getProcessors().each(function(index, processor) {\n if (processor.isEnabled()) {\n if (enabledValue === '') {\n enabledValue = processor.getName();\n } else {\n enabledValue += ',' + processor.getName();\n }\n }\n });\n\n if (enabledValue === '') {\n enabledValue = 'none';\n }\n\n const args = {\n userid: this.userId,\n preferences: [\n {\n type: this.getEnabledPreferenceKey(),\n value: enabledValue,\n }\n ],\n };\n\n const request = {\n methodname: 'core_user_update_user_preferences',\n args: args,\n };\n\n return Ajax.call([request])[0]\n .fail(Notification.exception)\n .always(function() {\n this.stopLoading();\n }.bind(this));\n };\n\n return NotificationPreference;\n});\n"],"file":"notification_preference.min.js"} \ No newline at end of file diff --git a/message/amd/build/notification_processor.min.js b/message/amd/build/notification_processor.min.js index 15aa09f9ed8..ac17e8e46c4 100644 --- a/message/amd/build/notification_processor.min.js +++ b/message/amd/build/notification_processor.min.js @@ -1,2 +1,2 @@ -define ("core_message/notification_processor",["jquery"],function(a){var b={STATE_NONE:"[data-state=\"none\"]",STATE_BOTH:"[data-state=\"both\"]",STATE_LOGGED_IN:"[data-state=\"loggedin\"]",STATE_LOGGED_OFF:"[data-state=\"loggedoff\"]"},c=function(b){this.root=a(b)};c.prototype.getName=function(){return this.root.attr("data-processor-name")};c.prototype.isLoggedInEnabled=function(){var a=this.root.find(b.STATE_NONE).find("input");if(a.prop("checked")){return!1}var c=this.root.find(b.STATE_BOTH).find("input"),d=this.root.find(b.STATE_LOGGED_IN).find("input");return d.prop("checked")||c.prop("checked")};c.prototype.isLoggedOffEnabled=function(){var a=this.root.find(b.STATE_NONE).find("input");if(a.prop("checked")){return!1}var c=this.root.find(b.STATE_BOTH).find("input"),d=this.root.find(b.STATE_LOGGED_OFF).find("input");return d.prop("checked")||c.prop("checked")};return c}); +define ("core_message/notification_processor",["jquery"],function(a){var b={STATE_INPUTS:".preference-state input.notification_enabled"},c=function(b){this.root=a(b)};c.prototype.getName=function(){return this.root.attr("data-processor-name")};c.prototype.isEnabled=function(){var a=this.root.find(b.STATE_INPUTS);return a.prop("checked")};return c}); //# sourceMappingURL=notification_processor.min.js.map diff --git a/message/amd/build/notification_processor.min.js.map b/message/amd/build/notification_processor.min.js.map index 174c134670f..31262036e49 100644 --- a/message/amd/build/notification_processor.min.js.map +++ b/message/amd/build/notification_processor.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/notification_processor.js"],"names":["define","$","SELECTORS","STATE_NONE","STATE_BOTH","STATE_LOGGED_IN","STATE_LOGGED_OFF","NotificationProcessor","element","root","prototype","getName","attr","isLoggedInEnabled","none","find","prop","both","loggedIn","isLoggedOffEnabled","loggedOff"],"mappings":"AAsBAA,OAAM,uCAAC,CAAC,QAAD,CAAD,CAAa,SAASC,CAAT,CAAY,IACvBC,CAAAA,CAAS,CAAG,CACZC,UAAU,CAAE,uBADA,CAEZC,UAAU,CAAE,uBAFA,CAGZC,eAAe,CAAE,2BAHL,CAIZC,gBAAgB,CAAE,4BAJN,CADW,CAcvBC,CAAqB,CAAG,SAASC,CAAT,CAAkB,CAC1C,KAAKC,IAAL,CAAYR,CAAC,CAACO,CAAD,CAChB,CAhB0B,CAwB3BD,CAAqB,CAACG,SAAtB,CAAgCC,OAAhC,CAA0C,UAAW,CACjD,MAAO,MAAKF,IAAL,CAAUG,IAAV,CAAe,qBAAf,CACV,CAFD,CAUAL,CAAqB,CAACG,SAAtB,CAAgCG,iBAAhC,CAAoD,UAAW,CAC3D,GAAIC,CAAAA,CAAI,CAAG,KAAKL,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACC,UAAzB,EAAqCY,IAArC,CAA0C,OAA1C,CAAX,CAEA,GAAID,CAAI,CAACE,IAAL,CAAU,SAAV,CAAJ,CAA0B,CACtB,QACH,CAL0D,GAOvDC,CAAAA,CAAI,CAAG,KAAKR,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACE,UAAzB,EAAqCW,IAArC,CAA0C,OAA1C,CAPgD,CAQvDG,CAAQ,CAAG,KAAKT,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACG,eAAzB,EAA0CU,IAA1C,CAA+C,OAA/C,CAR4C,CAU3D,MAAOG,CAAAA,CAAQ,CAACF,IAAT,CAAc,SAAd,GAA4BC,CAAI,CAACD,IAAL,CAAU,SAAV,CACtC,CAXD,CAmBAT,CAAqB,CAACG,SAAtB,CAAgCS,kBAAhC,CAAqD,UAAW,CAC5D,GAAIL,CAAAA,CAAI,CAAG,KAAKL,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACC,UAAzB,EAAqCY,IAArC,CAA0C,OAA1C,CAAX,CAEA,GAAID,CAAI,CAACE,IAAL,CAAU,SAAV,CAAJ,CAA0B,CACtB,QACH,CAL2D,GAOxDC,CAAAA,CAAI,CAAG,KAAKR,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACE,UAAzB,EAAqCW,IAArC,CAA0C,OAA1C,CAPiD,CAQxDK,CAAS,CAAG,KAAKX,IAAL,CAAUM,IAAV,CAAeb,CAAS,CAACI,gBAAzB,EAA2CS,IAA3C,CAAgD,OAAhD,CAR4C,CAU5D,MAAOK,CAAAA,CAAS,CAACJ,IAAV,CAAe,SAAf,GAA6BC,CAAI,CAACD,IAAL,CAAU,SAAV,CACvC,CAXD,CAaA,MAAOT,CAAAA,CACV,CAnEK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Represents the notification processor (e.g. email, popup, jabber)\n *\n * @module core_message/notification_processor\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery'], function($) {\n var SELECTORS = {\n STATE_NONE: '[data-state=\"none\"]',\n STATE_BOTH: '[data-state=\"both\"]',\n STATE_LOGGED_IN: '[data-state=\"loggedin\"]',\n STATE_LOGGED_OFF: '[data-state=\"loggedoff\"]',\n };\n\n /**\n * Constructor for the notification processor.\n *\n * @class\n * @param {object} element jQuery object root element of the processor\n */\n var NotificationProcessor = function(element) {\n this.root = $(element);\n };\n\n /**\n * Get the processor name.\n *\n * @method getName\n * @return {string}\n */\n NotificationProcessor.prototype.getName = function() {\n return this.root.attr('data-processor-name');\n };\n\n /**\n * Check if the processor is enabled when the user is logged in.\n *\n * @method isLoggedInEnabled\n * @return {bool}\n */\n NotificationProcessor.prototype.isLoggedInEnabled = function() {\n var none = this.root.find(SELECTORS.STATE_NONE).find('input');\n\n if (none.prop('checked')) {\n return false;\n }\n\n var both = this.root.find(SELECTORS.STATE_BOTH).find('input');\n var loggedIn = this.root.find(SELECTORS.STATE_LOGGED_IN).find('input');\n\n return loggedIn.prop('checked') || both.prop('checked');\n };\n\n /**\n * Check if the processor is enabled when the user is logged out.\n *\n * @method isLoggedOffEnabled\n * @return {bool}\n */\n NotificationProcessor.prototype.isLoggedOffEnabled = function() {\n var none = this.root.find(SELECTORS.STATE_NONE).find('input');\n\n if (none.prop('checked')) {\n return false;\n }\n\n var both = this.root.find(SELECTORS.STATE_BOTH).find('input');\n var loggedOff = this.root.find(SELECTORS.STATE_LOGGED_OFF).find('input');\n\n return loggedOff.prop('checked') || both.prop('checked');\n };\n\n return NotificationProcessor;\n});\n"],"file":"notification_processor.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/notification_processor.js"],"names":["define","$","SELECTORS","STATE_INPUTS","NotificationProcessor","element","root","prototype","getName","attr","isEnabled","enabled","find","prop"],"mappings":"AAsBAA,OAAM,uCAAC,CAAC,QAAD,CAAD,CAAa,SAASC,CAAT,CAAY,IACrBC,CAAAA,CAAS,CAAG,CACdC,YAAY,CAAE,8CADA,CADS,CAWrBC,CAAqB,CAAG,SAASC,CAAT,CAAkB,CAC5C,KAAKC,IAAL,CAAYL,CAAC,CAACI,CAAD,CAChB,CAb0B,CAqB3BD,CAAqB,CAACG,SAAtB,CAAgCC,OAAhC,CAA0C,UAAW,CACjD,MAAO,MAAKF,IAAL,CAAUG,IAAV,CAAe,qBAAf,CACV,CAFD,CAUAL,CAAqB,CAACG,SAAtB,CAAgCG,SAAhC,CAA4C,UAAW,CACnD,GAAMC,CAAAA,CAAO,CAAG,KAAKL,IAAL,CAAUM,IAAV,CAAeV,CAAS,CAACC,YAAzB,CAAhB,CAEA,MAAOQ,CAAAA,CAAO,CAACE,IAAR,CAAa,SAAb,CACV,CAJD,CAMA,MAAOT,CAAAA,CACV,CAtCK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Represents the notification processor (e.g. email, popup, jabber)\n *\n * @module core_message/notification_processor\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery'], function($) {\n const SELECTORS = {\n STATE_INPUTS: '.preference-state input.notification_enabled'\n };\n\n /**\n * Constructor for the notification processor.\n *\n * @class\n * @param {object} element jQuery object root element of the processor\n */\n const NotificationProcessor = function(element) {\n this.root = $(element);\n };\n\n /**\n * Get the processor name.\n *\n * @method getName\n * @return {string}\n */\n NotificationProcessor.prototype.getName = function() {\n return this.root.attr('data-processor-name');\n };\n\n /**\n * Check if the processor is enabled when the user is logged in.\n *\n * @method isLoggedInEnabled\n * @return {bool}\n */\n NotificationProcessor.prototype.isEnabled = function() {\n const enabled = this.root.find(SELECTORS.STATE_INPUTS);\n\n return enabled.prop('checked');\n };\n\n return NotificationProcessor;\n});\n"],"file":"notification_processor.min.js"} \ No newline at end of file diff --git a/message/amd/build/preferences_notifications_list_controller.min.js b/message/amd/build/preferences_notifications_list_controller.min.js index e6c81afd751..27f2d6c0168 100644 --- a/message/amd/build/preferences_notifications_list_controller.min.js +++ b/message/amd/build/preferences_notifications_list_controller.min.js @@ -1,2 +1,2 @@ -define ("core_message/preferences_notifications_list_controller",["jquery","core/ajax","core/notification","core/custom_interaction_events","core_message/notification_preference","core_message/notification_processor_settings","core/modal_factory"],function(a,b,c,d,f,g,h){var i={DISABLE_NOTIFICATIONS:"[data-region=\"disable-notification-container\"] [data-disable-notifications]",DISABLE_NOTIFICATIONS_CONTAINER:"[data-region=\"disable-notification-container\"]",PREFERENCE:"[data-state]",PREFERENCE_ROW:"[data-region=\"preference-row\"]",PREFERENCE_INPUT:"[data-state] input",PROCESSOR_SETTING:"[data-processor-setting]"},j=function(b){this.root=a(b);this.userId=this.root.attr("data-user-id");this.registerEventListeners()};j.prototype.isDisabled=function(){return this.root.hasClass("disabled")};j.prototype.setDisabled=function(){this.root.addClass("disabled");this.root.find(i.PREFERENCE_INPUT).prop("disabled",!0)};j.prototype.setEnabled=function(){this.root.removeClass("disabled");this.root.find(i.PREFERENCE_INPUT).prop("disabled",!1)};j.prototype.toggleDisableAllStatus=function(){var d=a(i.DISABLE_NOTIFICATIONS),e=a(i.DISABLE_NOTIFICATIONS_CONTAINER),f=d.prop("checked");if(e.hasClass("loading")){return a.Deferred().resolve()}e.addClass("loading");var g={methodname:"core_user_update_user_preferences",args:{userid:this.userId,emailstop:f?1:0}};return b.call([g])[0].done(function(){if(f){this.setDisabled()}else{this.setEnabled()}}.bind(this)).always(function(){e.removeClass("loading")}).fail(c.exception)};j.prototype.registerEventListeners=function(){var b=a(i.DISABLE_NOTIFICATIONS);d.define(this.root,[d.events.activate]);this.root.on("change",function(b){if(!this.isDisabled()){var c=a(b.target).closest(i.PREFERENCE),d=a(b.target).closest(i.PREFERENCE_ROW),e=new f(d,this.userId);c.addClass("loading");e.save().always(function(){c.removeClass("loading")})}}.bind(this));var j=h.create({type:g.TYPE});this.root.on(d.events.activate,i.PROCESSOR_SETTING,function(b,d){var e=a(b.target).closest(i.PROCESSOR_SETTING);d.originalEvent.preventDefault();j.then(function(c){c.setUserId(a(e).attr("data-user-id"));c.setName(a(e).attr("data-name"));c.setContextId(a(e).attr("data-context-id"));c.setElement(e);c.show();b.stopImmediatePropagation()}).fail(c.exception)});d.define(b,[d.events.activate]);b.on(d.events.activate,function(){this.toggleDisableAllStatus()}.bind(this))};return j}); +define ("core_message/preferences_notifications_list_controller",["jquery","core/ajax","core/notification","core/custom_interaction_events","core_message/notification_preference","core_message/notification_processor_settings","core/modal_factory"],function(a,b,c,d,f,g,h){var i={DISABLE_NOTIFICATIONS:"[data-region=\"disable-notification-container\"] [data-disable-notifications]",DISABLE_NOTIFICATIONS_CONTAINER:"[data-region=\"disable-notification-container\"]",PREFERENCE:".preference-state",PREFERENCE_ROW:"[data-region=\"preference-row\"]",PREFERENCE_INPUT:".preference-state input",PROCESSOR_SETTING:"[data-processor-setting]"},j=function(b){this.root=a(b);this.userId=this.root.attr("data-user-id");this.registerEventListeners()};j.prototype.isDisabled=function(){return this.root.hasClass("disabled")};j.prototype.setDisabled=function(){this.root.addClass("disabled");this.root.find(i.PREFERENCE_INPUT).prop("disabled",!0)};j.prototype.setEnabled=function(){this.root.removeClass("disabled");this.root.find(i.PREFERENCE_INPUT).prop("disabled",!1)};j.prototype.toggleDisableAllStatus=function(){var d=a(i.DISABLE_NOTIFICATIONS),e=a(i.DISABLE_NOTIFICATIONS_CONTAINER),f=d.prop("checked");if(e.hasClass("loading")){return a.Deferred().resolve()}e.addClass("loading");var g={methodname:"core_user_update_user_preferences",args:{userid:this.userId,emailstop:f?1:0}};return b.call([g])[0].done(function(){if(f){this.setDisabled()}else{this.setEnabled()}}.bind(this)).always(function(){e.removeClass("loading")}).fail(c.exception)};j.prototype.registerEventListeners=function(){var b=a(i.DISABLE_NOTIFICATIONS);d.define(this.root,[d.events.activate]);this.root.on("change",function(b){if(!this.isDisabled()){var c=a(b.target).closest(i.PREFERENCE),d=a(b.target).closest(i.PREFERENCE_ROW),e=new f(d,this.userId);c.addClass("loading");e.save().always(function(){c.removeClass("loading")})}}.bind(this));var j=h.create({type:g.TYPE});this.root.on(d.events.activate,i.PROCESSOR_SETTING,function(b,d){var e=a(b.target).closest(i.PROCESSOR_SETTING);d.originalEvent.preventDefault();j.then(function(c){c.setUserId(a(e).attr("data-user-id"));c.setName(a(e).attr("data-name"));c.setContextId(a(e).attr("data-context-id"));c.setElement(e);c.show();b.stopImmediatePropagation()}).fail(c.exception)});d.define(b,[d.events.activate]);b.on(d.events.activate,function(){this.toggleDisableAllStatus()}.bind(this))};return j}); //# sourceMappingURL=preferences_notifications_list_controller.min.js.map diff --git a/message/amd/build/preferences_notifications_list_controller.min.js.map b/message/amd/build/preferences_notifications_list_controller.min.js.map index 088f98c4e9e..201f59f1a00 100644 --- a/message/amd/build/preferences_notifications_list_controller.min.js.map +++ b/message/amd/build/preferences_notifications_list_controller.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/preferences_notifications_list_controller.js"],"names":["define","$","Ajax","Notification","CustomEvents","NotificationPreference","NotificationProcessorSettings","ModalFactory","SELECTORS","DISABLE_NOTIFICATIONS","DISABLE_NOTIFICATIONS_CONTAINER","PREFERENCE","PREFERENCE_ROW","PREFERENCE_INPUT","PROCESSOR_SETTING","PreferencesController","element","root","userId","attr","registerEventListeners","prototype","isDisabled","hasClass","setDisabled","addClass","find","prop","setEnabled","removeClass","toggleDisableAllStatus","checkbox","container","ischecked","Deferred","resolve","request","methodname","args","userid","emailstop","call","done","bind","always","fail","exception","disabledNotificationsElement","events","activate","on","e","preferenceElement","target","closest","preferenceRow","preference","save","eventFormPromise","create","type","TYPE","data","originalEvent","preventDefault","then","modal","setUserId","setName","setContextId","setElement","show","stopImmediatePropagation"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the preferences for the list of notification types on the\n * message preference page\n *\n * @module core_message/preferences_notifications_list_controller\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery',\n 'core/ajax',\n 'core/notification',\n 'core/custom_interaction_events',\n 'core_message/notification_preference',\n 'core_message/notification_processor_settings',\n 'core/modal_factory',\n ],\n function(\n $,\n Ajax,\n Notification,\n CustomEvents,\n NotificationPreference,\n NotificationProcessorSettings,\n ModalFactory\n ) {\n\n var SELECTORS = {\n DISABLE_NOTIFICATIONS: '[data-region=\"disable-notification-container\"] [data-disable-notifications]',\n DISABLE_NOTIFICATIONS_CONTAINER: '[data-region=\"disable-notification-container\"]',\n PREFERENCE: '[data-state]',\n PREFERENCE_ROW: '[data-region=\"preference-row\"]',\n PREFERENCE_INPUT: '[data-state] input',\n PROCESSOR_SETTING: '[data-processor-setting]',\n };\n\n /**\n * Constructor for the PreferencesController.\n *\n * @class\n * @param {object} element jQuery object root element of the preference\n */\n var PreferencesController = function(element) {\n this.root = $(element);\n this.userId = this.root.attr('data-user-id');\n\n this.registerEventListeners();\n };\n\n /**\n * Check if the preferences are all disabled.\n *\n * @method isDisabled\n * @return {bool}\n */\n PreferencesController.prototype.isDisabled = function() {\n return this.root.hasClass('disabled');\n };\n\n /**\n * Disable all of the preferences.\n *\n * @method setDisabled\n */\n PreferencesController.prototype.setDisabled = function() {\n this.root.addClass('disabled');\n this.root.find(SELECTORS.PREFERENCE_INPUT).prop('disabled', true);\n };\n\n /**\n * Enable all of the preferences.\n *\n * @method setEnabled\n */\n PreferencesController.prototype.setEnabled = function() {\n this.root.removeClass('disabled');\n this.root.find(SELECTORS.PREFERENCE_INPUT).prop('disabled', false);\n };\n\n /**\n * Update the disable all notifications user property in the DOM and\n * send a request to update on the server.\n *\n * @method toggleDisableAllStatus\n * @return {Promise}\n */\n PreferencesController.prototype.toggleDisableAllStatus = function() {\n var checkbox = $(SELECTORS.DISABLE_NOTIFICATIONS);\n var container = $(SELECTORS.DISABLE_NOTIFICATIONS_CONTAINER);\n var ischecked = checkbox.prop('checked');\n\n if (container.hasClass('loading')) {\n return $.Deferred().resolve();\n }\n\n container.addClass('loading');\n\n var request = {\n methodname: 'core_user_update_user_preferences',\n args: {\n userid: this.userId,\n emailstop: ischecked ? 1 : 0,\n }\n };\n\n return Ajax.call([request])[0]\n .done(function() {\n if (ischecked) {\n this.setDisabled();\n } else {\n this.setEnabled();\n }\n }.bind(this))\n .always(function() {\n container.removeClass('loading');\n })\n .fail(Notification.exception);\n };\n\n /**\n * Set up all of the event listeners for the PreferencesController.\n *\n * @method registerEventListeners\n */\n PreferencesController.prototype.registerEventListeners = function() {\n var disabledNotificationsElement = $(SELECTORS.DISABLE_NOTIFICATIONS);\n\n CustomEvents.define(this.root, [\n CustomEvents.events.activate,\n ]);\n\n this.root.on('change', function(e) {\n if (!this.isDisabled()) {\n var preferenceElement = $(e.target).closest(SELECTORS.PREFERENCE);\n var preferenceRow = $(e.target).closest(SELECTORS.PREFERENCE_ROW);\n var preference = new NotificationPreference(preferenceRow, this.userId);\n\n preferenceElement.addClass('loading');\n preference.save().always(function() {\n preferenceElement.removeClass('loading');\n });\n }\n }.bind(this));\n\n var eventFormPromise = ModalFactory.create({\n type: NotificationProcessorSettings.TYPE,\n });\n\n this.root.on(CustomEvents.events.activate, SELECTORS.PROCESSOR_SETTING, function(e, data) {\n var element = $(e.target).closest(SELECTORS.PROCESSOR_SETTING);\n\n data.originalEvent.preventDefault();\n\n eventFormPromise.then(function(modal) {\n // Configure modal with element settings.\n modal.setUserId($(element).attr('data-user-id'));\n modal.setName($(element).attr('data-name'));\n modal.setContextId($(element).attr('data-context-id'));\n modal.setElement(element);\n modal.show();\n\n e.stopImmediatePropagation();\n return;\n }).fail(Notification.exception);\n });\n\n CustomEvents.define(disabledNotificationsElement, [\n CustomEvents.events.activate\n ]);\n\n disabledNotificationsElement.on(CustomEvents.events.activate, function() {\n this.toggleDisableAllStatus();\n }.bind(this));\n };\n\n return PreferencesController;\n});\n"],"file":"preferences_notifications_list_controller.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/preferences_notifications_list_controller.js"],"names":["define","$","Ajax","Notification","CustomEvents","NotificationPreference","NotificationProcessorSettings","ModalFactory","SELECTORS","DISABLE_NOTIFICATIONS","DISABLE_NOTIFICATIONS_CONTAINER","PREFERENCE","PREFERENCE_ROW","PREFERENCE_INPUT","PROCESSOR_SETTING","PreferencesController","element","root","userId","attr","registerEventListeners","prototype","isDisabled","hasClass","setDisabled","addClass","find","prop","setEnabled","removeClass","toggleDisableAllStatus","checkbox","container","ischecked","Deferred","resolve","request","methodname","args","userid","emailstop","call","done","bind","always","fail","exception","disabledNotificationsElement","events","activate","on","e","preferenceElement","target","closest","preferenceRow","preference","save","eventFormPromise","create","type","TYPE","data","originalEvent","preventDefault","then","modal","setUserId","setName","setContextId","setElement","show","stopImmediatePropagation"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the preferences for the list of notification types on the\n * message preference page\n *\n * @module core_message/preferences_notifications_list_controller\n * @copyright 2016 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery',\n 'core/ajax',\n 'core/notification',\n 'core/custom_interaction_events',\n 'core_message/notification_preference',\n 'core_message/notification_processor_settings',\n 'core/modal_factory',\n ],\n function(\n $,\n Ajax,\n Notification,\n CustomEvents,\n NotificationPreference,\n NotificationProcessorSettings,\n ModalFactory\n ) {\n\n var SELECTORS = {\n DISABLE_NOTIFICATIONS: '[data-region=\"disable-notification-container\"] [data-disable-notifications]',\n DISABLE_NOTIFICATIONS_CONTAINER: '[data-region=\"disable-notification-container\"]',\n PREFERENCE: '.preference-state',\n PREFERENCE_ROW: '[data-region=\"preference-row\"]',\n PREFERENCE_INPUT: '.preference-state input',\n PROCESSOR_SETTING: '[data-processor-setting]',\n };\n\n /**\n * Constructor for the PreferencesController.\n *\n * @class\n * @param {object} element jQuery object root element of the preference\n */\n var PreferencesController = function(element) {\n this.root = $(element);\n this.userId = this.root.attr('data-user-id');\n\n this.registerEventListeners();\n };\n\n /**\n * Check if the preferences are all disabled.\n *\n * @method isDisabled\n * @return {bool}\n */\n PreferencesController.prototype.isDisabled = function() {\n return this.root.hasClass('disabled');\n };\n\n /**\n * Disable all of the preferences.\n *\n * @method setDisabled\n */\n PreferencesController.prototype.setDisabled = function() {\n this.root.addClass('disabled');\n this.root.find(SELECTORS.PREFERENCE_INPUT).prop('disabled', true);\n };\n\n /**\n * Enable all of the preferences.\n *\n * @method setEnabled\n */\n PreferencesController.prototype.setEnabled = function() {\n this.root.removeClass('disabled');\n this.root.find(SELECTORS.PREFERENCE_INPUT).prop('disabled', false);\n };\n\n /**\n * Update the disable all notifications user property in the DOM and\n * send a request to update on the server.\n *\n * @method toggleDisableAllStatus\n * @return {Promise}\n */\n PreferencesController.prototype.toggleDisableAllStatus = function() {\n var checkbox = $(SELECTORS.DISABLE_NOTIFICATIONS);\n var container = $(SELECTORS.DISABLE_NOTIFICATIONS_CONTAINER);\n var ischecked = checkbox.prop('checked');\n\n if (container.hasClass('loading')) {\n return $.Deferred().resolve();\n }\n\n container.addClass('loading');\n\n var request = {\n methodname: 'core_user_update_user_preferences',\n args: {\n userid: this.userId,\n emailstop: ischecked ? 1 : 0,\n }\n };\n\n return Ajax.call([request])[0]\n .done(function() {\n if (ischecked) {\n this.setDisabled();\n } else {\n this.setEnabled();\n }\n }.bind(this))\n .always(function() {\n container.removeClass('loading');\n })\n .fail(Notification.exception);\n };\n\n /**\n * Set up all of the event listeners for the PreferencesController.\n *\n * @method registerEventListeners\n */\n PreferencesController.prototype.registerEventListeners = function() {\n var disabledNotificationsElement = $(SELECTORS.DISABLE_NOTIFICATIONS);\n\n CustomEvents.define(this.root, [\n CustomEvents.events.activate,\n ]);\n\n this.root.on('change', function(e) {\n if (!this.isDisabled()) {\n var preferenceElement = $(e.target).closest(SELECTORS.PREFERENCE);\n var preferenceRow = $(e.target).closest(SELECTORS.PREFERENCE_ROW);\n var preference = new NotificationPreference(preferenceRow, this.userId);\n\n preferenceElement.addClass('loading');\n preference.save().always(function() {\n preferenceElement.removeClass('loading');\n });\n }\n }.bind(this));\n\n var eventFormPromise = ModalFactory.create({\n type: NotificationProcessorSettings.TYPE,\n });\n\n this.root.on(CustomEvents.events.activate, SELECTORS.PROCESSOR_SETTING, function(e, data) {\n var element = $(e.target).closest(SELECTORS.PROCESSOR_SETTING);\n\n data.originalEvent.preventDefault();\n\n eventFormPromise.then(function(modal) {\n // Configure modal with element settings.\n modal.setUserId($(element).attr('data-user-id'));\n modal.setName($(element).attr('data-name'));\n modal.setContextId($(element).attr('data-context-id'));\n modal.setElement(element);\n modal.show();\n\n e.stopImmediatePropagation();\n return;\n }).fail(Notification.exception);\n });\n\n CustomEvents.define(disabledNotificationsElement, [\n CustomEvents.events.activate\n ]);\n\n disabledNotificationsElement.on(CustomEvents.events.activate, function() {\n this.toggleDisableAllStatus();\n }.bind(this));\n };\n\n return PreferencesController;\n});\n"],"file":"preferences_notifications_list_controller.min.js"} \ No newline at end of file diff --git a/message/amd/src/default_notification_preferences.js b/message/amd/src/default_notification_preferences.js new file mode 100644 index 00000000000..07a36a02898 --- /dev/null +++ b/message/amd/src/default_notification_preferences.js @@ -0,0 +1,101 @@ +// 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 . + +/** + * Controls the default settings for the list of notification types on the + * notifications admin page + * + * @module core_message/default_notification_preferences + * @class default_notification_preferences + * @copyright 2021 Moodle + * @author Pau Ferrer OcaƱa + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +const selectors = { + provider: '.defaultmessageoutputs .provider_enabled', + lockSetting: '.locked_message_setting', + enabledSetting: '.enabled_message_setting', + allSettings: '.locked_message_setting, .enabled_message_setting' +}; + +/** + * Register event listeners for the default_notification_preferences page. + */ +const registerEventListeners = () => { + + /** + * Update the dimmed status of the "enabled" toggle on the notification setting. + * + * @param {HTMLElement} lockedElement Element that receives the event. + */ + const toggleLockSetting = (lockedElement) => { + const isEnabled = lockedElement.checked || false; + const enabledId = lockedElement.id.replace('_locked[', '_enabled['); + + const enabledElement = document.getElementById(enabledId).closest('div.custom-control'); + enabledElement.classList.toggle('dimmed_text', isEnabled); + }; + + /** + * Enable/Disable all settings of the provider. + * + * @param {HTMLElement} providerEnabledElement Element that receives the event. + */ + const toggleEnableProviderSettings = (providerEnabledElement) => { + const isEnabled = providerEnabledElement.checked || false; + const parentRow = providerEnabledElement.closest('tr'); + + const elements = parentRow.querySelectorAll(selectors.allSettings); + elements.forEach((element) => { + element.toggleAttribute('disabled', !isEnabled); + }); + }; + + const container = document.querySelector('.preferences-container'); + + container.querySelectorAll(selectors.provider).forEach((providerEnabledElement) => { + // Set the initial statuses. + if (!providerEnabledElement.checked) { + toggleEnableProviderSettings(providerEnabledElement); + } + + providerEnabledElement.addEventListener('change', (e) => { + toggleEnableProviderSettings(e.target); + }); + }); + + container.querySelectorAll(selectors.lockSetting).forEach((lockedElement) => { + // Set the initial statuses. + if (lockedElement.checked) { + toggleLockSetting(lockedElement); + } + + lockedElement.addEventListener('change', (e) => { + toggleLockSetting(e.target); + }); + }); +}; + +/** + * Initialize the page. + */ +const init = () => { + registerEventListeners(); +}; + +export default { + init: init, +}; diff --git a/message/amd/src/message_drawer_view_settings.js b/message/amd/src/message_drawer_view_settings.js index 5c929d7c6a8..fd068a737ec 100644 --- a/message/amd/src/message_drawer_view_settings.js +++ b/message/amd/src/message_drawer_view_settings.js @@ -144,11 +144,7 @@ function( var newValue = values.length ? values.join(',') : 'none'; var preferences = [ { - type: 'message_provider_moodle_instantmessage_loggedoff', - value: newValue - }, - { - type: 'message_provider_moodle_instantmessage_loggedin', + type: 'message_provider_moodle_instantmessage_enabled', value: newValue } ]; @@ -219,7 +215,7 @@ function( // Consider the the processor enabled if either preference is set. This is // for backwards compatibility. Going forward they will be treated as one // setting. - var checked = processor.loggedin.checked || processor.loggedoff.checked; + var checked = processor.enabled; return { displayname: processor.displayname, name: processor.name, diff --git a/message/amd/src/notification_preference.js b/message/amd/src/notification_preference.js index ae52eecf8b2..44ff20063a0 100644 --- a/message/amd/src/notification_preference.js +++ b/message/amd/src/notification_preference.js @@ -24,7 +24,7 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_processor'], function($, Ajax, Notification, NotificationProcessor) { - var SELECTORS = { + const SELECTORS = { PROCESSOR: '[data-processor-name]', STATE_INPUTS: '[data-state] input', }; @@ -36,7 +36,7 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p * @param {object} element jQuery object root element of the preference * @param {int} userId The current user id */ - var NotificationPreference = function(element, userId) { + const NotificationPreference = function(element, userId) { this.root = $(element); this.userId = userId; }; @@ -52,23 +52,13 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p }; /** - * Get the unique key for the logged in preference. + * Get the unique key for the enabled preference. * - * @method getLoggedInPreferenceKey + * @method getEnabledPreferenceKey * @return {string} */ - NotificationPreference.prototype.getLoggedInPreferenceKey = function() { - return this.getPreferenceKey() + '_loggedin'; - }; - - /** - * Get the unique key for the logged off preference. - * - * @method getLoggedOffPreferenceKey - * @return {string} - */ - NotificationPreference.prototype.getLoggedOffPreferenceKey = function() { - return this.getPreferenceKey() + '_loggedoff'; + NotificationPreference.prototype.getEnabledPreferenceKey = function() { + return this.getPreferenceKey() + '_enabled'; }; /** @@ -126,50 +116,33 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p this.startLoading(); - var loggedInValue = ''; - var loggedOffValue = ''; + let enabledValue = ''; this.getProcessors().each(function(index, processor) { - if (processor.isLoggedInEnabled()) { - if (loggedInValue === '') { - loggedInValue = processor.getName(); + if (processor.isEnabled()) { + if (enabledValue === '') { + enabledValue = processor.getName(); } else { - loggedInValue += ',' + processor.getName(); - } - } - - if (processor.isLoggedOffEnabled()) { - if (loggedOffValue === '') { - loggedOffValue = processor.getName(); - } else { - loggedOffValue += ',' + processor.getName(); + enabledValue += ',' + processor.getName(); } } }); - if (loggedInValue === '') { - loggedInValue = 'none'; + if (enabledValue === '') { + enabledValue = 'none'; } - if (loggedOffValue === '') { - loggedOffValue = 'none'; - } - - var args = { + const args = { userid: this.userId, preferences: [ { - type: this.getLoggedInPreferenceKey(), - value: loggedInValue, - }, - { - type: this.getLoggedOffPreferenceKey(), - value: loggedOffValue, - }, + type: this.getEnabledPreferenceKey(), + value: enabledValue, + } ], }; - var request = { + const request = { methodname: 'core_user_update_user_preferences', args: args, }; diff --git a/message/amd/src/notification_processor.js b/message/amd/src/notification_processor.js index 338dd24d443..c1870b28f8f 100644 --- a/message/amd/src/notification_processor.js +++ b/message/amd/src/notification_processor.js @@ -21,11 +21,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define(['jquery'], function($) { - var SELECTORS = { - STATE_NONE: '[data-state="none"]', - STATE_BOTH: '[data-state="both"]', - STATE_LOGGED_IN: '[data-state="loggedin"]', - STATE_LOGGED_OFF: '[data-state="loggedoff"]', + const SELECTORS = { + STATE_INPUTS: '.preference-state input.notification_enabled' }; /** @@ -34,7 +31,7 @@ define(['jquery'], function($) { * @class * @param {object} element jQuery object root element of the processor */ - var NotificationProcessor = function(element) { + const NotificationProcessor = function(element) { this.root = $(element); }; @@ -54,36 +51,10 @@ define(['jquery'], function($) { * @method isLoggedInEnabled * @return {bool} */ - NotificationProcessor.prototype.isLoggedInEnabled = function() { - var none = this.root.find(SELECTORS.STATE_NONE).find('input'); + NotificationProcessor.prototype.isEnabled = function() { + const enabled = this.root.find(SELECTORS.STATE_INPUTS); - if (none.prop('checked')) { - return false; - } - - var both = this.root.find(SELECTORS.STATE_BOTH).find('input'); - var loggedIn = this.root.find(SELECTORS.STATE_LOGGED_IN).find('input'); - - return loggedIn.prop('checked') || both.prop('checked'); - }; - - /** - * Check if the processor is enabled when the user is logged out. - * - * @method isLoggedOffEnabled - * @return {bool} - */ - NotificationProcessor.prototype.isLoggedOffEnabled = function() { - var none = this.root.find(SELECTORS.STATE_NONE).find('input'); - - if (none.prop('checked')) { - return false; - } - - var both = this.root.find(SELECTORS.STATE_BOTH).find('input'); - var loggedOff = this.root.find(SELECTORS.STATE_LOGGED_OFF).find('input'); - - return loggedOff.prop('checked') || both.prop('checked'); + return enabled.prop('checked'); }; return NotificationProcessor; diff --git a/message/amd/src/preferences_notifications_list_controller.js b/message/amd/src/preferences_notifications_list_controller.js index 5df98bb6cd7..b09e2d76e37 100644 --- a/message/amd/src/preferences_notifications_list_controller.js +++ b/message/amd/src/preferences_notifications_list_controller.js @@ -42,9 +42,9 @@ define(['jquery', var SELECTORS = { DISABLE_NOTIFICATIONS: '[data-region="disable-notification-container"] [data-disable-notifications]', DISABLE_NOTIFICATIONS_CONTAINER: '[data-region="disable-notification-container"]', - PREFERENCE: '[data-state]', + PREFERENCE: '.preference-state', PREFERENCE_ROW: '[data-region="preference-row"]', - PREFERENCE_INPUT: '[data-state] input', + PREFERENCE_INPUT: '.preference-state input', PROCESSOR_SETTING: '[data-processor-setting]', }; diff --git a/message/classes/helper.php b/message/classes/helper.php index 58592debd9b..04324eb4d08 100644 --- a/message/classes/helper.php +++ b/message/classes/helper.php @@ -270,18 +270,17 @@ class helper { // Get providers preferences. foreach ($providers as $provider) { - foreach (array('loggedin', 'loggedoff') as $state) { - $linepref = get_user_preferences('message_provider_' . $provider->component . '_' . $provider->name - . '_' . $state, '', $userid); - if ($linepref == '') { - continue; - } - $lineprefarray = explode(',', $linepref); - $preferences->{$provider->component.'_'.$provider->name.'_'.$state} = array(); - foreach ($lineprefarray as $pref) { - $preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$pref] = 1; - } + $linepref = get_user_preferences('message_provider_' . $provider->component . '_' . $provider->name + . '_enabled', '', $userid); + if ($linepref == '') { + continue; } + $lineprefarray = explode(',', $linepref); + $preferences->{$provider->component.'_'.$provider->name.'_enabled'} = []; + foreach ($lineprefarray as $pref) { + $preferences->{$provider->component.'_'.$provider->name.'_enabled'}[$pref] = 1; + } + } return $preferences; diff --git a/message/classes/output/preferences/notification_list.php b/message/classes/output/preferences/notification_list.php index d112b4a66f0..bfba030bb19 100644 --- a/message/classes/output/preferences/notification_list.php +++ b/message/classes/output/preferences/notification_list.php @@ -162,15 +162,6 @@ class notification_list implements templatable, renderable { $context['components'][] = $notificationcomponent->export_for_template($output); } - // This is fairly nasty but we don't currently have a way to add help icons - // in templates, so we'll need to provide it in the context. - // - // We only want the first component to render with the help icon. - if (!empty($context['components'])) { - $context['components'][0]['onlinehelphtml'] = $output->help_icon('loggedin', 'message'); - $context['components'][0]['offlinehelphtml'] = $output->help_icon('loggedoff', 'message'); - } - return $context; } } diff --git a/message/classes/output/preferences/notification_list_component.php b/message/classes/output/preferences/notification_list_component.php index 8a77d9436cf..84f12593881 100644 --- a/message/classes/output/preferences/notification_list_component.php +++ b/message/classes/output/preferences/notification_list_component.php @@ -127,6 +127,7 @@ class notification_list_component implements templatable, renderable { $context = [ 'displayname' => $componentname, + 'colspan' => count($processors) + 1, 'notifications' => [], ]; diff --git a/message/classes/output/preferences/notification_list_processor.php b/message/classes/output/preferences/notification_list_processor.php index b24f712c4fc..0464fb05ba9 100644 --- a/message/classes/output/preferences/notification_list_processor.php +++ b/message/classes/output/preferences/notification_list_processor.php @@ -81,16 +81,17 @@ class notification_list_processor implements templatable, renderable { * Check if the given preference is enabled or not. * * @param string $name preference name + * @param string $locked Wether the preference is locked by admin. * @return bool */ - private function is_preference_enabled($name) { + private function is_preference_enabled($name, $locked) { $processor = $this->processor; $preferences = $this->preferences; $defaultpreferences = get_message_output_default_preferences(); $checked = false; // See if user has touched this preference. - if (isset($preferences->{$name})) { + if (!$locked && isset($preferences->{$name})) { // User has some preferences for this state in the database. $checked = isset($preferences->{$name}[$processor->name]); } else { @@ -104,40 +105,64 @@ class notification_list_processor implements templatable, renderable { return $checked; } + /** + * Export this data so it can be used as the context for a mustache template. + * @todo Remove loggedin and loggedoff from context on MDL-73284. + * + * @param renderer_base $output + * @return stdClass + */ public function export_for_template(\renderer_base $output) { $processor = $this->processor; $preferencebase = $this->get_preference_base(); - $permitted = MESSAGE_DEFAULT_PERMITTED; $defaultpreferences = get_message_output_default_preferences(); - $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; + $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_locked'; + $providername = get_string('messageprovider:'.$this->provider->name, $this->provider->component); + $processorname = get_string('pluginname', 'message_'.$processor->name); + $labelparams = [ + 'provider' => $providername, + 'processor' => $processorname, + ]; + $context = [ - 'displayname' => get_string('pluginname', 'message_'.$processor->name), + 'displayname' => $processorname, 'name' => $processor->name, 'locked' => false, 'userconfigured' => $processor->object->is_user_configured(), + // Backward compatibility, deprecated attribute. 'loggedin' => [ 'name' => 'loggedin', - 'displayname' => get_string('loggedindescription', 'message'), - 'checked' => $this->is_preference_enabled($preferencebase.'_loggedin'), + 'displayname' => 'loggedin', + 'checked' => false, ], + // Backward compatibility, deprecated attribute. 'loggedoff' => [ 'name' => 'loggedoff', - 'displayname' => get_string('loggedoffdescription', 'message'), - 'checked' => $this->is_preference_enabled($preferencebase.'_loggedoff'), + 'displayname' => 'loggedoff', + 'checked' => false, ], + 'enabled' => false, + 'enabledlabel' => get_string('sendingviaenabled', 'message', $labelparams), ]; // Determine the default setting. if (isset($defaultpreferences->{$defaultpreference})) { - $permitted = $defaultpreferences->{$defaultpreference}; + $context['locked'] = $defaultpreferences->{$defaultpreference}; } + + $context['enabled'] = $this->is_preference_enabled($preferencebase.'_enabled', $context['locked']); + $context['loggedoff']['checked'] = $context['enabled']; // Backward compatibility, deprecated attribute. + $context['loggedin']['checked'] = $context['enabled']; // Backward compatibility, deprecated attribute. + // If settings are disallowed or forced, just display the corresponding message, if not use user settings. - if ($permitted == 'disallowed') { - $context['locked'] = true; - $context['lockedmessage'] = get_string('disallowed', 'message'); - } else if ($permitted == 'forced') { - $context['locked'] = true; - $context['lockedmessage'] = get_string('forced', 'message'); + if ($context['locked']) { + if ($context['enabled']) { + $context['lockedmessage'] = get_string('forced', 'message'); + $context['lockedlabel'] = get_string('providerprocesorislocked', 'message', $labelparams); + } else { + $context['lockedmessage'] = get_string('disallowed', 'message'); + $context['lockedlabel'] = get_string('providerprocesorisdisallowed', 'message', $labelparams); + } } return $context; diff --git a/message/externallib.php b/message/externallib.php index cbd533fd8ac..6b8d18a3ec4 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -3020,6 +3020,7 @@ class core_message_external extends external_api { * * @return external_single_structure the structure * @since Moodle 3.2 + * @todo Remove loggedin and loggedoff from processors structure on MDL-73284. */ protected static function get_preferences_structure() { return new external_single_structure( @@ -3061,15 +3062,20 @@ class core_message_external extends external_api { 'name' => new external_value(PARAM_NOTAGS, 'Name'), 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 'checked' => new external_value(PARAM_BOOL, 'Is checked?'), - ) + ), + 'DEPRECATED ATTRIBUTE - + Kept for backward compatibility, use enabled instead.', ), 'loggedoff' => new external_single_structure( array( 'name' => new external_value(PARAM_NOTAGS, 'Name'), 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 'checked' => new external_value(PARAM_BOOL, 'Is checked?'), - ) + ), + 'DEPRECATED ATTRIBUTE - + Kept for backward compatibility, use enabled instead.', ), + 'enabled' => new external_value(PARAM_BOOL, 'Is enabled?'), ) ), 'Processors values for this notification' diff --git a/message/lib.php b/message/lib.php index 634a1806511..db2b27dca4f 100644 --- a/message/lib.php +++ b/message/lib.php @@ -34,24 +34,37 @@ define('MESSAGE_TYPE_MESSAGE', 'message'); /** * Define contants for messaging default settings population. For unambiguity of * plugin developer intentions we use 4-bit value (LSB numbering): - * bit 0 - whether to send message when user is loggedin (MESSAGE_DEFAULT_LOGGEDIN) - * bit 1 - whether to send message when user is loggedoff (MESSAGE_DEFAULT_LOGGEDOFF) + * bit 0 - whether to send message (MESSAGE_DEFAULT_ENABLED) + * bit 1 - Deprecated: whether to send message (MESSAGE_DEFAULT_LOGGEDOFF). Used to mean only when the user is logged off. * bit 2..3 - messaging permission (MESSAGE_DISALLOWED|MESSAGE_PERMITTED|MESSAGE_FORCED) * - * MESSAGE_PERMITTED_MASK contains the mask we use to distinguish permission setting + * MESSAGE_PERMITTED_MASK contains the mask we use to distinguish permission setting. */ + /** + * @deprecated since Moodle 4.0. Use MESSAGE_DEFAULT_ENABLED instead. + * @todo Remove on MDL-73284. + */ define('MESSAGE_DEFAULT_LOGGEDIN', 0x01); // 0001 + + /** + * @deprecated since Moodle 4.0 MDL-73284. Use MESSAGE_DEFAULT_ENABLED instead. + * @todo Remove on MDL-73284. + */ define('MESSAGE_DEFAULT_LOGGEDOFF', 0x02); // 0010 -define('MESSAGE_DISALLOWED', 0x04); // 0100 -define('MESSAGE_PERMITTED', 0x08); // 1000 -define('MESSAGE_FORCED', 0x0c); // 1100 +define('MESSAGE_DEFAULT_ENABLED', 0x01); // 0001. -define('MESSAGE_PERMITTED_MASK', 0x0c); // 1100 +define('MESSAGE_DISALLOWED', 0x04); // 0100. +define('MESSAGE_PERMITTED', 0x08); // 1000. +define('MESSAGE_FORCED', 0x0c); // 1100. + +define('MESSAGE_PERMITTED_MASK', 0x0c); // 1100. /** * Set default value for default outputs permitted setting + * @deprecated since Moodle 4.0 MDL-73284. + * @todo Remove on MDL-73284. */ define('MESSAGE_DEFAULT_PERMITTED', 'permitted'); @@ -493,26 +506,15 @@ function get_message_output_default_preferences() { * Translate message default settings from binary value to the array of string * representing the settings to be stored. Also validate the provided value and * use default if it is malformed. + * @todo Remove usage of MESSAGE_DEFAULT_LOGGEDOFF on MDL-73284. * * @param int $plugindefault Default setting suggested by plugin * @param string $processorname The name of processor - * @return array $settings array of strings in the order: $permitted, $loggedin, $loggedoff. + * @return array $settings array of strings in the order: $locked, $enabled. */ function translate_message_default_setting($plugindefault, $processorname) { - // Preset translation arrays - $permittedvalues = array( - MESSAGE_DISALLOWED => 'disallowed', - MESSAGE_PERMITTED => 'permitted', - MESSAGE_FORCED => 'forced', - ); - $loggedinstatusvalues = array( - 0x00 => null, // use null if loggedin/loggedoff is not defined - MESSAGE_DEFAULT_LOGGEDIN => 'loggedin', - MESSAGE_DEFAULT_LOGGEDOFF => 'loggedoff', - ); - - // define the default setting + // Define the default setting. $processor = get_message_processor($processorname); $default = $processor->get_default_messaging_settings(); @@ -526,15 +528,31 @@ function translate_message_default_setting($plugindefault, $processorname) { $plugindefault = $default; } - $permitted = $permittedvalues[$plugindefault & MESSAGE_PERMITTED_MASK]; - $loggedin = $loggedoff = null; + $locked = false; + $enabled = false; - if (($plugindefault & MESSAGE_PERMITTED_MASK) == MESSAGE_PERMITTED) { - $loggedin = $loggedinstatusvalues[$plugindefault & MESSAGE_DEFAULT_LOGGEDIN]; - $loggedoff = $loggedinstatusvalues[$plugindefault & MESSAGE_DEFAULT_LOGGEDOFF]; + $permitted = $plugindefault & MESSAGE_PERMITTED_MASK; + switch ($permitted) { + case MESSAGE_FORCED: + $locked = true; + $enabled = true; + break; + case MESSAGE_DISALLOWED: + $locked = true; + $enabled = false; + break; + default: + $locked = false; + // It's equivalent to logged in. + $enabled = $plugindefault & MESSAGE_DEFAULT_ENABLED == MESSAGE_DEFAULT_ENABLED; + + // MESSAGE_DEFAULT_LOGGEDOFF is deprecated but we're checking it just in case. + $loggedoff = $plugindefault & MESSAGE_DEFAULT_LOGGEDOFF == MESSAGE_DEFAULT_LOGGEDOFF; + $enabled = $enabled || $loggedoff; + break; } - return array($permitted, $loggedin, $loggedoff); + return array($locked, $enabled); } /** @@ -791,13 +809,13 @@ function core_message_user_preferences() { 'null' => NULL_NOT_ALLOWED, 'default' => false ); - $preferences['/^message_provider_([\w\d_]*)_logged(in|off)$/'] = array('isregex' => true, 'type' => PARAM_NOTAGS, + $preferences['/^message_provider_([\w\d_]*)_enabled$/'] = array('isregex' => true, 'type' => PARAM_NOTAGS, 'null' => NULL_NOT_ALLOWED, 'default' => 'none', 'permissioncallback' => function ($user, $preferencename) { global $CFG; require_once($CFG->libdir.'/messagelib.php'); if (core_message_can_edit_message_profile($user) && - preg_match('/^message_provider_([\w\d_]*)_logged(in|off)$/', $preferencename, $matches)) { + preg_match('/^message_provider_([\w\d_]*)_enabled$/', $preferencename, $matches)) { $providers = message_get_providers_for_user($user->id); foreach ($providers as $provider) { if ($matches[1] === $provider->component . '_' . $provider->name) { diff --git a/message/module.js b/message/module.js index 4c5bd67dd6a..13fdecc4574 100644 --- a/message/module.js +++ b/message/module.js @@ -17,77 +17,6 @@ M.core_message.combinedsearchgotfocus = function(e) { } }; -M.core_message.init_defaultoutputs = function(Y) { - var defaultoutputs = { - - init : function() { - Y.all('#defaultmessageoutputs select').each(function(node) { - // attach event listener - node.on('change', defaultoutputs.changeState); - // set initial layout - node.simulate("change"); - }, this); - - Y.all('#defaultmessageoutputs input.messagedisable').each(function(node) { - // Attach event listener - node.on('change', defaultoutputs.changeProviderState); - node.simulate("change"); - }, this); - }, - - changeState : function(e) { - var value = e.target._node.options[e.target.get('selectedIndex')].value; - var parentnode = e.target.ancestor('td'); - switch (value) { - case 'forced': - defaultoutputs.updateCheckboxes(parentnode, 1, 1); - break; - case 'disallowed': - defaultoutputs.updateCheckboxes(parentnode, 1, 0); - break; - case 'permitted': - defaultoutputs.updateCheckboxes(parentnode, 0, 0); - break; - } - }, - - updateCheckboxes : function(blocknode, disabled, checked) { - blocknode.all('input[type=checkbox]').each(function(node) { - node.removeAttribute('disabled'); - if (disabled) { - node.setAttribute('disabled', 1) - node.removeAttribute('checked'); - } - if (checked) { - node.setAttribute('checked', 1) - } - }, this); - }, - - changeProviderState : function(e) { - var isenabled = e.target.get('checked') || undefined; - var parentnode = e.target.ancestor('tr'); - if (!isenabled) { - parentnode.all('select').each(function(node) { - node.set('value', 'disallowed'); - node.setAttribute('disabled', 1); - defaultoutputs.updateCheckboxes(node.ancestor('td'), 1, 0); - }, this); - parentnode.addClass('dimmed_text'); - } else { - parentnode.all('select[disabled]').each(function(node) { - node.removeAttribute('disabled'); - node.set('value', 'permitted'); - defaultoutputs.updateCheckboxes(node.ancestor('td'), 0, 0); - }, this); - parentnode.removeClass('dimmed_text'); - } - } - } - - defaultoutputs.init(); -} - M.core_message.init_editsettings = function(Y) { var editsettings = { diff --git a/message/output/airnotifier/classes/privacy/provider.php b/message/output/airnotifier/classes/privacy/provider.php index a02672c92c8..27d06237276 100644 --- a/message/output/airnotifier/classes/privacy/provider.php +++ b/message/output/airnotifier/classes/privacy/provider.php @@ -68,7 +68,7 @@ class provider implements 'smallmessage' => 'privacy:metadata:smallmessage', 'fullmessage' => 'privacy:metadata:fullmessage' ], 'privacy:metadata:externalpurpose'); - // This system is unaware of user preferences such as message_provider_moodle_instantmessage_loggedin. + // This system is unaware of user preferences such as message_provider_moodle_instantmessage_enabled. return $collection; } diff --git a/message/output/airnotifier/externallib.php b/message/output/airnotifier/externallib.php index ad176b0f6d5..a5275ec2022 100644 --- a/message/output/airnotifier/externallib.php +++ b/message/output/airnotifier/externallib.php @@ -115,8 +115,8 @@ class message_airnotifier_external extends external_api { $users = $DB->get_recordset_sql($usersql, $params); $result = array( - 'users' => array(), - 'warnings' => array() + 'users' => [], + 'warnings' => [] ); $hasuserupdatecap = has_capability('moodle/user:update', context_system::instance()); foreach ($users as $user) { @@ -126,7 +126,7 @@ class message_airnotifier_external extends external_api { if ($currentuser or $hasuserupdatecap) { if (!empty($user->deleted)) { - $warning = array(); + $warning = []; $warning['item'] = 'user'; $warning['itemid'] = $user->id; $warning['warningcode'] = '1'; @@ -135,7 +135,7 @@ class message_airnotifier_external extends external_api { continue; } - $preferences = array(); + $preferences = []; $preferences['userid'] = $user->id; $preferences['configured'] = 0; @@ -149,33 +149,29 @@ class message_airnotifier_external extends external_api { break; } - foreach (array('loggedin', 'loggedoff') as $state) { + $prefstocheck = []; + $prefname = 'message_provider_'.$provider->component.'_'.$provider->name.'_enabled'; - $prefstocheck = array(); - $prefname = 'message_provider_'.$provider->component.'_'.$provider->name.'_'.$state; + // First get forced settings. + if ($forcedpref = get_config('message', $prefname)) { + $prefstocheck = array_merge($prefstocheck, explode(',', $forcedpref)); + } - // First get forced settings. - if ($forcedpref = get_config('message', $prefname)) { - $prefstocheck = array_merge($prefstocheck, explode(',', $forcedpref)); - } - - // Then get user settings. - if ($userpref = get_user_preferences($prefname, '', $user->id)) { - $prefstocheck = array_merge($prefstocheck, explode(',', $userpref)); - } - - if (in_array('airnotifier', $prefstocheck)) { - $preferences['configured'] = 1; - $configured = true; - break; - } + // Then get user settings. + if ($userpref = get_user_preferences($prefname, '', $user->id)) { + $prefstocheck = array_merge($prefstocheck, explode(',', $userpref)); + } + if (in_array('airnotifier', $prefstocheck)) { + $preferences['configured'] = 1; + $configured = true; + break; } } $result['users'][] = $preferences; } else if (!$hasuserupdatecap) { - $warning = array(); + $warning = []; $warning['item'] = 'user'; $warning['itemid'] = $user->id; $warning['warningcode'] = '2'; diff --git a/message/output/airnotifier/tests/externallib_test.php b/message/output/airnotifier/tests/externallib_test.php index ef6fc065f83..218c603b117 100644 --- a/message/output/airnotifier/tests/externallib_test.php +++ b/message/output/airnotifier/tests/externallib_test.php @@ -82,10 +82,8 @@ class externallib_test extends externallib_advanced_testcase { self::setUser($user1); - set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user1); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'airnotifier', $user1); - set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user2); - set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $user3); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'airnotifier', $user1); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'airnotifier', $user2); $params = array($user1->id, $user2->id, $user3->id); @@ -112,23 +110,11 @@ class externallib_test extends externallib_advanced_testcase { $this->assertEquals($expected, $preferences['users']); $this->assertEquals(2, count($preferences['warnings'])); - // Now, remove one user1 preference (the user still has one prefernce for airnotifier). - unset_user_preference('message_provider_moodle_instantmessage_loggedin', $user1); + // Now, remove one user1 preference (the user still has one preference for airnotifier). + unset_user_preference('message_provider_moodle_instantmessage_enabled', $user1); $preferences = message_airnotifier_external::are_notification_preferences_configured($params); $preferences = \external_api::clean_returnvalue($returnsdescription, $preferences); $this->assertEquals($expected, $preferences['users']); - - // Delete the last user1 preference. - unset_user_preference('message_provider_moodle_instantmessage_loggedoff', $user1); - $preferences = message_airnotifier_external::are_notification_preferences_configured($params); - $preferences = \external_api::clean_returnvalue($returnsdescription, $preferences); - $expected = array( - array( - 'userid' => $user1->id, - 'configured' => 1 - ) - ); - $this->assertEquals($expected, $preferences['users']); } /** diff --git a/message/output/email/message_output_email.php b/message/output/email/message_output_email.php index 5dc5bdfb5e9..51020e1a762 100644 --- a/message/output/email/message_output_email.php +++ b/message/output/email/message_output_email.php @@ -204,7 +204,7 @@ class message_output_email extends message_output { * @return int The default settings */ public function get_default_messaging_settings() { - return MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF; + return MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED; } /** diff --git a/message/output/lib.php b/message/output/lib.php index bd29b25cf03..8045052d8bb 100644 --- a/message/output/lib.php +++ b/message/output/lib.php @@ -82,12 +82,11 @@ abstract class message_output { /** * Returns the message processors default settings - * Should the processor be enabled for logged in users by default? - * Should the processor be enabled for logged off users by default? + * Should the processor be enabled in users by default? * Is enabling it disallowed, permitted or forced? * * @return int The Default message output settings expressed as a bit mask - * MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF + MESSAGE_DISALLOWED|MESSAGE_PERMITTED|MESSAGE_FORCED + * MESSAGE_DEFAULT_ENABLED + MESSAGE_PERMITTED */ public function get_default_messaging_settings() { return MESSAGE_PERMITTED; diff --git a/message/output/popup/tests/behat/notification_popover_unread.feature b/message/output/popup/tests/behat/notification_popover_unread.feature index 0fbec12e492..51c37cca75a 100644 --- a/message/output/popup/tests/behat/notification_popover_unread.feature +++ b/message/output/popup/tests/behat/notification_popover_unread.feature @@ -13,9 +13,8 @@ Feature: Notification popover unread notifications | Course 1 | C1 | 0 | 1 | # Make sure the popup notifications are enabled for assignments. And the following config values are set as admin: - | popup_provider_mod_assign_assign_notification_permitted | permitted | message | - | message_provider_mod_assign_assign_notification_loggedin | popup | message | - | message_provider_mod_assign_assign_notification_loggedoff | popup | message | + | popup_provider_mod_assign_assign_notification_locked | 0 | message | + | message_provider_mod_assign_assign_notification_enabled | popup | message | And the following "users" exist: | username | firstname | lastname | email | | teacher1 | Teacher | 1 | teacher1@example.com | diff --git a/message/renderer.php b/message/renderer.php index 272f51b057e..3afe2c82fe3 100644 --- a/message/renderer.php +++ b/message/renderer.php @@ -54,7 +54,6 @@ class core_message_renderer extends plugin_renderer_base { $output .= $this->manage_messageoutputs($allprocessors); // Add active message output processors settings. - $output .= $this->heading(get_string('managemessageoutputs', 'message')); $output .= $this->manage_defaultmessageoutputs($processors, $providers, $preferences); $output .= html_writer::start_tag('div', array('class' => 'form-buttons')); @@ -84,7 +83,7 @@ class core_message_renderer extends plugin_renderer_base { get_string('settings'), ); $table->colclasses = array( - 'displayname', 'availability', 'settings', + 'displayname', 'availability text-center', 'settings', ); foreach ($processors as $processor) { @@ -124,97 +123,99 @@ class core_message_renderer extends plugin_renderer_base { * @return string The text to render */ public function manage_defaultmessageoutputs($processors, $providers, $preferences) { - // Prepare list of options for dropdown menu - $options = array(); - foreach (array('disallowed', 'permitted', 'forced') as $setting) { - $options[$setting] = get_string($setting, 'message'); - } + $context = []; - // Display users outputs table - $table = new html_table(); - $table->attributes['class'] = 'generaltable'; - $table->data = array(); - $table->head = array(''); - - // Populate the header row foreach ($processors as $processor) { - $table->head[] = get_string('pluginname', 'message_'.$processor->name); + $processor->displayname = get_string('pluginname', 'message_'.$processor->name); } - // Add enable/disable to head - $table->head[] = get_string('enabled', 'core_message'); - // Generate the matrix of settings for each provider and processor + $activitycomponents = []; + $othercomponents = []; + foreach ($providers as $provider) { - $row = new html_table_row(); - $row->attributes['class'] = 'defaultmessageoutputs'; - $row->cells = array(); - - // Provider Name - $providername = get_string('messageprovider:'.$provider->name, $provider->component); - $row->cells[] = new html_table_cell($providername); + $provider->displayname = get_string('messageprovider:'.$provider->name, $provider->component); $providersettingprefix = $provider->component.'_'.$provider->name.'_'; - $disableprovidersetting = $providersettingprefix.'disable'; - $providerdisabled = !empty($preferences->$disableprovidersetting); + $provider->enabledsetting = $providersettingprefix.'disable'; + $provider->enabled = empty($preferences->{$provider->enabledsetting}); + $provider->enabledlabel = get_string('providerenabled', 'message', $provider->displayname); + $provider->settings = []; + // Settings for each processor foreach ($processors as $processor) { - $cellcontent = ''; - foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) { - // pepare element and preference names - $elementname = $providersettingprefix.$setting.'['.$processor->name.']'; - $preferencebase = $providersettingprefix.$setting; - // prepare language bits - $processorname = get_string('pluginname', 'message_'.$processor->name); - $statename = get_string($setting, 'message'); - $labelparams = array( - 'provider' => $providername, - 'processor' => $processorname, - 'state' => $statename - ); - if ($setting == 'permitted') { - $label = get_string('sendingvia', 'message', $labelparams); - // determine the current setting or use default - $select = MESSAGE_DEFAULT_PERMITTED; - $preference = $processor->name.'_provider_'.$preferencebase; - if ($providerdisabled) { - $select = MESSAGE_DISALLOWED; - } else if (property_exists($preferences, $preference)) { - $select = $preferences->{$preference}; - } - // dropdown menu - $cellcontent = html_writer::label($label, $elementname, true, array('class' => 'accesshide')); - $cellcontent .= html_writer::select($options, $elementname, $select, false, array('id' => $elementname)); - $cellcontent .= html_writer::tag('div', get_string('defaults', 'message')); - } else { - $label = get_string('sendingviawhen', 'message', $labelparams); - // determine the current setting based on the 'permitted' setting above - $checked = false; - if ($select == 'forced') { - $checked = true; - } else if ($select == 'permitted') { - $preference = 'message_provider_'.$preferencebase; - if (property_exists($preferences, $preference)) { - $checked = (int)in_array($processor->name, explode(',', $preferences->{$preference})); - } - } - // generate content - $cellcontent .= html_writer::start_tag('div'); - $cellcontent .= html_writer::label($label, $elementname, true, array('class' => 'accesshide')); - $cellcontent .= html_writer::checkbox($elementname, 1, $checked, '', array('id' => $elementname)); - $cellcontent .= $statename; - $cellcontent .= html_writer::end_tag('div'); - } + $setting = new StdClass(); + + $setting->lockedsetting = $providersettingprefix.'locked['.$processor->name.']'; + $preference = $processor->name.'_provider_'.$providersettingprefix.'locked'; + + $setting->locked = false; + if (property_exists($preferences, $preference)) { + $setting->locked = $preferences->{$preference} == 1; + } + + $setting->enabledsetting = $providersettingprefix.'enabled['.$processor->name.']'; + $preference = 'message_provider_'.$providersettingprefix.'enabled'; + + $setting->enabled = false; + if (property_exists($preferences, $preference)) { + $setting->enabled = (int)in_array($processor->name, explode(',', $preferences->{$preference})); + } + $labelparams = [ + 'provider' => $provider->displayname, + 'processor' => $processor->displayname, + ]; + $setting->enabledlabel = get_string('sendingviaenabled', 'message', $labelparams); + $setting->lockedlabel = get_string('sendingvialocked', 'message', $labelparams); + + $provider->settings[] = $setting; + } + + // Order the components so that the activities appear first, followed + // by the system and then anything else. + if ($provider->component != 'moodle') { + if (substr($provider->component, 0, 4) == 'mod_') { + // Activities. + $activitycomponents[] = $provider->component; + } else { + // Other stuff. + $othercomponents[] = $provider->component; } - $row->cells[] = new html_table_cell($cellcontent); } - $disableprovider = html_writer::checkbox($disableprovidersetting, 1, !$providerdisabled, '', - array('id' => $disableprovidersetting, 'class' => 'messagedisable')); - $disableprovider = html_writer::tag('div', $disableprovider); - $row->cells[] = new html_table_cell($disableprovider); - $table->data[] = $row; } - $output = html_writer::table($table); - return $output; + $activitycomponents = array_unique($activitycomponents); + asort($activitycomponents); + $othercomponents = array_unique($othercomponents); + asort($othercomponents); + $components = array_merge($activitycomponents, ['moodle'], $othercomponents); + asort($providers); + + $colspan = count($processors) + 2; + $componentsexport = []; + + foreach ($components as $component) { + $componentexport = new StdClass(); + $componentexport->name = $component; + + if ($component != 'moodle') { + $componentexport->displayname = get_string('pluginname', $component); + } else { + $componentexport->displayname = get_string('coresystem'); + } + + $componentexport->providers = []; + foreach ($providers as $provider) { + if ($provider->component == $component) { + $componentexport->providers[] = $provider; + } + } + $componentexport->colspan = $colspan; + $componentsexport[] = $componentexport; + } + + $context['processors'] = array_values($processors); + $context['components'] = $componentsexport; + + return $this->render_from_template('message/default_notification_preferences', $context); } /** diff --git a/message/templates/default_notification_preferences.mustache b/message/templates/default_notification_preferences.mustache new file mode 100644 index 00000000000..17095853ac4 --- /dev/null +++ b/message/templates/default_notification_preferences.mustache @@ -0,0 +1,150 @@ +{{! + 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 . +}} +{{! + @template core_message/default_notification_preferences + + This template will render the default notification preferences for admin settings. + + Classes required for JS: + * none + + Data attributes required for JS: + * All data attributes are required + + Context variables required for this template: + * providers Message providers + * components Provider components + * processors Message processors + * preferences Saved preferences + + Example context (json): + { + "processors": [ + { + "displayname": "Web", + "name": "popup" + } + ], + "components": [ + { + "displayname": "Assignment", + "name": "mod_assign", + "colspan": 3, + "providers": [ + { + "name": "assign_notification", + "component": "mod_assign", + "displayname": "Assignment notifications", + "enabledsetting": "mod_assign_assign_notification_disable", + "enabledlabel": "Sending Assignment enabled status", + "enabled": 1, + "settings": [ + { + "lockedsetting": "mod_assign_assign_notification_locked[popup]", + "locked": 1, + "lockedlabel": "Sending Assignment via Web locked status", + "enabledsetting": "mod_assign_assign_notification_enabled[popup]", + "enabled": 1, + "enabledlabel": "Sending Assignment via Web enabled status" + } + ] + } + ] + } + ] + } +}} +
+

{{#str}} managemessageoutputs, message {{/str}}

+ +
+ + + + + + {{#processors}} + + {{/processors}} + + + + {{#components}} + + {{#providers}} + + + + {{#settings}} + + {{/settings}} + + {{/providers}} + {{/components}} + +
{{#str}} enabled, core_message {{/str}}{{{displayname}}}
{{{displayname}}}
{{{displayname}}} +
+
+ + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+{{#js}} +require(['core_message/default_notification_preferences'], function(NotificationPreferences) { + NotificationPreferences.init(); + }); +{{/js}} diff --git a/message/templates/message_preferences.mustache b/message/templates/message_preferences.mustache index c630a82cdd9..e966969c7e4 100644 --- a/message/templates/message_preferences.mustache +++ b/message/templates/message_preferences.mustache @@ -41,26 +41,13 @@ { "displayname": "Notices about minor problems", "preferencekey": "message_provider_moodle_notices", - "onlinehelphtml": "

some help HTML

", - "offlinehelphtml": "

some help HTML

", "processors": [ { "displayname": "Popup notification", "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0, - "disableall": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0, - "disableall": 0 - } + "enabled": 1 } ] } diff --git a/message/templates/message_preferences_component.mustache b/message/templates/message_preferences_component.mustache index 88b9aafcbff..2878f279fe4 100644 --- a/message/templates/message_preferences_component.mustache +++ b/message/templates/message_preferences_component.mustache @@ -34,26 +34,13 @@ { "displayname": "Notices about minor problems", "preferencekey": "message_provider_moodle_notices", - "onlinehelphtml": "

some help HTML

", - "offlinehelphtml": "

some help HTML

", "processors": [ { "displayname": "Popup notification", "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0, - "disableall": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0, - "disableall": 0 - } + "enabled": 1 } ] } @@ -64,18 +51,7 @@ {{displayname}} -
-
-
- {{#str}} loggedin, message {{/str}} - {{#onlinehelphtml}}{{{.}}}{{/onlinehelphtml}} -
-
- {{#str}} loggedoff, message {{/str}} - {{#offlinehelphtml}}{{{.}}}{{/offlinehelphtml}} -
-
-
+ {{#str}} enabled, core_message {{/str}} {{#processors}} diff --git a/message/templates/message_preferences_notification_processor.mustache b/message/templates/message_preferences_notification_processor.mustache index dec06ee4cd0..ab547340b29 100644 --- a/message/templates/message_preferences_notification_processor.mustache +++ b/message/templates/message_preferences_notification_processor.mustache @@ -40,16 +40,7 @@ "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0 - } + "enabled": 1 } ] } diff --git a/message/templates/notification_preferences.mustache b/message/templates/notification_preferences.mustache index 9bc7cdd715e..b0898912eb4 100644 --- a/message/templates/notification_preferences.mustache +++ b/message/templates/notification_preferences.mustache @@ -34,15 +34,19 @@ { "userid": 1, "disableall": 0, + "processors": [ + { + "displayname": "Popup notification", + "name": "popup", + "hassettings": 1, + "userid": 3, + "contextid": 3 + } + ], "components": [ { "displayname": "System", - "processors": [ - { - "onlinehelphtml": "

help button HTML

", - "offlinehelphtml": "

help button HTML

" - } - ], + "colspan": 2, "notifications": [ { "displayname": "Notices about minor problems", @@ -53,18 +57,8 @@ "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0, - "disableall": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0, - "disableall": 0 - } + "enabled": 1, + "enabledlabel": "Sending Assignment enabled status" } ] } @@ -87,7 +81,7 @@ - + {{#processors}} {{> message/notification_preferences_processor }} {{/processors}} @@ -103,8 +97,8 @@ {{#js}} require(['jquery', 'core_message/preferences_notifications_list_controller'], - function($, controller) { + function($, Controller) { - new controller($('.preferences-container')); + new Controller($('.preferences-container')); }); {{/js}} diff --git a/message/templates/notification_preferences_component.mustache b/message/templates/notification_preferences_component.mustache index 0700fba8858..6c98ac05a40 100644 --- a/message/templates/notification_preferences_component.mustache +++ b/message/templates/notification_preferences_component.mustache @@ -33,12 +33,7 @@ Example context (json): { "displayname": "System", - "processors": [ - { - "onlinehelphtml": "

help button HTML

", - "offlinehelphtml": "

help button HTML

" - } - ], + "colspan": 2, "notifications": [ { "displayname": "Notices about minor problems", @@ -49,18 +44,8 @@ "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0, - "disableall": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0, - "disableall": 0 - } + "enabled": 0, + "enabledlabel": "Sending Assignment enabled status" } ] } @@ -68,23 +53,7 @@ } }} - - {{#processors}} - - {{/processors}} + {{#notifications}} {{> message/notification_preferences_component_notification }} diff --git a/message/templates/notification_preferences_component_notification.mustache b/message/templates/notification_preferences_component_notification.mustache index c120b68b76e..b81380c6283 100644 --- a/message/templates/notification_preferences_component_notification.mustache +++ b/message/templates/notification_preferences_component_notification.mustache @@ -40,70 +40,33 @@ "name": "popup", "locked": 0, "userconfigured": 1, - "loggedin": { - "name": "loggedin", - "displayname": "When I'm logged in", - "checked": 0 - }, - "loggedoff": { - "name": "loggedoff", - "displayname": "When I'm offline", - "checked": 0 - } + "enabled": 1, + "enabledlabel": "Sending Assignment enabled status" } ] } }} - - + + {{#processors}} -
{{displayname}}{{{displayname}}}

{{displayname}}

-
-
-
- {{#str}} loggedin, message {{/str}} - {{#onlinehelphtml}}{{{.}}}{{/onlinehelphtml}} -
-
- {{#str}} loggedoff, message {{/str}} - {{#offlinehelphtml}}{{{.}}}{{/offlinehelphtml}} -
-
-
-
{{{displayname}}}
{{displayname}}
{{{displayname}}} + {{#locked}} -
{{lockedmessage}}
+
{{{lockedmessage}}}
{{/locked}} {{^locked}} -
{{#str}} disabled, admin {{/str}}
-
-
-
- {{#loggedin}} - {{< core/hover_tooltip }} - {{$anchor}} - - {{/anchor}} - {{$tooltip}}{{displayname}}{{/tooltip}} - {{/ core/hover_tooltip }} - {{/loggedin}} -
-
- {{#loggedoff}} - {{< core/hover_tooltip }} - {{$anchor}} - - {{/anchor}} - {{$tooltip}}{{displayname}}{{/tooltip}} - {{/ core/hover_tooltip }} - {{/loggedoff}} -
+
+
+ +
diff --git a/message/tests/api_test.php b/message/tests/api_test.php index dfcdf5c1634..a099a7db38b 100644 --- a/message/tests/api_test.php +++ b/message/tests/api_test.php @@ -2967,15 +2967,15 @@ class core_message_api_test extends core_message_messagelib_testcase { $this->setUser($user); // Set a couple of preferences to test. - set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user); - set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user); + set_user_preference('message_provider_mod_assign_assign_notification_enabled', 'popup', $user); + set_user_preference('message_provider_mod_feedback_submission_enabled', 'email', $user); $processors = get_message_processors(); $providers = message_get_providers_for_user($user->id); $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user); - $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']); - $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']); + $this->assertEquals(1, $prefs->mod_assign_assign_notification_enabled['popup']); + $this->assertEquals(1, $prefs->mod_feedback_submission_enabled['email']); } /** diff --git a/message/tests/behat/message_manage_notification_preferences.feature b/message/tests/behat/message_manage_notification_preferences.feature index f27e116acf1..b66050b81a2 100644 --- a/message/tests/behat/message_manage_notification_preferences.feature +++ b/message/tests/behat/message_manage_notification_preferences.feature @@ -8,6 +8,7 @@ Feature: Manage notification preferences - Email Given the following "users" exist: | username | firstname | lastname | email | | student1 | Student | 1 | student1@example.com | + | student2 | Student | 2 | student2@example.com | And the following config values are set as admin: | messaging | 1 | @@ -27,8 +28,7 @@ Feature: Manage notification preferences - Email # Disable email default value Given the following "user preferences" exist: | user | preference | value | - | student1 | message_provider_moodle_instantmessage_loggedin | none | - | student1 | message_provider_moodle_instantmessage_loggedoff | none | + | student1 | message_provider_moodle_instantmessage_enabled | none | When I log in as "admin" And I navigate to "Messaging > Notification settings" in site administration And I set the field "email" to "1" @@ -61,3 +61,142 @@ Feature: Manage notification preferences - Email And I follow "Preferences" in the user menu And I click on "Message preferences" "link" And the field "Email" matches value "0" + + Scenario: Disable email notifications for Assignment notifications + Given I log in as "admin" + When I navigate to "Messaging > Notification settings" in site administration + And I set the field "email" to "1" + And I press "Save changes" + Then the field "email" matches value "1" + And I set the field "mod_assign_assign_notification_disable" to "0" + And I press "Save changes" + And the field "mod_assign_assign_notification_disable" matches value "0" + And I follow "Preferences" in the user menu + And I click on "Notification preferences" "link" in the "#page-content" "css_element" + And I should not see "Assignment notifications" + + Scenario: Lock email notifications for Forum providers + Given I log in as "admin" + When I navigate to "Messaging > Notification settings" in site administration + And I set the field "email" to "1" + And I press "Save changes" + Then the field "email" matches value "1" + And I set the field "mod_forum_posts_enabled[email]" to "1" + And I set the field "mod_forum_posts_locked[email]" to "1" + And I set the field "mod_forum_digests_enabled[email]" to "0" + And I set the field "mod_forum_digests_locked[email]" to "1" + And I press "Save changes" + And the field "mod_forum_posts_enabled[email]" matches value "1" + And the field "mod_forum_posts_locked[email]" matches value "1" + And the field "mod_forum_digests_enabled[email]" matches value "0" + And the field "mod_forum_digests_locked[email]" matches value "1" + And I follow "Preferences" in the user menu + And I click on "Notification preferences" "link" in the "#page-content" "css_element" + And I should see "Locked" in the "[data-preference-key=message_provider_mod_forum_posts]" "css_element" + And I should see "Disallowed" in the "[data-preference-key=message_provider_mod_forum_digests]" "css_element" + + Scenario: User can disable notification preferences + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + | student2 | C1 | student | + And the following config values are set as admin: + | popup_provider_mod_assign_assign_notification_locked | 0 | message | + | message_provider_mod_assign_assign_notification_enabled | popup | message | + And the following "user preferences" exist: + | user | preference | value | + | student1 | message_provider_mod_assign_assign_notification_enabled | none | + | student2 | message_provider_mod_assign_assign_notification_enabled | popup | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + | assignsubmission_onlinetext_enabled | 1 | + | assignsubmission_file_enabled | 0 | + | submissiondrafts | 0 | + # This should generate a notification. + And the following "mod_assign > submissions" exist: + | assign | user | onlinetext | + | Test assignment name | student1 | I'm the student1 submission | + | Test assignment name | student2 | I'm the student2 submission | + When I log in as "student1" + # Confirm the popover is not showing any unread notifications. + Then I should not see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element" + # Open the popover. + And I open the notification popover + # Confirm the submission notification is NOT visible. + And I should not see "You have submitted your assignment submission for Test assignment name" in the "#nav-notification-popover-container" "css_element" + And I log in as "student2" + # Confirm the popover is showing the unread notifications. + Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element" + # Open the popover. + And I open the notification popover + # Confirm the submission notification is visible. + And I should see "You have submitted your assignment submission for Test assignment name" in the "#nav-notification-popover-container" "css_element" + + Scenario: User cannot disable forced notification preferences + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following config values are set as admin: + | popup_provider_mod_assign_assign_notification_locked | 1 | message | + | message_provider_mod_assign_assign_notification_enabled | popup | message | + And the following "user preferences" exist: + | user | preference | value | + | student1 | message_provider_mod_assign_assign_notification_enabled | none | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + | assignsubmission_onlinetext_enabled | 1 | + | assignsubmission_file_enabled | 0 | + | submissiondrafts | 0 | + # This should generate a notification. + And the following "mod_assign > submissions" exist: + | assign | user | onlinetext | + | Test assignment name | student1 | I'm the student1 submission | + When I log in as "student1" + # Confirm the popover is saying 1 unread notifications. + Then I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element" + # Open the popover. + And I open the notification popover + # Confirm the submission notification is visible. + And I should see "You have submitted your assignment submission for Test assignment name" in the "#nav-notification-popover-container" "css_element" + + Scenario: User cannot disable disallowed notification preferences + Given the following "courses" exist: + | fullname | shortname | category | groupmode | + | Course 1 | C1 | 0 | 1 | + And the following "course enrolments" exist: + | user | course | role | + | student1 | C1 | student | + And the following config values are set as admin: + | popup_provider_mod_assign_assign_notification_locked | 1 | message | + | message_provider_mod_assign_assign_notification_enabled | none | message | + And the following "user preferences" exist: + | user | preference | value | + | student1 | message_provider_mod_assign_assign_notification_enabled | popup | + And the following "activity" exists: + | activity | assign | + | course | C1 | + | name | Test assignment name | + | assignsubmission_onlinetext_enabled | 1 | + | assignsubmission_file_enabled | 0 | + | submissiondrafts | 0 | + # This should generate a notification. + And the following "mod_assign > submissions" exist: + | assign | user | onlinetext | + | Test assignment name | student1 | I'm the student1 submission | + When I log in as "student1" + # Confirm the popover is not showing any unread notifications. + Then I should not see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element" + # Open the popover. + And I open the notification popover + # Confirm the submission notification is NOT visible. + And I should not see "You have submitted your assignment submission for Test assignment name" in the "#nav-notification-popover-container" "css_element" diff --git a/message/tests/behat/message_preferences.feature b/message/tests/behat/message_preferences.feature index e12ee118b63..a8e530340e8 100644 --- a/message/tests/behat/message_preferences.feature +++ b/message/tests/behat/message_preferences.feature @@ -9,8 +9,7 @@ Feature: To be able to see and save user message preferences as admin | student1 | Student | 1 | student1@emample.com | And the following "user preferences" exist: | user | preference | value | - | student1 | message_provider_moodle_instantmessage_loggedin | none | - | student1 | message_provider_moodle_instantmessage_loggedoff | email | + | student1 | message_provider_moodle_instantmessage_enabled | email | @javascript Scenario: As an admin I can view and edit message preferences for a user @@ -22,7 +21,7 @@ Feature: To be able to see and save user message preferences as admin And I click on "Student 1" "link" in the "Student 1" "table_row" And I click on "Preferences" "link" in the "#region-main-box" "css_element" And I click on "Message preferences" "link" in the "#region-main-box" "css_element" - And I click on "//label[@data-state='loggedoff']" "xpath_element" + And I click on "//div[@class='preference-state']" "xpath_element" And I log out And I log in as "student1" And I follow "Preferences" in the user menu diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index faeb8391872..76e65115752 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -1980,8 +1980,7 @@ class externallib_test extends externallib_advanced_testcase { $this->setUser($user); // Set a couple of preferences to test. - set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user); - set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user); + set_user_preference('message_provider_mod_assign_assign_notification_enabled', 'popup', $user); $prefs = core_message_external::get_user_notification_preferences(); $prefs = \external_api::clean_returnvalue(core_message_external::get_user_notification_preferences_returns(), $prefs); @@ -2001,16 +2000,13 @@ class externallib_test extends externallib_advanced_testcase { } foreach ($prefdata['processors'] as $processor) { if ($processor['name'] == 'popup') { - $this->assertTrue($processor['loggedin']['checked']); - $found++; - } else if ($processor['name'] == 'email') { - $this->assertTrue($processor['loggedoff']['checked']); - $found++; + $this->assertTrue($processor['enabled']); + $found = 1; } } } } - $this->assertEquals(2, $found); + $this->assertEquals(1, $found); } /** @@ -3494,8 +3490,7 @@ class externallib_test extends externallib_advanced_testcase { set_config('messagingallusers', true); // Set a couple of preferences to test. - set_user_preference('message_provider_moodle_instantmessage_loggedin', 'email', $user); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'email', $user); set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user); $prefs = core_message_external::get_user_message_preferences(); @@ -3515,8 +3510,7 @@ class externallib_test extends externallib_advanced_testcase { } foreach ($prefdata['processors'] as $processor) { if ($processor['name'] == 'email') { - $this->assertTrue($processor['loggedin']['checked']); - $this->assertTrue($processor['loggedoff']['checked']); + $this->assertTrue($processor['enabled']); $found = true; } } diff --git a/message/tests/privacy/provider_test.php b/message/tests/privacy/provider_test.php index f3e19c0fa1d..9863c5906b3 100644 --- a/message/tests/privacy/provider_test.php +++ b/message/tests/privacy/provider_test.php @@ -170,11 +170,12 @@ class provider_test extends \core_privacy\tests\provider_testcase { $user = $this->getDataGenerator()->create_user(); // Set some message user preferences. - set_user_preference('message_provider_moodle_instantmessage_loggedin', 'airnotifier', $USER->id); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'popup', $USER->id); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'airnotifier', $USER->id); + set_user_preference('message_provider_mod_feedback_submission_enabled', 'popup', $USER->id); + set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $USER->id); set_user_preference('message_entertosend', true, $USER->id); - set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'inbound', $user->id); + set_user_preference('message_provider_moodle_instantmessage_enabled', 'inbound', $user->id); // Set an unrelated preference. set_user_preference('some_unrelated_preference', 'courses', $USER->id); @@ -189,15 +190,15 @@ class provider_test extends \core_privacy\tests\provider_testcase { // Check only 3 preferences exist. $this->assertCount(4, $prefs); - $this->assertArrayHasKey('message_provider_moodle_instantmessage_loggedin', $prefs); - $this->assertArrayHasKey('message_provider_moodle_instantmessage_loggedoff', $prefs); + $this->assertArrayHasKey('message_provider_moodle_instantmessage_enabled', $prefs); + $this->assertArrayHasKey('message_provider_mod_feedback_submission_enabled', $prefs); $this->assertArrayHasKey('message_blocknoncontacts', $prefs); $this->assertArrayHasKey('message_entertosend', $prefs); foreach ($prefs as $key => $pref) { - if ($key == 'message_provider_moodle_instantmessage_loggedin') { + if ($key == 'message_provider_moodle_instantmessage_enabled') { $this->assertEquals('airnotifier', $pref->value); - } else if ($key == 'message_provider_moodle_instantmessage_loggedoff') { + } else if ($key == 'message_provider_mod_feedback_submission_enabled') { $this->assertEquals('popup', $pref->value); } else { $this->assertEquals(1, $pref->value); diff --git a/mod/forum/db/messages.php b/mod/forum/db/messages.php index 4756901afd1..3b7182b59b9 100644 --- a/mod/forum/db/messages.php +++ b/mod/forum/db/messages.php @@ -27,7 +27,7 @@ $messageproviders = array ( // Ordinary single forum posts. 'posts' => array( 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), diff --git a/mod/forum/tests/mail_test.php b/mod/forum/tests/mail_test.php index c9d0247b8b8..4a60c7646d1 100644 --- a/mod/forum/tests/mail_test.php +++ b/mod/forum/tests/mail_test.php @@ -865,8 +865,7 @@ class mod_forum_mail_testcase extends advanced_testcase { $this->helper_spoof_message_inbound_setup(); $author->emailstop = '0'; - set_user_preference('message_provider_mod_forum_posts_loggedoff', 'email', $author); - set_user_preference('message_provider_mod_forum_posts_loggedin', 'email', $author); + set_user_preference('message_provider_mod_forum_posts_enabled', 'email', $author); // Run cron and check that the expected number of users received the notification. // Clear the mailsink, and close the messagesink. diff --git a/mod/lesson/db/messages.php b/mod/lesson/db/messages.php index e2dfbb73698..f90da13dc71 100644 --- a/mod/lesson/db/messages.php +++ b/mod/lesson/db/messages.php @@ -28,11 +28,8 @@ $messageproviders = array ( // essay graded notification 'graded_essay' => array ( 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ) ); - - - diff --git a/mod/quiz/db/messages.php b/mod/quiz/db/messages.php index 684f3fb02f6..32136d17e79 100644 --- a/mod/quiz/db/messages.php +++ b/mod/quiz/db/messages.php @@ -34,7 +34,7 @@ $messageproviders = array( 'confirmation' => array( 'capability' => 'mod/quiz:emailconfirmsubmission', 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), @@ -43,14 +43,14 @@ $messageproviders = array( 'attempt_overdue' => array( 'capability' => 'mod/quiz:emailwarnoverdue', 'defaults' => array( - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ), ), 'attempt_grading_complete' => [ 'capability' => 'mod/quiz:emailnotifyattemptgraded', 'defaults' => [ - 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, + 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED, ], ], ); diff --git a/user/externallib.php b/user/externallib.php index 0f402dfa9a0..87f8fbed253 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -415,6 +415,18 @@ class core_user_external extends external_api { if (!empty($preferences)) { $userpref = ['id' => $userid]; foreach ($preferences as $preference) { + + /* + * Rename user message provider preferences to avoid orphan settings on old app versions. + * @todo Remove this "translation" block on MDL-73284. + */ + if (preg_match('/message_provider_.*_loggedin/', $preference['type']) || + preg_match('/message_provider_.*_loggedoff/', $preference['type'])) { + $nameparts = explode('_', $preference['type']); + array_pop($nameparts); + $preference['type'] = implode('_', $nameparts).'_enabled'; + } + $userpref['preference_' . $preference['type']] = $preference['value']; } useredit_update_user_preference($userpref); diff --git a/version.php b/version.php index 9a415e2c739..3f17aa2de93 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2022012100.01; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2022012100.02; // 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