ActionScheduler_DBStore::claim_actionsprotectedWC 1.0

Mark actions claimed.

Method of the class: ActionScheduler_DBStore{}

Returns

Int. The number of actions that were claimed.

Usage

// protected - for code of main (parent) or child class
$result = $this->claim_actions( $claim_id, $limit, ?DateTime $before_date, $hooks, $group );
$claim_id(string) (required)
Claim Id.
$limit(int) (required)
Number of action to include in claim.
?DateTime $before_date
.
Default: null
$hooks(array)
Hooks to filter for.
Default: array()
$group(string)
Group to filter for.
Default: ''

ActionScheduler_DBStore::claim_actions() code WC 10.4.3

protected function claim_actions( $claim_id, $limit, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
	/**
	 * Global.
	 *
	 * @var \wpdb $wpdb
	 */
	global $wpdb;
	$now  = as_get_datetime_object();
	$date = is_null( $before_date ) ? $now : clone $before_date;

	// Set claim filters.
	if ( ! empty( $hooks ) ) {
		$this->set_claim_filter( 'hooks', $hooks );
	} else {
		$hooks = $this->get_claim_filter( 'hooks' );
	}
	if ( ! empty( $group ) ) {
		$this->set_claim_filter( 'group', $group );
	} else {
		$group = $this->get_claim_filter( 'group' );
	}

	$where        = 'WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s';
	$where_params = array(
		$date->format( 'Y-m-d H:i:s' ),
		self::STATUS_PENDING,
	);

	if ( ! empty( $hooks ) ) {
		$placeholders = array_fill( 0, count( $hooks ), '%s' );
		$where        .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
		$where_params = array_merge( $where_params, array_values( $hooks ) );
	}

	$group_operator = 'IN';
	if ( empty( $group ) ) {
		$group          = $this->get_claim_filter( 'exclude-groups' );
		$group_operator = 'NOT IN';
	}

	if ( ! empty( $group ) ) {
		$group_ids = $this->get_group_ids( $group, false );

		// throw exception if no matching group(s) found, this matches ActionScheduler_wpPostStore's behaviour.
		if ( empty( $group_ids ) ) {
			throw new InvalidArgumentException(
				sprintf(
					/* translators: %s: group name(s) */
					_n(
						'The group "%s" does not exist.',
						'The groups "%s" do not exist.',
						is_array( $group ) ? count( $group ) : 1,
						'woocommerce'
					),
					$group
				)
			);
		}

		$id_list = implode( ',', array_map( 'intval', $group_ids ) );
		$where  .= " AND group_id {$group_operator} ( $id_list )";
	}

	/**
	 * Sets the order-by clause used in the action claim query.
	 *
	 * @param string $order_by_sql
	 * @param string $claim_id Claim Id.
	 * @param array  $hooks    Hooks to filter for.
	 *
	 * @since 3.8.3 Made $claim_id and $hooks available.
	 * @since 3.4.0
	 */
	$order       = apply_filters( 'action_scheduler_claim_actions_order_by', 'ORDER BY priority ASC, attempts ASC, scheduled_date_gmt ASC, action_id ASC', $claim_id, $hooks );
	$skip_locked = $this->db_supports_skip_locked() ? ' SKIP LOCKED' : '';

	// Selecting the action_ids that we plan to claim, while skipping any locked rows to avoid deadlocking.
	$select_sql = $wpdb->prepare( "SELECT action_id from {$wpdb->actionscheduler_actions} {$where} {$order} LIMIT %d FOR UPDATE{$skip_locked}", array_merge( $where_params, array( $limit ) ) );

	// Now place it into an UPDATE statement by joining the result sets, allowing for the SKIP LOCKED behavior to take effect.
	$update_sql    = "UPDATE {$wpdb->actionscheduler_actions} t1 JOIN ( $select_sql ) t2 ON t1.action_id = t2.action_id SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
	$update_params = array(
		$claim_id,
		$now->format( 'Y-m-d H:i:s' ),
		current_time( 'mysql' ),
	);

	$rows_affected = $wpdb->query( $wpdb->prepare( $update_sql, $update_params ) );
	if ( false === $rows_affected ) {
		$error = empty( $wpdb->last_error )
			? _x( 'unknown', 'database error', 'woocommerce' )
			: $wpdb->last_error;
		throw new \RuntimeException(
			sprintf(
				/* translators: %s database error. */
				__( 'Unable to claim actions. Database error: %s.', 'woocommerce' ),
				$error
			)
		);
	}

	return (int) $rows_affected;
}