hooks_hooks(); } public function hooks_hooks() { add_filter( 'query_'.$this->slug.'_db_where_conditions', array( $this, 'date_filter_where_conditions' ), 10, 2 ); } public function date_filter_where_conditions( $where, $args ) { global $wpdb; if( ! empty( $args['action'] ) ) { if( is_array( $args['action'] ) ) { $actions = implode( ',', array_map( function ( $action ) { return '"' . sanitize_text_field ( $action ) . '"'; }, $args['action'] ) ); } else { $actions = sanitize_text_field( $args['action'] ); } $where .= " AND `action` IN( $actions ) "; } if ( !empty( $this->schema['date_queued'] ) ) { // Customers created for a specific date or in a date range if( ! empty( $args['date_queued'] ) ) { if( !is_array( $args['date_queued'] ) ) { if ( $args['date_queued'] == '0000-00-00 00:00:00' ) { $where .= " AND (`date_queued` = \"".$args['date_queued']."\" OR `date_queued` IS NULL ) "; } else { $where .= $wpdb->prepare( " AND `date_queued` = '" . '%s' . "' ", $args['date_queued'] ); } } } else { if( ! empty( $args['date_queued_min'] ) ) { $where .= $wpdb->prepare( " AND `date_queued` >= '" . '%s' . "' ", $args["date_queued_min"] ); } if( ! empty( $args['date_queued_max'] ) ) { $where .= $wpdb->prepare( " AND `date_queued` <= '" . '%s' . "' ", $args["date_queued_max"]); } } } if ( !empty( $this->schema['date_processed'] ) ) { // Customers created for a specific date or in a date range if( ! empty( $args['date_processed'] ) ) { if( !is_array( $args['date_processed'] ) ) { if ( $args['date_processed'] == '0000-00-00 00:00:00' ) { $where .= " AND (`date_processed` = \"".$args['date_processed']."\" OR `date_processed` IS NULL ) "; } else { $where .= $wpdb->prepare( " AND `date_processed` = '" . '%s' . "' ", $args['date_processed'] ); } } } else { if( ! empty( $args['date_processed_min'] ) ) { $where .= $wpdb->prepare( " AND `date_processed` >= '" . '%s' . "' ", $args["date_processed_min"] ); } if( ! empty( $args['date_processed_max'] ) ) { $where .= $wpdb->prepare( " AND `date_processed` <= '" . '%s' . "' ", $args["date_processed_max"] ); } } } if ( !empty( $this->schema['date_completed'] ) ) { // Customers created for a specific date or in a date range if( ! empty( $args['date_completed'] ) ) { if( !is_array( $args['date_completed'] ) ) { if ( $args['date_completed'] == '0000-00-00 00:00:00' ) { $where .= " AND (`date_completed` = \"".$args['date_completed']."\" OR `date_completed` IS NULL ) "; } else { $where .= $wpdb->prepare( " AND `date_completed` = '" . '%s' . "' ", $args['date_completed'] ); } } } else { if( ! empty( $args['date_completed_min'] ) ) { $where .= $wpdb->prepare( " AND `date_completed` >= '" . '%s' . "' ", $args["date_completed_min"] ); } if( ! empty( $args['date_completed_max'] ) ) { $where .= $wpdb->prepare( " AND `date_completed` <= '" . '%s' . "' ", $args["date_completed_max"] ); } } } return $where; } public function insert( $data, $type='' ) { if ( empty( $data['date_queued'] ) ) { $data['date_queued'] = gmdate( 'Y-m-d H:i:s' ); } return parent::insert( $data, $type ); } public function queue_action( $hook, $action = null, $priority = 10, $payload = array(), $object_type = null, $object_id = null, $action_group = null, $meta = array() ) { if ( empty( $action ) ) { $action = 'async_'.$hook; } $data = array( 'hook' => $hook, 'action' => $action, 'priority' => $priority, 'object_type' => $object_type, 'object_id' => $object_id, 'action_group' => $action_group, 'payload' => $payload, ); $meta = shortcode_atts( array( 'date_queued' => null, ), $meta ); foreach ($meta as $key => $value) { if ( empty( $value ) ) { continue; } $data[$key] = $value; } return $this->insert( $data ); } public function complete_action( $action_id, $response = array() ) { $this->update( $action_id, array( 'response' => $response, 'date_completed' => gmdate( 'Y-m-d H:i:s' ), ) ); } public function process( $query = array() ) { $query = shortcode_atts( array( 'date_processed' => '0000-00-00 00:00:00', 'orderby' => 'priority', 'order' => 'ASC', 'date_queued_max' => gmdate( 'Y-m-d H:i:s' ), ), $query ); $actions_to_do = $this->query( $query ); foreach ($actions_to_do as $key => $action_to_do) { if ( empty( $action_to_do['action'] ) ) { continue; } if ( empty( $action_to_do['date_queued'] ) || $action_to_do['date_queued'] > gmdate( 'Y-m-d H:i:s' ) ) { continue; } $action_to_do = $this->get( $action_to_do['id'] ); if ( !empty( $action_to_do['date_processed'] ) && $action_to_do['date_processed'] != '0000-00-00 00:00:00' ) { continue; } $action_to_do['date_processed'] = gmdate( 'Y-m-d H:i:s' ); $this->update( $action_to_do['id'], array( 'date_processed' => $action_to_do['date_processed'] ) ); do_action( $action_to_do['action'], $action_to_do['payload'], $action_to_do ); } if ( apply_filters( 'ssa/async/retry_incomplete_actions', false ) && empty( $action_to_do ) ) { // let's check for ones that started processing but never finished $ten_minutes_ago_ymd = gmdate( 'Y-m-d H:i:s', time()-600 ); $query = shortcode_atts( array( 'date_completed' => '0000-00-00 00:00:00', 'date_processed_max' => $ten_minutes_ago_ymd, 'date_processed_min' => gmdate( 'Y-m-d H:i:s', time() - HOUR_IN_SECONDS * 6 ), 'orderby' => 'priority', 'order' => 'ASC', 'date_queued_max' => gmdate( 'Y-m-d H:i:s' ), ), $query ); $actions_to_do = $this->query( $query ); foreach ($actions_to_do as $key => $action_to_do) { if ( empty( $action_to_do['action'] ) ) { continue; } if ( empty( $action_to_do['date_queued'] ) || $action_to_do['date_queued'] > gmdate( 'Y-m-d H:i:s' ) ) { continue; } $action_to_do = $this->get( $action_to_do['id'] ); if ( !empty( $action_to_do['date_processed'] ) && $action_to_do['date_processed'] > $ten_minutes_ago_ymd ) { // this already got picked up another time continue; } $action_to_do['date_processed'] = gmdate( 'Y-m-d H:i:s' ); $this->update( $action_to_do['id'], array( 'date_processed' => $action_to_do['date_processed'], 'date_completed' => $action_to_do['date_processed'], // we don't want it to infinitely loop, just try one more time ) ); do_action( $action_to_do['action'], $action_to_do['payload'], $action_to_do ); } } } protected $indexes = array( 'author_id' => [ 'author_id' ], 'hook' => [ 'hook' ], 'action' => [ 'action' ], 'date_queued' => [ 'date_queued' ], 'date_processed' => [ 'date_processed' ], 'date_completed' => [ 'date_completed' ], 'process_batch_token' => [ 'process_batch_token' ], ); protected $schema = array( 'author_id' => array( 'field' => 'author_id', 'label' => 'Author', 'default_value' => 0, 'format' => '%d', 'mysql_type' => 'BIGINT', 'mysql_length' => 11, 'mysql_unsigned' => true, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'hook' => array( 'field' => 'hook', 'label' => 'Hook', 'default_value' => '', 'format' => '%s', 'mysql_type' => 'VARCHAR', 'mysql_length' => 150, 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'action' => array( 'field' => 'action', 'label' => 'Action', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'VARCHAR', 'mysql_length' => '150', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'priority' => array( 'field' => 'priority', 'label' => 'Priority', 'default_value' => 10, 'format' => '%d', 'mysql_type' => 'INT', 'mysql_length' => '5', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'payload' => array( 'field' => 'payload', 'label' => 'Object Data', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'TEXT', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, 'type' => 'array', 'encoder' => 'json', ), 'object_type' => array( 'field' => 'object_type', 'label' => 'Object Type', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'VARCHAR', 'mysql_length' => '150', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'object_id' => array( 'field' => 'object_id', 'label' => 'Object ID', 'default_value' => 0, 'format' => '%d', 'mysql_type' => 'BIGINT', 'mysql_length' => 11, 'mysql_unsigned' => true, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'action_group' => array( 'field' => 'action_group', 'label' => 'Object Type', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'VARCHAR', 'mysql_length' => '150', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'response' => array( 'field' => 'response', 'label' => 'Response', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'TEXT', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, 'type' => 'array', 'encoder' => 'json', ), 'date_created' => array( 'field' => 'date_created', 'label' => 'Date Created', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'DATETIME', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => true, 'mysql_extra' => '', 'cache_key' => false, ), 'date_modified' => array( 'field' => 'date_modified', 'label' => 'Date Modified', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'DATETIME', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => true, 'mysql_extra' => '', 'cache_key' => false, ), 'date_queued' => array( 'field' => 'date_queued', 'label' => 'Date Queued', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'DATETIME', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => true, 'mysql_extra' => '', 'cache_key' => false, ), 'date_processed' => array( 'field' => 'date_processed', 'label' => 'Date Processed', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'DATETIME', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => true, 'mysql_extra' => '', 'cache_key' => false, ), 'process_batch_token' => array( 'field' => 'process_batch_token', 'label' => 'Process Batch Token', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'VARCHAR', 'mysql_length' => '50', 'mysql_unsigned' => false, 'mysql_allow_null' => false, 'mysql_extra' => '', 'cache_key' => false, ), 'date_completed' => array( 'field' => 'date_completed', 'label' => 'Date Completed', 'default_value' => false, 'format' => '%s', 'mysql_type' => 'DATETIME', 'mysql_length' => '', 'mysql_unsigned' => false, 'mysql_allow_null' => true, 'mysql_extra' => '', 'cache_key' => false, ), ); public function get_items_permissions_check( $request ) { return false; } public function get_item_permissions_check( $request ) { return false; } public function create_item_permissions_check( $request ) { return false; } public function update_item_permissions_check( $request ) { return false; } public function delete_item_permissions_check( $request ) { return false; } }