PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / trunk
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress vtrunk
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 / back / Controllers / Mails / Edition.php

Edition.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress trunk, at back/Controllers/Mails/Edition.php

917 lines 36.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Controllers\Mails;
4
5 use AcyMailing\Classes\FollowupClass;
6 use AcyMailing\Classes\ListClass;
7 use AcyMailing\Classes\MailClass;
8 use AcyMailing\Classes\TagClass;
9 use AcyMailing\Controllers\CampaignsController;
10 use AcyMailing\Helpers\EditorHelper;
11 use AcyMailing\Helpers\MailerHelper;
12 use AcyMailing\Helpers\PaginationHelper;
13 use AcyMailing\Types\UploadFileType;
14
15 trait Edition
16 {
17 public function edit(): void
18 {
19 if (!acym_isAdmin()) {
20 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
21 }
22
23 $tempId = acym_getVar('int', 'id');
24 $mailClass = new MailClass();
25 $typeEditor = acym_getVar('string', 'type_editor');
26 $notification = acym_getVar('cmd', 'notification');
27 $return = acym_getVar('string', 'return', '');
28 $followupId = acym_getVar('int', 'followup_id', 0);
29 $followupClass = new FollowupClass();
30
31 $campaignController = new CampaignsController();
32
33 if (base64_decode($return, true) === false) {
34 $return = empty($return) ? '' : $return;
35 } else {
36 $return = empty($return) ? '' : urldecode(base64_decode($return));
37 }
38
39 $type = acym_getVar('string', 'type', '');
40 $fromId = acym_getVar('int', 'from');
41 $listIds = acym_getVar('int', 'list_id', []);
42
43 if (in_array($type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
44 array_pop($this->breadcrumb);
45 $this->breadcrumb[acym_translation('ACYM_LISTS')] = acym_completeLink('lists');
46 $campaignController->setTaskListing($type);
47
48 if (!empty($listIds)) {
49 $listIds = [$listIds];
50 }
51 }
52
53
54 if (!empty($notification)) {
55 $mail = $mailClass->getOneByName($notification);
56 if (!empty($mail->id)) {
57 $tempId = $mail->id;
58 }
59 }
60
61 $isAutomationAdmin = false;
62 $fromMail = '';
63
64 if (!empty($fromId)) {
65 if (!$mailClass->hasUserAccess($fromId)) {
66 die('Access denied for this email');
67 }
68
69 $fromMail = $mailClass->getOneById($fromId);
70 }
71
72 if ($type === 'automation_admin') {
73 $type = MailClass::TYPE_AUTOMATION;
74 $isAutomationAdmin = true;
75 }
76
77 // new mails
78 if (empty($tempId)) {
79 if (empty($fromId)) {
80 $mail = new \stdClass();
81 $mail->name = '';
82 $mail->subject = '';
83 $mail->preheader = '';
84 $mail->tags = [];
85 $mail->type = $type;
86 $mail->body = '';
87 $mail->editor = in_array($type, [MailClass::TYPE_AUTOMATION, MailClass::TYPE_FOLLOWUP, MailClass::TYPE_SCENARIO]) ? 'acyEditor' : $typeEditor;
88 $mail->headers = '';
89 $mail->thumbnail = null;
90 $mail->links_language = '';
91 $mail->from_email = '';
92 $mail->from_name = '';
93 $mail->reply_to_email = '';
94 $mail->reply_to_name = '';
95 } else {
96 $mail = $fromMail;
97 $mail->id = 0;
98 $mail->from_email = $fromMail->from_email;
99 $mail->from_name = $fromMail->from_name;
100 $mail->reply_to_email = $fromMail->reply_to_email;
101 $mail->reply_to_name = $fromMail->reply_to_name;
102 if (0 == $mail->drag_editor) {
103 $mail->editor = 'html';
104 } else {
105 $mail->editor = !empty($typeEditor) ? $typeEditor : 'acyEditor';
106 }
107 }
108 $mail->access = [];
109 $mail->delay = 0;
110 $mail->delay_unit = FollowupClass::DEFAULT_DELAY_UNIT;
111
112 if (!empty($type)) $mail->type = $type;
113
114 if (MailClass::TYPE_AUTOMATION != $type || empty($fromId)) $mail->id = 0;
115
116 switch ($type) {
117 case MailClass::TYPE_WELCOME:
118 $breadcrumbTitle = 'ACYM_CREATE_WELCOME_MAIL';
119 break;
120 case MailClass::TYPE_UNSUBSCRIBE:
121 $breadcrumbTitle = 'ACYM_CREATE_UNSUBSCRIBE_MAIL';
122 break;
123 case MailClass::TYPE_AUTOMATION:
124 $breadcrumbTitle = 'ACYM_NEW_EMAIL';
125 break;
126 case MailClass::TYPE_FOLLOWUP:
127 $breadcrumbTitle = 'ACYM_NEW_FOLLOW_UP_EMAIL';
128 break;
129 case MailClass::TYPE_SCENARIO:
130 $breadcrumbTitle = 'ACYM_SCENARIO_EMAIL';
131 break;
132 default:
133 $breadcrumbTitle = 'ACYM_CREATE_TEMPLATE';
134 }
135
136 $breadcrumbTitle = acym_translation($breadcrumbTitle);
137 $breadcrumbUrl = 'mails&task=edit&type_editor='.$typeEditor.(!empty($fromId) ? '&from='.$fromId : '').'&type='.$type;
138 } else {
139 // Existing mails and notifications
140 if (!$mailClass->hasUserAccess($tempId)) {
141 die('Access denied for this email');
142 }
143
144 $mail = $mailClass->getOneById($tempId);
145
146 if (!empty($fromMail)) {
147 $mail->drag_editor = $fromMail->drag_editor;
148 $mail->body = $fromMail->body;
149 $mail->stylesheet = $fromMail->stylesheet;
150 $mail->settings = $fromMail->settings;
151 $mail->from_email = $fromMail->from_email;
152 $mail->from_name = $fromMail->from_name;
153 $mail->reply_to_email = $fromMail->reply_to_email;
154 $mail->reply_to_name = $fromMail->reply_to_name;
155 }
156
157 if (!empty($followupId)) $followupClass->getDelaySettingToMail($mail, $followupId);
158
159 $mail->editor = $mail->drag_editor == 0 ? 'html' : 'acyEditor';
160 if (!empty($typeEditor)) $mail->editor = $typeEditor;
161
162 if (empty($notification)) {
163 if (in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
164 array_pop($this->breadcrumb);
165 $this->breadcrumb[acym_translation('ACYM_LISTS')] = acym_completeLink('lists');
166 }
167
168 if ($mail->type === MailClass::TYPE_OVERRIDE) {
169 array_pop($this->breadcrumb);
170 $this->breadcrumb[acym_translation('ACYM_EMAILS_OVERRIDE')] = acym_completeLink('override');
171 acym_loadLanguageFile('plg_user_joomla', ACYM_BASE);
172 acym_loadLanguageFile('com_users');
173 acym_loadLanguageFile('com_contact');
174 $breadcrumbTitle = acym_translationSprintf(
175 preg_replace(
176 '#^{trans:([A-Z_]+)(|.+)*}$#',
177 '$1',
178 $mail->subject
179 ),
180 '{param1}',
181 '{param2}'
182 );
183 } else {
184 $breadcrumbTitle = $mail->name;
185 }
186
187 $breadcrumbUrl = 'mails&task=edit&id='.$mail->id;
188 } else {
189 if (empty($return)) {
190 $httpReferer = acym_getVar('string', 'HTTP_REFERER', '', 'SERVER');
191 $return = empty($httpReferer) ? '' : $httpReferer;
192 }
193
194 $notifName = acym_translation('ACYM_NOTIFICATIION_'.strtoupper(substr($mail->name, 4)));
195 if (strpos($notifName, 'ACYM_NOTIFICATIION_') !== false) {
196 array_pop($this->breadcrumb);
197 $this->breadcrumb[acym_translation('ACYM_CONFIGURATION')] = acym_completeLink('configuration');
198
199 $notifName = $mail->name;
200
201 if ($notifName === 'acy_confirm') {
202 $notifName = acym_translation('ACYM_CONFIRMATION_EMAIL');
203 } elseif ($notifName === 'acy_notification_create') {
204 $notifName = acym_translation('ACYM_NOTIFICATION_CREATE_EMAIL');
205 } elseif ($notifName === 'acy_notification_unsub') {
206 $notifName = acym_translation('ACYM_NOTIFICATION_UNSUB_EMAIL');
207 } elseif ($notifName === 'acy_notification_unsuball') {
208 $notifName = acym_translation('ACYM_NOTIFICATION_UNSUBALL_EMAIL');
209 } elseif ($notifName === 'acy_notification_subform') {
210 $notifName = acym_translation('ACYM_NOTIFICATION_SUBFORM_EMAIL');
211 } elseif ($notifName === 'acy_notification_profile') {
212 $notifName = acym_translation('ACYM_NOTIFICATION_PROFILE_EMAIL');
213 } elseif ($notifName === 'acy_notification_confirm') {
214 $notifName = acym_translation('ACYM_NOTIFICATION_CONFIRM_EMAIL');
215 }
216 }
217
218 $breadcrumbTitle = $notifName;
219 $breadcrumbUrl = 'mails&task=edit&notification='.$mail->name;
220 }
221
222 if (!empty($mail->stylesheet) && strpos($mail->stylesheet, '[class="') !== false) {
223 acym_enqueueMessage(acym_translation('ACYM_WARNING_STYLESHEET_NOT_CORRECT'), 'warning');
224 }
225 }
226
227 if (!empty($return)) {
228 $breadcrumbUrl .= '&return='.urlencode(base64_encode($return));
229 }
230 $this->breadcrumb[$breadcrumbTitle] = acym_completeLink($breadcrumbUrl);
231
232 $lists = [];
233
234 if (in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
235 $listClass = new ListClass();
236 $lists = $listClass->getAllWithIdName();
237
238 if (empty($listIds) && !empty($mail->id)) $listIds = $listClass->getListIdsByWelcomeUnsub($mail->id, $mail->type == MailClass::TYPE_WELCOME);
239 if (!is_array($listIds)) {
240 $listIds = [$listIds];
241 }
242 }
243
244 if (!empty($mail->attachments) && !is_array($mail->attachments)) {
245 $mail->attachments = json_decode($mail->attachments, true);
246 } elseif (empty($mail->attachments)) {
247 $mail->attachments = [];
248 }
249
250 $mail->thumbnail = $mail->thumbnail ?? '';
251
252 $tagClass = new TagClass();
253 $languages = acym_getLanguages(true, true);
254 $data = [
255 'mail' => $mail,
256 'allTags' => $tagClass->getAllTagsByType(TagClass::TYPE_MAIL),
257 'isAutomationAdmin' => $isAutomationAdmin,
258 'social_icons' => $this->config->get('social_icons', '{}'),
259 'fromId' => $fromId,
260 'langChoice' => count($languages) < 2
261 ? []
262 : [
263 'links' => $mail->links_language,
264 'name' => 'mail[links_language]',
265 ],
266 'list_id' => $listIds,
267 'lists' => $lists,
268 'delay_unit' => $followupClass->getDelayUnits(),
269 'default_delay_unit' => FollowupClass::DEFAULT_DELAY_UNIT,
270 'followup_id' => $followupId,
271 'uploadFileType' => new UploadFileType(),
272 'mailClass' => $mailClass,
273 ];
274 $followup = $followupClass->getOneById($data['followup_id']);
275
276 if (!empty($followup)) {
277 $data['followup_trigger'] = $followup->trigger;
278 }
279
280 $this->prepareMailMultilingual($data);
281 $this->prepareEditorEdit($data);
282
283 $campaignController->prepareMaxUpload($data);
284
285 if (!empty($return)) {
286 $data['return'] = $return;
287 }
288
289 acym_setVar('layout', 'edit');
290 $data['menuClass'] = $this->menuClass;
291
292 parent::display($data);
293 }
294
295 private function prepareMailMultilingual(array &$data): void
296 {
297 $mail = $data['mail'];
298 if (in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE, MailClass::TYPE_NOTIFICATION]) && acym_isMultilingual()) {
299 $data['multilingual'] = true;
300 }
301 }
302
303 private function prepareEditorEdit(array &$data): void
304 {
305 $data['editor'] = new EditorHelper();
306 $data['editor']->content = $data['mail']->body;
307 $data['editor']->autoSave = empty($data['mail']->autosave) ? '' : $data['mail']->autosave;
308 $data['editor']->editor = empty($data['mail']->editor) ? '' : $data['mail']->editor;
309 if (!empty($data['mail']->id)) $data['editor']->mailId = $data['mail']->id;
310 if (!empty($data['mail']->type)) $data['editor']->automation = $data['isAutomationAdmin'];
311 if (!empty($data['mail']->settings)) $data['editor']->settings = $data['mail']->settings;
312 if (!empty($data['mail']->stylesheet)) $data['editor']->stylesheet = $data['mail']->stylesheet;
313
314 $data['editor']->data = [
315 'mail' => $data['mail'],
316 'mailClass' => new MailClass(),
317 ];
318
319 if (!empty($data['multilingual'])) {
320 $data['editor']->data['tagClass'] = new TagClass();
321 $data['editor']->data['main_language'] = $this->config->get('multilingual_default');
322 $data['editor']->data['languages'] = explode(',', $this->config->get('multilingual_languages'));
323 $data['editor']->data['multilingual'] = true;
324
325 $allLanguages = acym_getLanguages();
326
327 $mainLang = new \stdClass();
328 $mainLang->code = $data['editor']->data['main_language'];
329 $mainLang->name = empty($allLanguages[$data['editor']->data['main_language']]) ? $data['editor']->data['main_language']
330 : $allLanguages[$data['editor']->data['main_language']]->name;
331 $data['editor']->data['main_language'] = $mainLang;
332 $mailClass = new MailClass();
333 $mailId = empty($data['mail']->id) ? -1 : $data['mail']->id;
334 $translations = $mailClass->getTranslationsById($mailId, true);
335 foreach ($data['editor']->data['languages'] as $i => $oneLangCode) {
336 $data['editor']->data['languages'][$i] = new \stdClass();
337 $data['editor']->data['languages'][$i]->code = $oneLangCode;
338 $data['editor']->data['languages'][$i]->name = empty($allLanguages[$oneLangCode]) ? $oneLangCode : $allLanguages[$oneLangCode]->name;
339 $data['editor']->data['languages'][$i]->subject = empty($translations[$oneLangCode]->subject) ? '' : $translations[$oneLangCode]->subject;
340 $data['editor']->data['languages'][$i]->preview = empty($translations[$oneLangCode]->preheader) ? '' : $translations[$oneLangCode]->preheader;
341 $data['editor']->data['languages'][$i]->content = empty($translations[$oneLangCode]->body) ? '' : $translations[$oneLangCode]->body;
342 $data['editor']->data['languages'][$i]->autosave = empty($translations[$oneLangCode]->autosave) ? '' : $translations[$oneLangCode]->autosave;
343 $data['editor']->data['languages'][$i]->settings = empty($translations[$oneLangCode]->settings) ? '' : $translations[$oneLangCode]->settings;
344 $data['editor']->data['languages'][$i]->stylesheet = empty($translations[$oneLangCode]->stylesheet) ? '' : $translations[$oneLangCode]->stylesheet;
345 }
346 $data['editor']->data['editor'] = new \stdClass();
347 $data['editor']->data['editor']->editor = 'acyEditor';
348 }
349
350 if ($data['editor']->isDragAndDrop()) {
351 $this->loadScripts['edit'][] = 'editor-wysid';
352 $this->loadScripts['edit']['vue-applications'] = ['custom_view'];
353 } else {
354 $this->loadScripts['edit'][] = 'dtextPicker';
355 }
356 }
357
358 /**
359 * Spaghetti code, needs refactoring.
360 *
361 * 1 - Save the main mail
362 * 2 - Save the alternate versions if any
363 */
364 public function store(bool $ajax = false): int
365 {
366 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
367
368 $mailClass = new MailClass();
369 $formData = acym_getVar('array', 'mail', []);
370 $versions = acym_getVar('array', 'versions', [], 'REQUEST', ACYM_ALLOWRAW);
371 $versionType = acym_getVar('string', 'version_type', '');
372 $currentVersion = acym_getVar('string', 'current_version', 'main');
373 $allowedFields = array_diff(acym_getColumns('mail'), ['creator_id']);
374 $fromId = acym_getVar('int', 'fromId', 0);
375 $return = acym_getVar('string', 'return');
376
377 $fromAutomation = false;
378 if (!empty($return) && strpos($return, 'automation') !== false) {
379 $fromAutomation = true;
380 }
381
382 $mail = new \stdClass();
383 foreach ($formData as $name => $data) {
384 if (!in_array($name, $allowedFields)) {
385 continue;
386 }
387
388 $mail->{$name} = $data;
389 }
390
391 if (!empty($mail->id)) {
392 if (!$mailClass->hasUserAccess($mail->id, true)) {
393 die('Cannot save this mail');
394 }
395
396 $previousMail = $mailClass->getOneById($mail->id);
397 }
398
399 $saveAsTmpl = acym_getVar('int', 'saveAsTmpl', 0);
400 if (!empty($versions)) {
401 $saveAsTmplVersion = $saveAsTmpl === 1 ? acym_getVar('string', 'saveAsTmplVersion', 'main') : 'main';
402 if (!empty($versions[$saveAsTmplVersion]['subject'])) $mail->subject = $versions[$saveAsTmplVersion]['subject'];
403 if (!empty($versions[$saveAsTmplVersion]['preview'])) $mail->preheader = $versions[$saveAsTmplVersion]['preview'];
404 if (!empty($versions[$saveAsTmplVersion]['content'])) $mail->body = $versions[$saveAsTmplVersion]['content'];
405 if (!empty($versions[$saveAsTmplVersion]['settings'])) $mail->settings = $versions[$saveAsTmplVersion]['settings'];
406 if (!empty($versions[$saveAsTmplVersion]['stylesheet'])) $mail->stylesheet = $versions[$saveAsTmplVersion]['stylesheet'];
407
408 if ($versionType === 'multilingual') {
409 $mail->links_language = $this->config->get('multilingual_default');
410 }
411 }
412
413 if ($saveAsTmpl === 1) {
414 unset($mail->id);
415 $mail->type = MailClass::TYPE_TEMPLATE;
416 }
417
418 if ($fromAutomation) {
419 acym_setVar('from', $mail->id);
420 acym_setVar('type', MailClass::TYPE_AUTOMATION);
421 acym_setVar('type_editor', 'acyEditor');
422 }
423
424 if (empty($mail->subject) && !empty($mail->type) && $mail->type !== MailClass::TYPE_TEMPLATE) {
425 $mail->subject = acym_translation('ACYM_EMAIL_SUBJECT');
426 }
427
428 $inputNameBody = $saveAsTmpl === 1 ? 'editor_content_template' : 'editor_content';
429 $inputNameSettings = $saveAsTmpl === 1 ? 'editor_settings_template' : 'editor_settings';
430 $inputNameStylesheet = $saveAsTmpl === 1 ? 'editor_stylesheet_template' : 'editor_stylesheet';
431 $inputNameColors = $saveAsTmpl === 1 ? 'main_colors_template' : 'main_colors';
432
433 $mail->tags = acym_getVar('array', 'template_tags', []);
434 $mail->body = acym_getVar('string', $inputNameBody, '', 'REQUEST', ACYM_ALLOWRAW);
435 $mail->settings = acym_getVar('string', $inputNameSettings, '', 'REQUEST', ACYM_ALLOWRAW);
436 $mail->stylesheet = acym_getVar('string', $inputNameStylesheet, '', 'REQUEST', ACYM_ALLOWRAW);
437 $mail->headers = acym_getVar('string', 'editor_headers', '', 'REQUEST', ACYM_ALLOWRAW);
438 $mail->drag_editor = strpos($mail->body, 'acym__wysid__template') === false ? 0 : 1;
439 $mail->thumbnail = '';
440
441 if ($fromAutomation) {
442 $mail->type = MailClass::TYPE_AUTOMATION;
443 } else {
444 $thumbnailName = acym_getVar('string', 'editor_thumbnail', '', 'REQUEST', ACYM_ALLOWRAW);
445
446 if (preg_match('#^thumbnail_([0-9]*)\.png$#', $thumbnailName)) {
447 $mail->thumbnail = $thumbnailName;
448 }
449 }
450
451 if (empty($mail->id)) {
452 $mail->creation_date = acym_date('now', 'Y-m-d H:i:s', false);
453 }
454
455 $uploadedThumbnail = $this->setThumbnailFromInput();
456 if (!empty($uploadedThumbnail)) {
457 if (!empty($previousMail->thumbnail)) {
458 acym_deleteFile(ACYM_UPLOAD_FOLDER_THUMBNAIL.$previousMail->thumbnail);
459 }
460
461 $mail->thumbnail = $uploadedThumbnail;
462 } elseif (acym_getVar('bool', 'custom_thumbnail_reset', false)) {
463 if (!empty($previousMail->thumbnail)) {
464 acym_deleteFile(ACYM_UPLOAD_FOLDER_THUMBNAIL.$previousMail->thumbnail);
465 }
466
467 $mail->thumbnail = null;
468 }
469
470 if (!empty($previousMail->mail_settings)) {
471 $mailSettings = json_decode($previousMail->mail_settings, false);
472 } else {
473 $mailSettings = new \stdClass();
474 }
475
476 $mailSettings->mainColors = acym_getVar('string', $inputNameColors, '', 'REQUEST', ACYM_ALLOWRAW);
477 $mail->mail_settings = json_encode($mailSettings);
478
479 // Use the thumbnail of the source mail if not modified
480 if (!empty($fromId) && empty($mail->thumbnail) && !$fromAutomation) {
481 $thumbnail = $this->setThumbnailFrom($fromId);
482 if (!empty($thumbnail)) {
483 if (!empty($previousMail->thumbnail)) {
484 acym_deleteFile(ACYM_UPLOAD_FOLDER_THUMBNAIL.$previousMail->thumbnail);
485 }
486
487 $mail->thumbnail = $thumbnail;
488 }
489 }
490
491 if (empty($mail->name) && !in_array($mail->type, MailClass::TYPES_NO_NAME) && empty($mail->id)) {
492 $mail->name = empty($mail->subject) ? acym_translation('ACYM_TEMPLATE_NAME') : $mail->subject;
493 }
494
495 $this->setAttachmentToMail($mail);
496
497 if ($versionType === 'multilingual' && $currentVersion !== 'main') {
498 if (empty($mail->id)) {
499 $mail->subject = $versions['main']['subject'];
500 $mail->body = $versions['main']['content'];
501 $mail->preheader = $versions['main']['preview'];
502 $mail->settings = $versions['main']['settings'];
503 $mail->stylesheet = $versions['main']['stylesheet'];
504
505 $mailID = $mailClass->save($mail);
506 } else {
507 $mailID = $mail->id;
508 }
509 } else {
510 $mailID = $mailClass->save($mail);
511 }
512
513 if (empty($mailID)) {
514 if (!$ajax) {
515 acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
516 }
517
518 if (!empty($mailClass->errors)) {
519 if (!$ajax) acym_enqueueMessage($mailClass->errors, 'error');
520 }
521
522 return 0;
523 }
524
525 if (!empty($mail->type) && in_array($mail->type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
526 $listIds = acym_getVar('array', 'list_ids', []);
527 $listClass = new ListClass();
528 $listClass->setWelcomeUnsubEmail($listIds, (int)$mailID, $mail->type);
529 } elseif (!empty($mail->type) && $mail->type === MailClass::TYPE_FOLLOWUP) {
530 // Pass the new email ID in the return URL to ask user if we should add it to the queue
531 acym_setVar('return', acym_getVar('string', 'return').'&newEmailId='.$mailID);
532
533 $followupData = acym_getVar('array', 'followup', []);
534 $followupClass = new FollowupClass();
535 if (!$followupClass->saveDelaySettings($followupData, $mailID)) {
536 acym_enqueueMessage(acym_translation('ACYM_COULD_NOT_SAVE_DELAY_SETTINGS'), 'error');
537 }
538 if (!empty($followupData['id'])) {
539 acym_setVar('followup_id', $followupData['id']);
540 }
541 }
542
543 if (!$ajax) {
544 acym_enqueueMessage(acym_translation('ACYM_SUCCESSFULLY_SAVED'));
545 }
546
547 if ($fromAutomation) {
548 acym_setVar('type', MailClass::TYPE_AUTOMATION);
549 acym_setVar('type_editor', 'acyEditor');
550 } else {
551 acym_setVar('mailID', $mailID);
552 }
553
554 if (!empty($versions) && in_array($versionType, ['multilingual', 'abtest']) && $saveAsTmpl !== 1) {
555 $abTestSendingParams = [];
556
557 unset($versions['main']);
558 foreach ($versions as $code => $version) {
559 if (empty($version['subject'])) {
560 if ($versionType === 'multilingual') {
561 $mailClass->delete([$mailClass->getTranslationId($mailID, $code)]);
562 } elseif (!empty($abTestSendingParams[$code])) {
563 $mailClass->delete([$abTestSendingParams[$code]]);
564 }
565 continue;
566 }
567
568 unset($mail->id);
569 $versionId = null;
570 if ($versionType === 'multilingual') {
571 $versionId = $mailClass->getTranslationId($mailID, $code);
572 } elseif (!empty($abTestSendingParams[$code])) {
573 $versionId = $abTestSendingParams[$code];
574 }
575
576 if (!empty($versionId)) {
577 $mail->id = $versionId;
578 }
579
580 $mail->subject = $version['subject'];
581 $mail->preheader = $version['preview'];
582 $mail->body = $version['content'];
583 $mail->parent_id = $mailID;
584 $mail->settings = $version['settings'];
585 $mail->stylesheet = $version['stylesheet'];
586
587 if ($versionType === 'multilingual') {
588 $mail->links_language = $code;
589 $mail->language = $code;
590 }
591
592 $abTestSendingParams[$code] = $mailClass->save($mail);
593 }
594 }
595
596 return (int)$mailID;
597 }
598
599 private function setThumbnailFromInput(): string
600 {
601 $thumbnailFile = acym_getVar('array', 'custom_thumbnail', [], 'FILES');
602 if (empty($thumbnailFile['name'])) {
603 return '';
604 }
605
606 $extension = acym_fileGetExt($thumbnailFile['name']);
607
608 $thumbNb = $this->config->get('numberThumbnail', 2);
609 $filename = 'thumbnail_custom_'.($thumbNb + 1).'.'.$extension;
610 $this->config->saveConfig(['numberThumbnail' => $thumbNb + 1]);
611 $thumbnailFile['name'] = $filename;
612
613 ob_start();
614 $uploaded = acym_importFile($thumbnailFile, ACYM_UPLOAD_FOLDER_THUMBNAIL, true);
615 ob_end_clean();
616 if (!empty($uploaded)) {
617 return $uploaded;
618 }
619
620 acym_enqueueMessage(acym_translation('ACYM_UPLOADED_FILE_IS_NOT_IMAGE'), 'error');
621
622 return '';
623 }
624
625 public function setAttachmentToMail(object $mail): void
626 {
627 if (!empty($mail->id)) {
628 $mailClass = new MailClass();
629 $mail->attachments = $mailClass->getMailAttachments($mail->id);
630 }
631
632 if (!empty($mail->attachments)) {
633 if (!is_array($mail->attachments)) {
634 $mail->attachments = json_decode($mail->attachments, true);
635 }
636 } else {
637 $mail->attachments = [];
638 }
639
640 // Attachments
641 $newAttachments = [];
642 $attachments = acym_getVar('array', 'attachments', []);
643 if (!empty($attachments)) {
644 foreach ($attachments as $filepath) {
645 if (empty($filepath)) continue;
646
647 $attachment = [
648 'filename' => $filepath,
649 'size' => filesize(ACYM_ROOT.$filepath),
650 ];
651
652 //We will never allow some files to be uploaded...
653 if (acym_isForbiddenFileExtension($attachment['filename'])) {
654 acym_enqueueMessage(
655 acym_translationSprintf(
656 'ACYM_ACCEPTED_TYPE',
657 esc_html(substr($attachment['filename'], strrpos($attachment['filename'], '.') + 1)),
658 $this->config->get('allowed_files')
659 ),
660 'notice'
661 );
662 continue;
663 }
664
665 if (in_array($attachment, $mail->attachments)) continue;
666
667 $newAttachments[] = $attachment;
668 }
669 // Add to previous attachments
670 if (!empty($mail->attachments)) {
671 $newAttachments = array_merge($mail->attachments, $newAttachments);
672 }
673 $mail->attachments = $newAttachments;
674 }
675
676 if (empty($mail->attachments)) {
677 unset($mail->attachments);
678 } else {
679 $mail->attachments = json_encode($mail->attachments);
680 }
681 }
682
683 private function setThumbnailFrom(int $fromId): string
684 {
685 $thumbNb = $this->config->get('numberThumbnail', 2);
686 $fileName = 'thumbnail_'.($thumbNb + 1).'.png';
687 $this->config->saveConfig(['numberThumbnail' => $thumbNb + 1]);
688
689 $mailClass = new MailClass();
690 $fromMail = $mailClass->getOneById($fromId);
691 $fromThumbnail = $fromMail->thumbnail;
692
693 $ret = acym_createFolder(ACYM_UPLOAD_FOLDER_THUMBNAIL);
694 if (!$ret) {
695 return '';
696 }
697
698 $fromThumbnailSource = acym_fileGetContent(acym_getMailThumbnail($fromThumbnail));
699 if (empty($fromThumbnailSource)) {
700 return '';
701 }
702
703 file_put_contents(ACYM_UPLOAD_FOLDER_THUMBNAIL.$fileName, $fromThumbnailSource);
704
705 return $fileName;
706 }
707
708 public function apply(): void
709 {
710 $mailId = $this->store();
711 acym_setVar('id', $mailId);
712 $this->edit();
713 }
714
715 public function save(): void
716 {
717 $mailId = $this->store();
718
719 // When saving notifications, we return to page where we clicked the "Edit email" button
720 $return = str_replace(
721 '{mailid}',
722 empty($mailId) ? '' : $mailId,
723 acym_getVar('string', 'return', '')
724 );
725
726 if (empty($return)) {
727 $this->listing();
728 } else {
729 acym_redirect($return);
730 }
731 }
732
733 public function getTemplateAjax(): void
734 {
735 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
736
737 $pagination = new PaginationHelper();
738 $id = acym_getVar('int', 'id');
739 $id = empty($id) ? '' : '&id='.$id;
740 $searchFilter = acym_getVar('string', 'search', '');
741 $tagFilter = acym_getVar('string', 'tag', 0);
742 $ordering = 'creation_date';
743 $orderingSortOrder = 'DESC';
744 $type = acym_getVar('string', 'type', 'custom');
745 $automation = acym_getVar('boolean', 'automation', false);
746 $returnUrl = acym_getVar('string', 'return');
747 $returnUrl = empty($returnUrl) || 'undefined' == $returnUrl ? '' : '&return='.urlencode(base64_encode($returnUrl));
748 $fromMultilingual = acym_getVar('int', 'is_multilingual_edition', 0);
749
750 $mailsPerPage = $pagination->getListLimit();
751 $page = acym_getVar('int', 'pagination_page_ajax', 1);
752 if ($page === 'undefined') {
753 $page = 1;
754 }
755
756 $mailClass = new MailClass();
757 $matchingMails = $mailClass->getMatchingElements(
758 [
759 'ordering' => $ordering,
760 'ordering_sort_order' => $orderingSortOrder,
761 'search' => $searchFilter,
762 'elementsPerPage' => $mailsPerPage,
763 'offset' => ($page - 1) * $mailsPerPage,
764 'tag' => $tagFilter,
765 'automation' => $automation,
766 'onlyStandard' => true,
767 'creator_id' => $this->setFrontEndParamsForTemplateChoose(),
768 'drag_editor' => !empty($fromMultilingual),
769 'gettingTemplates' => !$automation,
770 ]
771 );
772
773 $return = '<div class="grid-x grid-padding-x grid-padding-y grid-margin-x grid-margin-y xxlarge-up-6 large-up-4 medium-up-3 small-up-1 cell acym__template__choose__list margin-top-1">';
774
775 $followup_id = '';
776 if ($type == MailClass::TYPE_FOLLOWUP) {
777 $followup_id = acym_getVar('int', 'followup_id', 0);
778 }
779 $listId = 0;
780 if (in_array($type, [MailClass::TYPE_WELCOME, MailClass::TYPE_UNSUBSCRIBE])) {
781 $listId = acym_getVar('int', 'list_id', 0);
782 }
783 foreach ($matchingMails['elements'] as $oneTemplate) {
784 $return .= '<div class="cell grid-x acym__templates__oneTpl acym__listing__block" id="'.esc_attr($oneTemplate->id).'">
785 <div class="cell acym__templates__pic text-center">';
786
787 $url = acym_getVar('cmd', 'ctrl').'&task=edit&step=editEmail&from='.intval($oneTemplate->id).$returnUrl.'&type='.$type.$id.'&'.acym_getFormToken();
788 if (!empty($followup_id)) {
789 $url .= '&followup_id='.$followup_id;
790 }
791 if (!empty($listId)) {
792 $url .= '&list_id='.$listId;
793 }
794 if (!empty($this->data['campaignInformation'])) {
795 $url .= '&id='.intval($this->data['campaignInformation']);
796 }
797 if (!$automation || !empty($returnUrl)) {
798 $return .= '<a href="'.esc_url(acym_completeLink($url, false, false, true)).'">';
799 }
800
801 $return .= '<img src="'.esc_url(acym_getMailThumbnail($oneTemplate->thumbnail)).'" alt="template thumbnail"/>';
802 if (!$automation || !empty($returnUrl)) {
803 $return .= '</a>';
804 }
805
806 if ($oneTemplate->drag_editor) {
807 $return .= '<div class="acym__templates__choose__ribbon acyeditor">'.esc_html(acym_translation('ACYM_DD_EDITOR')).'</div>';
808 } else {
809 $return .= '<div class="acym__templates__choose__ribbon htmleditor">'.esc_html(acym_translation('ACYM_HTML_EDITOR')).'</div>';
810 }
811
812 if (strlen($oneTemplate->name) > 55) {
813 $oneTemplate->name = substr($oneTemplate->name, 0, 50).'...';
814 }
815 $return .= '</div>
816 <div class="cell grid-x acym__templates__footer text-center">
817 <div class="cell acym__templates__footer__title acym_text_ellipsis" title="'.esc_attr($oneTemplate->name).'">';
818 $return .= esc_html($oneTemplate->name).'</div>
819 <div class="cell">'.esc_html(acym_date($oneTemplate->creation_date, 'ACYM_DATE_FORMAT_LC3')).'</div>
820 </div>
821 </div>';
822 }
823
824 $return .= '</div>';
825
826 $pagination->setStatus((int)$matchingMails['total']->total, $page, $mailsPerPage);
827
828 ob_start();
829 $pagination->display('', '__ajax');
830 $return .= ob_get_clean();
831
832 acym_sendAjaxResponse('', ['pagination' => $return]);
833 exit;
834 }
835
836 public function saveAjax(): void
837 {
838 $mailId = $this->store(true);
839
840 if (!empty($mailId)) {
841 acym_sendAjaxResponse('', ['result' => $mailId]);
842 } else {
843 acym_sendAjaxResponse(acym_translation('ACYM_ERROR_SAVING'), [], false);
844 }
845 }
846
847 public function loadCSS(): void
848 {
849 header('Content-Type: text/css');
850 $idMail = acym_getVar('int', 'id', 0);
851 if (empty($idMail)) {
852 exit;
853 }
854
855 $mailClass = new MailClass();
856 $mail = $mailClass->getOneById($idMail);
857
858 if (empty($mail)) {
859 exit;
860 }
861
862 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Returning content as text/css, need to output raw content.
863 echo $mailClass->buildCSS($mail->stylesheet);
864 exit;
865 }
866
867 /*
868 * Method used to send a test when editing a notification email
869 */
870 public function test(): void
871 {
872 $mailId = $this->store();
873 $return = acym_getVar('string', 'return', '');
874 acym_setVar('return', $return);
875 acym_setVar('id', $mailId);
876
877 $mailClass = new MailClass();
878 $mail = $mailClass->getOneById($mailId);
879
880 if (empty($mail)) {
881 acym_enqueueMessage(acym_translation('ACYM_CAMPAIGN_NOT_FOUND'), 'error');
882 $this->edit();
883
884 return;
885 }
886
887 $mailerHelper = new MailerHelper();
888 $mailerHelper->autoAddUser = true;
889 $mailerHelper->report = false;
890
891 $currentEmail = acym_currentUserEmail();
892 $options = ['isTest' => true];
893 if ($mailerHelper->sendOne($mailId, $currentEmail, $options)) {
894 acym_enqueueMessage(acym_translationSprintf('ACYM_SEND_SUCCESS', $mail->name, $currentEmail), 'info');
895 } else {
896 $notification = [
897 'name' => 'send_error',
898 'removable' => 1,
899 ];
900 acym_enqueueMessage(acym_translationSprintf('ACYM_SEND_ERROR', $mail->name, $currentEmail), 'error', true, [$notification]);
901 }
902
903 $this->edit();
904 }
905
906 protected function setFrontEndParamsForTemplateChoose(): int
907 {
908 return 0;
909 }
910
911 public function saveAsTmplAjax(): void
912 {
913 $mailId = $this->store(true);
914 acym_sendAjaxResponse(!empty($mailId) ? '' : acym_translation('ACYM_ERROR_SAVING'), ['result' => $mailId], !empty($mailId));
915 }
916 }
917