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 / Configuration / Listing.php

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

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