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 | front/FrontControllers/FrontusersController.php +0 -1106 11.0.4 → 11.1.1 View file →
@@ -1,1106 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\FrontControllers;
4 -
5 -use AcyMailing\Classes\FieldClass;
6 -use AcyMailing\Classes\ListClass;
7 -use AcyMailing\Classes\MailClass;
8 -use AcyMailing\Classes\ScenarioClass;
9 -use AcyMailing\Classes\UserClass;
10 -use AcyMailing\Classes\UserStatClass;
11 -use AcyMailing\Controllers\UsersController;
12 -use AcyMailing\Helpers\CaptchaHelper;
13 -use AcyMailing\Helpers\EntitySelectHelper;
14 -use AcyMailing\Helpers\ExportHelper;
15 -use AcyMailing\Helpers\ToolbarHelper;
16 -use AcyMailing\Helpers\UserHelper;
17 -use AcyMailing\Core\AcymParameter;
18 -
19 -class FrontusersController extends UsersController
20 -{
21 - public function __construct()
22 - {
23 - parent::__construct();
24 -
25 - if (ACYM_CMS === 'joomla') {
26 - $menu = acym_getMenu();
27 - if (is_object($menu)) {
28 - $params = method_exists($menu, 'getParams') ? $menu->getParams() : $menu->params;
29 - $menuParams = new AcymParameter($params);
30 - $this->menuClass = $menuParams->get('pageclass_sfx', '');
31 - }
32 - }
33 -
34 - $this->publicFrontTasks = [
35 - 'subscribe',
36 - 'unsubscribe',
37 - 'unsubscribeAll',
38 - 'disableTracking',
39 - 'saveSubscriptions',
40 - 'unsubscribePage',
41 - 'confirm',
42 - 'profile',
43 - 'savechanges',
44 - 'exportdata',
45 - 'ajaxGetEnqueuedMessages',
46 - 'gdprDelete',
47 - ];
48 -
49 - }
50 -
51 -
52 - private function displayMessage(string $message, bool $ajax, string $type = 'error'): void
53 - {
54 - if ($ajax) {
55 - echo json_encode(
56 - [
57 - 'message' => acym_translation($message),
58 - 'type' => $type,
59 - 'code' => '1',
60 - ]
61 - );
62 - } else {
63 - acym_header('Content-type:text/html; charset=utf-8');
64 - echo '<script>alert("'.esc_html(acym_translation($message)).'"); window.history.go(-1);</script>';
65 - }
66 - exit;
67 - }
68 -
69 - public function subscribe(): void
70 - {
71 - acym_checkRobots();
72 -
73 - $formData = acym_getVar('array', 'user', []);
74 - if (!acym_getVar('string', 'acy_source') && !empty($formData)) {
75 - // Coming from a subscription via url...
76 - acym_setVar('acy_source', 'url');
77 - }
78 -
79 - // Do we have to return an ajax response or a web page ?
80 - $ajax = acym_getVar('int', 'ajax', 0);
81 - if ($ajax) {
82 - //in case of the page displays some warnings or whatever
83 - @ob_end_clean();
84 - acym_header('Content-type:application/json; charset=utf-8');
85 - }
86 -
87 - //We only allow logged in users and this user is not logged it...
88 - $currentUserid = acym_currentUserId();
89 - if ((int)$this->config->get('allow_visitor', 1) != 1 && empty($currentUserid)) {
90 - if ($ajax) {
91 - echo json_encode(
92 - [
93 - 'message' => acym_translation('ACYM_ONLY_LOGGED'),
94 - 'type' => 'error',
95 - 'code' => '0',
96 - ]
97 - );
98 - exit;
99 - } else {
100 - acym_askLog(false, 'ACYM_ONLY_LOGGED');
101 -
102 - return;
103 - }
104 - }
105 -
106 - if (empty($currentUserid) && $this->config->get('captcha', 'none') !== 'none' && acym_level(ACYM_ESSENTIAL)) {
107 - $captchaHelper = new CaptchaHelper();
108 - if (!$captchaHelper->check()) {
109 - $this->displayMessage('ACYM_WRONG_CAPTCHA', $ajax);
110 - }
111 - }
112 -
113 - $user = new \stdClass();
114 - if (!empty($formData['email'])) {
115 - $user->email = $formData['email'];
116 - }
117 -
118 - $userClass = new UserClass();
119 - if (empty($user->email)) {
120 - $connectedUser = $userClass->identify(true, 'userId', 'userKey');
121 - if (!empty($connectedUser->email)) {
122 - $user->email = $connectedUser->email;
123 - }
124 - }
125 - $user->email = trim($user->email);
126 -
127 - // Check email validity
128 - if (empty($user->email) || !acym_isValidEmail($user->email, true)) {
129 - $this->displayMessage('ACYM_VALID_EMAIL', $ajax);
130 - }
131 -
132 - // E-mail is valid now...
133 - // Check if this user already exists or not...
134 - $alreadyExists = $userClass->getOneByEmail($user->email);
135 - if (!empty($alreadyExists->id)) {
136 - $user->id = $alreadyExists->id;
137 - }
138 -
139 - $successfullySaved = $userClass->saveForm($ajax);
140 - $user->id = acym_getVar('int', 'userId');
141 -
142 - if (!empty($userClass->errors)) {
143 - $this->displayMessage(implode('<br /><br />', $userClass->errors), $ajax);
144 - }
145 -
146 - if (!$successfullySaved || empty($user->id)) {
147 - $this->displayMessage('ACYM_ERROR_SAVE_USER', $ajax);
148 - }
149 -
150 - //We will now load back the user from the one we saved so that we will have all its infos
151 - $myuser = $userClass->getOneById($user->id);
152 - if (empty($myuser->id)) {
153 - $this->displayMessage('ACYM_ERROR_SAVE_USER', $ajax);
154 - }
155 -
156 - $msgtype = 'success';
157 - if (empty($myuser->confirmed) && $this->config->get('require_confirmation', 1) == 1) {
158 - if ($userClass->confirmationSentSuccess || empty($userClass->confirmationSentError)) {
159 - $msg = acym_stripTags(acym_getVar('string', 'confirmation_message', ''));
160 - if (empty($msg)) {
161 - $msg = 'ACYM_CONFIRMATION_SENT';
162 - }
163 - $code = 2;
164 - } else {
165 - $msg = $userClass->confirmationSentError;
166 - $code = 7;
167 - $msgtype = 'error';
168 - }
169 - } else {
170 - if ($userClass->subscribed) {
171 - $msg = acym_stripTags(acym_getVar('string', 'confirmation_message', ''));
172 - if (empty($msg)) {
173 - $msg = 'ACYM_SUBSCRIPTION_OK';
174 - }
175 - $code = 3;
176 - } else {
177 - $msg = 'ACYM_ALREADY_SUBSCRIBED';
178 - $code = 5;
179 - $enqueueMsgType = 'info';
180 - }
181 - }
182 -
183 - // Replace tags inside the $msg and redirect link
184 - $replace = [];
185 - foreach ($myuser as $oneProp => $oneVal) {
186 - $replace['{user:'.$oneProp.'}'] = $oneVal;
187 - }
188 -
189 - $msg = str_replace(array_keys($replace), $replace, acym_translation($msg));
190 -
191 - if ($ajax) {
192 - //Make sure the message has a valid format for Ajax... so the user can customize it the way he wants without breaking anything
193 - $msg = str_replace(["\n", "\r", '"', '\\'], [' ', ' ', "'", '\\\\'], $msg);
194 - echo json_encode(
195 - [
196 - 'message' => $msg,
197 - 'type' => $msgtype,
198 - 'code' => $code,
199 - ]
200 - );
201 - exit;
202 - } else {
203 - acym_enqueueMessage($msg, !empty($enqueueMsgType) ? $enqueueMsgType : $msgtype);
204 - }
205 -
206 - $redirectUrl = urldecode(acym_getVar('string', 'redirect', ''));
207 - $redirectUrl = str_replace(array_keys($replace), $replace, $redirectUrl);
208 - if (empty($redirectUrl)) {
209 - $redirectUrl = acym_rootURI();
210 - }
211 -
212 - acym_redirect($redirectUrl, '', 'message', true);
213 - }
214 -
215 - private function unsubscribeDirectly(object $alreadyExists, bool $ajax): void
216 - {
217 - $userClass = new UserClass();
218 - if ($this->config->get('allow_modif', 'data') === 'none') {
219 - $currentUser = $userClass->identify(true, 'userId', 'userKey');
220 - if (empty($currentUser->email)) {
221 - $this->endUnsubscribe('ACYM_LOGIN', $ajax, 'error');
222 -
223 - return;
224 - }
225 - }
226 -
227 - if (empty($currentUser) || empty($currentUser->id)) {
228 - $currentUser = $alreadyExists;
229 - }
230 -
231 - $visibleSubscription = acym_getVar('array', 'subscription', []);
232 - $hiddenLists = trim(acym_getVar('string', 'hiddenlists', ''));
233 - $hiddenSubscription = empty($hiddenLists) ? [] : explode(',', $hiddenLists);
234 - $unsubscribeLists = array_merge($visibleSubscription, $hiddenSubscription);
235 - acym_arrayToInteger($unsubscribeLists);
236 -
237 - $mailId = acym_getVar('int', 'mail_id', 0);
238 -
239 - // Protect against bots
240 - if (!empty($mailId) && !empty($currentUser->id)) {
241 - $userStatClass = new UserStatClass();
242 - $userStat = $userStatClass->getOneByMailAndUserId($mailId, $currentUser->id);
243 - $delay = $this->config->get('tracking_delay', 0);
244 - if (acym_isRobot() || (!empty($userStat) && !empty($delay) && acym_getTimeFromUTCDate($userStat->send_date) > time() - $delay)) {
245 - return;
246 - }
247 - }
248 -
249 - if (empty($unsubscribeLists)) {
250 - $mailClass = new MailClass();
251 - $mailType = $mailClass->getMailType($mailId);
252 - if (empty($currentUser) || empty($currentUser->id)) {
253 - $currentUser = $userClass->identify(true, 'userId', 'userKey');
254 - }
255 -
256 - if ($mailType === $mailClass::TYPE_SCENARIO) {
257 - $scenarioClass = new ScenarioClass();
258 - $scenarioId = $scenarioClass->getScenarioIdByMailId($mailId);
259 - if (!empty($currentUser->id)) {
260 - $scenarioClass->markUserUnsubscribeFromScenario($currentUser->id, $scenarioId);
261 - }
262 - }
263 - }
264 -
265 - if (!empty($mailId)) {
266 - $mailClass = new MailClass();
267 - $unsubscribeLists = array_keys($mailClass->getAllListsByMailId($mailId));
268 - }
269 -
270 - if (empty($unsubscribeLists)) {
271 - $msg = 'ACYM_NO_SUBSCRIPTION_LINKED_EMAIL';
272 - } elseif (false === $userClass->unsubscribe([$alreadyExists->id], $unsubscribeLists)) {
273 - $msg = 'ACYM_UNSUBSCRIPTION_NOT_IN_LIST';
274 - } else {
275 - $msg = 'ACYM_UNSUBSCRIPTION_OK';
276 - }
277 -
278 - if (!empty($mailType) && $mailType === $mailClass::TYPE_SCENARIO) {
279 - $msg = 'ACYM_UNSUBSCRIPTION_SCENARIO_OK';
280 - }
281 -
282 -
283 - $this->endUnsubscribe($msg, $ajax);
284 - }
285 -
286 - private function endUnsubscribe(string $msg, bool $ajax, string $type = 'success'): void
287 - {
288 - $msg = acym_translation($msg);
289 -
290 - if ($ajax) {
291 - echo json_encode(
292 - [
293 - 'message' => $msg,
294 - 'type' => $type,
295 - 'code' => '10',
296 - ]
297 - );
298 - exit;
299 - }
300 - acym_enqueueMessage($msg, $type);
301 -
302 - $redirectUrl = urldecode(acym_getVar('string', 'redirectunsub', ''));
303 - if (empty($redirectUrl)) {
304 - $redirectUrl = acym_rootURI();
305 - }
306 -
307 - acym_redirect($this->normalizeRedirectUrl($redirectUrl), '', 'message', true);
308 - }
309 -
310 - private function normalizeRedirectUrl(string $url): string
311 - {
312 - if ($url === '') {
313 - return '';
314 - }
315 - if (preg_match('~^[a-z][a-z0-9+.\-]*://~i', $url)) {
316 - return $url;
317 - }
318 - if (strpos($url, '/') === 0 || strpos($url, 'index.php') === 0) {
319 - return $url;
320 - }
321 - if (preg_match('~^[^/?#]+\.[a-z]{2,}(?:[/?#]|$)~i', $url)) {
322 - return 'https://'.$url;
323 - }
324 -
325 - return $url;
326 - }
327 -
328 - public function unsubscribe(): void
329 - {
330 - acym_checkRobots();
331 - $userClass = new UserClass();
332 -
333 - $redirectToUnsubPage = $this->config->get('unsubscribe_page', 1);
334 - $direct = acym_getVar('int', 'direct', 0);
335 -
336 - // Do we have to return an ajax response or a web page ?
337 - $ajax = acym_getVar('int', 'ajax', 0);
338 - if ($ajax) {
339 - @ob_end_clean();
340 - acym_header('Content-type:application/json; charset=utf-8');
341 - }
342 -
343 - $currentUserid = acym_currentUserId();
344 - $user = $userClass->identify(true, 'userId', 'userKey');
345 - if (empty($user)) {
346 - $user = $userClass->identify(true, 'user_id', 'user_key');
347 - $direct = 1;
348 - }
349 - if (empty($user) && empty($currentUserid) && $this->config->get('captcha', 'none') !== 'none' && acym_level(ACYM_ESSENTIAL)) {
350 - $captchaClass = new CaptchaHelper();
351 - if (!$captchaClass->check()) {
352 - $this->displayMessage('ACYM_WRONG_CAPTCHA', $ajax);
353 - }
354 - }
355 -
356 - $formData = acym_getVar('array', 'user', []);
357 - $email = '';
358 -
359 - if (!empty($formData['email'])) {
360 - $email = trim(acym_stripTags($formData['email']));
361 - } elseif (empty($user)) {
362 - return;
363 - } elseif (!empty($user->email)) {
364 - $email = $user->email;
365 - } elseif (!empty(acym_currentUserEmail())) {
366 - $email = acym_currentUserEmail();
367 - }
368 -
369 - $currentEmail = acym_currentUserEmail();
370 - if (empty($email) && !empty($currentEmail)) {
371 - $email = $currentEmail;
372 - }
373 -
374 - // Check email validity
375 - if (empty($email) || !acym_isValidEmail($email)) {
376 - $this->displayMessage('ACYM_VALID_EMAIL', $ajax);
377 - }
378 -
379 - $alreadyExists = $userClass->getOneByEmail($email);
380 -
381 - // User not found
382 - if (empty($alreadyExists->id)) {
383 - $this->displayMessage(acym_translationSprintf('ACYM_SUB_NOT_IN_LIST', $email), $ajax);
384 - }
385 -
386 - $fromModuleOrWidget = acym_getVar('string', 'acysubmode', '');
387 - if ((!empty($fromModuleOrWidget) && in_array($fromModuleOrWidget, ['form_acym', 'mod_acym', 'widget_acym'])) || $ajax || !$redirectToUnsubPage || !empty($direct)) {
388 - $this->unsubscribeDirectly($alreadyExists, $ajax);
389 - } elseif ($redirectToUnsubPage && !$ajax && !$direct) {
390 - $identifiedEmail = !empty($user->email) ? $user->email : $currentEmail;
391 - if (empty($identifiedEmail) || strtolower($alreadyExists->email) !== strtolower($identifiedEmail)) {
392 - $this->displayMessage('ACYM_NOT_ALLOWED_MODIFY_USER', $ajax);
393 - }
394 - $this->unsubscribePage($alreadyExists);
395 - }
396 - }
397 -
398 - public function disableTracking(): void
399 - {
400 - acym_checkRobots();
401 -
402 - // Do we have to return an ajax response or a web page ?
403 - $ajax = acym_getVar('int', 'ajax', 0);
404 - if ($ajax) {
405 - @ob_end_clean();
406 - acym_header('Content-type:application/json; charset=utf-8');
407 - }
408 -
409 - $userClass = new UserClass();
410 - $user = $userClass->identify(true, 'userId', 'userKey');
411 -
412 - if (empty($user->id)) {
413 - $this->displayMessage('ACYM_USER_NOT_FOUND', $ajax);
414 - }
415 -
416 - // Protect against bots opening the link right after the email was sent
417 - $mailId = acym_getVar('int', 'mail_id', 0);
418 - if (!empty($mailId)) {
419 - $userStatClass = new UserStatClass();
420 - $userStat = $userStatClass->getOneByMailAndUserId($mailId, $user->id);
421 - $delay = $this->config->get('tracking_delay', 0);
422 - if (acym_isRobot() || (!empty($userStat) && !empty($delay) && acym_getTimeFromUTCDate($userStat->send_date) > time() - $delay)) {
423 - return;
424 - }
425 - }
426 -
427 - if ((int)$user->tracking !== 0) {
428 - $userClass->disableTracking($user, $mailId);
429 - }
430 -
431 - $this->endDisableTracking('ACYM_TRACKING_DISABLED_OK', $ajax);
432 - }
433 -
434 - private function endDisableTracking(string $msg, bool $ajax, string $type = 'success'): void
435 - {
436 - $msg = acym_translation($msg);
437 -
438 - if ($ajax) {
439 - echo json_encode(
440 - [
441 - 'message' => $msg,
442 - 'type' => $type,
443 - 'code' => '10',
444 - ]
445 - );
446 - exit;
447 - }
448 - acym_enqueueMessage($msg, $type);
449 -
450 - $redirectUrl = urldecode(acym_getVar('string', 'redirectunsub', ''));
451 - if (empty($redirectUrl)) {
452 - $redirectUrl = acym_rootURI();
453 - }
454 -
455 - acym_redirect($this->normalizeRedirectUrl($redirectUrl), '', 'message', true);
456 - }
457 -
458 - private function getUserFromUnsubPage(): object
459 - {
460 - $userID = acym_getVar('int', 'user_id');
461 - $userClass = new UserClass();
462 -
463 - $user = $userClass->getOneById($userID);
464 -
465 - if (empty($user)) {
466 - acym_enqueueMessage(acym_translation('ACYM_USER_NOT_FOUND'), 'error');
467 -
468 - acym_redirect(acym_rootURI());
469 - }
470 -
471 - return $user;
472 - }
473 -
474 - private function unsubscribeAllInner(bool $update = false): void
475 - {
476 - $userClass = new UserClass();
477 - $user = $this->getUserFromUnsubPage();
478 - $redirectUrl = urldecode(acym_getVar('string', 'redirectunsub', ''));
479 - if (empty($redirectUrl)) {
480 - $redirectUrl = $this->config->get('unsub_redirect_url', '');
481 - }
482 -
483 - $allLists = $userClass->getUserSubscriptionById($user->id);
484 - if (empty($allLists)) {
485 - acym_enqueueMessage(acym_translation('ACYM_NOT_SUBSCRIBED_ANY_LIST'), 'info');
486 - acym_redirect($this->normalizeRedirectUrl(!empty($redirectUrl) ? $redirectUrl : acym_rootURI()), '', 'message', true);
487 - }
488 -
489 - $lists = [];
490 - foreach ($allLists as $list) {
491 - if (!$update || $list->visible == 1) {
492 - $lists[] = $list->id;
493 - }
494 - }
495 -
496 - $userClass->sendNotification($user->id, 'acy_notification_unsuball');
497 - // A notification is sent when a user unsubscribes from a list, be we already sent a notification for this
498 - $userClass->blockNotifications = true;
499 - $userClass->unsubscribe([$user->id], $lists);
500 - }
501 -
502 - private function redirectUnsubWorked(): void
503 - {
504 - acym_enqueueMessage(acym_translation('ACYM_SUBSCRIPTION_UPDATED_OK'));
505 - $redirectUrl = urldecode(acym_getVar('string', 'redirectunsub', ''));
506 - if (empty($redirectUrl)) {
507 - $redirectUrl = $this->config->get('unsub_redirect_url', '');
508 - }
509 - if (!empty($redirectUrl)) {
510 - acym_redirect($this->normalizeRedirectUrl($redirectUrl), '', 'message', true);
511 - } else {
512 - acym_redirect(acym_rootURI());
513 - }
514 - }
515 -
516 - public function unsubscribeAll(): void
517 - {
518 - $userClass = new UserClass();
519 - if (empty($userClass->identify(true, 'user_id', 'user_key'))) {
520 - acym_enqueueMessage(acym_translation('ACYM_USER_NOT_FOUND'), 'error');
521 -
522 - acym_redirect(acym_rootURI());
523 - }
524 -
525 - $displayCheckedLists = acym_getVar('string', 'displayed_checked_lists', '');
526 - if (!empty($displayCheckedLists)) {
527 - $user = $this->getUserFromUnsubPage();
528 - $userClass->unsubscribe([$user->id], explode(',', $displayCheckedLists));
529 - } else {
530 - $this->unsubscribeAllInner();
531 - }
532 -
533 - $ajax = acym_getVar('int', 'ajax', 0);
534 - if (!$ajax) {
535 - $this->redirectUnsubWorked();
536 - }
537 - }
538 -
539 - public function saveSubscriptions(): void
540 - {
541 - $userClass = new UserClass();
542 - if (empty($userClass->identify(true, 'user_id', 'user_key'))) {
543 - $this->displayMessage('ACYM_USER_NOT_FOUND', false);
544 - }
545 -
546 - // Get the user
547 - $user = $this->getUserFromUnsubPage();
548 - // Get the list the user want to sub
549 - $listsChecked = acym_getVar('array', 'lists', []);
550 - $listsChecked = array_filter($listsChecked, function ($status) {
551 - return intval($status) === 1;
552 - });
553 - $listsChecked = array_keys($listsChecked);
554 - // Get the displayed lists
555 - $displayedCheckedLists = explode(',', acym_getVar('string', 'displayed_checked_lists', ''));
556 - // We get the user subscriptions
557 - $userSubscriptions = $userClass->getUserSubscriptionById($user->id);
558 -
559 - // We subscribe the user to the checked lists
560 - $userClass->subscribe([$user->id], $listsChecked);
561 -
562 - // We unsub to the unchecked lists
563 - $listsToUnsub = [];
564 - foreach ($userSubscriptions as $subscription) {
565 - // The list wasn't checked && the list is displayed && the user is subscribed to it
566 - if (
567 - !in_array($subscription->id, $listsChecked)
568 - && in_array($subscription->id, $displayedCheckedLists)
569 - && intval($subscription->status) === 1
570 - ) {
571 - $listsToUnsub[] = $subscription->id;
572 - }
573 - }
574 -
575 - $userClass->unsubscribe([$user->id], $listsToUnsub);
576 - $this->redirectUnsubWorked();
577 - }
578 -
579 - public function unsubscribePage(object $alreadyExists): void
580 - {
581 - $userClass = new UserClass();
582 - $lang = acym_getVar('string', 'language', acym_getLanguageTag());
583 - $mailId = acym_getVar('int', 'mail_id', 0);
584 - $campaignListOnly = $this->config->get('unsubscribe_campaign_list_only', '0') === '1';
585 - $displaySurvey = $this->config->get('unsubpage_survey', '0') === '1';
586 - $surveyAnswers = $this->config->get('unsub_survey', '[]');
587 - $unsubscribeColor = $this->config->get('unsubscribe_color', '#00a4ff');
588 - $hoverColor = $this->darkenRGBColor($unsubscribeColor, 20);
589 -
590 - $surveyAnswers = json_decode($surveyAnswers, true);
591 -
592 - $languageCode = acym_getVar('string', 'language');
593 - if (ACYM_CMS === 'joomla' && !empty($languageCode)) {
594 - $lang = $languageCode;
595 - }
596 - acym_setLanguage($lang);
597 - acym_loadLanguage($lang);
598 -
599 - $userSubscriptions = $userClass->getUserSubscriptionById($alreadyExists->id, 'id', false, false, true, false, $mailId, $campaignListOnly);
600 -
601 - $data = [
602 - 'user' => $alreadyExists,
603 - 'mail_id' => $mailId,
604 - 'subscriptions' => $userSubscriptions,
605 - 'lang' => $lang,
606 - ];
607 -
608 - if (acym_isMultilingual()) {
609 - $allLanguages = acym_getLanguages(false, true);
610 - if ($this->config->get('unsubpage_languages_multi_only', '0') === '1') {
611 - $allLanguages = acym_getMultilingualLanguages();
612 - }
613 -
614 - $data['languages'] = [];
615 - foreach ($allLanguages as $key => $language) {
616 - $data['languages'][$key] = $language->name;
617 - }
618 -
619 - $surveyAnswersTranslations = $this->config->get('unsub_survey_translation', '');
620 -
621 - if (!empty($surveyAnswersTranslations)) {
622 - $surveyAnswersTranslations = json_decode($surveyAnswersTranslations, true);
623 - if (isset($surveyAnswersTranslations[$data['lang']])) {
624 - $surveyAnswers = $surveyAnswersTranslations[$data['lang']]['unsub_survey'];
625 - }
626 - }
627 - }
628 -
629 - if ($displaySurvey) {
630 - $data['surveyAnswers'] = $surveyAnswers;
631 - array_unshift($data['surveyAnswers'], acym_translation('ACYM_SELECT_REASON'));
632 - $data['surveyAnswers'][] = acym_translation('ACYM_OTHER');
633 - $data['surveyAnswers'] = array_combine($data['surveyAnswers'], $data['surveyAnswers']);
634 - }
635 -
636 - if (!empty($this->config->get('unsubscribe_color'))) {
637 - $unsubscribeColor = $this->config->get('unsubscribe_color');
638 - $hoverColor = $this->darkenRGBColor($unsubscribeColor, 20);
639 - $data['unsubscribeColor'] = $unsubscribeColor;
640 - $data['hoverColor'] = $hoverColor;
641 - }
642 - $data['svgImage'] = $this->getSVGImage($unsubscribeColor, $hoverColor);
643 -
644 - acym_setVar('layout', 'unsubscribepage');
645 - acym_header('Content-Type: text/html; charset=utf-8');
646 -
647 - parent::display($data);
648 - }
649 -
650 - private function getSVGImage(string $unsubscribeColor, string $hoverColor): string
651 - {
652 - if ($this->config->get('display_unsub_image') === '1') {
653 - $svgPath = ACYM_IMAGES.'unsubscribe/unsub_image.svg';
654 -
655 - $svgContent = acym_fileGetContent($svgPath);
656 -
657 - return str_replace(
658 - ['#B118C8', '#C794CF'],
659 - [$unsubscribeColor, $hoverColor],
660 - $svgContent
661 - );
662 - }
663 -
664 - return '';
665 - }
666 -
667 - public function hexToRGB(string $hexColor): array
668 - {
669 - $hexColor = ltrim($hexColor, '#');
670 -
671 - if (strlen($hexColor) === 3) {
672 - $hexColor = $hexColor[0].$hexColor[0].$hexColor[1].$hexColor[1].$hexColor[2].$hexColor[2];
673 - }
674 -
675 - $r = hexdec(substr($hexColor, 0, 2));
676 - $g = hexdec(substr($hexColor, 2, 2));
677 - $b = hexdec(substr($hexColor, 4, 2));
678 -
679 - return [$r, $g, $b];
680 - }
681 -
682 - public function darkenRGBColor(string $hexColor, int $percent): string
683 - {
684 - $rgbValues = $this->hexToRGB($hexColor);
685 -
686 - $darkenedRGB = array_map(function ($value) use ($percent) {
687 - return max(0, $value - ($value * $percent / 100));
688 - }, $rgbValues);
689 -
690 - return sprintf('rgb(%d, %d, %d)', $darkenedRGB[0], $darkenedRGB[1], $darkenedRGB[2]);
691 - }
692 -
693 - public function confirm(): void
694 - {
695 - if (acym_isRobot()) {
696 - return;
697 - }
698 -
699 - // We identify the user
700 - $userClass = new UserClass();
701 - $user = $userClass->identify(true, 'userId', 'userKey');
702 - if (empty($user)) {
703 - acym_enqueueMessage(acym_translation('ACYM_USER_NOT_FOUND'), 'error');
704 - acym_redirect(acym_rootURI());
705 -
706 - return;
707 - }
708 -
709 - if ($this->config->get('confirmation_message', 1)) {
710 - if ($user->confirmed) {
711 - acym_enqueueMessage(acym_translation('ACYM_ALREADY_CONFIRMED'), 'info');
712 - } else {
713 - acym_enqueueMessage(acym_translation('ACYM_SUBSCRIPTION_CONFIRMED'), 'success');
714 - }
715 - }
716 -
717 - // Now we can really confirm the user
718 - if (!$user->confirmed) {
719 - $userClass->confirm($user->id);
720 - }
721 -
722 - // Get the redirect url from the configuration page if specified
723 - $redirectUrl = $this->config->get('confirm_redirect');
724 - if (!empty($redirectUrl)) {
725 - $replace = [];
726 - // We replace tags in case of the user added some dynamic information to its url.
727 - foreach ($user as $key => $val) {
728 - $replace['{user:'.$key.'}'] = $val;
729 - }
730 - $redirectUrl = str_replace(array_keys($replace), $replace, $redirectUrl);
731 - acym_redirect($redirectUrl, '', 'message', false);
732 -
733 - return;
734 - }
735 -
736 - acym_redirect(acym_rootURI());
737 - }
738 -
739 - public function profile(): void
740 - {
741 - $userClass = new UserClass();
742 - $user = $userClass->identify(true);
743 -
744 - if (empty($user)) {
745 - // Check if the subscription is allowed for non registered users
746 - $allowvisitor = $this->config->get('allow_visitor', 1);
747 - if (empty($allowvisitor)) {
748 - acym_askLog(true, 'ACYM_ONLY_LOGGED', 'message');
749 -
750 - return;
751 - }
752 - }
753 -
754 - global $acymEmailMisspelledLoaded;
755 - $spellChecker = empty($acymEmailMisspelledLoaded) && !empty($this->config->get('email_spellcheck'));
756 - if ($spellChecker) $acymEmailMisspelledLoaded = true;
757 -
758 - if ($spellChecker) {
759 - acym_addStyle(false, ACYM_CSS.'libraries/email-misspelled.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'email-misspelled.min.css'));
760 - acym_addScript(false, ACYM_JS.'libraries/email-misspelled.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'email-misspelled.min.js'));
761 - }
762 - acym_addScript(false, ACYM_JS.'module.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'module.min.js'));
763 -
764 - // Get the page parameters
765 - $params = new \stdClass();
766 - $menu = acym_getMenu();
767 - if (is_object($menu)) {
768 - $params->source = 'Menu n°'.$menu->id;
769 - $menuParameters = method_exists($menu, 'getParams') ? $menu->getParams() : $menu->params;
770 - $menuparams = new AcymParameter($menuParameters);
771 -
772 - if (!empty($menuparams)) {
773 - // Joomla specific params
774 - $params->suffix = $menuparams->get('pageclass_sfx', '');
775 - $params->page_heading = $menuparams->get('page_heading');
776 - $params->show_page_heading = $menuparams->get('show_page_heading', 0);
777 -
778 - if ($menuparams->get('menu-meta_description')) {
779 - acym_addMetadata('description', $menuparams->get('menu-meta_description'));
780 - }
781 - if ($menuparams->get('menu-meta_keywords')) {
782 - acym_addMetadata('keywords', $menuparams->get('menu-meta_keywords'));
783 - }
784 - if ($menuparams->get('robots')) {
785 - acym_addMetadata('robots', $menuparams->get('robots'));
786 - }
787 -
788 - // Our params
789 - $params->lists = $menuparams->get('lists', 'none');
790 - $params->listschecked = $menuparams->get('listschecked', 'none');
791 - $params->dropdown = $menuparams->get('dropdown');
792 - $params->hiddenlists = $menuparams->get('hiddenlists', 'None');
793 - $params->fields = $menuparams->get('fields');
794 - $params->introtext = $menuparams->get('introtext');
795 - $params->posttext = $menuparams->get('posttext');
796 - $params->page_title = $menuparams->get('page_title', '');
797 - }
798 - }
799 - $data = $this->prepareParams($params);
800 -
801 - if (empty($data['user']->language)) {
802 - $cmsUserLanguage = acym_getCmsUserLanguage();
803 - $data['user']->language = empty($cmsUserLanguage) ? acym_getLanguageTag() : $cmsUserLanguage;
804 - }
805 -
806 - $data['captchaHelper'] = new CaptchaHelper();
807 -
808 - acym_setVar('layout', 'profile');
809 - parent::display($data);
810 - }
811 -
812 - public function prepareParams(object $values): array
813 - {
814 - //TODO problem with the types throughout the entire method
815 - if (!isset($values->lists)) {
816 - $values->lists = 'none';
817 - }
818 - if (!isset($values->listschecked)) {
819 - $values->listschecked = 'none';
820 - }
821 - if (!isset($values->dropdown)) {
822 - $values->dropdown = 0;
823 - }
824 - if (!isset($values->hiddenlists)) {
825 - $values->hiddenlists = 'None';
826 - }
827 - if (empty($values->fields)) {
828 - $values->fields = [2];
829 - } elseif (is_string($values->fields)) {
830 - $values->fields = explode(',', $values->fields);
831 - }
832 - if (!in_array('2', $values->fields) && !in_array(2, $values->fields)) {
833 - $values->fields[] = '2';
834 - }
835 - if (!isset($values->page_heading)) {
836 - $values->page_heading = '';
837 - }
838 - if (!isset($values->introtext)) {
839 - $values->introtext = '';
840 - }
841 - if (!isset($values->posttext)) {
842 - $values->posttext = '';
843 - }
844 -
845 - foreach (['lists', 'listschecked', 'hiddenlists', 'fields'] as $option) {
846 - if (is_string($values->$option)) {
847 - $values->$option = explode(',', $values->$option);
848 - }
849 - }
850 -
851 - if ((empty($values->lists) || in_array('None', $values->lists)) && (empty($values->hiddenlists) || strtolower(implode('', $values->hiddenlists)) == 'none')) {
852 - $values->lists[] = 'All';
853 - }
854 -
855 - // Get the current user and his subscription
856 - $userClass = new UserClass();
857 - $user = $userClass->identify(true);
858 - if (empty($user)) {
859 - $listClass = new ListClass();
860 - $subscription = $listClass->getAll('id');
861 -
862 - if (acym_isMultilingual()) {
863 - $subscription = $listClass->getTranslatedNameDescription($subscription);
864 - }
865 -
866 - $user = new \stdClass();
867 - $user->id = 0;
868 - $user->key = 0;
869 -
870 - if (!empty($subscription)) {
871 - foreach ($subscription as $id => $onesub) {
872 - $subscription[$id]->status = 1;
873 - if (strtolower(implode('', $values->listschecked)) != 'all' && !in_array($id, $values->listschecked)) {
874 - $subscription[$id]->status = -1;
875 - }
876 - }
877 - }
878 -
879 - acym_addBreadcrumb(acym_translation('ACYM_SUBSCRIPTION'));
880 - if (empty($menu)) {
881 - acym_setPageTitle(acym_translation('ACYM_SUBSCRIPTION'));
882 - }
883 - } else {
884 - $subscription = $userClass->getAllListsUserSubscriptionById($user->id, 'id', true);
885 -
886 - acym_addBreadcrumb(acym_translation('ACYM_MODIFY_SUBSCRIPTION'));
887 - if (empty($menu)) {
888 - acym_setPageTitle(acym_translation('ACYM_MODIFY_SUBSCRIPTION'));
889 - }
890 - }
891 -
892 - if (!empty($values->page_title)) {
893 - acym_addBreadcrumb($values->page_title);
894 - if (empty($menu)) {
895 - acym_setPageTitle($values->page_title);
896 - }
897 - }
898 -
899 - $allLists = $subscription;
900 -
901 - acym_initModule();
902 -
903 - if (!empty($values->lists) && strtolower(implode('', $values->lists)) != 'all') {
904 - if (in_array('None', $values->lists)) {
905 - $subscription = [];
906 - } else {
907 - $newSubscription = [];
908 - foreach ($subscription as $id => $onesub) {
909 - if (in_array($id, $values->lists)) {
910 - $newSubscription[$id] = $onesub;
911 - }
912 - }
913 - $subscription = $newSubscription;
914 - }
915 - }
916 -
917 - if (!empty($values->hiddenlists)) {
918 - $hiddenListsArray = [];
919 - if (strtolower(implode('', $values->hiddenlists)) == 'all') {
920 - $subscription = [];
921 - foreach ($allLists as $oneList) {
922 - if (!empty($oneList->active)) {
923 - $hiddenListsArray[] = $oneList->id;
924 - }
925 - }
926 - } elseif (strtolower(implode('', $values->hiddenlists)) != 'none') {
927 - foreach ($allLists as $oneList) {
928 - if (!$oneList->active || !in_array($oneList->id, $values->hiddenlists)) {
929 - continue;
930 - }
931 - $hiddenListsArray[] = $oneList->id;
932 - unset($subscription[$oneList->id]);
933 - }
934 - }
935 - $values->hiddenlists = $hiddenListsArray;
936 - }
937 -
938 - // Overriding the list with the URL parameters: &listid= for displayed list, &hiddenlist= for hidden lists
939 - $defaultSubscription = $subscription;
940 - $forceLists = acym_getVar('string', 'listid', '');
941 - if (!empty($forceLists)) {
942 - $subscription = [];
943 - $forceLists = explode(',', $forceLists);
944 - foreach ($forceLists as $oneList) {
945 - if (!empty($defaultSubscription[$oneList])) {
946 - $subscription[$oneList] = $defaultSubscription[$oneList];
947 - }
948 - }
949 - }
950 - $forceHiddenLists = acym_getVar('string', 'hiddenlist', '');
951 - if (!empty($forceHiddenLists)) {
952 - $forceHiddenLists = explode(',', $forceHiddenLists);
953 - $tmpList = [];
954 - foreach ($forceHiddenLists as $oneList) {
955 - if (!empty($defaultSubscription[$oneList]) || in_array($oneList, $values->hiddenlists)) {
956 - $tmpList[] = $oneList;
957 - }
958 - }
959 - $values->hiddenlists = $tmpList;
960 - }
961 -
962 - $displayLists = false;
963 - foreach ($subscription as $oneSub) {
964 - if (!empty($oneSub->active) && $oneSub->visible) {
965 - $displayLists = true;
966 - break;
967 - }
968 - }
969 -
970 - $fieldClass = new FieldClass();
971 - $allfields = $fieldClass->getFieldsByID($values->fields);
972 - $fields = [];
973 - foreach ($allfields as $field) {
974 - if (intval($field->active) === 0) continue;
975 - $fields[$field->id] = $field;
976 - }
977 - $values->fields = $fields;
978 -
979 - $data = [
980 - 'config' => $this->config,
981 - 'displayLists' => $displayLists,
982 - 'user' => $user,
983 - 'subscription' => $subscription,
984 - 'fieldClass' => $fieldClass,
985 - ];
986 -
987 - foreach ($values as $key => $value) {
988 - $data[$key] = $value;
989 - }
990 -
991 - return $data;
992 - }
993 -
994 - public function savechanges(): void
995 - {
996 - wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
997 - acym_checkRobots();
998 -
999 - $userClass = new UserClass();
1000 -
1001 -
1002 - $status = $userClass->saveForm(true);
1003 - if ($status) {
1004 - if ($userClass->confirmationSentSuccess) {
1005 - $this->displayMessage('ACYM_CONFIRMATION_SENT', true, 'success');
1006 - } elseif ($userClass->newUser) {
1007 - $this->displayMessage('ACYM_SUBSCRIPTION_OK', true, 'success');
1008 - } else {
1009 - $this->displayMessage('ACYM_SUBSCRIPTION_UPDATED_OK', true, 'success');
1010 - }
1011 - } elseif (!empty($userClass->requireId)) {
1012 - $this->displayMessage('ACYM_IDENTIFICATION_SENT', true, 'success');
1013 - } elseif (!empty($userClass->errors)) {
1014 - $this->displayMessage(implode('<br/>', $userClass->errors), true);
1015 - } else {
1016 - $this->displayMessage('ACYM_ERROR_SAVING', true);
1017 - }
1018 -
1019 - exit;
1020 - }
1021 -
1022 - public function exportdata(): void
1023 - {
1024 - wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
1025 -
1026 - $userClass = new UserClass();
1027 - $user = $userClass->identify(true, 'userId', 'userKey');
1028 -
1029 - if (empty($user->id)) {
1030 - acym_redirect(acym_rootURI());
1031 - }
1032 -
1033 - $userHelper = new UserHelper();
1034 - $userData = $userHelper->getUserData($user);
1035 - $exportData = [];
1036 - foreach ($userData as $oneCategory) {
1037 - if (!isset($exportData[$oneCategory['group_label']])) {
1038 - $exportData[$oneCategory['group_label']] = [];
1039 - }
1040 -
1041 - $exportData[$oneCategory['group_label']][] = $oneCategory['data'];
1042 - }
1043 -
1044 - $exportFiles = [
1045 - [
1046 - 'name' => 'data.json',
1047 - 'data' => json_encode($exportData),
1048 - ],
1049 - ];
1050 -
1051 - $tempFolder = ACYM_MEDIA.'tmp'.DS;
1052 - acym_createArchive($tempFolder.'export_data_user_'.$user->id, $exportFiles);
1053 -
1054 - $exportHelper = new ExportHelper();
1055 - $exportHelper->setDownloadHeaders('export_data_user_'.$user->id, 'zip');
1056 - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- Downloading a file, better than WP functions for memory handling.
1057 - readfile($tempFolder.'export_data_user_'.$user->id.'.zip');
1058 -
1059 - // Avoid issue when user cancels the download
1060 - ignore_user_abort(true);
1061 - acym_deleteFile($tempFolder.'export_data_user_'.$user->id.'.zip');
1062 - exit;
1063 - }
1064 -
1065 - public function gdprDelete(): void
1066 - {
1067 - wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
1068 -
1069 - $userClass = new UserClass();
1070 - $user = $userClass->identify(true, 'userId', 'userKey');
1071 - if (empty($user->id)) {
1072 - acym_redirect(acym_rootURI());
1073 - }
1074 -
1075 - $userClass->delete([$user->id], true);
1076 -
1077 - acym_redirect(acym_rootURI(), 'ACYM_GDPR_DATA_DELETED');
1078 - }
1079 -
1080 - public function ajaxGetEnqueuedMessages(): void
1081 - {
1082 - $output = '';
1083 - $types = ['success', 'info', 'warning', 'error'];
1084 - foreach ($types as $type) {
1085 - $messages = acym_getVar('array', 'acymessage'.$type, [], 'SESSION');
1086 - if (empty($messages)) {
1087 - continue;
1088 - }
1089 -
1090 - if (!is_array($messages)) {
1091 - $messages = [$messages];
1092 - }
1093 -
1094 - $output .= '<div class="acym_callout acym__callout__front__'.esc_attr($type).'" role="alert">';
1095 - $output .= '<div>'.implode(' ', $messages).'</div>';
1096 - $output .= '<button class="acym_callout_close" aria-label="'.esc_attr(acym_translation('ACYM_CLOSE_NOTIFICATION')).'">x</button></div>';
1097 -
1098 - acym_setSession('acymessage'.$type, null, true);
1099 - }
1100 -
1101 - if (!empty($output)) {
1102 - $output = '<div id="acym__callout__container">'.$output.'</div>';
1103 - }
1104 - acym_sendAjaxResponse('', ['messages' => $output]);
1105 - }
1106 -}