Files
Cloud-CMS/lib/XTR/EmailNotificationsTask.php
Matt Batchelder 05ce0da296 Initial Upload
2025-12-02 10:32:59 -05:00

208 lines
7.0 KiB
PHP

<?php
/*
* Copyright (C) 2025 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Xibo\XTR;
use Carbon\Carbon;
use Slim\Views\Twig;
use Xibo\Entity\UserNotification;
use Xibo\Factory\UserGroupFactory;
use Xibo\Factory\UserNotificationFactory;
/**
* Class EmailNotificationsTask
* @package Xibo\XTR
*/
class EmailNotificationsTask implements TaskInterface
{
use TaskTrait;
/** @var Twig */
private $view;
/** @var UserNotificationFactory */
private $userNotificationFactory;
/** @var UserGroupFactory */
private $userGroupFactory;
/** @inheritdoc */
public function setFactories($container)
{
$this->view = $container->get('view');
$this->userNotificationFactory = $container->get('userNotificationFactory');
$this->userGroupFactory = $container->get('userGroupFactory');
return $this;
}
/** @inheritdoc */
public function run()
{
$this->runMessage = '# ' . __('Email Notifications') . PHP_EOL . PHP_EOL;
$this->processQueue();
}
/** Process Queue of emails
* @throws \PHPMailer\PHPMailer\Exception
*/
private function processQueue()
{
// Handle queue of notifications to email.
$this->runMessage .= '## ' . __('Email Notifications') . PHP_EOL;
$msgFrom = $this->config->getSetting('mail_from');
$msgFromName = $this->config->getSetting('mail_from_name');
$processedNotifications = [];
$this->log->debug('Notification Queue sending from ' . $msgFrom);
foreach ($this->userNotificationFactory->getEmailQueue() as $notification) {
$this->log->debug('Notification found: ' . $notification->notificationId);
if (!empty($notification->email) || $notification->isSystem == 1) {
$mail = new \PHPMailer\PHPMailer\PHPMailer();
$this->log->debug('Sending Notification email to ' . $notification->email);
if ($this->checkEmailPreferences($notification)) {
$mail->addAddress($notification->email);
}
// System notifications, add mail_to to addresses if set.
if ($notification->isSystem == 1) {
// We should send the system notification to:
// - all assigned users
// - the mail_to (if set)
$mailTo = $this->config->getSetting('mail_to');
// Make sure we've been able to resolve an address.
if (empty($notification->email) && empty($mailTo)) {
$this->log->error('Discarding NotificationId ' . $notification->notificationId
. ' as no email address could be resolved.');
continue;
}
// if mail_to is set and is different from user email, and we did not
// process this notification yet (the same notificationId will be returned for each assigned user)
// add it to addresses
if ($mailTo !== $notification->email
&& !empty($mailTo)
&& !in_array($notification->notificationId, $processedNotifications)
) {
$this->log->debug('Sending Notification email to mailTo ' . $mailTo);
$mail->addAddress($mailTo);
}
}
// Email them
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
$mail->From = $msgFrom;
// Add attachment
if ($notification->filename != null) {
$mail->addAttachment(
$this->config->getSetting('LIBRARY_LOCATION') . 'attachment/' . $notification->filename,
$notification->originalFileName
);
}
if (!empty($msgFromName)) {
$mail->FromName = $msgFromName;
}
$mail->Subject = $notification->subject;
$addresses = explode(',', $notification->nonusers);
foreach ($addresses as $address) {
$mail->AddAddress($address);
}
// Body
$mail->isHTML(true);
$mail->AltBody = $notification->body;
$mail->Body = $this->generateEmailBody($notification->subject, $notification->body);
if (!$mail->send()) {
$this->log->error('Unable to send email notification mail to ' . $notification->email);
$this->runMessage .= ' - E' . PHP_EOL;
$this->log->error('Unable to send email notification Error: ' . $mail->ErrorInfo);
} else {
$this->runMessage .= ' - A' . PHP_EOL;
}
$this->log->debug('Marking notification as sent');
} else {
$this->log->error('Discarding NotificationId ' . $notification->notificationId
. ' as no email address could be resolved.');
}
$processedNotifications[] = $notification->notificationId;
// Mark as sent
$notification->setEmailed(Carbon::now()->format('U'));
$notification->save();
}
$this->runMessage .= ' - Done' . PHP_EOL;
}
/**
* Generate an email body
* @param $subject
* @param $body
* @return string
*/
private function generateEmailBody($subject, $body)
{
// Generate Body
// Start an object buffer
ob_start();
// Render the template
echo $this->view->fetch(
'email-template.twig',
['config' => $this->config, 'subject' => $subject, 'body' => $body]
);
$body = ob_get_contents();
ob_end_clean();
return $body;
}
/**
* Should we send email to this user?
* check relevant flag for the notification type on the user group.
* @param UserNotification $notification
* @return bool
*/
private function checkEmailPreferences(UserNotification $notification): bool
{
return $this->userGroupFactory->checkNotificationEmailPreferences(
$notification->userId,
$notification->getTypeForGroup()
);
}
}