PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
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/Controllers/Mails/Edition.php +202 -130 10.2.2 → 11.1.0 View file →
@@ -17,9 +17,9 @@
17 17 {
18 18 public function edit(): void
19 19 {
20 20 if (!acym_isAdmin()) {
21 - acym_checkToken();
21 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
22 22 }
23 23
24 24 $tempId = acym_getVar('int', 'id');
25 25 $mailClass = new MailClass();
@@ -62,8 +62,12 @@
62 62 $isAutomationAdmin = false;
63 63 $fromMail = '';
64 64
65 65 if (!empty($fromId)) {
66 + if (!$mailClass->hasUserAccess($fromId)) {
67 + die('Access denied for this email');
68 + }
69 +
66 70 $fromMail = $mailClass->getOneById($fromId);
67 71 }
68 72
69 73 if ($type === 'automation_admin') {
@@ -70,8 +74,9 @@
70 74 $type = MailClass::TYPE_AUTOMATION;
71 75 $isAutomationAdmin = true;
72 76 }
73 77
78 + // new mails
74 79 if (empty($tempId)) {
75 80 if (empty($fromId)) {
76 81 $mail = new \stdClass();
77 82 $mail->name = '';
@@ -131,8 +136,9 @@
131 136
132 137 $breadcrumbTitle = acym_translation($breadcrumbTitle);
133 138 $breadcrumbUrl = 'mails&task=edit&type_editor='.$typeEditor.(!empty($fromId) ? '&from='.$fromId : '').'&type='.$type;
134 139 } else {
140 + // Existing mails and notifications
135 141 if (!$mailClass->hasUserAccess($tempId)) {
136 142 die('Access denied for this email');
137 143 }
138 144
@@ -181,14 +187,14 @@
181 187
182 188 $breadcrumbUrl = 'mails&task=edit&id='.$mail->id;
183 189 } else {
184 190 if (empty($return)) {
185 - $return = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
191 + $httpReferer = acym_getVar('string', 'HTTP_REFERER', '', 'SERVER');
192 + $return = empty($httpReferer) ? '' : $httpReferer;
186 193 }
187 194
188 195 $notifName = acym_translation('ACYM_NOTIFICATIION_'.strtoupper(substr($mail->name, 4)));
189 196 if (strpos($notifName, 'ACYM_NOTIFICATIION_') !== false) {
190 -
191 197 array_pop($this->breadcrumb);
192 198 $this->breadcrumb[acym_translation('ACYM_CONFIGURATION')] = acym_completeLink('configuration');
193 199
194 200 $notifName = $mail->name;
@@ -221,9 +227,9 @@
221 227
222 228 if (!empty($return)) {
223 229 $breadcrumbUrl .= '&return='.urlencode(base64_encode($return));
224 230 }
225 - $this->breadcrumb[acym_escape($breadcrumbTitle)] = acym_completeLink($breadcrumbUrl);
231 + $this->breadcrumb[$breadcrumbTitle] = acym_completeLink($breadcrumbUrl);
226 232
227 233 $lists = [];
228 234
229 235 if (in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
@@ -236,14 +242,17 @@
236 242 }
237 243 }
238 244
239 245 if (!empty($mail->attachments) && !is_array($mail->attachments)) {
240 - $mail->attachments = json_decode($mail->attachments);
246 + $mail->attachments = json_decode($mail->attachments, true);
241 247 } elseif (empty($mail->attachments)) {
242 248 $mail->attachments = [];
243 249 }
244 250
251 + $mail->thumbnail = $mail->thumbnail ?? '';
252 +
245 253 $tagClass = new TagClass();
254 + $languages = acym_getLanguages(true, true);
246 255 $data = [
247 256 'mail' => $mail,
248 257 'allTags' => $tagClass->getAllTagsByType(TagClass::TYPE_MAIL),
249 258 'isAutomationAdmin' => $isAutomationAdmin,
@@ -248,9 +257,14 @@
248 257 'allTags' => $tagClass->getAllTagsByType(TagClass::TYPE_MAIL),
249 258 'isAutomationAdmin' => $isAutomationAdmin,
250 259 'social_icons' => $this->config->get('social_icons', '{}'),
251 260 'fromId' => $fromId,
252 - 'langChoice' => acym_languageOption($mail->links_language, 'mail[links_language]'),
261 + 'langChoice' => count($languages) < 2
262 + ? []
263 + : [
264 + 'links' => $mail->links_language,
265 + 'name' => 'mail[links_language]',
266 + ],
253 267 'list_id' => $listIds,
254 268 'lists' => $lists,
255 269 'delay_unit' => $followupClass->getDelayUnits(),
256 270 'default_delay_unit' => FollowupClass::DEFAULT_DELAY_UNIT,
@@ -341,26 +355,33 @@
341 355 $this->loadScripts['edit'][] = 'dtextPicker';
342 356 }
343 357 }
344 358
359 + /**
360 + * Spaghetti code, needs refactoring.
361 + *
362 + * 1 - Save the main mail
363 + * 2 - Save the alternate versions if any
364 + */
345 365 public function store(bool $ajax = false): int
346 366 {
347 - acym_checkToken();
367 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
348 368
349 369 $mailClass = new MailClass();
350 370 $formData = acym_getVar('array', 'mail', []);
351 371 $versions = acym_getVar('array', 'versions', [], 'REQUEST', ACYM_ALLOWRAW);
352 372 $versionType = acym_getVar('string', 'version_type', '');
353 - $mail = new \stdClass();
354 - $allowedFields = acym_getColumns('mail');
373 + $currentVersion = acym_getVar('string', 'current_version', 'main');
374 + $allowedFields = array_diff(acym_getColumns('mail'), ['creator_id']);
355 375 $fromId = acym_getVar('int', 'fromId', 0);
356 376 $return = acym_getVar('string', 'return');
357 377
358 378 $fromAutomation = false;
359 -
360 379 if (!empty($return) && strpos($return, 'automation') !== false) {
361 380 $fromAutomation = true;
362 381 }
382 +
383 + $mail = new \stdClass();
363 384 foreach ($formData as $name => $data) {
364 385 if (!in_array($name, $allowedFields)) {
365 386 continue;
366 387 }
@@ -368,11 +389,12 @@
368 389 $mail->{$name} = $data;
369 390 }
370 391
371 392 if (!empty($mail->id)) {
372 - if (!$mailClass->hasUserAccess($mail->id)) {
393 + if (!$mailClass->hasUserAccess($mail->id, true)) {
373 394 die('Cannot save this mail');
374 395 }
396 +
375 397 $previousMail = $mailClass->getOneById($mail->id);
376 398 }
377 399
378 400 $saveAsTmpl = acym_getVar('int', 'saveAsTmpl', 0);
@@ -386,10 +408,8 @@
386 408
387 409 if ($versionType === 'multilingual') {
388 410 $mail->links_language = $this->config->get('multilingual_default');
389 411 }
390 -
391 - unset($versions['main']);
392 412 }
393 413
394 414 if ($saveAsTmpl === 1) {
395 415 unset($mail->id);
@@ -401,9 +421,9 @@
401 421 acym_setVar('type', MailClass::TYPE_AUTOMATION);
402 422 acym_setVar('type_editor', 'acyEditor');
403 423 }
404 424
405 - if (empty($mail->subject) && !empty($mail->type) && $mail->type != MailClass::TYPE_TEMPLATE) {
425 + if (empty($mail->subject) && !empty($mail->type) && $mail->type !== MailClass::TYPE_TEMPLATE) {
406 426 $mail->subject = acym_translation('ACYM_EMAIL_SUBJECT');
407 427 }
408 428
409 429 $inputNameBody = $saveAsTmpl === 1 ? 'editor_content_template' : 'editor_content';
@@ -416,11 +436,13 @@
416 436 $mail->settings = acym_getVar('string', $inputNameSettings, '', 'REQUEST', ACYM_ALLOWRAW);
417 437 $mail->stylesheet = acym_getVar('string', $inputNameStylesheet, '', 'REQUEST', ACYM_ALLOWRAW);
418 438 $mail->headers = acym_getVar('string', 'editor_headers', '', 'REQUEST', ACYM_ALLOWRAW);
419 439 $mail->drag_editor = strpos($mail->body, 'acym__wysid__template') === false ? 0 : 1;
440 + $mail->thumbnail = '';
420 441
421 - $mail->thumbnail = '';
422 - if (!$fromAutomation) {
442 + if ($fromAutomation) {
443 + $mail->type = MailClass::TYPE_AUTOMATION;
444 + } else {
423 445 $thumbnailName = acym_getVar('string', 'editor_thumbnail', '', 'REQUEST', ACYM_ALLOWRAW);
424 446
425 447 if (preg_match('#^thumbnail_([0-9]*)\.png$#', $thumbnailName)) {
426 448 $mail->thumbnail = $thumbnailName;
@@ -426,9 +448,8 @@
426 448 $mail->thumbnail = $thumbnailName;
427 449 }
428 450 }
429 451
430 - if ($fromAutomation) $mail->type = MailClass::TYPE_AUTOMATION;
431 452 if (empty($mail->id)) {
432 453 $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
433 454 }
434 455
@@ -451,11 +472,13 @@
451 472 $mailSettings = json_decode($previousMail->mail_settings, false);
452 473 } else {
453 474 $mailSettings = new \stdClass();
454 475 }
476 +
455 477 $mailSettings->mainColors = acym_getVar('string', $inputNameColors, '', 'REQUEST', ACYM_ALLOWRAW);
456 478 $mail->mail_settings = json_encode($mailSettings);
457 479
480 + // Use the thumbnail of the source mail if not modified
458 481 if (!empty($fromId) && empty($mail->thumbnail) && !$fromAutomation) {
459 482 $thumbnail = $this->setThumbnailFrom($fromId);
460 483 if (!empty($thumbnail)) {
461 484 if (!empty($previousMail->thumbnail)) {
@@ -471,86 +494,108 @@
471 494 }
472 495
473 496 $this->setAttachmentToMail($mail);
474 497
475 - $mailID = $mailClass->save($mail);
476 - if (!empty($mailID)) {
477 - if (!empty($mail->type) && in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
478 - $listIds = acym_getVar('array', 'list_ids', []);
479 - $listClass = new ListClass();
480 - $listClass->setWelcomeUnsubEmail($listIds, (int)$mailID, $mail->type);
481 - } elseif (!empty($mail->type) && $mail->type == MailClass::TYPE_FOLLOWUP) {
482 - acym_setVar('return', acym_getVar('string', 'return').'&newEmailId='.$mailID);
498 + if ($versionType === 'multilingual' && $currentVersion !== 'main') {
499 + if (empty($mail->id)) {
500 + $mail->subject = $versions['main']['subject'];
501 + $mail->body = $versions['main']['content'];
502 + $mail->preheader = $versions['main']['preview'];
503 + $mail->settings = $versions['main']['settings'];
504 + $mail->stylesheet = $versions['main']['stylesheet'];
483 505
484 - $followupData = acym_getVar('array', 'followup', []);
485 - $followupClass = new FollowupClass();
486 - if (!$followupClass->saveDelaySettings($followupData, $mailID)) {
487 - acym_enqueueMessage(acym_translation('ACYM_COULD_NOT_SAVE_DELAY_SETTINGS'), 'error');
488 - }
489 - if (!empty($followupData['id'])) {
490 - acym_setVar('followup_id', $followupData['id']);
491 - }
506 + $mailID = $mailClass->save($mail);
507 + } else {
508 + $mailID = $mail->id;
492 509 }
510 + } else {
511 + $mailID = $mailClass->save($mail);
512 + }
493 513
514 + if (empty($mailID)) {
494 515 if (!$ajax) {
495 - acym_enqueueMessage(acym_translation('ACYM_SUCCESSFULLY_SAVED'), 'success');
516 + acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
496 517 }
497 518
498 - if ($fromAutomation) {
499 - acym_setVar('type', MailClass::TYPE_AUTOMATION);
500 - acym_setVar('type_editor', 'acyEditor');
501 - } else {
502 - acym_setVar('mailID', $mailID);
519 + if (!empty($mailClass->errors)) {
520 + if (!$ajax) acym_enqueueMessage($mailClass->errors, 'error');
503 521 }
504 522
505 - if (!empty($versions) && in_array($versionType, ['multilingual', 'abtest']) && $saveAsTmpl !== 1) {
506 - $abTestSendingParams = [];
507 - foreach ($versions as $code => $version) {
508 - if (empty($version['subject'])) {
509 - if ($versionType === 'multilingual') {
510 - $mailClass->delete($mailClass->getTranslationId($mailID, $code));
511 - } elseif (!empty($abTestSendingParams[$code])) {
512 - $mailClass->delete($abTestSendingParams[$code]);
513 - }
514 - continue;
515 - }
523 + return 0;
524 + }
516 525
517 - unset($mail->id);
518 - $versionId = null;
526 + if (!empty($mail->type) && in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
527 + $listIds = acym_getVar('array', 'list_ids', []);
528 + $listClass = new ListClass();
529 + $listClass->setWelcomeUnsubEmail($listIds, (int)$mailID, $mail->type);
530 + } elseif (!empty($mail->type) && $mail->type === MailClass::TYPE_FOLLOWUP) {
531 + // Pass the new email ID in the return URL to ask user if we should add it to the queue
532 + acym_setVar('return', acym_getVar('string', 'return').'&newEmailId='.$mailID);
533 +
534 + $followupData = acym_getVar('array', 'followup', []);
535 + $followupClass = new FollowupClass();
536 + if (!$followupClass->saveDelaySettings($followupData, $mailID)) {
537 + acym_enqueueMessage(acym_translation('ACYM_COULD_NOT_SAVE_DELAY_SETTINGS'), 'error');
538 + }
539 + if (!empty($followupData['id'])) {
540 + acym_setVar('followup_id', $followupData['id']);
541 + }
542 + }
543 +
544 + if (!$ajax) {
545 + acym_enqueueMessage(acym_translation('ACYM_SUCCESSFULLY_SAVED'));
546 + }
547 +
548 + if ($fromAutomation) {
549 + acym_setVar('type', MailClass::TYPE_AUTOMATION);
550 + acym_setVar('type_editor', 'acyEditor');
551 + } else {
552 + acym_setVar('mailID', $mailID);
553 + }
554 +
555 + if (!empty($versions) && in_array($versionType, ['multilingual', 'abtest']) && $saveAsTmpl !== 1) {
556 + $abTestSendingParams = [];
557 +
558 + unset($versions['main']);
559 + foreach ($versions as $code => $version) {
560 + if (empty($version['subject'])) {
519 561 if ($versionType === 'multilingual') {
520 - $versionId = $mailClass->getTranslationId($mailID, $code);
562 + $mailClass->delete([$mailClass->getTranslationId($mailID, $code)]);
521 563 } elseif (!empty($abTestSendingParams[$code])) {
522 - $versionId = $abTestSendingParams[$code];
564 + $mailClass->delete([$abTestSendingParams[$code]]);
523 565 }
524 - if (!empty($versionId)) {
525 - $mail->id = $versionId;
526 - }
566 + continue;
567 + }
527 568
528 - $mail->subject = $version['subject'];
529 - $mail->preheader = $version['preview'];
530 - $mail->body = $version['content'];
531 - $mail->parent_id = $mailID;
532 - $mail->settings = $version['settings'];
533 - $mail->stylesheet = $version['stylesheet'];
569 + unset($mail->id);
570 + $versionId = null;
571 + if ($versionType === 'multilingual') {
572 + $versionId = $mailClass->getTranslationId($mailID, $code);
573 + } elseif (!empty($abTestSendingParams[$code])) {
574 + $versionId = $abTestSendingParams[$code];
575 + }
534 576
535 - if ($versionType === 'multilingual') {
536 - $mail->links_language = $code;
537 - $mail->language = $code;
538 - }
577 + if (!empty($versionId)) {
578 + $mail->id = $versionId;
579 + }
539 580
540 - $abTestSendingParams[$code] = $mailClass->save($mail);
581 + $mail->subject = $version['subject'];
582 + $mail->preheader = $version['preview'];
583 + $mail->body = $version['content'];
584 + $mail->parent_id = $mailID;
585 + $mail->settings = $version['settings'];
586 + $mail->stylesheet = $version['stylesheet'];
587 +
588 + if ($versionType === 'multilingual') {
589 + $mail->links_language = $code;
590 + $mail->language = $code;
541 591 }
542 - }
543 592
544 - return (int)$mailID;
545 - } else {
546 - if (!$ajax) acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
547 - if (!empty($mailClass->errors)) {
548 - if (!$ajax) acym_enqueueMessage($mailClass->errors, 'error');
593 + $abTestSendingParams[$code] = $mailClass->save($mail);
549 594 }
595 + }
550 596
551 - return 0;
552 - }
597 + return (int)$mailID;
553 598 }
554 599
555 600 private function setThumbnailFromInput(): string
556 601 {
@@ -562,11 +607,9 @@
562 607 $extension = acym_fileGetExt($thumbnailFile['name']);
563 608
564 609 $thumbNb = $this->config->get('numberThumbnail', 2);
565 610 $filename = 'thumbnail_custom_'.($thumbNb + 1).'.'.$extension;
566 - $newConfig = new \stdClass();
567 - $newConfig->numberThumbnail = $thumbNb + 1;
568 - $this->config->save($newConfig);
611 + $this->config->saveConfig(['numberThumbnail' => $thumbNb + 1]);
569 612 $thumbnailFile['name'] = $filename;
570 613
571 614 ob_start();
572 615 $uploaded = acym_importFile($thumbnailFile, ACYM_UPLOAD_FOLDER_THUMBNAIL, true);
@@ -579,9 +622,9 @@
579 622
580 623 return '';
581 624 }
582 625
583 - public function setAttachmentToMail(object &$mail): void
626 + public function setAttachmentToMail(object $mail): void
584 627 {
585 628 if (!empty($mail->id)) {
586 629 $mailClass = new MailClass();
587 630 $mail->attachments = $mailClass->getMailAttachments($mail->id);
@@ -586,14 +629,17 @@
586 629 $mailClass = new MailClass();
587 630 $mail->attachments = $mailClass->getMailAttachments($mail->id);
588 631 }
589 632
590 - if (!empty($mail->attachments) && !is_array($mail->attachments)) {
591 - $mail->attachments = json_decode($mail->attachments);
633 + if (!empty($mail->attachments)) {
634 + if (!is_array($mail->attachments)) {
635 + $mail->attachments = json_decode($mail->attachments, true);
636 + }
592 637 } else {
593 638 $mail->attachments = [];
594 639 }
595 640
641 + // Attachments
596 642 $newAttachments = [];
597 643 $attachments = acym_getVar('array', 'attachments', []);
598 644 if (!empty($attachments)) {
599 645 foreach ($attachments as $filepath) {
@@ -598,17 +644,19 @@
598 644 if (!empty($attachments)) {
599 645 foreach ($attachments as $filepath) {
600 646 if (empty($filepath)) continue;
601 647
602 - $attachment = new \stdClass();
603 - $attachment->filename = $filepath;
604 - $attachment->size = filesize(ACYM_ROOT.$filepath);
648 + $attachment = [
649 + 'filename' => $filepath,
650 + 'size' => filesize(ACYM_ROOT.$filepath),
651 + ];
605 652
606 - if (preg_match('#\.(php.?|.?htm.?|pl|py|jsp|asp|sh|cgi)#Ui', $attachment->filename)) {
653 + //We will never allow some files to be uploaded...
654 + if (acym_isForbiddenFileExtension($attachment['filename'])) {
607 655 acym_enqueueMessage(
608 656 acym_translationSprintf(
609 657 'ACYM_ACCEPTED_TYPE',
610 - substr($attachment->filename, strrpos($attachment->filename, '.') + 1),
658 + esc_html(substr($attachment['filename'], strrpos($attachment['filename'], '.') + 1)),
611 659 $this->config->get('allowed_files')
612 660 ),
613 661 'notice'
614 662 );
@@ -614,13 +662,14 @@
614 662 );
615 663 continue;
616 664 }
617 665
618 - if (in_array((array)$attachment, $mail->attachments)) continue;
666 + if (in_array($attachment, $mail->attachments)) continue;
619 667
620 668 $newAttachments[] = $attachment;
621 669 }
622 - if (!empty($mail->attachments) && is_array($mail->attachments)) {
670 + // Add to previous attachments
671 + if (!empty($mail->attachments)) {
623 672 $newAttachments = array_merge($mail->attachments, $newAttachments);
624 673 }
625 674 $mail->attachments = $newAttachments;
626 675 }
@@ -626,11 +675,9 @@
626 675 }
627 676
628 677 if (empty($mail->attachments)) {
629 678 unset($mail->attachments);
630 - }
631 -
632 - if (!empty($mail->attachments) && !is_string($mail->attachments)) {
679 + } else {
633 680 $mail->attachments = json_encode($mail->attachments);
634 681 }
635 682 }
636 683
@@ -637,9 +684,9 @@
637 684 private function setThumbnailFrom(int $fromId): string
638 685 {
639 686 $thumbNb = $this->config->get('numberThumbnail', 2);
640 687 $fileName = 'thumbnail_'.($thumbNb + 1).'.png';
641 - $this->config->save(['numberThumbnail' => $thumbNb + 1]);
688 + $this->config->saveConfig(['numberThumbnail' => $thumbNb + 1]);
642 689
643 690 $mailClass = new MailClass();
644 691 $fromMail = $mailClass->getOneById($fromId);
645 692 $fromThumbnail = $fromMail->thumbnail;
@@ -669,9 +716,15 @@
669 716 public function save(): void
670 717 {
671 718 $mailId = $this->store();
672 719
673 - $return = str_replace('{mailid}', empty($mailId) ? '' : $mailId, acym_getVar('string', 'return', ''));
720 + // When saving notifications, we return to page where we clicked the "Edit email" button
721 + $return = str_replace(
722 + '{mailid}',
723 + empty($mailId) ? '' : $mailId,
724 + acym_getVar('string', 'return', '')
725 + );
726 +
674 727 if (empty($return)) {
675 728 $this->listing();
676 729 } else {
677 730 acym_redirect($return);
@@ -679,16 +732,18 @@
679 732 }
680 733
681 734 public function autoSave(): void
682 735 {
736 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
737 +
683 738 $mailClass = new MailClass();
684 739 $mail = new \stdClass();
685 740
686 741 $language = acym_getVar('string', 'language', 'main');
687 742 $mail->id = acym_getVar('int', 'mailId', 0);
688 - $mail->autosave = acym_getVar('string', 'autoSave', '', 'REQUEST', ACYM_ALLOWRAW);
743 + $mail->autosave = base64_decode(acym_getVar('string', 'autoSave', '', 'REQUEST', ACYM_ALLOWRAW));
689 744
690 - if (empty($mail->id) || !$mailClass->hasUserAccess($mail->id) || !$mailClass->autoSave($mail, $language)) {
745 + if (empty($mail->id) || !$mailClass->hasUserAccess($mail->id, true) || !$mailClass->autoSave($mail, $language)) {
691 746 acym_sendAjaxResponse('', [], false);
692 747 } else {
693 748 acym_sendAjaxResponse();
694 749 }
@@ -695,9 +750,9 @@
695 750 }
696 751
697 752 public function ajaxCheckVideoUrl(): void
698 753 {
699 - acym_checkToken();
754 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
700 755 $videoUrl = acym_getVar('string', 'url', '');
701 756
702 757 if (!acym_isValidUrl($videoUrl)) {
703 758 acym_sendAjaxResponse('', [], false);
@@ -753,11 +808,12 @@
753 808
754 809 $left = round(($imageWidth - $logoWidth) / 2);
755 810 $top = round(($imageHeight - $logoHeight) / 2);
756 811 imagecopy($imageVideo, $playButton, $left, $top, 0, 0, $logoWidth, $logoHeight);
757 - imagepng($imageVideo, 'tmp.jpg', 9);
758 -
759 - $input = imagecreatefrompng('tmp.jpg');
812 + $tmpFilePath = ACYM_TMP_FOLDER.'tmp.jpg';
813 + acym_createFolder(ACYM_TMP_FOLDER);
814 + imagepng($imageVideo, $tmpFilePath, 9);
815 + $input = imagecreatefrompng($tmpFilePath);
760 816 $output = imagecreatetruecolor($imageWidth, $imageHeight);
761 817 $white = imagecolorallocate($output, 255, 255, 255);
762 818
763 819 imagefilledrectangle($output, 0, 0, $imageWidth, $imageHeight, $white);
@@ -766,17 +822,22 @@
766 822 ob_start();
767 823 $status = imagejpeg($output, null, 95);
768 824 $imageContent = ob_get_clean();
769 825 if ($status && acym_writeFile(ACYM_ROOT.ACYM_UPLOAD_FOLDER.$fileName, $imageContent)) {
826 + acym_deleteFile($tmpFilePath);
827 +
770 828 return ACYM_UPLOADS_URL.$fileName;
771 829 }
772 830
831 + acym_deleteFile($tmpFilePath);
832 +
773 833 return '';
774 834 }
775 835
776 836 public function getTemplateAjax(): void
777 837 {
778 - acym_checkToken();
838 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
839 +
779 840 $pagination = new PaginationHelper();
780 841 $id = acym_getVar('int', 'id');
781 842 $id = empty($id) ? '' : '&id='.$id;
782 843 $searchFilter = acym_getVar('string', 'search', '');
@@ -822,9 +883,9 @@
822 883 if (in_array($type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
823 884 $listId = acym_getVar('int', 'list_id', 0);
824 885 }
825 886 foreach ($matchingMails['elements'] as $oneTemplate) {
826 - $return .= '<div class="cell grid-x acym__templates__oneTpl acym__listing__block" id="'.acym_escape($oneTemplate->id).'">
887 + $return .= '<div class="cell grid-x acym__templates__oneTpl acym__listing__block" id="'.esc_attr($oneTemplate->id).'">
827 888 <div class="cell acym__templates__pic text-center">';
828 889
829 890 $url = acym_getVar('cmd', 'ctrl').'&task=edit&step=editEmail&from='.intval($oneTemplate->id).$returnUrl.'&type='.$type.$id.'&'.acym_getFormToken();
830 891 if (!empty($followup_id)) {
@@ -836,20 +897,20 @@
836 897 if (!empty($this->data['campaignInformation'])) {
837 898 $url .= '&id='.intval($this->data['campaignInformation']);
838 899 }
839 900 if (!$automation || !empty($returnUrl)) {
840 - $return .= '<a href="'.acym_completeLink($url, false, false, true).'">';
901 + $return .= '<a href="'.esc_url(acym_completeLink($url, false, false, true)).'">';
841 902 }
842 903
843 - $return .= '<img src="'.acym_escape(acym_getMailThumbnail($oneTemplate->thumbnail)).'" alt="template thumbnail"/>';
904 + $return .= '<img src="'.esc_url(acym_getMailThumbnail($oneTemplate->thumbnail)).'" alt="template thumbnail"/>';
844 905 if (!$automation || !empty($returnUrl)) {
845 906 $return .= '</a>';
846 907 }
847 908
848 909 if ($oneTemplate->drag_editor) {
849 - $return .= '<div class="acym__templates__choose__ribbon acyeditor">'.acym_translation('ACYM_DD_EDITOR').'</div>';
910 + $return .= '<div class="acym__templates__choose__ribbon acyeditor">'.esc_html(acym_translation('ACYM_DD_EDITOR')).'</div>';
850 911 } else {
851 - $return .= '<div class="acym__templates__choose__ribbon htmleditor">'.acym_translation('ACYM_HTML_EDITOR').'</div>';
912 + $return .= '<div class="acym__templates__choose__ribbon htmleditor">'.esc_html(acym_translation('ACYM_HTML_EDITOR')).'</div>';
852 913 }
853 914
854 915 if (strlen($oneTemplate->name) > 55) {
855 916 $oneTemplate->name = substr($oneTemplate->name, 0, 50).'...';
@@ -854,13 +915,14 @@
854 915 if (strlen($oneTemplate->name) > 55) {
855 916 $oneTemplate->name = substr($oneTemplate->name, 0, 50).'...';
856 917 }
857 918 $return .= '</div>
858 - <div class="cell grid-x acym__templates__footer text-center">
859 - <div class="cell acym__templates__footer__title acym_text_ellipsis" title="'.acym_escape($oneTemplate->name).'">'.acym_escape($oneTemplate->name).'</div>
860 - <div class="cell">'.acym_date($oneTemplate->creation_date, 'ACYM_DATE_FORMAT_LC3').'</div>
861 - </div>
862 - </div>';
919 + <div class="cell grid-x acym__templates__footer text-center">
920 + <div class="cell acym__templates__footer__title acym_text_ellipsis" title="'.esc_attr($oneTemplate->name).'">';
921 + $return .= esc_html($oneTemplate->name).'</div>
922 + <div class="cell">'.esc_html(acym_date($oneTemplate->creation_date, 'ACYM_DATE_FORMAT_LC3')).'</div>
923 + </div>
924 + </div>';
863 925 }
864 926
865 927 $return .= '</div>';
866 928
@@ -865,21 +927,23 @@
865 927 $return .= '</div>';
866 928
867 929 $pagination->setStatus((int)$matchingMails['total']->total, $page, $mailsPerPage);
868 930
869 - $return .= $pagination->displayAjax();
931 + ob_start();
932 + $pagination->display('', '__ajax');
933 + $return .= ob_get_clean();
870 934
871 - echo $return;
935 + acym_sendAjaxResponse('', ['pagination' => $return]);
872 936 exit;
873 937 }
874 938
875 939 public function setNewThumbnail(): void
876 940 {
877 - if (!acym_isAdmin()) {
941 + if (!acym_isAdmin() || (!acym_isAllowed('mails') && !acym_isAllowed('campaigns'))) {
878 942 die('Access denied for thumbnail creation');
879 943 }
880 944
881 - acym_checkToken();
945 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
882 946 $contentThumbnail = acym_getVar('string', 'content', '');
883 947 if (strpos($contentThumbnail, 'data:image/png') !== 0) {
884 948 acym_sendAjaxResponse('This file is not allowed.', [], false);
885 949 }
@@ -895,11 +959,9 @@
895 959
896 960 if (empty($file) || strpos($file, 'http') === 0) {
897 961 $thumbNb = $this->config->get('numberThumbnail', 2);
898 962 $file = 'thumbnail_'.($thumbNb + 1).'.png';
899 - $newConfig = new \stdClass();
900 - $newConfig->numberThumbnail = $thumbNb + 1;
901 - $this->config->save($newConfig);
963 + $this->config->saveConfig(['numberThumbnail' => $thumbNb + 1]);
902 964 }
903 965
904 966 $extension = acym_fileGetExt($file);
905 967 if (strpos($file, 'thumbnail_') === false || !in_array($extension, ['png', 'jpeg', 'jpg', 'gif', 'webp'])) {
@@ -913,9 +975,9 @@
913 975 }
914 976
915 977 public function setNewIconShare(): void
916 978 {
917 - acym_checkToken();
979 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
918 980 $socialName = acym_getVar('string', 'social', '');
919 981 $socialMedias = acym_getSocialMedias();
920 982 if (!in_array($socialName, $socialMedias)) {
921 983 acym_sendAjaxResponse(acym_translationSprintf('ACYM_UNKNOWN_SOCIAL', $socialName), [], false);
@@ -920,17 +982,21 @@
920 982 if (!in_array($socialName, $socialMedias)) {
921 983 acym_sendAjaxResponse(acym_translationSprintf('ACYM_UNKNOWN_SOCIAL', $socialName), [], false);
922 984 }
923 985
924 - $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
986 + $file = acym_getVar('array', 'file', [], 'FILES');
987 + $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
925 988 $newPath = ACYM_UPLOAD_FOLDER.'socials'.DS.$socialName;
926 989 $newPathComplete = $newPath.'.'.$extension;
927 990
928 - $allowedExtensions = acym_getImageFileExtensions();
991 + $allowedExtensions = acym_getImageFileExtensions(true);
929 992 if (!in_array($extension, $allowedExtensions)) {
930 - $errorMessage = acym_translationSprintf('ACYM_ACCEPTED_TYPE', $extension, implode(', ', $allowedExtensions));
931 - } elseif (!acym_uploadFile($_FILES['file']['tmp_name'], ACYM_ROOT.$newPathComplete)) {
993 + $errorMessage = acym_translationSprintf('ACYM_ACCEPTED_TYPE', esc_html($extension), implode(', ', $allowedExtensions));
994 + } elseif (!acym_uploadFile($file['tmp_name'], ACYM_ROOT.$newPathComplete)) {
932 995 $errorMessage = acym_translationSprintf('ACYM_ERROR_UPLOADING_FILE_X', $newPathComplete);
996 + } elseif (strtolower($extension) === 'svg' && !acym_isSvgFileSafe(ACYM_ROOT.$newPathComplete)) {
997 + acym_deleteFile(ACYM_ROOT.$newPathComplete);
998 + $errorMessage = acym_translationSprintf('ACYM_ERROR_UPLOADING_FILE_X', $newPathComplete);
933 999 }
934 1000
935 1001 if (!empty($errorMessage)) {
936 1002 acym_sendAjaxResponse($errorMessage, [], false);
@@ -935,17 +1001,14 @@
935 1001 if (!empty($errorMessage)) {
936 1002 acym_sendAjaxResponse($errorMessage, [], false);
937 1003 }
938 1004
939 - $newConfig = new \stdClass();
940 - $newConfig->social_icons = json_decode($this->config->get('social_icons', '{}'), true);
941 -
942 1005 $newImg = acym_rootURI().$newPathComplete;
943 1006 $newImgWithoutExtension = acym_rootURI().$newPath;
944 1007
945 - $newConfig->social_icons[$socialName] = $newImg;
946 - $newConfig->social_icons = json_encode($newConfig->social_icons);
947 - $this->config->save($newConfig);
1008 + $socialIcons = json_decode($this->config->get('social_icons', '{}'), true);
1009 + $socialIcons[$socialName] = $newImg;
1010 + $this->config->saveConfig(['social_icons' => json_encode($socialIcons)]);
948 1011
949 1012 acym_sendAjaxResponse(
950 1013 acym_translation('ACYM_ICON_IMPORTED'),
951 1014 [
@@ -957,8 +1020,9 @@
957 1020
958 1021 public function saveAjax(): void
959 1022 {
960 1023 $mailId = $this->store(true);
1024 +
961 1025 if (!empty($mailId)) {
962 1026 acym_sendAjaxResponse('', ['result' => $mailId]);
963 1027 } else {
964 1028 acym_sendAjaxResponse(acym_translation('ACYM_ERROR_SAVING'), [], false);
@@ -975,12 +1039,20 @@
975 1039
976 1040 $mailClass = new MailClass();
977 1041 $mail = $mailClass->getOneById($idMail);
978 1042
1043 + if (empty($mail)) {
1044 + exit;
1045 + }
1046 +
1047 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Returning content as text/css, need to output raw content.
979 1048 echo $mailClass->buildCSS($mail->stylesheet);
980 1049 exit;
981 1050 }
982 1051
1052 + /*
1053 + * Method used to send a test when editing a notification email
1054 + */
983 1055 public function test(): void
984 1056 {
985 1057 $mailId = $this->store();
986 1058 $return = acym_getVar('string', 'return', '');
@@ -1017,9 +1089,9 @@
1017 1089 }
1018 1090
1019 1091 public function sendTest(): void
1020 1092 {
1021 - acym_checkToken();
1093 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
1022 1094 $controller = acym_getVar('string', 'controller', 'mails');
1023 1095 $level = 'info';
1024 1096
1025 1097 $testNote = acym_getVar('string', 'test_note', '');