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/ListClass.php +0 -1017 10.11.1 → 11.1.1 View file →
@@ -1,1017 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Classes;
4 -
5 -use AcyMailing\Helpers\MailerHelper;
6 -use AcyMailing\Helpers\PaginationHelper;
7 -use AcyMailing\Core\AcymClass;
8 -
9 -class ListClass extends AcymClass
10 -{
11 - const LIST_TYPE_STANDARD = 'standard';
12 - const LIST_TYPE_FRONT = 'front';
13 - const LIST_TYPE_FOLLOWUP = 'followup';
14 - const COLOR_PARTS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
15 -
16 - public function __construct()
17 - {
18 - parent::__construct();
19 -
20 - $this->table = 'list';
21 - $this->pkey = 'id';
22 - }
23 -
24 - public function getMatchingElements(array $settings = []): array
25 - {
26 - $columns = 'list.*';
27 - if (!empty($settings['columns'])) {
28 - foreach ($settings['columns'] as $key => $value) {
29 - if ($value == 'lists.list_id') {
30 - unset($settings['columns'][$key]);
31 - continue;
32 - }
33 - $settings['columns'][$key] = $key === 'join' ? acym_secureDBColumn($value) : 'list.'.acym_secureDBColumn($value);
34 - }
35 - $columns = implode(', ', $settings['columns']);
36 - }
37 -
38 - $query = 'SELECT '.$columns.' FROM #__acym_list AS list';
39 - $queryCount = 'SELECT COUNT(list.id) AS total FROM #__acym_list AS list';
40 - if (!empty($settings['join'])) $query .= $this->getJoinForQuery($settings['join']);
41 - $queryStatus = 'SELECT COUNT(id) AS number, active + (visible*2) AS score FROM #__acym_list AS list';
42 - $filters = [];
43 - $listsId = [];
44 -
45 - if (!empty($settings['tag'])) {
46 - $tagJoin = ' JOIN #__acym_tag AS tag ON list.id = tag.id_element';
47 - $query .= $tagJoin;
48 - $queryCount .= $tagJoin;
49 - $queryStatus .= $tagJoin;
50 - $filters[] = 'tag.name = '.acym_escapeDB($settings['tag']);
51 - $filters[] = 'tag.type = "list"';
52 - }
53 -
54 - if (!empty($settings['search'])) {
55 - $filters[] = 'list.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
56 - }
57 -
58 - if (!empty($settings['creator_id']) && !acym_isAdmin()) {
59 - $userGroups = acym_getGroupsByUser($settings['creator_id']);
60 - $groupCondition = '(list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%")';
61 -
62 - $filters[] = 'list.cms_user_id = '.intval($settings['creator_id']).' OR '.$groupCondition.'';
63 - }
64 -
65 - $filters[] = 'list.type = '.acym_escapeDB(self::LIST_TYPE_STANDARD);
66 -
67 - if (!empty($filters)) {
68 - $queryStatus .= ' WHERE ('.implode(') AND (', $filters).')';
69 - }
70 -
71 - if (!empty($settings['status'])) {
72 - $allowedStatus = [
73 - 'active' => 'active = 1',
74 - 'inactive' => 'active = 0',
75 - 'visible' => 'visible = 1',
76 - 'invisible' => 'visible = 0',
77 - ];
78 - if (empty($allowedStatus[$settings['status']])) {
79 - die('Injection denied');
80 - }
81 - $filters[] = 'list.'.$allowedStatus[$settings['status']];
82 - }
83 -
84 - if (!empty($settings['where'])) {
85 - $filters[] = $settings['where'];
86 - }
87 -
88 -
89 - if (!empty($filters)) {
90 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
91 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
92 - }
93 -
94 - if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
95 - $query .= ' ORDER BY list.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
96 - }
97 -
98 - if (empty($settings['offset']) || $settings['offset'] < 0) {
99 - $settings['offset'] = 0;
100 - }
101 -
102 - if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) {
103 - $pagination = new PaginationHelper();
104 - $settings['elementsPerPage'] = $pagination->getListLimit();
105 - }
106 -
107 - $results['elements'] = acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']);
108 - if (!empty($settings['join'])) {
109 - $this->setSelectedList($results['elements'], $settings['join']);
110 - }
111 - foreach ($results['elements'] as $i => $oneList) {
112 - $listsId[] = $oneList->id;
113 - $results['elements'][$i]->sendable_users = 0;
114 - $results['elements'][$i]->unconfirmed_users = 0;
115 - $results['elements'][$i]->unsubscribed_users = 0;
116 - $results['elements'][$i]->inactive_users = 0;
117 - $results['elements'][$i]->newSub = 0;
118 - $results['elements'][$i]->newUnsub = 0;
119 - }
120 -
121 - $countUserByList = [];
122 - $countEvolByList = [];
123 - if (!empty($listsId) && empty($settings['entitySelect'])) {
124 - $countUserByList = $this->getSubscribersCountPerStatusByListIds($listsId);
125 - $countEvolByList = $this->getSubscribersEvolutionByListIds($listsId);
126 - }
127 -
128 - foreach ($results['elements'] as $i => $list) {
129 - $results['elements'][$i]->tags = [];
130 - foreach ($countUserByList as $userList) {
131 - if ($list->id == $userList->list_id) {
132 - $results['elements'][$i]->sendable_users = $userList->sendable_users;
133 - $results['elements'][$i]->unconfirmed_users = $userList->unconfirmed_users;
134 - $results['elements'][$i]->unsubscribed_users = $userList->unsubscribed_users;
135 - $results['elements'][$i]->inactive_users = $userList->inactive_users;
136 - }
137 - }
138 - if (isset($countEvolByList[$list->id]->newSub)) $results['elements'][$i]->newSub = $countEvolByList[$list->id]->newSub;
139 - if (isset($countEvolByList[$list->id]->newUnsub)) $results['elements'][$i]->newUnsub = $countEvolByList[$list->id]->newUnsub;
140 - }
141 -
142 - $results['total'] = acym_loadObject($queryCount);
143 -
144 - $listsPerStatus = acym_loadObjectList($queryStatus.' GROUP BY score', 'score');
145 - for ($i = 0; $i < 4; $i++) {
146 - $listsPerStatus[$i] = empty($listsPerStatus[$i]) ? 0 : $listsPerStatus[$i]->number;
147 - }
148 -
149 - $results['status'] = [
150 - 'all' => array_sum($listsPerStatus),
151 - 'active' => $listsPerStatus[1] + $listsPerStatus[3],
152 - 'inactive' => $listsPerStatus[0] + $listsPerStatus[2],
153 - 'visible' => $listsPerStatus[2] + $listsPerStatus[3],
154 - 'invisible' => $listsPerStatus[0] + $listsPerStatus[1],
155 - ];
156 -
157 - return $results;
158 - }
159 -
160 - public function getOneById(int $id): ?object
161 - {
162 - $list = parent::getOneById($id);
163 -
164 - if (!empty($list)) {
165 - $list->translation = empty($list->translation) ? [] : json_decode($list->translation, true);
166 - }
167 -
168 - return $list;
169 - }
170 -
171 - private function setSelectedList(array $elements, string $join): void
172 - {
173 - if (strpos($join, 'join_list') === false) {
174 - return;
175 - }
176 -
177 - $listsIds = explode('-', $join);
178 - $listsIds = $listsIds[1];
179 - $listsIds = explode(',', $listsIds);
180 - foreach ($elements as $element) {
181 - $element->list_id = in_array($element->id, $listsIds) ? $element->id : null;
182 - }
183 - }
184 -
185 - private function getJoinForQuery(string $joinType): string
186 - {
187 - if (strpos($joinType, 'join_mail') !== false) {
188 - $mailId = explode('-', $joinType);
189 -
190 - return ' LEFT JOIN #__acym_mail_has_list as maillist ON list.id = maillist.list_id AND maillist.mail_id = '.intval($mailId[1]);
191 - }
192 - if (strpos($joinType, 'join_user') !== false) {
193 - $userId = explode('-', $joinType);
194 -
195 - return ' LEFT JOIN #__acym_user_has_list as userlist ON list.id = userlist.list_id AND userlist.status = 1 AND userlist.user_id = '.intval($userId[1]);
196 - }
197 -
198 - return '';
199 - }
200 -
201 - public function getListsWithIdNameCount(array $settings): array
202 - {
203 - $filters = [];
204 -
205 - if (isset($settings['ids'])) {
206 - if (empty($settings['ids'])) {
207 - return ['lists' => [], 'total' => 0];
208 - } else {
209 - acym_arrayToInteger($settings['ids']);
210 - $filters[] = 'list.id IN ('.implode(',', $settings['ids']).')';
211 - }
212 - }
213 -
214 - $query = 'SELECT list.id, list.name, list.color, list.active, COUNT(user.id) AS subscribers
215 - FROM #__acym_list AS list
216 - LEFT JOIN #__acym_user_has_list AS userList
217 - ON list.id = userList.list_id
218 - AND userList.status = 1
219 - LEFT JOIN #__acym_user AS user
220 - ON user.id = userList.user_id
221 - AND user.active = 1 ';
222 -
223 - if (intval($this->config->get('require_confirmation', 1)) === 1) {
224 - $query .= ' AND user.confirmed = 1 ';
225 - }
226 -
227 - $queryCount = 'SELECT COUNT(list.id) FROM #__acym_list AS list';
228 -
229 - if (!acym_isAdmin()) {
230 - $currentUserId = acym_currentUserId();
231 - if (empty($currentUserId)) {
232 - return [
233 - 'lists' => [],
234 - 'total' => 0,
235 - ];
236 - }
237 -
238 - $userGroups = acym_getGroupsByUser($currentUserId);
239 - $groupCondition = '(list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%")';
240 -
241 - $filters[] = 'list.cms_user_id = '.intval($currentUserId).' OR '.$groupCondition;
242 - }
243 -
244 - if (!empty($settings['search'])) {
245 - $filters[] = 'list.name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
246 - }
247 -
248 - if (!empty($settings['already'])) {
249 - acym_arrayToInteger($settings['already']);
250 - $filters[] = 'list.id NOT IN('.implode(',', $settings['already']).')';
251 - }
252 - $filters[] = 'list.type = '.acym_escapeDB(self::LIST_TYPE_STANDARD);
253 -
254 - if (!empty($filters)) {
255 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
256 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
257 - }
258 -
259 - $query .= ' GROUP BY list.id ';
260 -
261 - return [
262 - 'lists' => acym_loadObjectList($query, '', $settings['offset'], $settings['listsPerPage']),
263 - 'total' => (int)acym_loadResult($queryCount),
264 - ];
265 - }
266 -
267 - public function getListsByIds(array $ids): array
268 - {
269 - acym_arrayToInteger($ids);
270 - if (empty($ids)) {
271 - return [];
272 - }
273 -
274 - $query = 'SELECT * FROM #__acym_list WHERE id IN ('.implode(', ', $ids).')';
275 -
276 - return acym_loadObjectList($query);
277 - }
278 -
279 - public function getSubscribersCount(array $listsIds): int
280 - {
281 - acym_arrayToInteger($listsIds);
282 - if (empty($listsIds)) {
283 - return 0;
284 - }
285 -
286 - $query = 'SELECT COUNT(DISTINCT user.id)
287 - FROM #__acym_user AS user
288 - JOIN #__acym_user_has_list AS userList ON user.id = userList.user_id
289 - WHERE userList.list_id IN ('.implode(",", $listsIds).') AND userList.status = 1 AND user.active = 1';
290 -
291 - if ($this->config->get('require_confirmation', 1) == 1) {
292 - $query .= ' AND user.confirmed = 1';
293 - }
294 -
295 - return (int)acym_loadResult($query);
296 - }
297 -
298 - public function getSubscribersForList(array $options = []): array
299 - {
300 - $listIds = $options['listIds'] ?? [];
301 - $offset = $options['offset'] ?? 0;
302 - $limit = $options['limit'] ?? 100;
303 - $status = $options['status'] ?? null;
304 - $orderBy = $options['orderBy'] ?? '';
305 - $orderBySort = $options['orderBySort'] ?? '';
306 - $subscribedAfter = $options['subscribed_after'] ?? null;
307 - $unsubscribedAfter = $options['unsubscribed_after'] ?? null;
308 -
309 - if (empty($listIds)) {
310 - return [];
311 - }
312 -
313 - acym_arrayToInteger($listIds);
314 -
315 - $statusCondition = '';
316 - if (!is_null($status)) {
317 - $statusCondition .= ' AND user_list.status = '.intval($status);
318 - }
319 -
320 - if (!empty($subscribedAfter)) {
321 - $statusCondition .= ' AND user_list.subscription_date > '.acym_escapeDB($subscribedAfter);
322 - }
323 -
324 - if (!empty($unsubscribedAfter)) {
325 - $statusCondition .= ' AND user_list.unsubscribe_date > '.acym_escapeDB($unsubscribedAfter);
326 - }
327 -
328 - $requestSub = 'SELECT user.*, user_list.status, user_list.subscription_date, user_list.unsubscribe_date FROM #__acym_user AS user';
329 - $requestSub .= ' LEFT JOIN #__acym_user_has_list AS user_list ON user.id = user_list.user_id';
330 - $requestSub .= ' WHERE user.active = 1 AND user_list.list_id IN ('.implode(', ', $listIds).')'.$statusCondition;
331 -
332 - if (!empty($orderBy)) {
333 - if (empty($orderBySort)) $orderBySort = 'desc';
334 - $requestSub .= ' ORDER BY '.acym_secureDBColumn($orderBy).' '.acym_secureDBColumn($orderBySort);
335 - }
336 -
337 - return acym_loadObjectList(
338 - $requestSub,
339 - '',
340 - $offset,
341 - $limit
342 - );
343 - }
344 -
345 - public function delete(array $elements, bool $force = false): int
346 - {
347 - if (!$force) {
348 - $this->onlyManageableLists($elements);
349 - }
350 -
351 - if (empty($elements)) {
352 - return 0;
353 - }
354 -
355 - foreach ($elements as $id) {
356 - acym_query('DELETE FROM #__acym_mail_has_list WHERE list_id = '.intval($id));
357 - acym_query('DELETE FROM #__acym_user_has_list WHERE list_id = '.intval($id));
358 - acym_query('DELETE FROM #__acym_tag WHERE `id_element` = '.intval($id).' AND `type` = "list"');
359 - }
360 -
361 - return parent::delete($elements);
362 - }
363 -
364 - public function synchDeleteCmsList(int $userId): void
365 - {
366 - $query = 'SELECT * FROM #__acym_list WHERE type = "'.self::LIST_TYPE_FRONT.'" AND cms_user_id = '.intval($userId);
367 - $listFrontManagement = acym_loadObject($query);
368 - if (!empty($listFrontManagement)) {
369 - $this->delete([$listFrontManagement->id]);
370 - }
371 - }
372 -
373 - public function save(object $list): ?int
374 - {
375 - if (isset($list->tags)) {
376 - $tags = $list->tags;
377 - unset($list->tags);
378 - }
379 -
380 - $oldList = null;
381 -
382 - if (empty($list->id)) {
383 - if (empty($list->cms_user_id)) {
384 - $list->cms_user_id = acym_currentUserId();
385 - }
386 -
387 - $list->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
388 - } else {
389 - $oldList = $this->getOneById($list->id);
390 - }
391 -
392 - if (!empty($list->translation)) {
393 - if (is_array($list->translation)) $list->translation = json_encode($list->translation);
394 - } else {
395 - $list->translation = '';
396 - }
397 -
398 - foreach ($list as $oneAttribute => $value) {
399 - if (empty($value)) continue;
400 -
401 - $list->$oneAttribute = strip_tags($value);
402 - }
403 -
404 - if (empty($list->description)) {
405 - $list->description = '';
406 - }
407 -
408 - if (!isset($list->access) && empty($list->id)) {
409 - $list->access = '';
410 - }
411 -
412 - if (empty($list->id)) {
413 - acym_trigger('onAcymBeforeListCreate', [&$list]);
414 - } else {
415 - acym_trigger('onAcymBeforeListModify', [&$list]);
416 - }
417 -
418 - $listID = parent::save($list);
419 -
420 - if (empty($listID)) {
421 - return null;
422 - }
423 -
424 - if (isset($tags)) {
425 - $tagClass = new TagClass();
426 - $tagClass->setTags(TagClass::TYPE_LIST, intval($listID), $tags);
427 - }
428 -
429 - $list->id = $listID;
430 -
431 - if (is_null($oldList)) {
432 - acym_trigger('onAcymAfterListCreate', [&$list]);
433 - } else {
434 - acym_trigger('onAcymAfterListModify', [&$list, &$oldList]);
435 - }
436 -
437 - return $listID;
438 - }
439 -
440 - public function getAllWithIdName(): array
441 - {
442 - $endQuery = '';
443 - if (!acym_isAdmin()) {
444 - $creatorId = acym_currentUserId();
445 -
446 - $userGroups = acym_getGroupsByUser($creatorId);
447 - $groupCondition = '(access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%")';
448 -
449 - $endQuery = ' AND (cms_user_id = '.intval($creatorId).' OR '.$groupCondition.')';
450 - }
451 - $lists = acym_loadObjectList('SELECT id, name FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_STANDARD).$endQuery, 'id');
452 -
453 - $listsToReturn = [];
454 -
455 - foreach ($lists as $key => $list) {
456 - $listsToReturn[$key] = $list->name;
457 - }
458 -
459 - return $listsToReturn;
460 - }
461 -
462 - public function getAllForSelect(bool $emptyFirst = true, int $userFrontID = 0, bool $needTranslation = false, bool $needFrontLabel = false): array
463 - {
464 - $groupCondition = '';
465 - if (!empty($userFrontID)) {
466 - $userGroups = acym_getGroupsByUser($userFrontID);
467 - $groupCondition = ' AND (cms_user_id = '.intval($userFrontID).' OR (access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%"))';
468 - }
469 -
470 - $lists = acym_loadObjectList('SELECT * FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_STANDARD).$groupCondition, 'id');
471 -
472 - if (acym_isMultilingual() && $needTranslation) {
473 - $lists = $this->getTranslatedNameDescription($lists);
474 - }
475 -
476 - $return = [];
477 -
478 - if ($emptyFirst) {
479 - $return[''] = acym_translation('ACYM_SELECT_A_LIST');
480 - }
481 -
482 - foreach ($lists as $key => $list) {
483 - $return[$key] = $needFrontLabel && !empty($list->display_name) ? $list->display_name : $list->name;
484 - }
485 -
486 - return $return;
487 - }
488 -
489 - public function getAllWithoutManagement(bool $needTranslation = false): array
490 - {
491 - $lists = acym_loadObjectList('SELECT * FROM #__acym_list WHERE `type` = '.acym_escapeDB(self::LIST_TYPE_STANDARD), 'id');
492 -
493 - if (acym_isMultilingual() && $needTranslation) {
494 - $lists = $this->getTranslatedNameDescription($lists);
495 - }
496 -
497 - return $lists;
498 - }
499 -
500 - public function getTranslatedNameDescription(array $lists): array
501 - {
502 - $currentLanguageTag = acym_getLanguageTag();
503 - foreach ($lists as $id => $list) {
504 - if (empty($list->translation)) continue;
505 -
506 - $list->translation = json_decode($list->translation, true);
507 - if (!empty($list->translation[$currentLanguageTag])) {
508 - if (!empty($list->translation[$currentLanguageTag]['name'])) {
509 - $list->name = $list->translation[$currentLanguageTag]['name'];
510 - }
511 -
512 - if (!empty($list->translation[$currentLanguageTag]['display_name'])) {
513 - $list->display_name = $list->translation[$currentLanguageTag]['display_name'];
514 - }
515 -
516 - if (!empty($list->translation[$currentLanguageTag]['description'])) {
517 - $list->description = $list->translation[$currentLanguageTag]['description'];
518 - }
519 - }
520 - }
521 -
522 - return $lists;
523 - }
524 -
525 - public function sendWelcome(int $userID, array $listIDs, bool $forceFront = false): void
526 - {
527 - if (!$forceFront && acym_isAdmin()) {
528 - return;
529 - }
530 -
531 - acym_arrayToInteger($listIDs);
532 - if (empty($listIDs)) {
533 - return;
534 - }
535 -
536 - $messages = acym_loadObjectList('SELECT `welcome_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1');
537 -
538 - if (empty($messages)) {
539 - return;
540 - }
541 -
542 - $alreadySent = [];
543 - $mailerHelper = new MailerHelper();
544 - $mailerHelper->report = (bool)$this->config->get('welcome_message', 1);
545 - foreach ($messages as $oneMessage) {
546 - $mailid = $oneMessage->welcome_id;
547 - if (empty($mailid)) continue;
548 -
549 - if (isset($alreadySent[$mailid])) {
550 - continue;
551 - }
552 -
553 - $mailerHelper->trackEmail = true;
554 - $mailerHelper->sendOne($mailid, $userID);
555 - $alreadySent[$mailid] = true;
556 - }
557 - }
558 -
559 - public function sendUnsubscribe(int $userID, array $listIDs): void
560 - {
561 - if (acym_isAdmin()) {
562 - return;
563 - }
564 -
565 - acym_arrayToInteger($listIDs);
566 - if (empty($listIDs)) {
567 - return;
568 - }
569 -
570 - $messages = acym_loadObjectList('SELECT `unsubscribe_id` FROM #__acym_list WHERE `id` IN ('.implode(',', $listIDs).') AND `active` = 1');
571 -
572 - if (empty($messages)) {
573 - return;
574 - }
575 -
576 - $alreadySent = [];
577 - $mailerHelper = new MailerHelper();
578 - $mailerHelper->report = (bool)$this->config->get('unsub_message', 1);
579 - foreach ($messages as $oneMessage) {
580 - if (!empty($oneMessage->unsubscribe_id)) {
581 - $mailid = $oneMessage->unsubscribe_id;
582 -
583 - if (isset($alreadySent[$mailid])) {
584 - continue;
585 - }
586 -
587 - $mailerHelper->trackEmail = true;
588 - $mailerHelper->sendOne($mailid, $userID);
589 - $alreadySent[$mailid] = true;
590 - }
591 - }
592 - }
593 -
594 - public function addDefaultList()
595 - {
596 - $listId = acym_loadResult('SELECT `id` FROM #__acym_list LIMIT 1');
597 - if (empty($listId)) {
598 - $defaultList = new \stdClass();
599 - $defaultList->name = 'Newsletters';
600 - $defaultList->color = '#3366ff';
601 - $defaultList->description = '';
602 -
603 - $this->save($defaultList);
604 - }
605 - }
606 -
607 - public function getTotalSubCount(array $ids): int
608 - {
609 - if (empty($ids)) {
610 - return 0;
611 - }
612 -
613 - acym_arrayToInteger($ids);
614 - $this->onlyManageableLists($ids);
615 - $query = 'SELECT COUNT(DISTINCT hasList.user_id)
616 - FROM #__acym_user_has_list AS hasList
617 - JOIN #__acym_user AS user
618 - ON hasList.user_id = user.id
619 - WHERE hasList.status = 1
620 - AND user.active = 1
621 - AND hasList.list_id IN ('.implode(',', $ids).')';
622 -
623 -
624 - if ($this->config->get('require_confirmation', 1) == 1) {
625 - $query .= ' AND user.confirmed = 1 ';
626 - }
627 -
628 - return intval(acym_loadResult($query));
629 - }
630 -
631 - public function getMailsByListId(int $listId): array
632 - {
633 - $mailIds = acym_loadResultArray('SELECT mail_id FROM #__acym_mail_has_list WHERE list_id = '.intval($listId));
634 -
635 - return empty($mailIds) ? [] : $mailIds;
636 - }
637 -
638 - public function getSubscribersCountPerStatusByListIds(array $listIds = []): array
639 - {
640 - $condList = '';
641 - if (!empty($listIds)) {
642 - acym_arrayToInteger($listIds);
643 - $condList = 'AND userList.list_id IN ('.implode(',', $listIds).')';
644 - }
645 -
646 - $query = 'SELECT userList.list_id, COUNT(userList.user_id) AS users, acyuser.confirmed + acyuser.active*2 AS score
647 - FROM #__acym_user_has_list AS userList
648 - JOIN #__acym_user AS acyuser
649 - ON acyuser.id = userList.user_id
650 - WHERE userList.status = 1
651 - '.$condList.'
652 - GROUP BY score, userList.list_id';
653 - $results = acym_loadObjectList($query);
654 -
655 - $confirmationRequired = $this->config->get('require_confirmation', 1);
656 - $listsUserStats = [];
657 - foreach ($results as $oneResult) {
658 - if (!isset($listsUserStats[$oneResult->list_id])) {
659 - $listsUserStats[$oneResult->list_id] = $this->initList($oneResult->list_id);
660 - }
661 -
662 - $oneResult->score = (string)$oneResult->score;
663 -
664 - if (in_array($oneResult->score, ['0', '1'])) {
665 - $listsUserStats[$oneResult->list_id]->inactive_users += $oneResult->users;
666 - }
667 -
668 - if (in_array($oneResult->score, ['0', '2'])) {
669 - $listsUserStats[$oneResult->list_id]->unconfirmed_users += $oneResult->users;
670 - }
671 -
672 - if ($oneResult->score === '3' || ($confirmationRequired != 1 && $oneResult->score == '2')) {
673 - $listsUserStats[$oneResult->list_id]->sendable_users += $oneResult->users;
674 - }
675 - }
676 -
677 - $query = 'SELECT userList.list_id, COUNT(userList.user_id) AS users
678 - FROM #__acym_user_has_list AS userList
679 - WHERE userList.status = 0
680 - '.$condList.'
681 - GROUP BY userList.list_id';
682 - $unsubscribed = acym_loadObjectList($query);
683 -
684 - foreach ($unsubscribed as $oneList) {
685 - if (!isset($listsUserStats[$oneList->list_id])) {
686 - $listsUserStats[$oneList->list_id] = $this->initList($oneList->list_id);
687 - }
688 - $listsUserStats[$oneList->list_id]->unsubscribed_users = $oneList->users;
689 - }
690 -
691 - return $listsUserStats;
692 - }
693 -
694 - public function getSubscribersEvolutionByListIds(array $listIds): array
695 - {
696 - $condList = '';
697 - if (!empty($listIds)) {
698 - acym_arrayToInteger($listIds);
699 - $condList = ' AND list_id IN ('.implode(',', $listIds).')';
700 - }
701 - $dateNow = acym_loadResult('SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH)');
702 - $queryEvolSub = 'SELECT list_id, COUNT(*) AS newSub FROM #__acym_user_has_list';
703 - $queryEvolSub .= ' WHERE subscription_date > '.acym_escapeDB($dateNow).' '.$condList;
704 - $queryEvolSub .= ' GROUP BY list_id';
705 - $evolSubscibers = acym_loadObjectList($queryEvolSub, 'list_id');
706 -
707 - $queryEvolUnsub = 'SELECT list_id, COUNT(*) AS newUnsub FROM #__acym_user_has_list';
708 - $queryEvolUnsub .= ' WHERE unsubscribe_date > '.acym_escapeDB($dateNow).' '.$condList;
709 - $queryEvolUnsub .= ' GROUP BY list_id';
710 - $newUnsubscribers = acym_loadObjectList($queryEvolUnsub, 'list_id');
711 -
712 - foreach ($newUnsubscribers as $listId => $oneUnsub) {
713 - if (empty($evolSubscibers[$listId])) {
714 - $evolSubscibers[$listId] = new \stdClass();
715 - }
716 - $evolSubscibers[$listId]->newUnsub = $oneUnsub->newUnsub;
717 - }
718 -
719 - return $evolSubscibers;
720 - }
721 -
722 - public function getYearSubEvolutionPerList(int $listId): array
723 - {
724 - $month = date('n') + 1;
725 - $year = date('Y') - 1;
726 - $initDate = $year.'-'.$month.'-01';
727 - if ($month == 13) {
728 - $initDate = date('Y').'-01-01';
729 - }
730 -
731 - $queryEvolSub = 'SELECT MONTH(subscription_date) as monthSub, DATE_FORMAT(subscription_date,"%Y_%m") AS unit, COUNT(user_id) AS nbUser';
732 - $queryEvolSub .= ' FROM `#__acym_user_has_list`';
733 - $queryEvolSub .= ' WHERE subscription_date >= "'.$initDate.'" AND list_id = '.$listId;
734 - $queryEvolSub .= ' GROUP BY unit';
735 - $evolSubscibers = acym_loadObjectList($queryEvolSub, 'unit');
736 -
737 - $queryEvolUnsub = 'SELECT MONTH(unsubscribe_date) as monthUnsub, DATE_FORMAT(unsubscribe_date,"%Y_%m") AS unit, COUNT(user_id) AS nbUser';
738 - $queryEvolUnsub .= ' FROM `#__acym_user_has_list`';
739 - $queryEvolUnsub .= ' WHERE unsubscribe_date >= "'.$initDate.'" AND list_id = '.$listId;
740 - $queryEvolUnsub .= ' GROUP BY unit';
741 - $evolUnsubscibers = acym_loadObjectList($queryEvolUnsub, 'unit');
742 -
743 - return [
744 - 'subscribers' => $evolSubscibers,
745 - 'unsubscribers' => $evolUnsubscibers,
746 - ];
747 - }
748 -
749 - private function initList(int $listId): object
750 - {
751 - $list = new \stdClass();
752 - $list->list_id = $listId;
753 - $list->sendable_users = 0;
754 - $list->unconfirmed_users = 0;
755 - $list->inactive_users = 0;
756 - $list->unsubscribed_users = 0;
757 -
758 - return $list;
759 - }
760 -
761 - public function getManageableLists(): array
762 - {
763 - $idCurrentUser = acym_currentUserId();
764 - if (empty($idCurrentUser)) {
765 - return [];
766 - }
767 -
768 - $userGroups = acym_getGroupsByUser($idCurrentUser);
769 -
770 - return acym_loadResultArray(
771 - 'SELECT id
772 - FROM #__acym_list
773 - WHERE cms_user_id = '.intval($idCurrentUser).'
774 - OR (access LIKE "%,'.implode(',%" OR access LIKE "%,', $userGroups).',%")'
775 - );
776 - }
777 -
778 - public function onlyManageableLists(&$elements): void
779 - {
780 - if (acym_isAdmin()) {
781 - return;
782 - }
783 -
784 - $manageableLists = $this->getManageableLists();
785 - $elements = array_intersect($elements, $manageableLists);
786 - }
787 -
788 - public function hasUserAccess(int $listId): bool
789 - {
790 - if (acym_isAdmin()) {
791 - return true;
792 - }
793 -
794 - return in_array($listId, $this->getManageableLists());
795 - }
796 -
797 - public function getfrontManagementList(): int
798 - {
799 - $idCurrentUser = acym_currentUserId();
800 - if (empty($idCurrentUser)) {
801 - return 0;
802 - }
803 -
804 - $frontListId = acym_loadResult('SELECT id FROM #__acym_list WHERE type = '.acym_escapeDB(self::LIST_TYPE_FRONT).' AND cms_user_id = '.intval($idCurrentUser));
805 -
806 - if (!empty($frontListId)) {
807 - return $frontListId;
808 - }
809 -
810 - $frontList = new \stdClass();
811 - $frontList->name = 'frontlist_'.$idCurrentUser;
812 - $frontList->active = 1;
813 - $frontList->visible = 0;
814 - $frontList->cms_user_id = $idCurrentUser;
815 - $frontList->type = self::LIST_TYPE_FRONT;
816 -
817 - return (int)$this->save($frontList);
818 - }
819 -
820 - public function setWelcomeUnsubEmail(array $listIds, int $mailId, string $type): bool
821 - {
822 - if (!in_array($type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE]) || empty($mailId)) {
823 - return false;
824 - }
825 -
826 - $column = acym_escape($type).'_id';
827 - $columnsList = acym_getColumns('list');
828 - if (!in_array($column, $columnsList)) {
829 - return false;
830 - }
831 -
832 - if (!$this->removeWelcomeUnsubByMailId($mailId, $listIds, $column)) {
833 - return false;
834 - }
835 -
836 - foreach ($listIds as $listId) {
837 - $list = $this->getOneById($listId);
838 - if (empty($list)) {
839 - return false;
840 - }
841 -
842 - $list->{$column} = $mailId;
843 -
844 - $savedListId = $this->save($list);
845 - if (empty($savedListId)) {
846 - return false;
847 - }
848 - }
849 -
850 - return true;
851 - }
852 -
853 - private function removeWelcomeUnsubByMailId(int $mailId, array $listIds, string $column): bool
854 - {
855 - if (empty($mailId)) {
856 - return false;
857 - }
858 -
859 - $query = 'SELECT * FROM #__acym_list WHERE '.acym_secureDBColumn($column).' = '.$mailId;
860 -
861 - if (!empty($listIds)) {
862 - acym_arrayToInteger($listIds);
863 - $query .= ' AND `id` NOT IN ('.implode(',', $listIds).')';
864 - }
865 -
866 - $lists = acym_loadObjectList($query);
867 - if (empty($lists)) {
868 - return true;
869 - }
870 -
871 - foreach ($lists as $list) {
872 - $list->{$column} = null;
873 -
874 - $savedListId = $this->save($list);
875 - if (empty($savedListId)) {
876 - return false;
877 - }
878 - }
879 -
880 - return true;
881 - }
882 -
883 - public function getListIdsByWelcomeUnsub(int $mailId, bool $welcome = true): array
884 - {
885 - $type = $welcome ? 'welcome_id' : 'unsubscribe_id';
886 -
887 - $return = acym_loadResultArray('SELECT id FROM #__acym_list WHERE '.$type.' = '.intval($mailId));
888 -
889 - return empty($return) ? [] : $return;
890 - }
891 -
892 - public function getUsersForSummaryModal(int $id, int $offset, int $limit, string $search): array
893 - {
894 - $whereQuery = ' AND user_list.status = 1 AND user.active = 1';
895 -
896 - if (!empty($search)) {
897 - $search = acym_escapeDB('%'.$search.'%');
898 - $whereQuery .= ' AND (user.email LIKE '.$search.' OR user.name LIKE '.$search.' OR user.id LIKE '.$search.') ';
899 - }
900 -
901 - if ($this->config->get('require_confirmation', '1') === '1') {
902 - $whereQuery .= ' AND user.confirmed = 1';
903 - }
904 -
905 - $query = 'SELECT user.email, user.name, user.id
906 - FROM #__acym_user as user
907 - JOIN #__acym_user_has_list as user_list ON user.id = user_list.user_id
908 - WHERE user_list.list_id = '.intval($id).$whereQuery.' LIMIT '.intval($offset).', '.intval($limit);
909 -
910 -
911 - return acym_loadObjectList($query, 'id');
912 - }
913 -
914 - public function getXLists(array $options = []): array
915 - {
916 - $limit = $options['limit'] ?? 10;
917 - $offset = $options['offset'] ?? 0;
918 - $filters = $options['filters'] ?? ['type' => self::LIST_TYPE_STANDARD];
919 -
920 - $conditions = [];
921 - foreach ($filters as $column => $filter) {
922 - switch ($column) {
923 - case 'id':
924 - case 'active':
925 - case 'visible':
926 - case 'clean':
927 - case 'welcome_id':
928 - case 'unsubscribe_id':
929 - case 'cms_user_id':
930 - case 'tracking':
931 - $conditions[] = acym_secureDBColumn($column).' = '.intval($filter);
932 - break;
933 - default:
934 - $conditions[] = acym_secureDBColumn($column).' LIKE '.acym_escapeDB('%'.$filter.'%');
935 - }
936 - }
937 -
938 - $query = 'SELECT * FROM #__acym_list';
939 - if (!empty($conditions)) {
940 - $query .= ' WHERE '.implode(' AND ', $conditions);
941 - }
942 -
943 - return acym_loadObjectList($query, $this->pkey, $offset, $limit);
944 - }
945 -
946 - public function getOneList(): bool
947 - {
948 - $firstList = acym_loadObject('SELECT * FROM #__acym_list WHERE `id` != 1');
949 -
950 - return !empty($firstList);
951 - }
952 -
953 - public function getMostUsedLists(): array
954 - {
955 - return acym_loadObjectList(
956 - 'SELECT list_id
957 - FROM #__acym_mail_has_list
958 - GROUP BY list_id
959 - ORDER BY COUNT(*) DESC
960 - LIMIT 5'
961 - );
962 - }
963 -
964 - public function getListsSubscribersAndUnsubscribeUsersFromUserHasList(): array
965 - {
966 - $query = 'SELECT list_id,
967 - SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS subscribers,
968 - SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS unsubscribed_users
969 - FROM `#__acym_user_has_list`
970 - GROUP BY list_id';
971 -
972 - return acym_loadObjectList($query);
973 - }
974 -
975 - public function updateListsSubscribersAndUnsubscribeUsers(int $listId, int $subscribers, int $unsubscribeUsers, int $new_sub, int $new_unsub): void
976 - {
977 - acym_query(
978 - 'UPDATE `#__acym_list`
979 - SET `subscribers` = '.$subscribers.', `unsubscribed_users` = '.$unsubscribeUsers.', `new_sub` = '.$new_sub.', `new_unsub` = '.$new_unsub.'
980 - WHERE id = '.$listId
981 - );
982 - }
983 -
984 - public function getMostUsedListsByIdsWithSubscribersData(array $ids = []): array
985 - {
986 - if (empty($ids)) {
987 - return [];
988 - }
989 - acym_arrayToInteger($ids);
990 - $query = 'SELECT name, subscribers, unsubscribed_users, new_sub, new_unsub FROM `#__acym_list` WHERE id IN ('.implode(', ', $ids).')';
991 -
992 - return acym_loadObjectList($query);
993 - }
994 -
995 - public function getUserListEntries(array $userIds, array $listIds): array
996 - {
997 - if (empty($userIds) || empty($listIds)) {
998 - return [];
999 - }
1000 -
1001 - $userIdsStr = implode(',', array_map('intval', $userIds));
1002 - $listIdsStr = implode(',', array_map('intval', $listIds));
1003 -
1004 - $query = 'SELECT * FROM `#__acym_user_has_list`
1005 - WHERE user_id IN ('.$userIdsStr.') AND list_id IN ('.$listIdsStr.')';
1006 -
1007 - $results = acym_loadObjectList($query);
1008 -
1009 - $entries = [];
1010 - foreach ($results as $row) {
1011 - $key = $row->user_id.'_'.$row->list_id;
1012 - $entries[$key] = $row;
1013 - }
1014 -
1015 - return $entries;
1016 - }
1017 -}