PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.3
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.3
6.0.3 6.0.2 6.0.1 6.0.0 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 5.7.9.2 5.7.9.1 5.7.8 5.7.9 5.7.6 5.7.7 5.7.5 5.7.4 5.7.3 5.7.2 5.7.1 trunk 5.6.0 5.6.1 All 34 releases
← All changes | includes/users.php +632 -0 5.7.8 → 6.0.3 View file →
@@ -1,0 +1,632 @@
1 +<?php
2 +/**
3 + * Users
4 + *
5 + * @package AutomatorWP\Users
6 + * @author AutomatorWP <[email protected]>, Ruben Garcia <[email protected]>
7 + * @since 1.0.0
8 + */
9 +// Exit if accessed directly
10 +if( !defined( 'ABSPATH' ) ) exit;
11 +
12 +/**
13 + * Get object completion times of a given object
14 + *
15 + * @since 1.0.0
16 + *
17 + * @param int $object_id The object ID
18 + * @param string $type The object type
19 + * @param int $since The user ID
20 + *
21 + * @return int
22 + */
23 +function automatorwp_get_object_completion_times( $object_id, $type, $since = 0 ) {
24 +
25 + global $wpdb;
26 +
27 + $object_id = absint( $object_id );
28 +
29 + // Check the object ID
30 + if( $object_id === 0 ) {
31 + return 0;
32 + }
33 +
34 + $types = automatorwp_get_log_types();
35 +
36 + // Check the type
37 + if( ! isset( $types[$type] ) ) {
38 + return 0;
39 + }
40 +
41 + // Since
42 + $date = false;
43 +
44 + if( absint( $since ) > 0 ) {
45 + $date = date( 'Y-m-d H:i:s', $since );
46 + }
47 +
48 + $ct_table = ct_setup_table( 'automatorwp_logs' );
49 +
50 + $completion_times = (int) $wpdb->get_var(
51 + "SELECT COUNT(*)
52 + FROM {$ct_table->db->table_name} AS l
53 + WHERE 1=1
54 + AND l.object_id = {$object_id}
55 + AND l.type = '{$type}' "
56 + . ( $date !== false ? "AND l.date > '{$date}'" : '' )
57 + );
58 +
59 + ct_reset_setup_table();
60 +
61 + return $completion_times;
62 +
63 +}
64 +
65 +/**
66 + * Get user completion times of a given object
67 + *
68 + * @since 1.0.0
69 + *
70 + * @param int $object_id The object ID
71 + * @param int $user_id The user ID
72 + * @param string $type The object type
73 + * @param int $since The user ID
74 + *
75 + * @return int
76 + */
77 +function automatorwp_get_user_completion_times( $object_id, $user_id, $type, $since = 0 ) {
78 +
79 + global $wpdb;
80 +
81 + $object_id = absint( $object_id );
82 +
83 + // Check the object ID
84 + if( $object_id === 0 ) {
85 + return 0;
86 + }
87 +
88 + $user_id = absint( $user_id );
89 +
90 + // Check the user ID
91 + if( $user_id === 0 ) {
92 + return 0;
93 + }
94 +
95 + $types = automatorwp_get_log_types();
96 +
97 + // Check the type
98 + if( ! isset( $types[$type] ) ) {
99 + return 0;
100 + }
101 +
102 + // Since
103 + $date = false;
104 +
105 + if( absint( $since ) > 0 ) {
106 + $date = date( 'Y-m-d H:i:s', $since );
107 + }
108 +
109 + $cache = automatorwp_get_cache( 'user_completion_times', array(), false );
110 +
111 + // If result already cached, return it
112 + if( isset( $cache[$user_id] )
113 + && isset( $cache[$user_id][$type] )
114 + && isset( $cache[$user_id][$type][$object_id] )
115 + && isset( $cache[$user_id][$type][$object_id][$date] ) ) {
116 +
117 + return $cache[$user_id][$type][$object_id][$date];
118 +
119 + }
120 +
121 + $ct_table = ct_setup_table( 'automatorwp_logs' );
122 +
123 + $completion_times = (int) $wpdb->get_var(
124 + "SELECT COUNT(*)
125 + FROM {$ct_table->db->table_name} AS l
126 + WHERE 1=1
127 + AND l.object_id = {$object_id}
128 + AND l.user_id = {$user_id}
129 + AND l.type = '{$type}' "
130 + . ( $date !== false ? "AND l.date > '{$date}'" : '' )
131 + );
132 +
133 + ct_reset_setup_table();
134 +
135 + // Cache function result
136 + if( ! isset( $cache[$user_id] ) ) {
137 + $cache[$user_id] = array();
138 + }
139 +
140 + if( ! isset( $cache[$user_id][$type] ) ) {
141 + $cache[$user_id][$type] = array();
142 + }
143 +
144 + if( ! isset( $cache[$user_id][$type][$object_id] ) ) {
145 + $cache[$user_id][$type][$object_id] = array();
146 + }
147 +
148 + $cache[$user_id][$type][$object_id][$date] = $completion_times;
149 +
150 + automatorwp_set_cache( 'user_completion_times', $cache );
151 +
152 + return $completion_times;
153 +
154 +}
155 +
156 +/**
157 + * Get user trigger completion times of a given object
158 + *
159 + * @since 1.0.0
160 + *
161 + * @param int $trigger_id The trigger ID
162 + * @param int $user_id The user ID
163 + *
164 + * @return int
165 + */
166 +function automatorwp_get_user_trigger_completion_times( $trigger_id, $user_id ) {
167 +
168 + $trigger = automatorwp_get_trigger_object( $trigger_id );
169 +
170 + if( ! $trigger ) {
171 + return 0;
172 + }
173 +
174 + // Get the last automation completion time (triggers always need to be based on this)
175 + $last_completion_time = automatorwp_get_user_last_completion_time( $trigger->automation_id, $user_id, 'automation' );
176 +
177 + return automatorwp_get_user_completion_times( $trigger->id, $user_id, 'trigger', $last_completion_time );
178 +
179 +}
180 +
181 +/**
182 + * Get user last object completion time
183 + *
184 + * @since 1.0.0
185 + *
186 + * @param int $object_id The object ID
187 + * @param int $user_id The user ID
188 + * @param string $type The object type (trigger|action|automation)
189 + *
190 + * @return int
191 + */
192 +function automatorwp_get_user_last_completion_time( $object_id, $user_id, $type ) {
193 +
194 + global $wpdb;
195 +
196 + $object_id = absint( $object_id );
197 +
198 + // Check the object ID
199 + if( $object_id === 0 ) {
200 + return 0;
201 + }
202 +
203 + $user_id = absint( $user_id );
204 +
205 + // Check the user ID
206 + if( $user_id === 0 ) {
207 + return 0;
208 + }
209 +
210 + $types = automatorwp_get_log_types();
211 +
212 + // Check the type
213 + if( ! isset( $types[$type] ) ) {
214 + return 0;
215 + }
216 +
217 + $cache = automatorwp_get_cache( 'user_last_completion_time', array(), false );
218 +
219 + // If result already cached, return it
220 + if( isset( $cache[$user_id] )
221 + && isset( $cache[$user_id][$type] )
222 + && isset( $cache[$user_id][$type][$object_id] ) ) {
223 + return $cache[$user_id][$type][$object_id];
224 + }
225 +
226 + $ct_table = ct_setup_table( 'automatorwp_logs' );
227 +
228 + $date = $wpdb->get_var(
229 + "SELECT l.date
230 + FROM {$ct_table->db->table_name} AS l
231 + WHERE 1=1
232 + AND l.object_id = {$object_id}
233 + AND l.user_id = {$user_id}
234 + AND l.type = '{$type}'
235 + ORDER BY l.date DESC
236 + LIMIT 1"
237 + );
238 +
239 + ct_reset_setup_table();
240 +
241 + if( $date ) {
242 + $result = strtotime( $date );
243 + } else {
244 + $result = 0;
245 + }
246 +
247 + // Cache function result
248 + if( ! isset( $cache[$user_id] ) ) {
249 + $cache[$user_id] = array();
250 + }
251 +
252 + if( ! isset( $cache[$user_id][$type] ) ) {
253 + $cache[$user_id][$type] = array();
254 + }
255 +
256 + $cache[$user_id][$type][$object_id] = $result;
257 +
258 + automatorwp_set_cache( 'user_last_completion_time', $cache );
259 +
260 + return $result;
261 +
262 +}
263 +
264 +/**
265 + * Get user last object completion log
266 + *
267 + * @since 1.0.0
268 + *
269 + * @param int $object_id The object ID
270 + * @param int $user_id The user ID
271 + * @param string $type The object type
272 + *
273 + * @return stdClass|false
274 + */
275 +function automatorwp_get_user_last_completion( $object_id, $user_id, $type ) {
276 +
277 + global $wpdb, $automatorwp_last_anonymous_trigger_log_id;
278 +
279 + $log = false;
280 +
281 + /**
282 + * Filter available to override the log entry to get the tags from
283 + *
284 + * @since 2.7.3
285 + *
286 + * @param stdClass $log The log object
287 + * @param stdClass $object_id The trigger object
288 + * @param int $user_id The user ID
289 + * @param string $type The content to parse
290 + *
291 + * @return stdClass|false
292 + */
293 + $log = apply_filters( 'automatorwp_get_user_last_completion', $log, $object_id, $user_id, $type );
294 +
295 + if( ! $log ) {
296 +
297 + $object_id = absint( $object_id );
298 +
299 + // Check the object ID
300 + if( $object_id === 0 ) {
301 + return false;
302 + }
303 +
304 + $types = automatorwp_get_log_types();
305 +
306 + // Check the type
307 + if( ! isset( $types[$type] ) ) {
308 + return false;
309 + }
310 +
311 + $user_id = absint( $user_id );
312 +
313 + // For backward compatibility, check if is trying to get a last anonymous trigger log ID
314 + if( $type === 'trigger' && $user_id === 0 && absint( $automatorwp_last_anonymous_trigger_log_id ) !== 0 ) {
315 +
316 + // Get the last anonymous trigger log if is parsing tags for an anonymous user
317 + $log = automatorwp_get_log_object( $automatorwp_last_anonymous_trigger_log_id );
318 +
319 + return ( $log ? $log : false );
320 + }
321 +
322 + // Check the user ID
323 + if( $user_id === 0 ) {
324 + return false;
325 + }
326 +
327 + $cache = automatorwp_get_cache( 'user_last_completion', array(), false );
328 +
329 + // If result already cached, return it
330 + if( isset( $cache[$user_id] )
331 + && isset( $cache[$user_id][$type] )
332 + && isset( $cache[$user_id][$type][$object_id] ) ) {
333 + return $cache[$user_id][$type][$object_id];
334 + }
335 +
336 + $ct_table = ct_setup_table( 'automatorwp_logs' );
337 +
338 + $log = $wpdb->get_row(
339 + "SELECT *
340 + FROM {$ct_table->db->table_name} AS l
341 + WHERE 1=1
342 + AND l.object_id = {$object_id}
343 + AND l.user_id = {$user_id}
344 + AND l.type = '{$type}'
345 + ORDER BY l.date DESC
346 + LIMIT 1"
347 + );
348 + }
349 +
350 + ct_reset_setup_table();
351 +
352 + $cache[$user_id][$type][$object_id] = $log;
353 +
354 + automatorwp_set_cache( 'user_last_completion', $cache );
355 +
356 + return $log;
357 +
358 +}
359 +
360 +/**
361 + * Clears the 'user_last_completion' and 'user_last_completion_time' every time a trigger, action or automation is completed.
362 + * Cache used on automatorwp_get_user_last_completion() and automatorwp_get_user_last_completion_time() functions.
363 + *
364 + * @since 1.0.0
365 + *
366 + * @param stdClass $object The trigger/action/filter/automation object
367 + * @param int $user_id The user ID
368 + * @param string $type The object type (only pass this parameter to force the type)
369 + */
370 +function automatorwp_clear_user_last_completion_cache( $object, $user_id, $type = '' ) {
371 +
372 + if( empty( $type ) ) {
373 + $type = str_replace( 'automatorwp_user_completed_', '', current_filter() );
374 + }
375 +
376 + $caches_to_clear = array(
377 + 'user_completion_times',
378 + 'user_last_completion',
379 + 'user_last_completion_time',
380 + );
381 +
382 + // Loop all caches to clear
383 + foreach( $caches_to_clear as $cache_to_clear ) {
384 +
385 + $cache = automatorwp_get_cache( $cache_to_clear, array(), false );
386 +
387 + if( isset( $cache[$user_id] )
388 + && isset( $cache[$user_id][$type] )
389 + && isset( $cache[$user_id][$type][$object->id] ) ) {
390 + // Clear the cache entry if exists
391 + unset( $cache[$user_id][$type][$object->id] );
392 + automatorwp_set_cache( $cache_to_clear, $cache );
393 + }
394 +
395 + }
396 +
397 +}
398 +add_action( 'automatorwp_user_completed_trigger', 'automatorwp_clear_user_last_completion_cache', 10, 2 );
399 +add_action( 'automatorwp_user_completed_action', 'automatorwp_clear_user_last_completion_cache', 10, 2 );
400 +add_action( 'automatorwp_user_completed_automation', 'automatorwp_clear_user_last_completion_cache', 10, 2 );
401 +
402 +/**
403 + * Check if user has completed the trigger
404 + *
405 + * @since 1.0.0
406 + *
407 + * @param int $trigger_id The trigger ID
408 + * @param int $user_id The user ID
409 + *
410 + * @return bool
411 + */
412 +function automatorwp_has_user_completed_trigger( $trigger_id, $user_id ) {
413 +
414 + $trigger = automatorwp_get_trigger_object( $trigger_id );
415 +
416 + if( ! $trigger ) {
417 + return false;
418 + }
419 +
420 + // Get the number of times the user has completed this trigger
421 + $completion_times = automatorwp_get_user_trigger_completion_times( $trigger->id, $user_id );
422 +
423 + // Get trigger required times
424 + $required_times = automatorwp_get_trigger_required_times( $trigger->id );
425 +
426 + // If user has not completed this trigger the number of times required then break to finish this function
427 + $completed = ( $completion_times >= $required_times );
428 +
429 + /**
430 + * Available filter to override if user has completed a trigger
431 + *
432 + * @since 1.0.0
433 + *
434 + * @param bool $completed True if user has completed the trigger
435 + * @param int $trigger_id The trigger ID
436 + * @param int $user_id The user ID
437 + *
438 + * @return bool
439 + */
440 + return apply_filters( 'automatorwp_has_user_completed_trigger', $completed, $trigger_id, $user_id );
441 +
442 +}
443 +
444 +/**
445 + * Check if has been executed all automation actions for an user
446 + *
447 + * @since 1.0.0
448 + *
449 + * @param int $automation_id The automation ID
450 + * @param int $user_id The user ID
451 + *
452 + * @return bool
453 + */
454 +function automatorwp_has_user_executed_all_automation_actions( $automation_id, $user_id ) {
455 +
456 + $automation = automatorwp_get_automation_object( $automation_id );
457 +
458 + if( ! $automation ) {
459 + return false;
460 + }
461 +
462 + $last_completion_time = automatorwp_get_user_last_completion_time( $automation->id, $user_id, 'automation' );
463 +
464 + $actions = automatorwp_get_automation_actions( $automation->id );
465 +
466 + $all_completed = true;
467 +
468 + foreach( $actions as $action ) {
469 +
470 + // Skip filters
471 + if( $action->type === 'filter' ) {
472 + continue;
473 + }
474 +
475 + // Check if action has not been completed
476 + if( ! automatorwp_get_user_completion_times( $action->id, $user_id, 'action', $last_completion_time ) ) {
477 +
478 + // If the action has filters, check if there is an entry for any of the filters
479 + $filters = automatorwp_get_action_filters( $action );
480 +
481 + if( count( $filters ) ) {
482 +
483 + $filter_registered = false;
484 +
485 + foreach( $filters as $filter ) {
486 +
487 + // Skip if a filter log entry have already found
488 + if( $filter_registered ) {
489 + continue;
490 + }
491 +
492 + // Check if there is a filter log entry registered for this action
493 + if( automatorwp_get_user_completion_times( $filter->id, $user_id, 'filter', $last_completion_time ) ) {
494 + $filter_registered = true;
495 + }
496 +
497 + }
498 +
499 + if( ! $filter_registered ) {
500 + // The action has not been executed yet
501 + $all_completed = false;
502 + break;
503 + }
504 +
505 + } else {
506 + // If the action does not have filters, them check it as not completed
507 + $all_completed = false;
508 + break;
509 + }
510 +
511 + }
512 +
513 + }
514 +
515 + return $all_completed;
516 +
517 +}
518 +
519 +/**
520 + * Get the trigger last completion log (used for parse tags replacements)
521 + *
522 + * @since 1.8.2
523 + *
524 + * @param stdClass $trigger The trigger object
525 + * @param int $user_id The user ID
526 + * @param string $content The content to parse
527 + *
528 + * @return array
529 + */
530 +function automatorwp_get_trigger_last_completion_log( $trigger, $user_id, $content = '' ) {
531 +
532 + global $automatorwp_last_anonymous_trigger_log_id, $automatorwp_event;
533 +
534 + $log = false;
535 +
536 + /**
537 + * Filter available to override the log entry to get the tags from
538 + *
539 + * @since 1.8.2
540 + *
541 + * @param stdClass $log The log object
542 + * @param stdClass $trigger The trigger object
543 + * @param int $user_id The user ID
544 + * @param string $content The content to parse
545 + *
546 + * @return stdClass|false
547 + */
548 + $log = apply_filters( 'automatorwp_get_trigger_last_completion_log', $log, $trigger, $user_id, $content );
549 +
550 + if( ! $log ) {
551 +
552 + $no_user_types = apply_filters( 'automatorwp_get_trigger_last_completion_log_no_user_types', array() );
553 +
554 + if( $user_id === 0 && absint( $automatorwp_last_anonymous_trigger_log_id ) !== 0 ) {
555 +
556 + // Get the last anonymous trigger log if parsing tags for an anonymous user
557 + $log = automatorwp_get_log_object( $automatorwp_last_anonymous_trigger_log_id );
558 +
559 + } else if ( in_array( $trigger->type, $no_user_types ) ) {
560 +
561 + // For automation loops, the log object is common to all entries
562 + $log = automatorwp_get_object_last_log( $trigger->id, 'trigger' );
563 +
564 + $log = apply_filters( 'automatorwp_get_trigger_last_completion_log_extend_log', $log, $trigger );
565 +
566 + } else {
567 +
568 + // Get the last trigger log (where data for tags replacement is)
569 + $log = automatorwp_get_user_last_completion( $trigger->id, $user_id, 'trigger' );
570 +
571 + }
572 +
573 + }
574 +
575 + return $log;
576 +
577 +}
578 +
579 +/**
580 + * Get the action last completion log (used for parse tags replacements)
581 + *
582 + * @since 1.8.2
583 + *
584 + * @param stdClass $action The action object
585 + * @param int $user_id The user ID
586 + * @param string $content The content to parse
587 + *
588 + * @return array
589 + */
590 +function automatorwp_get_action_last_completion_log( $action, $user_id, $content = '' ) {
591 +
592 + global $automatorwp_last_anonymous_trigger_log_id, $automatorwp_event;
593 +
594 + $log = false;
595 +
596 + /**
597 + * Filter available to override the log entry to get the tags from
598 + *
599 + * @since 1.8.2
600 + *
601 + * @param stdClass $log The log object
602 + * @param stdClass $action The action object
603 + * @param int $user_id The user ID
604 + * @param string $content The content to parse
605 + *
606 + * @return stdClass|false
607 + */
608 + $log = apply_filters( 'automatorwp_get_action_last_completion_log', $log, $action, $user_id, $content );
609 +
610 + if( ! $log ) {
611 +
612 + $no_user_types = apply_filters( 'automatorwp_get_action_last_completion_log_no_user_types', array() );
613 +
614 + if ( in_array( $action->type, $no_user_types ) ) {
615 +
616 + // For automation loops, the log object is common to all entries
617 + $log = automatorwp_get_object_last_log( $action->id, 'trigger' );
618 +
619 + $log = apply_filters( 'automatorwp_get_action_last_completion_log_extend_log', $log, $action );
620 +
621 + } else {
622 +
623 + // Get the last trigger log (where data for tags replacement is)
624 + $log = automatorwp_get_user_last_completion( $action->id, $user_id, 'action' );
625 +
626 + }
627 +
628 + }
629 +
630 + return $log;
631 +
632 +}