Elgg  Version 6.3
DelayedEmailService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Email;
4 
6 use Elgg\Email;
10 use Elgg\Invoker;
12 use Elgg\Traits\Loggable;
14 
22 
23  use Loggable;
24 
25  protected const NOTIFICATIONS_BATCH_SIZE = 500;
26 
36  public function __construct(
37  protected DelayedEmailQueueTable $queue_table,
38  protected EmailService $email,
39  protected ViewsService $views,
40  protected Translator $translator,
41  protected Invoker $invoker
42  ) {
43  }
44 
53  $recipient = $notification->getRecipient();
54 
55  $delivery_interval = $recipient->delayed_email_interval ?: 'daily';
56 
57  try {
58  return $this->queue_table->queueEmail($recipient->guid, $delivery_interval, $notification);
59  } catch (DatabaseException $e) {
60  $this->getLogger()->error($e);
61  }
62 
63  return false;
64  }
65 
74  public function processQueuedNotifications(string $delivery_interval, int $timestamp): int {
75  // processing could take a while
76  set_time_limit(0);
77 
78  return ($this->invoker->call(ELGG_IGNORE_ACCESS, function() use ($delivery_interval, $timestamp) {
79  $count = 0;
80 
81  // process one recipient
82  $processRecipient = function(int $recipient_guid, array $notifications, int $max_id) use ($delivery_interval, $timestamp) {
83  try {
84  $this->processRecipientNotifications($recipient_guid, $notifications, $delivery_interval);
85  } catch (\Throwable $t) {
86  $this->getLogger()->error($t);
87  }
88 
89  // cleanup the queue for this recipient
90  return $this->queue_table->deleteRecipientRows($recipient_guid, $delivery_interval, $timestamp, $max_id);
91  };
92 
93  // get the next recipient to process
94  $recipient_guid = $this->queue_table->getNextRecipientGUID($delivery_interval, $timestamp);
95  while ($recipient_guid > 0) {
96  // get a notification batch to process for this recipient
97  $rows = $this->queue_table->getRecipientRows($recipient_guid, $delivery_interval, $timestamp, self::NOTIFICATIONS_BATCH_SIZE);
98  while (!empty($rows)) {
99  $notifications = [];
100  $max_id = 0;
101  foreach ($rows as $row) {
102  $max_id = max($max_id, $row->id);
103 
104  $notification = $row->getNotification();
105  if (!$notification instanceof Notification) {
106  continue;
107  }
108 
110  }
111 
112  // send all notifications in this batch
113  $count += $processRecipient($recipient_guid, $notifications, $max_id);
114 
115  // get next batch
116  $rows = $this->queue_table->getRecipientRows($recipient_guid, $delivery_interval, $timestamp, static::NOTIFICATIONS_BATCH_SIZE);
117  }
118 
119  // get next recipient to process
120  $recipient_guid = $this->queue_table->getNextRecipientGUID($delivery_interval, $timestamp);
121  }
122 
123  return $count;
124  }));
125  }
126 
136  protected function processRecipientNotifications(int $recipient_guid, array $notifications, string $delivery_interval): bool {
138  if (!$recipient instanceof \ElggEntity || !isset($recipient->email)) {
139  return false;
140  }
141 
142  $view_vars = [
143  'recipient' => $recipient,
144  'notifications' => $notifications,
145  'delivery_interval' => $delivery_interval,
146  ];
147 
148  $body = $this->views->renderView('email/delayed_email/plaintext', $view_vars);
149  if (empty($body)) {
150  return true;
151  }
152 
153  $html_body = $this->views->renderView('email/delayed_email/html', $view_vars);
154 
155  $email = Email::factory([
156  'to' => $recipient,
157  'subject' => $this->translator->translate("notifications:delayed_email:subject:{$delivery_interval}", [], (string) $recipient->language),
158  'body' => $body,
159  'params' => [
160  'html_body' => $html_body,
161  ],
162  ]);
163 
164  return $this->email->send($email);
165  }
166 }
$site email
Definition: settings.php:14
$email
Definition: change_email.php:7
$recipient_guid
Definition: mute.php:7
$recipient
Definition: mute.php:8
$count
Definition: ban.php:24
foreach($categories as $key=> $category) $body
Definition: categories.php:35
Interfaces with the database to perform operations on the delayed_email_queue table.
Email service.
Handle storing and processing delayed emails.
enqueueNotification(Notification $notification)
Queue a notification for delayed email delivery.
processQueuedNotifications(string $delivery_interval, int $timestamp)
Send out notifications for the given delivery_interval.
__construct(protected DelayedEmailQueueTable $queue_table, protected EmailService $email, protected ViewsService $views, protected Translator $translator, protected Invoker $invoker)
Create a new service.
processRecipientNotifications(int $recipient_guid, array $notifications, string $delivery_interval)
Send out the combined email notification for a given recipient.
A generic parent class for database exceptions.
Invocation service.
Definition: Invoker.php:10
Notification container.
Views service.
const ELGG_IGNORE_ACCESS
elgg_call() flags
Definition: constants.php:121
$views
Definition: item.php:17
$notification
Definition: body.php:13
$notifications
Definition: html.php:12
get_entity(int $guid)
Loads and returns an entity object from a guid.
Definition: entities.php:68
$timestamp
Definition: date.php:34
$rows
Definition: redis.php:25