Skip to content

Commit

Permalink
[5.3] fine grain task notification mail (#44604)
Browse files Browse the repository at this point in the history
Co-authored-by: Richard Fath <richard67@users.noreply.github.com>
alikon and richard67 authored Feb 28, 2025

Verified

This commit was signed with the committer’s verified signature.
dgrammatiko Dimitris Grammatikogiannis
1 parent 1bc1e8f commit eb65310
Showing 3 changed files with 86 additions and 32 deletions.
4 changes: 4 additions & 0 deletions administrator/language/en-GB/plg_system_tasknotification.ini
Original file line number Diff line number Diff line change
@@ -6,16 +6,20 @@
PLG_SYSTEM_TASK_NOTIFICATION="System - Task Notification"
PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_BODY="Hello,\n\n\nPlanned execution of Scheduled Task#{TASK_ID}, {TASK_TITLE}, has failed with exit code {EXIT_CODE} at {EXEC_DATE_TIME}.\n\nPlease visit the Joomla! backend for more information.\n\n{TASK_OUTPUT}"
PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_MAIL_SUBJECT="Task Failure"
PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_USERGROUP_LABEL="User Groups to Notify"
PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_BODY="Hello,\n\nPlanned execution of Scheduler Task#{TASK_ID}, {TASK_TITLE}, recovered from a fatal failure.\n\nThis could mean that the task execution exhausted the system resources or the restrictions from the PHP INI.\n\nPlease visit the Joomla! backend for more information."
PLG_SYSTEM_TASK_NOTIFICATION_FATAL_MAIL_SUBJECT="Task Recover from Fatal Failure"
PLG_SYSTEM_TASK_NOTIFICATION_FATAL_USERGROUP_LABEL="User Groups to Notify"
PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FAILURE_MAIL_TOGGLE="Task Failure"
PLG_SYSTEM_TASK_NOTIFICATION_LABEL_FATAL_FAILURE_MAIL_TOGGLE="Fatal Failures/Crashes (Recommended)"
PLG_SYSTEM_TASK_NOTIFICATION_LABEL_ORPHANED_TASK_MAIL_TOGGLE="Orphaned Tasks (Recommended)"
PLG_SYSTEM_TASK_NOTIFICATION_LABEL_SUCCESS_MAIL_TOGGLE="Task Success"
PLG_SYSTEM_TASK_NOTIFICATION_NO_MAIL_SENT="Could not send task notification to any user. This either means that mailer is not set up properly or no user with system emails enabled, com_scheduler `core.manage` privilege exists."
PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_BODY="Hello,\n\nScheduled Task#{TASK_ID}, {TASK_TITLE}, has been orphaned. This likely means that the provider plugin was removed or disabled from your Joomla! installation.\n\nPlease visit the Joomla! backend to investigate."
PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_MAIL_SUBJECT="New Orphaned Task"
PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_USERGROUP_LABEL="User Groups to Notify"
PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_BODY="Hello,\n\nScheduled Task#{TASK_ID}, {TASK_TITLE}, has been successfully executed at {EXEC_DATE_TIME}.\n\n{TASK_OUTPUT}"
PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_MAIL_SUBJECT="Task Successful"
PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_USERGROUP_LABEL="User Groups to Notify"
PLG_SYSTEM_TASK_NOTIFICATION_USER_FETCH_FAIL="Failed to fetch users to send notifications to."
PLG_SYSTEM_TASK_NOTIFICATION_XML_DESCRIPTION="Responsible for email notifications for execution of Scheduled tasks."
44 changes: 44 additions & 0 deletions plugins/system/tasknotification/forms/task_notification.xml
Original file line number Diff line number Diff line change
@@ -13,6 +13,17 @@
<option value="0">JDISABLED</option>
<option value="1">JENABLED</option>
</field>
<field
name="notification_success_groups"
type="usergrouplist"
label="PLG_SYSTEM_TASK_NOTIFICATION_SUCCESS_USERGROUP_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
checksuperusergroup="0"
default="8"
showon="success_mail:1"
>
</field>
<field
name="failure_mail"
type="radio"
@@ -23,6 +34,17 @@
<option value="0">JDISABLED</option>
<option value="1">JENABLED</option>
</field>
<field
name="notification_failure_groups"
type="usergrouplist"
label="PLG_SYSTEM_TASK_NOTIFICATION_FAILURE_USERGROUP_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
checksuperusergroup="0"
default="8"
showon="failure_mail:1"
>
</field>
<field
name="fatal_failure_mail"
type="radio"
@@ -33,6 +55,17 @@
<option value="0">JDISABLED</option>
<option value="1">JENABLED</option>
</field>
<field
name="notification_fatal_groups"
type="usergrouplist"
label="PLG_SYSTEM_TASK_NOTIFICATION_FATAL_USERGROUP_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
checksuperusergroup="0"
default="8"
showon="fatal_failure_mail:1"
>
</field>
<field
name="orphan_mail"
type="radio"
@@ -43,6 +76,17 @@
<option value="0">JDISABLED</option>
<option value="1">JENABLED</option>
</field>
<field
name="notification_orphan_groups"
type="usergrouplist"
label="PLG_SYSTEM_TASK_NOTIFICATION_ORPHAN_USERGROUP_LABEL"
multiple="true"
layout="joomla.form.field.list-fancy-select"
checksuperusergroup="0"
default="8"
showon="orphan_mail:1"
>
</field>
</fieldset>
</fields>
</fields>
70 changes: 38 additions & 32 deletions plugins/system/tasknotification/src/Extension/TaskNotification.php
Original file line number Diff line number Diff line change
@@ -134,10 +134,11 @@ public function notifyFailure(Event $event): void

// Load translations
$this->loadLanguage();
$groups = $task->get('params.notifications.notification_failure_groups');

// @todo safety checks, multiple files [?]
$outFile = $event->getArgument('subject')->snapshot['output_file'] ?? '';
$this->sendMail('plg_system_tasknotification.failure_mail', $data, $outFile);
$this->sendMail('plg_system_tasknotification.failure_mail', $data, $outFile, $groups);
}

/**
@@ -163,9 +164,10 @@ public function notifyOrphan(Event $event): void

// Load translations
$this->loadLanguage();
$groups = $task->get('params.notifications.notification_orphan_groups');

$data = $this->getDataFromTask($event->getArgument('subject'));
$this->sendMail('plg_system_tasknotification.orphan_mail', $data);
$this->sendMail('plg_system_tasknotification.orphan_mail', $data, '', $groups);
}

/**
@@ -191,10 +193,11 @@ public function notifySuccess(Event $event): void

// Load translations
$this->loadLanguage();
$groups = $task->get('params.notifications.notification_success_groups');

// @todo safety checks, multiple files [?]
$outFile = $event->getArgument('subject')->snapshot['output_file'] ?? '';
$this->sendMail('plg_system_tasknotification.success_mail', $data, $outFile);
$this->sendMail('plg_system_tasknotification.success_mail', $data, $outFile, $groups);
}

/**
@@ -204,7 +207,7 @@ public function notifySuccess(Event $event): void
*
* @return void
*
* @since 5.3.0
* @since __DEPLOY_VERSION__
* @throws \Exception
*/
public function notifyWillResume(Event $event): void
@@ -236,8 +239,12 @@ public function notifyFatalRecovery(Event $event): void
return;
}

// Load translations
$this->loadLanguage();
$groups = $task->get('params.notifications.notification_fatal_groups');

$data = $this->getDataFromTask($event->getArgument('subject'));
$this->sendMail('plg_system_tasknotification.fatal_recovery_mail', $data);
$this->sendMail('plg_system_tasknotification.fatal_recovery_mail', $data, '', $groups);
}

/**
@@ -267,24 +274,27 @@ private function getDataFromTask(Task $task): array
* @param string $template The mail template.
* @param array $data The data to bind to the mail template.
* @param string $attachment The attachment to send with the mail (@todo multiple)
* @param array $groups The user groups to notify.
*
* @return void
*
* @since 4.1.0
* @throws \Exception
*/
private function sendMail(string $template, array $data, string $attachment = ''): void
private function sendMail(string $template, array $data, string $attachment = '', array $groups = []): void
{
$app = $this->getApplication();
$db = $this->getDatabase();

// Get all users who are not blocked and have opted in for system mails.
$query = $db->getQuery(true);

$query->select($db->quoteName(['name', 'email', 'sendEmail', 'id']))
->from($db->quoteName('#__users'))
->where($db->quoteName('sendEmail') . ' = 1')
->where($db->quoteName('block') . ' = 0');
$query->select('DISTINCT ' . $db->quoteName('u.id') . ', ' . $db->quoteName('u.email'))
->from($db->quoteName('#__users', 'u'))
->join('LEFT', $db->quoteName('#__user_usergroup_map', 'g') . ' ON ' . $db->quoteName('g.user_id') . ' = ' . $db->quoteName('u.id'))
->where($db->quoteName('u.sendEmail') . ' = 1')
->where($db->quoteName('u.block') . ' = 0')
->whereIn($db->quoteName('g.group_id'), $groups);

$db->setQuery($query);

@@ -302,30 +312,26 @@ private function sendMail(string $template, array $data, string $attachment = ''

$mailSent = false;

// Mail all matching users who also have the `core.manage` privilege for com_scheduler.
// Mail all matching users.
foreach ($users as $user) {
$user = $this->getUserFactory()->loadUserById($user->id);

if ($user->authorise('core.manage', 'com_scheduler')) {
try {
$mailer = new MailTemplate($template, $app->getLanguage()->getTag());
$mailer->addTemplateData($data);
$mailer->addRecipient($user->email);

if (
!empty($attachment)
&& is_file($attachment)
) {
// @todo we allow multiple files [?]
$attachName = pathinfo($attachment, PATHINFO_BASENAME);
$mailer->addAttachment($attachName, $attachment);
}

$mailer->send();
$mailSent = true;
} catch (MailerException) {
Log::add($this->getApplication()->getLanguage()->_('PLG_SYSTEM_TASK_NOTIFICATION_NOTIFY_SEND_EMAIL_FAIL'), Log::ERROR);
try {
$mailer = new MailTemplate($template, $app->getLanguage()->getTag());
$mailer->addTemplateData($data);
$mailer->addRecipient($user->email);

if (
!empty($attachment)
&& is_file($attachment)
) {
// @todo we allow multiple files [?]
$attachName = pathinfo($attachment, PATHINFO_BASENAME);
$mailer->addAttachment($attachName, $attachment);
}

$mailer->send();
$mailSent = true;
} catch (MailerException) {
Log::add($this->getApplication()->getLanguage()->_('PLG_SYSTEM_TASK_NOTIFICATION_NOTIFY_SEND_EMAIL_FAIL'), Log::ERROR);
}
}

0 comments on commit eb65310

Please sign in to comment.