PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / trunk
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress vtrunk
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Helpers / QueueHelper.php

QueueHelper.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress trunk, at back/Helpers/QueueHelper.php

663 lines 25.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Helpers;
4
5 use AcyMailing\Classes\MailStatClass;
6 use AcyMailing\Classes\QueueClass;
7 use AcyMailing\Classes\UserClass;
8 use AcyMailing\Classes\UserStatClass;
9 use AcyMailing\Core\AcymObject;
10
11 class QueueHelper extends AcymObject
12 {
13 const MESSAGE_TYPE_SUCCESS = 1;
14 const MESSAGE_TYPE_WARNING = 2;
15 const MESSAGE_TYPE_ERROR = 3;
16
17 public bool $report = true;
18 public bool $finish = false;
19 public bool $fromManual = false;
20 public int $id = 0;
21 public int $send_limit = 0;
22 public int $nbprocess = 0;
23 public int $startSendingFrom = 0;
24 public int $start = 0;
25 public int $stoptime = 0;
26 public int $successSend = 0;
27 public int $errorSend = 0;
28 public int $pause = 0;
29 public int $total;
30 public array $messages = [];
31 public array $emailTypes = [];
32
33 private int $consecutiveError = 0;
34 // Check apache module "mod_security" to avoid flush issue
35 private bool $mod_security2 = false;
36 // Number of ob_end_flush used in the process
37 private int $obend = 0;
38
39 private UserClass $userClass;
40 private QueueClass $queueClass;
41
42 public function __construct()
43 {
44 parent::__construct();
45
46 $this->queueClass = new QueueClass();
47 $this->userClass = new UserClass();
48
49 $this->send_limit = (int)$this->config->get('queue_nbmail', 40);
50
51 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- The default is 60s, which is far too much for email sending.
52 @ini_set('default_socket_timeout', 10);
53
54 // We call cron URLs but don't wait for the result, we still want the script to execute
55 @ignore_user_abort(true);
56
57 // Increase the limit to have enough time to send, and prevent infinite process
58 $timeLimit = acym_increasePerf();
59 if (empty($timeLimit)) {
60 $timeLimit = 600;
61 }
62
63 // We keep 4 seconds to finish the process properly
64 $this->stoptime = time() + $timeLimit - 4;
65 }
66
67 public function process(): bool
68 {
69 // Check if the current sending method has credits left and load the correct number of emails to send for this batch
70 $creditsLeft = 10000;
71 acym_trigger('onAcymCreditsLeft', [&$creditsLeft]);
72
73 if (empty($creditsLeft)) {
74 $this->finish = true;
75 if ($this->report) {
76 acym_display(acym_translation('ACYM_NOT_ENOUGH_CREDITS'), 'info');
77 }
78
79 return false;
80 }
81
82 if ($this->send_limit > $creditsLeft) {
83 $this->send_limit = $creditsLeft;
84 }
85
86 $queueClass = new QueueClass();
87 $queueClass->emailtypes = $this->emailTypes;
88 $queueElements = $queueClass->getReady($this->startSendingFrom, $this->send_limit, $this->id);
89
90 if (empty($queueElements)) {
91 $this->finish = true;
92 if ($this->report) {
93 acym_display(acym_translation('ACYM_NO_PROCESS'), 'info');
94 }
95
96 return true;
97 }
98
99 //We stop the flush
100 if ($this->report) {
101 if (function_exists('apache_get_modules')) {
102 $modules = apache_get_modules();
103 $this->mod_security2 = in_array('mod_security2', $modules);
104 }
105
106 /*This is to avoid the blank page... and it apparently works! ;) */
107 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Disabled to prevent blank output pages.
108 @ini_set('output_buffering', 'off');
109 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Disabled to prevent blank output pages.
110 @ini_set('zlib.output_compression', 0);
111
112 if (!headers_sent()) {
113 while (ob_get_level() > 0 && $this->obend++ < 3) {
114 @ob_end_flush();
115 }
116 }
117
118 ?>
119 <html>
120 <head>
121 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
122 <title><?php echo esc_html(acym_translation('ACYM_SEND_PROCESS')); ?></title>
123 <style>body{
124 font-size: 12px;
125 font-family: Arial, Helvetica, sans-serif;
126 }</style>
127 </head>
128 <body>
129 <div style="margin-bottom: 18px;padding: 8px !important; background-color: #fcf8e3; border: 1px solid #fbeed5; border-radius: 4px;">
130 <p style="margin:0;"><?php echo esc_html(acym_translation('ACYM_DONT_CLOSE')); ?></p>
131 </div>
132 <div style="display: inline;background-color : white;border : 1px solid grey; padding : 3px;font-size:14px">
133 <span id="divpauseinfo" style="padding:10px;margin:5px;font-size:16px;font-weight:bold;display:none;background-color:black;color:white;"> </span>
134 <?php echo esc_html(acym_translation('ACYM_SEND_PROCESS')); ?>:
135 <span id="counter"><?php echo intval($this->start); ?></span> / <?php echo intval($this->total); ?>
136 </div>
137 <div id="divinfo" style="display:none; position:fixed; bottom:3px;left:3px;background-color : white; border : 1px solid grey; padding : 3px;"></div>
138 <br /><br />
139 <script type="text/javascript" language="javascript">
140 function setInfo(message) {
141 const divinfo = document.getElementById('divinfo');
142 divinfo.style.display = 'block';
143 divinfo.innerHTML = message;
144 }
145
146 function setPauseInfo(nbpause) {
147 const divpauseinfo = document.getElementById('divpauseinfo');
148 divpauseinfo.style.display = '';
149 divpauseinfo.innerHTML = nbpause;
150 }
151
152 function setCounter(val) {
153 document.getElementById('counter').innerHTML = val;
154 }
155
156 let acymailingScriptPause = <?php echo intval($this->pause); ?>;
157
158 function handlePause() {
159 setPauseInfo(acymailingScriptPause);
160 if (acymailingScriptPause > 0) {
161 acymailingScriptPause = acymailingScriptPause - 1;
162 setTimeout(handlePause, 1000);
163 } else {
164 document.location.href = <?php echo json_encode(
165 acym_completeLink('queue&task=continuesend&id='.$this->id.'&totalsend='.$this->total, true, true).'&'.acym_getFormToken().'&alreadysent='
166 ); ?> +document.getElementById('counter').innerHTML;
167 }
168 }
169 </script>
170 <?php
171 if (function_exists('ob_flush')) {
172 @ob_flush();
173 }
174 if (!$this->mod_security2) {
175 @flush();
176 }
177 }
178
179 $mailerHelper = new MailerHelper();
180 $mailerHelper->report = false;
181 if ($this->config->get('smtp_keepalive', 1) || $this->config->get('mailer_method') === 'elasticemail') {
182 $mailerHelper->SMTPKeepAlive = true;
183 }
184
185 //To delete some entries from the queue
186 //$queueDelete[mailing][] = subid;
187 $queueDelete = [];
188 //Update some entries with a new try and a new delay
189 //$queueUpdate[mailing][] = subid;
190 $queueUpdate = [];
191 //Add some stats because we deleted the Newsletter
192 //$statsAdd[mailing][status (1 for success/0 for fail)][] = subid;
193 $statsAdd = [];
194
195 //Maximum number of try...
196 $maxTry = (int)$this->config->get('queue_try', 0);
197
198 $currentMail = $this->start;
199 $this->nbprocess = 0;
200
201 if (count($queueElements) < $this->send_limit) {
202 $this->finish = true;
203 }
204
205 $externalSending = false;
206 acym_trigger('onAcymProcessQueueExternalSendingCampaign', [&$externalSending]);
207
208 if ($externalSending) {
209 $listExternalSending = [];
210 if (!empty($this->id)) {
211 acym_trigger('onAcymInitExternalSendingMethodBeforeSend', [&$listExternalSending, $this->id]);
212 } else {
213 $mailIds = [];
214 foreach ($queueElements as $oneElement) {
215 if (!in_array($oneElement->mail_id, $mailIds)) {
216 $mailIds[] = $oneElement->mail_id;
217 acym_trigger('onAcymInitExternalSendingMethodBeforeSend', [&$listExternalSending, $oneElement->mail_id]);
218 }
219 }
220 }
221 }
222
223 $sentEmails = [];
224 $emailFrequency = $this->fromManual ? 0 : intval($this->config->get('email_frequency', 0));
225 if ($emailFrequency < 0) {
226 $emailFrequency = 0;
227 }
228
229 $userLists = [];
230 $userClass = new UserClass();
231 $isSendingMethodByListActive = false;
232 acym_trigger('sendingMethodByListActive', [&$isSendingMethodByListActive]);
233 $mailerHelper->isSendingMethodByListActive = $isSendingMethodByListActive;
234
235 $statisticsByBatch = $this->config->get('queue_statistics_by_batch', 1) == 1;
236
237 foreach ($queueElements as $oneQueue) {
238 if ($isSendingMethodByListActive && empty($userLists[$oneQueue->user_id])) {
239 $userSubscriptions = $userClass->getUserStandardListIdById($oneQueue->user_id);
240 $userLists[$oneQueue->user_id] = empty($userSubscriptions) ? [] : $userSubscriptions;
241 }
242 if (!empty($emailFrequency)) {
243 sleep($emailFrequency);
244 }
245
246 $currentMail++;
247 $this->nbprocess++;
248 if ($this->report) {
249 echo '<script type="text/javascript">setCounter('.esc_html($currentMail).')</script>';
250 if (function_exists('ob_flush')) {
251 @ob_flush();
252 }
253 if (!$this->mod_security2) {
254 @flush();
255 }
256 }
257
258 $isAbTesting = false;
259
260 if (!empty($oneQueue->sending_params)) {
261 $sendingParams = json_decode($oneQueue->sending_params, true);
262
263 $isAbTesting = isset($sendingParams['abtest']);
264 }
265
266 $this->triggerSendHook((int)$oneQueue->mail_id);
267 try {
268 $mailerHelper->isAbTest = $isAbTesting;
269 $mailerHelper->listsIds = empty($userLists[$oneQueue->user_id]) ? [] : $userLists[$oneQueue->user_id];
270 $mailerHelper->setSendingMethodSetting();
271 $result = $mailerHelper->sendOne($oneQueue->mail_id, $oneQueue->user_id);
272 } catch (\Exception $e) {
273 $result = false;
274 $this->displayMessage([$e->getMessage()], self::MESSAGE_TYPE_ERROR, $e->getCode());
275 }
276
277 if (empty($sentEmails[$oneQueue->mail_id])) {
278 $sentEmails[$oneQueue->mail_id] = $mailerHelper->Body;
279 }
280
281 $queueDeleteOk = true;
282 $otherMessage = '';
283
284 if ($result === true) {
285 $this->successSend++;
286 $this->consecutiveError = 0;
287 $queueDelete[$oneQueue->mail_id][] = $oneQueue->user_id;
288 $statsAdd[$oneQueue->mail_id][1][] = $oneQueue->user_id;
289
290 //In case of the e-mail has been sent now, we immediately process the update/delete and stats
291 $queueDeleteOk = $this->deleteQueue($queueDelete);
292 $mailerHelper->triggerFollowUpAgain($oneQueue->mail_id, $oneQueue->user_id);
293 $queueDelete = [];
294
295 //We only update the queue and add the stats every 10 emails so that we can group things and avoid queries
296 if (!$statisticsByBatch || $this->nbprocess % 10 == 0) {
297 $this->statsAdd($statsAdd);
298 $this->queueUpdate($queueUpdate);
299 $statsAdd = [];
300 $queueUpdate = [];
301 }
302 } elseif ($mailerHelper->dtextsFailed) {
303 $this->consecutiveError = 0;
304 $queueDelete[$oneQueue->mail_id][] = $oneQueue->user_id;
305 //In case of the e-mail has been sent now, we immediately process the update/delete and stats
306 $queueDeleteOk = $this->deleteQueue($queueDelete);
307 $queueDelete = [];
308 } else {
309 acym_trigger('onAcymFailedSendingEmail', [$oneQueue->mail_id, $oneQueue->user_id, $mailerHelper->errorNumber]);
310 $this->errorSend++;
311
312 $shouldTrySendingLater = false;
313 if (in_array($mailerHelper->errorNumber, MailerHelper::NEW_TRY_ERRORS)) {
314 if (empty($maxTry) || $oneQueue->try < $maxTry - 1) {
315 $shouldTrySendingLater = true;
316 if ($mailerHelper->failedCounting) {
317 $otherMessage = acym_translationSprintf('ACYM_QUEUE_NEXT_TRY', 60);
318 }
319 }
320
321 if ($mailerHelper->errorNumber === 1) {
322 $this->consecutiveError++;
323 }
324
325 //If we have 2 consecutive errors, we pause the process a little bit to avoid possible other issues.
326 if ($this->consecutiveError === 2) {
327 sleep(1);
328 }
329 }
330
331 //We delete the queue entry if it's more than number of try allowed
332 if (!$shouldTrySendingLater) {
333 $queueDelete[$oneQueue->mail_id][] = $oneQueue->user_id;
334 $statsAdd[$oneQueue->mail_id][0][] = $oneQueue->user_id;
335 if ($mailerHelper->errorNumber === 1 && $this->config->get('bounce_action_maxtry')) {
336 //We have to delete the queue now otherwise we may have problems!
337 $queueDeleteOk = $this->deleteQueue($queueDelete);
338 $queueDelete = [];
339 //Let's execute an action on this subscriber if we have something to do...
340 $otherMessage .= $this->failedActions((int)$oneQueue->user_id);
341 }
342 } elseif ($mailerHelper->failedCounting) {
343 $queueUpdate[$oneQueue->mail_id][] = $oneQueue->user_id;
344 }
345
346 $mailerHelper->failedCounting = true;
347 }
348
349 $messageOnScreen = '[ID '.$oneQueue->mail_id.'] '.$mailerHelper->reportMessage;
350 if (!empty($otherMessage)) {
351 $messageOnScreen .= ' => '.$otherMessage;
352 }
353 $this->displayMessage([$messageOnScreen], $result ? self::MESSAGE_TYPE_SUCCESS : self::MESSAGE_TYPE_ERROR, $currentMail);
354
355 //We didn't delete the right number of elements so to avoid a double send process, we stop immediately
356 if (!$queueDeleteOk) {
357 $this->finish = true;
358 break;
359 }
360
361 if (!empty($this->stoptime) && $this->stoptime < time()) {
362 $this->displayMessage([acym_translation('ACYM_SEND_REFRESH_TIMEOUT')], self::MESSAGE_TYPE_WARNING);
363 if ($this->nbprocess < count($queueElements)) {
364 $this->finish = false;
365 }
366 break;
367 }
368
369 if ($this->consecutiveError > 3 && $this->successSend > 3) {
370 //We refresh the page in case of we used to send e-mails but now we can not, that may be due to a mysql close connection
371 $this->displayMessage([acym_translation('ACYM_SEND_REFRESH_CONNECTION')], self::MESSAGE_TYPE_WARNING);
372 break;
373 }
374
375 //After 5 consecutive send error, we stop the process and display a message
376 //We stop the send process if the user closed the windows so that he can stop the send process at any time he wants
377 if ($this->consecutiveError > 5 || ($this->report && connection_aborted())) {
378 $this->finish = true;
379 break;
380 }
381 }
382
383 if ($externalSending) {
384 foreach ($sentEmails as $mailId => $content) {
385 if (!$queueClass->isSendingFinished($mailId)) continue;
386
387 acym_trigger('onAcymSendCampaignOnExternalSendingMethod', [$mailId, $content]);
388 }
389 }
390
391 //Update all values if it's not already done (we don't do it for each error so that's why we still have some
392 $this->deleteQueue($queueDelete);
393 $this->statsAdd($statsAdd);
394 $this->queueUpdate($queueUpdate);
395
396 if ($mailerHelper->SMTPKeepAlive) {
397 $mailerHelper->smtpClose();
398 }
399
400 //We finished the send process
401 if (!empty($this->total) && $currentMail >= $this->total) {
402 $this->finish = true;
403 }
404
405 if ($this->consecutiveError > 5) {
406 $this->handleError();
407
408 return false;
409 }
410
411 if ($this->report && !$this->finish) {
412 //We handle the pause in JS.
413 echo '<script type="text/javascript" language="javascript">handlePause();</script>';
414 }
415
416 if ($this->report) {
417 //We need to finish the current page properly
418 echo '</body></html>';
419 while ($this->obend-- > 0) {
420 ob_start();
421 }
422 exit;
423 }
424
425 return true;
426 }
427
428 /**
429 * Function to add/update elements in the stats
430 * $statsAdd[mailing][1 for success or 0 for fail][] = subscriber id;
431 * $statsAdd[mailing][1][] = 123;
432 */
433 public function statsAdd(array $statsAdd): void
434 {
435 if (empty($statsAdd)) {
436 return;
437 }
438
439 $userStatClass = new UserStatClass();
440 $mailStatClass = new MailStatClass();
441
442 $currentDate = acym_date('now', 'Y-m-d H:i:s', false);
443 $subscriberIds = [];
444
445 foreach ($statsAdd as $mailId => $infos) {
446 $mailId = intval($mailId);
447
448 foreach ($infos as $status => $subscribers) {
449 foreach ($subscribers as $oneSubscriber) {
450 $oneSubscriber = intval($oneSubscriber);
451
452 $userStat = new \stdClass();
453 $userStat->user_id = $oneSubscriber;
454 $userStat->mail_id = $mailId;
455 $userStat->send_date = $currentDate;
456 $userStat->fail = $status ? 0 : 1;
457 $userStat->sent = $status ? 1 : 0;
458 $userStat->statusSending = $status;
459
460 $userStatClass->save($userStat, true);
461
462 if ($status) {
463 $subscriberIds[] = $oneSubscriber;
464 }
465 }
466 }
467
468 $nbSent = empty($infos[1]) ? 0 : count($infos[1]);
469 $nbFail = empty($infos[0]) ? 0 : count($infos[0]);
470
471 $mailStat = new \stdClass();
472 $mailStat->mail_id = $mailId;
473 $mailStat->sent = $nbSent;
474 $mailStat->fail = $nbFail;
475
476 $mailStatClass->save($mailStat);
477 }
478
479 if (!empty($subscriberIds)) {
480 acym_query('UPDATE `#__acym_user` SET `last_sent_date` = '.acym_escapeDB($currentDate).' WHERE `id` IN ('.implode(',', $subscriberIds).')');
481 }
482 }
483
484 private function triggerSendHook(int $mailId): void
485 {
486 static $triggered = [];
487 if (!empty($triggered[$mailId])) {
488 return;
489 }
490
491 $triggered[$mailId] = true;
492 acym_triggerCmsHook('onAcymSendMail', [$mailId]);
493 }
494
495 /**
496 * Function to delete elements from the queue
497 * $queueDelete[mailId][] = subscriberId;
498 */
499 private function deleteQueue(array $queueDelete): bool
500 {
501 if (empty($queueDelete)) {
502 return true;
503 }
504
505 $status = true;
506
507 foreach ($queueDelete as $mailId => $userIds) {
508 $nbUsers = count($userIds);
509 $nbDeleted = $this->queueClass->deleteQueuedByUserIds($userIds, $mailId);
510
511 if (!empty($this->queueClass->errors)) {
512 $status = false;
513 $this->displayMessage($this->queueClass->errors, self::MESSAGE_TYPE_ERROR);
514 } else {
515 // If we didn't delete the entry, it may have been done by another send process so we stop it immediately to avoid double send
516 if ($nbDeleted !== $nbUsers) {
517 $status = false;
518 $this->displayMessage(
519 [$nbDeleted < $nbUsers ? acym_translation('ACYM_QUEUE_DOUBLE') : $nbDeleted.' emails deleted from the queue whereas we only have '.$nbUsers.' subscribers'],
520 self::MESSAGE_TYPE_ERROR
521 );
522 }
523 }
524 }
525
526 return $status;
527 }
528
529 /**
530 * Function to update elements in the queue
531 * $queueUpdate[mailing][] = subid;
532 */
533 private function queueUpdate(array $queueUpdate): void
534 {
535 if (empty($queueUpdate)) {
536 return;
537 }
538
539 //Delay to requeue the e-mail in seconds
540 foreach ($queueUpdate as $mailid => $subscribers) {
541 $this->queueClass->delayFailed($mailid, $subscribers);
542 }
543 }
544
545 private function handleError(): void
546 {
547 $this->finish = true;
548 $message = acym_translation('ACYM_SEND_STOPED');
549 $message .= '<br />';
550 $message .= acym_translation('ACYM_SEND_KEPT_ALL');
551 $message .= '<br />';
552 //ERROR 1 : no e-mail sent at all...
553 if ($this->report) {
554 if (empty($this->successSend) && empty($this->start)) {
555 $message .= acym_translation('ACYM_SEND_CHECKONE');
556 $message .= '<br />';
557 $message .= acym_translation('ACYM_SEND_ADVISE_LIMITATION');
558 } else {
559 //We used to send e-mails but now we can not any more... sounds like a server limitation!
560 $message .= acym_translation('ACYM_SEND_REFUSE');
561 $message .= '<br />';
562 if (!acym_level(ACYM_ESSENTIAL)) {
563 $message .= acym_translation('ACYM_SEND_CONTINUE_COMMERCIAL');
564 } else {
565 $message .= acym_translation('ACYM_SEND_CONTINUE_AUTO');
566 }
567 }
568 }
569
570 $this->displayMessage([$message], self::MESSAGE_TYPE_WARNING);
571 }
572
573 /**
574 * If num is empty then it's a message otherwise it's a send status
575 */
576 private function displayMessage(array $messages, int $status, int $num = 0): void
577 {
578 foreach ($messages as $message) {
579 $this->messages[] = acym_stripTags($message);
580 }
581
582 if (!$this->report) {
583 return;
584 }
585
586 $color = $status === self::MESSAGE_TYPE_SUCCESS ? 'green' : ($status === self::MESSAGE_TYPE_WARNING ? 'orange' : 'red');
587 foreach ($messages as $message) {
588 if (!empty($num)) {
589 echo '<br />'.esc_html($num).' : <span style="color:'.esc_attr($color).';">'.wp_kses(
590 $message,
591 [
592 'b' => [],
593 'i' => [],
594 'a' => [
595 'href' => true,
596 'target' => true,
597 ],
598 ]
599 ).'</span>';
600 } else {
601 echo '<script type="text/javascript" language="javascript">setInfo('.json_encode($message).')</script>';
602 }
603 }
604
605 if (function_exists('ob_flush')) {
606 @ob_flush();
607 }
608 if (!$this->mod_security2) {
609 @flush();
610 }
611 }
612
613 private function failedActions(int $userId): string
614 {
615 $actionMaxTries = $this->config->get('bounce_action_maxtry');
616 if (in_array($actionMaxTries, ['sub', 'remove', 'unsub'])) {
617 $subscriptions = $this->userClass->getUserSubscriptionById($userId);
618 }
619
620 $listId = 0;
621 $message = '';
622 switch ($actionMaxTries) {
623 case 'sub':
624 $listId = $this->config->get('bounce_action_lists_maxtry');
625 if (!empty($listId)) {
626 $message .= ' user '.$userId.' subscribed to list n°'.$listId;
627 $this->userClass->subscribe([$userId], [$listId]);
628 }
629 // There is no break here as we will remove the user from the other lists
630 case 'remove':
631 $unsubLists = array_diff(array_keys($subscriptions), [$listId]);
632 if (!empty($unsubLists)) {
633 $message .= ' user '.$userId.' removed from lists '.implode(',', $unsubLists);
634 $this->userClass->removeSubscription([$userId], $unsubLists);
635 } else {
636 $message .= ' user '.$userId.' not subscribed';
637 }
638 break;
639 case 'unsub':
640 $unsubLists = array_diff(array_keys($subscriptions), [$listId]);
641 if (!empty($unsubLists)) {
642 $message .= ' user '.$userId.' unsubscribed from lists '.implode(',', $unsubLists);
643 $this->userClass->unsubscribe([$userId], $unsubLists);
644 } else {
645 $message .= ' user '.$userId.' not unsubscribed';
646 }
647 break;
648 case 'delete':
649 $message .= ' user '.$userId.' deleted';
650 $this->userClass->delete([$userId]);
651 break;
652 case 'block':
653 $message .= ' user '.$userId.' blocked';
654 $this->userClass->deactivate([$userId]);
655 // We delete any other e-mail from the queue as well
656 $this->queueClass->deleteQueuedByUserIds([$userId]);
657 break;
658 }
659
660 return $message;
661 }
662 }
663