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 -1765 10.10.2 → 11.1.1 View file →
@@ -1,1765 +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' ? $value : 'user.'.$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 - $query = 'SELECT `list`.`id`, `list`.`color`, `list`.`name`, `userlist`.`user_id`, `userlist`.`status`
463 - FROM #__acym_list AS `list`
464 - JOIN #__acym_user_has_list AS `userlist`
465 - ON `list`.`id` = `userlist`.`list_id`
466 - WHERE `userlist`.`user_id` IN ('.implode(',', $userIds).')
467 - AND `list`.`type` = '.acym_escapeDB(ListClass::LIST_TYPE_STANDARD);
468 -
469 - if (!empty($creatorId)) {
470 - $userGroups = acym_getGroupsByUser($creatorId);
471 - $groupCondition = '`list`.`access` LIKE "%,'.implode(',%" OR `list`.`access` LIKE "%,', $userGroups).',%"';
472 - $query .= ' AND (`list`.`cms_user_id` = '.intval($creatorId).' OR '.$groupCondition.')';
473 - }
474 - $query .= ' ORDER BY `userlist`.`status` DESC, `list`.`id` ASC';
475 -
476 - return acym_loadObjectList($query);
477 - }
478 -
479 - public function getCountTotalUsers(): int
480 - {
481 - $numberOfUsers = acym_loadResult('SELECT COUNT(id) FROM #__acym_user');
482 -
483 - return empty($numberOfUsers) ? 0 : $numberOfUsers;
484 - }
485 -
486 - public function getSubscriptionStatus(int $userId, array $listIds = [], ?int $wantedStatus = null): array
487 - {
488 - $query = 'SELECT status, list_id
489 - FROM #__acym_user_has_list
490 - WHERE user_id = '.intval($userId);
491 - if (!empty($listIds)) {
492 - acym_arrayToInteger($listIds);
493 - $query .= ' AND list_id IN ('.implode(',', $listIds).')';
494 - }
495 -
496 - if ($wantedStatus !== null) {
497 - $query .= ' AND status = '.intval($wantedStatus);
498 - }
499 -
500 - return acym_loadObjectList($query, 'list_id');
501 - }
502 -
503 - public function identify(bool $onlyValue = false, ?string $idName = null, ?string $keyName = null): ?object
504 - {
505 - $id = acym_getVar('int', empty($idName) ? 'id' : $idName, 0);
506 - $key = acym_getVar('string', empty($keyName) ? 'key' : $keyName, '');
507 -
508 - if (empty($id) && !empty($idName) && empty($key) && !empty($keyName)) {
509 - $id = acym_getVar('int', 'id', 0);
510 - $key = acym_getVar('string', 'key', 0);
511 - }
512 -
513 - if (empty($id) || empty($key)) {
514 - $currentUserid = acym_currentUserId();
515 - if (!empty($currentUserid)) {
516 - return $this->getOneByCMSId($currentUserid);
517 - }
518 - if (!$onlyValue) {
519 - acym_enqueueMessage(acym_translation('ACYM_LOGIN'), 'error');
520 - }
521 -
522 - return null;
523 - }
524 -
525 - $userIdentified = acym_loadObject('SELECT * FROM #__acym_user WHERE `id` = '.intval($id).' AND `key` = '.acym_escapeDB($key));
526 -
527 - if (!empty($userIdentified)) {
528 - return $userIdentified;
529 - }
530 -
531 - if (!$onlyValue) {
532 - acym_enqueueMessage(acym_translation('ACYM_USER_NOT_FOUND'), 'error');
533 - }
534 -
535 - return null;
536 - }
537 -
538 - public function subscribe($userIds, array $addLists, bool $trigger = true, bool $forceFront = false): bool
539 - {
540 - if (empty($addLists)) {
541 - return false;
542 - }
543 -
544 - if (!is_array($userIds)) {
545 - $userIds = [$userIds];
546 - }
547 -
548 - $listClass = new ListClass();
549 - $historyClass = new HistoryClass();
550 -
551 - $confirmationRequired = !empty($this->config->get('require_confirmation', 1));
552 - $subscribedToLists = false;
553 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $addLists));
554 -
555 - foreach ($userIds as $userId) {
556 - $user = $this->getOneById($userId);
557 - if (empty($user)) continue;
558 - $currentSubscription = $this->getUserSubscriptionById($userId, 'id', true);
559 -
560 - $currentlySubscribed = [];
561 - $currentlyUnsubscribed = [];
562 - foreach ($currentSubscription as $oneList) {
563 - if ($oneList->status == 1) {
564 - $currentlySubscribed[$oneList->id] = $oneList;
565 - }
566 - if ($oneList->status == 0) {
567 - $currentlyUnsubscribed[$oneList->id] = $oneList;
568 - }
569 - }
570 -
571 - $subscribedLists = [];
572 - $listsNotExisting = [];
573 - foreach ($addLists as $oneListId) {
574 - if (empty($oneListId) || !empty($currentlySubscribed[$oneListId])) {
575 - continue;
576 - }
577 -
578 - $list = $listClass->getOneById($oneListId);
579 - if (empty($list)) {
580 - $listsNotExisting[] = $oneListId;
581 - continue;
582 - }
583 -
584 - $subscription = new \stdClass();
585 - $subscription->user_id = $userId;
586 - $subscription->list_id = $oneListId;
587 - $subscription->status = 1;
588 - $subscription->subscription_date = date('Y-m-d H:i:s', time() - date('Z'));
589 -
590 - if (empty($currentSubscription[$oneListId])) {
591 - acym_insertObject('#__acym_user_has_list', $subscription);
592 - } elseif (!empty($currentlyUnsubscribed[$oneListId])) {
593 - acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
594 - }
595 -
596 - $subscribedLists[] = $oneListId;
597 - $subscribedToLists = true;
598 - }
599 -
600 - if (!empty($listsNotExisting)) {
601 - $this->errors['list_not_existing'] = acym_translationSprintf('ACYM_LIST_NOT_FOUND', implode(', ', $listsNotExisting));
602 - }
603 -
604 - $historyClass->insert($userId, 'subscribed', [$historyData]);
605 -
606 - if ($trigger) {
607 - acym_trigger('onAcymAfterUserSubscribe', [&$user, &$subscribedLists]);
608 - }
609 -
610 - if ($this->sendWelcomeEmail && (!$confirmationRequired || $user->confirmed == 1) && $user->active == 1) {
611 - $listClass->sendWelcome($userId, $subscribedLists, $forceFront);
612 - }
613 - }
614 -
615 - return $subscribedToLists;
616 - }
617 -
618 - private function registerUnsubUser(array $userIds): void
619 - {
620 - $mailId = acym_getVar('int', 'mail_id', 0);
621 - if (empty($mailId)) return;
622 -
623 - $mailStatClass = new MailStatClass();
624 - $userStatClass = new UserStatClass();
625 -
626 - $countUnsubscribe = 0;
627 -
628 - foreach ($userIds as $id) {
629 - $userStat = $userStatClass->getOneByMailAndUserId($mailId, $id);
630 - if (empty($userStat)) continue;
631 -
632 - $newUserStat = new \stdClass();
633 - $newUserStat->mail_id = $mailId;
634 - $newUserStat->user_id = $id;
635 - $newUserStat->unsubscribe = empty($userStat->unsubscribe) ? 1 : $userStat->unsubscribe + 1;
636 -
637 - if (empty($userStat->unsubscribe)) {
638 - $countUnsubscribe++;
639 - }
640 -
641 - $userStatClass->save($newUserStat);
642 - }
643 -
644 - $mailStat = new \stdClass();
645 - $mailStat->mail_id = $mailId;
646 - $mailStat->unsubscribe_total = $countUnsubscribe;
647 -
648 - $mailStatClass->save($mailStat);
649 - }
650 -
651 - public function unsubscribe($userIds, array $lists): bool
652 - {
653 - if (empty($lists)) {
654 - return false;
655 - }
656 -
657 - if (!is_array($userIds)) {
658 - $userIds = [$userIds];
659 - }
660 -
661 - $listClass = new ListClass();
662 - $unsubscribedFromLists = false;
663 - foreach ($userIds as $userId) {
664 - $user = $this->getOneById($userId);
665 -
666 - if (empty($user)) {
667 - continue;
668 - }
669 -
670 - $currentSubscription = $this->getUserSubscriptionById($userId);
671 -
672 - $currentlySubscribed = [];
673 - $currentlyUnsubscribed = [];
674 - foreach ($currentSubscription as $oneList) {
675 - if ($oneList->status == 0) {
676 - $currentlyUnsubscribed[$oneList->id] = $oneList;
677 - } elseif ($oneList->status == 1) {
678 - $currentlySubscribed[$oneList->id] = $oneList;
679 - }
680 - }
681 -
682 - $unsubscribedLists = [];
683 - $listsNotExisting = [];
684 - foreach ($lists as $oneListId) {
685 - if (empty($oneListId) || !empty($currentlyUnsubscribed[$oneListId])) {
686 - continue;
687 - }
688 -
689 - if (empty($currentlySubscribed[$oneListId])) {
690 - continue;
691 - }
692 -
693 - $list = $listClass->getOneById($oneListId);
694 - if (empty($list)) {
695 - $listsNotExisting[] = $oneListId;
696 - continue;
697 - }
698 -
699 - $subscription = new \stdClass();
700 - $subscription->user_id = $userId;
701 - $subscription->list_id = $oneListId;
702 - $subscription->status = 0;
703 - $subscription->unsubscribe_date = date('Y-m-d H:i:s', time() - date('Z'));
704 - if (empty($currentSubscription[$oneListId])) {
705 - acym_insertObject('#__acym_user_has_list', $subscription);
706 - } else {
707 - acym_updateObject('#__acym_user_has_list', $subscription, ['user_id', 'list_id']);
708 - }
709 -
710 - $unsubscribedLists[] = $oneListId;
711 - $unsubscribedFromLists = true;
712 - }
713 -
714 - if (!empty($listsNotExisting)) {
715 - $this->errors['list_not_existing'] = acym_translationSprintf('ACYM_LIST_NOT_FOUND', implode(', ', $listsNotExisting));
716 - }
717 -
718 - acym_query(
719 - 'DELETE FROM #__acym_queue WHERE user_id = '.intval($userId).' AND mail_id IN (
720 - SELECT followup_mail.mail_id FROM #__acym_followup_has_mail AS followup_mail
721 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup.list_id IN ('.implode(',', $lists).')
722 - )'
723 - );
724 -
725 - $historyClass = new HistoryClass();
726 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $lists));
727 - $historyClass->insert($userId, 'unsubscribed', [$historyData], 0, acym_getVar('string', 'unsubscribe_reason'));
728 -
729 - if ($this->triggers) {
730 - acym_trigger('onAcymAfterUserUnsubscribe', [&$user, &$unsubscribedLists]);
731 - }
732 -
733 - if ($this->sendUnsubscribeEmail) {
734 - $listClass->sendUnsubscribe($userId, $unsubscribedLists);
735 - }
736 -
737 - if (!empty($unsubscribedLists)) {
738 - foreach ($unsubscribedLists as $i => $oneListId) {
739 - $currentList = $listClass->getOneById($oneListId);
740 - $unsubscribedLists[$i] = $currentList->name;
741 - }
742 - $this->sendNotification($user->id, 'acy_notification_unsub', ['lists' => implode(', ', $unsubscribedLists)]);
743 - }
744 - }
745 -
746 - if ($unsubscribedFromLists) {
747 - $this->registerUnsubUser($userIds);
748 - }
749 -
750 - return $unsubscribedFromLists;
751 - }
752 -
753 - public function unsubscribeOnSubscriptions(int $userId, array $listIds): bool
754 - {
755 - if (empty($listIds)) {
756 - return false;
757 - }
758 -
759 - acym_arrayToInteger($listIds);
760 -
761 - $subscribedLists = acym_loadResultArray('SELECT list_id FROM #__acym_user_has_list WHERE user_id = '.intval($userId).' AND list_id IN ('.implode(',', $listIds).')');
762 -
763 - if (!empty($subscribedLists)) $this->unsubscribe([$userId], $subscribedLists);
764 -
765 - return true;
766 - }
767 -
768 - public function removeSubscription(array $userIds, array $listIds = []): void
769 - {
770 - if (empty($listIds) || empty($userIds)) {
771 - return;
772 - }
773 -
774 - acym_arrayToInteger($listIds);
775 -
776 - acym_query(
777 - 'DELETE FROM #__acym_user_has_list
778 - WHERE user_id IN ('.implode(',', $userIds).')
779 - AND list_id IN ('.implode(',', $listIds).')'
780 - );
781 - }
782 -
783 - public function onlyManageableUsers(array &$elements): void
784 - {
785 - if (acym_isAdmin()) {
786 - return;
787 - }
788 -
789 - $listClass = new ListClass();
790 - $manageableLists = $listClass->getManageableLists();
791 - if (empty($manageableLists)) {
792 - return;
793 - }
794 -
795 - $currentUserId = acym_currentUserId();
796 - acym_arrayToInteger($elements);
797 -
798 - $selfManagement = in_array($currentUserId, $elements);
799 -
800 - $elements = acym_loadResultArray(
801 - 'SELECT DISTINCT user_id
802 - FROM #__acym_user_has_list
803 - WHERE `list_id` IN ('.implode(',', $manageableLists).')
804 - AND `user_id` IN ('.implode(',', $elements).')'
805 - );
806 -
807 - if ($selfManagement && !in_array($currentUserId, $elements)) {
808 - $elements[] = $currentUserId;
809 - }
810 - }
811 -
812 - public function delete(array $elements, bool $forceDelete = false): int
813 - {
814 - acym_arrayToInteger($elements);
815 - $this->onlyManageableUsers($elements);
816 -
817 - if (empty($elements)) {
818 - return 0;
819 - }
820 -
821 - if (acym_isAdmin() || $forceDelete || 'delete' === $this->config->get('frontend_delete_button', 'delete')) {
822 - acym_query('DELETE FROM #__acym_user_has_list WHERE user_id IN ('.implode(',', $elements).')');
823 - acym_query('DELETE FROM #__acym_queue WHERE user_id IN ('.implode(',', $elements).')');
824 - acym_query('DELETE FROM #__acym_user_has_field WHERE user_id IN ('.implode(',', $elements).')');
825 - acym_query('DELETE FROM #__acym_history WHERE user_id IN ('.implode(',', $elements).')');
826 - acym_query('DELETE FROM #__acym_user_stat WHERE user_id IN ('.implode(',', $elements).')');
827 -
828 - $scenarioProcessIds = acym_loadResultArray('SELECT id FROM #__acym_scenario_process WHERE user_id IN ('.implode(',', $elements).')');
829 -
830 - if (!empty($scenarioProcessIds)) {
831 - acym_query('DELETE FROM #__acym_scenario_history_line WHERE scenario_process_id IN ('.implode(',', $scenarioProcessIds).')');
832 - acym_query('DELETE FROM #__acym_scenario_queue WHERE scenario_process_id IN ('.implode(',', $scenarioProcessIds).')');
833 - acym_query('DELETE FROM #__acym_scenario_process WHERE id IN ('.implode(',', $scenarioProcessIds).')');
834 - }
835 -
836 - $uploadFolder = trim(acym_cleanPath(html_entity_decode(acym_getFilesFolder(true))), DS.' ').DS;
837 - foreach ($elements as $userId) {
838 - $folderPath = acym_cleanPath(ACYM_ROOT.$uploadFolder.'userfiles'.DS.$userId.DS);
839 - if (is_dir($folderPath)) {
840 - acym_deleteFolder($folderPath);
841 - }
842 - }
843 -
844 - return parent::delete($elements);
845 - } else {
846 - $listClass = new ListClass();
847 - $manageableLists = $listClass->getManageableLists();
848 -
849 - if (!empty($manageableLists)) {
850 - $this->removeSubscription($elements, $manageableLists);
851 - acym_query(
852 - 'DELETE queue
853 - FROM #__acym_queue AS queue
854 - JOIN #__acym_mail_has_list AS maillist
855 - ON queue.mail_id = maillist.mail_id
856 - WHERE queue.user_id IN ('.implode(',', $elements).')
857 - AND maillist.list_id IN ('.implode(',', $manageableLists).')'
858 - );
859 - }
860 -
861 - return count($elements);
862 - }
863 - }
864 -
865 - public function save(object $user, array $customFields = [], bool $ajax = false): ?int
866 - {
867 - if (empty($user->email) && empty($user->id)) {
868 - return null;
869 - }
870 -
871 - if (isset($user->email)) {
872 - $user->email = strtolower($user->email);
873 - if (!acym_isValidEmail($user->email)) {
874 - $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
875 -
876 - return null;
877 - }
878 - }
879 -
880 - if (empty($user->id)) {
881 - if (!isset($user->active)) {
882 - $user->active = 1;
883 - }
884 -
885 - if (empty($user->language)) {
886 - if (!acym_isAdmin()) {
887 - $cmsUserLanguage = acym_getCmsUserLanguage();
888 - }
889 -
890 - if (!empty($cmsUserLanguage)) {
891 - $user->language = $cmsUserLanguage;
892 - } elseif (acym_isMultilingual()) {
893 - $configUserLanguage = $this->config->get('multilingual_user_default', 'current_language');
894 - $user->language = $configUserLanguage === 'current_language' ? acym_getLanguageTag() : $configUserLanguage;
895 - }
896 - }
897 -
898 - $currentUserid = acym_currentUserId();
899 - $currentEmail = acym_currentUserEmail();
900 - $allowVisitors = $this->config->get('allow_visitor', 1) == 1;
901 - if ($this->checkVisitor && !acym_isAdmin() && !$allowVisitors && (empty($currentUserid) || strtolower($currentEmail) !== $user->email)) {
902 - $this->errors[] = acym_translation('ACYM_ONLY_LOGGED');
903 -
904 - return null;
905 - }
906 -
907 - if (empty($user->name) && $this->config->get('generate_name', 1)) {
908 - $user->name = ucwords(trim(str_replace(['.', '_', ')', ',', '(', '-', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0], ' ', substr($user->email, 0, strpos($user->email, '@')))));
909 - }
910 -
911 - $source = acym_getVar('string', 'acy_source', '');
912 - if (empty($user->source) && !empty($source)) {
913 - $user->source = $source;
914 - }
915 -
916 - $user->key = acym_generateKey(14);
917 -
918 - $user->creation_date = date('Y-m-d H:i:s', time() - date('Z'));
919 - } elseif (!empty($user->confirmed)) {
920 - $oldUser = $this->getOneByIdWithCustomFields($user->id);
921 - if (!empty($oldUser) && empty($oldUser['confirmed'])) {
922 - $user->confirmation_date = date('Y-m-d H:i:s', time() - date('Z'));
923 - $user->confirmation_ip = acym_getIP();
924 -
925 - if ($this->triggers) {
926 - acym_trigger('onAcymAfterUserConfirm', [&$user]);
927 - }
928 - }
929 - } else {
930 - $oldUser = $this->getOneByIdWithCustomFields($user->id);
931 - }
932 -
933 - if (!empty($user->id) && isset($user->active) && !empty($oldUser)) {
934 - $wasActive = isset($oldUser['active']) ? (int)$oldUser['active'] : 1;
935 - $isNowActive = (int)$user->active;
936 - if ($wasActive === 1 && $isNowActive === 0) {
937 - $user->deactivation_date = acym_date('now', 'Y-m-d H:i:s');
938 - } elseif ($wasActive === 0 && $isNowActive === 1) {
939 - $user->deactivation_date = null;
940 - }
941 - }
942 -
943 - foreach ($user as $oneAttribute => $value) {
944 - if (empty($value)) {
945 - continue;
946 - }
947 -
948 - $oneAttribute = trim(strtolower($oneAttribute));
949 - if (!in_array($oneAttribute, self::RESTRICTED_FIELDS)) {
950 - $user->$oneAttribute = strip_tags($value);
951 - }
952 -
953 - if (is_numeric($user->$oneAttribute)) {
954 - continue;
955 - }
956 -
957 - if (function_exists('mb_detect_encoding')) {
958 - if (mb_detect_encoding($user->$oneAttribute, 'UTF-8', true) !== 'UTF-8') {
959 - $user->$oneAttribute = acym_utf8Encode($user->$oneAttribute);
960 - }
961 - } elseif (
962 - !preg_match(
963 - '%^(?:[\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',
964 - $user->$oneAttribute
965 - )
966 - ) {
967 - $user->$oneAttribute = acym_utf8Encode($user->$oneAttribute);
968 - }
969 - }
970 -
971 - if (!empty($user->automation) && strlen($user->automation) > 20) {
972 - $user->automation = '';
973 - }
974 -
975 - if (empty($user->id)) {
976 - if (empty($user->cms_id) && !empty($user->email)) {
977 - global $acymCmsUserVars;
978 - $userCmsID = acym_loadResult(
979 - 'SELECT '.acym_secureDBColumn($acymCmsUserVars->id).' FROM '.$acymCmsUserVars->table.' WHERE '.acym_secureDBColumn(
980 - $acymCmsUserVars->email
981 - ).' = '.acym_escapeDB($user->email)
982 - );
983 -
984 - if (!empty($userCmsID)) $user->cms_id = $userCmsID;
985 - }
986 - if ($this->triggers) {
987 - $result = acym_trigger('onAcymBeforeUserCreate', [&$user]);
988 - if (in_array(false, $result)) {
989 - $acycheckerError = acym_getVar('string', 'acychecker_error');
990 - if (!empty($acycheckerError)) {
991 - if ($ajax) {
992 - $this->errors[] = $acycheckerError;
993 - } else {
994 - acym_enqueueMessage($acycheckerError, 'error');
995 - }
996 - }
997 -
998 - return null;
999 - }
1000 - }
1001 - } else {
1002 - if ($this->triggers) {
1003 - acym_trigger('onAcymBeforeUserModify', [&$user]);
1004 - }
1005 - }
1006 -
1007 - $userID = parent::save($user);
1008 -
1009 - $fieldClass = new FieldClass();
1010 - if (!empty($customFields)) {
1011 - foreach ($customFields as $key => $value) {
1012 - if (!is_string($value)) {
1013 - continue;
1014 - }
1015 -
1016 - $value = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $value);
1017 -
1018 - $field = $fieldClass->getOneById($key);
1019 - if (empty($field) || $field->type !== 'textarea') {
1020 - $value = preg_replace('/\s+/', ' ', $value);
1021 - }
1022 - $customFields[$key] = $value;
1023 - }
1024 - }
1025 - $fieldClass->store($userID, $customFields, $ajax);
1026 - if (!empty($fieldClass->errors)) {
1027 - $this->errors = array_merge($this->errors, $fieldClass->errors);
1028 - }
1029 -
1030 - $historyClass = new HistoryClass();
1031 - if (empty($user->id)) {
1032 - $user->id = $userID;
1033 - $historyClass->insert($user->id, 'created');
1034 - if ($this->triggers) {
1035 - acym_trigger('onAcymAfterUserCreate', [&$user]);
1036 - acym_triggerCmsHook('onAcymAfterUserSave', [$user, true]);
1037 - }
1038 - } else {
1039 - $historyClass->insert($user->id, 'modified');
1040 - if ($this->triggers) {
1041 - acym_trigger('onAcymAfterUserModify', [&$user, &$oldUser]);
1042 - acym_triggerCmsHook('onAcymAfterUserSave', [$user, false]);
1043 - }
1044 - }
1045 -
1046 - $this->sendConfirmation($userID);
1047 -
1048 - return $userID;
1049 - }
1050 -
1051 - public function saveForm(bool $ajax = false): bool
1052 - {
1053 - $allowUserModifications = $this->config->get('allow_modif', 'data') === 'all' || $this->allowModif;
1054 - $allowSubscriptionModifications = $this->config->get('allow_modif', 'data') !== 'none' || $this->allowModif;
1055 -
1056 - $user = new \stdClass();
1057 - $connectedUser = $this->identify(true, 'userId', 'userKey');
1058 -
1059 - $userData = acym_getVar('array', 'user', []);
1060 - if (!empty($userData)) {
1061 - foreach ($userData as $attribute => $value) {
1062 - if (!in_array($attribute, self::FORM_ALLOWED_FIELDS, true)) {
1063 - continue;
1064 - }
1065 - $user->$attribute = $value;
1066 - }
1067 - }
1068 -
1069 - if (empty($user->email)) {
1070 - if (!empty($connectedUser->email)) {
1071 - $user->email = $connectedUser->email;
1072 - }
1073 - }
1074 -
1075 - if (empty($user->email)) {
1076 - $this->errors[] = acym_translation('ACYM_VALID_EMAIL');
1077 -
1078 - return false;
1079 - }
1080 -
1081 - if (!$allowUserModifications && !empty($connectedUser)) {
1082 - if ($connectedUser->email != $user->email) {
1083 - $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
1084 -
1085 - return false;
1086 - }
1087 -
1088 - $allowUserModifications = true;
1089 - $allowSubscriptionModifications = true;
1090 - }
1091 -
1092 - if (!empty($user->email)) {
1093 - if (empty($user->id)) {
1094 - $user->id = 0;
1095 - }
1096 - $existUser = acym_loadObject('SELECT * FROM #__acym_user WHERE email = '.acym_escapeDB($user->email).' AND id != '.intval($user->id));
1097 - if (!empty($existUser->id)) {
1098 - if (!$this->allowModif && !$allowSubscriptionModifications) {
1099 - $this->errors[] = acym_translation('ACYM_ADDRESS_TAKEN');
1100 -
1101 - return false;
1102 - } else {
1103 - $user->id = $existUser->id;
1104 - }
1105 - }
1106 - }
1107 -
1108 - if (!empty($user->id) && !empty($user->email)) {
1109 - $existUser = $this->getOneById($user->id);
1110 - if (trim(strtolower($user->email)) != strtolower($existUser->email)) {
1111 - $user->confirmed = 0;
1112 - }
1113 - }
1114 -
1115 - $this->newUser = empty($user->id);
1116 - if (empty($user->id) || $allowUserModifications) {
1117 - if ($this->newUser && $this->config->get('require_confirmation', 1) == 1) {
1118 - $user->confirmed = 0;
1119 - }
1120 - $customFieldData = acym_getVar('array', 'customField', []);
1121 - $id = $this->save($user, $customFieldData, $ajax);
1122 - $allowSubscriptionModifications = true;
1123 - } else {
1124 - $id = $user->id;
1125 - if (isset($user->confirmed) && empty($user->confirmed)) {
1126 - $this->sendConfirmation($id);
1127 - }
1128 - }
1129 -
1130 - if (empty($id)) return false;
1131 -
1132 - $formData = acym_getVar('array', 'data', []);
1133 - acym_setVar('userId', $id);
1134 -
1135 - if (!acym_isAdmin()) {
1136 - $hiddenlistsString = acym_getVar('string', 'hiddenlists', '');
1137 - $hiddenlists = explode(',', $hiddenlistsString);
1138 - acym_arrayToInteger($hiddenlists);
1139 - $visibleSubscription = acym_getVar('array', 'subscription', []);
1140 - $subscribeLists = array_merge($hiddenlists, $visibleSubscription);
1141 - if (!empty($subscribeLists)) {
1142 - foreach ($subscribeLists as $oneListId) {
1143 - $formData['listsub'][$oneListId] = ['status' => 1];
1144 - }
1145 - }
1146 - }
1147 -
1148 - $fromProfile = acym_getVar('int', 'acyprofile', 0) == 1;
1149 -
1150 - if (empty($formData['listsub'])) {
1151 - if (!$fromProfile) $this->sendNotification($id, 'acy_notification_subform');
1152 -
1153 - $this->sendNotification(
1154 - $id,
1155 - $this->newUser ? 'acy_notification_create' : 'acy_notification_profile'
1156 - );
1157 -
1158 - return true;
1159 - }
1160 -
1161 - if (!$allowSubscriptionModifications) {
1162 - $this->requireId = true;
1163 - $this->errors[] = acym_translation('ACYM_NOT_ALLOWED_MODIFY_USER');
1164 -
1165 - return false;
1166 - }
1167 -
1168 - $addLists = [];
1169 - $unsubLists = [];
1170 - foreach ($formData['listsub'] as $listID => $oneList) {
1171 - if ($oneList['status'] == 1) {
1172 - $addLists[] = $listID;
1173 - } else {
1174 - $unsubLists[] = $listID;
1175 - }
1176 - }
1177 -
1178 - $this->subscribed = $this->subscribe([$id], $addLists);
1179 -
1180 - if (!$fromProfile) $this->sendNotification($id, 'acy_notification_subform');
1181 -
1182 - $this->sendNotification(
1183 - $id,
1184 - $this->newUser ? 'acy_notification_create' : 'acy_notification_profile'
1185 - );
1186 -
1187 - if (!$this->newUser) $this->unsubscribe([$id], $unsubLists);
1188 -
1189 - return true;
1190 - }
1191 -
1192 - public function sendConfirmation(int $userID): void
1193 - {
1194 - if (!$this->forceConf && !$this->sendConf) {
1195 - return;
1196 - }
1197 -
1198 - if ($this->config->get('require_confirmation', 1) != 1 || (acym_isAdmin() && !$this->forceConfAdmin)) {
1199 - return;
1200 - }
1201 -
1202 - $myUser = $this->getOneById($userID);
1203 -
1204 - if (!empty($myUser->confirmed)) {
1205 - return;
1206 - }
1207 -
1208 - $mailerHelper = new MailerHelper();
1209 - $mailerHelper->report = (bool)$this->config->get('confirm_message', 0);
1210 -
1211 - $mailClass = new MailClass();
1212 - $confirmationEmail = $mailClass->getOneByName('acy_confirm');
1213 - $this->confirmationSentSuccess = !empty($confirmationEmail) && $mailerHelper->sendOne($confirmationEmail->id, $myUser->id);
1214 - $this->confirmationSentError = $mailerHelper->reportMessage;
1215 - }
1216 -
1217 - public function setInactive(array $elements): void
1218 - {
1219 - $this->deactivate($elements);
1220 - }
1221 -
1222 - public function deactivate(array $userIds): void
1223 - {
1224 - $userIds = array_map('intval', $userIds);
1225 - $userIds = array_filter($userIds);
1226 -
1227 - if (empty($userIds)) return;
1228 -
1229 - acym_query('UPDATE `#__acym_user` SET `active` = 0, `deactivation_date` = UTC_TIMESTAMP() WHERE `id` IN ('.implode(',', $userIds).')');
1230 - }
1231 -
1232 - public function setActive(array $elements): void
1233 - {
1234 - $this->reactivate($elements);
1235 - }
1236 -
1237 - public function reactivate(array $userIds): void
1238 - {
1239 - $userIds = array_map('intval', $userIds);
1240 - $userIds = array_filter($userIds);
1241 -
1242 - if (empty($userIds)) return;
1243 -
1244 - acym_query('UPDATE `#__acym_user` SET `active` = 1, `deactivation_date` = NULL WHERE `id` IN ('.implode(',', $userIds).')');
1245 - }
1246 -
1247 - public function confirm(int $userId): void
1248 - {
1249 - $user = $this->getOneById($userId);
1250 - if (empty($user)) return;
1251 -
1252 - $confirmDate = date('Y-m-d H:i:s', time() - date('Z'));
1253 - $ip = acym_getIP();
1254 - $query = 'UPDATE `#__acym_user`';
1255 - $query .= ' SET `confirmed` = 1, `confirmation_date` = '.acym_escapeDB($confirmDate).', `confirmation_ip` = '.acym_escapeDB($ip);
1256 - $query .= ' WHERE `id` = '.intval($userId).' LIMIT 1';
1257 -
1258 - try {
1259 - $res = acym_query($query);
1260 - } catch (\Exception $e) {
1261 - $res = false;
1262 - }
1263 - if ($res === false) {
1264 - $errorMessage = isset($e) ? $e->getMessage() : acym_getDBError();
1265 - $msg = acym_translation('ACYM_CONTACT_ADMIN_ERROR').'<br />'.substr(strip_tags($errorMessage), 0, 200).'...';
1266 - acym_display($msg, 'error');
1267 - exit;
1268 - }
1269 -
1270 - acym_trigger('onAcymAfterUserConfirm', [&$user]);
1271 - $this->sendNotification($userId, 'acy_notification_confirm');
1272 -
1273 - $historyClass = new HistoryClass();
1274 - $historyClass->insert($userId, 'confirmed');
1275 -
1276 - if (empty($this->config->get('require_confirmation', 1))) return;
1277 -
1278 - $listIDs = acym_loadResultArray('SELECT `list_id` FROM `#__acym_user_has_list` WHERE `status` = 1 AND `user_id` = '.intval($userId));
1279 -
1280 - if (empty($listIDs)) return;
1281 -
1282 - $listClass = new ListClass();
1283 - $listClass->sendWelcome($userId, $listIDs);
1284 - }
1285 -
1286 - public function getOneByIdWithCustomFields(int $id): array
1287 - {
1288 - $user = $this->getOneById($id);
1289 - if (empty($user)) {
1290 - return [];
1291 - }
1292 -
1293 - $user = get_object_vars($user);
1294 -
1295 - $fieldsValue = acym_loadObjectList(
1296 - 'SELECT user_field.`value`, field.`name`
1297 - FROM #__acym_user_has_field AS `user_field`
1298 - LEFT JOIN #__acym_field AS `field` ON user_field.`field_id` = field.`id`
1299 - WHERE user_field.`user_id` = '.intval($id),
1300 - 'name'
1301 - );
1302 -
1303 - foreach ($fieldsValue as $key => $value) {
1304 - $fieldsValue[$key] = $value->value;
1305 - }
1306 -
1307 - return array_merge($user, $fieldsValue);
1308 - }
1309 -
1310 - public function getCustomFieldValueById(int $id): array
1311 - {
1312 - $fieldsValue = acym_loadObjectList(
1313 - 'SELECT user_field.value AS value, field.name AS name, field.type AS type, field.value AS field_params, field.id AS id
1314 - FROM #__acym_user_has_field as user_field
1315 - LEFT JOIN #__acym_field as field ON user_field.field_id = field.id
1316 - WHERE user_field.user_id = '.intval($id),
1317 - 'id'
1318 - );
1319 -
1320 - $fieldReturn = [];
1321 -
1322 - foreach ($fieldsValue as $fieldId => $field) {
1323 - if (in_array($field->type, ['checkbox', 'radio', 'single_dropdown', 'multiple_dropdown'])) {
1324 - $field->field_params = json_decode($field->field_params, true);
1325 - $field->value = explode(',', $field->value);
1326 - $values = [];
1327 - foreach ($field->value as $oneValue) {
1328 - $key = array_search($oneValue, array_column($field->field_params, 'value'));
1329 - $values[] = $field->field_params[$key]['title'];
1330 - }
1331 - $fieldReturn[$field->name] = implode(',', $values);
1332 - } else {
1333 - $fieldReturn[$field->name] = $field->value;
1334 - }
1335 - }
1336 -
1337 - return $fieldReturn;
1338 - }
1339 -
1340 - public function getAllColumnsUserAndCustomField(bool $inAction = false, bool $withSubInfos = false): array
1341 - {
1342 - $return = [];
1343 -
1344 - $userFields = acym_getColumns('user');
1345 - foreach ($userFields as $value) {
1346 - $return[$value] = $value;
1347 - }
1348 -
1349 - $languageFieldId = $this->config->get(FieldClass::LANGUAGE_FIELD_ID_KEY, 0);
1350 -
1351 - $customFields = acym_loadObjectList(
1352 - 'SELECT * FROM #__acym_field WHERE id NOT IN (1, 2, '.intval($languageFieldId).') '.($inAction ? 'AND type != "phone"' : ''),
1353 - 'id'
1354 - );
1355 - if (!empty($customFields)) {
1356 - foreach ($customFields as $key => $value) {
1357 - $return[$key] = $value->name;
1358 - }
1359 - }
1360 -
1361 - if ($withSubInfos) {
1362 - $listCLass = new ListClass();
1363 - $listFields = $listCLass->getAll('name');
1364 - if (!empty($listFields)) {
1365 - foreach ($listFields as $key => $value) {
1366 - if ($value->type === ListClass::LIST_TYPE_FOLLOWUP) {
1367 - continue;
1368 - }
1369 - $return['subscription_date_'.$value->id] = acym_translation('ACYM_SUBSCRIPTION_DATE').' '.$value->name;
1370 - $return['unsubscription_date_'.$value->id] = acym_translation('ACYM_UNSUBSCRIPTION_DATE').' '.$value->name;
1371 - }
1372 - }
1373 - }
1374 -
1375 - return $return;
1376 - }
1377 -
1378 - public function getAllUserFields(object $user): object
1379 - {
1380 - if (empty($user->id)) {
1381 - return $user;
1382 - }
1383 -
1384 - $query = 'SELECT field.*, field.value AS field_value, userfield.*
1385 - FROM #__acym_field AS field
1386 - LEFT JOIN #__acym_user_has_field AS userfield ON field.id = userfield.field_id AND userfield.user_id = '.intval($user->id).'
1387 - WHERE field.id NOT IN(1, 2)';
1388 -
1389 - $allFields = acym_loadObjectList($query);
1390 -
1391 - foreach ($allFields as $oneField) {
1392 - $fieldOptions = @json_decode(empty($oneField->option) ? '{}' : $oneField->option);
1393 - if (in_array($oneField->type, ['multiple_dropdown', 'radio', 'checkbox', 'single_dropdown'])) {
1394 - $oneField->field_value = json_decode($oneField->field_value, true);
1395 - if (!empty($oneField->value)) {
1396 - $oneField->value = explode(',', $oneField->value);
1397 - $values = [];
1398 - foreach ($oneField->field_value as $oneFieldValue) {
1399 - foreach ($oneField->value as $oneValue) {
1400 - if ($oneFieldValue['value'] == $oneValue) {
1401 - $values[] = $oneFieldValue['title'];
1402 - }
1403 - }
1404 - }
1405 - $oneField->value = implode(',', $values);
1406 - }
1407 - } elseif ($oneField->type === 'file' && !empty($oneField->value)) {
1408 - $tryJsonDecode = json_decode($oneField->value);
1409 - if (json_last_error() === JSON_ERROR_NONE && is_array($tryJsonDecode)) {
1410 - $oneField->value = !empty($tryJsonDecode) ? $tryJsonDecode[0] : null;
1411 - }
1412 - } elseif ($oneField->type === 'date') {
1413 - if (empty($fieldOptions->format)) {
1414 - acym_logError('Date field with ID '.$oneField->id.' without format option');
1415 - continue;
1416 - }
1417 - $formatToDisplay = explode('%', str_replace('y', 'Y', $fieldOptions->format));
1418 - unset($formatToDisplay[0]);
1419 - if (!empty($oneField->value)) {
1420 - $oneField->value = acym_date($oneField->value, implode('-', $formatToDisplay));
1421 - }
1422 - }
1423 - $user->{$oneField->namekey} = empty($oneField->value) ? '' : $oneField->value;
1424 - }
1425 -
1426 - return $user;
1427 - }
1428 -
1429 - public function getAllSimpleData(): array
1430 - {
1431 - return acym_loadObjectList('SELECT email, name FROM #__acym_user');
1432 - }
1433 -
1434 - public function synchSaveCmsUser(array $user, bool $isnew, ?array $oldUser = null): void
1435 - {
1436 - $source = acym_getVar('string', 'acy_source', '');
1437 - if (empty($source)) acym_setVar('acy_source', ACYM_CMS);
1438 -
1439 - if (!$this->config->get('regacy', 0)) return;
1440 -
1441 - $this->checkVisitor = false;
1442 - $this->sendConf = false;
1443 -
1444 - $regacyForceConf = $this->config->get('regacy_forceconf', 0);
1445 - $cmsUser = new \stdClass();
1446 - $cmsUser->email = trim(strip_tags($user['email']));
1447 - if (!acym_isValidEmail($cmsUser->email)) return;
1448 - if (!empty($user['name'])) $cmsUser->name = trim(strip_tags($user['name']));
1449 - if (!$regacyForceConf) $cmsUser->confirmed = 1;
1450 - $cmsUser->active = 1 - intval($user['block']);
1451 - $cmsUser->cms_id = $user['id'];
1452 -
1453 - if (!$isnew && !empty($oldUser['email']) && $user['email'] != $oldUser['email']) {
1454 - $acyUser = $this->getOneByEmail($oldUser['email']);
1455 - if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
1456 - }
1457 -
1458 - if (empty($cmsUser->id) && !empty($cmsUser->cms_id)) {
1459 - $acyUser = $this->getOneByCMSId($cmsUser->cms_id);
1460 - if (!empty($acyUser)) $cmsUser->id = $acyUser->id;
1461 - }
1462 -
1463 - $acyUser = $this->getOneByEmail($cmsUser->email);
1464 - if (!empty($acyUser)) {
1465 - if (empty($cmsUser->id)) {
1466 - $cmsUser->id = $acyUser->id;
1467 - } elseif ($cmsUser->id != $acyUser->id) {
1468 - $this->delete([$acyUser->id]);
1469 - }
1470 - } else {
1471 - $cmsUser->source = $source;
1472 - }
1473 -
1474 - $isnew = $isnew || empty($cmsUser->id);
1475 -
1476 - $id = $this->save($cmsUser);
1477 - if (empty($id)) {
1478 - return;
1479 - }
1480 -
1481 - $confirmationRequired = $this->config->get('require_confirmation', 1);
1482 - if (!$isnew && !$regacyForceConf && $user['block'] == 0 && !empty($oldUser['block']) && $confirmationRequired == 1) {
1483 - $this->confirm($id);
1484 - }
1485 -
1486 -
1487 - $currentSubscription = $this->getSubscriptionStatus($id);
1488 -
1489 - $autoLists = $isnew ? $this->config->get('regacy_autolists', '') : '';
1490 - $autoLists = explode(',', $autoLists);
1491 - acym_arrayToInteger($autoLists);
1492 -
1493 - $listsClass = new ListClass();
1494 - $allLists = $listsClass->getAll();
1495 -
1496 - $visibleLists = acym_getVar('string', 'regacy_visible_lists', '');
1497 - $visibleLists = explode(',', $visibleLists);
1498 - acym_arrayToInteger($visibleLists);
1499 -
1500 - $visibleListsChecked = acym_getVar('array', 'regacy_visible_lists_checked', []);
1501 - acym_arrayToInteger($visibleListsChecked);
1502 -
1503 -
1504 - if (!$isnew && !empty($visibleLists)) {
1505 - $currentlySubscribedLists = [];
1506 - foreach ($currentSubscription as $oneSubscription) {
1507 - if ($oneSubscription->status == 1) $currentlySubscribedLists[] = $oneSubscription->list_id;
1508 - }
1509 - $unsubscribeLists = array_intersect($currentlySubscribedLists, array_diff($visibleLists, $visibleListsChecked));
1510 - $this->unsubscribe([$id], $unsubscribeLists);
1511 - }
1512 -
1513 - $listsToSubscribe = [];
1514 - foreach ($allLists as $oneList) {
1515 - if (!$oneList->active) continue;
1516 - if (!empty($currentSubscription[$oneList->id]) && $currentSubscription[$oneList->id]->status == 1) continue;
1517 -
1518 - if (
1519 - in_array($oneList->id, $visibleListsChecked)
1520 - || (
1521 - in_array($oneList->id, $autoLists)
1522 - && !in_array($oneList->id, $visibleLists) && empty($currentSubscription[$oneList->id])
1523 - )
1524 - ) {
1525 - $listsToSubscribe[] = $oneList->id;
1526 - }
1527 - }
1528 -
1529 - if (!empty($listsToSubscribe)) $this->subscribe([$id], $listsToSubscribe);
1530 -
1531 - if ($isnew) $this->sendNotification($id, 'acy_notification_create');
1532 -
1533 - $acymailingUser = $this->getOneById($id);
1534 - if (!empty($user['block']) || !empty($acymailingUser->confirmed)) return;
1535 -
1536 - if ($isnew || !empty($oldUser['block'])) {
1537 - if ($confirmationRequired && $regacyForceConf) {
1538 - $this->forceConf = true;
1539 - $this->sendConfirmation($id);
1540 - }
1541 -
1542 - if (!$confirmationRequired && !empty($oldUser['email'])) {
1543 - $listIDs = acym_loadResultArray('SELECT `list_id` FROM `#__acym_user_has_list` WHERE `status` = 1 AND `user_id` = '.intval($id));
1544 - if (empty($listIDs)) return;
1545 - $listsClass->sendWelcome($id, $listIDs);
1546 - }
1547 - }
1548 - }
1549 -
1550 - public function synchDeleteCmsUser(string $userEmail): void
1551 - {
1552 - $acyUser = $this->getOneByEmail($userEmail);
1553 -
1554 - if (empty($acyUser)) return;
1555 -
1556 - if ($this->config->get('regacy', '0') == 1 && $this->config->get('regacy_delete', '0') == 1) {
1557 - $this->delete([$acyUser->id]);
1558 - } else {
1559 - acym_query('UPDATE #__acym_user SET `cms_id` = 0 WHERE `id` = '.intval($acyUser->id));
1560 - }
1561 - }
1562 -
1563 - public function getUsersLikeEmail(string $search): array
1564 - {
1565 - $query = 'SELECT id, email FROM #__acym_user WHERE email LIKE '.acym_escapeDB('%'.$search.'%');
1566 -
1567 - return acym_loadObjectList($query);
1568 - }
1569 -
1570 - public function sendNotification(int $userId, string $notification, array $params = []): void
1571 - {
1572 - if (empty($userId) || $this->blockNotifications) return;
1573 -
1574 - $notifyUsers = explode(',', $this->config->get($notification));
1575 - if (acym_isAdmin() || empty($notifyUsers)) return;
1576 -
1577 - $mailerHelper = new MailerHelper();
1578 - $mailerHelper->report = false;
1579 - $mailerHelper->autoAddUser = true;
1580 -
1581 - $user = $this->getOneById($userId);
1582 - $userField = empty($user) ? null : $this->getAllUserFields($user);
1583 - if (!empty($userField)) {
1584 - foreach ($userField as $map => $value) {
1585 - $mailerHelper->addParam('user:'.$map, $value);
1586 - }
1587 - }
1588 -
1589 - $rawSubscription = $this->getUserSubscriptionById($userId);
1590 - $subscription = [''];
1591 - foreach ($rawSubscription as $listId => $listData) {
1592 - $currentList = $listData->name.' => ';
1593 - if (intval($listData->status) === 1) {
1594 - $currentList .= acym_translation('ACYM_SUBSCRIBED').' - '.$listData->subscription_date;
1595 - } else {
1596 - $currentList .= acym_translation('ACYM_UNSUBSCRIBED').' - '.$listData->unsubscribe_date;
1597 - }
1598 - $subscription[] = $currentList;
1599 - }
1600 - $mailerHelper->addParam('user:subscription', implode('<br/>', $subscription));
1601 -
1602 - if (!empty($params)) {
1603 - foreach ($params as $name => $value) {
1604 - $mailerHelper->addParam($name, $value);
1605 - }
1606 - }
1607 -
1608 - $mailClass = new MailClass();
1609 - foreach ($notifyUsers as $oneUser) {
1610 - if (!acym_isValidEmail($oneUser)) {
1611 - continue;
1612 - }
1613 -
1614 - $admin = $this->getOneByEmail($oneUser, true);
1615 -
1616 - $notificationEmail = $mailClass->getOneByName($notification);
1617 - if (!empty($admin) && !empty($notificationEmail)) {
1618 - try {
1619 - $mailerHelper->sendOne($notificationEmail->id, $admin->id);
1620 - } catch (\Exception $e) {
1621 - acym_logError($e->getMessage());
1622 - }
1623 - }
1624 - }
1625 - }
1626 -
1627 - public function getMailHistory(int $userId)
1628 - {
1629 - $mailHistory = acym_loadObjectList(
1630 - 'SELECT user_stat.*, mail.id, mail.subject, SUM(url_click.click) as click
1631 - FROM #__acym_user_stat AS user_stat
1632 - JOIN #__acym_mail AS mail ON mail.id = user_stat.mail_id
1633 - LEFT JOIN #__acym_url_click AS url_click ON user_stat.mail_id = url_click.mail_id AND url_click.user_id = '.intval($userId).'
1634 - WHERE user_stat.user_id = '.intval($userId).'
1635 - GROUP BY mail_id
1636 - ORDER BY send_date DESC
1637 - LIMIT 50',
1638 - 'mail_id'
1639 - );
1640 - $mailClass = new MailClass();
1641 -
1642 - return $mailClass->decode($mailHistory);
1643 - }
1644 -
1645 - public function deleteHistoryPeriod(): array
1646 - {
1647 - if (empty($this->config->get('delete_user_history_enabled', 0))) return [];
1648 - $deleteOverSecond = $this->config->get('delete_user_history', 0);
1649 - if (empty($deleteOverSecond)) return [];
1650 - $date = time() - $deleteOverSecond;
1651 -
1652 - $query = 'DELETE FROM #__acym_history WHERE date < '.intval($date);
1653 -
1654 - try {
1655 - $status = acym_query($query);
1656 - $message = empty($status) ? '' : acym_translationSprintf('ACYM_DELETE_X_ROWS_TABLE_X', $status, strtolower(acym_translation('ACYM_USER_HISTORY')));
1657 - } catch (\Exception $e) {
1658 - $status = false;
1659 - $message = $e->getMessage();
1660 - }
1661 -
1662 - return ['status' => $status !== false, 'message' => $message];
1663 - }
1664 -
1665 - public function resetSubscription(array $userIds, array $lists): bool
1666 - {
1667 - if (empty($lists)) return false;
1668 -
1669 - acym_arrayToInteger($userIds);
1670 - acym_arrayToInteger($lists);
1671 -
1672 - foreach ($userIds as $userId) {
1673 - acym_query(
1674 - 'DELETE FROM `#__acym_user_has_list`
1675 - WHERE user_id = '.$userId.'
1676 - AND list_id IN ('.implode(',', $lists).')'
1677 - );
1678 -
1679 - acym_query(
1680 - 'DELETE FROM #__acym_queue WHERE user_id = '.$userId.' AND mail_id IN (
1681 - SELECT followup_mail.mail_id FROM #__acym_followup_has_mail AS followup_mail
1682 - JOIN #__acym_followup AS followup ON followup.id = followup_mail.followup_id AND followup.list_id IN ('.implode(',', $lists).')
1683 - )'
1684 - );
1685 -
1686 - $historyClass = new HistoryClass();
1687 - $historyData = acym_translationSprintf('ACYM_LISTS_NUMBERS', implode(', ', $lists));
1688 - $historyClass->insert($userId, 'reset_subscription', [$historyData]);
1689 - }
1690 -
1691 - return true;
1692 - }
1693 -
1694 - public function addMissingKeys(): int
1695 - {
1696 - $usersMissingKey = acym_loadResultArray('SELECT `id` FROM #__acym_user WHERE `key` IS NULL OR `key` = ""');
1697 - foreach ($usersMissingKey as $oneUserId) {
1698 - acym_query('UPDATE #__acym_user SET `key` = '.acym_escapeDB(acym_generateKey(14)).' WHERE `id` = '.intval($oneUserId));
1699 - }
1700 -
1701 - return count($usersMissingKey);
1702 - }
1703 -
1704 - public function hasUserAccess(int $subscriberId): bool
1705 - {
1706 - $userId = acym_currentUserId();
1707 - if (empty($userId)) {
1708 - return false;
1709 - }
1710 -
1711 - if (acym_isAdmin()) {
1712 - return true;
1713 - }
1714 -
1715 - $user = $this->getOneById($subscriberId);
1716 - $userEmail = acym_currentUserEmail();
1717 - if (!empty($user) && $user->email === $userEmail) {
1718 - return true;
1719 - }
1720 -
1721 - $listClass = new ListClass();
1722 - $allowedListIds = $listClass->getManageableLists();
1723 - if (empty($allowedListIds)) {
1724 - return false;
1725 - }
1726 -
1727 - $query = 'SELECT COUNT(*) FROM #__acym_user AS user
1728 - JOIN #__acym_user_has_list AS map ON map.user_id = user.id
1729 - WHERE map.list_id IN ('.implode(',', $allowedListIds).')
1730 - AND user.id = '.intval($subscriberId);
1731 -
1732 - return acym_loadResult($query) > 0;
1733 - }
1734 -
1735 - public function getXUsers(array $options = []): array
1736 - {
1737 - $limit = $options['limit'] ?? 10;
1738 - $offset = $options['offset'] ?? 0;
1739 - $filters = $options['filters'] ?? [];
1740 -
1741 - $conditions = [];
1742 - foreach ($filters as $column => $filter) {
1743 - if (in_array($column, ['id', 'cms_id', 'active', 'confirmed', 'tracking'])) {
1744 - $conditions[] = acym_secureDBColumn($column).' = '.intval($filter);
1745 - } else {
1746 - $conditions[] = acym_secureDBColumn($column).' LIKE '.acym_escapeDB('%'.$filter.'%');
1747 - }
1748 - }
1749 -
1750 - if (!empty($options['created_after'])) {
1751 - $conditions[] = 'creation_date > '.acym_escapeDB($options['created_after']);
1752 - }
1753 -
1754 - if (!empty($options['confirmed_after'])) {
1755 - $conditions[] = 'confirmation_date > '.acym_escapeDB($options['confirmed_after']);
1756 - }
1757 -
1758 - $query = 'SELECT * FROM #__acym_user';
1759 - if (!empty($conditions)) {
1760 - $query .= ' WHERE '.implode(' AND ', $conditions);
1761 - }
1762 -
1763 - return acym_loadObjectList($query, $this->pkey, $offset, $limit);
1764 - }
1765 -}