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/UserClass.php +0 -1776 10.11.1 → 11.1.1 View file →
@@ -1,1776 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Classes;
4 -
5 -use AcyMailing\Helpers\AutomationHelper;
6 -use AcyMailing\Helpers\MailerHelper;
7 -use AcyMailing\Helpers\PaginationHelper;
8 -use AcyMailing\Core\AcymClass;
9 -
10 -class UserClass extends AcymClass
11 -{
12 - public const STATUS_SUBSCRIBED = 1;
13 - private const RESTRICTED_FIELDS = [
14 - 'id',
15 - 'key',
16 - 'confirmed',
17 - 'active',
18 - 'cms_id',
19 - 'creation_date',
20 - ];
21 -
22 - private const FORM_ALLOWED_FIELDS = [
23 - 'id',
24 - 'email',
25 - 'name',
26 - 'language',
27 - 'tracking',
28 - ];
29 -
30 - public bool $checkVisitor = true;
31 - public bool $requireId = false;
32 - public bool $sendConf = true;
33 - public bool $confirmationSentSuccess = false;
34 - public bool $newUser = false;
35 - public bool $blockNotifications = false;
36 - public bool $subscribed = false;
37 - public string $confirmationSentError;
38 - public bool $triggers = true;
39 -
40 - public bool $forceConfAdmin = false;
41 -
42 - public bool $sendWelcomeEmail = true;
43 - public bool $sendUnsubscribeEmail = true;
44 -
45 - private bool $allowModif = false;
46 - private bool $forceConf = false;
47 -
48 - public function __construct()
49 - {
50 - parent::__construct();
51 -
52 - $this->table = 'user';
53 - $this->pkey = 'id';
54 - }
55 -
56 - public function getMatchingElements(array $settings = []): array
57 - {
58 - $results = [];
59 - $columns = '`user`.*';
60 - if (!empty($settings['columns'])) {
61 - foreach ($settings['columns'] as $key => $value) {
62 - $settings['columns'][$key] = $key === 'join' ? acym_secureDBColumn($value) : 'user.'.acym_secureDBColumn($value);
63 - }
64 - $columns = implode(', ', $settings['columns']);
65 - }
66 -
67 - $query = $columns.' FROM #__acym_user AS `user`';
68 - $queryCount = 'SELECT COUNT(DISTINCT user.id) AS total FROM #__acym_user AS user';
69 - $queryStatus = 'SELECT COUNT(DISTINCT user.id) AS number, user.confirmed + user.active*2 AS score FROM #__acym_user AS user';
70 - $filters = [];
71 -
72 - if (!empty($settings['join'])) {
73 - $query .= $this->getJoinForQuery($settings['join']);
74 - }
75 - $this->handleSegmentFilter($settings, $filters, $query, $queryCount, $queryStatus);
76 - $this->handleSubscriptionFilter($settings, $filters, $query, $queryCount, $queryStatus);
77 - $this->handleFrontend($settings, $query, $queryCount, $queryStatus);
78 - $this->handleSearchFilter($settings, $filters, $query, $queryCount, $queryStatus);
79 - $results['status'] = $this->handleUserStatusFilter($settings, $filters, $queryStatus);
80 - $entityResult = $this->handleEntitySelect($settings, $filters);
81 -
82 - if (!empty($entityResult)) {
83 - return $entityResult;
84 - }
85 -
86 - if (!empty($filters)) {
87 - $query .= ' WHERE ('.implode(') AND (', $filters).')';
88 - $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
89 - }
90 -
91 - if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
92 - $query .= ' ORDER BY user.'.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
93 - }
94 -
95 - if (empty($settings['offset']) || $settings['offset'] < 0) {
96 - $settings['offset'] = 0;
97 - }
98 -
99 - if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) {
100 - $pagination = new PaginationHelper();
101 - $settings['elementsPerPage'] = $pagination->getListLimit();
102 - }
103 -
104 - acym_query('SET SQL_BIG_SELECTS=1');
105 - $results['elements'] = acym_loadObjectList('SELECT DISTINCT '.$query, '', $settings['offset'], $settings['elementsPerPage']);
106 - $results['total'] = acym_loadObject($queryCount);
107 -
108 - if (!empty($results['elements']) && !empty($settings['cms_username'])) {
109 - $cmsIds = array_diff(array_column($results['elements'], 'cms_id'), [0, '']);
110 - if (!empty($cmsIds)) {
111 - global $acymCmsUserVars;
112 - $userNames = acym_loadObjectList(
113 - 'SELECT '.$acymCmsUserVars->id.' AS id, '.$acymCmsUserVars->username.' AS `cms_username`
114 - FROM '.$acymCmsUserVars->table.'
115 - WHERE id IN ('.implode(', ', array_values($cmsIds)).')',
116 - 'id'
117 - );
118 - foreach ($results['elements'] as $key => $oneElement) {
119 - if (empty($results['elements'][$key]->cms_id)) continue;
120 - if (empty($userNames[$results['elements'][$key]->cms_id])) {
121 - $oneUser = $this->getOneById($results['elements'][$key]->id);
122 - $oneUser->cms_id = 0;
123 - $this->save($oneUser);
124 - $results['elements'][$key]->cms_id = 0;
125 - continue;
126 - }
127 - $results['elements'][$key]->cms_username = $userNames[$results['elements'][$key]->cms_id]->cms_username;
128 - }
129 - }
130 - }
131 -
132 - return $results;
133 - }
134 -
135 - private function handleSubscriptionFilter(array $settings, array &$filters, string &$query, string &$queryCount, string &$queryStatus): void
136 - {
137 - if (empty($settings['list'])) {
138 - return;
139 - }
140 -
141 - $listJoin = ' JOIN #__acym_user_has_list AS list ON user.id = list.user_id AND list.list_id = '.intval($settings['list']).' ';
142 -
143 - if ($settings['list_status'] === 'none') {
144 - $listJoin = ' LEFT'.$listJoin;
145 - $filters[] = 'list.user_id IS NULL';
146 - } else {
147 - $filters[] = 'list.status = '.($settings['list_status'] === 'sub' ? 1 : 0);
148 - }
149 -
150 - $query .= $listJoin;
151 - $queryCount .= $listJoin;
152 - $queryStatus .= $listJoin;
153 - }
154 -
155 - private function handleFrontend(array $settings, string &$query, string &$queryCount, string &$queryStatus): void
156 - {
157 - if (!acym_isAdmin()) {
158 - $settings['creator_id'] = acym_currentUserId();
159 - if (empty($settings['creator_id'])) {
160 - $settings['creator_id'] = '-1';
161 - }
162 - }
163 -
164 - if (!empty($settings['creator_id'])) {
165 - $userGroups = acym_getGroupsByUser($settings['creator_id']);
166 - $groupCondition = 'list.access LIKE "%,'.implode(',%" OR list.access LIKE "%,', $userGroups).',%"';
167 - $joinList = ' JOIN #__acym_user_has_list as user_list ON user_list.user_id = user.id JOIN #__acym_list AS list ON list.id = user_list.list_id AND (list.cms_user_id = '.intval(
168 - $settings['creator_id']
169 - ).' OR '.$groupCondition.')';
170 -
171 - $query .= $joinList;
172 - $queryCount .= $joinList;
173 - $queryStatus .= $joinList;
174 - }
175 - }
176 -
177 - private function handleSearchFilter(array $settings, array &$filters, string &$query, string &$queryCount, string &$queryStatus): void
178 - {
179 - if (empty($settings['search'])) return;
180 -
181 - $searchValue = acym_escapeDB('%'.$settings['search'].'%');
182 - $searchFilter = 'user.email LIKE '.$searchValue.' OR user.name LIKE '.$searchValue.' OR user.id = '.intval($settings['search']);
183 -
184 - $listingFields = acym_loadResultArray('SELECT `id` FROM #__acym_field WHERE `'.(acym_isAdmin() ? 'back' : 'front').'end_listing` = 1');
185 - if (!empty($listingFields)) {
186 - $query = 'DISTINCT '.$query;
187 - $join = ' LEFT JOIN #__acym_user_has_field AS userfield ON user.id = userfield.user_id AND userfield.field_id IN ('.implode(', ', $listingFields).') AND ';
188 - $cfSearch = 'userfield.value LIKE '.$searchValue;
189 -
190 - $fieldsWithMultipleValues = acym_loadObjectList(
191 - 'SELECT *
192 - FROM #__acym_field
193 - WHERE id IN ('.implode(', ', $listingFields).')
194 - AND `value` LIKE '.acym_escapeDB('%"title":"'.$settings['search'].'"%')
195 - );
196 -
197 - if (!empty($fieldsWithMultipleValues)) {
198 - foreach ($fieldsWithMultipleValues as $oneField) {
199 - $oneField->value = json_decode($oneField->value, true);
200 - foreach ($oneField->value as $value) {
201 - if (stripos($value['title'], $settings['search']) !== false) {
202 - $cfSearch .= ' OR (userfield.field_id = '.intval($oneField->id).' AND userfield.value LIKE '.acym_escapeDB('%'.$value['value'].'%').')';
203 - }
204 - }
205 - }
206 - }
207 -
208 - $join .= '('.$cfSearch.')';
209 - $searchFilter .= ' OR userfield.field_id IS NOT NULL';
210 -
211 - $query .= $join;
212 - $queryCount .= $join;
213 - $queryStatus .= $join;
214 - }
215 -
216 - $filters[] = $searchFilter;
217 - }
218 -
219 - private function handleUserStatusFilter(array $settings, array &$filters, string $queryStatus): array
220 - {
221 - if (!empty($filters)) {
222 - $queryStatus .= ' WHERE ('.implode(') AND (', $filters).')';
223 - }
224 -
225 - $usersPerStatusObject = acym_loadObjectList($queryStatus.' GROUP BY score', 'score');
226 -
227 - $usersPerStatus = [];
228 - for ($i = 0; $i < 4; $i++) {
229 - $usersPerStatus[$i] = empty($usersPerStatusObject[$i]) ? 0 : $usersPerStatusObject[$i]->number;
230 - }
231 -
232 - if (!empty($settings['status'])) {
233 - $allowedStatus = [
234 - 'active' => 'active = 1',
235 - 'inactive' => 'active = 0',
236 - 'confirmed' => 'confirmed = 1',
237 - 'unconfirmed' => 'confirmed = 0',
238 - ];
239 - if (empty($allowedStatus[$settings['status']])) {
240 - die('Injection denied');
241 - }
242 - $filters[] = 'user.'.$allowedStatus[$settings['status']];
243 - }
244 -
245 - return [
246 - 'all' => array_sum($usersPerStatus),
247 - 'active' => $usersPerStatus[2] + $usersPerStatus[3],
248 - 'inactive' => $usersPerStatus[0] + $usersPerStatus[1],
249 - 'confirmed' => $usersPerStatus[1] + $usersPerStatus[3],
250 - 'unconfirmed' => $usersPerStatus[0] + $usersPerStatus[2],
251 - ];
252 - }
253 -
254 - private function handleEntitySelect(array $settings, array &$filters): ?array
255 - {
256 - if (isset($settings['hiddenElements'])) {
257 - if (empty($settings['hiddenElements'])) {
258 - $filters[] = 'user.id IS NOT NULL';
259 - } else {
260 - acym_arrayToInteger($settings['hiddenElements']);
261 - $filters[] = 'user.id NOT IN('.implode(',', $settings['hiddenElements']).')';
262 - }
263 - }
264 -
265 - if (isset($settings['onlyElements'])) {
266 - if (empty($settings['onlyElements'])) {
267 - $filters[] = 'user.id IS NULL';
268 - } else {
269 - acym_arrayToInteger($settings['onlyElements']);
270 - $filters[] = 'user.id IN('.implode(',', $settings['onlyElements']).')';
271 - }
272 - }
273 -
274 - if (!empty($settings['showOnlySelected'])) {
275 - if (!empty($settings['selectedUsers'])) {
276 - acym_arrayToInteger($settings['selectedUsers']);
277 - $filters[] = 'user.id IN('.implode(',', $settings['selectedUsers']).')';
278 - } else {
279 - return ['users' => [], 'total' => 0];
280 - }
281 - }
282 -
283 - return null;
284 - }
285 -
286 - private function handleSegmentFilter(array $settings, array &$filters, string &$query, string &$queryCount, string &$queryStatus): void
287 - {
288 - if (!array_key_exists('segment', $settings)) return;
289 - if ($settings['segment'] == 0) return;
290 -
291 - $segmentClass = (new SegmentClass())->getOneById($settings['segment']);
292 - $automationHelpers = [];
293 - if (!empty($segmentClass) && !empty($segmentClass->filters)) {
294 - foreach ($segmentClass->filters as $or => $orValues) {
295 - if (empty($orValues)) continue;
296 - $automationHelpers[$or] = new AutomationHelper();
297 - foreach ($orValues as $and => $andValues) {
298 - $and = intval($and);
299 - foreach ($andValues as $filterName => $options) {
300 - acym_trigger('onAcymProcessFilter_'.$filterName, [&$automationHelpers[$or], &$options, $and.'_'.$or]);
301 - }
302 - }
303 - }
304 - }
305 -
306 - $where = '';
307 - $join = '';
308 - foreach ($automationHelpers as $index => $automationHelper) {
309 - if (!empty($automationHelper->where)) {
310 - $where .= ' ('.implode(') and (', $automationHelper->where).')';
311 - if ($index != count($automationHelpers) - 1) $where .= ' OR ';
312 - }
313 - if (!empty($automationHelper->join)) $join .= ' JOIN '.implode(' JOIN ', $automationHelper->join);
314 - if (!empty($automationHelper->leftjoin)) $join .= ' LEFT JOIN '.implode(' LEFT JOIN ', $automationHelper->leftjoin);
315 - }
316 - if (!empty($where)) {
317 - $filters[] = $where;
318 - }
319 - $query .= $join;
320 - $queryCount .= $join;
321 - $queryStatus .= $join;
322 - }
323 -
324 - public function getJoinForQuery(string $joinType): string
325 - {
326 - if (strpos($joinType, 'join_list') !== false) {
327 - $listId = explode('-', $joinType);
328 -
329 - return ' LEFT JOIN #__acym_user_has_list AS userlist ON user.id = userlist.user_id AND userlist.status = 1 AND userlist.list_id = '.intval($listId[1]);
330 - }
331 -
332 - return '';
333 - }
334 -
335 - public function getOneByCMSId(?int $id): ?object
336 - {
337 - if (empty($id)) {
338 - return null;
339 - }
340 -
341 - $user = acym_loadObject('SELECT * FROM #__acym_user WHERE cms_id = '.intval($id));
342 -
343 - return empty($user) ? null : $user;
344 - }
345 -
346 - public function getOneByEmail(?string $email, bool $autoAdd = false): ?object
347 - {
348 - if (!acym_isValidEmail($email)) {
349 - return null;
350 - }
351 -
352 - $user = acym_loadObject('SELECT * FROM #__acym_user WHERE email = '.acym_escapeDB($email));
353 -
354 - if (empty($user) && $autoAdd) {
355 - $newUser = new \stdClass();
356 - $newUser->email = $email;
357 - $this->sendConf = false;
358 - $this->checkVisitor = false;
359 -
360 - $userId = $this->save($newUser);
361 - if (empty($userId)) {
362 - return null;
363 - }
364 -
365 - $user = $this->getOneById($userId);
366 - }
367 -
368 - return empty($user) ? null : $user;
369 - }
370 -
371 - public function getByColumnValue(string $column, string $value): array
372 - {
373 - $userColumns = acym_getColumns('user');
374 - if (!in_array($column, $userColumns)) return [];
375 -
376 - $query = 'SELECT * FROM #__acym_user WHERE '.acym_secureDBColumn($column).' = '.acym_escapeDB($value);
377 -
378 - return acym_loadObjectList($query, $this->pkey);
379 - }
380 -
381 - public function getUserSubscriptionById(
382 - int $userId,
383 - string $key = 'id',
384 - bool $includeManagement = false,
385 - bool $visible = false,
386 - bool $needTranslation = false,
387 - bool $sortBySubscription = false,
388 - int $mailId = 0,
389 - bool $campaignOnly = false
390 - ): array {
391 - $mailType = null;
392 - if (!empty($mailId)) {
393 - $mailType = (new MailClass())->getMailType(intval($mailId));
394 - }
395 -
396 - $query = 'SELECT list.id, list.translation, list.name, list.display_name, list.color, list.active, list.visible, list.description, userlist.status, userlist.subscription_date, userlist.unsubscribe_date
397 - FROM #__acym_list AS list
398 - JOIN #__acym_user_has_list AS userlist
399 - ON list.id = userlist.list_id ';
400 -
401 - if (!empty($mailId) && $campaignOnly && !empty($mailType) && $mailType !== MailClass::TYPE_FOLLOWUP) {
402 - $query .= 'JOIN #__acym_mail_has_list AS mail_list ON list.id = mail_list.list_id AND mail_list.mail_id = '.intval($mailId);
403 - }
404 -
405 - $query .= ' WHERE userlist.user_id = '.intval($userId);
406 -
407 - if (!$includeManagement && !empty($mailType) && $mailType === MailClass::TYPE_FOLLOWUP) {
408 - $query .= ' AND list.type = '.acym_escapeDB(ListClass::LIST_TYPE_FOLLOWUP);
409 - } elseif (!$includeManagement) {
410 - $types = [ListClass::LIST_TYPE_STANDARD, ListClass::LIST_TYPE_FOLLOWUP];
411 - $types = array_map('acym_escapeDB', $types);
412 - $query .= ' AND list.type IN ('.implode(',', $types).')';
413 - }
414 -
415 - if ($visible) {
416 - $query .= ' AND list.visible = 1';
417 - }
418 -
419 - if ($sortBySubscription) {
420 - $query .= ' ORDER BY userlist.subscription_date DESC';
421 - }
422 -
423 - $lists = acym_loadObjectList($query, $key);
424 -
425 - if (acym_isMultilingual() && $needTranslation) {
426 - $listClass = new ListClass();
427 - $lists = $listClass->getTranslatedNameDescription($lists);
428 - }
429 -
430 - return $lists;
431 - }
432 -
433 - public function getUserStandardListIdById(int $userId): array
434 - {
435 - $query = 'SELECT list.id FROM #__acym_list AS list
436 - JOIN #__acym_user_has_list AS user_list ON list.id = user_list.list_id AND user_list.status = 1 AND user_list.user_id = '.$userId.'
437 - WHERE list.visible = 1 AND list.type = '.acym_escapeDB(ListClass::LIST_TYPE_STANDARD);
438 -
439 - return acym_loadResultArray($query);
440 - }
441 -
442 - public function getAllListsUserSubscriptionById(int $userId, string $key = 'id', bool $needTranslation = false): array
443 - {
444 - $query = 'SELECT list.id, list.translation, list.name, list.color, list.active, list.visible, userlist.status, userlist.subscription_date, userlist.unsubscribe_date
445 - FROM #__acym_list AS list
446 - LEFT JOIN #__acym_user_has_list AS userlist
447 - ON list.id = userlist.list_id
448 - AND userlist.user_id = '.intval($userId);
449 -
450 - $lists = acym_loadObjectList($query, $key);
451 -
452 - if (acym_isMultilingual() && $needTranslation) {
453 - $listClass = new ListClass();
454 - $lists = $listClass->getTranslatedNameDescription($lists);
455 - }
456 -
457 - return $lists;
458 - }
459 -
460 - public function getUsersSubscriptionsByIds(array $userIds, int $creatorId = 0): array
461 - {
462 - acym_arrayToInteger($userIds);
463 - $query = 'SELECT `list`.`id`, `list`.`color`, `list`.`name`, `userlist`.`user_id`, `userlist`.`status`
464 - FROM #__acym_list AS `list`
465 - JOIN #__acym_user_has_list AS `userlist`
466 - ON `list`.`id` = `userlist`.`list_id`
467 - WHERE `userlist`.`user_id` IN ('.implode(',', $userIds).')
468 - AND `list`.`type` = '.acym_escapeDB(ListClass::LIST_TYPE_STANDARD);
469 -
470 - if (!empty($creatorId)) {
471 - $userGroups = acym_getGroupsByUser($creatorId);
472 -
473 - $safeGroups = [];
474 - foreach ($userGroups as $group) {
475 - $safeGroups[] = acym_escapeDB('%,'.$group.',%');
476 - }
477 - $query .= ' AND (`list`.`cms_user_id` = '.intval($creatorId).' OR `list`.`access` LIKE '.implode(' OR `list`.`access` LIKE ', $safeGroups).')';
478 - }
479 - $query .= ' ORDER BY `userlist`.`status` DESC, `list`.`id` ASC';
480 -
481 - return acym_loadObjectList($query);
482 - }
483 -
484 - public function getCountTotalUsers(): int
485 - {
486 - $numberOfUsers = acym_loadResult('SELECT COUNT(id) FROM #__acym_user');
487 -
488 - return empty($numberOfUsers) ? 0 : $numberOfUsers;
489 - }
490 -
491 - public function getSubscriptionStatus(int $userId, array $listIds = [], ?int $wantedStatus = null): array
492 - {
493 - $query = 'SELECT status, list_id
494 - FROM #__acym_user_has_list
495 - WHERE user_id = '.intval($userId);
496 - if (!empty($listIds)) {
497 - acym_arrayToInteger($listIds);
498 - $query .= ' AND list_id IN ('.implode(',', $listIds).')';
499 - }
500 -
501 - if ($wantedStatus !== null) {
502 - $query .= ' AND status = '.intval($wantedStatus);
503 - }
504 -
505 - return acym_loadObjectList($query, 'list_id');
506 - }
507 -
508 - public function identify(bool $onlyValue = false, ?string $idName = null, ?string $keyName = null): ?object
509 - {
510 - $id = acym_getVar('int', empty($idName) ? 'id' : $idName, 0);
511 - $key = acym_getVar('string', empty($keyName) ? 'key' : $keyName, '');
512 -
513 - if (empty($id) && !empty($idName) && empty($key) && !empty($keyName)) {
514 - $id = acym_getVar('int', 'id', 0);
515 - $key = acym_getVar('string', 'key', 0);
516 - }
517 -
518 - if (empty($id) || empty($key)) {
519 - $currentUserid = acym_currentUserId();
520 - if (!empty($currentUserid)) {
521 - return $this->getOneByCMSId($currentUserid);
522 - }
523 - if (!$onlyValue) {
524 - acym_enqueueMessage(acym_translation('ACYM_LOGIN'), 'error');
525 - }
526 -
527 - return null;
528 - }
529 -
530 - $userIdentified = acym_loadObject('SELECT * FROM #__acym_user WHERE `id` = '.intval($id).' AND `key` = '.acym_escapeDB($key));
531 -
532 - if (!empty($userIdentified)) {
533 - return $userIdentified;
534 - }
535 -
536 - if (!$onlyValue) {
537 - acym_enqueueMessage(acym_translation('ACYM_USER_NOT_FOUND'), 'error');
538 - }
539 -
540 - return null;
541 - }
542 -
543 - public function subscribe($userIds, array $addLists, bool $trigger = true, bool $forceFront = false): bool
544 - {
545 - if (empty($addLists)) {
546 - return false;
547 - }
548 - acym_arrayToInteger($addLists);
549 -
550 - if (!is_array($userIds)) {
551 - $userIds = [$userIds];
552 - }
553 - acym_arrayToInteger($userIds);
554 -
555 - $listClass = new ListClass();
556 - $historyClass = new HistoryClass();
557 -
558 - $confirmationRequired = !empty($this->config->get('require_confirmation', 1));
559 - $subscribedToLists = false;
560 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $addLists));
561 -
562 - foreach ($userIds as $userId) {
563 - $user = $this->getOneById($userId);
564 - if (empty($user)) continue;
565 - $currentSubscription = $this->getUserSubscriptionById($userId, 'id', true);
566 -
567 - $currentlySubscribed = [];
568 - $currentlyUnsubscribed = [];
569 - foreach ($currentSubscription as $oneList) {
570 - if ($oneList->status == 1) {
571 - $currentlySubscribed[$oneList->id] = $oneList;
572 - }
573 - if ($oneList->status == 0) {
574 - $currentlyUnsubscribed[$oneList->id] = $oneList;
575 - }
576 - }
577 -
578 - $subscribedLists = [];
579 - $listsNotExisting = [];
580 - foreach ($addLists as $oneListId) {
581 - if (empty($oneListId) || !empty($currentlySubscribed[$oneListId])) {
582 - continue;
583 - }
584 -
585 - $list = $listClass->getOneById($oneListId);
586 - if (empty($list)) {
587 - $listsNotExisting[] = $oneListId;
588 - continue;
589 - }
590 -
591 - $subscription = new \stdClass();
592 - $subscription->user_id = $userId;
593 - $subscription->list_id = $oneListId;
594 - $subscription->status = 1;
595 - $subscription->subscription_date = date('Y-m-d H:i:s', time() - date('Z'));
596 -
597 - if (empty($currentSubscription[$oneListId])) {
598 - acym_insertObject('#__acym_user_has_list', $subscription);
599 - } elseif (!empty($currentlyUnsubscribed[$oneListId])) {
600 - acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
601 - }
602 -
603 - $subscribedLists[] = $oneListId;
604 - $subscribedToLists = true;
605 - }
606 -
607 - if (!empty($listsNotExisting)) {
608 - $this->errors['list_not_existing'] = acym_translationSprintf('ACYM_LIST_NOT_FOUND', implode(', ', $listsNotExisting));
609 - }
610 -
611 - $historyClass->insert($userId, 'subscribed', [$historyData]);
612 -
613 - if ($trigger) {
614 - acym_trigger('onAcymAfterUserSubscribe', [&$user, &$subscribedLists]);
615 - }
616 -
617 - if ($this->sendWelcomeEmail && (!$confirmationRequired || $user->confirmed == 1) && $user->active == 1) {
618 - $listClass->sendWelcome($userId, $subscribedLists, $forceFront);
619 - }
620 - }
621 -
622 - return $subscribedToLists;
623 - }
624 -
625 - private function registerUnsubUser(array $userIds): void
626 - {
627 - $mailId = acym_getVar('int', 'mail_id', 0);
628 - if (empty($mailId)) return;
629 -
630 - $mailStatClass = new MailStatClass();
631 - $userStatClass = new UserStatClass();
632 -
633 - $countUnsubscribe = 0;
634 -
635 - foreach ($userIds as $id) {
636 - $userStat = $userStatClass->getOneByMailAndUserId($mailId, $id);
637 - if (empty($userStat)) continue;
638 -
639 - $newUserStat = new \stdClass();
640 - $newUserStat->mail_id = $mailId;
641 - $newUserStat->user_id = $id;
642 - $newUserStat->unsubscribe = empty($userStat->unsubscribe) ? 1 : $userStat->unsubscribe + 1;
643 -
644 - if (empty($userStat->unsubscribe)) {
645 - $countUnsubscribe++;
646 - }
647 -
648 - $userStatClass->save($newUserStat);
649 - }
650 -
651 - $mailStat = new \stdClass();
652 - $mailStat->mail_id = $mailId;
653 - $mailStat->unsubscribe_total = $countUnsubscribe;
654 -
655 - $mailStatClass->save($mailStat);
656 - }
657 -
658 - public function unsubscribe($userIds, array $lists): bool
659 - {
660 - if (empty($lists)) {
661 - return false;
662 - }
663 -
664 - if (!is_array($userIds)) {
665 - $userIds = [$userIds];
666 - }
667 - acym_arrayToInteger($userIds);
668 - acym_arrayToInteger($lists);
669 -
670 - $listClass = new ListClass();
671 - $unsubscribedFromLists = false;
672 - foreach ($userIds as $userId) {
673 - $user = $this->getOneById($userId);
674 -
675 - if (empty($user)) {
676 - continue;
677 - }
678 -
679 - $currentSubscription = $this->getUserSubscriptionById($userId);
680 -
681 - $currentlySubscribed = [];
682 - $currentlyUnsubscribed = [];
683 - foreach ($currentSubscription as $oneList) {
684 - if ($oneList->status == 0) {
685 - $currentlyUnsubscribed[$oneList->id] = $oneList;
686 - } elseif ($oneList->status == 1) {
687 - $currentlySubscribed[$oneList->id] = $oneList;
688 - }
689 - }
690 -
691 - $unsubscribedLists = [];
692 - $listsNotExisting = [];
693 - foreach ($lists as $oneListId) {
694 - if (empty($oneListId) || !empty($currentlyUnsubscribed[$oneListId])) {
695 - continue;
696 - }
697 -
698 - if (empty($currentlySubscribed[$oneListId])) {
699 - continue;
700 - }
701 -
702 - $list = $listClass->getOneById($oneListId);
703 - if (empty($list)) {
704 - $listsNotExisting[] = $oneListId;
705 - continue;
706 - }
707 -
708 - $subscription = new \stdClass();
709 - $subscription->user_id = $userId;
710 - $subscription->list_id = $oneListId;
711 - $subscription->status = 0;
712 - $subscription->unsubscribe_date = date('Y-m-d H:i:s', time() - date('Z'));
713 - if (empty($currentSubscription[$oneListId])) {
714 - acym_insertObject('#__acym_user_has_list', $subscription);
715 - } else {
716 - acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
717 - }
718 -
719 - $unsubscribedLists[] = $oneListId;
720 - $unsubscribedFromLists = true;
721 - }
722 -
723 - if (!empty($listsNotExisting)) {
724 - $this->errors['list_not_existing'] = acym_translationSprintf('ACYM_LIST_NOT_FOUND', implode(', ', $listsNotExisting));
725 - }
726 -
727 - acym_query(
728 - 'DELETE FROM #__acym_queue WHERE user_id = '.intval($userId).' AND mail_id IN (
729 - SELECT followup_mail.mail_id FROM #__acym_followup_has_mail AS followup_mail
730 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup.list_id IN ('.implode(',', $lists).')
731 - )'
732 - );
733 -
734 - $historyClass = new HistoryClass();
735 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $lists));
736 - $historyClass->insert($userId, 'unsubscribed', [$historyData], 0, acym_getVar('string', 'unsubscribe_reason'));
737 -
738 - if ($this->triggers) {
739 - acym_trigger('onAcymAfterUserUnsubscribe', [&$user, &$unsubscribedLists]);
740 - }
741 -
742 - if ($this->sendUnsubscribeEmail) {
743 - $listClass->sendUnsubscribe($userId, $unsubscribedLists);
744 - }
745 -
746 - if (!empty($unsubscribedLists)) {
747 - foreach ($unsubscribedLists as $i => $oneListId) {
748 - $currentList = $listClass->getOneById($oneListId);
749 - $unsubscribedLists[$i] = $currentList->name;
750 - }
751 - $this->sendNotification($user->id, 'acy_notification_unsub', ['lists' => implode(', ', $unsubscribedLists)]);
752 - }
753 - }
754 -
755 - if ($unsubscribedFromLists) {
756 - $this->registerUnsubUser($userIds);
757 - }
758 -
759 - return $unsubscribedFromLists;
760 - }
761 -
762 - public function unsubscribeOnSubscriptions(int $userId, array $listIds): bool
763 - {
764 - if (empty($listIds)) {
765 - return false;
766 - }
767 -
768 - acym_arrayToInteger($listIds);
769 -
770 - $subscribedLists = acym_loadResultArray('SELECT list_id FROM #__acym_user_has_list WHERE user_id = '.intval($userId).' AND list_id IN ('.implode(',', $listIds).')');
771 -
772 - if (!empty($subscribedLists)) $this->unsubscribe([$userId], $subscribedLists);
773 -
774 - return true;
775 - }
776 -
777 - public function removeSubscription(array $userIds, array $listIds = []): void
778 - {
779 - if (empty($listIds) || empty($userIds)) {
780 - return;
781 - }
782 -
783 - acym_arrayToInteger($userIds);
784 - acym_arrayToInteger($listIds);
785 -
786 - acym_query(
787 - 'DELETE FROM #__acym_user_has_list
788 - WHERE user_id IN ('.implode(',', $userIds).')
789 - AND list_id IN ('.implode(',', $listIds).')'
790 - );
791 - }
792 -
793 - public function onlyManageableUsers(array &$elements): void
794 - {
795 - if (acym_isAdmin()) {
796 - return;
797 - }
798 -
799 - $listClass = new ListClass();
800 - $manageableLists = $listClass->getManageableLists();
801 - if (empty($manageableLists)) {
802 - return;
803 - }
804 -
805 - $currentUserId = acym_currentUserId();
806 - acym_arrayToInteger($elements);
807 -
808 - $selfManagement = in_array($currentUserId, $elements);
809 -
810 - $elements = acym_loadResultArray(
811 - 'SELECT DISTINCT user_id
812 - FROM #__acym_user_has_list
813 - WHERE `list_id` IN ('.implode(',', $manageableLists).')
814 - AND `user_id` IN ('.implode(',', $elements).')'
815 - );
816 -
817 - if ($selfManagement && !in_array($currentUserId, $elements)) {
818 - $elements[] = $currentUserId;
819 - }
820 - }
821 -
822 - public function delete(array $elements, bool $forceDelete = false): int
823 - {
824 - acym_arrayToInteger($elements);
825 - $this->onlyManageableUsers($elements);
826 -
827 - if (empty($elements)) {
828 - return 0;
829 - }
830 -
831 - if (acym_isAdmin() || $forceDelete || 'delete' === $this->config->get('frontend_delete_button', 'delete')) {
832 - acym_query('DELETE FROM #__acym_user_has_list WHERE user_id IN ('.implode(',', $elements).')');
833 - acym_query('DELETE FROM #__acym_queue WHERE user_id IN ('.implode(',', $elements).')');
834 - acym_query('DELETE FROM #__acym_user_has_field WHERE user_id IN ('.implode(',', $elements).')');
835 - acym_query('DELETE FROM #__acym_history WHERE user_id IN ('.implode(',', $elements).')');
836 - acym_query('DELETE FROM #__acym_user_stat WHERE user_id IN ('.implode(',', $elements).')');
837 -
838 - $scenarioProcessIds = acym_loadResultArray('SELECT id FROM #__acym_scenario_process WHERE user_id IN ('.implode(',', $elements).')');
839 -
840 - if (!empty($scenarioProcessIds)) {
841 - acym_query('DELETE FROM #__acym_scenario_history_line WHERE scenario_process_id IN ('.implode(',', $scenarioProcessIds).')');
842 - acym_query('DELETE FROM #__acym_scenario_queue WHERE scenario_process_id IN ('.implode(',', $scenarioProcessIds).')');
843 - acym_query('DELETE FROM #__acym_scenario_process WHERE id IN ('.implode(',', $scenarioProcessIds).')');
844 - }
845 -
846 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
847 - foreach ($elements as $userId) {
848 - $folderPath = acym_cleanPath(ACYM_ROOT.$uploadFolder.'userfiles'.DS.$userId.DS);
849 - if (is_dir($folderPath)) {
850 - acym_deleteFolder($folderPath);
851 - }
852 - }
853 -
854 - return parent::delete($elements);
855 - } else {
856 - $listClass = new ListClass();
857 - $manageableLists = $listClass->getManageableLists();
858 -
859 - if (!empty($manageableLists)) {
860 - $this->removeSubscription($elements, $manageableLists);
861 - acym_query(
862 - 'DELETE queue
863 - FROM #__acym_queue AS queue
864 - JOIN #__acym_mail_has_list AS maillist
865 - ON queue.mail_id = maillist.mail_id
866 - WHERE queue.user_id IN ('.implode(',', $elements).')
867 - AND maillist.list_id IN ('.implode(',', $manageableLists).')'
868 - );
869 - }
870 -
871 - return count($elements);
872 - }
873 - }
874 -
875 - public function save(object $user, array $customFields = [], bool $ajax = false): ?int
876 - {
877 - if (empty($user->email) && empty($user->id)) {
878 - return null;
879 - }
880 -
881 - if (isset($user->email)) {
882 - $user->email = strtolower($user->email);
883 - if (!acym_isValidEmail($user->email)) {
884 - $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
885 -
886 - return null;
887 - }
888 - }
889 -
890 - if (empty($user->id)) {
891 - if (!isset($user->active)) {
892 - $user->active = 1;
893 - }
894 -
895 - if (empty($user->language)) {
896 - if (!acym_isAdmin()) {
897 - $cmsUserLanguage = acym_getCmsUserLanguage();
898 - }
899 -
900 - if (!empty($cmsUserLanguage)) {
901 - $user->language = $cmsUserLanguage;
902 - } elseif (acym_isMultilingual()) {
903 - $configUserLanguage = $this->config->get('multilingual_user_default', 'current_language');
904 - $user->language = $configUserLanguage === 'current_language' ? acym_getLanguageTag() : $configUserLanguage;
905 - }
906 - }
907 -
908 - $currentUserid = acym_currentUserId();
909 - $currentEmail = acym_currentUserEmail();
910 - $allowVisitors = $this->config->get('allow_visitor', 1) == 1;
911 - if ($this->checkVisitor && !acym_isAdmin() && !$allowVisitors && (empty($currentUserid) || strtolower($currentEmail) !== $user->email)) {
912 - $this->errors[] = acym_translation('ACYM_ONLY_LOGGED');
913 -
914 - return null;
915 - }
916 -
917 - if (empty($user->name) && $this->config->get('generate_name', 1)) {
918 - $user->name = ucwords(trim(str_replace(['.', '_', ')', ',', '(', '-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0], ' ', substr($user->email, 0, strpos($user->email, '@')))));
919 - }
920 -
921 - $source = acym_getVar('string', 'acy_source', '');
922 - if (empty($user->source) && !empty($source)) {
923 - $user->source = $source;
924 - }
925 -
926 - $user->key = acym_generateKey(14);
927 -
928 - $user->creation_date = date('Y-m-d H:i:s', time() - date('Z'));
929 - } elseif (!empty($user->confirmed)) {
930 - $oldUser = $this->getOneByIdWithCustomFields($user->id);
931 - if (!empty($oldUser) && empty($oldUser['confirmed'])) {
932 - $user->confirmation_date = date('Y-m-d H:i:s', time() - date('Z'));
933 - $user->confirmation_ip = acym_getIP();
934 -
935 - if ($this->triggers) {
936 - acym_trigger('onAcymAfterUserConfirm', [&$user]);
937 - }
938 - }
939 - } else {
940 - $oldUser = $this->getOneByIdWithCustomFields($user->id);
941 - }
942 -
943 - if (!empty($user->id) && isset($user->active) && !empty($oldUser)) {
944 - $wasActive = isset($oldUser['active']) ? (int)$oldUser['active'] : 1;
945 - $isNowActive = (int)$user->active;
946 - if ($wasActive === 1 && $isNowActive === 0) {
947 - $user->deactivation_date = acym_date('now', 'Y-m-d H:i:s');
948 - } elseif ($wasActive === 0 && $isNowActive === 1) {
949 - $user->deactivation_date = null;
950 - }
951 - }
952 -
953 - foreach ($user as $oneAttribute => $value) {
954 - if (empty($value)) {
955 - continue;
956 - }
957 -
958 - $oneAttribute = trim(strtolower($oneAttribute));
959 - if (!in_array($oneAttribute, self::RESTRICTED_FIELDS)) {
960 - $user->$oneAttribute = strip_tags($value);
961 - }
962 -
963 - if (is_numeric($user->$oneAttribute)) {
964 - continue;
965 - }
966 -
967 - if (function_exists('mb_detect_encoding')) {
968 - if (mb_detect_encoding($user->$oneAttribute, 'UTF-8', true) !== 'UTF-8') {
969 - $user->$oneAttribute = acym_utf8Encode($user->$oneAttribute);
970 - }
971 - } elseif (
972 - !preg_match(
973 - '%^(?:[\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$%xs',
974 - $user->$oneAttribute
975 - )
976 - ) {
977 - $user->$oneAttribute = acym_utf8Encode($user->$oneAttribute);
978 - }
979 - }
980 -
981 - if (!empty($user->automation) && strlen($user->automation) > 20) {
982 - $user->automation = '';
983 - }
984 -
985 - if (empty($user->id)) {
986 - if (empty($user->cms_id) && !empty($user->email)) {
987 - global $acymCmsUserVars;
988 - $userCmsID = acym_loadResult(
989 - 'SELECT '.acym_secureDBColumn($acymCmsUserVars->id).' FROM '.$acymCmsUserVars->table.' WHERE '.acym_secureDBColumn(
990 - $acymCmsUserVars->email
991 - ).' = '.acym_escapeDB($user->email)
992 - );
993 -
994 - if (!empty($userCmsID)) $user->cms_id = $userCmsID;
995 - }
996 - if ($this->triggers) {
997 - $result = acym_trigger('onAcymBeforeUserCreate', [&$user]);
998 - if (in_array(false, $result)) {
999 - $acycheckerError = acym_getVar('string', 'acychecker_error');
1000 - if (!empty($acycheckerError)) {
1001 - if ($ajax) {
1002 - $this->errors[] = $acycheckerError;
1003 - } else {
1004 - acym_enqueueMessage($acycheckerError, 'error');
1005 - }
1006 - }
1007 -
1008 - return null;
1009 - }
1010 - }
1011 - } else {
1012 - if ($this->triggers) {
1013 - acym_trigger('onAcymBeforeUserModify', [&$user]);
1014 - }
1015 - }
1016 -
1017 - $userID = parent::save($user);
1018 -
1019 - $fieldClass = new FieldClass();
1020 - if (!empty($customFields)) {
1021 - foreach ($customFields as $key => $value) {
1022 - if (!is_string($value)) {
1023 - continue;
1024 - }
1025 -
1026 - $value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $value);
1027 -
1028 - $field = $fieldClass->getOneById($key);
1029 - if (empty($field) || $field->type !== 'textarea') {
1030 - $value = preg_replace('/\s+/', ' ', $value);
1031 - }
1032 - $customFields[$key] = $value;
1033 - }
1034 - }
1035 - $fieldClass->store($userID, $customFields, $ajax);
1036 - if (!empty($fieldClass->errors)) {
1037 - $this->errors = array_merge($this->errors, $fieldClass->errors);
1038 - }
1039 -
1040 - $historyClass = new HistoryClass();
1041 - if (empty($user->id)) {
1042 - $user->id = $userID;
1043 - $historyClass->insert($user->id, 'created');
1044 - if ($this->triggers) {
1045 - acym_trigger('onAcymAfterUserCreate', [&$user]);
1046 - acym_triggerCmsHook('onAcymAfterUserSave', [$user, true]);
1047 - }
1048 - } else {
1049 - $historyClass->insert($user->id, 'modified');
1050 - if ($this->triggers) {
1051 - acym_trigger('onAcymAfterUserModify', [&$user, &$oldUser]);
1052 - acym_triggerCmsHook('onAcymAfterUserSave', [$user, false]);
1053 - }
1054 - }
1055 -
1056 - $this->sendConfirmation($userID);
1057 -
1058 - return $userID;
1059 - }
1060 -
1061 - public function saveForm(bool $ajax = false): bool
1062 - {
1063 - $allowUserModifications = $this->config->get('allow_modif', 'data') === 'all' || $this->allowModif;
1064 - $allowSubscriptionModifications = $this->config->get('allow_modif', 'data') !== 'none' || $this->allowModif;
1065 -
1066 - $user = new \stdClass();
1067 - $connectedUser = $this->identify(true, 'userId', 'userKey');
1068 -
1069 - $userData = acym_getVar('array', 'user', []);
1070 - if (!empty($userData)) {
1071 - foreach ($userData as $attribute => $value) {
1072 - if (!in_array($attribute, self::FORM_ALLOWED_FIELDS, true)) {
1073 - continue;
1074 - }
1075 - $user->$attribute = $value;
1076 - }
1077 - }
1078 -
1079 - if (empty($user->email)) {
1080 - if (!empty($connectedUser->email)) {
1081 - $user->email = $connectedUser->email;
1082 - }
1083 - }
1084 -
1085 - if (empty($user->email)) {
1086 - $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
1087 -
1088 - return false;
1089 - }
1090 -
1091 - if (!$allowUserModifications && !empty($connectedUser)) {
1092 - if ($connectedUser->email != $user->email) {
1093 - $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
1094 -
1095 - return false;
1096 - }
1097 -
1098 - $allowUserModifications = true;
1099 - $allowSubscriptionModifications = true;
1100 - }
1101 -
1102 - if (!empty($user->email)) {
1103 - if (empty($user->id)) {
1104 - $user->id = 0;
1105 - }
1106 - $existUser = acym_loadObject('SELECT * FROM #__acym_user WHERE email = '.acym_escapeDB($user->email).' AND id != '.intval($user->id));
1107 - if (!empty($existUser->id)) {
1108 - if (!$this->allowModif && !$allowSubscriptionModifications) {
1109 - $this->errors[] = acym_translation('ACYM_ADDRESS_TAKEN');
1110 -
1111 - return false;
1112 - } else {
1113 - $user->id = $existUser->id;
1114 - }
1115 - }
1116 - }
1117 -
1118 - if (!empty($user->id) && !empty($user->email)) {
1119 - $existUser = $this->getOneById($user->id);
1120 - if (trim(strtolower($user->email)) != strtolower($existUser->email)) {
1121 - $user->confirmed = 0;
1122 - }
1123 - }
1124 -
1125 - $this->newUser = empty($user->id);
1126 - if (empty($user->id) || $allowUserModifications) {
1127 - if ($this->newUser && $this->config->get('require_confirmation', 1) == 1) {
1128 - $user->confirmed = 0;
1129 - }
1130 - $customFieldData = acym_getVar('array', 'customField', []);
1131 - $id = $this->save($user, $customFieldData, $ajax);
1132 - $allowSubscriptionModifications = true;
1133 - } else {
1134 - $id = $user->id;
1135 - if (isset($user->confirmed) && empty($user->confirmed)) {
1136 - $this->sendConfirmation($id);
1137 - }
1138 - }
1139 -
1140 - if (empty($id)) return false;
1141 -
1142 - $formData = acym_getVar('array', 'data', []);
1143 - acym_setVar('userId', $id);
1144 -
1145 - if (!acym_isAdmin()) {
1146 - $hiddenlistsString = acym_getVar('string', 'hiddenlists', '');
1147 - $hiddenlists = explode(',', $hiddenlistsString);
1148 - $visibleSubscription = acym_getVar('array', 'subscription', []);
1149 - $subscribeLists = array_merge($hiddenlists, $visibleSubscription);
1150 - acym_arrayToInteger($subscribeLists);
1151 -
1152 - if (!empty($subscribeLists)) {
1153 - foreach ($subscribeLists as $oneListId) {
1154 - $formData['listsub'][$oneListId] = ['status' => 1];
1155 - }
1156 - }
1157 - }
1158 -
1159 - $fromProfile = acym_getVar('int', 'acyprofile', 0) == 1;
1160 -
1161 - if (empty($formData['listsub'])) {
1162 - if (!$fromProfile) $this->sendNotification($id, 'acy_notification_subform');
1163 -
1164 - $this->sendNotification(
1165 - $id,
1166 - $this->newUser ? 'acy_notification_create' : 'acy_notification_profile'
1167 - );
1168 -
1169 - return true;
1170 - }
1171 -
1172 - if (!$allowSubscriptionModifications) {
1173 - $this->requireId = true;
1174 - $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
1175 -
1176 - return false;
1177 - }
1178 -
1179 - $addLists = [];
1180 - $unsubLists = [];
1181 - foreach ($formData['listsub'] as $listID => $oneList) {
1182 - if ($oneList['status'] == 1) {
1183 - $addLists[] = $listID;
1184 - } else {
1185 - $unsubLists[] = $listID;
1186 - }
1187 - }
1188 -
1189 - $this->subscribed = $this->subscribe([$id], $addLists);
1190 -
1191 - if (!$fromProfile) $this->sendNotification($id, 'acy_notification_subform');
1192 -
1193 - $this->sendNotification(
1194 - $id,
1195 - $this->newUser ? 'acy_notification_create' : 'acy_notification_profile'
1196 - );
1197 -
1198 - if (!$this->newUser) $this->unsubscribe([$id], $unsubLists);
1199 -
1200 - return true;
1201 - }
1202 -
1203 - public function sendConfirmation(int $userID): void
1204 - {
1205 - if (!$this->forceConf && !$this->sendConf) {
1206 - return;
1207 - }
1208 -
1209 - if ($this->config->get('require_confirmation', 1) != 1 || (acym_isAdmin() && !$this->forceConfAdmin)) {
1210 - return;
1211 - }
1212 -
1213 - $myUser = $this->getOneById($userID);
1214 -
1215 - if (!empty($myUser->confirmed)) {
1216 - return;
1217 - }
1218 -
1219 - $mailerHelper = new MailerHelper();
1220 - $mailerHelper->report = (bool)$this->config->get('confirm_message', 0);
1221 -
1222 - $mailClass = new MailClass();
1223 - $confirmationEmail = $mailClass->getOneByName('acy_confirm');
1224 - $this->confirmationSentSuccess = !empty($confirmationEmail) && $mailerHelper->sendOne($confirmationEmail->id, $myUser->id);
1225 - $this->confirmationSentError = $mailerHelper->reportMessage;
1226 - }
1227 -
1228 - public function setInactive(array $elements): void
1229 - {
1230 - $this->deactivate($elements);
1231 - }
1232 -
1233 - public function deactivate(array $userIds): void
1234 - {
1235 - $userIds = array_map('intval', $userIds);
1236 - $userIds = array_filter($userIds);
1237 -
1238 - if (empty($userIds)) return;
1239 -
1240 - acym_query('UPDATE `#__acym_user` SET `active` = 0, `deactivation_date` = UTC_TIMESTAMP() WHERE `id` IN ('.implode(',', $userIds).')');
1241 - }
1242 -
1243 - public function setActive(array $elements): void
1244 - {
1245 - $this->reactivate($elements);
1246 - }
1247 -
1248 - public function reactivate(array $userIds): void
1249 - {
1250 - $userIds = array_map('intval', $userIds);
1251 - $userIds = array_filter($userIds);
1252 -
1253 - if (empty($userIds)) return;
1254 -
1255 - acym_query('UPDATE `#__acym_user` SET `active` = 1, `deactivation_date` = NULL WHERE `id` IN ('.implode(',', $userIds).')');
1256 - }
1257 -
1258 - public function confirm(int $userId): void
1259 - {
1260 - $user = $this->getOneById($userId);
1261 - if (empty($user)) return;
1262 -
1263 - $confirmDate = date('Y-m-d H:i:s', time() - date('Z'));
1264 - $ip = acym_getIP();
1265 - $query = 'UPDATE `#__acym_user`';
1266 - $query .= ' SET `confirmed` = 1, `confirmation_date` = '.acym_escapeDB($confirmDate).', `confirmation_ip` = '.acym_escapeDB($ip);
1267 - $query .= ' WHERE `id` = '.intval($userId).' LIMIT 1';
1268 -
1269 - try {
1270 - $res = acym_query($query);
1271 - } catch (\Exception $e) {
1272 - $res = false;
1273 - }
1274 - if ($res === false) {
1275 - $errorMessage = isset($e) ? $e->getMessage() : acym_getDBError();
1276 - $msg = acym_translation('ACYM_CONTACT_ADMIN_ERROR').'<br />'.substr(strip_tags($errorMessage), 0, 200).'...';
1277 - acym_display($msg, 'error');
1278 - exit;
1279 - }
1280 -
1281 - acym_trigger('onAcymAfterUserConfirm', [&$user]);
1282 - $this->sendNotification($userId, 'acy_notification_confirm');
1283 -
1284 - $historyClass = new HistoryClass();
1285 - $historyClass->insert($userId, 'confirmed');
1286 -
1287 - if (empty($this->config->get('require_confirmation', 1))) return;
1288 -
1289 - $listIDs = acym_loadResultArray('SELECT `list_id` FROM `#__acym_user_has_list` WHERE `status` = 1 AND `user_id` = '.intval($userId));
1290 -
1291 - if (empty($listIDs)) return;
1292 -
1293 - $listClass = new ListClass();
1294 - $listClass->sendWelcome($userId, $listIDs);
1295 - }
1296 -
1297 - public function getOneByIdWithCustomFields(int $id): array
1298 - {
1299 - $user = $this->getOneById($id);
1300 - if (empty($user)) {
1301 - return [];
1302 - }
1303 -
1304 - $user = get_object_vars($user);
1305 -
1306 - $fieldsValue = acym_loadObjectList(
1307 - 'SELECT user_field.`value`, field.`name`
1308 - FROM #__acym_user_has_field AS `user_field`
1309 - LEFT JOIN #__acym_field AS `field` ON user_field.`field_id` = field.`id`
1310 - WHERE user_field.`user_id` = '.intval($id),
1311 - 'name'
1312 - );
1313 -
1314 - foreach ($fieldsValue as $key => $value) {
1315 - $fieldsValue[$key] = $value->value;
1316 - }
1317 -
1318 - return array_merge($user, $fieldsValue);
1319 - }
1320 -
1321 - public function getCustomFieldValueById(int $id): array
1322 - {
1323 - $fieldsValue = acym_loadObjectList(
1324 - 'SELECT user_field.value AS value, field.name AS name, field.type AS type, field.value AS field_params, field.id AS id
1325 - FROM #__acym_user_has_field as user_field
1326 - LEFT JOIN #__acym_field as field ON user_field.field_id = field.id
1327 - WHERE user_field.user_id = '.intval($id),
1328 - 'id'
1329 - );
1330 -
1331 - $fieldReturn = [];
1332 -
1333 - foreach ($fieldsValue as $fieldId => $field) {
1334 - if (in_array($field->type, ['checkbox', 'radio', 'single_dropdown', 'multiple_dropdown'])) {
1335 - $field->field_params = json_decode($field->field_params, true);
1336 - $field->value = explode(',', $field->value);
1337 - $values = [];
1338 - foreach ($field->value as $oneValue) {
1339 - $key = array_search($oneValue, array_column($field->field_params, 'value'));
1340 - $values[] = $field->field_params[$key]['title'];
1341 - }
1342 - $fieldReturn[$field->name] = implode(',', $values);
1343 - } else {
1344 - $fieldReturn[$field->name] = $field->value;
1345 - }
1346 - }
1347 -
1348 - return $fieldReturn;
1349 - }
1350 -
1351 - public function getAllColumnsUserAndCustomField(bool $inAction = false, bool $withSubInfos = false): array
1352 - {
1353 - $return = [];
1354 -
1355 - $userFields = acym_getColumns('user');
1356 - foreach ($userFields as $value) {
1357 - $return[$value] = $value;
1358 - }
1359 -
1360 - $languageFieldId = $this->config->get(FieldClass::LANGUAGE_FIELD_ID_KEY, 0);
1361 -
1362 - $customFields = acym_loadObjectList(
1363 - 'SELECT * FROM #__acym_field WHERE id NOT IN (1, 2, '.intval($languageFieldId).') '.($inAction ? 'AND type != "phone"' : ''),
1364 - 'id'
1365 - );
1366 - if (!empty($customFields)) {
1367 - foreach ($customFields as $key => $value) {
1368 - $return[$key] = $value->name;
1369 - }
1370 - }
1371 -
1372 - if ($withSubInfos) {
1373 - $listCLass = new ListClass();
1374 - $listFields = $listCLass->getAll('name');
1375 - if (!empty($listFields)) {
1376 - foreach ($listFields as $key => $value) {
1377 - if ($value->type === ListClass::LIST_TYPE_FOLLOWUP) {
1378 - continue;
1379 - }
1380 - $return['subscription_date_'.$value->id] = acym_translation('ACYM_SUBSCRIPTION_DATE').' '.$value->name;
1381 - $return['unsubscription_date_'.$value->id] = acym_translation('ACYM_UNSUBSCRIPTION_DATE').' '.$value->name;
1382 - }
1383 - }
1384 - }
1385 -
1386 - return $return;
1387 - }
1388 -
1389 - public function getAllUserFields(object $user): object
1390 - {
1391 - if (empty($user->id)) {
1392 - return $user;
1393 - }
1394 -
1395 - $query = 'SELECT field.*, field.value AS field_value, userfield.*
1396 - FROM #__acym_field AS field
1397 - LEFT JOIN #__acym_user_has_field AS userfield ON field.id = userfield.field_id AND userfield.user_id = '.intval($user->id).'
1398 - WHERE field.id NOT IN(1, 2)';
1399 -
1400 - $allFields = acym_loadObjectList($query);
1401 -
1402 - foreach ($allFields as $oneField) {
1403 - $fieldOptions = @json_decode(empty($oneField->option) ? '{}' : $oneField->option);
1404 - if (in_array($oneField->type, ['multiple_dropdown', 'radio', 'checkbox', 'single_dropdown'])) {
1405 - $oneField->field_value = json_decode($oneField->field_value, true);
1406 - if (!empty($oneField->value)) {
1407 - $oneField->value = explode(',', $oneField->value);
1408 - $values = [];
1409 - foreach ($oneField->field_value as $oneFieldValue) {
1410 - foreach ($oneField->value as $oneValue) {
1411 - if ($oneFieldValue['value'] == $oneValue) {
1412 - $values[] = $oneFieldValue['title'];
1413 - }
1414 - }
1415 - }
1416 - $oneField->value = implode(',', $values);
1417 - }
1418 - } elseif ($oneField->type === 'file' && !empty($oneField->value)) {
1419 - $tryJsonDecode = json_decode($oneField->value);
1420 - if (json_last_error() === JSON_ERROR_NONE && is_array($tryJsonDecode)) {
1421 - $oneField->value = !empty($tryJsonDecode) ? $tryJsonDecode[0] : null;
1422 - }
1423 - } elseif ($oneField->type === 'date') {
1424 - if (empty($fieldOptions->format)) {
1425 - acym_logError('Date field with ID '.$oneField->id.' without format option');
1426 - continue;
1427 - }
1428 - $formatToDisplay = explode('%', str_replace('y', 'Y', $fieldOptions->format));
1429 - unset($formatToDisplay[0]);
1430 - if (!empty($oneField->value)) {
1431 - $oneField->value = acym_date($oneField->value, implode('-', $formatToDisplay));
1432 - }
1433 - }
1434 - $user->{$oneField->namekey} = empty($oneField->value) ? '' : $oneField->value;
1435 - }
1436 -
1437 - return $user;
1438 - }
1439 -
1440 - public function getAllSimpleData(): array
1441 - {
1442 - return acym_loadObjectList('SELECT email, name FROM #__acym_user');
1443 - }
1444 -
1445 - public function synchSaveCmsUser(array $user, bool $isnew, ?array $oldUser = null): void
1446 - {
1447 - $source = acym_getVar('string', 'acy_source', '');
1448 - if (empty($source)) acym_setVar('acy_source', ACYM_CMS);
1449 -
1450 - if (!$this->config->get('regacy', 0)) return;
1451 -
1452 - $this->checkVisitor = false;
1453 - $this->sendConf = false;
1454 -
1455 - $regacyForceConf = $this->config->get('regacy_forceconf', 0);
1456 - $cmsUser = new \stdClass();
1457 - $cmsUser->email = trim(strip_tags($user['email']));
1458 - if (!acym_isValidEmail($cmsUser->email)) return;
1459 - if (!empty($user['name'])) $cmsUser->name = trim(strip_tags($user['name']));
1460 - if (!$regacyForceConf) $cmsUser->confirmed = 1;
1461 - $cmsUser->active = 1 - intval($user['block']);
1462 - $cmsUser->cms_id = $user['id'];
1463 -
1464 - if (!$isnew && !empty($oldUser['email']) && $user['email'] != $oldUser['email']) {
1465 - $acyUser = $this->getOneByEmail($oldUser['email']);
1466 - if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
1467 - }
1468 -
1469 - if (empty($cmsUser->id) && !empty($cmsUser->cms_id)) {
1470 - $acyUser = $this->getOneByCMSId($cmsUser->cms_id);
1471 - if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
1472 - }
1473 -
1474 - $acyUser = $this->getOneByEmail($cmsUser->email);
1475 - if (!empty($acyUser)) {
1476 - if (empty($cmsUser->id)) {
1477 - $cmsUser->id = $acyUser->id;
1478 - } elseif ($cmsUser->id != $acyUser->id) {
1479 - $this->delete([$acyUser->id]);
1480 - }
1481 - } else {
1482 - $cmsUser->source = $source;
1483 - }
1484 -
1485 - $isnew = $isnew || empty($cmsUser->id);
1486 -
1487 - $id = $this->save($cmsUser);
1488 - if (empty($id)) {
1489 - return;
1490 - }
1491 -
1492 - $confirmationRequired = $this->config->get('require_confirmation', 1);
1493 - if (!$isnew && !$regacyForceConf && $user['block'] == 0 && !empty($oldUser['block']) && $confirmationRequired == 1) {
1494 - $this->confirm($id);
1495 - }
1496 -
1497 -
1498 - $currentSubscription = $this->getSubscriptionStatus($id);
1499 -
1500 - $autoLists = $isnew ? $this->config->get('regacy_autolists', '') : '';
1501 - $autoLists = explode(',', $autoLists);
1502 - acym_arrayToInteger($autoLists);
1503 -
1504 - $listsClass = new ListClass();
1505 - $allLists = $listsClass->getAll();
1506 -
1507 - $visibleLists = acym_getVar('string', 'regacy_visible_lists', '');
1508 - $visibleLists = explode(',', $visibleLists);
1509 - acym_arrayToInteger($visibleLists);
1510 -
1511 - $visibleListsChecked = acym_getVar('array', 'regacy_visible_lists_checked', []);
1512 - acym_arrayToInteger($visibleListsChecked);
1513 -
1514 -
1515 - if (!$isnew && !empty($visibleLists)) {
1516 - $currentlySubscribedLists = [];
1517 - foreach ($currentSubscription as $oneSubscription) {
1518 - if ($oneSubscription->status == 1) $currentlySubscribedLists[] = $oneSubscription->list_id;
1519 - }
1520 - $unsubscribeLists = array_intersect($currentlySubscribedLists, array_diff($visibleLists, $visibleListsChecked));
1521 - $this->unsubscribe([$id], $unsubscribeLists);
1522 - }
1523 -
1524 - $listsToSubscribe = [];
1525 - foreach ($allLists as $oneList) {
1526 - if (!$oneList->active) continue;
1527 - if (!empty($currentSubscription[$oneList->id]) && $currentSubscription[$oneList->id]->status == 1) continue;
1528 -
1529 - if (
1530 - in_array($oneList->id, $visibleListsChecked)
1531 - || (
1532 - in_array($oneList->id, $autoLists)
1533 - && !in_array($oneList->id, $visibleLists) && empty($currentSubscription[$oneList->id])
1534 - )
1535 - ) {
1536 - $listsToSubscribe[] = $oneList->id;
1537 - }
1538 - }
1539 -
1540 - if (!empty($listsToSubscribe)) $this->subscribe([$id], $listsToSubscribe);
1541 -
1542 - if ($isnew) $this->sendNotification($id, 'acy_notification_create');
1543 -
1544 - $acymailingUser = $this->getOneById($id);
1545 - if (!empty($user['block']) || !empty($acymailingUser->confirmed)) return;
1546 -
1547 - if ($isnew || !empty($oldUser['block'])) {
1548 - if ($confirmationRequired && $regacyForceConf) {
1549 - $this->forceConf = true;
1550 - $this->sendConfirmation($id);
1551 - }
1552 -
1553 - if (!$confirmationRequired && !empty($oldUser['email'])) {
1554 - $listIDs = acym_loadResultArray('SELECT `list_id` FROM `#__acym_user_has_list` WHERE `status` = 1 AND `user_id` = '.intval($id));
1555 - if (empty($listIDs)) return;
1556 - $listsClass->sendWelcome($id, $listIDs);
1557 - }
1558 - }
1559 - }
1560 -
1561 - public function synchDeleteCmsUser(string $userEmail): void
1562 - {
1563 - $acyUser = $this->getOneByEmail($userEmail);
1564 -
1565 - if (empty($acyUser)) return;
1566 -
1567 - if ($this->config->get('regacy', '0') == 1 && $this->config->get('regacy_delete', '0') == 1) {
1568 - $this->delete([$acyUser->id]);
1569 - } else {
1570 - acym_query('UPDATE #__acym_user SET `cms_id` = 0 WHERE `id` = '.intval($acyUser->id));
1571 - }
1572 - }
1573 -
1574 - public function getUsersLikeEmail(string $search): array
1575 - {
1576 - $query = 'SELECT id, email FROM #__acym_user WHERE email LIKE '.acym_escapeDB('%'.$search.'%');
1577 -
1578 - return acym_loadObjectList($query);
1579 - }
1580 -
1581 - public function sendNotification(int $userId, string $notification, array $params = []): void
1582 - {
1583 - if (empty($userId) || $this->blockNotifications) return;
1584 -
1585 - $notifyUsers = explode(',', $this->config->get($notification));
1586 - if (acym_isAdmin() || empty($notifyUsers)) return;
1587 -
1588 - $mailerHelper = new MailerHelper();
1589 - $mailerHelper->report = false;
1590 - $mailerHelper->autoAddUser = true;
1591 -
1592 - $user = $this->getOneById($userId);
1593 - $userField = empty($user) ? null : $this->getAllUserFields($user);
1594 - if (!empty($userField)) {
1595 - foreach ($userField as $map => $value) {
1596 - $mailerHelper->addParam('user:'.$map, $value);
1597 - }
1598 - }
1599 -
1600 - $rawSubscription = $this->getUserSubscriptionById($userId);
1601 - $subscription = [''];
1602 - foreach ($rawSubscription as $listId => $listData) {
1603 - $currentList = $listData->name.' => ';
1604 - if (intval($listData->status) === 1) {
1605 - $currentList .= acym_translation('ACYM_SUBSCRIBED').' - '.$listData->subscription_date;
1606 - } else {
1607 - $currentList .= acym_translation('ACYM_UNSUBSCRIBED').' - '.$listData->unsubscribe_date;
1608 - }
1609 - $subscription[] = $currentList;
1610 - }
1611 - $mailerHelper->addParam('user:subscription', implode('<br/>', $subscription));
1612 -
1613 - if (!empty($params)) {
1614 - foreach ($params as $name => $value) {
1615 - $mailerHelper->addParam($name, $value);
1616 - }
1617 - }
1618 -
1619 - $mailClass = new MailClass();
1620 - foreach ($notifyUsers as $oneUser) {
1621 - if (!acym_isValidEmail($oneUser)) {
1622 - continue;
1623 - }
1624 -
1625 - $admin = $this->getOneByEmail($oneUser, true);
1626 -
1627 - $notificationEmail = $mailClass->getOneByName($notification);
1628 - if (!empty($admin) && !empty($notificationEmail)) {
1629 - try {
1630 - $mailerHelper->sendOne($notificationEmail->id, $admin->id);
1631 - } catch (\Exception $e) {
1632 - acym_logError($e->getMessage());
1633 - }
1634 - }
1635 - }
1636 - }
1637 -
1638 - public function getMailHistory(int $userId)
1639 - {
1640 - $mailHistory = acym_loadObjectList(
1641 - 'SELECT user_stat.*, mail.id, mail.subject, SUM(url_click.click) as click
1642 - FROM #__acym_user_stat AS user_stat
1643 - JOIN #__acym_mail AS mail ON mail.id = user_stat.mail_id
1644 - LEFT JOIN #__acym_url_click AS url_click ON user_stat.mail_id = url_click.mail_id AND url_click.user_id = '.intval($userId).'
1645 - WHERE user_stat.user_id = '.intval($userId).'
1646 - GROUP BY mail_id
1647 - ORDER BY send_date DESC
1648 - LIMIT 50',
1649 - 'mail_id'
1650 - );
1651 - $mailClass = new MailClass();
1652 -
1653 - return $mailClass->decode($mailHistory);
1654 - }
1655 -
1656 - public function deleteHistoryPeriod(): array
1657 - {
1658 - if (empty($this->config->get('delete_user_history_enabled', 0))) return [];
1659 - $deleteOverSecond = $this->config->get('delete_user_history', 0);
1660 - if (empty($deleteOverSecond)) return [];
1661 - $date = time() - $deleteOverSecond;
1662 -
1663 - $query = 'DELETE FROM #__acym_history WHERE date < '.intval($date);
1664 -
1665 - try {
1666 - $status = acym_query($query);
1667 - $message = empty($status) ? '' : acym_translationSprintf('ACYM_DELETE_X_ROWS_TABLE_X', $status, strtolower(acym_translation('ACYM_USER_HISTORY')));
1668 - } catch (\Exception $e) {
1669 - $status = false;
1670 - $message = $e->getMessage();
1671 - }
1672 -
1673 - return ['status' => $status !== false, 'message' => $message];
1674 - }
1675 -
1676 - public function resetSubscription(array $userIds, array $lists): bool
1677 - {
1678 - if (empty($lists)) return false;
1679 -
1680 - acym_arrayToInteger($userIds);
1681 - acym_arrayToInteger($lists);
1682 -
1683 - foreach ($userIds as $userId) {
1684 - acym_query(
1685 - 'DELETE FROM `#__acym_user_has_list`
1686 - WHERE user_id = '.$userId.'
1687 - AND list_id IN ('.implode(',', $lists).')'
1688 - );
1689 -
1690 - acym_query(
1691 - 'DELETE FROM #__acym_queue WHERE user_id = '.$userId.' AND mail_id IN (
1692 - SELECT followup_mail.mail_id FROM #__acym_followup_has_mail AS followup_mail
1693 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup.list_id IN ('.implode(',', $lists).')
1694 - )'
1695 - );
1696 -
1697 - $historyClass = new HistoryClass();
1698 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $lists));
1699 - $historyClass->insert($userId, 'reset_subscription', [$historyData]);
1700 - }
1701 -
1702 - return true;
1703 - }
1704 -
1705 - public function addMissingKeys(): int
1706 - {
1707 - $usersMissingKey = acym_loadResultArray('SELECT `id` FROM #__acym_user WHERE `key` IS NULL OR `key` = ""');
1708 - foreach ($usersMissingKey as $oneUserId) {
1709 - acym_query('UPDATE #__acym_user SET `key` = '.acym_escapeDB(acym_generateKey(14)).' WHERE `id` = '.intval($oneUserId));
1710 - }
1711 -
1712 - return count($usersMissingKey);
1713 - }
1714 -
1715 - public function hasUserAccess(int $subscriberId): bool
1716 - {
1717 - $userId = acym_currentUserId();
1718 - if (empty($userId)) {
1719 - return false;
1720 - }
1721 -
1722 - if (acym_isAdmin()) {
1723 - return true;
1724 - }
1725 -
1726 - $user = $this->getOneById($subscriberId);
1727 - $userEmail = acym_currentUserEmail();
1728 - if (!empty($user) && $user->email === $userEmail) {
1729 - return true;
1730 - }
1731 -
1732 - $listClass = new ListClass();
1733 - $allowedListIds = $listClass->getManageableLists();
1734 - if (empty($allowedListIds)) {
1735 - return false;
1736 - }
1737 -
1738 - $query = 'SELECT COUNT(*) FROM #__acym_user AS user
1739 - JOIN #__acym_user_has_list AS map ON map.user_id = user.id
1740 - WHERE map.list_id IN ('.implode(',', $allowedListIds).')
1741 - AND user.id = '.intval($subscriberId);
1742 -
1743 - return acym_loadResult($query) > 0;
1744 - }
1745 -
1746 - public function getXUsers(array $options = []): array
1747 - {
1748 - $limit = $options['limit'] ?? 10;
1749 - $offset = $options['offset'] ?? 0;
1750 - $filters = $options['filters'] ?? [];
1751 -
1752 - $conditions = [];
1753 - foreach ($filters as $column => $filter) {
1754 - if (in_array($column, ['id', 'cms_id', 'active', 'confirmed', 'tracking'])) {
1755 - $conditions[] = acym_secureDBColumn($column).' = '.intval($filter);
1756 - } else {
1757 - $conditions[] = acym_secureDBColumn($column).' LIKE '.acym_escapeDB('%'.$filter.'%');
1758 - }
1759 - }
1760 -
1761 - if (!empty($options['created_after'])) {
1762 - $conditions[] = 'creation_date > '.acym_escapeDB($options['created_after']);
1763 - }
1764 -
1765 - if (!empty($options['confirmed_after'])) {
1766 - $conditions[] = 'confirmation_date > '.acym_escapeDB($options['confirmed_after']);
1767 - }
1768 -
1769 - $query = 'SELECT * FROM #__acym_user';
1770 - if (!empty($conditions)) {
1771 - $query .= ' WHERE '.implode(' AND ', $conditions);
1772 - }
1773 -
1774 - return acym_loadObjectList($query, $this->pkey, $offset, $limit);
1775 - }
1776 -}