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/Core/AcymController.php +75 -25 10.10.2 → 11.1.0 View file →
@@ -1,10 +1,8 @@
1 1 <?php
2 2
3 3 namespace AcyMailing\Core;
4 4
5 -use AcyMailing\Helpers\HeaderHelper;
6 -
7 5 abstract class AcymController extends AcymObject
8 6 {
9 7 private $currentClass = null;
10 8 private string $sessionName;
@@ -45,14 +43,19 @@
45 43 }
46 44
47 45 private function initSession(): void
48 46 {
49 - acym_session();
50 - if (empty($_SESSION[$this->sessionName])) {
51 - $_SESSION[$this->sessionName] = [];
47 + $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
48 + if (empty($controllerSession)) {
49 + acym_setSession($this->sessionName, []);
52 50 }
53 51 }
54 52
53 + /**
54 + * @param mixed $default
55 + *
56 + * @return mixed
57 + */
55 58 public function getVarFiltersListing(string $type, string $varName, $default, bool $overrideIfNull = false)
56 59 {
57 60 if ($this->taskCalled === 'clearFilters') {
58 61 return $default;
@@ -58,20 +61,27 @@
58 61 return $default;
59 62 }
60 63
61 64 $this->initSession();
62 - $returnValue = acym_getVar($type, $varName);
63 65
64 - if (is_null($returnValue) && $overrideIfNull) $returnValue = $default;
66 + $isVarInRequest = !is_null(acym_getVar('raw', $varName, null, '', ACYM_ALLOWRAW));
67 + $returnValue = $isVarInRequest ? acym_getVar($type, $varName) : null;
65 68
69 + if (is_null($returnValue) && $overrideIfNull) {
70 + $returnValue = $default;
71 + }
72 +
66 73 if (!is_null($returnValue)) {
67 - $_SESSION[$this->sessionName][$varName] = $returnValue;
74 + $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
75 + $controllerSession[$varName] = $returnValue;
76 + acym_setSession($this->sessionName, $controllerSession);
68 77
69 78 return $returnValue;
70 79 }
71 80
72 - if (!empty($_SESSION[$this->sessionName][$varName])) {
73 - return $_SESSION[$this->sessionName][$varName];
81 + $filters = acym_getVar('array', $this->sessionName, [], 'SESSION');
82 + if (!empty($filters[$varName])) {
83 + return $filters[$varName];
74 84 }
75 85
76 86 return $default;
77 87 }
@@ -79,15 +89,19 @@
79 89 public function setVarFiltersListing(string $varName, int $value): void
80 90 {
81 91 acym_setVar($varName, $value);
82 92 $this->initSession();
83 - $_SESSION[$this->sessionName][$varName] = $value;
93 + $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
94 + $controllerSession[$varName] = $value;
95 + acym_setSession($this->sessionName, $controllerSession);
84 96 }
85 97
98 + /**
99 + * Called using data-task
100 + */
86 101 public function clearFilters(): void
87 102 {
88 - $this->initSession();
89 - $_SESSION[$this->sessionName] = [];
103 + acym_setSession($this->sessionName, []);
90 104
91 105 $taskToCall = acym_getVar('string', 'cleartask', $this->defaulttask);
92 106 if (in_array($taskToCall, ['campaigns_auto', 'welcome', 'unsubscribe', $this->defaulttask])) {
93 107 $this->call($taskToCall);
@@ -95,9 +109,12 @@
95 109 }
96 110
97 111 public function call(string $task, bool $isFront = false): void
98 112 {
99 - if (!in_array($task, $this->publicFrontTasks, true) && !acym_isAllowed($this->name, $task) && $this->name !== 'dashboard') {
113 + if (
114 + !in_array($task, $this->publicFrontTasks, true)
115 + && !acym_isAllowed($this->name, $task)
116 + ) {
100 117 acym_enqueueMessage(acym_translation('ACYM_ACCESS_DENIED'), 'warning');
101 118 acym_redirect($isFront ? ACYM_LIVE : acym_completeLink('dashboard'));
102 119
103 120 return;
@@ -102,14 +119,16 @@
102 119
103 120 return;
104 121 }
105 122
106 - if (!method_exists($this, $task)) {
123 + // If task doesn't exist, redirect to default task + add message
124 + if (!is_callable([$this, $task])) {
107 125 acym_enqueueMessage(acym_translation('ACYM_NON_EXISTING_PAGE'), 'warning');
108 126 $task = $this->defaulttask;
109 127 acym_setVar('task', $task);
110 128 }
111 129
130 + // Call the task
112 131 $this->$task();
113 132 }
114 133
115 134 public function loadScripts(string $task): void
@@ -130,8 +149,16 @@
130 149 if (in_array('editor-wysid', $scripts)) {
131 150 acym_addStyle(false, ACYM_CSS.'editorWYSID.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'editorWYSID.min.css'));
132 151 acym_addScript(false, ACYM_JS.'editor_wysid_utils.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'editor_wysid_utils.min.js'));
133 152
153 + acym_addScript(
154 + true,
155 + 'const ACYM_UNSPLASH_KEY = "'.addslashes($this->config->get('unsplash_key', '')).'";
156 + const ACYM_GIPHY_KEY = "'.addslashes($this->config->get('giphy_key', '')).'";
157 + const ACYM_SAVE_THUMBNAIL = '.(acym_isAdmin() ? (int)$this->config->get('save_thumbnail', 0) : 0).';'
158 + );
159 +
160 + // Automatically add editor dependencies
134 161 $scripts = array_merge($scripts, ['colorpicker', 'datepicker', 'thumbnail', 'foundation-email', 'parse-css', 'vue-prism-editor', 'masonry']);
135 162
136 163 if (empty($scripts['vue-applications'])) {
137 164 $scripts['vue-applications'] = ['code_editor'];
@@ -149,12 +176,14 @@
149 176 acym_addStyle(false, ACYM_CSS.'libraries/spectrum.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'spectrum.min.css'));
150 177 }
151 178
152 179 if (in_array('datepicker', $scripts)) {
153 - acym_addScript(false, ACYM_JS.'libraries/moment.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'moment.min.js'));
154 - acym_addScript(false, ACYM_JS.'libraries/rome.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'rome.min.js'));
155 - acym_addScript(false, ACYM_JS.'libraries/material-datetime-picker.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'material-datetime-picker.min.js'));
156 - acym_addStyle(false, ACYM_CSS.'libraries/material-datetime-picker.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'material-datetime-picker.min.css'));
180 + if (ACYM_CMS === 'joomla') {
181 + acym_addScript(false, ACYM_JS.'libraries/moment.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'moment.min.js'));
182 + } else {
183 + wp_enqueue_script('moment');
184 + }
185 + acym_addScript(true, 'window.ACYM_DATE_NOW = "'.gmdate('Y-m-d\TH:i', time() + acym_getTimeOffsetCMS()).'";');
157 186 }
158 187
159 188 if (in_array('dtextPicker', $scripts)) {
160 189 acym_addScript(false, ACYM_JS.'dtext_picker.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'dtext_picker.min.js'));
@@ -178,10 +207,12 @@
178 207 acym_addScript(false, ACYM_JS.'libraries/masonry.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'masonry.min.js'));
179 208 }
180 209
181 210 if (!empty($scripts['vue-applications'])) {
211 + //vuejs javascript library
182 212 acym_addScript(false, ACYM_JS.'libraries/vuejs.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'vuejs.min.js'));
183 213 acym_addScript(false, ACYM_JS.'libraries/vue-infinite-scroll.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'vue-infinite-scroll.min.js'));
214 + //All the component created to use in vue app (ex: select2 component)
184 215 acym_addScript(false, ACYM_JS.'vue/vue_components.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'vue'.DS.'vue_components.min.js'));
185 216 foreach ($scripts['vue-applications'] as $script) {
186 217 acym_addScript(false, ACYM_JS.'vue/'.$script.'.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'vue'.DS.$script.'.min.js'));
187 218 }
@@ -208,10 +239,9 @@
208 239 public function display(array $data = []): void
209 240 {
210 241 if (acym_isAdmin()) {
211 242 if (!acym_isNoTemplate()) {
212 - $header = new HeaderHelper();
213 - $data['header'] = $header->display($this->breadcrumb);
243 + $data['breadcrumb'] = $this->breadcrumb;
214 244 }
215 245 $viewNamespace = 'AcyMailing\\Views\\';
216 246 } else {
217 247 $viewNamespace = 'AcyMailing\\FrontViews\\';
@@ -222,8 +252,11 @@
222 252 $view = new $viewNamespace();
223 253 $view->display($this, $data);
224 254 }
225 255
256 + /**
257 + * Called using data-task
258 + */
226 259 public function cancel(): void
227 260 {
228 261 acym_setVar('layout', 'listing');
229 262 $this->display();
@@ -247,8 +280,15 @@
247 280 acym_setVar('layout', 'edit');
248 281
249 282 $this->display();
250 283 } else {
284 + if (!is_callable([$this, $nextstep])) {
285 + acym_enqueueMessage(acym_translation('ACYM_NON_EXISTING_PAGE'), 'warning');
286 + $this->listing();
287 +
288 + return;
289 + }
290 +
251 291 acym_setVar('step', $nextstep);
252 292
253 293 $this->$nextstep();
254 294 }
@@ -277,9 +317,9 @@
277 317
278 318 if (!empty($step)) {
279 319 $saveMethod = 'save'.ucfirst($step);
280 320 if (!method_exists($this, $saveMethod)) {
281 - die('Save method '.acym_escape($saveMethod).' not found');
321 + die('Save method '.esc_html($saveMethod).' not found');
282 322 }
283 323
284 324 $this->$saveMethod();
285 325
@@ -294,9 +334,9 @@
294 334 }
295 335
296 336 public function delete(): void
297 337 {
298 - acym_checkToken();
338 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
299 339 $ids = acym_getVar('array', 'elements_checked', []);
300 340 $allChecked = acym_getVar('string', 'checkbox_all');
301 341 $currentPage = explode('_', acym_getVar('string', 'page', ''));
302 342 $pageNumber = $this->getVarFiltersListing('int', end($currentPage).'_pagination_page', 1);
@@ -314,9 +354,9 @@
314 354 }
315 355
316 356 public function setActive(): void
317 357 {
318 - acym_checkToken();
358 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
319 359 $ids = acym_getVar('array', 'elements_checked', []);
320 360
321 361 if (!empty($ids) && !empty($this->currentClass)) {
322 362 $this->currentClass->setActive($ids);
@@ -326,9 +366,9 @@
326 366 }
327 367
328 368 public function setInactive(): void
329 369 {
330 - acym_checkToken();
370 + wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
331 371 $ids = acym_getVar('array', 'elements_checked', []);
332 372
333 373 if (!empty($ids) && !empty($this->currentClass)) {
334 374 $this->currentClass->setInactive($ids);
@@ -342,8 +382,9 @@
342 382 $className = 'AcyMailing\\Classes\\'.ucfirst(strtolower($class)).'Class';
343 383 $classElement = empty($class) ? $this->currentClass : new $className();
344 384 $matchingElement = $classElement->getMatchingElements($requestData);
345 385
386 + // No result and no search used, we revert to default listing (all)
346 387 if (empty($matchingElement['elements'])) {
347 388 if (!empty($status) && empty($requestData['search']) && empty($requestData['tag'])) {
348 389 $status = '';
349 390 $requestData['status'] = $status;
@@ -361,10 +402,14 @@
361 402
362 403 return $matchingElement;
363 404 }
364 405
406 + /**
407 + * Used in front/acym.php
408 + */
365 409 public function checkTaskFront(string $task = ''): void
366 410 {
411 + // For cron tasks created by users on their own server, for Joomla 4
367 412 if ($this->getName() === 'cron') {
368 413 $task = 'cron';
369 414 }
370 415
@@ -371,8 +416,9 @@
371 416 if (empty($task) && !empty($this->defaulttask)) {
372 417 $task = $this->defaulttask;
373 418 }
374 419
420 + // Handle whitelisted tasks
375 421 if (in_array($task, $this->publicFrontTasks)) {
376 422 $this->$task();
377 423
378 424 return;
@@ -377,17 +423,20 @@
377 423
378 424 return;
379 425 }
380 426
427 + // No front-end management for WordPress users
381 428 if (empty(acym_currentUserId()) || ACYM_CMS !== 'joomla' || !acym_level(ACYM_ENTERPRISE)) {
382 429 acym_redirect(acym_rootURI(), 'Front-end management not available');
383 430 }
384 431
432 + // If there is no menu, someone typed the URL manually
385 433 $currentMenu = acym_getMenu();
386 434 if (empty($currentMenu)) {
387 435 acym_redirect(acym_rootURI(), 'Direct access denied');
388 436 }
389 437
438 + // We whitelist specific routes when having access to specific menus
390 439 if ($this->isTaskAllowed($currentMenu->link, $task)) {
391 440 $this->$task();
392 441
393 442 return;
@@ -392,8 +441,9 @@
392 441
393 442 return;
394 443 }
395 444
445 + // Blacklist tasks by default
396 446 acym_redirect(acym_rootURI(), 'Unknown route, access denied');
397 447 }
398 448
399 449 private function isTaskAllowed(string $menuUrl, string $task): bool