MDL-67853 message: Remove on/offline settings on message preferences

This commit is contained in:
Pau Ferrer Ocaña
2020-01-29 16:45:32 +01:00
parent e8ad1eaa43
commit d74bd798b6
44 changed files with 696 additions and 682 deletions

View File

@@ -48,69 +48,52 @@ if (($form = data_submitted()) && confirm_sesskey()) {
foreach ($providers as $provider) { foreach ($providers as $provider) {
$componentproviderbase = $provider->component.'_'.$provider->name; $componentproviderbase = $provider->component.'_'.$provider->name;
$disableprovidersetting = $componentproviderbase.'_disable'; $disableprovidersetting = $componentproviderbase.'_disable';
$providerdisabled = false;
if (!isset($form->$disableprovidersetting)) { if (!isset($form->$disableprovidersetting)) {
$providerdisabled = true;
$newpreferences[$disableprovidersetting] = 1; $newpreferences[$disableprovidersetting] = 1;
} else { } else {
$newpreferences[$disableprovidersetting] = 0; $newpreferences[$disableprovidersetting] = 0;
} }
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) { $componentprovidersetting = $componentproviderbase.'_locked';
$value = null; foreach ($processors as $processor) {
$componentprovidersetting = $componentproviderbase.'_'.$setting; $value = 0;
if ($setting == 'permitted') { if (isset($form->{$componentprovidersetting}[$processor->name])) {
// If we deal with permitted select element, we need to create individual $value = $form->{$componentprovidersetting}[$processor->name];
// setting for each possible processor. Note that this block will if ($value == 'on') {
// always be processed first after entring parental foreach iteration $value = 1;
// 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;
} }
} }
if ($setting != 'permitted') {
// We have already recoded site preferences for 'permitted' type. // Record the site preference.
$newpreferences['message_provider_'.$componentprovidersetting] = $value; $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. // Update database.
@@ -142,8 +125,6 @@ if (($form = data_submitted()) && confirm_sesskey()) {
// Page settings // Page settings
$PAGE->set_context(context_system::instance()); $PAGE->set_context(context_system::instance());
$PAGE->requires->js_init_call('M.core_message.init_defaultoutputs');
$renderer = $PAGE->get_renderer('core', 'message'); $renderer = $PAGE->get_renderer('core', 'message');
// Display the page. // Display the page.

View File

@@ -28,8 +28,8 @@ $messageproviders = [
// Notify Data Protection Officer about incoming data requests. // Notify Data Protection Officer about incoming data requests.
'contactdataprotectionofficer' => [ 'contactdataprotectionofficer' => [
'defaults' => [ 'defaults' => [
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
], ],
'capability' => 'tool/dataprivacy:managedatarequests' 'capability' => 'tool/dataprivacy:managedatarequests'
], ],
@@ -37,15 +37,15 @@ $messageproviders = [
// Notify user about the processing results of their data request. // Notify user about the processing results of their data request.
'datarequestprocessingresults' => [ 'datarequestprocessingresults' => [
'defaults' => [ 'defaults' => [
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
] ]
], ],
// Notify Data Protection Officer about exceptions. // Notify Data Protection Officer about exceptions.
'notifyexceptions' => [ 'notifyexceptions' => [
'defaults' => [ 'defaults' => [
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
], ],
'capability' => 'tool/dataprivacy:managedatarequests' 'capability' => 'tool/dataprivacy:managedatarequests'
], ],

View File

@@ -82,3 +82,10 @@ navmethod,core_grades
dropdown,core_grades dropdown,core_grades
tabs,core_grades tabs,core_grades
combo,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

View File

@@ -51,7 +51,6 @@ $string['contacts'] = 'Contacts';
$string['conversationactions'] = 'Conversation actions menu'; $string['conversationactions'] = 'Conversation actions menu';
$string['decline'] = 'Decline'; $string['decline'] = 'Decline';
$string['defaultmessageoutputs'] = 'Notification settings'; $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['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['deleteallmessages'] = "Delete all messages";
$string['deleteallselfconfirm'] = "Are you sure you would like to delete this entire personal conversation?"; $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['isnotinyourcontacts'] = '{$a} is not in your contacts';
$string['loadmore'] = 'Load more'; $string['loadmore'] = 'Load more';
$string['loggedin'] = 'Online'; $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'] = '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['managemessageoutputs'] = 'Default notification preferences';
$string['messageoutputs'] = 'Notification plugins'; $string['messageoutputs'] = 'Notification plugins';
$string['messagepreferences'] = 'Message preferences'; $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:request:preference:set'] = 'The value of the setting \'{$a->name}\' was \'{$a->value}\'';
$string['privacy:export:conversationprefix'] = 'Conversation: '; $string['privacy:export:conversationprefix'] = 'Conversation: ';
$string['processorsettings'] = 'Processor settings'; $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['removecontact'] = 'Remove contact';
$string['removecontactconfirm'] = 'Are you sure you want to remove {$a} from your contacts?'; $string['removecontactconfirm'] = 'Are you sure you want to remove {$a} from your contacts?';
$string['removecoursefilter'] = 'Remove filter for course {$a}'; $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['selfconversationdefaultmessage'] = 'Save draft messages, links, notes etc. to access later.';
$string['send'] = 'Send'; $string['send'] = 'Send';
$string['sender'] = '{$a}:'; $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['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['sendmessage'] = 'Send message';
$string['sendbulkmessage'] = 'Send message to {$a} people'; $string['sendbulkmessage'] = 'Send message to {$a} people';
$string['sendbulkmessagesingle'] = 'Send message to 1 person'; $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. // Deprecated since Moodle 3.9.
$string['messagecontactrequestsnotification'] = '{$a} is requesting to be added as a contact.'; $string['messagecontactrequestsnotification'] = '{$a} is requesting to be added as a contact.';
$string['messagecontactrequestsnotificationsubject'] = 'Contact request from {$a}'; $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}';

View File

@@ -208,20 +208,6 @@ class manager {
return false; 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. // Fill in the array of processors to be used based on default and user preferences.
// Do not process muted conversations. // Do not process muted conversations.
$processorlist = []; $processorlist = [];
@@ -233,23 +219,30 @@ class manager {
} }
// First find out permissions. // First find out permissions.
$defaultpreference = $processor->name . '_provider_' . $preferencebase . '_permitted'; $defaultlockedpreference = $processor->name . '_provider_' . $preferencebase . '_locked';
if (isset($defaultpreferences->{$defaultpreference})) { $locked = false;
$permitted = $defaultpreferences->{$defaultpreference}; if (isset($defaultpreferences->{$defaultlockedpreference})) {
$locked = $defaultpreferences->{$defaultlockedpreference};
} else { } else {
// MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't // 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). // 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.
to message_send() are valid."; Make sure the component and name you supplied to message_send() are valid.";
throw new coding_exception($preferrormsg); 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. // Find out if user has configured this output.
// Some processors cannot function without settings from the user. // Some processors cannot function without settings from the user.
$userisconfigured = $processor->object->is_user_configured($recipient); $userisconfigured = $processor->object->is_user_configured($recipient);
// DEBUG: notify if we are forcing unconfigured output. // 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 . debugging('Attempt to force message delivery to user who has "' . $processor->name .
'" output unconfigured', DEBUG_NORMAL); '" output unconfigured', DEBUG_NORMAL);
} }
@@ -257,13 +250,13 @@ class manager {
// Populate the list of processors we will be using. // Populate the list of processors we will be using.
if (!$eventdata->notification && $processor->object->force_process_messages()) { if (!$eventdata->notification && $processor->object->force_process_messages()) {
$processorlist[] = $processor->name; $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. // An admin is forcing users to use this message processor. Use this processor unconditionally.
$processorlist[] = $processor->name; $processorlist[] = $processor->name;
} else if ($permitted == 'permitted' && $userisconfigured && !$recipient->emailstop) { } else if (!$locked && $userisconfigured && !$recipient->emailstop) {
// User has not disabled notifications. // User has not disabled notifications.
// See if user set any notification preferences, otherwise use site default ones. // 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 ($userpreference = get_user_preferences($userpreferencename, null, $recipient)) {
if (in_array($processor->name, explode(',', $userpreference))) { if (in_array($processor->name, explode(',', $userpreference))) {
$processorlist[] = $processor->name; $processorlist[] = $processor->name;

View File

@@ -37,8 +37,8 @@ $messageproviders = array (
'newlogin' => array ( 'newlogin' => array (
'defaults' => array( 'defaults' => array(
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
), ),
@@ -56,15 +56,15 @@ $messageproviders = array (
'availableupdate' => array( 'availableupdate' => array(
'capability' => 'moodle/site:config', 'capability' => 'moodle/site:config',
'defaults' => array( 'defaults' => array(
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED
), ),
), ),
'instantmessage' => array ( 'instantmessage' => array (
'defaults' => array( 'defaults' => array(
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
), ),
@@ -81,7 +81,7 @@ $messageproviders = array (
'courserequestapproved' => array ( 'courserequestapproved' => array (
'capability' => 'moodle/course:request', 'capability' => 'moodle/course:request',
'defaults' => array( '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 ( 'courserequestrejected' => array (
'capability' => 'moodle/course:request', 'capability' => 'moodle/course:request',
'defaults' => array( '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. // 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. // Course content updated. New content (activities or resources) has been created or existing content updated.
'coursecontentupdated' => array ( 'coursecontentupdated' => array (
'defaults' => array( 'defaults' => array(
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
), ),
// Badge award notification to a badge recipient. // Badge award notification to a badge recipient.
'badgerecipientnotice' => array ( 'badgerecipientnotice' => array (
'defaults' => array( 'defaults' => array(
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
'capability' => 'moodle/badges:earnbadge' 'capability' => 'moodle/badges:earnbadge'
), ),
@@ -118,7 +122,7 @@ $messageproviders = array (
// Badge award notification to a badge creator (mostly cron-based). // Badge award notification to a badge creator (mostly cron-based).
'badgecreatornotice' => array ( 'badgecreatornotice' => array (
'defaults' => array( 'defaults' => array(
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
) )
), ),
@@ -131,9 +135,9 @@ $messageproviders = array (
// User insights. // User insights.
'insights' => array ( 'insights' => array (
'defaults' => [ 'defaults' => [
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
] ]
), ),
@@ -142,23 +146,23 @@ $messageproviders = array (
'defaults' => [ 'defaults' => [
// We don't need to notify in the popup output here because the message drawer // We don't need to notify in the popup output here because the message drawer
// already notifies users of contact requests. // already notifies users of contact requests.
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
] ]
], ],
// Asyncronhous backup/restore notifications. // Asyncronhous backup/restore notifications.
'asyncbackupnotification' => array( 'asyncbackupnotification' => array(
'defaults' => array( 'defaults' => array(
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
) )
), ),
'gradenotifications' => [ 'gradenotifications' => [
'defaults' => array( 'defaults' => array(
'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'popup' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDOFF, 'email' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
], ],

View File

@@ -241,20 +241,6 @@ function message_send(\core\message\message $eventdata) {
return false; 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. // Check if we are creating a notification or message.
$table = 'notifications'; $table = 'notifications';
@@ -299,40 +285,47 @@ function message_send(\core\message\message $eventdata) {
} }
// First find out permissions // First find out permissions
$defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted'; $defaultlockedpreference = $processor->name . '_provider_' . $preferencebase . '_locked';
if (isset($defaultpreferences->{$defaultpreference})) { $locked = false;
$permitted = $defaultpreferences->{$defaultpreference}; if (isset($defaultpreferences->{$defaultlockedpreference})) {
$locked = $defaultpreferences->{$defaultlockedpreference};
} else { } else {
// MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't // 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). // 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."; to message_send() are valid.";
throw new coding_exception($preferrormsg); 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 // Find out if user has configured this output
// Some processors cannot function without settings from the user // Some processors cannot function without settings from the user
$userisconfigured = $processor->object->is_user_configured($eventdata->userto); $userisconfigured = $processor->object->is_user_configured($eventdata->userto);
// DEBUG: notify if we are forcing unconfigured output // 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); 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 // 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. // An admin is forcing users to use this message processor. Use this processor unconditionally.
$processorlist[] = $processor->name; $processorlist[] = $processor->name;
} else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) { } else if (!$forced && !$locked && $userisconfigured && !$eventdata->userto->emailstop) {
// User has not disabled notifications // User has not disabled notifications
// See if user set any notification preferences, otherwise use site default ones // See if user set any notification preferences, otherwise use site default ones
$userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate; if ($userpreference = get_user_preferences($preferencename, null, $eventdata->userto)) {
if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto)) {
if (in_array($processor->name, explode(',', $userpreference))) { if (in_array($processor->name, explode(',', $userpreference))) {
$processorlist[] = $processor->name; $processorlist[] = $processor->name;
} }
} else if (isset($defaultpreferences->{$userpreferencename})) { } else if (isset($defaultpreferences->{$preferencename})) {
if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { if (in_array($processor->name, explode(',', $defaultpreferences->{$preferencename}))) {
$processorlist[] = $processor->name; $processorlist[] = $processor->name;
} }
} }
@@ -523,51 +516,37 @@ function message_set_default_message_preference($component, $messagename, $filep
// Setting default preference // Setting default preference
$componentproviderbase = $component.'_'.$messagename; $componentproviderbase = $component.'_'.$messagename;
$loggedinpref = array(); $enabledpref = [];
$loggedoffpref = array(); // Set 'locked' preference first for each messaging processor.
// set 'permitted' preference first for each messaging processor
foreach ($processors as $processor) { foreach ($processors as $processor) {
$preferencename = $processor->name.'_provider_'.$componentproviderbase.'_permitted'; $preferencename = $processor->name.'_provider_'.$componentproviderbase.'_locked';
// if we do not have this setting yet, set it // If we do not have this setting yet, set it.
if (!isset($defaultpreferences->{$preferencename})) { if (!isset($defaultpreferences->{$preferencename})) {
// determine plugin default settings // Determine plugin default settings.
$plugindefault = 0; $plugindefault = 0;
if (isset($fileprovider['defaults'][$processor->name])) { if (isset($fileprovider['defaults'][$processor->name])) {
$plugindefault = $fileprovider['defaults'][$processor->name]; $plugindefault = $fileprovider['defaults'][$processor->name];
} }
// get string values of the settings // Get string values of the settings.
list($permitted, $loggedin, $loggedoff) = translate_message_default_setting($plugindefault, $processor->name); list($locked, $enabled) = translate_message_default_setting($plugindefault, $processor->name);
// store default preferences for current processor // Store default preferences for current processor.
set_config($preferencename, $permitted, 'message'); set_config($preferencename, $locked, 'message');
// save loggedin/loggedoff settings // Save enabled settings.
if ($loggedin) { if ($enabled) {
$loggedinpref[] = $processor->name; $enabledpref[] = $processor->name;
}
if ($loggedoff) {
$loggedoffpref[] = $processor->name;
} }
} }
} }
// now set loggedin/loggedoff preferences // Now set enabled preferences.
if (!empty($loggedinpref)) { if (!empty($enabledpref)) {
$preferencename = 'message_provider_'.$componentproviderbase.'_loggedin'; $preferencename = 'message_provider_'.$componentproviderbase.'_enabled';
if (isset($defaultpreferences->{$preferencename})) { if (isset($defaultpreferences->{$preferencename})) {
// We have the default preferences for this message provider, which // We have the default preferences for this message provider, which
// likely means that we have been adding a new processor. Add defaults // likely means that we have been adding a new processor. Add defaults
// to exisitng preferences. // to exisitng preferences.
$loggedinpref = array_merge($loggedinpref, explode(',', $defaultpreferences->{$preferencename})); $enabledpref = array_merge($enabledpref, explode(',', $defaultpreferences->{$preferencename}));
} }
set_config($preferencename, join(',', $loggedinpref), 'message'); set_config($preferencename, join(',', $enabledpref), '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');
} }
} }
@@ -754,8 +733,8 @@ function message_processor_uninstall($name) {
$transaction = $DB->start_delegated_transaction(); $transaction = $DB->start_delegated_transaction();
$DB->delete_records('message_processors', array('name' => $name)); $DB->delete_records('message_processors', array('name' => $name));
$DB->delete_records_select('config_plugins', "plugin = ?", array("message_{$name}")); $DB->delete_records_select('config_plugins', "plugin = ?", array("message_{$name}"));
// delete permission preferences only, we do not care about loggedin/loggedoff // Delete permission preferences only, we do not care about enabled defaults,
// defaults, they will be removed on the next attempt to update the preferences // 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_%")); $DB->delete_records_select('config_plugins', "plugin = 'message' AND ".$DB->sql_like('name', '?', false), array("{$name}_provider_%"));
$transaction->allow_commit(); $transaction->allow_commit();
// Purge all messaging settings from the caches. They are stored by plugin so we have to clear all message settings. // Purge all messaging settings from the caches. They are stored by plugin so we have to clear all message settings.

View File

@@ -163,6 +163,12 @@ current value for a pluginname depending on its status (enabled, disabled, other
* /renderer.php * /renderer.php
* /rsslib.php * /rsslib.php
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. 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.
* 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 === === 3.11.4 ===
* A new option dontforcesvgdownload has been added to the $options parameter of the send_file() function. * A new option dontforcesvgdownload has been added to the $options parameter of the send_file() function.

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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 //# sourceMappingURL=message_drawer_view_settings.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -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 //# sourceMappingURL=notification_preference.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -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 //# sourceMappingURL=notification_processor.min.js.map

View File

@@ -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 <http://www.gnu.org/licenses/>.\n\n/**\n * Represents the notification processor (e.g. email, popup, jabber)\n *\n * @module core_message/notification_processor\n * @copyright 2016 Ryan Wyllie <ryan@moodle.com>\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"} {"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 <http://www.gnu.org/licenses/>.\n\n/**\n * Represents the notification processor (e.g. email, popup, jabber)\n *\n * @module core_message/notification_processor\n * @copyright 2016 Ryan Wyllie <ryan@moodle.com>\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"}

View File

@@ -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 //# sourceMappingURL=preferences_notifications_list_controller.min.js.map

File diff suppressed because one or more lines are too long

View File

@@ -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 <http://www.gnu.org/licenses/>.
/**
* 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 <pau@moodle.com>
* @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,
};

View File

@@ -144,11 +144,7 @@ function(
var newValue = values.length ? values.join(',') : 'none'; var newValue = values.length ? values.join(',') : 'none';
var preferences = [ var preferences = [
{ {
type: 'message_provider_moodle_instantmessage_loggedoff', type: 'message_provider_moodle_instantmessage_enabled',
value: newValue
},
{
type: 'message_provider_moodle_instantmessage_loggedin',
value: newValue value: newValue
} }
]; ];
@@ -219,7 +215,7 @@ function(
// Consider the the processor enabled if either preference is set. This is // Consider the the processor enabled if either preference is set. This is
// for backwards compatibility. Going forward they will be treated as one // for backwards compatibility. Going forward they will be treated as one
// setting. // setting.
var checked = processor.loggedin.checked || processor.loggedoff.checked; var checked = processor.enabled;
return { return {
displayname: processor.displayname, displayname: processor.displayname,
name: processor.name, name: processor.name,

View File

@@ -24,7 +24,7 @@
define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_processor'], define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_processor'],
function($, Ajax, Notification, NotificationProcessor) { function($, Ajax, Notification, NotificationProcessor) {
var SELECTORS = { const SELECTORS = {
PROCESSOR: '[data-processor-name]', PROCESSOR: '[data-processor-name]',
STATE_INPUTS: '[data-state] input', 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 {object} element jQuery object root element of the preference
* @param {int} userId The current user id * @param {int} userId The current user id
*/ */
var NotificationPreference = function(element, userId) { const NotificationPreference = function(element, userId) {
this.root = $(element); this.root = $(element);
this.userId = userId; 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} * @return {string}
*/ */
NotificationPreference.prototype.getLoggedInPreferenceKey = function() { NotificationPreference.prototype.getEnabledPreferenceKey = function() {
return this.getPreferenceKey() + '_loggedin'; return this.getPreferenceKey() + '_enabled';
};
/**
* Get the unique key for the logged off preference.
*
* @method getLoggedOffPreferenceKey
* @return {string}
*/
NotificationPreference.prototype.getLoggedOffPreferenceKey = function() {
return this.getPreferenceKey() + '_loggedoff';
}; };
/** /**
@@ -126,50 +116,33 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p
this.startLoading(); this.startLoading();
var loggedInValue = ''; let enabledValue = '';
var loggedOffValue = '';
this.getProcessors().each(function(index, processor) { this.getProcessors().each(function(index, processor) {
if (processor.isLoggedInEnabled()) { if (processor.isEnabled()) {
if (loggedInValue === '') { if (enabledValue === '') {
loggedInValue = processor.getName(); enabledValue = processor.getName();
} else { } else {
loggedInValue += ',' + processor.getName(); enabledValue += ',' + processor.getName();
}
}
if (processor.isLoggedOffEnabled()) {
if (loggedOffValue === '') {
loggedOffValue = processor.getName();
} else {
loggedOffValue += ',' + processor.getName();
} }
} }
}); });
if (loggedInValue === '') { if (enabledValue === '') {
loggedInValue = 'none'; enabledValue = 'none';
} }
if (loggedOffValue === '') { const args = {
loggedOffValue = 'none';
}
var args = {
userid: this.userId, userid: this.userId,
preferences: [ preferences: [
{ {
type: this.getLoggedInPreferenceKey(), type: this.getEnabledPreferenceKey(),
value: loggedInValue, value: enabledValue,
}, }
{
type: this.getLoggedOffPreferenceKey(),
value: loggedOffValue,
},
], ],
}; };
var request = { const request = {
methodname: 'core_user_update_user_preferences', methodname: 'core_user_update_user_preferences',
args: args, args: args,
}; };

View File

@@ -21,11 +21,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/ */
define(['jquery'], function($) { define(['jquery'], function($) {
var SELECTORS = { const SELECTORS = {
STATE_NONE: '[data-state="none"]', STATE_INPUTS: '.preference-state input.notification_enabled'
STATE_BOTH: '[data-state="both"]',
STATE_LOGGED_IN: '[data-state="loggedin"]',
STATE_LOGGED_OFF: '[data-state="loggedoff"]',
}; };
/** /**
@@ -34,7 +31,7 @@ define(['jquery'], function($) {
* @class * @class
* @param {object} element jQuery object root element of the processor * @param {object} element jQuery object root element of the processor
*/ */
var NotificationProcessor = function(element) { const NotificationProcessor = function(element) {
this.root = $(element); this.root = $(element);
}; };
@@ -54,36 +51,10 @@ define(['jquery'], function($) {
* @method isLoggedInEnabled * @method isLoggedInEnabled
* @return {bool} * @return {bool}
*/ */
NotificationProcessor.prototype.isLoggedInEnabled = function() { NotificationProcessor.prototype.isEnabled = function() {
var none = this.root.find(SELECTORS.STATE_NONE).find('input'); const enabled = this.root.find(SELECTORS.STATE_INPUTS);
if (none.prop('checked')) { return enabled.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 NotificationProcessor; return NotificationProcessor;

View File

@@ -42,9 +42,9 @@ define(['jquery',
var SELECTORS = { var SELECTORS = {
DISABLE_NOTIFICATIONS: '[data-region="disable-notification-container"] [data-disable-notifications]', DISABLE_NOTIFICATIONS: '[data-region="disable-notification-container"] [data-disable-notifications]',
DISABLE_NOTIFICATIONS_CONTAINER: '[data-region="disable-notification-container"]', DISABLE_NOTIFICATIONS_CONTAINER: '[data-region="disable-notification-container"]',
PREFERENCE: '[data-state]', PREFERENCE: '.preference-state',
PREFERENCE_ROW: '[data-region="preference-row"]', PREFERENCE_ROW: '[data-region="preference-row"]',
PREFERENCE_INPUT: '[data-state] input', PREFERENCE_INPUT: '.preference-state input',
PROCESSOR_SETTING: '[data-processor-setting]', PROCESSOR_SETTING: '[data-processor-setting]',
}; };

View File

@@ -270,18 +270,17 @@ class helper {
// Get providers preferences. // Get providers preferences.
foreach ($providers as $provider) { foreach ($providers as $provider) {
foreach (array('loggedin', 'loggedoff') as $state) { $linepref = get_user_preferences('message_provider_' . $provider->component . '_' . $provider->name
$linepref = get_user_preferences('message_provider_' . $provider->component . '_' . $provider->name . '_enabled', '', $userid);
. '_' . $state, '', $userid); if ($linepref == '') {
if ($linepref == '') { continue;
continue;
}
$lineprefarray = explode(',', $linepref);
$preferences->{$provider->component.'_'.$provider->name.'_'.$state} = array();
foreach ($lineprefarray as $pref) {
$preferences->{$provider->component.'_'.$provider->name.'_'.$state}[$pref] = 1;
}
} }
$lineprefarray = explode(',', $linepref);
$preferences->{$provider->component.'_'.$provider->name.'_enabled'} = [];
foreach ($lineprefarray as $pref) {
$preferences->{$provider->component.'_'.$provider->name.'_enabled'}[$pref] = 1;
}
} }
return $preferences; return $preferences;

View File

@@ -162,15 +162,6 @@ class notification_list implements templatable, renderable {
$context['components'][] = $notificationcomponent->export_for_template($output); $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; return $context;
} }
} }

View File

@@ -127,6 +127,7 @@ class notification_list_component implements templatable, renderable {
$context = [ $context = [
'displayname' => $componentname, 'displayname' => $componentname,
'colspan' => count($processors) + 1,
'notifications' => [], 'notifications' => [],
]; ];

View File

@@ -81,16 +81,17 @@ class notification_list_processor implements templatable, renderable {
* Check if the given preference is enabled or not. * Check if the given preference is enabled or not.
* *
* @param string $name preference name * @param string $name preference name
* @param string $locked Wether the preference is locked by admin.
* @return bool * @return bool
*/ */
private function is_preference_enabled($name) { private function is_preference_enabled($name, $locked) {
$processor = $this->processor; $processor = $this->processor;
$preferences = $this->preferences; $preferences = $this->preferences;
$defaultpreferences = get_message_output_default_preferences(); $defaultpreferences = get_message_output_default_preferences();
$checked = false; $checked = false;
// See if user has touched this preference. // 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. // User has some preferences for this state in the database.
$checked = isset($preferences->{$name}[$processor->name]); $checked = isset($preferences->{$name}[$processor->name]);
} else { } else {
@@ -104,40 +105,64 @@ class notification_list_processor implements templatable, renderable {
return $checked; 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) { public function export_for_template(\renderer_base $output) {
$processor = $this->processor; $processor = $this->processor;
$preferencebase = $this->get_preference_base(); $preferencebase = $this->get_preference_base();
$permitted = MESSAGE_DEFAULT_PERMITTED;
$defaultpreferences = get_message_output_default_preferences(); $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 = [ $context = [
'displayname' => get_string('pluginname', 'message_'.$processor->name), 'displayname' => $processorname,
'name' => $processor->name, 'name' => $processor->name,
'locked' => false, 'locked' => false,
'userconfigured' => $processor->object->is_user_configured(), 'userconfigured' => $processor->object->is_user_configured(),
// Backward compatibility, deprecated attribute.
'loggedin' => [ 'loggedin' => [
'name' => 'loggedin', 'name' => 'loggedin',
'displayname' => get_string('loggedindescription', 'message'), 'displayname' => 'loggedin',
'checked' => $this->is_preference_enabled($preferencebase.'_loggedin'), 'checked' => false,
], ],
// Backward compatibility, deprecated attribute.
'loggedoff' => [ 'loggedoff' => [
'name' => 'loggedoff', 'name' => 'loggedoff',
'displayname' => get_string('loggedoffdescription', 'message'), 'displayname' => 'loggedoff',
'checked' => $this->is_preference_enabled($preferencebase.'_loggedoff'), 'checked' => false,
], ],
'enabled' => false,
'enabledlabel' => get_string('sendingviaenabled', 'message', $labelparams),
]; ];
// Determine the default setting. // Determine the default setting.
if (isset($defaultpreferences->{$defaultpreference})) { 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 settings are disallowed or forced, just display the corresponding message, if not use user settings.
if ($permitted == 'disallowed') { if ($context['locked']) {
$context['locked'] = true; if ($context['enabled']) {
$context['lockedmessage'] = get_string('disallowed', 'message'); $context['lockedmessage'] = get_string('forced', 'message');
} else if ($permitted == 'forced') { $context['lockedlabel'] = get_string('providerprocesorislocked', 'message', $labelparams);
$context['locked'] = true; } else {
$context['lockedmessage'] = get_string('forced', 'message'); $context['lockedmessage'] = get_string('disallowed', 'message');
$context['lockedlabel'] = get_string('providerprocesorisdisallowed', 'message', $labelparams);
}
} }
return $context; return $context;

View File

@@ -3020,6 +3020,7 @@ class core_message_external extends external_api {
* *
* @return external_single_structure the structure * @return external_single_structure the structure
* @since Moodle 3.2 * @since Moodle 3.2
* @todo Remove loggedin and loggedoff from processors structure on MDL-73284.
*/ */
protected static function get_preferences_structure() { protected static function get_preferences_structure() {
return new external_single_structure( return new external_single_structure(
@@ -3061,15 +3062,20 @@ class core_message_external extends external_api {
'name' => new external_value(PARAM_NOTAGS, 'Name'), 'name' => new external_value(PARAM_NOTAGS, 'Name'),
'displayname' => new external_value(PARAM_TEXT, 'Display name'), 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
'checked' => new external_value(PARAM_BOOL, 'Is checked?'), 'checked' => new external_value(PARAM_BOOL, 'Is checked?'),
) ),
'DEPRECATED ATTRIBUTE -
Kept for backward compatibility, use enabled instead.',
), ),
'loggedoff' => new external_single_structure( 'loggedoff' => new external_single_structure(
array( array(
'name' => new external_value(PARAM_NOTAGS, 'Name'), 'name' => new external_value(PARAM_NOTAGS, 'Name'),
'displayname' => new external_value(PARAM_TEXT, 'Display name'), 'displayname' => new external_value(PARAM_TEXT, 'Display name'),
'checked' => new external_value(PARAM_BOOL, 'Is checked?'), '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' 'Processors values for this notification'

View File

@@ -34,24 +34,37 @@ define('MESSAGE_TYPE_MESSAGE', 'message');
/** /**
* Define contants for messaging default settings population. For unambiguity of * Define contants for messaging default settings population. For unambiguity of
* plugin developer intentions we use 4-bit value (LSB numbering): * plugin developer intentions we use 4-bit value (LSB numbering):
* bit 0 - whether to send message when user is loggedin (MESSAGE_DEFAULT_LOGGEDIN) * bit 0 - whether to send message (MESSAGE_DEFAULT_ENABLED)
* bit 1 - whether to send message when user is loggedoff (MESSAGE_DEFAULT_LOGGEDOFF) * 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) * 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 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_DEFAULT_LOGGEDOFF', 0x02); // 0010
define('MESSAGE_DISALLOWED', 0x04); // 0100 define('MESSAGE_DEFAULT_ENABLED', 0x01); // 0001.
define('MESSAGE_PERMITTED', 0x08); // 1000
define('MESSAGE_FORCED', 0x0c); // 1100
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 * 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'); 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 * Translate message default settings from binary value to the array of string
* representing the settings to be stored. Also validate the provided value and * representing the settings to be stored. Also validate the provided value and
* use default if it is malformed. * 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 int $plugindefault Default setting suggested by plugin
* @param string $processorname The name of processor * @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) { function translate_message_default_setting($plugindefault, $processorname) {
// Preset translation arrays
$permittedvalues = array(
MESSAGE_DISALLOWED => 'disallowed',
MESSAGE_PERMITTED => 'permitted',
MESSAGE_FORCED => 'forced',
);
$loggedinstatusvalues = array( // Define the default setting.
0x00 => null, // use null if loggedin/loggedoff is not defined
MESSAGE_DEFAULT_LOGGEDIN => 'loggedin',
MESSAGE_DEFAULT_LOGGEDOFF => 'loggedoff',
);
// define the default setting
$processor = get_message_processor($processorname); $processor = get_message_processor($processorname);
$default = $processor->get_default_messaging_settings(); $default = $processor->get_default_messaging_settings();
@@ -526,15 +528,31 @@ function translate_message_default_setting($plugindefault, $processorname) {
$plugindefault = $default; $plugindefault = $default;
} }
$permitted = $permittedvalues[$plugindefault & MESSAGE_PERMITTED_MASK]; $locked = false;
$loggedin = $loggedoff = null; $enabled = false;
if (($plugindefault & MESSAGE_PERMITTED_MASK) == MESSAGE_PERMITTED) { $permitted = $plugindefault & MESSAGE_PERMITTED_MASK;
$loggedin = $loggedinstatusvalues[$plugindefault & MESSAGE_DEFAULT_LOGGEDIN]; switch ($permitted) {
$loggedoff = $loggedinstatusvalues[$plugindefault & MESSAGE_DEFAULT_LOGGEDOFF]; 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, 'null' => NULL_NOT_ALLOWED,
'default' => false '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', 'null' => NULL_NOT_ALLOWED, 'default' => 'none',
'permissioncallback' => function ($user, $preferencename) { 'permissioncallback' => function ($user, $preferencename) {
global $CFG; global $CFG;
require_once($CFG->libdir.'/messagelib.php'); require_once($CFG->libdir.'/messagelib.php');
if (core_message_can_edit_message_profile($user) && 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); $providers = message_get_providers_for_user($user->id);
foreach ($providers as $provider) { foreach ($providers as $provider) {
if ($matches[1] === $provider->component . '_' . $provider->name) { if ($matches[1] === $provider->component . '_' . $provider->name) {

View File

@@ -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) { M.core_message.init_editsettings = function(Y) {
var editsettings = { var editsettings = {

View File

@@ -115,8 +115,8 @@ class message_airnotifier_external extends external_api {
$users = $DB->get_recordset_sql($usersql, $params); $users = $DB->get_recordset_sql($usersql, $params);
$result = array( $result = array(
'users' => array(), 'users' => [],
'warnings' => array() 'warnings' => []
); );
$hasuserupdatecap = has_capability('moodle/user:update', context_system::instance()); $hasuserupdatecap = has_capability('moodle/user:update', context_system::instance());
foreach ($users as $user) { foreach ($users as $user) {
@@ -126,7 +126,7 @@ class message_airnotifier_external extends external_api {
if ($currentuser or $hasuserupdatecap) { if ($currentuser or $hasuserupdatecap) {
if (!empty($user->deleted)) { if (!empty($user->deleted)) {
$warning = array(); $warning = [];
$warning['item'] = 'user'; $warning['item'] = 'user';
$warning['itemid'] = $user->id; $warning['itemid'] = $user->id;
$warning['warningcode'] = '1'; $warning['warningcode'] = '1';
@@ -135,7 +135,7 @@ class message_airnotifier_external extends external_api {
continue; continue;
} }
$preferences = array(); $preferences = [];
$preferences['userid'] = $user->id; $preferences['userid'] = $user->id;
$preferences['configured'] = 0; $preferences['configured'] = 0;
@@ -149,33 +149,30 @@ class message_airnotifier_external extends external_api {
break; break;
} }
foreach (array('loggedin', 'loggedoff') as $state) {
$prefstocheck = array(); $prefstocheck = [];
$prefname = 'message_provider_'.$provider->component.'_'.$provider->name.'_'.$state; $prefname = 'message_provider_'.$provider->component.'_'.$provider->name.'_enabled';
// First get forced settings. // First get forced settings.
if ($forcedpref = get_config('message', $prefname)) { if ($forcedpref = get_config('message', $prefname)) {
$prefstocheck = array_merge($prefstocheck, explode(',', $forcedpref)); $prefstocheck = array_merge($prefstocheck, explode(',', $forcedpref));
} }
// Then get user settings. // Then get user settings.
if ($userpref = get_user_preferences($prefname, '', $user->id)) { if ($userpref = get_user_preferences($prefname, '', $user->id)) {
$prefstocheck = array_merge($prefstocheck, explode(',', $userpref)); $prefstocheck = array_merge($prefstocheck, explode(',', $userpref));
} }
if (in_array('airnotifier', $prefstocheck)) {
$preferences['configured'] = 1;
$configured = true;
break;
}
if (in_array('airnotifier', $prefstocheck)) {
$preferences['configured'] = 1;
$configured = true;
break;
} }
} }
$result['users'][] = $preferences; $result['users'][] = $preferences;
} else if (!$hasuserupdatecap) { } else if (!$hasuserupdatecap) {
$warning = array(); $warning = [];
$warning['item'] = 'user'; $warning['item'] = 'user';
$warning['itemid'] = $user->id; $warning['itemid'] = $user->id;
$warning['warningcode'] = '2'; $warning['warningcode'] = '2';

View File

@@ -204,7 +204,7 @@ class message_output_email extends message_output {
* @return int The default settings * @return int The default settings
*/ */
public function get_default_messaging_settings() { public function get_default_messaging_settings() {
return MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF; return MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED;
} }
/** /**

View File

@@ -82,12 +82,11 @@ abstract class message_output {
/** /**
* Returns the message processors default settings * Returns the message processors default settings
* Should the processor be enabled for logged in users by default? * Should the processor be enabled in users by default?
* Should the processor be enabled for logged off users by default?
* Is enabling it disallowed, permitted or forced? * Is enabling it disallowed, permitted or forced?
* *
* @return int The Default message output settings expressed as a bit mask * @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() { public function get_default_messaging_settings() {
return MESSAGE_PERMITTED; return MESSAGE_PERMITTED;

View File

@@ -54,7 +54,6 @@ class core_message_renderer extends plugin_renderer_base {
$output .= $this->manage_messageoutputs($allprocessors); $output .= $this->manage_messageoutputs($allprocessors);
// Add active message output processors settings. // Add active message output processors settings.
$output .= $this->heading(get_string('managemessageoutputs', 'message'));
$output .= $this->manage_defaultmessageoutputs($processors, $providers, $preferences); $output .= $this->manage_defaultmessageoutputs($processors, $providers, $preferences);
$output .= html_writer::start_tag('div', array('class' => 'form-buttons')); $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'), get_string('settings'),
); );
$table->colclasses = array( $table->colclasses = array(
'displayname', 'availability', 'settings', 'displayname', 'availability text-center', 'settings',
); );
foreach ($processors as $processor) { foreach ($processors as $processor) {
@@ -124,97 +123,99 @@ class core_message_renderer extends plugin_renderer_base {
* @return string The text to render * @return string The text to render
*/ */
public function manage_defaultmessageoutputs($processors, $providers, $preferences) { public function manage_defaultmessageoutputs($processors, $providers, $preferences) {
// Prepare list of options for dropdown menu $context = [];
$options = array();
foreach (array('disallowed', 'permitted', 'forced') as $setting) {
$options[$setting] = get_string($setting, 'message');
}
// 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) { 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) { foreach ($providers as $provider) {
$row = new html_table_row(); $provider->displayname = get_string('messageprovider:'.$provider->name, $provider->component);
$row->attributes['class'] = 'defaultmessageoutputs';
$row->cells = array();
// Provider Name
$providername = get_string('messageprovider:'.$provider->name, $provider->component);
$row->cells[] = new html_table_cell($providername);
$providersettingprefix = $provider->component.'_'.$provider->name.'_'; $providersettingprefix = $provider->component.'_'.$provider->name.'_';
$disableprovidersetting = $providersettingprefix.'disable'; $provider->enabledsetting = $providersettingprefix.'disable';
$providerdisabled = !empty($preferences->$disableprovidersetting); $provider->enabled = empty($preferences->{$provider->enabledsetting});
$provider->enabledlabel = get_string('providerenabled', 'message', $provider->displayname);
$provider->settings = [];
// Settings for each processor // Settings for each processor
foreach ($processors as $processor) { foreach ($processors as $processor) {
$cellcontent = ''; $setting = new StdClass();
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) {
// pepare element and preference names $setting->lockedsetting = $providersettingprefix.'locked['.$processor->name.']';
$elementname = $providersettingprefix.$setting.'['.$processor->name.']'; $preference = $processor->name.'_provider_'.$providersettingprefix.'locked';
$preferencebase = $providersettingprefix.$setting;
// prepare language bits $setting->locked = false;
$processorname = get_string('pluginname', 'message_'.$processor->name); if (property_exists($preferences, $preference)) {
$statename = get_string($setting, 'message'); $setting->locked = $preferences->{$preference} == 1;
$labelparams = array( }
'provider' => $providername,
'processor' => $processorname, $setting->enabledsetting = $providersettingprefix.'enabled['.$processor->name.']';
'state' => $statename $preference = 'message_provider_'.$providersettingprefix.'enabled';
);
if ($setting == 'permitted') { $setting->enabled = false;
$label = get_string('sendingvia', 'message', $labelparams); if (property_exists($preferences, $preference)) {
// determine the current setting or use default $setting->enabled = (int)in_array($processor->name, explode(',', $preferences->{$preference}));
$select = MESSAGE_DEFAULT_PERMITTED; }
$preference = $processor->name.'_provider_'.$preferencebase; $labelparams = [
if ($providerdisabled) { 'provider' => $provider->displayname,
$select = MESSAGE_DISALLOWED; 'processor' => $processor->displayname,
} else if (property_exists($preferences, $preference)) { ];
$select = $preferences->{$preference}; $setting->enabledlabel = get_string('sendingviaenabled', 'message', $labelparams);
} $setting->lockedlabel = get_string('sendingvialocked', 'message', $labelparams);
// dropdown menu
$cellcontent = html_writer::label($label, $elementname, true, array('class' => 'accesshide')); $provider->settings[] = $setting;
$cellcontent .= html_writer::select($options, $elementname, $select, false, array('id' => $elementname)); }
$cellcontent .= html_writer::tag('div', get_string('defaults', 'message'));
} else { // Order the components so that the activities appear first, followed
$label = get_string('sendingviawhen', 'message', $labelparams); // by the system and then anything else.
// determine the current setting based on the 'permitted' setting above if ($provider->component != 'moodle') {
$checked = false; if (substr($provider->component, 0, 4) == 'mod_') {
if ($select == 'forced') { // Activities.
$checked = true; $activitycomponents[] = $provider->component;
} else if ($select == 'permitted') { } else {
$preference = 'message_provider_'.$preferencebase; // Other stuff.
if (property_exists($preferences, $preference)) { $othercomponents[] = $provider->component;
$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');
}
} }
$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); $activitycomponents = array_unique($activitycomponents);
return $output; 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);
} }
/** /**

View File

@@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@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"
}
]
}
]
}
]
}
}}
<div class="preferences-page-container">
<h2>{{#str}} managemessageoutputs, message {{/str}}</h2>
<div class="preferences-container">
<table class="table table-hover preference-table">
<thead>
<tr>
<th></th>
<th>{{#str}} enabled, core_message {{/str}}</th>
{{#processors}}
<th data-processor-name="{{name}}">{{{displayname}}}</th>
{{/processors}}
</tr>
</thead>
<tbody>
{{#components}}
<tr class="preference-row"><th colspan="{{{colspan}}}">{{{displayname}}}</th></tr>
{{#providers}}
<tr class="defaultmessageoutputs">
<td>{{{displayname}}}</td>
<td>
<div data-preference="{{{enabledsetting}}}">
<div class="custom-control custom-switch">
<input type="checkbox"
id="{{{enabledsetting}}}"
name="{{{enabledsetting}}}"
class="custom-control-input provider_enabled"
{{#enabled}}checked{{/enabled}}
>
<label for="{{{enabledsetting}}}" class="custom-control-label"
title="{{enabledlabel}}">
<span class="accesshide">{{enabledlabel}}</span>
</label>
</div>
</div>
</td>
{{#settings}}
<td class="text-left">
<div data-preference="{{{enabledsetting}}}">
<div class="custom-control custom-switch {{#locked}} dimmed_text{{/locked}} pb-1">
<input type="checkbox"
id="{{{enabledsetting}}}"
name="{{{enabledsetting}}}"
class="custom-control-input enabled_message_setting"
{{#enabled}}checked{{/enabled}}
>
<label for="{{{enabledsetting}}}" class="custom-control-label"
title="{{enabledlabel}}">
{{#str}} enabled, core_message {{/str}}
</label>
</div>
</div>
<div data-preference="{{{lockedsetting}}}">
<div class="custom-control custom-switch pt-1">
<input type="checkbox"
id="{{{lockedsetting}}}"
name="{{{lockedsetting}}}"
class="custom-control-input locked_message_setting"
{{#locked}}checked{{/locked}}
>
<label for="{{{lockedsetting}}}" class="custom-control-label"
title="{{lockedlabel}}">
{{#str}} forced, core_message {{/str}}
</label>
</div>
</div>
</td>
{{/settings}}
</tr>
{{/providers}}
{{/components}}
</tbody>
</table>
</div>
</div>
{{#js}}
require(['core_message/default_notification_preferences'], function(NotificationPreferences) {
NotificationPreferences.init();
});
{{/js}}

View File

@@ -41,26 +41,13 @@
{ {
"displayname": "Notices about minor problems", "displayname": "Notices about minor problems",
"preferencekey": "message_provider_moodle_notices", "preferencekey": "message_provider_moodle_notices",
"onlinehelphtml": "<p>some help HTML</p>",
"offlinehelphtml": "<p>some help HTML</p>",
"processors": [ "processors": [
{ {
"displayname": "Popup notification", "displayname": "Popup notification",
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 1
"name": "loggedin",
"displayname": "When I'm logged in",
"checked": 0,
"disableall": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0,
"disableall": 0
}
} }
] ]
} }

View File

@@ -34,26 +34,13 @@
{ {
"displayname": "Notices about minor problems", "displayname": "Notices about minor problems",
"preferencekey": "message_provider_moodle_notices", "preferencekey": "message_provider_moodle_notices",
"onlinehelphtml": "<p>some help HTML</p>",
"offlinehelphtml": "<p>some help HTML</p>",
"processors": [ "processors": [
{ {
"displayname": "Popup notification", "displayname": "Popup notification",
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 1
"name": "loggedin",
"displayname": "When I'm logged in",
"checked": 0,
"disableall": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0,
"disableall": 0
}
} }
] ]
} }
@@ -64,18 +51,7 @@
<tr data-preference-key="{{preferencekey}}"> <tr data-preference-key="{{preferencekey}}">
<th>{{displayname}}</th> <th>{{displayname}}</th>
<td class="align-bottom"> <td class="align-bottom">
<div class="container-fluid"> {{#str}} enabled, core_message {{/str}}
<div class="row">
<div class="span6 col-6">
{{#str}} loggedin, message {{/str}}
{{#onlinehelphtml}}{{{.}}}{{/onlinehelphtml}}
</div>
<div class="span6 col-6">
{{#str}} loggedoff, message {{/str}}
{{#offlinehelphtml}}{{{.}}}{{/offlinehelphtml}}
</div>
</div>
</div>
</td> </td>
</tr> </tr>
{{#processors}} {{#processors}}

View File

@@ -40,16 +40,7 @@
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 1
"name": "loggedin",
"displayname": "When I'm logged in",
"checked": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0
}
} }
] ]
} }

View File

@@ -34,15 +34,19 @@
{ {
"userid": 1, "userid": 1,
"disableall": 0, "disableall": 0,
"processors": [
{
"displayname": "Popup notification",
"name": "popup",
"hassettings": 1,
"userid": 3,
"contextid": 3
}
],
"components": [ "components": [
{ {
"displayname": "System", "displayname": "System",
"processors": [ "colspan": 2,
{
"onlinehelphtml": "<p>help button HTML</p>",
"offlinehelphtml": "<p>help button HTML</p>"
}
],
"notifications": [ "notifications": [
{ {
"displayname": "Notices about minor problems", "displayname": "Notices about minor problems",
@@ -53,18 +57,8 @@
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 1,
"name": "loggedin", "enabledlabel": "Sending Assignment enabled status"
"displayname": "When I'm logged in",
"checked": 0,
"disableall": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0,
"disableall": 0
}
} }
] ]
} }
@@ -87,7 +81,7 @@
<table class="table preference-table"> <table class="table preference-table">
<thead> <thead>
<tr> <tr>
<th>{{displayname}}</th> <th>{{{displayname}}}</th>
{{#processors}} {{#processors}}
{{> message/notification_preferences_processor }} {{> message/notification_preferences_processor }}
{{/processors}} {{/processors}}
@@ -103,8 +97,8 @@
</div> </div>
{{#js}} {{#js}}
require(['jquery', 'core_message/preferences_notifications_list_controller'], require(['jquery', 'core_message/preferences_notifications_list_controller'],
function($, controller) { function($, Controller) {
new controller($('.preferences-container')); new Controller($('.preferences-container'));
}); });
{{/js}} {{/js}}

View File

@@ -33,12 +33,7 @@
Example context (json): Example context (json):
{ {
"displayname": "System", "displayname": "System",
"processors": [ "colspan": 2,
{
"onlinehelphtml": "<p>help button HTML</p>",
"offlinehelphtml": "<p>help button HTML</p>"
}
],
"notifications": [ "notifications": [
{ {
"displayname": "Notices about minor problems", "displayname": "Notices about minor problems",
@@ -49,18 +44,8 @@
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 0,
"name": "loggedin", "enabledlabel": "Sending Assignment enabled status"
"displayname": "When I'm logged in",
"checked": 0,
"disableall": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0,
"disableall": 0
}
} }
] ]
} }
@@ -68,23 +53,7 @@
} }
}} }}
<tr> <tr>
<th><h4>{{displayname}}</h4></th> <th colspan="{{{colspan}}}">{{{displayname}}}</th>
{{#processors}}
<td class="align-bottom">
<div class="container-fluid">
<div class="row">
<div class="col-6">
{{#str}} loggedin, message {{/str}}
{{#onlinehelphtml}}{{{.}}}{{/onlinehelphtml}}
</div>
<div class="col-6">
{{#str}} loggedoff, message {{/str}}
{{#offlinehelphtml}}{{{.}}}{{/offlinehelphtml}}
</div>
</div>
</div>
</td>
{{/processors}}
</tr> </tr>
{{#notifications}} {{#notifications}}
{{> message/notification_preferences_component_notification }} {{> message/notification_preferences_component_notification }}

View File

@@ -40,70 +40,33 @@
"name": "popup", "name": "popup",
"locked": 0, "locked": 0,
"userconfigured": 1, "userconfigured": 1,
"loggedin": { "enabled": 1,
"name": "loggedin", "enabledlabel": "Sending Assignment enabled status"
"displayname": "When I'm logged in",
"checked": 0
},
"loggedoff": {
"name": "loggedoff",
"displayname": "When I'm offline",
"checked": 0
}
} }
] ]
} }
}} }}
<tr class="preference-row" data-region="preference-row" data-preference-key="{{preferencekey}}"> <tr class="preference-row" data-region="preference-row" data-preference-key="{{{preferencekey}}}">
<td class="preference-name">{{displayname}}</td> <td class="preference-name">{{{displayname}}}</td>
{{#processors}} {{#processors}}
<td {{^userconfigured}}class="disabled"{{/userconfigured}} data-processor-name="{{name}}"> <td {{^userconfigured}}class="disabled"{{/userconfigured}} data-processor-name="{{name}}">
{{#locked}} {{#locked}}
<div class="dimmed_text">{{lockedmessage}}</div> <div class="dimmed_text" title="{{lockedlabel}}">{{{lockedmessage}}}</div>
{{/locked}} {{/locked}}
{{^locked}} {{^locked}}
<div class="disabled-message">{{#str}} disabled, admin {{/str}}</div>
<form> <form>
<div class="container-fluid"> <div class="preference-state" data-preference="{{{preferencekey}}}_{{{name}}}">
<div class="row"> <div class="custom-control custom-switch">
<div class="col-6"> <input type="checkbox"
{{#loggedin}} id="{{{preferencekey}}}_{{{name}}}"
{{< core/hover_tooltip }} name="{{{preferencekey}}}_{{{name}}}"
{{$anchor}} class="custom-control-input notification_enabled"
<label class="custom-control custom-switch" {{#enabled}}checked{{/enabled}}
title="{{displayname}}" >
data-state="{{name}}"> <label for="{{{preferencekey}}}_{{{name}}}" class="custom-control-label"
<span class="accesshide">{{displayname}}</span> title="{{enabledlabel}}">
<input type="checkbox" {{#str}} enabled, core_message {{/str}}
class="custom-control-input" </label>
{{#checked}}checked{{/checked}}
{{#disableall}}disabled{{/disableall}} />
<span class="custom-control-label d-block"></span>
</label>
{{/anchor}}
{{$tooltip}}{{displayname}}{{/tooltip}}
{{/ core/hover_tooltip }}
{{/loggedin}}
</div>
<div class="col-6">
{{#loggedoff}}
{{< core/hover_tooltip }}
{{$anchor}}
<label class="custom-control custom-switch"
title="{{displayname}}"
data-state="{{name}}">
<span class="accesshide">{{displayname}}</span>
<input type="checkbox"
class="custom-control-input"
{{#checked}}checked{{/checked}}
{{#disableall}}disabled{{/disableall}} />
<span class="custom-control-label d-block"></span>
</label>
{{/anchor}}
{{$tooltip}}{{displayname}}{{/tooltip}}
{{/ core/hover_tooltip }}
{{/loggedoff}}
</div>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -27,7 +27,7 @@ $messageproviders = array (
// Ordinary single forum posts. // Ordinary single forum posts.
'posts' => array( 'posts' => array(
'defaults' => array( 'defaults' => array(
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
), ),

View File

@@ -28,11 +28,8 @@ $messageproviders = array (
// essay graded notification // essay graded notification
'graded_essay' => array ( 'graded_essay' => array (
'defaults' => array( 'defaults' => array(
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
) )
); );

View File

@@ -34,7 +34,7 @@ $messageproviders = array(
'confirmation' => array( 'confirmation' => array(
'capability' => 'mod/quiz:emailconfirmsubmission', 'capability' => 'mod/quiz:emailconfirmsubmission',
'defaults' => array( '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( 'attempt_overdue' => array(
'capability' => 'mod/quiz:emailwarnoverdue', 'capability' => 'mod/quiz:emailwarnoverdue',
'defaults' => array( 'defaults' => array(
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
), ),
), ),
'attempt_grading_complete' => [ 'attempt_grading_complete' => [
'capability' => 'mod/quiz:emailnotifyattemptgraded', 'capability' => 'mod/quiz:emailnotifyattemptgraded',
'defaults' => [ 'defaults' => [
'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_LOGGEDIN + MESSAGE_DEFAULT_LOGGEDOFF, 'airnotifier' => MESSAGE_PERMITTED + MESSAGE_DEFAULT_ENABLED,
], ],
], ],
); );