PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
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
← All changes | back/Classes/QueueClass.php +181 -104 10.2.2 → 11.1.0 View file →
@@ -7,28 +7,73 @@
7 7 use AcyMailing\Core\AcymClass;
8 8
9 9 class QueueClass extends AcymClass
10 10 {
11 - public $emailtypes;
11 + public array $emailtypes = [];
12 12
13 + /**
14 + * Get campaigns depending on filters (search, status, pagination)
15 + */
13 16 public function getMatchingCampaigns(array $settings): array
14 17 {
18 + $queuedMails = acym_loadResultArray('SELECT DISTINCT mail_id FROM #__acym_queue');
19 + if (empty($queuedMails)) {
20 + return [
21 + 'elements' => [],
22 + 'total' => (object)['total' => 0],
23 + 'status' => [
24 + 'all' => 0,
25 + 'sending' => 0,
26 + 'paused' => 0,
27 + 'automation' => 0,
28 + 'followup' => 0,
29 + ],
30 + ];
31 + }
32 +
15 33 $campaignClass = new CampaignClass();
16 34 $mailStatClass = new MailStatClass();
17 35 $mailClass = new MailClass();
18 - $query = 'FROM #__acym_mail AS mail
19 - JOIN #__acym_queue AS queue ON mail.id = queue.mail_id
20 - LEFT JOIN #__acym_campaign AS campaign ON mail.id = campaign.mail_id OR mail.parent_id = campaign.mail_id';
21 36
37 + $queryCount = 'SELECT COUNT(DISTINCT mail.id) AS total
38 + FROM #__acym_mail AS mail
39 + LEFT JOIN #__acym_campaign AS campaign ON campaign.mail_id = mail.id OR campaign.mail_id = mail.parent_id';
40 +
41 + $query = 'SELECT
42 + mail.name,
43 + mail.subject,
44 + mail.type,
45 + mail.id,
46 + campaign.id AS campaign,
47 + COALESCE(campaign.sending_date, queue.min_sending_date) AS sending_date,
48 + campaign.sending_type,
49 + campaign.active,
50 + campaign.sending_params AS sending_params,
51 + queue.nbqueued,
52 + mail.language,
53 + mail.parent_id
54 + FROM #__acym_mail AS mail
55 + JOIN (
56 + SELECT mail_id, COUNT(*) AS nbqueued, MIN(sending_date) AS min_sending_date
57 + FROM #__acym_queue
58 + GROUP BY mail_id
59 + ) AS queue ON mail.id = queue.mail_id
60 + LEFT JOIN #__acym_campaign AS campaign
61 + ON mail.id = campaign.mail_id
62 + OR mail.parent_id = campaign.mail_id';
63 +
64 + // This query returns an array like "number of mails" => score. cf the equivalent in the list class to understand how it works
22 65 $queryStatus = 'SELECT COUNT(DISTINCT mail.id) AS number, campaign.active
23 66 FROM #__acym_mail AS mail
24 - JOIN #__acym_queue AS queue ON queue.mail_id = mail.id
25 67 LEFT JOIN #__acym_campaign AS campaign ON mail.id = campaign.mail_id';
26 68
27 69 if (!empty($settings['tag'])) {
28 - $query .= ' JOIN #__acym_tag AS tag ON (mail.id = tag.id_element OR mail.parent_id = tag.id_element) AND tag.type = "mail" AND tag.name = '.acym_escapeDB(
29 - $settings['tag']
30 - );
70 + $tagJoin = ' JOIN #__acym_tag AS tag
71 + ON (mail.id = tag.id_element OR mail.parent_id = tag.id_element)
72 + AND tag.type = "mail"
73 + AND tag.name = '.acym_escapeDB($settings['tag']);
74 + $query .= $tagJoin;
75 + $queryCount .= $tagJoin;
31 76 $queryStatus .= ' JOIN #__acym_tag AS tag ON mail.id = tag.id_element AND tag.type = "mail" AND tag.name = '.acym_escapeDB($settings['tag']);
32 77 }
33 78
34 79 $filters = [];
@@ -37,11 +82,9 @@
37 82 if (!empty($settings['search'])) {
38 83 $filters[] = 'mail.subject LIKE '.acym_escapeDB('%'.$settings['search'].'%').' OR mail.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
39 84 }
40 85
41 - if (!empty($filters)) {
42 - $queryStatus .= ' WHERE ('.implode(') AND (', $filters).')';
43 - }
86 + $queryStatus .= ' WHERE ('.implode(') AND (', $filters).') AND mail.id IN ('.implode(',', $queuedMails).')';
44 87
45 88 if (!empty($settings['status'])) {
46 89 $allowedStatus = [
47 90 'sending' => 'campaign.active = 1',
@@ -50,31 +93,28 @@
50 93 'followup' => 'mail.type = '.acym_escapeDB(MailClass::TYPE_FOLLOWUP),
51 94 ];
52 95
53 96 if (empty($allowedStatus[$settings['status']])) {
54 - die('Unauthorized filter: '.acym_escape($settings['status']));
97 + die('Unauthorized filter: '.esc_html($settings['status']));
55 98 }
56 99
57 100 $filters[] = $allowedStatus[$settings['status']];
58 101 }
59 102
60 - if (!empty($filters)) {
61 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
62 - }
103 + $queryCount .= ' WHERE ('.implode(') AND (', $filters).') AND mail.id IN ('.implode(',', $queuedMails).')';
104 + $query .= ' WHERE ('.implode(') AND (', $filters).')';
105 + $query .= ' ORDER BY queue.min_sending_date ASC';
63 106
64 - $queryCount = 'SELECT COUNT(DISTINCT mail.id) AS total '.$query;
65 - $query .= ' GROUP BY mail.id';
66 -
67 - $query = 'SELECT mail.name, mail.subject, mail.type, mail.id, campaign.id AS campaign, IF(campaign.sending_date IS NULL, queue.sending_date, campaign.sending_date) AS sending_date, campaign.sending_type, campaign.active, campaign.sending_params AS sending_params, COUNT(queue.mail_id) AS nbqueued, mail.language, mail.parent_id '.$query.' ORDER BY queue.sending_date ASC';
68 -
69 107 acym_query('SET SQL_BIG_SELECTS=1;');
70 - $results['elements'] = $mailClass->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['campaignsPerPage']));
71 - $results['total'] = acym_loadObject($queryCount);
108 + $results = [
109 + 'elements' => $mailClass->decode(acym_loadObjectList($query, '', $settings['offset'], $settings['campaignsPerPage'])),
110 + 'total' => acym_loadObject($queryCount),
111 + ];
72 112
73 113 $isMultilingual = acym_isMultilingual();
74 114 $campaignRecipientsMultilingual = [];
75 - $automationHelper = new AutomationHelper();
76 115
116 + // Get the recipients
77 117 $specialTypes = [];
78 118 acym_trigger('getCampaignTypes', [&$specialTypes]);
79 119
80 120 foreach ($results['elements'] as $i => $oneMail) {
@@ -111,8 +151,10 @@
111 151 $results['elements'][$i]->recipients = intval($mailStatClass->getTotalSubscribersByMailIdWithChild($mailId));
112 152 }
113 153 } elseif ($isMultilingual) {
114 154 if (empty($campaignRecipientsMultilingual[$oneMail->campaign])) {
155 + $automationHelper = new AutomationHelper();
156 +
115 157 $listIds = array_keys($results['elements'][$i]->lists);
116 158 acym_arrayToInteger($listIds);
117 159
118 160 $automationHelper->join['user_list'] = ' #__acym_user_has_list AS user_list ON user_list.user_id = user.id AND user_list.list_id IN ('.implode(
@@ -171,17 +213,27 @@
171 213 ON mail.id = queue.mail_id
172 214 WHERE mail.type = '.acym_escapeDB(MailClass::TYPE_FOLLOWUP)
173 215 );
174 216
175 - $elementsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY active', 'active');
176 - foreach ($elementsPerStatus as $i => $element) {
177 - $elementsPerStatus[$i] = empty($element->number) ? 0 : $element->number;
217 + $elementsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY active');
218 + $queuedActiveCampaigns = 0;
219 + $queuedPausedCampaigns = 0;
220 + foreach ($elementsPerStatus as $element) {
221 + if (is_null($element->active)) {
222 + continue;
223 + }
224 +
225 + if (!empty($element->active)) {
226 + $queuedActiveCampaigns = intval($element->number);
227 + } else {
228 + $queuedPausedCampaigns = intval($element->number);
229 + }
178 230 }
179 231
180 232 $results['status'] = [
181 - 'all' => array_sum($elementsPerStatus) + $automationNumber + $followupNumber,
182 - 'sending' => $elementsPerStatus[1] ?? 0,
183 - 'paused' => $elementsPerStatus[0] ?? 0,
233 + 'all' => $queuedActiveCampaigns + $queuedPausedCampaigns + $automationNumber + $followupNumber,
234 + 'sending' => $queuedActiveCampaigns,
235 + 'paused' => $queuedPausedCampaigns,
184 236 'automation' => $automationNumber,
185 237 'followup' => $followupNumber,
186 238 ];
187 239
@@ -187,11 +239,13 @@
187 239
188 240 return $results;
189 241 }
190 242
243 + /**
244 + * Get campaigns depending on filters (search, status, pagination)
245 + */
191 246 public function getMatchingScheduledCampaigns(array $settings): array
192 247 {
193 - $campaignClass = new CampaignClass();
194 248 $mailClass = new MailClass();
195 249 $query = 'FROM #__acym_mail AS mail
196 250 JOIN #__acym_campaign AS campaign ON mail.id = campaign.mail_id OR mail.parent_id = campaign.mail_id ';
197 251
@@ -208,11 +262,9 @@
208 262 if (!empty($settings['search'])) {
209 263 $filters[] = 'mail.subject LIKE '.acym_escapeDB('%'.$settings['search'].'%').' OR mail.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
210 264 }
211 265
212 - if (!empty($filters)) {
213 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
214 - }
266 + $query .= ' WHERE ('.implode(') AND (', $filters).')';
215 267
216 268 $queryCount = 'SELECT COUNT(DISTINCT mail.id) AS total '.$query;
217 269 $query = 'SELECT mail.name, mail.subject, mail.id, campaign.sending_date, campaign.sending_params, mail.language, mail.parent_id '.$query.' GROUP BY mail.id ORDER BY campaign.sending_date ASC';
218 270
@@ -234,8 +286,11 @@
234 286
235 287 return $results;
236 288 }
237 289
290 + /**
291 + * Get mails depending on filters (search, status, pagination)
292 + */
238 293 public function getMatchingResults(array $settings): array
239 294 {
240 295 $query = 'FROM #__acym_queue AS queue
241 296 JOIN #__acym_mail AS mail ON mail.id = queue.mail_id
@@ -261,13 +316,15 @@
261 316 if (!empty($filters)) {
262 317 $query .= ' WHERE ('.implode(') AND (', $filters).')';
263 318 }
264 319
265 - if (!empty($settings['tag'])) {
320 + if (empty($settings['tag'])) {
321 + $queryCount = 'SELECT COUNT(queue.mail_id) AS total '.$query;
322 + } else {
323 + $queryCount = 'SELECT COUNT(DISTINCT queue.mail_id, queue.user_id) AS total '.$query;
266 324 $query .= ' GROUP BY queue.mail_id, queue.user_id';
267 325 }
268 326
269 - $queryCount = 'SELECT COUNT(queue.mail_id) AS total '.$query;
270 327 $query = 'SELECT mail.id, queue.sending_date, mail.name, mail.subject, user.email, user.name AS user_name, queue.user_id, queue.try '.$query.' ORDER BY queue.sending_date ASC';
271 328
272 329 $mailClass = new MailClass();
273 330
@@ -276,13 +333,12 @@
276 333 'total' => acym_loadObject($queryCount),
277 334 ];
278 335 }
279 336
280 - public function scheduleReady()
337 + public function scheduleReady(): ?int
281 338 {
282 339 $this->messages = [];
283 340
284 - $campaignClass = new CampaignClass();
285 341 $mailClass = new MailClass();
286 342
287 343 $multilingualQuery = acym_isMultilingual() ? ' OR mail.parent_id = campaign.mail_id ' : '';
288 344
@@ -300,16 +356,26 @@
300 356 )
301 357 );
302 358
303 359 if (empty($mailReady)) {
304 - return false;
360 + return null;
305 361 }
306 362
307 363 $nbQueue = [];
308 364
309 365 foreach ($mailReady as $mailId => $mail) {
310 - $nbQueue[$mailId] = $this->queue($mail);
311 - $this->messages[] = acym_translationSprintf('ACYM_ADDED_QUEUE_SCHEDULE', $nbQueue[$mailId], '<b>'.$mail->name.'</b>');
366 + // A/B test campaigns are queued later by CampaignClass::send(), so skip queueing here
367 + $sendingParams = $mail->sending_params ?? [];
368 + if (is_string($sendingParams)) {
369 + $sendingParams = json_decode($sendingParams, true) ?? [];
370 + }
371 +
372 + if (!empty($sendingParams['abtest']['repartition'])) {
373 + $nbQueue[$mailId] = 0;
374 + } else {
375 + $nbQueue[$mailId] = $this->queue($mail);
376 + $this->messages[] = acym_translationSprintf('ACYM_ADDED_QUEUE_SCHEDULE', $nbQueue[$mailId], '<b>'.$mail->name.'</b>');
377 + }
312 378 }
313 379
314 380 $mailIds = array_keys($mailReady);
315 381 acym_arrayToInteger($mailIds);
@@ -316,14 +382,20 @@
316 382 $campaigns = acym_loadObjectList('SELECT id, mail_id FROM #__acym_campaign WHERE mail_id IN ('.implode(',', $mailIds).')');
317 383 $campaignClass = new CampaignClass();
318 384 foreach ($campaigns as $campaign) {
319 385 $result = $campaignClass->send($campaign->id, $nbQueue[$campaign->mail_id]);
320 - if (empty($result) && acym_isMultilingual()) {
321 - $translatedMails = acym_loadResultArray('SELECT id FROM #__acym_mail WHERE id != '.intval($campaign->mail_id).' AND parent_id = '.intval($campaign->mail_id));
322 - if (!empty($translatedMails)) {
323 - foreach ($translatedMails as $translatedMailId) {
324 - if (!empty($nbQueue[$translatedMailId])) $campaignClass->send($campaign->id, $nbQueue[$translatedMailId]);
325 - }
386 + if (!empty($result) || !acym_isMultilingual()) {
387 + continue;
388 + }
389 +
390 + $translatedMails = acym_loadResultArray('SELECT id FROM #__acym_mail WHERE id != '.intval($campaign->mail_id).' AND parent_id = '.intval($campaign->mail_id));
391 + if (empty($translatedMails)) {
392 + continue;
393 + }
394 +
395 + foreach ($translatedMails as $translatedMailId) {
396 + if (!empty($nbQueue[$translatedMailId])) {
397 + $campaignClass->send($campaign->id, $nbQueue[$translatedMailId]);
326 398 }
327 399 }
328 400 }
329 401
@@ -329,12 +401,11 @@
329 401
330 402 return count($mailReady);
331 403 }
332 404
333 - public function delete($elements)
405 + public function delete(array $elements): int
334 406 {
335 407 if (empty($elements)) return 0;
336 - if (!is_array($elements)) $elements = [$elements];
337 408 acym_arrayToInteger($elements);
338 409
339 410 $query = 'DELETE FROM #__acym_queue WHERE mail_id IN ('.implode(',', $elements).')';
340 411 $result = acym_query($query);
@@ -341,60 +412,48 @@
341 412
342 413 acym_query('UPDATE #__acym_campaign SET draft = 1, active = 1 WHERE mail_id IN ('.implode(',', $elements).')');
343 414
344 415 if (!$result) {
345 - return false;
416 + return 0;
346 417 }
347 418
348 419 return $result;
349 420 }
350 421
351 - public function deleteOne($elements, $mailId = null)
422 + public function deleteQueuedByUserIds(array $userIds, ?int $mailId = null): int
352 423 {
353 - if (!is_array($elements)) {
354 - $elements = [$elements];
424 + acym_arrayToInteger($userIds);
425 + if (empty($userIds)) {
426 + return 0;
355 427 }
356 428
357 - if (empty($elements)) {
358 - return 0;
429 + $query = 'DELETE FROM #__acym_queue WHERE user_id IN ('.implode(',', $userIds).')';
430 + if (!empty($mailId)) {
431 + $query .= ' AND mail_id = '.intval($mailId);
359 432 }
360 433
361 - $nbDeleted = 0;
362 - foreach ($elements as $one) {
363 - if (strpos($one, '_')) {
364 - [$mailId, $userId] = explode('_', $one);
365 - } else {
366 - $userId = $one;
434 + try {
435 + $nbDeleted = acym_query($query);
436 +
437 + if ($nbDeleted === false) {
438 + $this->errors[] = acym_getDBError();
439 +
440 + return 0;
367 441 }
368 442
369 - $query = 'DELETE FROM #__acym_queue WHERE user_id = '.intval($userId);
370 - if (!empty($mailId)) {
371 - $query .= ' AND mail_id = '.intval($mailId);
372 - }
443 + return (int)$nbDeleted;
444 + } catch (\Exception $e) {
445 + $this->errors[] = $e->getMessage();
373 446
374 - try {
375 - $res = acym_query($query);
376 - } catch (\Exception $e) {
377 - $res = false;
378 - }
379 - if ($res === false) {
380 - if (isset($e)) {
381 - $this->errors[] = $e->getMessage();
382 - unset($e);
383 - } else {
384 - $this->errors[] = acym_getDBError();
385 - }
386 - } else {
387 - $nbDeleted += $res;
388 - }
447 + return 0;
389 448 }
390 -
391 - return $res;
392 449 }
393 450
394 - public function getReady($limit, $mailId = 0): array
451 + public function getReady(int $startFrom, int $limit, int $mailId = 0): array
395 452 {
396 - if (empty($limit)) return [];
453 + if (empty($limit)) {
454 + return [];
455 + }
397 456
398 457 $query = 'SELECT queue.*, campaign.sending_params AS sending_params FROM #__acym_queue AS queue';
399 458 $query .= ' JOIN #__acym_user AS user ON queue.`user_id` = user.`id` ';
400 459 $query .= ' JOIN #__acym_mail AS mail ON queue.`mail_id` = mail.`id` ';
@@ -421,8 +480,9 @@
421 480 if (!empty($mailId)) {
422 481 $query .= ' AND queue.`mail_id` = '.intval($mailId);
423 482 }
424 483
484 + // We don't display this option in the configuration anymore but we use its value if it's set in the database
425 485 $sendOrder = $this->config->get('sendorder');
426 486 if (empty($sendOrder)) {
427 487 $order = 'queue.`user_id` ASC';
428 488 } elseif ($sendOrder === 'rand') {
@@ -429,14 +489,14 @@
429 489 $order = 'RAND()';
430 490 } else {
431 491 $sendOrder = str_replace('subid', 'user_id', $sendOrder);
432 492 $ordering = explode(',', $sendOrder);
433 - $order = 'queue.`'.acym_secureDBColumn(trim($ordering[0])).'` '.acym_secureDBColumn(trim($ordering[1]));
493 + $order = 'queue.`'.acym_secureDBColumn(trim($ordering[0])).'` '.acym_secureDBColumn(trim($ordering[1] ?? 'ASC'));
434 494 }
435 495
436 496 $query .= ' ORDER BY queue.`priority` ASC, queue.`sending_date` ASC, '.$order;
437 - $startqueue = acym_getVar('int', 'startqueue', 0);
438 - $query .= ' LIMIT '.intval($startqueue).','.intval($limit);
497 + // You can add a "startqueue" parameter to the url so Acy will not load the first e-mails but will start directly with the 300 or 500 or...
498 + $query .= ' LIMIT '.intval($startFrom).','.intval($limit);
439 499
440 500 try {
441 501 $results = acym_loadObjectList($query);
442 502 } catch (\Exception $e) {
@@ -443,8 +503,9 @@
443 503 $results = null;
444 504 }
445 505
446 506 if ($results === null) {
507 + // We got an issue here... maybe the table is crashed so we will repair it.
447 508 acym_query('REPAIR TABLE #__acym_queue, #__acym_user, #__acym_mail, #__acym_campaign');
448 509 }
449 510
450 511 if (empty($results)) {
@@ -450,8 +511,12 @@
450 511 if (empty($results)) {
451 512 return [];
452 513 }
453 514
515 + // This comment doesn't make any sense
516 + //We update the first entry from the queue and change its sending_date with +1 so it does not get sent immediately after in case of we had an issue (a time out execution)...
517 + //That way e-mails which can't be sent will be sent at the end and we will be able to clean the queue and don't care about what's left in the queue any more
518 + //Also it will avoid the same user to receive messages again and again and again in case of there is a problem
454 519 $firstElementQueued = reset($results);
455 520 acym_query(
456 521 'UPDATE #__acym_queue
457 522 SET sending_date = DATE_ADD(sending_date, INTERVAL 1 SECOND)
@@ -461,16 +526,16 @@
461 526
462 527 return $results;
463 528 }
464 529
465 - public function delayFailed($mailId, $userIds)
530 + public function delayFailed(int $mailId, array $userIds): void
466 531 {
467 532 acym_arrayToInteger($userIds);
468 533 if (empty($mailId) || empty($userIds)) {
469 - return false;
534 + return;
470 535 }
471 536
472 - return acym_query(
537 + acym_query(
473 538 'UPDATE #__acym_queue
474 539 SET sending_date = DATE_ADD(sending_date, INTERVAL 1 HOUR), try = try +1
475 540 WHERE mail_id = '.intval($mailId).'
476 541 AND user_id IN ('.implode(',', $userIds).')'
@@ -476,15 +541,15 @@
476 541 AND user_id IN ('.implode(',', $userIds).')'
477 542 );
478 543 }
479 544
480 - public function delayAll(int $hours)
545 + public function delayAll(int $hours): void
481 546 {
482 547 if ($hours < 1) {
483 - return false;
548 + return;
484 549 }
485 550
486 - return acym_query(
551 + acym_query(
487 552 'UPDATE #__acym_queue
488 553 SET sending_date = DATE_ADD(sending_date, INTERVAL '.$hours.' HOUR)
489 554 WHERE sending_date < DATE_ADD(NOW(), INTERVAL '.intval($hours).' HOUR)'
490 555 );
@@ -489,9 +554,9 @@
489 554 WHERE sending_date < DATE_ADD(NOW(), INTERVAL '.intval($hours).' HOUR)'
490 555 );
491 556 }
492 557
493 - public function getMailReceivers($mail, $onlyNew = false)
558 + public function getMailReceivers(object $mail, bool $onlyNew = false): AutomationHelper
494 559 {
495 560 if (empty($mail->sending_params)) {
496 561 $sendingParams = [];
497 562 $mail->filters = [];
@@ -513,11 +578,13 @@
513 578 'userlist.status = 1',
514 579 'maillist.mail_id = '.intval(empty($mail->parent_id) ? $mail->id : $mail->parent_id),
515 580 ];
516 581
582 + // Send this version only to the users with the correct language
517 583 if (!$onlyNew && acym_isMultilingual()) {
518 584 $where = 'user.language = '.acym_escapeDB($mail->language);
519 585 if ($mail->id == $mail->parent_id) {
586 + //TODO check if a user with no language will receive every versions or only the main one
520 587 $where .= ' OR user.language = "" OR user.language NOT IN (SELECT language FROM #__acym_mail WHERE parent_id = '.intval($mail->id).')';
521 588 }
522 589 $automationHelper->where[] = $where;
523 590 }
@@ -531,8 +598,9 @@
531 598 $mail->id
532 599 ).' OR id = '.intval($mail->id).')';
533 600 $automationHelper->where[] = '`us`.`user_id` IS NULL';
534 601
602 + // Do not count the disabled user for the resend counter on summary
535 603 $automationHelper->where[] = '`user`.`active` = 1';
536 604 }
537 605
538 606 $automationHelper->removeFlag(SegmentsController::FLAG_USERS);
@@ -537,12 +605,14 @@
537 605
538 606 $automationHelper->removeFlag(SegmentsController::FLAG_USERS);
539 607 $automationHelper->removeFlag(SegmentsController::FLAG_COUNT);
540 608
609 + // Handle potential segment
541 610 if (empty($mail->filters)) {
542 611 return $automationHelper;
543 612 }
544 613
614 + // Mark users matching the segment
545 615 foreach ($mail->filters as $orValues) {
546 616 if (empty($orValues)) continue;
547 617
548 618 $automationHelperSegment = new AutomationHelper();
@@ -563,11 +633,12 @@
563 633
564 634 return $automationHelper;
565 635 }
566 636
567 - public function queue($mail)
637 + public function queue(object $mail): int
568 638 {
569 639 $automationHelper = $this->getMailReceivers($mail);
640 + // Only queue enabled users
570 641 $automationHelper->where[] = '`user`.`active` = 1';
571 642
572 643 $priority = $this->config->get('priority_newsletter', 3);
573 644 $select = [intval($mail->id), 'userlist.user_id', acym_escapeDB($mail->sending_date), intval($priority), '0'];
@@ -574,19 +645,23 @@
574 645 $inserted = acym_query('INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`, `try`) ('.$automationHelper->getQuery($select).')');
575 646
576 647 $automationHelper->removeFlag(SegmentsController::FLAG_COUNT);
577 648
578 - return $inserted;
649 + return (int)$inserted;
579 650 }
580 651
581 - public function addQueue($userId, $mailId, $sendingDate)
652 + public function addQueue(int $userId, int $mailId, string $sendingDate): int
582 653 {
583 654 $priority = $this->config->get('priority_newsletter', 3);
584 655
585 - return acym_query('INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`, `try`) VALUES ('.intval($mailId).', '.intval($userId).', '.acym_escapeDB($sendingDate).', '.intval($priority).', 0)');
656 + return (int)acym_query(
657 + 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`, `try`) VALUES ('.intval($mailId).', '.intval($userId).', '.acym_escapeDB(
658 + $sendingDate
659 + ).', '.intval($priority).', 0)'
660 + );
586 661 }
587 662
588 - public function unpauseCampaign($campaignId, $active)
663 + public function unpauseCampaign(int $campaignId, int $active): void
589 664 {
590 665 if (acym_query('UPDATE #__acym_campaign SET active = '.intval($active).' WHERE id = '.intval($campaignId))) {
591 666 acym_enqueueMessage(acym_translation($active ? 'ACYM_UNPAUSE_CAMPAIGN_SUCCESSFUL' : 'ACYM_PAUSE_CAMPAIGN_SUCCESSFUL'), "success");
592 667 } else {
@@ -593,19 +668,21 @@
593 668 acym_enqueueMessage(acym_translation($active ? 'ACYM_UNPAUSE_CAMPAIGN_FAIL' : 'ACYM_PAUSE_CAMPAIGN_FAIL'), "error");
594 669 }
595 670 }
596 671
597 - public function emptyQueue()
672 + public function emptyQueue(): int
598 673 {
599 - return acym_query('DELETE FROM `#__acym_queue`');
674 + return (int)acym_query('DELETE FROM `#__acym_queue`');
600 675 }
601 676
602 - public function cleanQueue()
677 + public function cleanQueue(): int
603 678 {
604 679 $twoDaysEarlier = acym_date(time() - 172800, 'Y-m-d H:i:s', false);
605 680
606 681 $conditionUser = '`user`.`active` = 0';
607 - if ($this->config->get('require_confirmation', 1) == 1) $conditionUser .= ' OR `user`.`confirmed` = 0';
682 + if ($this->config->get('require_confirmation', 1) == 1) {
683 + $conditionUser .= ' OR `user`.`confirmed` = 0';
684 + }
608 685
609 686 $numberOfDaysToWait = $this->config->get('queue_delete_days', 0);
610 687 $conditionDateDelete = '';
611 688 if (!empty($numberOfDaysToWait)) {
@@ -612,9 +689,9 @@
612 689 $dateTimeConditionDelete = acym_date(time() - ($numberOfDaysToWait * 86400), 'Y-m-d H:i:s', false);
613 690 $conditionDateDelete = ' OR (`queue`.`sending_date` < '.acym_escapeDB($dateTimeConditionDelete).')';
614 691 }
615 692
616 - return acym_query(
693 + return (int)acym_query(
617 694 'DELETE `queue`.*
618 695 FROM `#__acym_queue` AS `queue`
619 696 JOIN `#__acym_user` AS `user` ON `queue`.`user_id` = `user`.`id`
620 697 WHERE (('.$conditionUser.') AND `queue`.`sending_date` < '.acym_escapeDB($twoDaysEarlier).') '.$conditionDateDelete
@@ -620,9 +697,9 @@
620 697 WHERE (('.$conditionUser.') AND `queue`.`sending_date` < '.acym_escapeDB($twoDaysEarlier).') '.$conditionDateDelete
621 698 );
622 699 }
623 700
624 - public function isSendingFinished($mailId): bool
701 + public function isSendingFinished(int $mailId): bool
625 702 {
626 703 $mailClass = new MailClass();
627 704 $mail = $mailClass->getOneById($mailId);
628 705