PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.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
← All changes | back/Helpers/ScenarioHelper.php +0 -352 10.2.2 → 11.1.1 View file →
@@ -1,352 +1,0 @@
1 -<?php
2 -
3 -namespace AcyMailing\Helpers;
4 -
5 -use AcyMailing\Classes\ScenarioClass;
6 -use AcyMailing\Classes\ScenarioHistoryLineClass;
7 -use AcyMailing\Classes\ScenarioProcessClass;
8 -use AcyMailing\Classes\ScenarioStepClass;
9 -use AcyMailing\Classes\ScenarioQueueClass;
10 -use AcyMailing\Classes\UserClass;
11 -use AcyMailing\Core\AcymObject;
12 -
13 -class ScenarioHelper extends AcymObject
14 -{
15 - private ScenarioClass $scenarioClass;
16 - private ScenarioStepClass $scenarioStepClass;
17 - private ScenarioQueueClass $scenarioQueueClass;
18 - private ScenarioHistoryLineClass $scenarioHistoryLineClass;
19 - private ScenarioProcessClass $scenarioProcessClass;
20 -
21 - public function __construct()
22 - {
23 - parent::__construct();
24 - $this->scenarioClass = new ScenarioClass();
25 - $this->scenarioStepClass = new ScenarioStepClass();
26 - $this->scenarioQueueClass = new ScenarioQueueClass();
27 - $this->scenarioHistoryLineClass = new ScenarioHistoryLineClass();
28 - $this->scenarioProcessClass = new ScenarioProcessClass();
29 - }
30 -
31 - public function trigger(string $trigger, array $options): void
32 - {
33 - if (!acym_level(ACYM_ENTERPRISE) || empty($trigger)) {
34 - acym_logError('ScenarioHelper::trigger - Missing trigger or not allowed, trigger: '.$trigger);
35 -
36 - return;
37 - }
38 -
39 - if (empty($options['userId'])) {
40 - acym_logError('ScenarioHelper::trigger - Missing userId, trigger: '.$trigger);
41 -
42 - return;
43 - }
44 -
45 - $userId = intval($options['userId']);
46 -
47 - $userClass = new UserClass();
48 - if (empty($userClass->getOneById($userId))) {
49 - acym_logError('ScenarioHelper::trigger - User not found, userId: '.$userId);
50 -
51 - return;
52 - }
53 -
54 - $scenarios = $this->scenarioClass->getAllActiveByTriggers([$trigger]);
55 -
56 - foreach ($scenarios as $scenario) {
57 - if ($scenario->trigger_once) {
58 - if (!empty($this->scenarioProcessClass->getOneByScenarioIdUserId($scenario->id, $userId))) {
59 - continue;
60 - }
61 - }
62 -
63 - $scenario->is_scenario = true;
64 - $scenario->triggers = [$scenario->trigger => 1];
65 - $execute = false;
66 - $options = $this->formatOptions($scenario->trigger_params, 'trigger');
67 - $options['userId'] = $userId;
68 - $options['time'] = time();
69 - acym_trigger('onAcymExecuteTrigger', [&$scenario, &$execute, &$options]);
70 -
71 - if (!$execute) {
72 - continue;
73 - }
74 -
75 - $firstStep = $this->scenarioStepClass->getFirstStepByScenarioId($scenario->id);
76 -
77 - if (empty($firstStep)) {
78 - acym_logError('ScenarioHelper::trigger - No first step found for scenario '.$scenario->id);
79 - continue;
80 - }
81 -
82 - $scenarioProcess = new \stdClass();
83 - $scenarioProcess->scenario_id = $scenario->id;
84 - $scenarioProcess->user_id = $userId;
85 - $scenarioProcess->start_at = acym_date('now', 'Y-m-d H:i:s', false);
86 - $scenarioProcess->id = $this->scenarioProcessClass->save($scenarioProcess);
87 -
88 - $this->createHistory($scenarioProcess->id, 'trigger', 'success');
89 -
90 - $this->handleStep($firstStep, $userId, $scenarioProcess->id);
91 - }
92 - }
93 -
94 - private function handleStep(object $step, int $userId, int $scenarioProcessId): void
95 - {
96 - switch ($step->type) {
97 - case ScenarioClass::TYPE_DELAY:
98 - $this->handleDelay($step, $userId, $scenarioProcessId);
99 - break;
100 - case ScenarioClass::TYPE_CONDITION:
101 - $this->handleCondition($step, $userId, $scenarioProcessId);
102 - break;
103 - case ScenarioClass::TYPE_ACTION:
104 - $this->handleAction($step, $userId, $scenarioProcessId);
105 - break;
106 - }
107 - }
108 -
109 - private function handleDelay(object $step, int $userId, int $scenarioProcessId): void
110 - {
111 - $nextStep = $this->scenarioStepClass->getStepByPreviousStepId($step->id);
112 -
113 - if (empty($nextStep)) {
114 - $this->ending($scenarioProcessId);
115 -
116 - return;
117 - }
118 -
119 - $scenarioQueue = new \stdClass();
120 - $scenarioQueue->scenario_process_id = $scenarioProcessId;
121 - $scenarioQueue->step_id = $nextStep->id;
122 - $timestampNextAction = time() + $this->calculateDelaySecondsToAdd($step->params);
123 - $scenarioQueue->execution_date = acym_date($timestampNextAction, 'Y-m-d H:i:s', false);
124 -
125 - $this->scenarioQueueClass->save($scenarioQueue);
126 - $this->scenarioQueueClass->deleteByStepIds([$step->id]);
127 -
128 - $this->createHistory($scenarioProcessId, ScenarioClass::TYPE_DELAY, 'success', $step->id, $step->params);
129 - }
130 -
131 - private function calculateDelaySecondsToAdd(array $stepDelayParams): int
132 - {
133 - if (empty($stepDelayParams['delay']) || empty($stepDelayParams['unit'])) {
134 - return 0;
135 - }
136 -
137 - return $stepDelayParams['delay'] * $stepDelayParams['unit'];
138 - }
139 -
140 - private function handleCondition(object $step, int $userId, int $scenarioProcessId): void
141 - {
142 - $conditionNotValidCount = 0;
143 -
144 - $query = new AutomationHelper();
145 - $query->where = ['user.id = '.$userId];
146 -
147 - $conditionOptions = $this->formatOptions($step->params['option'], $step->type);
148 - $number = 0;
149 - acym_trigger('onAcymProcessCondition_'.$step->params['condition'], [&$query, &$conditionOptions, &$number, &$conditionNotValidCount]);
150 - $this->scenarioQueueClass->deleteByStepIds([$step->id]);
151 -
152 - $conditionValid = $conditionNotValidCount === 0;
153 -
154 - $historyOptions = array_merge($conditionOptions, ['scenario_condition' => $step->params['condition']]);
155 - $this->createHistory($scenarioProcessId, ScenarioClass::TYPE_CONDITION, 'Condition is '.($conditionValid ? 'valid' : 'not valid'), $step->id, $historyOptions);
156 -
157 - $nextStep = $this->scenarioStepClass->getStepByPreviousConditionId($step->id, $conditionValid);
158 -
159 - if (empty($nextStep)) {
160 - $this->ending($scenarioProcessId);
161 -
162 - return;
163 - }
164 -
165 - $this->handleStep($nextStep, $userId, $scenarioProcessId);
166 - }
167 -
168 - private function formatOptions(array $options, string $type): array
169 - {
170 - $formattedOptions = [];
171 -
172 - switch ($type) {
173 - case ScenarioClass::TYPE_CONDITION:
174 - $regex = '/acym_condition\[conditions\]\[__numor__\]\[__numand__\]\[(.+)\]\[(.+)\]/';
175 - break;
176 - case ScenarioClass::TYPE_ACTION:
177 - $regex = '/acym_action\[actions\]\[__and__\]\[(.+)\]\[(.+)\]/';
178 - break;
179 - case 'trigger':
180 - $regex = '/\[triggers\]\[user\]\[(.+)\]\[(.+)\]/';
181 - break;
182 - default:
183 - $regex = '';
184 - }
185 -
186 - if (empty($regex)) {
187 - return $formattedOptions;
188 - }
189 -
190 - foreach ($options as $key => $option) {
191 - $formattedKey = preg_replace($regex, '$2', $key);
192 - if ($formattedKey === $key) {
193 - continue;
194 - }
195 - $formattedOptions[$formattedKey] = $option;
196 - }
197 -
198 - return $formattedOptions;
199 - }
200 -
201 - private function handleAction(object $step, int $userId, int $scenarioProcessId): void
202 - {
203 - $query = new AutomationHelper();
204 - $query->where = ['user.id = '.$userId];
205 -
206 - $actionOptions = $this->formatOptions($step->params['option'], $step->type);
207 - $log = '';
208 - $report = '';
209 - try {
210 - $report = acym_trigger('onAcymProcessAction_'.$step->params['action'], [&$query, &$actionOptions]);
211 - $report = is_array($report) ? implode(', ', $report) : $report;
212 - } catch (\Exception $e) {
213 - $log = $e->getMessage();
214 - }
215 -
216 - $this->scenarioQueueClass->deleteByStepIds([$step->id]);
217 -
218 - $historyOptions = array_merge($actionOptions, ['scenario_action' => $step->params['action']]);
219 - $this->createHistory($scenarioProcessId, ScenarioClass::TYPE_CONDITION, 'Action completed: '.$report, $step->id, $historyOptions, $log);
220 -
221 - $nextStep = $this->scenarioStepClass->getStepByPreviousStepId($step->id);
222 -
223 - if (empty($nextStep)) {
224 - $this->ending($scenarioProcessId);
225 -
226 - return;
227 - }
228 -
229 - $this->handleStep($nextStep, $userId, $scenarioProcessId);
230 - }
231 -
232 - private function ending(int $scenarioProcessId): void
233 - {
234 - $this->createHistory($scenarioProcessId, 'ending', acym_translation('ACYM_SCENARIO_ENDED'));
235 -
236 - $this->scenarioProcessClass->endProcess($scenarioProcessId);
237 - }
238 -
239 - public function executeAvailableSteps(): void
240 - {
241 - $dateNowUtc = acym_date('now', 'Y-m-d H:i:s', false);
242 -
243 - $steps = $this->scenarioStepClass->getAvailableStepsByDate($dateNowUtc);
244 -
245 - if (empty($steps)) {
246 - return;
247 - }
248 -
249 - foreach ($steps as $step) {
250 - $this->handleStep($step, $step->user_id, $step->scenario_process_id);
251 - }
252 - }
253 -
254 - public function triggerTimeScenarios(): void
255 - {
256 - $userStatusTriggers = [];
257 - acym_trigger('onAcymDefineUserStatusCheckTriggers', [&$userStatusTriggers]);
258 -
259 - if (empty($userStatusTriggers)) {
260 - return;
261 - }
262 -
263 - $scenarioClass = new ScenarioClass();
264 - $scenarios = $scenarioClass->getAllActiveByTriggers($userStatusTriggers);
265 -
266 - if (empty($scenarios)) {
267 - return;
268 - }
269 -
270 - foreach ($scenarios as $scenario) {
271 - $nextExecution = $scenario->trigger_params['next_execution'] ?? null;
272 - $scenario->next_execution = $nextExecution;
273 -
274 - if (!empty($nextExecution) && $nextExecution > time()) {
275 - continue;
276 - }
277 -
278 - $firstStep = $this->scenarioStepClass->getFirstStepByScenarioId($scenario->id);
279 - if (empty($firstStep)) {
280 - acym_logError('ScenarioHelper::triggerTimeScenarios - No first step found for scenario '.$scenario->id);
281 - continue;
282 - }
283 -
284 - $execute = false;
285 - $options = $this->formatOptions($scenario->trigger_params['option'] ?? [], 'trigger');
286 - $options['time'] = time();
287 -
288 - $scenario->is_scenario = true;
289 - $scenario->triggers = [$scenario->trigger => $options];
290 -
291 - acym_trigger('onAcymExecuteTrigger', [&$scenario, &$execute, &$options]);
292 -
293 - if ($nextExecution !== $scenario->next_execution) {
294 - $scenario->trigger_params['next_execution'] = $scenario->next_execution;
295 - $scenarioClass->save($scenario);
296 - }
297 -
298 - if (empty($options['userIds'])) {
299 - continue;
300 - }
301 -
302 - foreach ($options['userIds'] as $userId) {
303 - if ($scenario->trigger_once && !empty($this->scenarioProcessClass->getOneByScenarioIdUserId($scenario->id, $userId))) {
304 - continue;
305 - }
306 -
307 - $scenarioProcess = new \stdClass();
308 - $scenarioProcess->scenario_id = $scenario->id;
309 - $scenarioProcess->user_id = $userId;
310 - $scenarioProcess->start_at = acym_date('now', 'Y-m-d H:i:s', false);
311 - $scenarioProcess->id = $this->scenarioProcessClass->save($scenarioProcess);
312 -
313 - $this->createHistory($scenarioProcess->id, 'trigger', 'success');
314 -
315 - $this->handleStep($firstStep, $userId, $scenarioProcess->id);
316 - }
317 - }
318 - }
319 -
320 - private function createHistory(int $scenarioProcessId, string $type, string $result, string $scenarioStepId = '', array $params = [], string $log = ''): void
321 - {
322 - $scenarioHistoryLine = new \stdClass();
323 - $scenarioHistoryLine->scenario_process_id = $scenarioProcessId;
324 - $scenarioHistoryLine->date = acym_date('now', 'Y-m-d H:i:s', false);
325 - $scenarioHistoryLine->type = $type;
326 - $scenarioHistoryLine->result = $result;
327 -
328 - if (!empty($scenarioStepId)) {
329 - $scenarioHistoryLine->scenario_step_id = $scenarioStepId;
330 - }
331 -
332 - if (!empty($params)) {
333 - $scenarioHistoryLine->params = $params;
334 - }
335 -
336 - if (!empty($log)) {
337 - $scenarioHistoryLine->log = $log;
338 - }
339 -
340 - $this->scenarioHistoryLineClass->save($scenarioHistoryLine);
341 - }
342 -
343 - public function getConditionValue(object $step): string
344 - {
345 - return $step->params['condition'];
346 - }
347 -
348 - public function getActionValue(object $step): string
349 - {
350 - return $step->params['action'];
351 - }
352 -}