Skip to content

Commit c34feaf

Browse files
committed
Improve usability of defining recipients for update notifications
1 parent b52b408 commit c34feaf

File tree

5 files changed

+76
-92
lines changed

5 files changed

+76
-92
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
UPDATE #__scheduler_task
2+
SET params = JSON_REMOVE(params, '$.email')
3+
WHERE JSON_CONTAINS_PATH(params, 'one', '$.email');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
UPDATE #__scheduler_task
2+
SET params = params - 'email'
3+
WHERE params ? 'email';

administrator/language/en-GB/plg_task_updatenotification.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
; Note : All ini files need to be saved as UTF-8
55

66
PLG_TASK_UPDATENOTIFICATION="Task - Joomla! Update Notification"
7-
PLG_TASK_UPDATENOTIFICATION_EMAIL_DESC="A comma separated list of the email addresses which will receive the update notification emails. The addresses in the list MUST belong to existing users of your site who have the Super User privilege. If none of the listed emails belongs to Super Users, or if it's left blank, all Super Users of this site will receive the update notification email."
8-
PLG_TASK_UPDATENOTIFICATION_EMAIL_LBL="Super User Emails"
7+
PLG_TASK_UPDATENOTIFICATION_EMAIL_DESC="All Super Users and all users in the selected groups will receive the emails if they have the receive system emails option enabled in their user profile."
8+
PLG_TASK_UPDATENOTIFICATION_EMAIL_LBL="Send Email to User Groups"
99
PLG_TASK_UPDATENOTIFICATION_SEND_TITLE="Joomla! Update Notification"
1010
PLG_TASK_UPDATENOTIFICATION_SEND_DESC="This task periodically checks for the availability of new Joomla! versions. When one is found it will send you an email, reminding you to update. You can customise the email at <a href=\"index.php?option=com_mails&view=templates&filter[extension]=plg_task_updatenotification\">System &rarr; Mail Templates.</a>"
1111
PLG_TASK_UPDATENOTIFICATION_LANGUAGE_OVERRIDE_DESC="Select a language for the update notification emails. Set to Auto to send them in the site language at the time."

plugins/task/updatenotification/forms/sendForm.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
<fieldset name="task_params">
55
<field
66
name="email"
7-
type="text"
7+
type="usergrouplist"
88
label="PLG_TASK_UPDATENOTIFICATION_EMAIL_LBL"
99
description="PLG_TASK_UPDATENOTIFICATION_EMAIL_DESC"
10-
default=""
10+
multiple="true"
11+
checksuperusergroup="0"
12+
layout="joomla.form.field.list-fancy-select"
1113
/>
1214
<field
1315
name="language_override"

plugins/task/updatenotification/src/Extension/UpdateNotification.php

Lines changed: 64 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
use Joomla\CMS\Access\Access;
1414
use Joomla\CMS\Component\ComponentHelper;
1515
use Joomla\CMS\Extension\ExtensionHelper;
16+
use Joomla\CMS\Factory;
17+
use Joomla\CMS\Helper\UserGroupsHelper;
1618
use Joomla\CMS\Mail\Exception\MailDisabledException;
19+
use Joomla\CMS\Mail\MailHelper;
1720
use Joomla\CMS\Mail\MailTemplate;
1821
use Joomla\CMS\Plugin\CMSPlugin;
19-
use Joomla\CMS\Table\Table;
2022
use Joomla\CMS\Updater\Updater;
2123
use Joomla\CMS\Uri\Uri;
2224
use Joomla\CMS\Version;
@@ -25,7 +27,6 @@
2527
use Joomla\Component\Scheduler\Administrator\Task\Status;
2628
use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait;
2729
use Joomla\Database\DatabaseAwareTrait;
28-
use Joomla\Database\ParameterType;
2930
use Joomla\Event\SubscriberInterface;
3031
use PHPMailer\PHPMailer\Exception as phpMailerException;
3132

@@ -90,11 +91,8 @@ public static function getSubscribedEvents(): array
9091
*/
9192
private function sendNotification(ExecuteTaskEvent $event): int
9293
{
93-
// Load the parameters.
94-
$specificEmail = $event->getArgument('params')->email ?? '';
9594
$forcedLanguage = $event->getArgument('params')->language_override ?? '';
96-
97-
$updateParams = ComponentHelper::getParams('com_joomlaupdate');
95+
$updateParams = ComponentHelper::getParams('com_joomlaupdate');
9896

9997
// Don't send when automated updates are active and working
10098
$registrationState = AutoupdateRegisterState::tryFrom($updateParams->get('autoupdate_status', ''));
@@ -135,7 +133,6 @@ private function sendNotification(ExecuteTaskEvent $event): int
135133
if (version_compare($update->version, JVERSION, 'le')) {
136134
return Status::OK;
137135
}
138-
139136
// If we're here, we have updates. First, get a link to the Joomla! Update component.
140137
$baseURL = Uri::base();
141138
$baseURL = rtrim($baseURL, '/');
@@ -158,17 +155,9 @@ private function sendNotification(ExecuteTaskEvent $event): int
158155
$this->getApplication()->triggerEvent('onBuildAdministratorLoginURL', [&$uri]);
159156

160157
// Let's find out the email addresses to notify
161-
$superUsers = [];
162-
163-
if (!empty($specificEmail)) {
164-
$superUsers = $this->getSuperUsers($specificEmail);
165-
}
166-
167-
if (empty($superUsers)) {
168-
$superUsers = $this->getSuperUsers();
169-
}
158+
$emailReceivers = $this->getEmailReceivers();
170159

171-
if (empty($superUsers)) {
160+
if (empty($emailReceivers)) {
172161
return Status::KNOCKOUT;
173162
}
174163

@@ -205,11 +194,11 @@ private function sendNotification(ExecuteTaskEvent $event): int
205194
'releasenews' => 'https://www.joomla.org/announcements/release-news/',
206195
];
207196

208-
// Send the emails to the Super Users
209-
foreach ($superUsers as $superUser) {
197+
// Send the emails
198+
foreach ($emailReceivers as $receiver) {
210199
try {
211200
$mailer = new MailTemplate('plg_task_updatenotification.mail', $jLanguage->getTag());
212-
$mailer->addRecipient($superUser->email);
201+
$mailer->addRecipient($receiver->email);
213202
$mailer->addTemplateData($substitutions);
214203
$mailer->send();
215204
} catch (MailDisabledException | phpMailerException $exception) {
@@ -227,95 +216,82 @@ private function sendNotification(ExecuteTaskEvent $event): int
227216
}
228217

229218
/**
230-
* Returns the Super Users email information. If you provide a comma separated $email list
231-
* we will check that these emails do belong to Super Users and that they have not blocked
232-
* system emails.
233-
*
234-
* @param null|string $email A list of Super Users to email
219+
* Returns all Email recipients: super users and the users of email receiver groups
235220
*
236-
* @return array The list of Super User emails
221+
* @return array The list of email recipients
237222
*
238-
* @since 3.5
223+
* @since __DEPLOY_VERSION__
239224
*/
240-
private function getSuperUsers($email = null)
225+
private function getEmailReceivers(): array
241226
{
242-
$db = $this->getDatabase();
243-
$emails = [];
227+
$emailReceivers = [];
244228

245-
// Convert the email list to an array
246-
if (!empty($email)) {
247-
$temp = explode(',', $email);
229+
// Find all user groups
230+
$groups = UserGroupsHelper::getInstance()->getAll();
248231

249-
foreach ($temp as $entry) {
250-
$emails[] = trim($entry);
251-
}
252-
253-
$emails = array_unique($emails);
232+
if (empty($groups)) {
233+
return [];
254234
}
255235

256-
// Get a list of groups which have Super User privileges
257-
$ret = [];
258-
259-
try {
260-
$rootId = Table::getInstance('Asset')->getRootId();
261-
$rules = Access::getAssetRules($rootId)->getData();
262-
$rawGroups = $rules['core.admin']->getData();
263-
$groups = [];
236+
// Find groups with core.admin rights (super users)
237+
$superUserGroups = [];
264238

265-
if (empty($rawGroups)) {
266-
return $ret;
239+
foreach ($groups as $group) {
240+
if (Access::checkGroup($group->id, 'core.admin')) {
241+
$superUserGroups[] = $group->id;
267242
}
243+
}
268244

269-
foreach ($rawGroups as $g => $enabled) {
270-
if ($enabled) {
271-
$groups[] = $g;
272-
}
273-
}
245+
// Get User group ids from input field
246+
$params = ComponentHelper::getParams('com_joomlaupdate');
247+
$emailGroups = $params->get('email_groups');
274248

275-
if (empty($groups)) {
276-
return $ret;
249+
if (!empty($emailGroups)) {
250+
if (!is_array($emailGroups)) {
251+
$emailGroups = ArrayHelper::toInteger(explode(',', $emailGroups));
277252
}
278-
} catch (\Exception $exc) {
279-
return $ret;
253+
} else {
254+
$emailGroups = [];
280255
}
281256

282-
// Get the user IDs of users belonging to the SA groups
283-
try {
284-
$query = $db->getQuery(true)
285-
->select($db->quoteName('user_id'))
286-
->from($db->quoteName('#__user_usergroup_map'))
287-
->whereIn($db->quoteName('group_id'), $groups);
257+
// Make a list of email groups, including Super User Groups
258+
$emailGroups = \array_unique(\array_merge($emailGroups, $superUserGroups));
288259

289-
$db->setQuery($query);
290-
$userIDs = $db->loadColumn(0);
260+
// Get the users of all groups in the emailGroups
261+
$usersModel = Factory::getApplication()->bootComponent('com_users')
262+
->getMVCFactory()->createModel('Users', 'Administrator');
291263

292-
if (empty($userIDs)) {
293-
return $ret;
294-
}
295-
} catch (\Exception $exc) {
296-
return $ret;
264+
$usersModel->setState('filter.groups', $emailGroups);
265+
$usersModel->setState('filter.block', (int) 0);
266+
267+
$usersInGroup = $usersModel->getItems();
268+
269+
// This cannot happen, as at least one super user must exist, but better safe than sorry
270+
if (empty($usersInGroup)) {
271+
return [];
297272
}
298273

299-
// Get the user information for the Super Administrator users
300-
try {
301-
$query = $db->getQuery(true)
302-
->select($db->quoteName(['id', 'username', 'email']))
303-
->from($db->quoteName('#__users'))
304-
->whereIn($db->quoteName('id'), $userIDs)
305-
->where($db->quoteName('block') . ' = 0')
306-
->where($db->quoteName('sendEmail') . ' = 1');
307-
308-
if (!empty($emails)) {
309-
$lowerCaseEmails = array_map('strtolower', $emails);
310-
$query->whereIn('LOWER(' . $db->quoteName('email') . ')', $lowerCaseEmails, ParameterType::STRING);
311-
}
274+
// Only users with valid email address who are not blocked can receive the email
275+
foreach ($usersInGroup as $user) {
276+
if (MailHelper::isEmailAddress($user->email) && $user->sendEmail === 1) {
277+
$user->email = strtolower(trim($user->email));
278+
279+
// Check if the email already exists in the emailReceivers array
280+
$exist = false;
281+
foreach ($emailReceivers as $rec) {
282+
if ($rec->email === $user->email) {
283+
$exist = true;
284+
break;
285+
}
286+
}
312287

313-
$db->setQuery($query);
314-
$ret = $db->loadObjectList();
315-
} catch (\Exception) {
316-
return $ret;
288+
// Add to the list if it is not already in the list
289+
if (!$exist) {
290+
$emailReceivers[] = $user;
291+
}
292+
}
317293
}
318294

319-
return $ret;
295+
return $emailReceivers;
320296
}
321297
}

0 commit comments

Comments
 (0)