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
acymailing / back / Core / AcymController.php

AcymController.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 11.1.0, at back/Core/AcymController.php

471 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Core;
4
5 abstract class AcymController extends AcymObject
6 {
7 private $currentClass = null;
8 private string $sessionName;
9
10 protected array $breadcrumb = [];
11 protected array $loadScripts = [];
12 protected array $publicFrontTasks = [];
13 protected array $allowedTasks = [];
14 protected array $menuAlias = [];
15 protected string $taskCalled = '';
16 protected string $menuClass = '';
17
18 public string $defaulttask = 'listing';
19 public string $name = '';
20
21 public function __construct()
22 {
23 parent::__construct();
24
25 $classname = get_class($this);
26 $classname = substr($classname, strrpos($classname, '\\') + 1);
27 $this->name = strtolower(
28 substr(
29 $classname,
30 0,
31 strpos($classname, 'Controller')
32 )
33 );
34
35 $currentClassName = 'AcyMailing\\Classes\\'.rtrim(ucfirst(str_replace(['Front', 'front'], '', $this->name)), 's').'Class';
36 if (class_exists($currentClassName)) {
37 $this->currentClass = new $currentClassName();
38 }
39 $this->sessionName = 'acym_filters_'.$this->name;
40 $this->taskCalled = acym_getVar('string', 'task', '');
41
42 $this->breadcrumb['AcyMailing'] = acym_completeLink('dashboard');
43 }
44
45 private function initSession(): void
46 {
47 $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
48 if (empty($controllerSession)) {
49 acym_setSession($this->sessionName, []);
50 }
51 }
52
53 /**
54 * @param mixed $default
55 *
56 * @return mixed
57 */
58 public function getVarFiltersListing(string $type, string $varName, $default, bool $overrideIfNull = false)
59 {
60 if ($this->taskCalled === 'clearFilters') {
61 return $default;
62 }
63
64 $this->initSession();
65
66 $isVarInRequest = !is_null(acym_getVar('raw', $varName, null, '', ACYM_ALLOWRAW));
67 $returnValue = $isVarInRequest ? acym_getVar($type, $varName) : null;
68
69 if (is_null($returnValue) && $overrideIfNull) {
70 $returnValue = $default;
71 }
72
73 if (!is_null($returnValue)) {
74 $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
75 $controllerSession[$varName] = $returnValue;
76 acym_setSession($this->sessionName, $controllerSession);
77
78 return $returnValue;
79 }
80
81 $filters = acym_getVar('array', $this->sessionName, [], 'SESSION');
82 if (!empty($filters[$varName])) {
83 return $filters[$varName];
84 }
85
86 return $default;
87 }
88
89 public function setVarFiltersListing(string $varName, int $value): void
90 {
91 acym_setVar($varName, $value);
92 $this->initSession();
93 $controllerSession = acym_getVar('array', $this->sessionName, [], 'SESSION');
94 $controllerSession[$varName] = $value;
95 acym_setSession($this->sessionName, $controllerSession);
96 }
97
98 /**
99 * Called using data-task
100 */
101 public function clearFilters(): void
102 {
103 acym_setSession($this->sessionName, []);
104
105 $taskToCall = acym_getVar('string', 'cleartask', $this->defaulttask);
106 if (in_array($taskToCall, ['campaigns_auto', 'welcome', 'unsubscribe', $this->defaulttask])) {
107 $this->call($taskToCall);
108 }
109 }
110
111 public function call(string $task, bool $isFront = false): void
112 {
113 if (
114 !in_array($task, $this->publicFrontTasks, true)
115 && !acym_isAllowed($this->name, $task)
116 ) {
117 acym_enqueueMessage(acym_translation('ACYM_ACCESS_DENIED'), 'warning');
118 acym_redirect($isFront ? ACYM_LIVE : acym_completeLink('dashboard'));
119
120 return;
121 }
122
123 // If task doesn't exist, redirect to default task + add message
124 if (!is_callable([$this, $task])) {
125 acym_enqueueMessage(acym_translation('ACYM_NON_EXISTING_PAGE'), 'warning');
126 $task = $this->defaulttask;
127 acym_setVar('task', $task);
128 }
129
130 // Call the task
131 $this->$task();
132 }
133
134 public function loadScripts(string $task): void
135 {
136 if (empty($this->loadScripts)) return;
137
138 $scripts = [];
139 if (!empty($this->loadScripts['all'])) {
140 $scripts = $this->loadScripts['all'];
141 }
142
143 if (!empty($task) && !empty($this->loadScripts[$task])) {
144 $scripts = array_merge($scripts, $this->loadScripts[$task]);
145 }
146
147 if (empty($scripts)) return;
148
149 if (in_array('editor-wysid', $scripts)) {
150 acym_addStyle(false, ACYM_CSS.'editorWYSID.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'editorWYSID.min.css'));
151 acym_addScript(false, ACYM_JS.'editor_wysid_utils.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'editor_wysid_utils.min.js'));
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
161 $scripts = array_merge($scripts, ['colorpicker', 'datepicker', 'thumbnail', 'foundation-email', 'parse-css', 'vue-prism-editor', 'masonry']);
162
163 if (empty($scripts['vue-applications'])) {
164 $scripts['vue-applications'] = ['code_editor'];
165 } else {
166 $scripts['vue-applications'][] = 'code_editor';
167 }
168 }
169
170 if (in_array('sankey', $scripts)) {
171 acym_addScript(false, ACYM_JS.'libraries/sankey.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'sankey.min.js'));
172 }
173
174 if (in_array('colorpicker', $scripts)) {
175 acym_addScript(false, ACYM_JS.'libraries/spectrum.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'spectrum.min.js'));
176 acym_addStyle(false, ACYM_CSS.'libraries/spectrum.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'spectrum.min.css'));
177 }
178
179 if (in_array('datepicker', $scripts)) {
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()).'";');
186 }
187
188 if (in_array('dtextPicker', $scripts)) {
189 acym_addScript(false, ACYM_JS.'dtext_picker.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'dtext_picker.min.js'));
190 acym_addStyle(false, ACYM_CSS.'dtext_picker.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'dtext_picker.min.css'));
191 }
192
193 if (in_array('thumbnail', $scripts)) {
194 acym_addScript(false, ACYM_JS.'libraries/html2canvas.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'html2canvas.min.js'));
195 }
196
197 if (in_array('foundation-email', $scripts)) {
198 acym_addStyle(false, ACYM_CSS.'libraries/foundation_email.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'foundation_email.min.css'));
199 acym_addStyle(true, acym_getEmailCssFixes());
200 }
201
202 if (in_array('parse-css', $scripts)) {
203 acym_addScript(false, ACYM_JS.'libraries/parse-css.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'parse-css.min.js'));
204 }
205
206 if (in_array('masonry', $scripts)) {
207 acym_addScript(false, ACYM_JS.'libraries/masonry.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'masonry.min.js'));
208 }
209
210 if (!empty($scripts['vue-applications'])) {
211 //vuejs javascript library
212 acym_addScript(false, ACYM_JS.'libraries/vuejs.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'vuejs.min.js'));
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)
215 acym_addScript(false, ACYM_JS.'vue/vue_components.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'vue'.DS.'vue_components.min.js'));
216 foreach ($scripts['vue-applications'] as $script) {
217 acym_addScript(false, ACYM_JS.'vue/'.$script.'.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'vue'.DS.$script.'.min.js'));
218 }
219 }
220
221 if (in_array('vue-prism-editor', $scripts)) {
222 acym_addScript(false, ACYM_JS.'libraries/prism-editor.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'prism-editor.min.js'));
223 acym_addScript(false, ACYM_JS.'libraries/prism.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'prism.min.js'));
224 acym_addStyle(false, ACYM_CSS.'libraries/prism.min.css?v='.filemtime(ACYM_MEDIA.'css'.DS.'libraries'.DS.'prism.min.css'));
225 acym_addScript(false, ACYM_JS.'libraries/beautify-html.min.js?v='.filemtime(ACYM_MEDIA.'js'.DS.'libraries'.DS.'beautify-html.min.js'));
226 }
227 }
228
229 public function setDefaultTask(string $task): void
230 {
231 $this->defaulttask = $task;
232 }
233
234 public function getName(): string
235 {
236 return $this->name;
237 }
238
239 public function display(array $data = []): void
240 {
241 if (acym_isAdmin()) {
242 if (!acym_isNoTemplate()) {
243 $data['breadcrumb'] = $this->breadcrumb;
244 }
245 $viewNamespace = 'AcyMailing\\Views\\';
246 } else {
247 $viewNamespace = 'AcyMailing\\FrontViews\\';
248 }
249
250 $viewName = ucfirst($this->getName());
251 $viewNamespace .= $viewName.'\\'.$viewName.'View';
252 $view = new $viewNamespace();
253 $view->display($this, $data);
254 }
255
256 /**
257 * Called using data-task
258 */
259 public function cancel(): void
260 {
261 acym_setVar('layout', 'listing');
262 $this->display();
263 }
264
265 public function listing(): void
266 {
267 acym_setVar('layout', 'listing');
268
269 $this->display();
270 }
271
272 public function edit(): void
273 {
274 $nextstep = acym_getVar('string', 'nextstep', '');
275 if (empty($nextstep)) {
276 $nextstep = acym_getVar('string', 'step', '');
277 }
278
279 if (empty($nextstep)) {
280 acym_setVar('layout', 'edit');
281
282 $this->display();
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
291 acym_setVar('step', $nextstep);
292
293 $this->$nextstep();
294 }
295 }
296
297 public function apply(): void
298 {
299 if (method_exists($this, 'store')) {
300 $this->store();
301 }
302
303 $this->edit();
304 }
305
306 public function add(): void
307 {
308 acym_setVar('cid', []);
309 acym_setVar('layout', 'form');
310
311 $this->display();
312 }
313
314 public function save(): void
315 {
316 $step = acym_getVar('string', 'step', '');
317
318 if (!empty($step)) {
319 $saveMethod = 'save'.ucfirst($step);
320 if (!method_exists($this, $saveMethod)) {
321 die('Save method '.esc_html($saveMethod).' not found');
322 }
323
324 $this->$saveMethod();
325
326 return;
327 }
328
329 if (method_exists($this, 'store')) {
330 $this->store();
331 }
332
333 $this->listing();
334 }
335
336 public function delete(): void
337 {
338 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
339 $ids = acym_getVar('array', 'elements_checked', []);
340 $allChecked = acym_getVar('string', 'checkbox_all');
341 $currentPage = explode('_', acym_getVar('string', 'page', ''));
342 $pageNumber = $this->getVarFiltersListing('int', end($currentPage).'_pagination_page', 1);
343
344 if (!empty($ids) && !empty($this->currentClass)) {
345 $this->currentClass->delete($ids);
346 if ($allChecked === 'on') {
347 $this->setVarFiltersListing(end($currentPage).'_pagination_page', $pageNumber - 1);
348 }
349 }
350
351 if (!acym_getVar('bool', 'no_listing', false)) {
352 $this->listing();
353 }
354 }
355
356 public function setActive(): void
357 {
358 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
359 $ids = acym_getVar('array', 'elements_checked', []);
360
361 if (!empty($ids) && !empty($this->currentClass)) {
362 $this->currentClass->setActive($ids);
363 }
364
365 $this->listing();
366 }
367
368 public function setInactive(): void
369 {
370 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
371 $ids = acym_getVar('array', 'elements_checked', []);
372
373 if (!empty($ids) && !empty($this->currentClass)) {
374 $this->currentClass->setInactive($ids);
375 }
376
377 $this->listing();
378 }
379
380 public function getMatchingElementsFromData(array $requestData, string &$status, int &$page, string $class = ''): array
381 {
382 $className = 'AcyMailing\\Classes\\'.ucfirst(strtolower($class)).'Class';
383 $classElement = empty($class) ? $this->currentClass : new $className();
384 $matchingElement = $classElement->getMatchingElements($requestData);
385
386 // No result and no search used, we revert to default listing (all)
387 if (empty($matchingElement['elements'])) {
388 if (!empty($status) && empty($requestData['search']) && empty($requestData['tag'])) {
389 $status = '';
390 $requestData['status'] = $status;
391 } elseif (!empty($requestData['offset'])) {
392 $page = 1;
393 $requestData['offset'] = 0;
394 } else {
395 return $matchingElement;
396 }
397
398 $matchingElement = $classElement->getMatchingElements($requestData);
399 }
400
401 $matchingElement['total']->total = intval($matchingElement['total']->total);
402
403 return $matchingElement;
404 }
405
406 /**
407 * Used in front/acym.php
408 */
409 public function checkTaskFront(string $task = ''): void
410 {
411 // For cron tasks created by users on their own server, for Joomla 4
412 if ($this->getName() === 'cron') {
413 $task = 'cron';
414 }
415
416 if (empty($task) && !empty($this->defaulttask)) {
417 $task = $this->defaulttask;
418 }
419
420 // Handle whitelisted tasks
421 if (in_array($task, $this->publicFrontTasks)) {
422 $this->$task();
423
424 return;
425 }
426
427 // No front-end management for WordPress users
428 if (empty(acym_currentUserId()) || ACYM_CMS !== 'joomla' || !acym_level(ACYM_ENTERPRISE)) {
429 acym_redirect(acym_rootURI(), 'Front-end management not available');
430 }
431
432 // If there is no menu, someone typed the URL manually
433 $currentMenu = acym_getMenu();
434 if (empty($currentMenu)) {
435 acym_redirect(acym_rootURI(), 'Direct access denied');
436 }
437
438 // We whitelist specific routes when having access to specific menus
439 if ($this->isTaskAllowed($currentMenu->link, $task)) {
440 $this->$task();
441
442 return;
443 }
444
445 // Blacklist tasks by default
446 acym_redirect(acym_rootURI(), 'Unknown route, access denied');
447 }
448
449 private function isTaskAllowed(string $menuUrl, string $task): bool
450 {
451 if (!empty($this->allowedTasks[$menuUrl]) && in_array($task, $this->allowedTasks[$menuUrl])) {
452 return true;
453 }
454
455 if (!empty($this->menuAlias[$menuUrl])) {
456 $menuUrl = $this->menuAlias[$menuUrl];
457
458 return $this->isTaskAllowed($menuUrl, $task);
459 }
460
461 return false;
462 }
463
464 protected function prepareMultilingualOption(array &$data): void
465 {
466 if (!acym_isMultilingual()) return;
467
468 $data['translation_languages'] = acym_getMultilingualLanguages();
469 }
470 }
471