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 / Controllers / ToggleController.php

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

301 lines 12.8 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;
4
5 use AcyMailing\Classes\ListClass;
6 use AcyMailing\Classes\MailClass;
7 use AcyMailing\Classes\UserClass;
8 use AcyMailing\Core\AcymController;
9
10 class ToggleController extends AcymController
11 {
12 protected array $toggleableColumns = [];
13 protected array $icons = [];
14 protected array $tooltips = [];
15 private array $deletableRows = [];
16
17 public function __construct()
18 {
19 parent::__construct();
20
21 $this->defaulttask = 'toggle';
22
23 $this->defineToggles();
24
25 // Avoid caching issue in Internet Explorer
26 acym_noCache();
27 }
28
29 protected function defineToggles(): void
30 {
31 // $this->toggleableColumns[TABLE NAME WITHOUT PREFIX] = array(COLUMN NAME => PRIMARY KEY);
32 $this->toggleableColumns['automation'] = ['active' => 'id'];
33 $this->toggleableColumns['field'] = [
34 'active' => 'id',
35 'required' => 'id',
36 'backend_edition' => 'id',
37 'backend_listing' => 'id',
38 'frontend_edition' => 'id',
39 'frontend_listing' => 'id',
40 ];
41 $this->toggleableColumns['list'] = ['active' => 'id', 'visible' => 'id'];
42 $this->toggleableColumns['rule'] = ['active' => 'id'];
43 $this->toggleableColumns['user'] = ['active' => 'id', 'confirmed' => 'id'];
44 $this->toggleableColumns['form'] = ['active' => 'id'];
45 $this->toggleableColumns['segment'] = ['active' => 'id'];
46 $this->toggleableColumns['campaign'] = ['visible' => 'id'];
47 $this->toggleableColumns['followup'] = ['active' => 'id'];
48 $this->toggleableColumns['mail_override'] = ['active' => 'id'];
49 $this->toggleableColumns['mailbox_action'] = ['active' => 'id'];
50 $this->toggleableColumns['scenario'] = ['active' => 'id'];
51
52 // $this->icons[TABLE NAME WITHOUT PREFIX][COLUMN NAME][VALUE] = ICON CLASS;
53 $this->icons['automation']['active'][1] = 'acymicon-check-circle acym__color__green';
54 $this->icons['automation']['active'][0] = 'acymicon-times-circle acym__color__red';
55 $this->icons['field']['active'][1] = 'acymicon-check-circle acym__color__green';
56 $this->icons['field']['active'][0] = 'acymicon-times-circle acym__color__red';
57 $this->icons['field']['required'][1] = 'acymicon-check-circle acym__color__green';
58 $this->icons['field']['required'][0] = 'acymicon-times-circle acym__color__red';
59 $this->icons['field']['backend_edition'][1] = 'acymicon-check-circle acym__color__green';
60 $this->icons['field']['backend_edition'][0] = 'acymicon-times-circle acym__color__red';
61 $this->icons['field']['backend_listing'][1] = 'acymicon-check-circle acym__color__green';
62 $this->icons['field']['backend_listing'][0] = 'acymicon-times-circle acym__color__red';
63 $this->icons['field']['frontend_edition'][1] = 'acymicon-check-circle acym__color__green';
64 $this->icons['field']['frontend_edition'][0] = 'acymicon-times-circle acym__color__red';
65 $this->icons['field']['frontend_listing'][1] = 'acymicon-check-circle acym__color__green';
66 $this->icons['field']['frontend_listing'][0] = 'acymicon-times-circle acym__color__red';
67 $this->icons['list']['active'][1] = 'acymicon-check-circle acym__color__green';
68 $this->icons['list']['active'][0] = 'acymicon-times-circle acym__color__red';
69 $this->icons['list']['visible'][1] = 'acymicon-eye';
70 $this->icons['list']['visible'][0] = 'acymicon-eye-slash acym__color__dark-gray';
71 $this->icons['rule']['active'][0] = 'acymicon-times-circle acym__color__red';
72 $this->icons['rule']['active'][1] = 'acymicon-check-circle acym__color__green';
73 $this->icons['user']['active'][1] = 'acymicon-check-circle acym__color__green';
74 $this->icons['user']['active'][0] = 'acymicon-times-circle acym__color__red';
75 $this->icons['user']['confirmed'][1] = 'acymicon-check-circle acym__color__green';
76 $this->icons['user']['confirmed'][0] = 'acymicon-times-circle acym__color__red';
77 $this->icons['form']['active'][1] = 'acymicon-check-circle acym__color__green';
78 $this->icons['form']['active'][0] = 'acymicon-times-circle acym__color__red';
79 $this->icons['segment']['active'][1] = 'acymicon-check-circle acym__color__green';
80 $this->icons['segment']['active'][0] = 'acymicon-times-circle acym__color__red';
81 $this->icons['campaign']['visible'][1] = 'acymicon-eye';
82 $this->icons['campaign']['visible'][0] = 'acymicon-eye-slash acym__color__dark-gray';
83 $this->icons['followup']['active'][1] = 'acymicon-check-circle acym__color__green';
84 $this->icons['followup']['active'][0] = 'acymicon-times-circle acym__color__red';
85 $this->icons['mail_override']['active'][1] = 'acymicon-check-circle acym__color__green';
86 $this->icons['mail_override']['active'][0] = 'acymicon-times-circle acym__color__red';
87 $this->icons['mailbox_action']['active'][1] = 'acymicon-check-circle acym__color__green';
88 $this->icons['mailbox_action']['active'][0] = 'acymicon-times-circle acym__color__red';
89 $this->icons['scenario']['active'][1] = 'acymicon-check-circle acym__color__green';
90 $this->icons['scenario']['active'][0] = 'acymicon-times-circle acym__color__red';
91
92 $this->tooltips['user']['active'][1] = 'ACYM_ACTIVATED';
93 $this->tooltips['user']['active'][0] = 'ACYM_DEACTIVATED';
94 $this->tooltips['user']['confirmed'][1] = 'ACYM_CONFIRMED';
95 $this->tooltips['user']['confirmed'][0] = 'ACYM_NOT_CONFIRMED';
96 $this->tooltips['list']['active'][1] = 'ACYM_ACTIVATED';
97 $this->tooltips['list']['active'][0] = 'ACYM_DEACTIVATED';
98 $this->tooltips['list']['visible'][1] = 'ACYM_VISIBLE';
99 $this->tooltips['list']['visible'][0] = 'ACYM_INVISIBLE';
100 $this->tooltips['campaign']['visible'][0] = 'ACYM_INVISIBLE';
101 $this->tooltips['campaign']['visible'][1] = 'ACYM_VISIBLE';
102 $this->tooltips['mail_override']['active'][0] = 'ACYM_INACTIVE';
103 $this->tooltips['mail_override']['active'][1] = 'ACYM_ACTIVE';
104
105 // $this->deletableRows[] = TABLE NAME WITHOUT PREFIX;
106 $this->deletableRows[] = 'mail';
107 $this->deletableRows[] = 'queue';
108 }
109
110 public function toggle(): void
111 {
112 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
113
114 $table = acym_getVar('word', 'table', '');
115 $field = acym_getVar('cmd', 'field', '');
116 $id = acym_getVar('int', 'id', 0);
117 $newValue = acym_getVar('int', 'value', 0);
118 if (!empty($newValue)) {
119 $newValue = 1;
120 }
121
122 if (empty($table) || empty($field) || empty($id) || empty($this->toggleableColumns[$table][$field])) {
123 exit;
124 }
125
126 // Security (ACL): per-table check — the 'toggle' exception opens this controller to ~10 roles regardless of table.
127 $this->checkToggleAcl($table);
128
129 $preciseMethod = $table.ucfirst($field);
130 $globalMethod = $table.'Global';
131 if (method_exists($this, $preciseMethod)) {
132 $this->$preciseMethod($id, $table, $field, $newValue);
133 } elseif (method_exists($this, $globalMethod)) {
134 $this->$globalMethod($id, $table, $field, $newValue);
135 } else {
136 $this->doToggle($id, $table, $field, $newValue);
137 }
138
139 acym_trigger('onAcymToggle'.ucfirst($table).ucfirst($field), [&$id, &$newValue]);
140
141 // Return the replacement icon
142 if (empty($this->icons[$table][$field][$newValue])) {
143 acym_sendAjaxResponse(acym_translation('ACYM_UNAUTHORIZED_ACCESS'), [], false);
144 }
145
146 $data = [];
147 $data['value'] = 1 - $newValue;
148 $data['classes'] = 'acym_toggleable '.$this->icons[$table][$field][$newValue];
149
150 if (!empty($this->tooltips[$table][$field][$newValue])) {
151 $data['tooltip'] = ucfirst(acym_translation($this->tooltips[$table][$field][$newValue]));
152 }
153
154 acym_sendAjaxResponse('', $data);
155 }
156
157 // Each toggle icon is only rendered on the page whose ACL the user already holds, so this per-table check blocks only forged cross-feature requests (the 'toggle' exception opens the controller to ~10 roles); overridden as a no-op by FronttoggleController.
158 protected function checkToggleAcl(string $table): void
159 {
160 $tableAcl = [
161 'user' => 'users',
162 'list' => 'lists',
163 'campaign' => 'campaigns',
164 'followup' => 'campaigns',
165 'automation' => 'automation',
166 'segment' => 'segments',
167 'scenario' => 'scenarios',
168 'form' => 'forms',
169 'field' => 'fields',
170 'mailbox_action' => 'bounces',
171 'rule' => 'bounces',
172 'mail_override' => 'override',
173 ];
174
175 if (empty($tableAcl[$table]) || !acym_isAllowed($tableAcl[$table])) {
176 acym_sendAjaxResponse(acym_translation('ACYM_ACCESS_DENIED'), [], false);
177 }
178 }
179
180 protected function userActive(int $id, string $table, string $field, int $newValue): void
181 {
182 $userClass = new UserClass();
183 if ($newValue === 0) {
184 $userClass->deactivate([$id]);
185 } else {
186 $userClass->reactivate([$id]);
187 }
188 }
189
190 protected function doToggle(int $id, string $table, string $field, int $newValue): void
191 {
192 $updateQuery = 'UPDATE '.acym_secureDBColumn(ACYM_DBPREFIX.$table);
193 $updateQuery .= ' SET `'.acym_secureDBColumn($field).'` = '.$newValue;
194 $updateQuery .= ' WHERE `'.acym_secureDBColumn($this->toggleableColumns[$table][$field]).'` = '.$id;
195 $updateQuery .= ' LIMIT 1';
196 acym_query($updateQuery);
197 }
198
199 public function delete(): void
200 {
201 if (!acym_isAdmin()) exit;
202 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
203
204 $table = acym_getVar('word', 'table', '');
205 $id = acym_getVar('int', 'id', 0);
206
207 if (empty($table) || !in_array($table, $this->deletableRows) || empty($id)) {
208 exit;
209 }
210
211 if ($table === 'queue') {
212 $allowed = acym_isAllowed('queue');
213 } else {
214 $mailClass = new MailClass();
215 $allowed = $mailClass->hasUserAccess($id, true);
216 }
217
218 if (!$allowed) {
219 acym_sendAjaxResponse(acym_translation('ACYM_ACCESS_DENIED'), [], false);
220 }
221
222 $method = $table === 'queue' ? 'deleteQueuedByUserIds' : 'delete';
223
224 $namespaceClass = 'AcyMailing\\Classes\\'.ucfirst($table).'Class';
225 $elementClass = new $namespaceClass();
226 $elementClass->$method([$id]);
227
228 exit;
229 }
230
231 public function setDoNotRemindMe(): void
232 {
233 $newValue = acym_getVar('string', 'value');
234
235 if (empty($newValue)) {
236 acym_sendAjaxResponse(acym_translation('ACYM_ERROR_SAVING'), [], false);
237 }
238
239 $remindMe = json_decode($this->config->get('remindme', '[]'));
240 if (!in_array($newValue, $remindMe)) {
241 $remindMe[] = $newValue;
242 }
243
244 if ($this->config->saveConfig(['remindme' => json_encode($remindMe)])) {
245 acym_sendAjaxResponse(acym_translation('ACYM_THANKS'));
246 } else {
247 acym_sendAjaxResponse(acym_translation('ACYM_ERROR_SAVING'), [], false);
248 }
249 }
250
251 public function subscribeOnClick(): void
252 {
253 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
254 // Security (ACL): subscription management is restricted to the 'users' role (backend); no-op on front (ownership).
255 $this->checkToggleAcl('user');
256
257 $userIds = acym_getVar('array', 'userid', []);
258 $listIds = acym_getVar('array', 'listid', []);
259
260 $userClass = new UserClass();
261 $userClass->onlyManageableUsers($userIds);
262
263 $listClass = new ListClass();
264 $listClass->onlyManageableLists($listIds);
265
266 $userClass = new UserClass();
267 $result = $userClass->subscribe($userIds, $listIds);
268
269 if ($result) {
270 acym_sendAjaxResponse();
271 } else {
272 acym_sendAjaxResponse('', [], false);
273 }
274 }
275
276 public function unsubscribeOnClick(): void
277 {
278 wp_verify_nonce(acym_getVar('cmd', '_wpnonce'), 'acymnonce') || die('Invalid Token');
279 // Security (ACL): subscription management is restricted to the 'users' role (backend); no-op on front (ownership).
280 $this->checkToggleAcl('user');
281
282 $userIds = acym_getVar('array', 'userid', []);
283 $listIds = acym_getVar('array', 'listid', []);
284
285 $userClass = new UserClass();
286 $userClass->onlyManageableUsers($userIds);
287
288 $listClass = new ListClass();
289 $listClass->onlyManageableLists($listIds);
290
291 $userClass = new UserClass();
292 $result = $userClass->unsubscribe($userIds, $listIds);
293
294 if ($result) {
295 acym_sendAjaxResponse();
296 } else {
297 acym_sendAjaxResponse('', [], false);
298 }
299 }
300 }
301