PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.1
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/FollowupClass.php +0 -704 10.11.1 → 11.1.1 View file →
@@ -1,704 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Classes;
4 -
5 -use AcyMailing\Helpers\PaginationHelper;
6 -use AcyMailing\Core\AcymClass;
7 -
8 -class FollowupClass extends AcymClass
9 -{
10 - const DEFAULT_DELAY_UNIT = 86400;
11 - const DELAY_UNIT = [
12 - 60 => 'ACYM_MINUTES',
13 - 3600 => 'ACYM_HOURS',
14 - 86400 => 'ACYM_DAYS',
15 - 604800 => 'ACYM_WEEKS',
16 - 2628000 => 'ACYM_MONTHS',
17 - ];
18 -
19 - public function __construct()
20 - {
21 - parent::__construct();
22 -
23 - $this->table = 'followup';
24 - $this->pkey = 'id';
25 - }
26 -
27 - public function getDelayUnits(): array
28 - {
29 - $return = self::DELAY_UNIT;
30 - foreach ($return as $key => $value) {
31 - $return[$key] = acym_translation($value);
32 - }
33 -
34 - return $return;
35 - }
36 -
37 - public function getMatchingElements(array $settings = []): array
38 - {
39 - $query = 'SELECT `followup`.*, COUNT(`mails`.`mail_id`) AS nbEmails
40 - FROM #__acym_followup AS followup
41 - LEFT JOIN #__acym_followup_has_mail AS mails
42 - ON followup.id = mails.followup_id';
43 -
44 - $queryCount = 'SELECT COUNT(*) AS total FROM #__acym_followup AS followup ';
45 -
46 - $filters = [];
47 -
48 - if (!empty($settings['search'])) {
49 - $filters[] = 'followup.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
50 - }
51 -
52 - if (!empty($filters)) {
53 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
54 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
55 - }
56 -
57 - $query .= ' GROUP BY `followup`.`id` ';
58 -
59 - if (empty($settings['ordering'])) $settings['ordering'] = $this->pkey;
60 - $query .= ' ORDER BY `'.acym_secureDBColumn($settings['ordering']).'`';
61 - if (!empty($settings['ordering_sort_order'])) $query .= ' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
62 -
63 - if (empty($settings['offset']) || $settings['offset'] < 0) {
64 - $settings['offset'] = 0;
65 - }
66 -
67 - if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) {
68 - $pagination = new PaginationHelper();
69 - $settings['elementsPerPage'] = $pagination->getListLimit();
70 - }
71 -
72 - $results = [];
73 - $results['elements'] = acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']);
74 - $urlClickClass = new UrlClickClass();
75 - foreach ($results['elements'] as $key => $oneFollowup) {
76 - $results['elements'][$key]->subscribers = $this->getNumberSubscribersByListId($oneFollowup->list_id);
77 - $this->getGlobalStats($results['elements'][$key], $urlClickClass);
78 - }
79 -
80 - $results['total'] = acym_loadObject($queryCount);
81 -
82 - return $results;
83 - }
84 -
85 - public function getNumberSubscribersByListId(int $listId = 0, bool $onlySubscribed = false): int
86 - {
87 - if (empty($listId)) return 0;
88 -
89 - $query = 'SELECT COUNT(*)
90 - FROM #__acym_user_has_list
91 - WHERE `list_id` = '.intval($listId);
92 -
93 - if ($onlySubscribed) {
94 - $query .= ' AND `status` = 1';
95 - }
96 -
97 - return (int)acym_loadResult($query);
98 - }
99 -
100 - private function getGlobalStats(object $element, UrlClickClass $urlClickClass): void
101 - {
102 - $mailsStats = acym_loadObjectList(
103 - 'SELECT mail_stat.*
104 - FROM #__acym_mail_stat AS mail_stat
105 - JOIN #__acym_followup_has_mail AS fhm ON fhm.mail_id = mail_stat.mail_id
106 - WHERE fhm.followup_id = '.intval($element->id)
107 - );
108 -
109 - $element->open = 0;
110 - $element->click = 0;
111 - $element->income = 0;
112 - $numberMailSent = 0;
113 - if (empty($mailsStats)) return;
114 -
115 - foreach ($mailsStats as $key => $mailsStat) {
116 - $element->open += $mailsStat->open_unique;
117 - $element->click += $urlClickClass->getNumberUsersClicked([$mailsStat->mail_id]);
118 - $numberMailSent += $mailsStat->sent;
119 - }
120 -
121 - if (!empty($numberMailSent)) {
122 - $element->open = number_format($element->open / $numberMailSent * 100, 2);
123 - $element->click = number_format($element->click / $numberMailSent * 100, 2);
124 - }
125 -
126 - if (!acym_isTrackingSalesActive()) return;
127 -
128 - $trackingSales = acym_loadObject(
129 - 'SELECT SUM(user_stat.tracking_sale) AS sale, user_stat.currency
130 - FROM #__acym_user_stat AS user_stat
131 - JOIN #__acym_followup_has_mail AS fhm ON fhm.mail_id = user_stat.mail_id
132 - WHERE fhm.followup_id = '.intval($element->id)
133 - );
134 -
135 - $element->sale = $trackingSales->sale;
136 - if (empty($element->currency)) {
137 - $element->currency = '';
138 - }
139 -
140 - acym_trigger('getCurrency', [&$element->currency]);
141 - }
142 -
143 - public function delete(array $elements): int
144 - {
145 - acym_arrayToInteger($elements);
146 -
147 - if (empty($elements)) return 0;
148 -
149 - $emailIds = $this->getEmailsByIds($elements);
150 - if (!empty($emailIds)) {
151 - $mailClass = new MailClass();
152 - $mailClass->delete($emailIds);
153 - }
154 -
155 - $listIds = $this->getListsByIds($elements);
156 -
157 - $result = parent::delete($elements);
158 -
159 - $listClass = new ListClass();
160 - $listClass->delete($listIds);
161 -
162 - return $result;
163 - }
164 -
165 - public function getEmailsByIds(array $followupIds): array
166 - {
167 - acym_arrayToInteger($followupIds);
168 -
169 - if (empty($followupIds)) {
170 - return [];
171 - }
172 -
173 - return acym_loadResultArray(
174 - 'SELECT `mail_id`
175 - FROM #__acym_followup_has_mail
176 - WHERE `followup_id` IN ('.implode(', ', $followupIds).')
177 - ORDER BY `delay`*`delay_unit` ASC'
178 - );
179 - }
180 -
181 - public function getListsByIds(array $followupIds): array
182 - {
183 - acym_arrayToInteger($followupIds);
184 -
185 - if (empty($followupIds)) {
186 - return [];
187 - }
188 -
189 - return acym_loadResultArray(
190 - 'SELECT `list_id`
191 - FROM #__acym_followup
192 - WHERE `id` IN ('.implode(', ', $followupIds).')'
193 - );
194 - }
195 -
196 - public function getOneById(int $id): ?object
197 - {
198 - $followup = parent::getOneById($id);
199 -
200 - if (empty($followup)) return null;
201 -
202 - if (!empty($followup->condition)) {
203 - $followup->condition = json_decode($followup->condition, true);
204 - }
205 -
206 - if (!empty($followup->loop_mail_skip)) {
207 - $followup->loop_mail_skip = json_decode($followup->loop_mail_skip, true);
208 - }
209 -
210 - return $followup;
211 - }
212 -
213 - public function getOneByListId(int $listId): ?object
214 - {
215 - $followup = acym_loadObject('SELECT * FROM `#__acym_followup` WHERE `list_id` = '.intval($listId));
216 -
217 - if (empty($followup)) {
218 - return null;
219 - }
220 -
221 - if (!empty($followup->condition)) {
222 - $followup->condition = json_decode($followup->condition, true);
223 - }
224 -
225 - return $followup;
226 - }
227 -
228 - public function save(object $element): ?int
229 - {
230 - if (!empty($element->condition) && is_array($element->condition)) {
231 - $element->condition = json_encode($element->condition);
232 - }
233 -
234 - if (!empty($element->loop_mail_skip) && is_array($element->loop_mail_skip)) {
235 - $element->loop_mail_skip = json_encode($element->loop_mail_skip);
236 - }
237 -
238 - $this->updateListFollowup($element);
239 -
240 - return parent::save($element);
241 - }
242 -
243 - private function updateListFollowup(object $element): void
244 - {
245 - $listClass = new ListClass();
246 - if (empty($element->list_id)) {
247 - $list = new \stdClass();
248 - $list->name = $element->display_name;
249 - $list->description = '';
250 - $list->color = '#'.implode('', [
251 - ListClass::COLOR_PARTS[rand(0, 15)],
252 - ListClass::COLOR_PARTS[rand(0, 15)],
253 - ListClass::COLOR_PARTS[rand(0, 15)],
254 - ListClass::COLOR_PARTS[rand(0, 15)],
255 - ListClass::COLOR_PARTS[rand(0, 15)],
256 - ListClass::COLOR_PARTS[rand(0, 15)],
257 - ]);
258 - $list->access = '';
259 - $list->type = ListClass::LIST_TYPE_FOLLOWUP;
260 - } else {
261 - $list = $listClass->getOneById($element->list_id);
262 - $list->name = $element->display_name;
263 - }
264 -
265 - $element->list_id = $listClass->save($list);
266 - }
267 -
268 - public function getConditionSummary(object $followup): array
269 - {
270 - $condition = $followup->condition;
271 - $statusArray = [
272 - 'is' => acym_strtolower(acym_translation('ACYM_IS')),
273 - 'is_not' => acym_strtolower(acym_translation('ACYM_IS_NOT')),
274 - ];
275 - $listClass = new ListClass();
276 - $segmentClass = new SegmentClass();
277 -
278 - $return = [];
279 - if (empty($condition['lists_status']) || empty($condition['lists'])) {
280 - $return[] = acym_translation('ACYM_NO_CONDITION_USER_SUBSCRIPTION');
281 - } else {
282 - $lists = $listClass->getListsByIds($condition['lists']);
283 - $listsToDisplay = [];
284 - foreach ($lists as $list) {
285 - $listsToDisplay[] = $list->name;
286 - }
287 -
288 - $translationKey = $followup->trigger === 'user_subscribe' ? 'ACYM_X_SUBSCRIBING_X_LIST' : 'ACYM_X_SUBSCRIBED_X_LIST';
289 - $return[] = acym_translationSprintf($translationKey, acym_strtolower($statusArray[$condition['lists_status']]), implode(',', $listsToDisplay));
290 - }
291 -
292 -
293 - if (empty($condition['segments_status']) || empty($condition['segments'])) {
294 - $return[] = acym_translation('ACYM_NO_CONDITION_SEGMENT');
295 - } else {
296 - $segments = $segmentClass->getByIds($condition['segments']);
297 - $segmentsToDisplay = [];
298 - foreach ($segments as $segment) {
299 - $segmentsToDisplay[] = $segment->name;
300 - }
301 - $return[] = acym_translationSprintf('ACYM_X_PART_X_SEGMENT', acym_strtolower($statusArray[$condition['segments_status']]), implode(',', $segmentsToDisplay));
302 - }
303 -
304 - acym_trigger('getFollowupConditionSummary', [&$return, $condition, $followup->trigger, $statusArray]);
305 -
306 - return $return;
307 - }
308 -
309 - private function getKeyMailArray(int $key, array $mailsKey): int
310 - {
311 - if (!empty($mailsKey) && in_array($key, $mailsKey)) {
312 - return $this->getKeyMailArray(++$key, $mailsKey);
313 - }
314 -
315 - return $key;
316 - }
317 -
318 - public function getOneByIdWithMails(int $id): ?object
319 - {
320 - $followup = $this->getOneById($id);
321 -
322 - if (empty($followup)) {
323 - return null;
324 - }
325 -
326 - $mailClass = new MailClass();
327 - $mails = $mailClass->decode(
328 - acym_loadObjectList(
329 - 'SELECT mail.subject, mail.id, followup_mail.delay, followup_mail.delay_unit
330 - FROM #__acym_mail AS mail
331 - JOIN #__acym_followup_has_mail AS followup_mail ON mail.id = followup_mail.mail_id AND followup_mail.followup_id = '.intval($id),
332 - 'id'
333 - )
334 - );
335 -
336 - $return = [];
337 - foreach ($mails as $key => $mail) {
338 - $mail->delay_display = $this->getDelayDisplay($mail->delay, $mail->delay_unit);
339 - $mail->edit_link = acym_completeLink('mails&task=edit&step=editEmail&type=followup&id='.$key.'&followup_id='.$id.'&return='.urlencode(acym_currentURL()), false, true);
340 - $finalKey = $this->getKeyMailArray(intval($mail->delay) * intval($mail->delay_unit), array_keys($return));
341 - $return[$finalKey] = $mail;
342 - }
343 -
344 - ksort($return);
345 -
346 - $followup->mails = empty($return) ? [] : $return;
347 -
348 - return $followup;
349 - }
350 -
351 - private function getDelayDisplay(int $delay, int $delayUnit): string
352 - {
353 - $delayUnits = $this->getDelayUnits();
354 -
355 - return acym_translationSprintf('ACYM_X_PLUS_X_FOLLOW_UP', $delayUnits[$delayUnit], $delay);
356 - }
357 -
358 - public function getDelaySettingToMail(object $mail, int $followupId): bool
359 - {
360 - $settings = acym_loadObject('SELECT delay, delay_unit FROM #__acym_followup_has_mail WHERE followup_id = '.intval($followupId).' AND mail_id = '.intval($mail->id));
361 -
362 - if (empty($settings)) {
363 - return false;
364 - }
365 -
366 - $mail->delay = $settings->delay;
367 - $mail->delay_unit = $settings->delay_unit;
368 -
369 - return true;
370 - }
371 -
372 - public function saveDelaySettings(array $followupData, int $mailId): bool
373 - {
374 - if (empty($followupData['id']) || empty($followupData['delay_unit']) || empty($mailId)) {
375 - return false;
376 - }
377 -
378 - acym_arrayToInteger($followupData);
379 -
380 - $affectedRow = acym_query(
381 - 'INSERT INTO #__acym_followup_has_mail (`mail_id`, `followup_id`, `delay`, `delay_unit`) VALUE ('.intval(
382 - $mailId
383 - ).', '.$followupData['id'].', '.$followupData['delay'].', '.$followupData['delay_unit'].') ON DUPLICATE KEY UPDATE delay = '.$followupData['delay'].', delay_unit = '.$followupData['delay_unit'].''
384 - );
385 -
386 - return $affectedRow !== false;
387 - }
388 -
389 - public function duplicateMail(int $mailId, int $id): bool
390 - {
391 - if (empty($mailId) || empty($id)) {
392 - return false;
393 - }
394 -
395 - $mailClass = new MailClass();
396 - $mail = $mailClass->getOneById($mailId);
397 -
398 - if (empty($mail)) {
399 - return false;
400 - }
401 -
402 - $delaySettings = new \stdClass();
403 - $delaySettings->id = $mail->id;
404 - $this->getDelaySettingToMail($delaySettings, $id);
405 -
406 - unset($mail->id);
407 - $mail->name .= '_copy';
408 -
409 - $mail->id = $mailClass->save($mail);
410 - if (empty($mail->id)) {
411 - return false;
412 - }
413 -
414 - $affectedRow = acym_query(
415 - 'INSERT INTO #__acym_followup_has_mail (`mail_id`, `followup_id`, `delay`, `delay_unit`) VALUE ('.intval($mail->id).', '.$id.', '.intval(
416 - $delaySettings->delay
417 - ).', '.intval($delaySettings->delay_unit).')'
418 - );
419 -
420 - return !empty($affectedRow);
421 - }
422 -
423 - public function deleteMail(int $mailId): bool
424 - {
425 - if (empty($mailId)) {
426 - return false;
427 - }
428 -
429 - $mailClass = new MailClass();
430 -
431 - return (bool)$mailClass->delete([$mailId]);
432 - }
433 -
434 - public function getFollowupsWithMailsInfoByIds(array $followupIds): array
435 - {
436 - acym_arrayToInteger($followupIds);
437 -
438 - $mailsInfo = acym_loadObjectList(
439 - 'SELECT followup_mail.*, followup.send_once
440 - FROM #__acym_followup_has_mail AS followup_mail
441 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup_mail.followup_id IN ('.implode(',', $followupIds).')'
442 - );
443 -
444 - if (empty($mailsInfo)) {
445 - return [];
446 - }
447 -
448 - $return = [];
449 -
450 - foreach ($mailsInfo as $mailInfo) {
451 - if (!isset($return[$mailInfo->followup_id])) $return[$mailInfo->followup_id] = [];
452 - $return[$mailInfo->followup_id][] = $mailInfo;
453 - }
454 -
455 - return $return;
456 - }
457 -
458 - public function subscribeUserToFollowupList(array $followupIds, $userId): array
459 - {
460 - acym_arrayToInteger($followupIds);
461 -
462 - $followupLists = acym_loadObjectList(
463 - 'SELECT followup.list_id, IF(user_list.status IS NULL, "", status) AS status, followup.id, followup.send_once FROM #__acym_followup AS followup
464 - LEFT JOIN #__acym_user_has_list AS user_list ON followup.list_id = user_list.list_id AND (user_list.user_id = '.intval($userId).' OR user_list.user_id IS NULL)
465 - WHERE followup.id IN ('.implode(',', $followupIds).')',
466 - 'list_id'
467 - );
468 -
469 - if (empty($followupLists)) {
470 - return [];
471 - }
472 -
473 - $followupListIds = [];
474 - foreach ($followupLists as $listId => $followupList) {
475 - if (in_array($followupList->status, [0, '0'], true)) {
476 - continue;
477 - }
478 -
479 - if ($followupList->status === '' || $followupList->send_once == 0) {
480 - $followupListIds[$listId] = $followupList->id;
481 - }
482 - }
483 -
484 - if (empty($followupListIds)) {
485 - return [];
486 - }
487 -
488 - $userClass = new UserClass();
489 - $userClass->subscribe([$userId], array_keys($followupListIds), false);
490 -
491 - return $followupListIds;
492 - }
493 -
494 - public function addFollowupEmailsQueue(string $followupTrigger, int $userId, array $params = []): bool
495 - {
496 - if (empty($followupTrigger) || empty($userId)) {
497 - return false;
498 - }
499 -
500 - $followupToTrigger = acym_loadObjectList('SELECT * FROM #__acym_followup WHERE active = 1 AND `trigger` = '.acym_escapeDB($followupTrigger), 'id');
501 -
502 - if (empty($followupToTrigger)) {
503 - return false;
504 - }
505 -
506 - foreach ($followupToTrigger as $key => $followup) {
507 - if (!empty($followup->condition)) {
508 - $followupToTrigger[$key]->condition = json_decode($followup->condition, true);
509 - }
510 - }
511 -
512 - acym_trigger('matchFollowupsConditions', [&$followupToTrigger, $userId, $params]);
513 -
514 - if (empty($followupToTrigger)) {
515 - return false;
516 - }
517 -
518 - $followupIds = $this->subscribeUserToFollowupList(array_keys($followupToTrigger), $userId);
519 -
520 - if (empty($followupIds)) {
521 - return false;
522 - }
523 -
524 - $followups = $this->getFollowupsWithMailsInfoByIds($followupIds);
525 -
526 - if (empty($followups)) {
527 - return false;
528 - }
529 -
530 - $priority = $this->config->get('followup_max_priority', 0) == 1 ? 1 : 2;
531 -
532 - $valuesToInsert = [];
533 -
534 - foreach ($followups as $followupId => $mailsInfo) {
535 - foreach ($mailsInfo as $mailInfo) {
536 - $sendDate = time() + (intval($mailInfo->delay) * intval($mailInfo->delay_unit));
537 - $sendDate = acym_date($sendDate, 'Y-m-d H:i:s', false);
538 - $valuesToInsert[] = ' ('.intval($mailInfo->mail_id).', '.intval($userId).', '.acym_escapeDB($sendDate).', '.intval($priority).', '.acym_escapeDB(
539 - json_encode($params)
540 - ).') ';
541 - $this->addMailStat($mailInfo->mail_id);
542 - }
543 - $followupToTrigger[$followupId]->last_trigger = time();
544 - $this->save($followupToTrigger[$followupId]);
545 - }
546 -
547 - $query = 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`, `params`) VALUES '.implode(',', $valuesToInsert);
548 -
549 - $affectedRows = acym_query($query);
550 -
551 - return !empty($affectedRows);
552 - }
553 -
554 - private function addMailStat(int $mailId): void
555 - {
556 - $mailStatClass = new MailStatClass();
557 - $mailStat = $mailStatClass->getOneRowByMailId($mailId);
558 - $newMailStat = new \stdClass();
559 - $newMailStat->mail_id = intval($mailId);
560 - $newMailStat->total_subscribers = 1;
561 -
562 - if (empty($mailStat)) {
563 - $newMailStat->send_date = acym_date('now', 'Y-m-d H:i:s', false);
564 - }
565 -
566 - $mailStatClass->save($newMailStat);
567 - }
568 -
569 - public function getFollowupDailyBases(): array
570 - {
571 - $triggers = [];
572 - acym_trigger('onAcymGetFollowupDailyBases', [&$triggers]);
573 -
574 - if (empty($triggers)) {
575 - return [];
576 - }
577 -
578 - $safeTriggers = array_map('acym_escapeDB', $triggers);
579 -
580 - return acym_loadObjectList('SELECT * FROM #__acym_followup WHERE `trigger` IN ('.implode(',', $safeTriggers).') AND active = 1');
581 - }
582 -
583 - public function queueForSubscribers(int $emailId): bool
584 - {
585 - if (empty($emailId)) {
586 - return false;
587 - }
588 -
589 - $mailInfo = acym_loadObject(
590 - 'SELECT map.*, followup.list_id
591 - FROM #__acym_followup_has_mail AS map
592 - JOIN #__acym_followup AS followup
593 - ON followup.id = map.followup_id
594 - WHERE map.mail_id = '.intval($emailId)
595 - );
596 - if (empty($mailInfo)) return false;
597 -
598 - $this->addMailStat($mailInfo->mail_id);
599 -
600 - $delay = intval($mailInfo->delay) * intval($mailInfo->delay_unit);
601 - $query = 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`)
602 - SELECT '.intval($mailInfo->mail_id).', user_id, TIMESTAMPADD(SECOND, '.$delay.', subscription_date), 2
603 - FROM #__acym_user_has_list
604 - WHERE status = 1
605 - AND list_id = '.intval($mailInfo->list_id);
606 -
607 - return (bool)acym_query($query);
608 - }
609 -
610 - public function getXFollowups(array $options): array
611 - {
612 - $limit = $options['limit'] ?? 10;
613 - $offset = $options['offset'] ?? 0;
614 - $filters = $options['filters'] ?? [];
615 -
616 - $conditions = [];
617 - foreach ($filters as $column => $filter) {
618 - switch ($column) {
619 - case 'id':
620 - case 'active':
621 - case 'send_one':
622 - $conditions[] = acym_secureDBColumn($column).' = '.intval($filter);
623 - break;
624 - case 'name':
625 - case 'trigger':
626 - case 'display_name':
627 - $conditions[] = '`'.acym_secureDBColumn($column).'` LIKE '.acym_escapeDB('%'.$filter.'%');
628 - break;
629 - default:
630 - $conditions[] = acym_secureDBColumn($column).' = '.acym_escapeDB('%'.$filter.'%');
631 - }
632 - }
633 -
634 - $query = 'SELECT * FROM #__acym_followup ';
635 -
636 - if (!empty($conditions)) {
637 - $query .= ' WHERE '.implode(' AND ', $conditions);
638 - }
639 -
640 - $followUps = acym_loadObjectList($query, $this->pkey, $offset, $limit);
641 -
642 - if (empty($followUps)) {
643 - return [];
644 - }
645 -
646 - foreach ($followUps as &$followUp) {
647 - if (!empty($followUp->condition)) {
648 - $followUp->condition = json_decode($followUp->condition, true);
649 - }
650 - }
651 -
652 - return $followUps;
653 - }
654 -
655 - public function getOneByMailId(int $mailId): ?object
656 - {
657 - return acym_loadObject(
658 - 'SELECT followup.*
659 - FROM #__acym_followup AS followup
660 - JOIN #__acym_followup_has_mail AS map
661 - ON followup.id = map.followup_id
662 - WHERE mail_id = '.intval($mailId)
663 - );
664 - }
665 -
666 - public function getLastEmail(int $followupId): object
667 - {
668 - return acym_loadObject(
669 - 'SELECT mail_id as id, delay * delay_unit as totalDelay FROM #__acym_followup_has_mail WHERE followup_id = '.intval($followupId).' ORDER BY totalDelay DESC'
670 - );
671 - }
672 -
673 - public function triggerFollowUp(int $followUpId, int $userId, int $additionalDelay = 0, array $mailIdToSkip = []): void
674 - {
675 - $followUp = $this->getOneById($followUpId);
676 -
677 - if (empty($followUp)) {
678 - return;
679 - }
680 -
681 - $values = intval($userId).', '.intval($followUp->list_id).', 1, '.acym_escapeDB(acym_date(time(), 'Y-m-d H:i:s'));
682 -
683 - acym_query('INSERT IGNORE INTO #__acym_user_has_list (`user_id`, `list_id`, `status`, `subscription_date`) VALUES ('.$values.') ON DUPLICATE KEY UPDATE status = 1');
684 -
685 - $followups = $this->getFollowupsWithMailsInfoByIds([$followUpId]);
686 - $allValues = [];
687 - foreach ($followups as $mails) {
688 - foreach ($mails as $mail) {
689 - if (in_array($mail->mail_id, $mailIdToSkip)) {
690 - continue;
691 - }
692 - $sendDate = time() + (intval($mail->delay) * intval($mail->delay_unit)) + $additionalDelay;
693 - $sendDate = acym_escapeDB(acym_date($sendDate, 'Y-m-d H:i:s', false));
694 - $allValues[] = '('.intval($mail->mail_id).', '.intval($userId).', '.$sendDate.', '.$this->config->get('priority_newsletter', 3).', 0'.')';
695 - }
696 - }
697 -
698 - $queryToProcess = 'INSERT IGNORE INTO #__acym_queue (`mail_id`, `user_id`, `sending_date`, `priority`, `try`) VALUES '.implode(', ', $allValues);
699 -
700 - if (empty(acym_query($queryToProcess))) {
701 - acym_logError("Error adding follow up email to queue \n Values: ".implode(', ', $allValues)." \n Error: ".acym_getDBError());
702 - }
703 - }
704 -}