Automator_Functions

Class Automator_Functions


Description Description

Development ready functions.


Source Source

File: src/core/lib/class-automator-functions.php

class Automator_Functions {

	/**
	 * @var
	 */
	public static $instance;
	/**
	 * Composite Class of integration, trigger, action, and closure registration functions
	 *
	 * @since    1.0.0
	 * @access   public
	 * @var Automator_Registration
	 */
	public $register;
	/**
	 * Collection of all recipe types
	 *
	 * @since    2.0.0
	 * @access   public
	 */
	public $recipe_types = array( 'user' );
	/**
	 * Collection of all integrations
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $integrations = array();
	/**
	 * Collection of all triggers
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $triggers = array();
	/**
	 * Collection of all actions
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $actions = array();
	/**
	 * Collection of all closures
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $closures = array();
	/**
	 * Triggers and actions for each recipe with data
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $recipes_data = array();
	/**
	 * Collection of all localized strings
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $i18n = array();
	/**
	 * @since    2.1
	 * @access   public
	 * @var Automator_Recipe_Process
	 */
	public $process;
	/**
	 *
	 * @since    2.1
	 * @access   public
	 * @var Automator_Recipe_Process_Complete
	 */
	public $complete;
	/**
	 * Composite Class of pre-defined Automator helper functions
	 *
	 * @since    2.1.0
	 * @access   public
	 * @var Automator_Helpers
	 */
	public $helpers;
	/**
	 * Composite Class of pre-defined Automator utilities
	 *
	 * @since    1.0.0
	 * @access   public
	 * @var Automator_Utilities
	 */
	public $utilities;
	/**
	 * Composite Class of data collection functions
	 *
	 * @since    1.0.0
	 * @access   public
	 * @var Automator_Get_Data
	 */
	public $get;
	/**
	 * Composite Class of pre-defined Automator tokens
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $tokens;
	/**
	 * Composite Class that checks plugin status
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $plugin_status;
	/**
	 * Composite Class that returns common error messages
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $error_message;
	/**
	 * Composite Class that returns an input that needs to have tokens replaced
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $parse;
	/**
	 * Collection of all Automator Email Variables
	 *
	 * @since    1.0.0
	 * @access   public
	 */
	public $defined_variables;

	/**
	 * System report
	 *
	 * @since    3.0.0
	 * @access   public
	 * @var Automator_System_Report
	 */
	public $system_report;

	/**
	 * @var Automator_WP_Error
	 */
	public $error;

	/**
	 * @var Automator_WP_Error
	 */
	public $exception;

	/**
	 * @var Automator_DB_Handler
	 */
	public $db;

	/**
	 * Initializes all development helper classes and variables via class composition
	 */
	public function __construct() {

		// Automator DB Handler
		require_once __DIR__ . '/utilities/db/class-automator-db-handler-tokens.php';
		require_once __DIR__ . '/utilities/db/class-automator-db-handler-closures.php';
		require_once __DIR__ . '/utilities/db/class-automator-db-handler-actions.php';
		require_once __DIR__ . '/utilities/db/class-automator-db-handler-triggers.php';
		require_once __DIR__ . '/utilities/db/class-automator-db-handler-recipes.php';
		require_once __DIR__ . '/utilities/db/class-automator-db-handler.php';
		$this->db = Automator_DB_Handler::get_instance();

		// Automator WP_Error Handler
		require_once __DIR__ . '/utilities/error/class-automator-wp-error.php';
		$this->error = Automator_WP_Error::get_instance();

		// Automator_Exception Handler
		require_once __DIR__ . '/utilities/error/class-automator-exception.php';
		$this->exception = Automator_Exception::get_instance();

		// Automator integration, trigger, action and closure registration
		require_once __DIR__ . '/utilities/class-automator-registration.php';
		$this->register = Automator_Registration::get_instance();

		// Automator integration, trigger, action and closure process
		require_once __DIR__ . '/process/class-automator-recipe-process.php';
		require_once __DIR__ . '/process/class-automator-recipe-process-user.php';
		$this->process = Automator_Recipe_Process::get_instance();

		// Automator integration, trigger, action and closure process
		require_once __DIR__ . '/process/class-automator-recipe-process-complete.php';
		$this->complete = Automator_Recipe_Process_Complete::get_instance();

		// Load pre-defined options for triggers, actions, and closures
		require_once __DIR__ . '/helpers/class-automator-helpers.php';
		require_once __DIR__ . '/helpers/class-automator-email-helpers.php';
		require_once __DIR__ . '/helpers/class-automator-recipe-helpers.php';
		require_once __DIR__ . '/helpers/class-automator-recipe-helpers-field.php';
		require_once __DIR__ . '/helpers/class-automator-trigger-condition-helpers.php';
		$this->helpers = Automator_Helpers::get_instance();

		// Load plugin status checks
		require_once __DIR__ . '/utilities/class-automator-integrations-status.php';
		$this->plugin_status = Automator_Integrations_Status::get_instance();

		// Load plugin status checks
		require_once __DIR__ . '/utilities/error/class-automator-error-messages.php';
		$this->error_message = Automator_Error_Messages::get_instance();

		// Load plugin status checks
		require_once UA_ABSPATH . 'src/core/lib/recipe-parts/trait-tokens.php';
		require_once __DIR__ . '/recipe-parts/tokens/class-automator-tokens.php';
		$this->tokens = Automator_Tokens::get_instance();

		// Load plugin status checks
		require_once __DIR__ . '/utilities/class-automator-input-parser.php';
		$this->parse = Automator_Input_Parser::get_instance();

		// Load plugin translated strings
		require_once __DIR__ . '/utilities/class-automator-translations.php';
		$this->i18n = Automator_Translations::get_instance();

		// Load plugin translated strings
		require_once __DIR__ . '/utilities/class-automator-utilities.php';
		$this->utilities = Automator_Utilities::get_instance();

		// Load plugin translated strings
		require_once __DIR__ . '/utilities/class-automator-get-data.php';
		$this->get = Automator_Get_Data::get_instance();

		// Load System report
		require_once __DIR__ . '/utilities/class-automator-system-report.php';
		$this->system_report = Automator_System_Report::get_instance();
	}

	/**
	 * @return \Uncanny_Automator\Automator_Functions
	 */
	public static function get_instance() {

		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * @param $integration_code
	 * @param $integration
	 */
	public function set_integrations( $integration_code, $integration ) {
		$this->integrations[ $integration_code ] = $integration;
	}

	/**
	 * @param $trigger
	 */
	public function set_triggers( $trigger ) {
		$this->triggers[] = $trigger;
	}

	/**
	 * @param $action
	 */
	public function set_actions( $action ) {
		$this->actions[] = $action;
	}

	/**
	 * @param $closure
	 */
	public function set_closures( $closure ) {
		$this->closures[] = $closure;
	}

	/**
	 * @param $recipe_type
	 * @param $details
	 */
	public function set_recipe_type( $recipe_type, $details ) {
		$this->recipe_types[ $recipe_type ] = $details;
	}

	/**
	 * Returns a filtered set on automator integrations
	 *
	 * @return array
	 */
	public function get_integrations() {
		$this->integrations = apply_filters_deprecated( 'uap_integrations', array( $this->integrations ), '3.0', 'automator_integrations' );

		return apply_filters( 'automator_integrations', $this->integrations );
	}

	/**
	 * Returns a filtered set on automator triggers
	 *
	 * @return array
	 */
	public function get_triggers() {
		$this->triggers = apply_filters_deprecated( 'uap_triggers', array( $this->triggers ), '3.0', 'automator_triggers' );

		return apply_filters( 'automator_triggers', $this->triggers );
	}

	/**
	 * Returns a filtered set on automator actions
	 *
	 * @return array
	 */
	public function get_actions() {
		$this->actions = apply_filters_deprecated( 'uap_actions', array( $this->actions ), '3.0', 'automator_actions' );

		return apply_filters( 'automator_actions', $this->actions );
	}

	/**
	 * Returns a filtered set on automator closures
	 *
	 * @return array
	 */
	public function get_closures() {
		$this->closures = apply_filters_deprecated( 'uap_closures', array( $this->closures ), '3.0', 'automator_closures' );

		return apply_filters( 'automator_closures', $this->closures );
	}

	/**
	 * Returns a recipe types for automator
	 *
	 * @return array
	 */
	public function get_recipe_types() {
		$this->recipe_types = apply_filters_deprecated( 'uap_recipe_types', array( $this->recipe_types ), '3.0', 'automator_recipe_types' );

		return apply_filters( 'automator_recipe_types', $this->recipe_types );
	}

	/**
	 * @param string $code
	 *
	 * @return mixed
	 */
	public function get_author_name( $code = '' ) {
		if ( ! empty( $code ) ) {
			$code   = strtolower( $code );
			$filter = "automator_{$code}_author_name";
		} else {
			$filter = 'automator_author_name';
		}

		return apply_filters( $filter, 'Uncanny Owl' );
	}

	/**
	 * @param string $code
	 * @param string $link
	 *
	 * @return mixed
	 */
	public function get_author_support_link( $code = '', $link = '' ) {
		$url = 'https://automatorplugin.com/';
		if ( ! empty( $code ) ) {
			$code   = strtolower( $code );
			$filter = "automator_{$code}_author_support_link";
		} else {
			$filter = 'automator_author_support_link';
		}
		if ( ! empty( $link ) ) {
			$url .= $link;
		}

		return apply_filters( $filter, $url );
	}

	/**
	 * Get data for all recipe objects
	 *
	 * @param bool $force_new_data_load
	 * @param null $recipe_id
	 *
	 * @return array
	 */
	public function get_recipes_data( $force_new_data_load = false, $recipe_id = null ) {
		if ( ( false === $force_new_data_load ) && ! empty( $this->recipes_data ) && null === $recipe_id ) {
			return $this->recipes_data;
		}

		// Accidentally sent recipe post instead of id?
		if ( $recipe_id instanceof \WP_Post && 'uo-recipe' === (string) $recipe_id->post_type ) {
			$recipe_id = $recipe_id->ID;
		}

		if ( null !== $recipe_id && is_numeric( $recipe_id ) ) {
			return $this->get_recipe_data_by_recipe_id( $recipe_id );
		}

		global $wpdb;

		$recipes = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_title, post_type, post_status, post_parent FROM $wpdb->posts WHERE post_type = %s ORDER BY ID DESC LIMIT 0, 99999", 'uo-recipe' ) );
		if ( empty( $recipes ) ) {
			return array();
		}
		//Extract Recipe IDs
		$recipe_ids = array_column( (array) $recipes, 'ID' );
		//Collective array of recipes triggers, actions, closures
		$recipe_data = $this->pre_fetch_recipe_metas( $recipes );
		//Collective array of users recipes completed status
		$recipes_completed = $this->are_recipes_completed( null, $recipe_ids );
		$recipes_completed = empty( $recipes_completed ) ? array() : $recipes_completed;
		$key               = 0;
		foreach ( $recipes as $recipe ) {
			$recipe_id = $recipe->ID;
			if ( array_key_exists( $recipe_id, $recipe_data ) && is_array( $recipe_data[ $recipe_id ] ) && array_key_exists( 'triggers', $recipe_data[ $recipe_id ] ) ) {
				if ( $recipe_data[ $recipe_id ]['triggers'] ) {
					//Grab tokens for each of trigger
					foreach ( $recipe_data[ $recipe_id ]['triggers'] as $t_id => $tr ) {
						$tokens = $this->tokens->trigger_tokens( $tr['meta'], $recipe_id );

						$recipe_data[ $recipe_id ]['triggers'][ $t_id ]['tokens'] = $tokens;
					}
				}
				$triggers = $recipe_data[ $recipe_id ]['triggers'];
			} else {
				$triggers = array();
			}

			$this->recipes_data[ $key ]['ID']          = $recipe_id;
			$this->recipes_data[ $key ]['post_status'] = $recipe->post_status;
			$this->recipes_data[ $key ]['recipe_type'] = Automator()->utilities->get_recipe_type( $recipe_id );

			$this->recipes_data[ $key ]['triggers'] = $triggers;

			if ( array_key_exists( $recipe_id, $recipe_data ) && is_array( $recipe_data[ $recipe_id ] ) && array_key_exists( 'actions', $recipe_data[ $recipe_id ] ) ) {
				$actions = $recipe_data[ $recipe_id ]['actions'];
			} else {
				$actions = array();
			}
			$this->recipes_data[ $key ]['actions'] = $actions;

			if ( array_key_exists( $recipe_id, $recipe_data ) && is_array( $recipe_data[ $recipe_id ] ) && array_key_exists( 'closures', $recipe_data[ $recipe_id ] ) ) {
				$closures = $recipe_data[ $recipe_id ]['closures'];
			} else {
				$closures = array();
			}
			$this->recipes_data[ $key ]['closures'] = $closures;

			$this->recipes_data[ $key ]['completed_by_current_user'] = array_key_exists( $recipe_id, $recipes_completed ) ? $recipes_completed[ $recipe_id ] : false;
			$key ++;
		}

		return $this->recipes_data;
	}

	/**
	 * @param null $recipe_id
	 *
	 * @return array
	 */
	public function get_recipe_data_by_recipe_id( $recipe_id = null ) {
		if ( null === $recipe_id ) {
			return array();
		}

		$recipe  = array();
		$recipes = get_post( $recipe_id );
		if ( ! $recipes ) {
			return array();
		}

		$is_recipe_completed           = $this->is_recipe_completed( $recipe_id );
		$key                           = $recipe_id;
		$recipe[ $key ]['ID']          = $recipe_id;
		$recipe[ $key ]['post_status'] = $recipes->post_status;
		$recipe[ $key ]['recipe_type'] = $this->utilities->get_recipe_type( $recipe_id );

		$triggers_array             = array();
		$triggers                   = $this->get_recipe_data( 'uo-trigger', $recipe_id, $triggers_array );
		$recipe[ $key ]['triggers'] = $triggers;

		$action_array              = array();
		$actions                   = $this->get_recipe_data( 'uo-action', $recipe_id, $action_array );
		$recipe[ $key ]['actions'] = $actions;

		$closure_array              = array();
		$closures                   = $this->get_recipe_data( 'uo-closure', $recipe_id, $closure_array );
		$recipe[ $key ]['closures'] = $closures;

		$recipe[ $key ]['completed_by_current_user'] = $is_recipe_completed;

		return $recipe;

	}

	/**
	 * @param array $recipes
	 *
	 * @return array
	 */
	public function pre_fetch_recipe_metas( $recipes = array() ) {
		$metas    = array();
		$triggers = array();
		$actions  = array();
		$closures = array();
		if ( ! empty( $recipes ) ) {

			global $wpdb;
			// Fetch uo-trigger, uo-action, uo-closure.
			$recipe_children = $wpdb->get_results( "SELECT ID, post_status, post_type
													FROM $wpdb->posts
													WHERE post_parent IN (SELECT ID
													FROM $wpdb->posts
													WHERE post_type = 'uo-recipe')" );

			if ( $recipe_children ) {
				foreach ( $recipe_children as $p ) {
					$ID  = $p->ID;
					$p_t = $p->post_type;
					$p_s = $p->post_status;
					switch ( $p_t ) {
						case 'uo-trigger':
							$triggers[ $ID ] = [ 'ID' => $ID, 'post_status' => $p_s, ];
							break;
						case 'uo-action':
							$actions[ $ID ] = [ 'ID' => $ID, 'post_status' => $p_s, ];
							break;
						case 'uo-closure':
							$closures[ $ID ] = [ 'ID' => $ID, 'post_status' => $p_s, ];
							break;
					}
				}
			}

			///END
			//////////////////////
			//////////////////////

			//////////////////////
			//////////////////////
			//////////////////////
			/////Fetch metas for uo-trigger, uo-action, uo-closure
			$q             = $wpdb->prepare( "SELECT pm.post_id, pm.meta_key, pm.meta_value, p.post_parent, p.post_type
														FROM $wpdb->postmeta pm
														LEFT JOIN $wpdb->posts p
														ON p.ID = pm.post_id
														WHERE pm.post_id IN (SELECT ID
														FROM $wpdb->posts
														WHERE post_parent IN (SELECT ID
														FROM $wpdb->posts
														WHERE post_type = %s))", 'uo-recipe' );
			$related_metas = $wpdb->get_results( $q );

			if ( $related_metas ) {
				foreach ( $related_metas as $p ) {
					$ID  = $p->post_id;
					$m_k = $p->meta_key;
					$m_v = $p->meta_value;
					if ( array_key_exists( $ID, $triggers ) ) {
						$triggers[ $ID ]['meta'][ $m_k ] = $m_v;
					} elseif ( array_key_exists( $ID, $actions ) ) {
						$actions[ $ID ]['meta'][ $m_k ] = $m_v;
					} elseif ( array_key_exists( $ID, $closures ) ) {
						$closures[ $ID ]['meta'][ $m_k ] = $m_v;
					}
				}
			}
			//Fix missing metas!
			if ( $triggers ) {
				foreach ( $triggers as $trigger_ID => $array ) {
					if ( ! array_key_exists( 'meta', $array ) ) {
						$triggers[ $trigger_ID ]['meta'] = [ 'code' => '' ];
					} elseif ( array_key_exists( 'meta', $array ) ) {
						//Attempt to return Trigger ID for magic button
						foreach ( $array['meta'] as $mk => $mv ) {
							if ( 'code' === (string) trim( $mk ) && 'WPMAGICBUTTON' === (string) trim( $mv ) ) {
								$triggers[ $trigger_ID ]['meta']['WPMAGICBUTTON'] = $trigger_ID;
							}
						}
					}
				}
			}

			///END
			//////////////////////
			//////////////////////

			/////Build old recipe array style
			foreach ( $related_metas as $r ) {
				$recipe_id     = absint( $r->post_parent );
				$non_recipe_id = absint( $r->post_id );
				switch ( $r->post_type ) {
					case 'uo-trigger':
						if ( array_key_exists( $non_recipe_id, $triggers ) ) {
							$metas[ $recipe_id ]['triggers'][] = $triggers[ $non_recipe_id ];
							unset( $triggers[ $non_recipe_id ] );
						}
						break;
					case 'uo-action':
						if ( array_key_exists( $non_recipe_id, $actions ) ) {
							$metas[ $recipe_id ]['actions'][] = $actions[ $non_recipe_id ];
							unset( $actions[ $non_recipe_id ] );
						}
						break;
					case 'uo-closure':
						if ( array_key_exists( $non_recipe_id, $closures ) ) {
							$metas[ $recipe_id ]['closures'][] = $closures[ $non_recipe_id ];
							unset( $closures[ $non_recipe_id ] );
						}
						break;
				}
			}
		}

		return $metas;
	}

	/**
	 * Check if the recipe was completed
	 *
	 * @param null $user_id
	 * @param array $recipe_ids
	 *
	 * @return array
	 */
	public function are_recipes_completed( $user_id = null, $recipe_ids = array() ) {

		if ( empty( $recipe_ids ) ) {
			Automator()->error->trigger( 'You are trying to check if a recipe is completed without providing a recipe_ids.' );

			return null;
		}

		// Set user ID
		if ( null === $user_id ) {
			$user_id = get_current_user_id();
		}

		// No user id is available.
		if ( 0 === $user_id ) {
			Automator()->error->trigger( 'You are trying to check if a recipe is completed when a there is no logged in user.' );

			return null;
		}

		$completed = array();
		global $wpdb;
		$results = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT COUNT(completed) AS completed, automator_recipe_id
					FROM {$wpdb->prefix}uap_recipe_log
WHERE user_id = %d AND automator_recipe_id IN (" . join( ',', $recipe_ids ) . ")
  AND completed = 1
  GROUP BY automator_recipe_id", $user_id )
		);

		if ( $results ) {
			foreach ( $recipe_ids as $recipe_id ) {
				$complete = 0;
				$found    = false;
				foreach ( $results as $r ) {
					if ( $recipe_id === (int) $r->automator_recipe_id ) {
						$found    = true;
						$complete = $r->completed;
						break;
					} else {
						$found = false;
					}
				}

				if ( $found ) {
					$completed[ $recipe_id ] = $complete;
				} else {
					$completed[ $recipe_id ] = 0;
				}
			}
		} else {
			//Fallback to mark every recipe incomplete
			foreach ( $recipe_ids as $recipe_id ) {
				$completed[ $recipe_id ] = 0;
			}
		}

		return $this->utilities->recipes_number_times_completed( $recipe_ids, $completed );
	}

	/**
	 * Check if the recipe was completed
	 *
	 * @param null $recipe_id
	 * @param null $user_id
	 *
	 * @return null|bool
	 */
	public function is_recipe_completed( $recipe_id = null, $user_id = null ) {

		if ( null === $recipe_id || ! is_numeric( $recipe_id ) ) {
			Automator()->error->trigger( 'You are trying to check if a recipe is completed without providing a recipe_id.' );

			return null;
		}

		/**
		 * If recipe is completed maximum number of times, bail.
		 *
		 * @since 3.0
		 */
		if ( $this->is_recipe_completed_max_times( $recipe_id ) ) {
			return true;
		}

		if ( ! is_user_logged_in() ) {
			return null;
		}

		// Set user ID
		if ( is_null( $user_id ) ) {
			$user_id = get_current_user_id();
		}

		global $wpdb;
		$results = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(completed) AS num_times_completed
						FROM {$wpdb->prefix}uap_recipe_log
						WHERE 1=1
						AND user_id = %d
						AND automator_recipe_id = %d
						AND completed = 1",
				$user_id,
				$recipe_id
			)
		);

		if ( 0 === $results ) {
			return false;
		}

		$results = empty( $results ) ? 0 : $results;

		return $this->utilities->recipe_number_times_completed( $recipe_id, $results );
	}

	/**
	 * @param null $recipe_id
	 *
	 * @return bool|null
	 */
	public function is_recipe_completed_max_times( $recipe_id = null ) {

		if ( null === $recipe_id || ! is_numeric( $recipe_id ) ) {
			Automator()->error->add_error( 'is_recipe_completed', 'ERROR: You are trying to check if a recipe is completed without providing a recipe_id.', $this );

			return null;
		}

		global $wpdb;
		$results = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(completed) AS num_times_completed
						FROM {$wpdb->prefix}uap_recipe_log
						WHERE 1=1
						AND automator_recipe_id = %d
						AND completed = 1",
				$recipe_id
			)
		);

		if ( 0 === $results ) {
			return false;
		}
		$results = empty( $results ) ? 0 : $results;

		return $this->utilities->recipe_max_times_completed( $recipe_id, $results );
	}

	/**
	 * Get saved data for recipe actions or triggers
	 *
	 * @param null $type
	 * @param null $recipe_id
	 * @param array $recipe_children
	 * @param null $matched_trigger
	 *
	 * @return null
	 */
	public function get_recipe_data( $type = null, $recipe_id = null, $recipe_children = array(), $matched_trigger = null ) {

		if ( null === $type ) {
			return null;
		}

		if ( ! in_array( $type, array( 'uo-trigger', 'uo-action', 'uo-closure' ), true ) ) {
			return null;
		}

		if ( is_null( $recipe_id ) || ! is_numeric( $recipe_id ) ) {
			Automator()->error->trigger( 'You are trying to get recipe data without providing a recipe_id' );

			return null;
		}

		global $wpdb;
		if ( empty( $recipe_children ) ) {
			$q = $wpdb->prepare( "SELECT ID, post_status FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", $recipe_id, $type );
			$q = apply_filters_deprecated(
				'q_get_recipe_data',
				array(
					$q,
					$recipe_id,
					$type,
				),
				'3.0',
				'automator_get_recipe_data_query'
			);
			$q = apply_filters( 'automator_get_recipe_data_query', $q, $recipe_id, $type );

			// All the triggers associated with the recipe
			$recipe_children = $wpdb->get_results( $q, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		}
		// All data for recipe triggers
		$recipe_children_data = array();
		if ( empty( $recipe_children ) ) {
			return $recipe_children_data;
		}
		// Check each trigger for set values
		foreach ( $recipe_children as $key => $child ) {
			// Collect all meta data for this trigger
			if ( ! array_key_exists( 'meta', $child ) ) {
				$child_meta = get_post_custom( $child['ID'] );
			} else {
				$child_meta = $child['meta'];
			}

			if ( ! $child_meta ) {
				continue;
			}
			// Get post custom return an array for each meta_key as there maybe more than one value per key.. we only store and need one value
			$child_meta_single = array();
			foreach ( $child_meta as $meta_key => $meta_value ) {
				$child_meta_single[ $meta_key ] = reset( $meta_value );
			}
			$code = array_key_exists( 'code', $child_meta_single ) ? $child_meta_single['code'] : '';

			/** Fix to show MAGIC BUTTON ID
			 *
			 * @since 3.0
			 * @package Uncanny_Automator
			 */
			if ( 'WPMAGICBUTTON' === (string) $code && ! array_key_exists( 'WPMAGICBUTTON', $child_meta_single ) ) {
				$child_meta_single['WPMAGICBUTTON'] = $child['ID'];
			}

			$item_not_found = true;

			if ( 'uo-trigger' === $type ) {
				$system_triggers = $this->get_triggers();
				if ( ! empty( $system_triggers ) ) {
					foreach ( $system_triggers as $trigger ) {
						if ( $trigger['code'] === $code ) {
							$item_not_found = false;
						}
					}
				} else {
					$item_not_found = false;
				}
			}

			if ( 'uo-action' === $type ) {
				$system_actions = $this->get_actions();
				if ( ! empty( $system_actions ) ) {
					foreach ( $system_actions as $action ) {
						if ( $action['code'] === $code ) {
							$item_not_found = false;
						}
					}
				} else {
					$item_not_found = false;
				}
			}

			if ( 'uo-closure' === $type ) {
				$system_closures = $this->get_closures();
				if ( ! empty( $system_closures ) ) {
					foreach ( $system_closures as $closure ) {
						if ( $closure['code'] === $code ) {
							$item_not_found = false;
						}
					}
				} else {
					$item_not_found = false;
				}
			}

			if ( $item_not_found ) {
				$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_status = 'draft' WHERE ID = %d", absint( $child['ID'] ) ) );
				$child['post_status'] = 'draft';
			}

			// The trigger is create/stored automatically but may not have been saved. Delete if not saved!
			if ( empty( $child_meta ) && isset( $child['ID'] ) ) {
				continue;
			}

			$recipe_children_data[ $key ]['ID']          = absint( $child['ID'] );
			$recipe_children_data[ $key ]['post_status'] = $child['post_status'];
			$recipe_children_data[ $key ]['meta']        = $child_meta_single;

			if ( 'uo-trigger' === $type ) {
				$recipe_children_data[ $key ]['tokens'] = $this->tokens->trigger_tokens( $child_meta_single, $recipe_id );
			}
		}

		return apply_filters(
			'automator_recipe_children_data',
			$recipe_children_data,
			array(
				'type'            => $type,
				'recipe_id'       => $recipe_id,
				'recipe_children' => $recipe_children,
			)
		);
	}

	/**
	 * Added this function to directly fetch trigger data instead of looping thru
	 * recipe and it's triggers for parsing. Specially needed for multi-trigger
	 * parsing
	 *
	 * @param int $recipe_id
	 * @param int $trigger_id
	 *
	 * @return array|mixed
	 * @since  2.9
	 * @author Saad S.
	 */
	public function get_trigger_data( $recipe_id = 0, $trigger_id = 0 ) {
		$recipe_data = $this->get_recipe_data( 'uo-trigger', $recipe_id );
		if ( ! $recipe_data ) {
			return array();
		}
		foreach ( $recipe_data as $trigger_data ) {
			if ( absint( $trigger_id ) !== absint( $trigger_data['ID'] ) ) {
				continue;
			}

			return $trigger_data;
		}

		return array();
	}

	/**
	 * Complete the action for the user
	 *
	 * @param null $user_id
	 * @param null $action_data
	 * @param null $recipe_id
	 * @param string $error_message
	 * @param null $recipe_log_id
	 *
	 * @param array $args
	 *
	 * @return null
	 * @deprecated 3.0
	 */
	public function complete_action( $user_id = null, $action_data = null, $recipe_id = null, $error_message = '', $recipe_log_id = null, $args = array() ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'complete_actions', 'Please use Automator()->complete->action() instead.', 3.0 );
		}

		return $this->complete->action( $user_id, $action_data, $recipe_id, $error_message, $recipe_log_id, $args );
	}

	/**
	 * Complete a recipe
	 *
	 * @param $recipe_id     null||int
	 * @param $user_id       null||int
	 * @param $recipe_log_id null||int
	 *
	 * @param array $args
	 *
	 * @return null|true
	 * @deprecated 3.0
	 */
	public function complete_recipe( $recipe_id = null, $user_id = null, $recipe_log_id = null, $args = array() ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'complete_recipe', 'Please use Automator()->complete->recipe() instead.', 3.0 );
		}

		return $this->complete->recipe( $recipe_id, $user_id, $recipe_log_id, $args );
	}

	/**
	 * Complete all actions in recipe
	 *
	 * @param null $recipe_id
	 * @param null $user_id
	 * @param null $recipe_log_id
	 *
	 * @param array $args
	 *
	 * @return bool
	 * @deprecated 3.0
	 */
	public function complete_actions( $recipe_id = null, $user_id = null, $recipe_log_id = null, $args = array() ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'complete_actions', 'Please use Automator()->complete->complete_actions() instead.', 3.0 );
		}

		return $this->complete->complete_actions( $recipe_id, $user_id, $recipe_log_id, $args );
	}

	/**
	 * Complete all closures in recipe
	 *
	 * @param null $recipe_id
	 * @param null $user_id
	 * @param null $recipe_log_id
	 * @param array $args
	 *
	 * @return bool
	 * @deprecated 3.0
	 *
	 */
	public function complete_closures( $recipe_id = null, $user_id = null, $recipe_log_id = null, $args = array() ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'complete_closures', 'Please use Automator()->complete->closures() instead.', 3.0 );
		}

		return $this->complete->closures( $recipe_id, $user_id, $recipe_log_id, $args );
	}

	/**
	 * Insert the trigger for the user
	 *
	 * @param $args
	 *
	 * @return null
	 * @deprecated 3.0
	 */
	public function insert_trigger_meta( $args ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'insert_trigger_meta', 'Please use Automator()->process->user->insert_trigger_meta() instead.', 3.0 );
		}

		return $this->process->user->insert_trigger_meta( $args );
	}

	/**
	 *
	 * Complete a trigger once all validation & trigger entry added
	 * and number of times met, complete the trigger
	 *
	 * @param $args
	 *
	 * @return bool
	 * @deprecated 3.0
	 */
	public function maybe_trigger_complete( $args ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'maybe_trigger_complete', 'Please use Automator()->process->user->maybe_trigger_complete() instead.', 3.0 );
		}

		return $this->process->user->maybe_trigger_complete( $args );
	}

	/**
	 * Complete the trigger for the user
	 *
	 * @param array $args
	 *
	 * @return null
	 * @deprecated 3.0
	 */
	public function complete_trigger( $args = array() ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'complete_trigger', 'Please use Automator()->complete->trigger() instead.', 3.0 );
		}

		return $this->complete->trigger( $args );
	}

	/**
	 *
	 * Matches recipes against trigger meta/code. If a recipe is found and not completed,
	 * add a trigger entry in to the DB and matches number of times.
	 *
	 * @param      $args
	 * @param bool $mark_trigger_complete
	 *
	 * @return array|bool|int|null
	 * @deprecated 3.0
	 */
	public function maybe_add_trigger_entry( $args, $mark_trigger_complete = true ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'maybe_add_trigger_entry', 'Please use Automator()->process->user->maybe_add_trigger_entry() instead.', 3.0 );
		}

		return $this->process->user->maybe_add_trigger_entry( $args, $mark_trigger_complete );
	}


	/**
	 * @param int $recipe_id
	 * @param int $user_id
	 * @param bool $create_recipe
	 * @param array $args
	 * @param bool $maybe_simulate
	 * @param null $maybe_add_log_id
	 *
	 * @return array
	 * @since  2.0
	 * @deprecated 3.0
	 * @author Saad S. on Nov 15th, 2019
	 *
	 * Added $maybe_simulate in order to avoid unnecessary recipe logs in database.
	 * It'll return existing $recipe_log_id if there's one for a user & recipe, or
	 * simulate an ID for the next run.. The reason for simulate is to avoid unnecessary
	 * recipe_logs in the database since we insert recipe log first & check if trigger
	 * is valid after which means, recipe log is added and not used in this run.
	 * Once trigger is validated.. I pass $maybe_simulate ID to $maybe_add_log_id
	 * and insert recipe log at this point.
	 *
	 */
	public function maybe_create_recipe_log_entry( $recipe_id, $user_id, $create_recipe = true, $args = array(), $maybe_simulate = false, $maybe_add_log_id = null ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'maybe_create_recipe_log_entry', 'Please use Automator()->process->user->maybe_create_recipe_log_entry() instead.', 3.0 );
		}

		return $this->process->user->maybe_create_recipe_log_entry( $recipe_id, $user_id, $create_recipe, $args, $maybe_simulate, $maybe_add_log_id );
	}

	/**
	 *
	 * Record an entry in to DB against a trigger
	 *
	 * @param      $user_id
	 * @param      $trigger_id
	 * @param      $recipe_id
	 * @param null $recipe_log_id
	 *
	 * @return array
	 * @deprecated 3.0
	 */
	public function maybe_get_trigger_id( $user_id, $trigger_id, $recipe_id, $recipe_log_id = null ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'maybe_get_trigger_id', 'Please use Automator()->process->user->maybe_get_trigger_id() instead.', 3.0 );
		}

		return $this->process->user->maybe_get_trigger_id( $user_id, $trigger_id, $recipe_id, $recipe_log_id );
	}

	/**
	 * @param        $data
	 * @param string $type
	 *
	 * @return string
	 * @deprecated 3.0
	 */
	public function uap_sanitize( $data, $type = 'text' ) {
		if ( defined( 'AUTOMATOR_DEBUG_MODE' ) && true === AUTOMATOR_DEBUG_MODE ) {
			_doing_it_wrong( 'uap_sanitize', 'Please use Automator()->utilities->automator_sanitize() instead.', 3.0 );
		}

		return $this->utilities->automator_sanitize( $data, $type );
	}

	/**
	 * @param $args
	 * @param bool $check
	 *
	 * @return bool
	 */
	public function is_user_signed_in( $args, bool $check = true ) {
		$is_signed_in = array_key_exists( 'is_signed_in', $args ) ? $args['is_signed_in'] : false;

		return true === $is_signed_in ? $is_signed_in : true === $check && is_user_logged_in();
	}
}

Top ↑

Methods Methods