PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.0.2
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.0.2
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.0.2, at back/Core/AcymController.php

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