PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.0.4
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.0.4
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 / Configuration / Listing.php

Listing.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 11.0.4, at back/Controllers/Configuration/Listing.php

635 lines 21.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\Configuration;
4
5 use AcyMailing\Classes\FieldClass;
6 use AcyMailing\Classes\ListClass;
7 use AcyMailing\Classes\MailClass;
8 use AcyMailing\Helpers\EncodingHelper;
9 use AcyMailing\Helpers\MailerHelper;
10 use AcyMailing\Helpers\TabHelper;
11 use AcyMailing\Helpers\ToolbarHelper;
12 use AcyMailing\Helpers\UpdatemeHelper;
13 use AcyMailing\Types\AclType;
14 use AcyMailing\Types\DelayType;
15 use AcyMailing\Types\FailActionType;
16
17 trait Listing
18 {
19 public function listing(): void
20 {
21 acym_setVar('layout', 'listing');
22
23 // We check if we have to store a token from an OAuth provider
24 $this->handleOauthAuthentication();
25
26 $data = [];
27 $data['tab'] = new TabHelper();
28 $this->prepareLanguages($data);
29 $this->prepareLists($data);
30 $this->prepareNotifications($data);
31 $this->prepareAcl($data);
32 $this->prepareClass($data);
33 $this->prepareDataTab($data);
34 $this->prepareSecurity($data);
35 $this->checkConfigMail();
36 $this->prepareToolbar($data);
37 $this->prepareHoursMinutes($data);
38 $this->resetQueueProcess();
39
40 $this->prepareMailSettings($data);
41 $this->prepareMultilingualOption($data);
42
43 $this->loadSurveyAnswers($data);
44
45 parent::display($data);
46 }
47
48 private function checkConfigMail(): void
49 {
50 $queueType = $this->config->get('queue_type');
51 $batchesNumber = $this->config->get('queue_batch_auto', 1);
52 $emailsPerBatch = $this->config->get('queue_nbmail_auto', 70);
53 $cronFrequency = $this->config->get('cron_frequency', 900);
54 if ($queueType !== 'manual') {
55 if (($batchesNumber > 1 || $cronFrequency < 900) && !function_exists('curl_multi_exec')) {
56 $notification = [
57 'name' => 'curl_multi_exec',
58 'removable' => 0,
59 ];
60 acym_enqueueMessage(acym_translation('ACYM_NEED_CURL_MULTI'), 'error', true, [$notification]);
61 } elseif ($batchesNumber <= 1 && $cronFrequency >= 900) {
62 acym_removeDashboardNotification('curl_multi_exec');
63 }
64
65 $remindme = json_decode($this->config->get('remindme', '[]'), true);
66 if (!in_array('sendoverload', $remindme) && ($batchesNumber > 4 || $emailsPerBatch > 300 || $cronFrequency < 300)) {
67 $text = acym_translation('ACYM_SEND_CONFIGURATION_WARNING');
68 $text .= '<p class="acym__do__not__remindme" title="sendoverload">'.acym_translation('ACYM_DO_NOT_REMIND_ME').'</p>';
69 $notification = [
70 'name' => 'sendoverload',
71 'removable' => 1,
72 ];
73 acym_enqueueMessage($text, 'warning', true, [$notification]);
74 } else {
75 acym_removeDashboardNotification('sendoverload');
76 }
77 }
78 }
79
80 private function prepareMailSettings(array &$data): void
81 {
82 $data['sendingMethodsType'] = [
83 'server' => acym_translation('ACYM_USING_YOUR_SERVER'),
84 'external' => acym_translation('ACYM_USING_AN_EXTERNAL_SERVER'),
85 ];
86
87 $data['sendingMethods'] = [];
88 acym_trigger('onAcymGetSendingMethods', [&$data]);
89 acym_trigger('onAcymGetSendingMethodsSelected', [&$data]);
90
91 $data['sendingMethodsHtmlSettings'] = [];
92 acym_trigger('onAcymGetSendingMethodsHtmlSetting', [&$data]);
93
94 $data['embedImage'] = [];
95 $data['embedAttachment'] = [];
96 acym_trigger('onAcymSendingMethodOptions', [&$data]);
97 }
98
99 public function prepareToolbar(array &$data): void
100 {
101 $toolbarHelper = new ToolbarHelper();
102 $toolbarHelper->addButton(
103 acym_translation('ACYM_SEND_TEST'),
104 [
105 'data-before-action' => 'configSave',
106 'data-task' => 'test',
107 ]
108 );
109 $toolbarHelper->addButton(
110 acym_translation('ACYM_SAVE'),
111 [
112 'data-before-action' => 'configSave',
113 'data-task' => 'save',
114 ],
115 '',
116 true
117 );
118
119 $data['toolbar'] = $toolbarHelper;
120 }
121
122 private function prepareClass(array &$data): void
123 {
124 $data['typeDelay'] = new DelayType();
125 $data['failaction'] = new FailActionType();
126 $data['encodingHelper'] = new EncodingHelper();
127 }
128
129 private function prepareLanguages(array &$data): void
130 {
131 $langs = acym_getLanguages();
132 $data['languages'] = [];
133
134 foreach ($langs as $lang => $obj) {
135 if ($lang === 'xx-XX') {
136 continue;
137 }
138
139 $oneLanguage = new \stdClass();
140 $oneLanguage->language = $lang;
141 $oneLanguage->name = $obj->name;
142 $oneLanguage->icon = $obj->exists ? 'edit' : 'add';
143
144 $data['languages'][] = $oneLanguage;
145 }
146
147 usort(
148 $data['languages'],
149 function ($a, $b) {
150 return strtolower($a->name) > strtolower($b->name) ? 1 : -1;
151 }
152 );
153
154
155 $data['content_translation'] = acym_getTranslationTools();
156
157 $data['user_languages'] = array_merge(
158 [
159 (object)['language' => 'current_language', 'name' => acym_translation('ACYM_BROWSING_LANGUAGE')],
160 ],
161 $data['languages']
162 );
163 }
164
165 private function prepareLists(array &$data): void
166 {
167 $listClass = new ListClass();
168 try {
169 $lists = $listClass->getAllWithoutManagement();
170 } catch (\Exception $exception) {
171 $lists = [];
172 }
173 foreach ($lists as $i => $oneList) {
174 if ($oneList->active == 0) {
175 unset($lists[$i]);
176 }
177 }
178 $data['lists'] = $lists;
179 }
180
181 private function prepareNotifications(array &$data): void
182 {
183 $data['notifications'] = [
184 'acy_notification_create' => [
185 'label' => 'ACYM_NOTIFICATION_CREATE',
186 'tooltip' => '',
187 ],
188 'acy_notification_unsub' => [
189 'label' => 'ACYM_NOTIFICATION_UNSUB',
190 'tooltip' => '',
191 ],
192 'acy_notification_unsuball' => [
193 'label' => 'ACYM_NOTIFICATION_UNSUBALL',
194 'tooltip' => '',
195 ],
196 'acy_notification_subform' => [
197 'label' => 'ACYM_NOTIFICATION_SUBFORM',
198 'tooltip' => '',
199 ],
200 'acy_notification_profile' => [
201 'label' => 'ACYM_NOTIFICATION_PROFILE',
202 'tooltip' => '',
203 ],
204 'acy_notification_confirm' => [
205 'label' => 'ACYM_NOTIFICATION_CONFIRM',
206 'tooltip' => '',
207 ],
208 ];
209 }
210
211 private function prepareAcl(array &$data): void
212 {
213 $data['adminPermissions'] = acym_hasAdminPermissions();
214 $data['acl_advanced'] = acym_getPagesForAcl();
215 $data['aclType'] = new AclType();
216 }
217
218 private function prepareSecurity(array &$data): void
219 {
220 $data['wp_mail_smtp_installed'] = ACYM_CMS === 'wordpress' && acym_isExtensionActive('wp-mail-smtp/wp_mail_smtp.php');
221 $data['acychecker_installed'] = acym_isAcyCheckerInstalled();
222 $data['acychecker_get_link'] = ACYM_ACYCHECKER_WEBSITE.'?utm_source=acymailing_plugin&utm_campaign=get_acychecker&utm_medium=button_configuration_security';
223
224 $data['level'] = acym_level(ACYM_ESSENTIAL);
225
226 $captchaOptions = array_replace(
227 [
228 'none' => acym_translation('ACYM_NONE'),
229 'acym_hcaptcha' => acym_translation('ACYM_HCAPTCHA'),
230 'acym_ireCaptcha' => acym_translation('ACYM_CAPTCHA_INVISIBLE'),
231 'acym_reCaptcha_v3' => acym_translation('ACYM_CAPTCHA_V3'),
232 ],
233 acym_getCmsCaptcha()
234 );
235
236 $data['captchaOptions'] = $captchaOptions;
237
238 if (!acym_level(ACYM_ESSENTIAL)) {
239 $data['captchaOptions'] = [];
240 }
241 }
242
243 private function prepareDataTab(array &$data): void
244 {
245 $fieldClass = new FieldClass();
246 $data['fields'] = $fieldClass->getAll();
247
248 $data['export_data_changes_fields'] = $this->config->get('export_data_changes_fields', []);
249 if (!is_array($data['export_data_changes_fields'])) {
250 $data['export_data_changes_fields'] = explode(',', $data['export_data_changes_fields']);
251 }
252 }
253
254 private function prepareHoursMinutes(array &$data): void
255 {
256 $listHours = [];
257 for ($i = 0; $i < 24; $i++) {
258 $value = $i < 10 ? '0'.$i : $i;
259 $listHours[] = acym_selectOption($value, $value);
260 }
261 $listMinutes = [];
262 for ($i = 0; $i < 60; $i += 5) {
263 $value = $i < 10 ? '0'.$i : $i;
264 $listMinutes[] = acym_selectOption($value, $value);
265 }
266 $listAllMinutes = [];
267 for ($i = 0; $i < 60; $i++) {
268 $value = $i < 10 ? '0'.$i : $i;
269 $listAllMinutes[] = acym_selectOption($value, $value);
270 }
271 $data['listHours'] = $listHours;
272 $data['listMinutes'] = $listMinutes;
273 $data['listAllMinutes'] = $listAllMinutes;
274 }
275
276 private function handleEmails(array &$formData): void
277 {
278 $formData['from_email'] = acym_strtolower($formData['from_email']);
279 $formData['replyto_email'] = acym_strtolower($formData['replyto_email']);
280 $formData['bounce_email'] = acym_strtolower($formData['bounce_email']);
281 }
282
283 public function store(): void
284 {
285 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
286
287 $formData = acym_getVar('array', 'config', []);
288 if (empty($formData)) {
289 return;
290 }
291
292 $this->handleReplyTo($formData);
293 $this->handleWordWrap($formData);
294 $this->handleQueueSettings($formData);
295 $this->handleDemoSite($formData);
296 $this->handleAcl($formData);
297 $this->handleSelect2Fields($formData);
298 $this->handleAcyChecker($formData);
299 $this->handleNewDkim($formData);
300 $this->handleEmails($formData);
301 $this->handleUnsubSurvey($formData);
302
303 acym_trigger('onBeforeSaveConfigFields', [&$formData]);
304
305 // Don't move this line in the if, we need to do it before the save
306 $licenseKeyBeforeSave = $this->config->get('license_key');
307
308 if ($this->config->saveConfig($formData)) {
309 $this->handleWebsiteLinking($formData, $licenseKeyBeforeSave);
310
311 acym_enqueueMessage(acym_translation('ACYM_SUCCESSFULLY_SAVED'));
312 } else {
313 acym_enqueueMessage(acym_translation('ACYM_ERROR_SAVING'), 'error');
314 }
315
316 $this->handleMultilingual($formData);
317
318 $this->config->load();
319 }
320
321 private function handleReplyTo(array &$formData): void
322 {
323 if ($formData['from_as_replyto'] == 1) {
324 if (isset($formData['from_name'])) {
325 $formData['replyto_name'] = $formData['from_name'];
326 }
327 $formData['replyto_email'] = $formData['from_email'];
328 }
329 }
330
331 private function handleWordWrap(array &$formData): void
332 {
333 if (empty($formData['mailer_wordwrap']) || $formData['mailer_wordwrap'] < 0) {
334 $formData['mailer_wordwrap'] = 0;
335 }
336
337 if ($formData['mailer_wordwrap'] > 998) {
338 $formData['mailer_wordwrap'] = 998;
339 }
340 }
341
342 private function handleQueueSettings(array &$formData): void
343 {
344 $currentTaskId = (int)$this->config->get('scheduled_task_id');
345 $frequency = (int)$formData['cron_frequency'];
346
347 //TODO maybe also handle 15min cron like this
348 if (
349 !acym_level(ACYM_ESSENTIAL)
350 || $formData['queue_type'] === 'manual'
351 || empty($frequency)
352 || $frequency === 900
353 || !acym_isLicenseValidWeekly()
354 ) {
355 acym_deleteScheduledTask(
356 [
357 'taskId' => $currentTaskId,
358 'type' => 'plg_task_requests_task_get',
359 'name' => self::CRON_TASK_NAME,
360 ]
361 );
362 $formData['scheduled_task_id'] = 0;
363
364 return;
365 }
366
367 $taskId = acym_scheduleTask(
368 [
369 'title' => 'AcyMailing – Automated tasks',
370 'type' => 'plg_task_requests_task_get',
371 'frequencyInMinutes' => $frequency / 60,
372 'name' => self::CRON_TASK_NAME,
373 'taskFrequency' => 'every_minute',
374 'taskId' => $currentTaskId,
375 'config' => $formData,
376 ]
377 );
378
379 if (!empty($taskId) && ACYM_CMS === 'joomla') {
380 $formData['scheduled_task_id'] = $taskId;
381 }
382 }
383
384 private function handleDemoSite(array &$formData): void
385 {
386 }
387
388 private function handleAcl(array &$formData): void
389 {
390 if (ACYM_PRODUCTION && acym_hasAdminPermissions()) {
391 $aclPages = array_keys(acym_getPagesForAcl());
392 foreach ($aclPages as $page) {
393 if (empty($formData['acl_'.$page])) {
394 $formData['acl_'.$page] = [ACYM_ADMIN_GROUP];
395 }
396 }
397 }
398 }
399
400 private function handleSelect2Fields(array &$formData): void
401 {
402 $select2Fields = [
403 'regacy_lists',
404 'regacy_checkedlists',
405 'regacy_autolists',
406 'acy_notification_create',
407 'acy_notification_unsub',
408 'acy_notification_unsuball',
409 'acy_notification_subform',
410 'acy_notification_profile',
411 'acy_notification_confirm',
412 'multilingual_languages',
413 'allowed_hosts',
414 'unsub_survey',
415 ];
416
417 if (acym_hasAdminPermissions()) {
418 $select2Fields[] = 'wp_access';
419 }
420
421 foreach ($select2Fields as $oneField) {
422 if ($oneField === 'unsub_survey' && !empty($formData[$oneField])) {
423 $formData[$oneField] = json_encode($formData[$oneField]);
424 }
425
426 if (empty($formData[$oneField])) {
427 $formData[$oneField] = [];
428 }
429 }
430 }
431
432 private function handleAcyChecker(array &$formData): void
433 {
434 if (empty($formData['email_verification'])) {
435 return;
436 }
437
438 $disabledOptions = true;
439 $verificationOptions = [
440 'email_verification_non_existing',
441 'email_verification_disposable',
442 'email_verification_free',
443 'email_verification_role',
444 'email_verification_acceptall',
445 ];
446
447 foreach ($verificationOptions as $oneOption) {
448 if (!empty($formData[$oneOption])) {
449 $disabledOptions = false;
450 }
451 }
452
453 if ($disabledOptions) {
454 $formData['email_verification'] = false;
455 acym_enqueueMessage(acym_translation('ACYM_ACYCHECKER_AUTO_DISABLED'), 'info');
456 }
457 }
458
459 private function handleNewDkim(array &$formData): void
460 {
461 // The user set DKIM as disabled
462 if (empty($formData['dkim'])) {
463 return;
464 }
465
466 $privateKey = $this->config->get('dkim_private');
467 $publicKey = $this->config->get('dkim_public');
468
469 // We're manually submitting keys
470 if (!empty($formData['dkim_private']) || !empty($formData['dkim_public'])) {
471 return;
472 }
473
474 // We don't submit keys and stored keys are not empty
475 if (!isset($formData['dkim_private']) && !empty($privateKey) && !empty($publicKey)) {
476 return;
477 }
478
479 $newDkimKeys = UpdatemeHelper::call('public/dkim');
480 if (empty($newDkimKeys['private_key'])) {
481 return;
482 }
483
484 $formData['dkim_private'] = $newDkimKeys['private_key'];
485 $formData['dkim_public'] = $newDkimKeys['public_key'];
486 }
487
488 private function handleWebsiteLinking(array $formData, string $licenseKeyBeforeSave): void
489 {
490 $isLicenseKeyUpdated = isset($formData['license_key']) && $licenseKeyBeforeSave !== $formData['license_key'];
491
492 if ($isLicenseKeyUpdated && ACYM_PRODUCTION) {
493 // If we add a key or edit it, we try to attach it
494 if (!empty($formData['license_key'])) {
495 $resultAttachLicenseOnUpdateMe = $this->attachLicenseOnUpdateMe($formData['license_key']);
496
497 if (!empty($resultAttachLicenseOnUpdateMe['message'])) {
498 $this->displayMessage($resultAttachLicenseOnUpdateMe['message']);
499 }
500 } else {
501 // If we remove a key, we try to unlink it
502 $resultUnlinkLicenseOnUpdateMe = $this->unlinkLicenseOnUpdateMe($licenseKeyBeforeSave);
503
504 if (!empty($resultUnlinkLicenseOnUpdateMe['message'])) {
505 $this->displayMessage($resultUnlinkLicenseOnUpdateMe['message']);
506 }
507 }
508
509 UpdatemeHelper::getLicenseInfo();
510 }
511 }
512
513 private function handleMultilingual(array $formData): void
514 {
515 // Remove unused email translations
516 $removed = array_diff(
517 explode(',', acym_getVar('string', 'previous_multilingual_languages', '')),
518 $formData['multilingual_languages']
519 );
520
521 if (!empty($removed)) {
522 $mailClass = new MailClass();
523 $mailClass->deleteByTranslationLang($removed);
524 }
525 }
526
527 public function test(): void
528 {
529 $this->store();
530
531 $mailerHelper = new MailerHelper();
532 $addedName = $this->config->get('add_names', true) ? $mailerHelper->cleanText(acym_currentUserName()) : '';
533
534 $mailerHelper->AddAddress(acym_currentUserEmail(), $addedName);
535 $mailerHelper->Subject = 'Test e-mail from '.ACYM_LIVE;
536 $mailerHelper->Body = acym_translation('ACYM_TEST_EMAIL');
537 $mailerHelper->SMTPDebug = 1;
538 $mailerHelper->isTest = true;
539 //We set the full error reporting if we are in debug mode
540 if (acym_isDebug()) {
541 $mailerHelper->SMTPDebug = 2;
542 }
543
544 $mailerHelper->isHTML(false);
545 $result = $mailerHelper->send();
546
547 if (!$result) {
548 $sendingMethod = $this->config->get('mailer_method');
549
550 if ($sendingMethod === 'smtp') {
551 if ($this->config->get('smtp_secured') === 'ssl' && !function_exists('openssl_sign')) {
552 acym_enqueueMessage(acym_translation('ACYM_OPENSSL'), 'notice');
553 }
554
555 if (!$this->config->get('smtp_auth') && strlen($this->config->get('smtp_password')) > 1) {
556 acym_enqueueMessage(acym_translation('ACYM_ADVICE_SMTP_AUTH'), 'notice');
557 }
558
559 if ($this->config->get('smtp_port') && !in_array($this->config->get('smtp_port'), [25, 2525, 465, 587])) {
560 acym_enqueueMessage(acym_translationSprintf('ACYM_ADVICE_PORT', $this->config->get('smtp_port')), 'notice');
561 }
562 }
563
564 if (acym_isLocalWebsite() && in_array($sendingMethod, ['sendmail', 'qmail', 'mail'])) {
565 acym_enqueueMessage(acym_translation('ACYM_ADVICE_LOCALHOST'), 'notice');
566 }
567
568 $creditsLeft = 10000;
569 acym_trigger('onAcymCreditsLeft', [&$creditsLeft]);
570
571 $bounce = $this->config->get('bounce_email');
572 if (!empty($creditsLeft) && !empty($bounce) && !in_array($sendingMethod, ['smtp', 'elasticemail'])) {
573 acym_enqueueMessage(acym_translationSprintf('ACYM_ADVICE_BOUNCE', '<b>'.$bounce.'</b>'), 'notice');
574 }
575 }
576
577 $this->listing();
578 }
579
580 public function handleUnsubSurvey(array &$formData): void
581 {
582 if (isset($formData['unsub_survey'])) {
583 $unsubSurvey = json_decode($formData['unsub_survey'], true);
584 if (is_array($unsubSurvey)) {
585 foreach ($unsubSurvey as $key => $value) {
586 if (is_string($value)) {
587 $unsubSurvey[$key] = acym_stripTags($value);
588 }
589 }
590 $formData['unsub_survey'] = json_encode($unsubSurvey);
591 }
592 }
593
594 if (isset($formData['unsub_survey_translation'])) {
595 $unsubSurveyTranslation = json_decode($formData['unsub_survey_translation'], true);
596 if (is_array($unsubSurveyTranslation)) {
597 foreach ($unsubSurveyTranslation as $lang => $unsubSurvey) {
598 if (is_array($unsubSurvey) && isset($unsubSurvey['unsub_survey'])) {
599 foreach ($unsubSurvey['unsub_survey'] as $key => $value) {
600 if (is_string($value)) {
601 $unsubSurveyTranslation[$lang]['unsub_survey'][$key] = acym_stripTags($value);
602 }
603 }
604 }
605 }
606 $formData['unsub_survey_translation'] = json_encode($unsubSurveyTranslation);
607 }
608 }
609 }
610
611 private function resetQueueProcess(): void
612 {
613 if (!acym_level(ACYM_ESSENTIAL) && $this->config->get('queue_type', 'manual') !== 'manual') {
614 $this->config->saveConfig(['queue_type' => 'manual']);
615 }
616 }
617
618
619 public function addNewSml(): void
620 {
621 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
622
623 acym_trigger('onConfigurationAddSml');
624 $this->listing();
625 }
626
627 public function deleteSml(): void
628 {
629 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
630
631 acym_trigger('onConfigurationDeleteSml');
632 $this->listing();
633 }
634 }
635