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.0.1 → 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)
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)
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)
110 - {
111 - $nextStep = $this->scenarioStepClass->getStepByPreviousStepId($step->id);
112 -
113 - if (empty($nextStep)) {
114 - $this->ending($step->scenario_id, $userId, $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)
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)
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($step->scenario_id, $userId, $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)
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($step->scenario_id, $userId, $scenarioProcessId);
225 -
226 - return;
227 - }
228 -
229 - $this->handleStep($nextStep, $userId, $scenarioProcessId);
230 - }
231 -
232 - private function ending(int $scenarioId, int $userId, int $scenarioProcessId)
233 - {
234 - $this->createHistory($scenarioProcessId, 'ending', acym_translation('ACYM_SCENARIO_ENDED'));
235 -
236 - $this->scenarioProcessClass->endProcess($scenarioProcessId);
237 - }
238 -
239 - public function executeAvailableSteps()
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 = '')
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(\stdClass $step): string
344 - {
345 - return $step->params['condition'];
346 - }
347 -
348 - public function getActionValue(\stdClass $step): string
349 - {
350 - return $step->params['action'];
351 - }
352 -}