Skip to content

Commit 1223b9f

Browse files
chmstbrianteemanmuhmerichard67
authored
[5.4] Autoupdate email groups (joomla#45721)
--------- Co-authored-by: Brian Teeman <[email protected]> Co-authored-by: Heiko Lübbe <[email protected]> Co-authored-by: Richard Fath <[email protected]>
1 parent 8dcff52 commit 1223b9f

File tree

3 files changed

+75
-81
lines changed

3 files changed

+75
-81
lines changed

administrator/components/com_joomlaupdate/config.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,15 @@
121121
class="alert alert-info w-100"
122122
showon="updatesource!:default[OR]minimum_stability!:4"
123123
/>
124+
<field
125+
name="automated_updates_email_groups"
126+
type="usergrouplist"
127+
label="COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_UPDATE_EMAIL_LABEL"
128+
description="COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_UPDATE_EMAIL_DESCRIPTION"
129+
checksuperusergroup="0"
130+
multiple="true"
131+
layout="joomla.form.field.list-fancy-select"
132+
showon="updatesource:default[AND]minimum_stability:4[AND]autoupdate:1"
133+
/>
124134
</fieldset>
125135
</config>

administrator/components/com_joomlaupdate/src/Model/NotificationModel.php

Lines changed: 63 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
use Joomla\CMS\Access\Access;
1414
use Joomla\CMS\Component\ComponentHelper;
1515
use Joomla\CMS\Factory;
16+
use Joomla\CMS\Helper\UserGroupsHelper;
1617
use Joomla\CMS\Mail\MailHelper;
1718
use Joomla\CMS\Mail\MailTemplate;
1819
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
19-
use Joomla\CMS\Table\Asset;
2020
use Joomla\CMS\Uri\Uri;
2121
use Joomla\CMS\Version;
22-
use Joomla\Database\ParameterType;
2322
use Joomla\Registry\Registry;
23+
use Joomla\Utilities\ArrayHelper;
2424

2525
// phpcs:disable PSR1.Files.SideEffects
2626
\defined('_JEXEC') or die;
@@ -49,11 +49,26 @@ public function sendNotification($type, $oldVersion, $newVersion): void
4949
{
5050
$params = ComponentHelper::getParams('com_joomlaupdate');
5151

52-
// Send a notification to all super users
53-
$superUsers = $this->getSuperUsers();
52+
// Superusergroups as fallback
53+
$superUserGroups = $this->getSuperUserGroups();
5454

55-
if (empty($superUsers)) {
56-
throw new \RuntimeException();
55+
if (!\is_array($superUserGroups)) {
56+
$emailGroups = ArrayHelper::toInteger(explode(',', $superUserGroups));
57+
}
58+
59+
// User groups from input field
60+
$emailGroups = $params->get('automated_updates_email_groups', $superUserGroups, 'array');
61+
62+
if (!\is_array($emailGroups)) {
63+
$emailGroups = ArrayHelper::toInteger(explode(',', $emailGroups));
64+
}
65+
66+
// Get all users in these groups who can receive emails
67+
$emailReceivers = $this->getEmailReceivers($emailGroups);
68+
69+
// If no email receivers are found, we use superusergroups as fallback
70+
if (empty($emailReceivers)) {
71+
$emailReceivers = $this->getEmailReceivers($superUserGroups);
5772
}
5873

5974
$app = Factory::getApplication();
@@ -67,110 +82,77 @@ public function sendNotification($type, $oldVersion, $newVersion): void
6782
'url' => Uri::root(),
6883
];
6984

70-
// Send the emails to the Super Users
71-
foreach ($superUsers as $superUser) {
72-
$params = new Registry($superUser->params);
85+
// Send emails to all receivers
86+
foreach ($emailReceivers as $receiver) {
87+
$params = new Registry($receiver->params);
7388
$jLanguage->load('com_joomlaupdate', JPATH_ADMINISTRATOR, 'en-GB', true, true);
7489
$jLanguage->load('com_joomlaupdate', JPATH_ADMINISTRATOR, $params->get('admin_language', null), true, true);
7590

7691
$mailer = new MailTemplate('com_joomlaupdate.update.' . $type, $jLanguage->getTag());
77-
$mailer->addRecipient($superUser->email);
92+
$mailer->addRecipient($receiver->email);
7893
$mailer->addTemplateData($substitutions);
7994
$mailer->send();
8095
}
8196
}
8297

8398
/**
84-
* Returns the Super Users email information. If you provide a comma separated $email list
85-
* we will check that these emails do belong to Super Users and that they have not blocked
86-
* system emails.
99+
* Returns the email information of receivers. Receiver can be any user who is not disabled.
87100
*
88-
* @param null|string $email A list of Super Users to email
101+
* @param array $emailGroups A list of usergroups to email
89102
*
90-
* @return array The list of Super User emails
103+
* @return array The list of email receivers. Can be empty if no users are found.
91104
*
92105
* @since 5.4.0
93106
*/
94-
private function getSuperUsers($email = null): array
107+
private function getEmailReceivers($emailGroups): array
95108
{
96-
$db = $this->getDatabase();
97-
$emails = [];
98-
99-
// Convert the email list to an array
100-
if (!empty($email)) {
101-
$temp = explode(',', $email);
102-
103-
foreach ($temp as $entry) {
104-
if (!MailHelper::isEmailAddress(trim($entry))) {
105-
continue;
106-
}
107-
108-
$emails[] = trim($entry);
109-
}
110-
111-
$emails = array_unique($emails);
109+
if (empty($emailGroups)) {
110+
return [];
112111
}
113112

114-
// Get a list of groups which have Super User privileges
115-
$ret = [];
113+
$emailReceivers = [];
116114

117-
try {
118-
$rootId = (new Asset($db))->getRootId();
119-
$rules = Access::getAssetRules($rootId)->getData();
120-
$rawGroups = $rules['core.admin']->getData();
121-
$groups = [];
115+
// Get the users of all groups in the emailGroups
116+
$usersModel = Factory::getApplication()->bootComponent('com_users')
117+
->getMVCFactory()->createModel('Users', 'Administrator');
118+
$usersModel->setState('filter.state', (int) 0); // Only enabled users
122119

123-
if (empty($rawGroups)) {
124-
return $ret;
125-
}
120+
foreach ($emailGroups as $group) {
121+
$usersModel->setState('filter.group_id', $group);
126122

127-
foreach ($rawGroups as $g => $enabled) {
128-
if ($enabled) {
129-
$groups[] = $g;
130-
}
123+
$usersInGroup = $usersModel->getItems();
124+
if (empty($usersInGroup)) {
125+
continue;
131126
}
132127

133-
if (empty($groups)) {
134-
return $ret;
128+
// Users can be in more than one group. Accept only one entry
129+
foreach ($usersInGroup as $user) {
130+
if (MailHelper::isEmailAddress($user->email) && $user->sendEmail === 1) {
131+
$emailReceivers[$user->id] ??= $user;
132+
}
135133
}
136-
} catch (\Exception $exc) {
137-
return $ret;
138134
}
139135

140-
// Get the user IDs of users belonging to the SA groups
141-
try {
142-
$query = $db->getQuery(true)
143-
->select($db->quoteName('user_id'))
144-
->from($db->quoteName('#__user_usergroup_map'))
145-
->whereIn($db->quoteName('group_id'), $groups);
146-
147-
$db->setQuery($query);
148-
$userIDs = $db->loadColumn(0);
136+
return $emailReceivers;
137+
}
149138

150-
if (empty($userIDs)) {
151-
return $ret;
152-
}
153-
} catch (\Exception $exc) {
154-
return $ret;
155-
}
139+
/**
140+
* Returns all Super Users
141+
*
142+
* @return array The list of super user groups.
143+
*
144+
* @since 5.4.0
145+
*/
146+
private function getSuperUserGroups(): array
147+
{
148+
$groups = UserGroupsHelper::getInstance()->getAll();
149+
$ret = [];
156150

157-
// Get the user information for the Super Administrator users
158-
try {
159-
$query = $db->getQuery(true)
160-
->select($db->quoteName(['id', 'username', 'email', 'params']))
161-
->from($db->quoteName('#__users'))
162-
->whereIn($db->quoteName('id'), $userIDs)
163-
->where($db->quoteName('block') . ' = 0')
164-
->where($db->quoteName('sendEmail') . ' = 1');
165-
166-
if (!empty($emails)) {
167-
$lowerCaseEmails = array_map('strtolower', $emails);
168-
$query->whereIn('LOWER(' . $db->quoteName('email') . ')', $lowerCaseEmails, ParameterType::STRING);
151+
// Find groups with core.admin rights (super users)
152+
foreach ($groups as $group) {
153+
if (Access::checkGroup($group->id, 'core.admin')) {
154+
$ret[] = $group->id;
169155
}
170-
171-
$ret = $db->setQuery($query)->loadObjectList();
172-
} catch (\Exception) {
173-
return $ret;
174156
}
175157

176158
return $ret;

administrator/language/en-GB/com_joomlaupdate.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ COM_JOOMLAUPDATE_CONFIG_AUTOMATED_UPDATES_DISABLED_LABEL="<span class=\"fa-fw me
1616
COM_JOOMLAUPDATE_CONFIG_AUTOMATED_UPDATES_LABEL="Automated Updates"
1717
COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_DESC="Automatically update Joomla to the latest version when it is available."
1818
COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_LABEL="Automated Update"
19+
COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_UPDATE_EMAIL_DESCRIPTION="All users in the selected groups will receive the emails. If no users are found, the emails are sent to all Super Users. Recipients MUST have the Receive System Emails option enabled."
20+
COM_JOOMLAUPDATE_CONFIG_AUTOUPDATE_UPDATE_EMAIL_LABEL="Send Email to User Groups"
1921
COM_JOOMLAUPDATE_CONFIG_BACKUPCHECK_DESC="Shows the checkbox to confirm you have taken a backup and you're ready to update in the final step before the update is actually applied."
2022
COM_JOOMLAUPDATE_CONFIG_BACKUPCHECK_LABEL="Confirm Backup Checkbox"
2123
COM_JOOMLAUPDATE_CONFIG_CUSTOMURL_LABEL="Custom URL"

0 commit comments

Comments
 (0)