PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.1
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 / Classes / AutomationClass.php

AutomationClass.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at back/Classes/AutomationClass.php

353 lines 11.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\Classes;
4
5 use AcyMailing\Helpers\AutomationHelper;
6 use AcyMailing\Helpers\PaginationHelper;
7 use AcyMailing\Core\AcymClass;
8
9 class AutomationClass extends AcymClass
10 {
11 const ACTIONS_TO_SKIP = ['acy_send_email'];
12
13 public bool $didAnAction = false;
14 public array $report = [];
15
16 public function __construct()
17 {
18 parent::__construct();
19
20 $this->table = 'automation';
21 $this->pkey = 'id';
22 $this->intColumns = [
23 'id',
24 'active',
25 'admin',
26 ];
27 }
28
29 public function getMatchingElements(array $settings = []): array
30 {
31 $query = 'SELECT * FROM #__acym_automation';
32 $queryCount = 'SELECT COUNT(id) AS total, SUM(active) AS totalActive FROM #__acym_automation';
33 $filters = [];
34
35 if (!empty($settings['search'])) {
36 $filters[] = 'name LIKE '.acym_escapeDB('%'.$settings['search'].'%');
37 }
38
39 if (!empty($filters)) {
40 $query .= ' WHERE ('.implode(') AND (', $filters).')';
41 $queryCount .= ' WHERE ('.implode(') AND (', $filters).')';
42 }
43
44 if (!empty($settings['status'])) {
45 $query .= empty($filters) ? ' WHERE ' : ' AND ';
46 $query .= 'active = '.($settings['status'] === 'active' ? '1' : '0');
47 }
48
49 if (!empty($settings['ordering']) && !empty($settings['ordering_sort_order'])) {
50 $query .= ' ORDER BY '.acym_secureDBColumn($settings['ordering']).' '.acym_secureDBColumn(strtoupper($settings['ordering_sort_order']));
51 } else {
52 $query .= ' ORDER BY ordering asc';
53 }
54
55 if (empty($settings['offset']) || $settings['offset'] < 0) {
56 $settings['offset'] = 0;
57 }
58
59 if (empty($settings['elementsPerPage']) || $settings['elementsPerPage'] < 1) {
60 $pagination = new PaginationHelper();
61 $settings['elementsPerPage'] = $pagination->getListLimit();
62 }
63
64 $elements = acym_loadObjectList($query, '', $settings['offset'], $settings['elementsPerPage']);
65 array_map([$this, 'fixTypes'], $elements);
66
67 return [
68 'elements' => $elements,
69 'total' => acym_loadObject($queryCount),
70 ];
71 }
72
73 public function save(object $element): ?int
74 {
75 foreach ($element as $oneAttribute => $value) {
76 if (empty($value)) {
77 continue;
78 }
79
80 $element->$oneAttribute = is_array($value) ? json_encode($value) : strip_tags($value);
81 }
82
83 return parent::save($element);
84 }
85
86 public function delete(array $elements): int
87 {
88 if (empty($elements)) return 0;
89
90 acym_arrayToInteger($elements);
91
92 $steps = acym_loadResultArray('SELECT id FROM #__acym_step WHERE automation_id IN ('.implode(',', $elements).')');
93 $stepClass = new StepClass();
94 $stepClass->delete($steps);
95
96 return parent::delete($elements);
97 }
98
99 public function trigger($triggers, array $data = []): void
100 {
101 if (!acym_level(ACYM_ENTERPRISE) || empty($triggers)) {
102 return;
103 }
104
105 if (!is_array($triggers)) {
106 $triggers = [$triggers];
107 }
108
109 $stepClass = new StepClass();
110 $actionClass = new ActionClass();
111 $conditionClass = new ConditionClass();
112
113 $steps = $stepClass->getActiveStepByTrigger($triggers);
114
115 $data['time'] = time();
116 foreach ($steps as $step) {
117 $newData = $data;
118 $execute = false;
119
120 if (!empty($step->next_execution) && $step->next_execution <= $newData['time']) {
121 $execute = true;
122 }
123
124 acym_trigger('onAcymExecuteTrigger', [&$step, &$execute, &$newData]);
125
126 $newData['automation'] = $this->getOneById($step->automation_id);
127
128 if ($execute) {
129 $step->last_execution = $newData['time'];
130 $conditions = $conditionClass->getConditionsByStepId($step->id);
131 if (!empty($conditions)) {
132 foreach ($conditions as $condition) {
133 if (!$this->verifyCondition($condition->conditions, $newData)) continue;
134
135 $actions = $actionClass->getActionsByStepId($step->id);
136 if (empty($actions)) continue;
137
138 foreach ($actions as $action) {
139 $this->execute($action, $newData);
140 }
141 }
142 }
143 }
144
145 $stepClass->save($step);
146 }
147 }
148
149 public function execute(object $action, array $data = []): bool
150 {
151 $usersTriggeringAction = empty($data['userIds']) ? [] : $data['userIds'];
152 $userTriggeringAction = empty($data['userId']) ? 0 : $data['userId'];
153
154 $action->actions = json_decode($action->actions ?? '[]', true);
155 if (empty($action->actions)) return false;
156
157 $isMassAction = false;
158 static $massAction = 0;
159 if (empty($action->id)) {
160 $action->id = $massAction--;
161 $isMassAction = true;
162 }
163
164 $action->filters = json_decode($action->filters ?? '[]', true);
165 if (empty($action->filters)) return false;
166
167
168 $initialWhere = ['1 = 1'];
169 $query = new AutomationHelper();
170 $query->removeFlag($action->id);
171
172 if (!empty($action->filters['type_filter']) && $action->filters['type_filter'] == 'user') {
173 if (empty($usersTriggeringAction)) {
174 if (empty($userTriggeringAction)) return false;
175
176 $initialWhere = ['user.id = '.intval($userTriggeringAction)];
177 } else {
178 acym_arrayToInteger($usersTriggeringAction);
179 $initialWhere = ['user.id IN ('.implode(', ', $usersTriggeringAction).')'];
180 }
181 }
182
183 $typeFilter = $action->filters['type_filter'] ?? null;
184
185 unset($action->filters['type_filter']);
186 if (empty($action->filters)) {
187 $query->where = $initialWhere;
188 }
189
190 foreach ($action->filters as $or => $orValue) {
191 if (empty($orValue)) {
192 continue;
193 }
194 $num = 0;
195 $query->where = $initialWhere;
196 foreach ($orValue as $and => $andValue) {
197 $num++;
198 foreach ($andValue as $filterName => $filterOptions) {
199 acym_trigger('onAcymProcessFilter_'.$filterName, [&$query, &$filterOptions, &$num]);
200 }
201 }
202
203 $query->addFlag($action->id);
204 }
205
206 $this->didAnAction = $this->didAnAction || $query->count() > 0;
207 foreach ($action->actions as $and => $andValue) {
208 foreach ($andValue as $actionName => $actionOptions) {
209 $this->report = array_merge(
210 $this->report,
211 acym_trigger(
212 'onAcymProcessAction_'.$actionName,
213 [&$query, &$actionOptions, ['automationAdmin' => !empty($data['automation']->admin), 'user_id' => $userTriggeringAction]]
214 )
215 );
216 $action->actions[$and][$actionName] = $actionOptions;
217 }
218 }
219
220 if (!$isMassAction) {
221 if ($typeFilter !== null) {
222 $action->filters['type_filter'] = $typeFilter;
223 }
224 $action->filters = json_encode($action->filters);
225 $action->actions = json_encode($action->actions);
226 $actionClass = new ActionClass();
227 $actionClass->save($action);
228 }
229
230 $query->removeFlag($action->id);
231
232 return $this->didAnAction;
233 }
234
235 private function verifyCondition($conditions, array $data = []): bool
236 {
237 if (empty($conditions)) return true;
238 $userTriggeringAction = empty($data['userId']) ? 0 : $data['userId'];
239 $usersTriggeringAction = empty($data['userIds']) ? [] : $data['userIds'];
240
241 $conditions = json_decode($conditions, true);
242 $query = new AutomationHelper();
243 $initialWhere = ['1 = 1'];
244 if (!empty($conditions['type_condition']) && $conditions['type_condition'] == 'user') {
245 if (empty($usersTriggeringAction)) {
246 if (empty($userTriggeringAction)) return false;
247
248 $initialWhere = ['user.id = '.intval($userTriggeringAction)];
249 } else {
250 acym_arrayToInteger($usersTriggeringAction);
251 $initialWhere = ['user.id IN ('.implode(', ', $usersTriggeringAction).')'];
252 }
253 }
254 unset($conditions['type_condition']);
255
256 if (empty($conditions)) return true;
257
258 foreach ($conditions as $or => $orValue) {
259 if (empty($orValue)) continue;
260
261 $conditionNotValid = 0;
262 $num = 0;
263 foreach ($orValue as $and => $andValue) {
264 $num++;
265 $query->where = $initialWhere;
266 foreach ($andValue as $filterName => $filterOptions) {
267 acym_trigger('onAcymProcessCondition_'.$filterName, [&$query, &$filterOptions, &$num, &$conditionNotValid]);
268 }
269 }
270
271 if ($conditionNotValid == 0) return true;
272 }
273
274 return false;
275 }
276
277 public function triggerManual(array $automationIds): array
278 {
279 if (!acym_level(ACYM_ENTERPRISE) || empty($automationIds)) {
280 return [];
281 }
282
283 acym_arrayToInteger($automationIds);
284
285 $actionClass = new ActionClass();
286 $conditionClass = new ConditionClass();
287 $stepClass = new StepClass();
288
289 $executedCount = 0;
290 $skippedCount = 0;
291
292 foreach ($automationIds as $automationId) {
293 $steps = $stepClass->getStepsByAutomationId($automationId);
294 if (empty($steps)) {
295 continue;
296 }
297
298 $step = $steps[0];
299 if (!empty($step->triggers)) {
300 $step->triggers = json_decode($step->triggers, true);
301 }
302
303 if (!empty($step->triggers['type_trigger']) && $step->triggers['type_trigger'] !== 'classic') {
304 $skippedCount++;
305 continue;
306 }
307
308 $data = ['time' => time()];
309 $data['automation'] = $this->getOneById($step->automation_id);
310
311 $conditions = $conditionClass->getConditionsByStepId($step->id);
312 if (!empty($conditions)) {
313 foreach ($conditions as $condition) {
314 if (!$this->verifyCondition($condition->conditions, $data)) {
315 continue;
316 }
317
318 $actions = $actionClass->getActionsByStepId($step->id);
319 if (empty($actions)) {
320 continue;
321 }
322
323 foreach ($actions as $action) {
324 $this->execute($action, $data);
325 }
326 }
327 }
328
329 $executedCount++;
330 }
331
332 return [
333 'executed' => $executedCount,
334 'skipped' => $skippedCount,
335 ];
336 }
337
338 public function getAutomationsAdmin(array $ids = []): array
339 {
340 acym_arrayToInteger($ids);
341
342 $query = 'SELECT * FROM #__acym_automation WHERE `admin` = 1';
343 if (!empty($ids)) {
344 $query .= ' AND `id` IN ('.implode(', ', $ids).')';
345 }
346
347 $automations = acym_loadObjectList($query, 'name');
348 array_map([$this, 'fixTypes'], $automations);
349
350 return $automations;
351 }
352 }
353