Elgg  Version 4.3
DelayedEmailService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Email;
4 
6 use Elgg\Email;
11 use Elgg\Invoker;
15 
23 
24  use Loggable;
25 
29  protected $queue_table;
30 
34  protected $email;
35 
39  protected $views;
40 
44  protected $translator;
45 
49  protected $invoker;
50 
61  $this->queue_table = $queue_table;
62  $this->email = $email;
63  $this->views = $views;
64  $this->translator = $translator;
65  $this->invoker = $invoker;
66  }
67 
76  $recipient = $notification->getRecipient();
77 
78  $delivery_interval = $recipient->getPrivateSetting('delayed_email_interval') ?? 'daily';
79 
80  try {
81  return $this->queue_table->queueEmail($recipient->guid, $delivery_interval, $notification);
82  } catch (DatabaseException $e) {
83  $this->getLogger()->error($e);
84  }
85 
86  return false;
87  }
88 
97  public function processQueuedNotifications(string $delivery_interval, int $timestamp): int {
98  // processing could take a while
99  set_time_limit(0);
100 
101  return ($this->invoker->call(ELGG_IGNORE_ACCESS, function() use ($delivery_interval, $timestamp) {
102  $count = 0;
103  $last_recipient_guid = null;
104  $notifications = [];
105 
106  // process one recipient
107  $processRecipient = function($row = null) use (&$last_recipient_guid, &$notifications, $delivery_interval, $timestamp) {
108  try {
109  $this->processRecipientNotifications($last_recipient_guid, $notifications, $delivery_interval);
110  } catch (\Throwable $t) {
111  $this->getLogger()->error($t);
112  }
113 
114  // cleanup the queue for this recipient
115  $this->queue_table->deleteRecipientRows($last_recipient_guid, $delivery_interval, $timestamp);
116 
117  // start collecting data for the new recipient
118  $last_recipient_guid = $row ? $row->recipient_guid : null;
119  $notifications = [];
120  };
121 
122  $rows = $this->queue_table->getIntervalRows($delivery_interval, $timestamp);
123 
124  /* @var $row DatabaseRecord */
125  foreach ($rows as $row) {
126  $count++;
127 
128  if (!isset($last_recipient_guid)) {
129  $last_recipient_guid = $row->recipient_guid;
130  } elseif ($last_recipient_guid !== $row->recipient_guid) {
131  // process one recipient
132  $processRecipient($row);
133  }
134 
135  $notfication = $row->getNotification();
136  if (!$notfication instanceof Notification) {
137  continue;
138  }
139 
140  $notifications[] = $notfication;
141  }
142 
143  if (isset($last_recipient_guid)) {
144  $processRecipient();
145  }
146 
147  return $count;
148  }));
149  }
150 
160  protected function processRecipientNotifications(int $recipient_guid, array $notifications, string $delivery_interval): bool {
161  $recipient = get_entity($recipient_guid);
162  if (!$recipient instanceof \ElggEntity || !isset($recipient->email)) {
163  return false;
164  }
165 
166  $view_vars = [
167  'recipient' => $recipient,
168  'notifications' => $notifications,
169  'delivery_interval' => $delivery_interval,
170  ];
171 
172  $body = $this->views->renderView('email/delayed_email/plaintext', $view_vars);
173  if (empty($body)) {
174  return true;
175  }
176 
177  $html_body = $this->views->renderView('email/delayed_email/html', $view_vars);
178 
180  'to' => $recipient,
181  'subject' => $this->translator->translate("notifications:delayed_email:subject:{$delivery_interval}", [], $recipient->language),
182  'body' => $body,
183  'params' => [
184  'html_body' => $html_body,
185  ],
186  ]);
187 
188  return $this->email->send($email);
189  }
190 }
getRecipient()
Get the recipient entity.
$notifications
Definition: html.php:12
processQueuedNotifications(string $delivery_interval, int $timestamp)
Send out notifications for the given delivery_interval.
$rows
Definition: redis.php:25
static factory(array $options=[])
Create an email instance form an array of options.
Definition: Email.php:80
Notification container.
$timestamp
Definition: date.php:36
__construct(DelayedEmailQueueTable $queue_table, EmailService $email, ViewsService $views, Translator $translator, Invoker $invoker)
Create a new service.
trait Loggable
Enables adding a logger.
Definition: Loggable.php:14
const ELGG_IGNORE_ACCESS
elgg_call() flags
Definition: constants.php:146
enqueueNotification(Notification $notification)
Queue a notification for delayed email delivery.
$notification
Definition: body.php:13
$site email
Definition: settings.php:22
A generic parent class for database exceptions.
Views service.
$count
Definition: ban.php:24
processRecipientNotifications(int $recipient_guid, array $notifications, string $delivery_interval)
Send out the combined email notification for a given recipient.
Interfaces with the database to perform operations on the delayed_email_queue table.
getLogger()
Returns logger.
Definition: Loggable.php:37
if($item instanceof\ElggEntity) elseif($item instanceof\ElggRiverItem) elseif($item instanceof ElggRelationship) elseif(is_callable([$item, 'getType']))
Definition: item.php:48
$recipient_guid
Definition: mute.php:7
Email service.
$recipient
Definition: mute.php:8
Handle storing and processing delayed emails.
Invocation service.
Definition: Invoker.php:12
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:69