PluginProbe
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI / 6.0.2
AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI v6.0.2
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 5.6.2 All 33 releases
automatorwp / classes / automation-loop.php

automation-loop.php in AutomatorWP – No-Code Workflow Automation, Integration & Webhooks Plugin, now with AI 6.0.2, at classes/automation-loop.php

811 lines 28.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Automation Loop
4 *
5 * @package AutomatorWP\Classes\Automation_Loop
6 * @author AutomatorWP <contact@automatorwp.com>, Ruben Garcia <rubengcdev@gmail.com>
7 * @since 1.0.0
8 */
9 // Exit if accessed directly
10 if( !defined( 'ABSPATH' ) ) exit;
11
12 class AutomatorWP_Automation_Loop extends AutomatorWP_Automation_Type {
13
14 /**
15 * Type
16 *
17 * @since 1.0.0
18 *
19 * @var array $args
20 */
21 public $args = array(
22 'image' => AUTOMATORWP_URL . 'assets/img/automatorwp-logo.svg',
23 'label' => '',
24 'desc' => '',
25 'labels' => array(
26 'singular' => '',
27 'plural' => '',
28 ),
29 'required_trigger' => '',
30 );
31
32 /**
33 * Process the given items IDs to run the automation actions on them
34 *
35 * @since 2.2.2
36 *
37 * @param array $items_ids The items IDs array.
38 * @param stdClass $automation The automation object.
39 * @param stdClass $trigger The trigger object. null if required_trigger is empty
40 * @param array $trigger_options The trigger options array. An empty array if required_trigger is empty
41 *
42 * @return array|false
43 */
44 public function process_items( $items_ids, $automation, $trigger, $trigger_options ) {
45 // Override
46 }
47
48 /**
49 * Get the items count
50 *
51 * @since 2.2.2
52 *
53 * @param stdClass $automation The automation object.
54 * @param stdClass $trigger The trigger object. null if required_trigger is empty
55 *
56 * @return int|false
57 */
58 public function get_items_count( $automation, $trigger ) {
59 // OVERRIDE in case the items count is not from the database
60
61 global $wpdb;
62
63 // Get the posts SQL
64 $sql = $this->get_items_sql( $automation, $trigger, true );
65
66 if( ! $sql ) {
67 return false;
68 }
69
70 return absint( $wpdb->get_var( $sql ) );
71 }
72
73 /**
74 * Get the items IDs
75 *
76 * @since 2.2.2
77 *
78 * @param stdClass $automation The automation object.
79 * @param stdClass $trigger The trigger object. null if required_trigger is empty
80 *
81 * @return array|false
82 */
83 public function get_items_ids( $automation, $trigger ) {
84 // OVERRIDE in case the items count is not from the database
85
86 global $wpdb;
87
88 // Get the posts SQL
89 $sql = $this->get_items_sql( $automation, $trigger, false );
90
91 if( ! $sql ) {
92 return false;
93 }
94
95 return $wpdb->get_col( $sql );
96 }
97
98 /**
99 * Get the items SQL (used for count and get ids)
100 *
101 * @since 2.2.2
102 *
103 * @param stdClass $automation The automation object.
104 * @param stdClass $trigger The trigger object.
105 *
106 * @return string|false
107 */
108 public function get_items_sql( $automation, $trigger, $count = false ) {
109
110 global $automatorwp_run_automation_error;
111
112 if( ! is_object( $automation ) ) {
113 $automatorwp_run_automation_error = __( 'Invalid automation.', 'automatorwp' );
114 return false;
115 }
116
117 $loop = 0;
118 $items_per_loop = 0;
119
120 if( ! $count ) {
121 $items_per_loop = absint( automatorwp_get_automation_meta( $automation->id, 'items_per_loop', true ) );
122
123 // Bail if users per loop not correctly configured
124 if( $items_per_loop <= 0 ) {
125 $automatorwp_run_automation_error = sprintf( __( '%s per loop needs to be higher than 0.', 'automatorwp' ), $this->args['labels']['plural'] );
126 return false;
127 }
128
129 // Get the loop stored in options to calculate the offset
130 $loop = absint( automatorwp_get_automation_meta( $automation->id, 'current_loop', true ) );
131 }
132
133 $trigger_options = array();
134
135 if( $trigger ) {
136 // Get the trigger stored options
137 $trigger_options = automatorwp_get_trigger_stored_options( $trigger->id );
138 }
139
140 $sql = false;
141
142 /**
143 * Available filter to override the all users automation SQL (overwritten by the trigger)
144 *
145 * @since 2.2.2
146 *
147 * @param string $sql The SQL query
148 * @param stdClass $automation The automation object
149 * @param stdClass $trigger The trigger object
150 * @param bool $count True if is looking for the SQL to count the number of users
151 * @param array $trigger_options The trigger's stored options
152 * @param int $items_per_loop The automation items per loop option
153 * @param int $loop The current loop
154 */
155 $sql = apply_filters( "automatorwp_get_{$this->type}_automation_sql", $sql, $automation, $trigger, $count, $trigger_options, $items_per_loop, $loop );
156
157 return $sql;
158
159 }
160
161 public function hooks() {
162
163 // Register as loop type
164 add_filter( 'automatorwp_automation_loop_types', array( $this, 'register_as_automation_loop_type' ), 10, 1 );
165
166 // On insert/update hooks
167 add_action( 'cmb2_admin_init', array( $this, 'meta_boxes' ), 9 );
168 add_filter( 'automatorwp_automation_ui_admin_body_class', array( $this, 'automation_ui_admin_body_class' ), 10, 2 );
169
170 add_action( 'ct_insert_object', array( $this, 'on_insert_automation' ), 10, 3 );
171 add_action( 'ct_insert_object', array( $this, 'on_update_automation' ), 10, 3 );
172
173 add_filter( 'automatorwp_check_automation_required_triggers', array( $this, 'automation_required_triggers' ), 10, 2 );
174
175 // Run automation hooks
176 add_action('automatorwp_ajax_run_automation', array( $this, 'ajax_run_automation' ) );
177
178 add_filter( 'automatorwp_get_automation_run_details_count', array( $this, 'automation_run_details_count' ), 10, 2 );
179
180 add_filter( 'automatorwp_run_automation_result', array( $this, 'maybe_run_automation' ), 10, 2 );
181
182 parent::hooks();
183
184 }
185
186 /**
187 * Register the automation loop type
188 *
189 * @since 2.2.2
190 *
191 * @param array $loop_types The automation loop types.
192 *
193 * @return array
194 */
195 public function register_as_automation_loop_type( $loop_types ) {
196
197 $loop_types[] = $this->type;
198
199 return $loop_types;
200
201 }
202
203 /**
204 * Register custom CMB2 meta boxes
205 *
206 * @since 1.0.0
207 */
208 public function meta_boxes() {
209
210 // Execution Options
211 $default_datetime = strtotime( date( 'Y-m-d 00:00:00', current_time( 'timestamp' ) ) );
212
213 automatorwp_add_meta_box(
214 'automatorwp-automations-execution-options',
215 __( 'Execution Options', 'automatorwp' ),
216 'automatorwp_automations',
217 array(
218 'items_per_loop' => array(
219 'type' => 'text',
220 'default' => '200',
221 'attributes' => array(
222 'type' => 'number',
223 'min' => '1',
224 ),
225 'before_field' => array( $this, 'items_per_loop_before_field' ),
226 'after_field' => array( $this, 'items_per_loop_after_field' ),
227 ),
228 'delay_amount' => array(
229 'type' => 'text',
230 'default' => '1',
231 'attributes' => array(
232 'type' => 'number',
233 'min' => '1',
234 ),
235 'before_field' => array( $this, 'delay_amount_before_field' ),
236 ),
237 'delay_seconds' => array(
238 'type' => 'select',
239 'options' => array(
240 MINUTE_IN_SECONDS => __( 'Minutes', 'automatorwp' ),
241 HOUR_IN_SECONDS => __( 'Hours', 'automatorwp' ),
242 DAY_IN_SECONDS => __( 'Days', 'automatorwp' ),
243 MONTH_IN_SECONDS => __( 'Months', 'automatorwp' ),
244 YEAR_IN_SECONDS => __( 'Years', 'automatorwp' ),
245 ),
246 ),
247 'schedule_run' => array(
248 'name' => '<div class="dashicons dashicons-calendar-alt"></div>' . __( 'Schedule execution:', 'automatorwp' ),
249 'type' => 'checkbox',
250 'classes' => 'cmb2-switch',
251 ),
252 'schedule_run_datetime' => array(
253 'name' => __( 'Execute this automation on:', 'automatorwp' ),
254 'type' => 'text_datetime_timestamp',
255 'date_format' => automatorwp_get_date_format( array( 'Y-m-d', 'm/d/Y' ) ),
256 'time_format' => automatorwp_get_time_format(),
257 'default' => $default_datetime,
258 ),
259 'recurring_run' => array(
260 'name' => '<div class="dashicons dashicons-backup"></div>' . __( 'Recurring execution:', 'automatorwp' ),
261 'type' => 'checkbox',
262 'classes' => 'cmb2-switch',
263 ),
264 'recurring_run_day' => array(
265 'name' => __( 'Execute this automation:', 'automatorwp' ),
266 'desc' => __( 'of', 'automatorwp' ),
267 'type' => 'text',
268 'default' => '1',
269 'attributes' => array(
270 'type' => 'number',
271 'min' => '1',
272 'max' => '365',
273 ),
274 'before_row' => array( $this, 'recurring_run_day_before_row' ),
275 'before_field' => array( $this, 'recurring_run_day_before_field' ),
276 ),
277 'recurring_run_period' => array(
278 'name' => __( 'Period:', 'automatorwp' ),
279 'type' => 'select',
280 'default' => 'day',
281 'options' => array(
282 'day' => __( 'Every day', 'automatorwp' ),
283 'week' => __( 'every week', 'automatorwp' ),
284 'month' => __( 'every month', 'automatorwp' ),
285 'year' => __( 'every year', 'automatorwp' ),
286 )
287 ),
288 'recurring_run_time' => array(
289 'name' => __( 'at', 'automatorwp' ),
290 'type' => 'text_time',
291 'time_format' => automatorwp_get_time_format(),
292 'default' => date( automatorwp_get_time_format(), $default_datetime ),
293 'after_row' => array( $this, 'execute_options_actions' ),
294 ),
295 ),
296 array(
297 'priority' => 'default',
298 'context' => 'side',
299 'show_on_cb' => array( $this, 'execution_options_box_show_cb' ),
300 )
301 );
302
303 }
304
305 function get_automation_from_url() {
306
307 global $ct_table;
308
309 if( ! $ct_table ) {
310 return false;
311 }
312
313 if( $ct_table->name !== 'automatorwp_automations' ) {
314 return false;
315 }
316
317 $primary_key = $ct_table->db->primary_key;
318 $object_id = isset( $_GET[$primary_key] ) ? absint( $_GET[$primary_key] ) : 0;
319
320 $automation = ct_get_object( $object_id );
321
322 // Bail if automation doesn't exists
323 if( ! $automation ) {
324 return false;
325 }
326
327 return $automation;
328
329 }
330
331 public function items_per_loop_before_field() {
332 echo '<span class="automatorwp-items-per-loop-label-before">' . automatorwp_dashicon( 'controls-play' ) . __( 'Process', 'automatorwp' ) . '</span>';
333 }
334
335 public function items_per_loop_after_field() {
336
337 $automation = $this->get_automation_from_url();
338 $html = '<span class="automatorwp-items-per-loop-label-before">%s</span>';
339
340 // Bail if automation doesn't exists
341 if( ! $automation ) {
342 echo sprintf( $html, __( 'items per loop', 'automatorwp' ) );
343 return;
344 }
345
346 $automation_types = automatorwp_get_automation_types();
347
348 $label = sprintf( __( '%s per loop', 'automatorwp' ), strtolower( $automation_types[$automation->type]['labels']['plural'] ) );
349
350 echo sprintf( $html, $label );
351 }
352
353 public function delay_amount_before_field() {
354 echo '<span class="automatorwp-delay-amount-label-before">' . automatorwp_dashicon( 'filter' ) . __( 'Every', 'automatorwp' ) . '</span>';
355 }
356
357 /**
358 * Before recurring run day row
359 *
360 * @since 1.0.0
361 */
362 public function recurring_run_day_before_row() {
363 ?><label for="recurring_run_day" class="automatorwp-recurring-run-day-label"><?php _e( 'Execute this automation:', 'automatorwp' ); ?></label><?php
364 }
365
366 /**
367 * Before recurring run day field
368 *
369 * @since 1.0.0
370 */
371 public function recurring_run_day_before_field() {
372 ?><p class="cmb2-metabox-description"><?php _e( 'The day', 'automatorwp' ); ?></p><?php
373 }
374
375 /**
376 * Execute options actions
377 *
378 * @since 1.0.0
379 */
380 public function execute_options_actions() {
381
382 $automation = $this->get_automation_from_url();
383
384 // Bail if automation doesn't exists
385 if( ! $automation ) {
386 return;
387 }
388
389 // Check if automation has been scheduled to show the next run date
390 $schedule_run = (bool) automatorwp_get_automation_meta( $automation->id, 'schedule_run', true );
391 $recurring_run = (bool) automatorwp_get_automation_meta( $automation->id, 'recurring_run', true );
392 $next_run_date = automatorwp_get_automation_meta( $automation->id, 'next_run_date', true );
393
394 if( ( $schedule_run || $recurring_run ) && ! empty( $next_run_date ) ) :
395 $date_format = automatorwp_get_date_format();
396 $time_format = automatorwp_get_time_format(); ?>
397 <div class="automatorwp-next-run-date">
398 <span class="dashicons dashicons-controls-play"></span>
399 <?php _e( 'Next run:', 'automatorwp' ); ?>
400 <strong><?php echo date( $date_format . ' ' . $time_format, strtotime( $next_run_date ) ); ?></strong>
401 </div>
402 <?php endif;
403
404 // Setup vars for an automation in progress
405 if( $automation->status === 'in-progress' ) {
406 $original_status = automatorwp_get_automation_meta( $automation->id, 'original_status', true );
407 $details = automatorwp_get_automation_run_details( $automation );
408 }
409
410 ?>
411 <div id="major-publishing-actions">
412
413 <div class="automatorwp-run-automation <?php if( $automation->status === 'in-progress' ) : ?>automatorwp-is-running<?php endif; ?>" <?php if( $automation->status === 'in-progress' ) : ?>data-original-status="<?php echo esc_attr( $original_status ); ?>"<?php endif; ?>>
414 <button type="button" class="button button-primary button-large" <?php if( $automation->status === 'in-progress' ) : ?>disabled<?php endif; ?>>
415 <div class="automatorwp-run-automation-run-label" <?php if( $automation->status === 'in-progress' ) : ?>style="display: none;"<?php endif; ?>>
416 <span class="dashicons dashicons-controls-play"></span> <?php _e( 'Run automation', 'automatorwp' ); ?>
417 </div>
418 <div class="automatorwp-run-automation-running-label" <?php if( $automation->status !== 'in-progress' ) : ?>style="display: none;"<?php endif; ?>>
419 <span class="dashicons dashicons-update"></span> <?php _e( 'Running...', 'automatorwp' ); ?>
420 </div>
421 <div class="automatorwp-run-automation-done-label" style="display: none;">
422 <span class="dashicons dashicons-yes"></span> <?php _e( 'Done!', 'automatorwp' ); ?>
423 </div>
424 </button>
425 </div>
426
427 <div class="automatorwp-cancel-automation-run" <?php if( $automation->status !== 'in-progress' ) : ?>style="display: none;"<?php endif; ?>>
428 <button type="button" class="button automatorwp-button-danger button-large">
429 <div class="automatorwp-cancel-automation-run-cancel-label">
430 <?php _e( 'Cancel', 'automatorwp' ); ?>
431 </div>
432 <div class="automatorwp-cancel-automation-run-cancelling-label" style="display: none;">
433 <?php _e( 'Cancelling...', 'automatorwp' ); ?>
434 </div>
435 <div class="automatorwp-cancel-automation-run-done-label" style="display: none;">
436 <?php _e( 'Cancelled', 'automatorwp' ); ?>
437 </div>
438 </button>
439 </div>
440
441 <div class="clear"></div>
442
443 <div class="automatorwp-run-automation-progress" <?php if( $automation->status !== 'in-progress' ) : ?>style="display: none;"<?php endif; ?>>
444 <div class="automatorwp-run-automation-progress-bar">
445 <?php if( $automation->status === 'in-progress' ) : ?>
446 <div class="automatorwp-run-automation-progress-current-progress" style="width: <?php echo $details['percentage']; ?>%"></div>
447 <?php else : ?>
448 <div class="automatorwp-run-automation-progress-current-progress"></div>
449 <?php endif; ?>
450 </div>
451 <?php if( $automation->status === 'in-progress' ) : ?>
452 <div class="automatorwp-run-automation-progress-text"><?php echo $details['processed'] . '/' . $details['count']; ?></div>
453 <?php else : ?>
454 <div class="automatorwp-run-automation-progress-text">0/0</div>
455 <?php endif; ?>
456 </div>
457
458 <div class="clear"></div>
459
460 </div>
461
462 <?php
463 }
464
465 /**
466 * Execution options box show callback
467 *
468 * @since 1.0.0
469 *
470 * @param object $cmb CMB2 object
471 *
472 * @return bool True/false whether to show the metabox
473 */
474 public function execution_options_box_show_cb( $cmb ) {
475
476 global $ct_table;
477
478 if( ! $ct_table ) {
479 return false;
480 }
481
482 if( $ct_table->name !== 'automatorwp_automations' ) {
483 return false;
484 }
485
486 $object_id = $cmb->object_id();
487
488 $object = ct_get_object( $object_id );
489
490 return ( in_array( $object->type, automatorwp_get_automation_loop_types() ) );
491
492 }
493
494 function automation_ui_admin_body_class( $classes, $automation ) {
495
496 if( in_array( $automation->type, automatorwp_get_automation_loop_types() ) ) {
497 $classes .= ' is-automatorwp-loop';
498 }
499
500 return $classes;
501
502 }
503
504 /**
505 * Handler when a new automation is getting created
506 *
507 * @since 1.0.0
508 *
509 * @param int $object_id Object ID.
510 * @param stdClass $object Object.
511 * @param bool $update Whether this is an existing object being updated or not.
512 */
513 public function on_insert_automation( $object_id, $object, $update ) {
514
515 global $ct_table;
516
517 // If not is our custom table, return
518 if( $ct_table->name !== 'automatorwp_automations' ) {
519 return;
520 }
521
522 // Bail if updating
523 if( $update ) {
524 return;
525 }
526
527 // Check if is an loop automation
528 if( $object->type !== $this->type ) {
529 return;
530 }
531
532 /**
533 * Filter available to define the default items per loop option
534 *
535 * @since 1.0.0
536 *
537 * @param int $items_per_loop
538 *
539 * @return int
540 */
541 $items_per_loop = apply_filters( 'automatorwp_default_items_per_loop', 200 );
542
543 // Update the items per loop meta
544 ct_update_object_meta( $object_id, 'items_per_loop', $items_per_loop );
545
546 }
547
548 /**
549 * Handler when an automation is getting updated
550 *
551 * @since 1.0.0
552 *
553 * @param int $object_id Object ID.
554 * @param stdClass $object Object.
555 * @param bool $update Whether this is an existing object being updated or not.
556 */
557 public function on_update_automation( $object_id, $object, $update ) {
558
559 global $ct_table;
560
561 // If not is our custom table, return
562 if( $ct_table->name !== 'automatorwp_automations' ) {
563 return;
564 }
565
566 // Bail if not updating
567 if( ! $update ) {
568 return;
569 }
570
571 // Check if is an loop automation
572 if( $object->type !== $this->type ) {
573 return;
574 }
575
576 // Calculate the next run date based on settings submitted
577 automatorwp_update_automation_next_run_date( $object_id, true );
578 }
579
580 /**
581 * If required_trigger configure, ensures that the trigger is present when creating the automation
582 *
583 * @since 2.2.2
584 *
585 * @param array $triggers The automation triggers list.
586 * @param stdClass $automation The automation object.
587 *
588 * @return array
589 */
590 public function automation_required_triggers( $triggers, $automation ) {
591
592 if( $automation->type !== $this->type ) {
593 return $triggers;
594 }
595
596 if( $this->args['required_trigger'] === '' ) {
597 return $triggers;
598 }
599
600 // Creates the required trigger if not exists in the automation
601
602 $create = false;
603
604 // Check if the first action is the action required for anonymous automations
605 if( ! isset( $triggers[0] ) ) {
606 $create = true;
607 }
608
609 if( isset( $triggers[0] ) && $triggers[0]->type !== $this->args['required_trigger'] ) {
610 $create = true;
611 }
612
613 if( $create ) {
614 ct_setup_table( 'automatorwp_triggers' );
615
616 $trigger_args = automatorwp_get_trigger( $this->args['required_trigger'] );
617
618 // Setup the trigger data
619 $trigger_data = array(
620 'automation_id' => $automation->id,
621 'title' => $trigger_args['label'],
622 'type' => $this->args['required_trigger'],
623 'status' => 'active',
624 'position' => 0,
625 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
626 );
627
628 // Insert the new trigger
629 $trigger_id = ct_insert_object( $trigger_data );
630
631 if( $trigger_id ) {
632 $trigger_data['id'] = $trigger_id;
633
634 $trigger_data = (object) $trigger_data;
635
636 // Prepend the new trigger at start of the triggers list
637 array_unshift( $triggers, $trigger_data );
638 }
639
640 ct_reset_setup_table();
641 }
642
643
644 return $triggers;
645
646 }
647
648 /**
649 * Handles the ajax run for automation loop
650 *
651 * @since 2.2.2
652 *
653 * @param stdClass $automation The automation object.
654 */
655 public function ajax_run_automation( $automation ) {
656
657 if( $automation->type !== $this->type ) {
658 return;
659 }
660
661 $items_per_loop = ( isset( $_POST['items_per_loop'] ) ? absint( $_POST['items_per_loop'] ) : 0 );
662
663 if( $items_per_loop <= 0 ) {
664 wp_send_json_error( sprintf( __( '%s per loop need to be higher than 0.', 'automatorwp' ), $this->args['labels']['plural'] ) );
665 }
666
667 // Get the loop before gets updated
668 $loop = absint( automatorwp_get_automation_meta( $automation->id, 'current_loop', true ) );
669
670 // First loop checks
671 if( $loop === 0 ) {
672
673 // Update the items per loop
674 $stored_items_per_loop = absint( automatorwp_get_automation_meta( $automation->id, 'items_per_loop', true ) );
675
676 if( $items_per_loop !== $stored_items_per_loop ) {
677 automatorwp_update_automation_meta( $automation->id, 'items_per_loop', $items_per_loop );
678 }
679
680 // Update a flag to meet that is a manual run
681 automatorwp_update_automation_meta( $automation->id, 'manual_run', '1' );
682 }
683 }
684
685 /**
686 * Updates the automation run details count
687 *
688 * @since 2.2.2
689 *
690 * @param int $count The run details count.
691 * @param stdClass $automation The automation object.
692 *
693 * @return array
694 */
695 public function automation_run_details_count( $count, $automation ) {
696
697 global $automatorwp_run_automation_error;
698
699 if( ! is_object( $automation ) ) {
700 $automatorwp_run_automation_error = __( 'Invalid automation.', 'automatorwp' );
701 return $count;
702 }
703
704 if( $automation->type !== $this->type ) {
705 return $count;
706 }
707
708 $trigger = null;
709
710 if( $this->args['required_trigger'] !== '' ) {
711 $trigger = automatorwp_get_automation_trigger_by_type( $automation->id, $this->args['required_trigger'] );
712
713 // Prevent automations already in progress
714 if( ! $trigger ) {
715 $automatorwp_run_automation_error = __( 'Trigger configuration not found.', 'automatorwp' );
716 return $count;
717 }
718 }
719
720 return $this->get_items_count( $automation, $trigger );
721 }
722
723 /**
724 * Checks if should run automation
725 *
726 * @since 2.2.2
727 *
728 * @param array $run_details The automation run details.
729 * @param stdClass $automation The automation object.
730 *
731 * @return array
732 */
733 function maybe_run_automation( $result, $automation ) {
734
735 global $automatorwp_run_automation_error;
736
737 if( ! is_object( $automation ) ) {
738 $automatorwp_run_automation_error = __( 'Invalid automation.', 'automatorwp' );
739 return false;
740 }
741
742 if( $automation->type !== $this->type ) {
743 return $result;
744 }
745
746 $result = $this->run_automation( $automation );
747
748 return $result;
749
750 }
751
752 /**
753 * Run this automation
754 *
755 * @since 2.2.2
756 *
757 * @param stdClass $automation The automation object.
758 *
759 * @return bool True on success, false on failure
760 */
761 public function run_automation( $automation ) {
762
763 global $automatorwp_run_automation_error;
764
765 // Get the items per loop
766 $items_per_loop = absint( automatorwp_get_automation_meta( $automation->id, 'items_per_loop', true ) );
767
768 // Bail if items per loop not correctly configured
769 if( $items_per_loop <= 0 ) {
770 $automatorwp_run_automation_error = sprintf( __( '%s per loop needs to be higher than 0.', 'automatorwp' ), $this->args['labels']['plural'] );
771 return false;
772 }
773
774 $trigger = null;
775 $trigger_options = array();
776
777 if( $this->args['required_trigger'] !== '' ) {
778 // Get the required trigger
779 $trigger = automatorwp_get_automation_trigger_by_type( $automation->id, $this->args['required_trigger'] );
780
781 // Bail if trigger not found
782 if( ! $trigger ) {
783 $automatorwp_run_automation_error = __( 'Trigger configuration not found.', 'automatorwp' );
784 return false;
785 }
786
787 // Get the trigger stored options
788 $trigger_options = automatorwp_get_trigger_stored_options( $trigger->id );
789
790 }
791
792 // Update automation status to in progress
793 if( $automation->status !== 'in-progress' ) {
794 // Call the automation run started function
795 automatorwp_run_automation_started( $automation, $trigger, $trigger_options );
796 }
797
798 // Get the items ids to run the actions
799 $items_ids = $this->get_items_ids( $automation, $trigger );
800
801 if( $items_ids === false ) {
802 return false;
803 }
804
805 $this->process_items( $items_ids, $automation, $trigger, $trigger_options );
806
807 return true;
808
809 }
810
811 }