PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.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
acymailing / front / FrontControllers / FrontusersController.php

FrontusersController.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at front/FrontControllers/FrontusersController.php

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