plugin updates

This commit is contained in:
Tony Volpe
2024-11-15 13:53:04 -05:00
parent 1293d604ca
commit 0238f0c4ca
2009 changed files with 163492 additions and 89543 deletions

View File

@@ -5,11 +5,11 @@
* Description: A robust scheduling library for use in WordPress plugins.
* Author: Automattic
* Author URI: https://automattic.com/
* Version: 3.8.1
* Version: 3.8.2
* License: GPLv3
* Requires at least: 6.2
* Tested up to: 6.5
* Requires PHP: 5.6
* Requires at least: 6.4
* Tested up to: 6.6
* Requires PHP: 7.0
*
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
*
@@ -29,29 +29,29 @@
* @package ActionScheduler
*/
if ( ! function_exists( 'action_scheduler_register_3_dot_8_dot_1' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.
if ( ! function_exists( 'action_scheduler_register_3_dot_8_dot_2' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.
if ( ! class_exists( 'ActionScheduler_Versions', false ) ) {
require_once __DIR__ . '/classes/ActionScheduler_Versions.php';
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
}
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_8_dot_1', 0, 0 ); // WRCS: DEFINED_VERSION.
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_8_dot_2', 0, 0 ); // WRCS: DEFINED_VERSION.
// phpcs:disable Generic.Functions.OpeningFunctionBraceKernighanRitchie.ContentAfterBrace
/**
* Registers this version of Action Scheduler.
*/
function action_scheduler_register_3_dot_8_dot_1() { // WRCS: DEFINED_VERSION.
function action_scheduler_register_3_dot_8_dot_2() { // WRCS: DEFINED_VERSION.
$versions = ActionScheduler_Versions::instance();
$versions->register( '3.8.1', 'action_scheduler_initialize_3_dot_8_dot_1' ); // WRCS: DEFINED_VERSION.
$versions->register( '3.8.2', 'action_scheduler_initialize_3_dot_8_dot_2' ); // WRCS: DEFINED_VERSION.
}
// phpcs:disable Generic.Functions.OpeningFunctionBraceKernighanRitchie.ContentAfterBrace
/**
* Initializes this version of Action Scheduler.
*/
function action_scheduler_initialize_3_dot_8_dot_1() { // WRCS: DEFINED_VERSION.
function action_scheduler_initialize_3_dot_8_dot_2() { // WRCS: DEFINED_VERSION.
// A final safety check is required even here, because historic versions of Action Scheduler
// followed a different pattern (in some unusual cases, we could reach this point and the
// ActionScheduler class is already defined—so we need to guard against that).
@@ -63,7 +63,7 @@ if ( ! function_exists( 'action_scheduler_register_3_dot_8_dot_1' ) && function_
// Support usage in themes - load this version if no plugin has loaded a version yet.
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
action_scheduler_initialize_3_dot_8_dot_1(); // WRCS: DEFINED_VERSION.
action_scheduler_initialize_3_dot_8_dot_2(); // WRCS: DEFINED_VERSION.
do_action( 'action_scheduler_pre_theme_init' );
ActionScheduler_Versions::initialize_latest_version();
}

View File

@@ -1,5 +1,11 @@
*** Changelog ***
= 3.8.2 - 2024-09-12 =
* Add missing parameter to the `pre_as_enqueue_async_action` hook.
* Bump minimum PHP version to 7.0.
* Bump minimum WordPress version to 6.4.
* Make the batch size adjustable during processing.
= 3.8.1 - 2024-06-20 =
* Fix typos.
* Improve the messaging in our unidentified action exceptions.

View File

@@ -4,20 +4,33 @@
* Class ActionScheduler_ActionClaim
*/
class ActionScheduler_ActionClaim {
/** @var string */
private $id = '';
/** @var int[] */
private $action_ids = array();
/**
* Construct.
*
* @param string $id Claim ID.
* @param int[] $action_ids Action IDs.
*/
public function __construct( $id, array $action_ids ) {
$this->id = $id;
$this->action_ids = $action_ids;
}
/**
* Get claim ID.
*/
public function get_id() {
return $this->id;
}
/**
* Get IDs of claimed actions.
*/
public function get_actions() {
return $this->action_ids;
}
}

View File

@@ -6,8 +6,10 @@
*/
class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
/** @var null|self */
private static $admin_view = NULL;
/** @var string */
private static $screen_id = 'tools_page_action-scheduler';
/** @var ActionScheduler_ListTable */
@@ -28,6 +30,8 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
}
/**
* Initialize.
*
* @codeCoverageIgnore
*/
public function init() {
@@ -45,6 +49,9 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
}
}
/**
* Print system status report.
*/
public function system_status_report() {
$table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() );
$table->render();
@@ -119,20 +126,20 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
*/
public function maybe_check_pastdue_actions() {
# Filter to prevent checking actions (ex: inappropriate user).
// Filter to prevent checking actions (ex: inappropriate user).
if ( ! apply_filters( 'action_scheduler_check_pastdue_actions', current_user_can( 'manage_options' ) ) ) {
return;
}
# Get last check transient.
// Get last check transient.
$last_check = get_transient( 'action_scheduler_last_pastdue_actions_check' );
# If transient exists, we're within interval, so bail.
// If transient exists, we're within interval, so bail.
if ( ! empty( $last_check ) ) {
return;
}
# Perform the check.
// Perform the check.
$this->check_pastdue_actions();
}
@@ -143,9 +150,9 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
*/
protected function check_pastdue_actions() {
# Set thresholds.
$threshold_seconds = ( int ) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS );
$threshold_min = ( int ) apply_filters( 'action_scheduler_pastdue_actions_min', 1 );
// Set thresholds.
$threshold_seconds = (int) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS );
$threshold_min = (int) apply_filters( 'action_scheduler_pastdue_actions_min', 1 );
// Set fallback value for past-due actions count.
$num_pastdue_actions = 0;
@@ -158,24 +165,24 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
return;
}
# Scheduled actions query arguments.
// Scheduled actions query arguments.
$query_args = array(
'date' => as_get_datetime_object( time() - $threshold_seconds ),
'status' => ActionScheduler_Store::STATUS_PENDING,
'per_page' => $threshold_min,
);
# If no third-party preempted, run default check.
// If no third-party preempted, run default check.
if ( is_null( $check ) ) {
$store = ActionScheduler_Store::instance();
$num_pastdue_actions = ( int ) $store->query_actions( $query_args, 'count' );
$num_pastdue_actions = (int) $store->query_actions( $query_args, 'count' );
# Check if past-due actions count is greater than or equal to threshold.
// Check if past-due actions count is greater than or equal to threshold.
$check = ( $num_pastdue_actions >= $threshold_min );
$check = ( bool ) apply_filters( 'action_scheduler_pastdue_actions_check', $check, $num_pastdue_actions, $threshold_seconds, $threshold_min );
$check = (bool) apply_filters( 'action_scheduler_pastdue_actions_check', $check, $num_pastdue_actions, $threshold_seconds, $threshold_min );
}
# If check failed, set transient and abort.
// If check failed, set transient and abort.
if ( ! boolval( $check ) ) {
$interval = apply_filters( 'action_scheduler_pastdue_actions_check_interval', round( $threshold_seconds / 4 ), $threshold_seconds );
set_transient( 'action_scheduler_last_pastdue_actions_check', time(), $interval );
@@ -189,7 +196,7 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
'order' => 'asc',
), admin_url( 'tools.php' ) );
# Print notice.
// Print notice.
echo '<div class="notice notice-warning"><p>';
printf(
// translators: 1) is the number of affected actions, 2) is a link to an admin screen.
@@ -204,7 +211,7 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
);
echo '</p></div>';
# Facilitate third-parties to evaluate and print notices.
// Facilitate third-parties to evaluate and print notices.
do_action( 'action_scheduler_pastdue_actions_extra_notices', $query_args );
}

View File

@@ -1,7 +1,4 @@
<?php
/**
* ActionScheduler_AsyncRequest_QueueRunner
*/
defined( 'ABSPATH' ) || exit;
@@ -35,7 +32,9 @@ class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request {
protected $action = 'async_request_queue_runner';
/**
* Initiate new async request
* Initiate new async request.
*
* @param ActionScheduler_Store $store Store object.
*/
public function __construct( ActionScheduler_Store $store ) {
parent::__construct();
@@ -49,7 +48,7 @@ class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request {
* if there are still pending actions after completing a queue in this request.
*/
protected function handle() {
do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context
do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context.
$sleep_seconds = $this->get_sleep_seconds();

View File

@@ -154,7 +154,7 @@ class ActionScheduler_DataController {
$wp_object_cache->cache = array();
if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) {
call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important
call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important!
}
}

View File

@@ -34,7 +34,7 @@ class ActionScheduler_DateTime extends DateTime {
*
* This represents a fixed offset instead of a timezone setting.
*
* @param $offset
* @param string|int $offset UTC offset value.
*/
public function setUtcOffset( $offset ) {
$this->utcOffset = intval( $offset );
@@ -54,7 +54,7 @@ class ActionScheduler_DateTime extends DateTime {
/**
* Set the TimeZone associated with the DateTime
*
* @param DateTimeZone $timezone
* @param DateTimeZone $timezone Timezone object.
*
* @return static
* @link http://php.net/manual/en/datetime.settimezone.php

View File

@@ -8,12 +8,23 @@ class ActionScheduler_FatalErrorMonitor {
private $claim = NULL;
/** @var ActionScheduler_Store */
private $store = NULL;
/** @var int */
private $action_id = 0;
/**
* Construct.
*
* @param ActionScheduler_Store $store Action store.
*/
public function __construct( ActionScheduler_Store $store ) {
$this->store = $store;
}
/**
* Start monitoring.
*
* @param ActionScheduler_ActionClaim $claim Claimed actions.
*/
public function attach( ActionScheduler_ActionClaim $claim ) {
$this->claim = $claim;
add_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) );
@@ -23,6 +34,9 @@ class ActionScheduler_FatalErrorMonitor {
add_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0, 0 );
}
/**
* Stop monitoring.
*/
public function detach() {
$this->claim = NULL;
$this->untrack_action();
@@ -33,16 +47,29 @@ class ActionScheduler_FatalErrorMonitor {
remove_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0 );
}
/**
* Track specified action.
*
* @param int $action_id Action ID to track.
*/
public function track_current_action( $action_id ) {
$this->action_id = $action_id;
}
/**
* Un-track action.
*/
public function untrack_action() {
$this->action_id = 0;
}
/**
* Handle unexpected shutdown.
*/
public function handle_unexpected_shutdown() {
if ( $error = error_get_last() ) {
$error = error_get_last();
if ( $error ) {
if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ) ) ) {
if ( !empty($this->action_id) ) {
$this->store->mark_failure( $this->action_id );

View File

@@ -13,6 +13,7 @@ class ActionScheduler_InvalidActionException extends \InvalidArgumentException i
* Create a new exception when the action's schedule cannot be fetched.
*
* @param string $action_id The action ID with bad args.
* @param mixed $schedule Passed schedule.
* @return static
*/
public static function from_schedule( $action_id, $schedule ) {
@@ -32,6 +33,7 @@ class ActionScheduler_InvalidActionException extends \InvalidArgumentException i
* @author Jeremy Pry
*
* @param string $action_id The action ID with bad args.
* @param mixed $args Passed arguments.
* @return static
*/
public static function from_decoding_args( $action_id, $args = array() ) {

View File

@@ -76,9 +76,9 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Sets the current data store object into `store->action` and initialises the object.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_Logger $logger
* @param ActionScheduler_QueueRunner $runner
* @param ActionScheduler_Store $store Store object.
* @param ActionScheduler_Logger $logger Logger object.
* @param ActionScheduler_QueueRunner $runner Runner object.
*/
public function __construct( ActionScheduler_Store $store, ActionScheduler_Logger $logger, ActionScheduler_QueueRunner $runner ) {
@@ -225,8 +225,9 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
}
$output = '';
$num_time_periods = count( self::$time_periods );
for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < count( self::$time_periods ) && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index++ ) {
for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < $num_time_periods && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index++ ) {
$periods_in_interval = floor( $seconds_remaining / self::$time_periods[ $time_period_index ]['seconds'] );
@@ -246,7 +247,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Returns the recurrence of an action or 'Non-repeating'. The output is human readable.
*
* @param ActionScheduler_Action $action
* @param ActionScheduler_Action $action Action object.
*
* @return string
*/
@@ -269,7 +270,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Serializes the argument of an action to render it in a human friendly format.
*
* @param array $row The array representation of the current row of the table
* @param array $row The array representation of the current row of the table.
*
* @return string
*/
@@ -311,8 +312,8 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
*
* @param ActionScheduler_LogEntry $log_entry
* @param DateTimezone $timezone
* @param ActionScheduler_LogEntry $log_entry Log entry object.
* @param DateTimezone $timezone Timestamp.
* @return string
*/
protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, DateTimezone $timezone ) {
@@ -324,8 +325,8 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Only display row actions for pending actions.
*
* @param array $row Row to render
* @param string $column_name Current row
* @param array $row Row to render.
* @param string $column_name Current row.
*
* @return string
*/
@@ -390,7 +391,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
$async_request_lock_expiration = ActionScheduler::lock()->get_expiration( 'async-request-runner' );
// No lock set or lock expired
// No lock set or lock expired.
if ( false === $async_request_lock_expiration || $async_request_lock_expiration < time() ) {
$in_progress_url = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) );
/* translators: %s: process URL */
@@ -449,7 +450,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Prints the scheduled date in a human friendly format.
*
* @param array $row The array representation of the current row of the table
* @param array $row The array representation of the current row of the table.
*
* @return string
*/
@@ -460,7 +461,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Get the scheduled date in a human friendly format.
*
* @param ActionScheduler_Schedule $schedule
* @param ActionScheduler_Schedule $schedule Action's schedule.
* @return string
*/
protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
@@ -492,13 +493,13 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
}
/**
* Bulk delete
* Bulk delete.
*
* Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data
* properly validated by the callee and it will delete the actions without any extra validation.
*
* @param array $ids
* @param string $ids_sql Inherited and unused
* @param int[] $ids Action IDs.
* @param string $ids_sql Inherited and unused.
*/
protected function bulk_delete( array $ids, $ids_sql ) {
foreach ( $ids as $id ) {
@@ -523,7 +524,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
* Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
* parameters are valid.
*
* @param int $action_id
* @param int $action_id Action ID.
*/
protected function row_action_cancel( $action_id ) {
$this->process_row_action( $action_id, 'cancel' );
@@ -533,7 +534,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
* Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
* parameters are valid.
*
* @param int $action_id
* @param int $action_id Action ID.
*/
protected function row_action_run( $action_id ) {
$this->process_row_action( $action_id, 'run' );
@@ -560,7 +561,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
/**
* Implements the logic behind processing an action once an action link is clicked on the list table.
*
* @param int $action_id
* @param int $action_id Action ID.
* @param string $row_action_type The type of action to perform on the action.
*/
protected function process_row_action( $action_id, $row_action_type ) {

View File

@@ -23,13 +23,12 @@ class ActionScheduler_LogEntry {
/**
* Constructor
*
* @param mixed $action_id Action ID
* @param string $message Message
* @param Datetime $date Datetime object with the time when this log entry was created. If this parameter is
* not provided a new Datetime object (with current time) will be created.
* @param mixed $action_id Action ID.
* @param string $message Message.
* @param Datetime $date Datetime object with the time when this log entry was created. If this parameter is
* not provided a new Datetime object (with current time) will be created.
*/
public function __construct( $action_id, $message, $date = null ) {
/*
* ActionScheduler_wpCommentLogger::get_entry() previously passed a 3rd param of $comment->comment_type
* to ActionScheduler_LogEntry::__construct(), goodness knows why, and the Follow-up Emails plugin
@@ -56,10 +55,16 @@ class ActionScheduler_LogEntry {
return $this->date;
}
/**
* Get action ID of log entry.
*/
public function get_action_id() {
return $this->action_id;
}
/**
* Get log entry message.
*/
public function get_message() {
return $this->message;
}

View File

@@ -4,8 +4,15 @@
* Class ActionScheduler_NullLogEntry
*/
class ActionScheduler_NullLogEntry extends ActionScheduler_LogEntry {
/**
* Construct.
*
* @param string $action_id Action ID.
* @param string $message Log entry.
*/
public function __construct( $action_id = '', $message = '' ) {
// nothing to see here
// nothing to see here.
}
}

View File

@@ -66,7 +66,6 @@ class ActionScheduler_QueueCleaner {
return array();
}
/**
* Filter the statuses when cleaning the queue.
*
@@ -83,7 +82,7 @@ class ActionScheduler_QueueCleaner {
* @param string[] $statuses_to_purge List of action statuses to purge. Defaults to canceled, complete.
* @param DateTime $cutoff_date Date limit for selecting actions. Defaults to 31 days ago.
* @param int|null $batch_size Maximum number of actions per status to delete. Defaults to 20.
* @param string $context Calling process context. Defaults to `old`.
* @param string $context Calling process context. Defaults to `old`.
* @return array Actions deleted.
*/
public function clean_actions( array $statuses_to_purge, DateTime $cutoff_date, $batch_size = null, $context = 'old' ) {
@@ -111,8 +110,10 @@ class ActionScheduler_QueueCleaner {
}
/**
* @param int[] $actions_to_delete List of action IDs to delete.
* @param int $lifespan Minimum scheduled age in seconds of the actions being deleted.
* Delete actions.
*
* @param int[] $actions_to_delete List of action IDs to delete.
* @param int $lifespan Minimum scheduled age in seconds of the actions being deleted.
* @param string $context Context of the delete request.
* @return array Deleted action IDs.
*/
@@ -159,7 +160,7 @@ class ActionScheduler_QueueCleaner {
if ( $timeout < 0 ) {
return;
}
$cutoff = as_get_datetime_object($timeout.' seconds ago');
$cutoff = as_get_datetime_object($timeout . ' seconds ago');
$actions_to_reset = $this->store->query_actions( array(
'status' => ActionScheduler_Store::STATUS_PENDING,
'modified' => $cutoff,
@@ -189,7 +190,7 @@ class ActionScheduler_QueueCleaner {
if ( $timeout < 0 ) {
return;
}
$cutoff = as_get_datetime_object($timeout.' seconds ago');
$cutoff = as_get_datetime_object($timeout . ' seconds ago');
$actions_to_reset = $this->store->query_actions( array(
'status' => ActionScheduler_Store::STATUS_RUNNING,
'modified' => $cutoff,

View File

@@ -32,9 +32,10 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
/**
* ActionScheduler_QueueRunner constructor.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_FatalErrorMonitor $monitor
* @param ActionScheduler_QueueCleaner $cleaner
* @param ActionScheduler_Store $store Store object.
* @param ActionScheduler_FatalErrorMonitor $monitor Monitor object.
* @param ActionScheduler_QueueCleaner $cleaner Cleaner object.
* @param ActionScheduler_AsyncRequest_QueueRunner $async_request Async request runner object.
*/
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null, ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) {
parent::__construct( $store, $monitor, $cleaner );
@@ -53,7 +54,7 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) );
// Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param
// Check for and remove any WP Cron hook scheduled by Action Scheduler < 3.0.0, which didn't include the $context param.
$next_timestamp = wp_next_scheduled( self::WP_CRON_HOOK );
if ( $next_timestamp ) {
wp_unschedule_event( $next_timestamp, self::WP_CRON_HOOK );
@@ -134,11 +135,11 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
$this->processed_actions_count = 0;
if ( false === $this->has_maximum_concurrent_batches() ) {
$batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
do {
$batch_size = apply_filters( 'action_scheduler_queue_runner_batch_size', 25 );
$processed_actions_in_batch = $this->do_batch( $batch_size, $context );
$this->processed_actions_count += $processed_actions_in_batch;
} while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory
} while ( $processed_actions_in_batch > 0 && ! $this->batch_limits_exceeded( $this->processed_actions_count ) ); // keep going until we run out of actions, time, or memory.
}
do_action( 'action_scheduler_after_process_queue' );
@@ -151,9 +152,9 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
* Actions are processed by claiming a set of pending actions then processing each one until either the batch
* size is completed, or memory or time limits are reached, defined by @see $this->batch_limits_exceeded().
*
* @param int $size The maximum number of actions to process in the batch.
* @param int $size The maximum number of actions to process in the batch.
* @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
* Generally, this should be capitalised and not localised as it's a proper noun.
* Generally, this should be capitalised and not localised as it's a proper noun.
* @return int The number of actions processed.
*/
protected function do_batch( $size = 100, $context = '' ) {
@@ -162,7 +163,7 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
$processed_actions = 0;
foreach ( $claim->get_actions() as $action_id ) {
// bail if we lost the claim
// bail if we lost the claim.
if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) {
break;
}
@@ -218,9 +219,15 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
}
}
/**
* Add schedule to WP cron.
*
* @param array<string, array<string, int|string>> $schedules Schedules.
* @return array<string, array<string, int|string>>
*/
public function add_wp_cron_schedule( $schedules ) {
$schedules['every_minute'] = array(
'interval' => 60, // in seconds
'interval' => 60, // in seconds.
'display' => __( 'Every minute', 'woocommerce' ),
);

View File

@@ -9,8 +9,15 @@ class ActionScheduler_Versions {
*/
private static $instance = NULL;
/** @var array<string, callable> */
private $versions = array();
/**
* Register version's callback.
*
* @param string $version_string Action Scheduler version.
* @param callable $initialization_callback Callback to initialize the version.
*/
public function register( $version_string, $initialization_callback ) {
if ( isset($this->versions[$version_string]) ) {
return FALSE;
@@ -19,10 +26,16 @@ class ActionScheduler_Versions {
return TRUE;
}
/**
* Get all versions.
*/
public function get_versions() {
return $this->versions;
}
/**
* Get latest version registered.
*/
public function latest_version() {
$keys = array_keys($this->versions);
if ( empty($keys) ) {
@@ -32,6 +45,9 @@ class ActionScheduler_Versions {
return end($keys);
}
/**
* Get callback for latest registered version.
*/
public function latest_version_callback() {
$latest = $this->latest_version();
if ( empty($latest) || !isset($this->versions[$latest]) ) {
@@ -59,4 +75,3 @@ class ActionScheduler_Versions {
call_user_func($self->latest_version_callback());
}
}

View File

@@ -42,10 +42,10 @@ class ActionScheduler_WPCommentCleaner {
// While there are orphaned logs left in the comments table, we need to attach the callbacks which filter comment counts.
add_action( 'pre_get_comments', array( self::$wp_comment_logger, 'filter_comment_queries' ), 10, 1 );
add_action( 'wp_count_comments', array( self::$wp_comment_logger, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
add_action( 'wp_count_comments', array( self::$wp_comment_logger, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs.
add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 );
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen.
add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) );
add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) );
}
@@ -90,7 +90,7 @@ class ActionScheduler_WPCommentCleaner {
public static function register_admin_notice() {
add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) );
}
/**
* Prints details about the orphaned action logs and includes information on where to learn more.
*/

View File

@@ -79,7 +79,7 @@ class ActionScheduler_WPCLI_Clean_Command extends WP_CLI_Command {
/**
* Print WP CLI message about how many batches of actions were processed.
*
* @param int $batches_processed
* @param int $batches_processed Number of batches processed.
*/
protected function print_total_batches( int $batches_processed ) {
WP_CLI::log(
@@ -111,7 +111,7 @@ class ActionScheduler_WPCLI_Clean_Command extends WP_CLI_Command {
/**
* Print a success message with the number of completed actions.
*
* @param int $actions_deleted
* @param int $actions_deleted Number of deleted actions.
*/
protected function print_success( int $actions_deleted ) {
WP_CLI::success(

View File

@@ -21,11 +21,11 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
/**
* ActionScheduler_WPCLI_QueueRunner constructor.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_FatalErrorMonitor $monitor
* @param ActionScheduler_QueueCleaner $cleaner
* @param ActionScheduler_Store $store Store object.
* @param ActionScheduler_FatalErrorMonitor $monitor Monitor object.
* @param ActionScheduler_QueueCleaner $cleaner Cleaner object.
*
* @throws Exception When this is not run within WP CLI
* @throws Exception When this is not run within WP CLI.
*/
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null ) {
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
@@ -131,7 +131,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
*
* @author Jeremy Pry
*
* @param $action_id
* @param int $action_id Action ID.
*/
public function before_execute( $action_id ) {
/* translators: %s refers to the action ID */
@@ -143,11 +143,11 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
*
* @author Jeremy Pry
*
* @param int $action_id
* @param int $action_id ActionID.
* @param null|ActionScheduler_Action $action The instance of the action. Default to null for backward compatibility.
*/
public function after_execute( $action_id, $action = null ) {
// backward compatibility
// backward compatibility.
if ( null === $action ) {
$action = $this->store->fetch_action( $action_id );
}
@@ -160,8 +160,8 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
*
* @author Jeremy Pry
*
* @param int $action_id
* @param Exception $exception
* @param int $action_id Action ID.
* @param Exception $exception Exception.
* @throws \WP_CLI\ExitException With failure message.
*/
public function action_failed( $action_id, $exception ) {
@@ -175,7 +175,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
/**
* Sleep and help avoid hitting memory limit
*
* @param int $sleep_time Amount of seconds to sleep
* @param int $sleep_time Amount of seconds to sleep.
* @deprecated 3.0.0
*/
protected function stop_the_insanity( $sleep_time = 0 ) {

View File

@@ -104,7 +104,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
// Custom queue cleaner instance.
$cleaner = new ActionScheduler_QueueCleaner( null, $clean );
// Get the queue runner instance
// Get the queue runner instance.
$runner = new ActionScheduler_WPCLI_QueueRunner( null, null, $cleaner );
// Determine how many tasks will be run in the first batch.
@@ -143,7 +143,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
*
* @author Jeremy Pry
*
* @param int $total
* @param int $total Number of actions found.
*/
protected function print_total_actions( $total ) {
WP_CLI::log(
@@ -160,7 +160,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
*
* @author Jeremy Pry
*
* @param int $batches_completed
* @param int $batches_completed Number of completed batches.
*/
protected function print_total_batches( $batches_completed ) {
WP_CLI::log(
@@ -196,7 +196,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
*
* @author Jeremy Pry
*
* @param int $actions_completed
* @param int $actions_completed Number of completed actions.
*/
protected function print_success( $actions_completed ) {
WP_CLI::success(

View File

@@ -93,7 +93,7 @@ class Migration_Command extends WP_CLI_Command {
} while ( $actions_processed > 0 );
if ( ! $config->get_dry_run() ) {
// let the scheduler know that there's nothing left to do
// let the scheduler know that there's nothing left to do.
$scheduler = new Scheduler();
$scheduler->mark_complete();
}

View File

@@ -39,7 +39,7 @@ class ProgressBar {
* @param integer $count Total number of ticks to be performed.
* @param integer $interval Optional. The interval in milliseconds between updates. Default 100.
*
* @throws Exception When this is not run within WP CLI
* @throws \Exception When this is not run within WP CLI.
*/
public function __construct( $message, $count, $interval = 100 ) {
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {

View File

@@ -8,12 +8,16 @@ use Action_Scheduler\Migration\Controller;
* @codeCoverageIgnore
*/
abstract class ActionScheduler {
/** @var string */
private static $plugin_file = '';
/** @var ActionScheduler_ActionFactory */
private static $factory = NULL;
/** @var bool */
private static $data_store_initialized = false;
/**
* Factory.
*/
public static function factory() {
if ( !isset(self::$factory) ) {
self::$factory = new ActionScheduler_ActionFactory();
@@ -21,22 +25,37 @@ abstract class ActionScheduler {
return self::$factory;
}
/**
* Get Store instance.
*/
public static function store() {
return ActionScheduler_Store::instance();
}
/**
* Get Lock instance.
*/
public static function lock() {
return ActionScheduler_Lock::instance();
}
/**
* Get Logger instance.
*/
public static function logger() {
return ActionScheduler_Logger::instance();
}
/**
* Get QueueRunner instance.
*/
public static function runner() {
return ActionScheduler_QueueRunner::instance();
}
/**
* Get AdminView instance.
*/
public static function admin_view() {
return ActionScheduler_AdminView::instance();
}
@@ -44,13 +63,13 @@ abstract class ActionScheduler {
/**
* Get the absolute system path to the plugin directory, or a file therein
* @static
* @param string $path
* @param string $path Path relative to plugin directory.
* @return string
*/
public static function plugin_path( $path ) {
$base = dirname(self::$plugin_file);
if ( $path ) {
return trailingslashit($base).$path;
return trailingslashit($base) . $path;
} else {
return untrailingslashit($base);
}
@@ -59,13 +78,18 @@ abstract class ActionScheduler {
/**
* Get the absolute URL to the plugin directory, or a file therein
* @static
* @param string $path
* @param string $path Path relative to plugin directory.
* @return string
*/
public static function plugin_url( $path ) {
return plugins_url($path, self::$plugin_file);
}
/**
* Autoload.
*
* @param string $class Class name.
*/
public static function autoload( $class ) {
$d = DIRECTORY_SEPARATOR;
$classes_dir = self::plugin_path( 'classes' . $d );
@@ -128,7 +152,7 @@ abstract class ActionScheduler {
* Initialize the plugin
*
* @static
* @param string $plugin_file
* @param string $plugin_file Plugin file path.
*/
public static function init( $plugin_file ) {
self::$plugin_file = $plugin_file;
@@ -149,7 +173,8 @@ abstract class ActionScheduler {
// Ensure initialization on plugin activation.
if ( ! did_action( 'init' ) ) {
add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init()
// phpcs:ignore Squiz.PHP.CommentedOutCode
add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init().
add_action( 'init', array( $store, 'init' ), 1, 0 );
add_action( 'init', array( $logger, 'init' ), 1, 0 );
add_action( 'init', array( $runner, 'init' ), 1, 0 );
@@ -308,18 +333,33 @@ abstract class ActionScheduler {
return isset( $cli_segments[ $segment ] ) && $cli_segments[ $segment ];
}
/**
* Clone.
*/
final public function __clone() {
trigger_error("Singleton. No cloning allowed!", E_USER_ERROR);
trigger_error('Singleton. No cloning allowed!', E_USER_ERROR);
}
/**
* Wakeup.
*/
final public function __wakeup() {
trigger_error("Singleton. No serialization allowed!", E_USER_ERROR);
trigger_error('Singleton. No serialization allowed!', E_USER_ERROR);
}
/**
* Construct.
*/
final private function __construct() {}
/** Deprecated **/
/**
* Get DateTime object.
*
* @param null|string $when Date/time string.
* @param string $timezone Timezone string.
*/
public static function get_datetime_object( $when = null, $timezone = 'UTC' ) {
_deprecated_function( __METHOD__, '2.0', 'wcs_add_months()' );
return as_get_datetime_object( $when, $timezone );

View File

@@ -27,9 +27,9 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
/**
* ActionScheduler_Abstract_QueueRunner constructor.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_FatalErrorMonitor $monitor
* @param ActionScheduler_QueueCleaner $cleaner
* @param ActionScheduler_Store $store Store object.
* @param ActionScheduler_FatalErrorMonitor $monitor Monitor object.
* @param ActionScheduler_QueueCleaner $cleaner Cleaner object.
*/
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null ) {
@@ -43,9 +43,10 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
/**
* Process an individual action.
*
* @param int $action_id The action ID to process.
* @param int $action_id The action ID to process.
* @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
* Generally, this should be capitalised and not localised as it's a proper noun.
* Generally, this should be capitalised and not localised as it's a proper noun.
* @throws \Exception When error running action.
*/
public function process_action( $action_id, $context = '' ) {
// Temporarily override the error handler while we process the current action.
@@ -141,8 +142,8 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
/**
* Schedule the next instance of the action if necessary.
*
* @param ActionScheduler_Action $action
* @param int $action_id
* @param ActionScheduler_Action $action Action.
* @param int $action_id Action ID.
*/
protected function schedule_next_instance( ActionScheduler_Action $action, $action_id ) {
// If a recurring action has been consistently failing, we may wish to stop rescheduling it.
@@ -256,7 +257,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
$time_limit = 30;
// Apply deprecated filter from deprecated get_maximum_execution_time() method
// Apply deprecated filter from deprecated get_maximum_execution_time() method.
if ( has_filter( 'action_scheduler_maximum_execution_time' ) ) {
_deprecated_function( 'action_scheduler_maximum_execution_time', '2.1.1', 'action_scheduler_queue_runner_time_limit' );
$time_limit = apply_filters( 'action_scheduler_maximum_execution_time', $time_limit );
@@ -288,7 +289,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
/**
* Check if the host's max execution time is (likely) to be exceeded if processing more actions.
*
* @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action
* @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action.
* @return bool
*/
protected function time_likely_to_be_exceeded( $processed_actions ) {
@@ -318,7 +319,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
$memory_limit = '128M'; // Sensible default, and minimum required by WooCommerce
$memory_limit = '128M'; // Sensible default, and minimum required by WooCommerce.
}
if ( ! $memory_limit || -1 === $memory_limit || '-1' === $memory_limit ) {
@@ -353,7 +354,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
*
* Based on WC_Background_Process::batch_limits_exceeded()
*
* @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action
* @param int $processed_actions The number of actions processed so far - used to determine the likelihood of exceeding the time limit if processing another action.
* @return bool
*/
protected function batch_limits_exceeded( $processed_actions ) {

View File

@@ -35,8 +35,8 @@ abstract class ActionScheduler_Abstract_RecurringSchedule extends ActionSchedule
protected $recurrence;
/**
* @param DateTime $date The date & time to run the action.
* @param mixed $recurrence The data used to determine the schedule's recurrence.
* @param DateTime $date The date & time to run the action.
* @param mixed $recurrence The data used to determine the schedule's recurrence.
* @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
*/
public function __construct( DateTime $date, $recurrence, DateTime $first = null ) {

View File

@@ -36,7 +36,7 @@ abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedul
/**
* Calculate when the next instance of this schedule would run based on a given date & time.
*
* @param DateTime $after
* @param DateTime $after Start timestamp.
* @return DateTime
*/
abstract protected function calculate_next( DateTime $after );
@@ -44,7 +44,7 @@ abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedul
/**
* Get the next date & time when this schedule should run after a given date & time.
*
* @param DateTime $after
* @param DateTime $after Start timestamp.
* @return DateTime|null
*/
public function get_next( DateTime $after ) {
@@ -76,6 +76,9 @@ abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedul
);
}
/**
* Wakeup.
*/
public function __wakeup() {
$this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp );
unset( $this->scheduled_timestamp );

View File

@@ -43,14 +43,14 @@ abstract class ActionScheduler_Abstract_Schema {
public function register_tables( $force_update = false ) {
global $wpdb;
// make WP aware of our tables
// make WP aware of our tables.
foreach ( $this->tables as $table ) {
$wpdb->tables[] = $table;
$name = $this->get_full_table_name( $table );
$wpdb->$table = $name;
}
// create the tables
// create the tables.
if ( $this->schema_update_required() || $force_update ) {
foreach ( $this->tables as $table ) {
/**
@@ -67,7 +67,9 @@ abstract class ActionScheduler_Abstract_Schema {
}
/**
* @param string $table The name of the table
* Get table definition.
*
* @param string $table The name of the table.
*
* @return string The CREATE TABLE statement, suitable for passing to dbDelta
*/
@@ -84,7 +86,7 @@ abstract class ActionScheduler_Abstract_Schema {
$option_name = 'schema-' . static::class;
$this->db_version = get_option( $option_name, 0 );
// Check for schema option stored by the Action Scheduler Custom Tables plugin in case site has migrated from that plugin with an older schema
// Check for schema option stored by the Action Scheduler Custom Tables plugin in case site has migrated from that plugin with an older schema.
if ( 0 === $this->db_version ) {
$plugin_option_name = 'schema-';
@@ -115,7 +117,7 @@ abstract class ActionScheduler_Abstract_Schema {
private function mark_schema_update_complete() {
$option_name = 'schema-' . static::class;
// work around race conditions and ensure that our option updates
// work around race conditions and ensure that our option updates.
$value_to_save = (string) $this->schema_version . '.0.' . time();
update_option( $option_name, $value_to_save );
@@ -124,7 +126,7 @@ abstract class ActionScheduler_Abstract_Schema {
/**
* Update the schema for the given table
*
* @param string $table The name of the table to update
* @param string $table The name of the table to update.
*
* @return void
*/
@@ -142,7 +144,9 @@ abstract class ActionScheduler_Abstract_Schema {
}
/**
* @param string $table
* Get full table name.
*
* @param string $table Table name.
*
* @return string The full name of the table, including the
* table prefix for the current blog

View File

@@ -5,9 +5,13 @@
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Logger {
/** @var null|self */
private static $logger = NULL;
/**
* Get instance.
*
* @return ActionScheduler_Logger
*/
public static function instance() {
@@ -19,23 +23,29 @@ abstract class ActionScheduler_Logger {
}
/**
* @param string $action_id
* @param string $message
* @param DateTime $date
* Create log entry.
*
* @param string $action_id Action ID.
* @param string $message Log message.
* @param DateTime $date Log date.
*
* @return string The log entry ID
*/
abstract public function log( $action_id, $message, DateTime $date = NULL );
/**
* @param string $entry_id
* Get action's log entry.
*
* @param string $entry_id Entry ID.
*
* @return ActionScheduler_LogEntry
*/
abstract public function get_entry( $entry_id );
/**
* @param string $action_id
* Get action's logs.
*
* @param string $action_id Action ID.
*
* @return ActionScheduler_LogEntry[]
*/
@@ -43,6 +53,8 @@ abstract class ActionScheduler_Logger {
/**
* Initialize.
*
* @codeCoverageIgnore
*/
public function init() {
@@ -60,22 +72,44 @@ abstract class ActionScheduler_Logger {
add_action( 'action_scheduler_bulk_cancel_actions', array( $this, 'bulk_log_cancel_actions' ), 10, 1 );
}
/**
* Register callback for storing action.
*/
public function hook_stored_action() {
add_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) );
}
/**
* Unhook callback for storing action.
*/
public function unhook_stored_action() {
remove_action( 'action_scheduler_stored_action', array( $this, 'log_stored_action' ) );
}
/**
* Log action stored.
*
* @param int $action_id Action ID.
*/
public function log_stored_action( $action_id ) {
$this->log( $action_id, __( 'action created', 'woocommerce' ) );
}
/**
* Log action cancellation.
*
* @param int $action_id Action ID.
*/
public function log_canceled_action( $action_id ) {
$this->log( $action_id, __( 'action canceled', 'woocommerce' ) );
}
/**
* Log action start.
*
* @param int $action_id Action ID.
* @param string $context Action execution context.
*/
public function log_started_action( $action_id, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: %s: context */
@@ -86,6 +120,13 @@ abstract class ActionScheduler_Logger {
$this->log( $action_id, $message );
}
/**
* Log action completion.
*
* @param int $action_id Action ID.
* @param null|ActionScheduler_Action $action Action.
* @param string $context Action exeuction context.
*/
public function log_completed_action( $action_id, $action = NULL, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: %s: context */
@@ -96,6 +137,13 @@ abstract class ActionScheduler_Logger {
$this->log( $action_id, $message );
}
/**
* Log action failure.
*
* @param int $action_id Action ID.
* @param Exception $exception Exception.
* @param string $context Action execution context.
*/
public function log_failed_action( $action_id, Exception $exception, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: 1: context 2: exception message */
@@ -107,11 +155,23 @@ abstract class ActionScheduler_Logger {
$this->log( $action_id, $message );
}
/**
* Log action timeout.
*
* @param int $action_id Action ID.
* @param string $timeout Timeout.
*/
public function log_timed_out_action( $action_id, $timeout ) {
/* translators: %s: amount of time */
$this->log( $action_id, sprintf( __( 'action marked as failed after %s seconds. Unknown error occurred. Check server, PHP and database error logs to diagnose cause.', 'woocommerce' ), $timeout ) );
}
/**
* Log unexpected shutdown.
*
* @param int $action_id Action ID.
* @param mixed[] $error Error.
*/
public function log_unexpected_shutdown( $action_id, $error ) {
if ( ! empty( $error ) ) {
/* translators: 1: error message 2: filename 3: line */
@@ -119,10 +179,21 @@ abstract class ActionScheduler_Logger {
}
}
/**
* Log action reset.
*
* @param int $action_id Action ID.
*/
public function log_reset_action( $action_id ) {
$this->log( $action_id, __( 'action reset', 'woocommerce' ) );
}
/**
* Log ignored action.
*
* @param int $action_id Action ID.
* @param string $context Action execution context.
*/
public function log_ignored_action( $action_id, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: %s: context */
@@ -134,10 +205,10 @@ abstract class ActionScheduler_Logger {
}
/**
* @param string $action_id
* @param Exception|NULL $exception The exception which occurred when fetching the action. NULL by default for backward compatibility.
* Log the failure of fetching the action.
*
* @return ActionScheduler_LogEntry[]
* @param string $action_id Action ID.
* @param null|Exception $exception The exception which occurred when fetching the action. NULL by default for backward compatibility.
*/
public function log_failed_fetch_action( $action_id, Exception $exception = NULL ) {
@@ -151,6 +222,12 @@ abstract class ActionScheduler_Logger {
$this->log( $action_id, $log_message );
}
/**
* Log the failure of scheduling the action's next instance.
*
* @param int $action_id Action ID.
* @param Exception $exception Exception object.
*/
public function log_failed_schedule_next_instance( $action_id, Exception $exception ) {
/* translators: %s: exception message */
$this->log( $action_id, sprintf( __( 'There was a failure scheduling the next instance of this action: %s', 'woocommerce' ), $exception->getMessage() ) );

View File

@@ -19,17 +19,19 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
protected static $max_args_length = 191;
/**
* @param ActionScheduler_Action $action
* @param DateTime $scheduled_date Optional Date of the first instance
* to store. Otherwise uses the first date of the action's
* schedule.
* @param ActionScheduler_Action $action Action to save.
* @param null|DateTime $scheduled_date Optional Date of the first instance
* to store. Otherwise uses the first date of the action's
* schedule.
*
* @return int The action ID
*/
abstract public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = NULL );
/**
* @param string $action_id
* Get action.
*
* @param string $action_id Action ID.
*
* @return ActionScheduler_Action
*/
@@ -141,7 +143,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
public function extra_action_counts() {
$extra_actions = array();
$pastdue_action_counts = ( int ) $this->query_actions( array(
$pastdue_action_counts = (int) $this->query_actions( array(
'status' => self::STATUS_PENDING,
'date' => as_get_datetime_object(),
), 'count' );
@@ -160,17 +162,23 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
}
/**
* @param string $action_id
* Cancel action.
*
* @param string $action_id Action ID.
*/
abstract public function cancel_action( $action_id );
/**
* @param string $action_id
* Delete action.
*
* @param string $action_id Action ID.
*/
abstract public function delete_action( $action_id );
/**
* @param string $action_id
* Get action's schedule or run timestamp.
*
* @param string $action_id Action ID.
*
* @return DateTime The date the action is schedule to run, or the date that it ran.
*/
@@ -178,7 +186,9 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
/**
* @param int $max_actions
* Make a claim.
*
* @param int $max_actions Maximum number of actions to claim.
* @param DateTime $before_date Claim only actions schedule before the given date. Defaults to now.
* @param array $hooks Claim only actions with a hook or hooks.
* @param string $group Claim only actions in the given group.
@@ -188,56 +198,75 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
abstract public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' );
/**
* Get claim count.
*
* @return int
*/
abstract public function get_claim_count();
/**
* @param ActionScheduler_ActionClaim $claim
* Release the claim.
*
* @param ActionScheduler_ActionClaim $claim Claim object.
*/
abstract public function release_claim( ActionScheduler_ActionClaim $claim );
/**
* @param string $action_id
* Un-claim the action.
*
* @param string $action_id Action ID.
*/
abstract public function unclaim_action( $action_id );
/**
* @param string $action_id
* Mark action as failed.
*
* @param string $action_id Action ID.
*/
abstract public function mark_failure( $action_id );
/**
* @param string $action_id
* Log action's execution.
*
* @param string $action_id Actoin ID.
*/
abstract public function log_execution( $action_id );
/**
* @param string $action_id
* Mark action as complete.
*
* @param string $action_id Action ID.
*/
abstract public function mark_complete( $action_id );
/**
* @param string $action_id
* Get action's status.
*
* @param string $action_id Action ID.
* @return string
*/
abstract public function get_status( $action_id );
/**
* @param string $action_id
* Get action's claim ID.
*
* @param string $action_id Action ID.
* @return mixed
*/
abstract public function get_claim_id( $action_id );
/**
* @param string $claim_id
* Find actions by claim ID.
*
* @param string $claim_id Claim ID.
* @return array
*/
abstract public function find_actions_by_claim_id( $claim_id );
/**
* @param string $comparison_operator
* Validate SQL operator.
*
* @param string $comparison_operator Operator.
* @return string
*/
protected function validate_sql_comparator( $comparison_operator ) {
@@ -250,8 +279,8 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
/**
* Get the time MySQL formatted date/time string for an action's (next) scheduled date.
*
* @param ActionScheduler_Action $action
* @param DateTime $scheduled_date (optional)
* @param ActionScheduler_Action $action Action.
* @param null|DateTime $scheduled_date Action's schedule date (optional).
* @return string
*/
protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
@@ -267,8 +296,8 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
/**
* Get the time MySQL formatted date/time string for an action's (next) scheduled date.
*
* @param ActionScheduler_Action $action
* @param DateTime $scheduled_date (optional)
* @param ActionScheduler_Action $action Action.
* @param null|DateTime $scheduled_date Action's scheduled date (optional).
* @return string
*/
protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
@@ -386,7 +415,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
*
* @since 3.0.0
*
* @param array $action_ids List of action IDs.
* @param int[] $action_ids List of action IDs.
*
* @return void
*/
@@ -399,7 +428,9 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
}
/**
* @return array
* Get status labels.
*
* @return array<string, string>
*/
public function get_status_labels() {
return array(
@@ -414,14 +445,12 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
/**
* Check if there are any pending scheduled actions due to run.
*
* @param ActionScheduler_Action $action
* @param DateTime $scheduled_date (optional)
* @return string
*/
public function has_pending_actions_due() {
$pending_actions = $this->query_actions( array(
'date' => as_get_datetime_object(),
'status' => ActionScheduler_Store::STATUS_PENDING,
'status' => self::STATUS_PENDING,
'orderby' => 'none',
) );
@@ -435,6 +464,8 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
/**
* Callable function to mark an action as migrated optionally overridden in derived classes.
*
* @param int $action_id Action ID.
*/
public function mark_migrated( $action_id ) {}

View File

@@ -4,6 +4,8 @@
* Class ActionScheduler_TimezoneHelper
*/
abstract class ActionScheduler_TimezoneHelper {
/** @var null|DateTimeZone */
private static $local_timezone = NULL;
/**
@@ -12,12 +14,12 @@ abstract class ActionScheduler_TimezoneHelper {
*
* @since 2.1.0
*
* @param DateTime $date
* @param DateTime $date Timestamp.
* @return ActionScheduler_DateTime
*/
public static function set_local_timezone( DateTime $date ) {
// Accept a DateTime for easier backward compatibility, even though we require methods on ActionScheduler_DateTime
// Accept a DateTime for easier backward compatibility, even though we require methods on ActionScheduler_DateTime.
if ( ! is_a( $date, 'ActionScheduler_DateTime' ) ) {
$date = as_get_datetime_object( $date->format( 'U' ) );
}
@@ -42,6 +44,7 @@ abstract class ActionScheduler_TimezoneHelper {
* timezone.
*
* @since 2.1.0
* @param bool $reset Unused.
* @return string PHP timezone string for the site or empty if no timezone string is available.
*/
protected static function get_local_timezone_string( $reset = false ) {
@@ -75,7 +78,7 @@ abstract class ActionScheduler_TimezoneHelper {
}
}
// No timezone string
// No timezone string.
return '';
}
@@ -97,6 +100,9 @@ abstract class ActionScheduler_TimezoneHelper {
}
/**
* Get local timezone.
*
* @param bool $reset Toggle to discard stored value.
* @deprecated 2.1.0
*/
public static function get_local_timezone( $reset = FALSE ) {

View File

@@ -4,10 +4,13 @@
* Class ActionScheduler_Action
*/
class ActionScheduler_Action {
/** @var string */
protected $hook = '';
/** @var array<string, mixed> */
protected $args = array();
/** @var ActionScheduler_Schedule */
protected $schedule = NULL;
/** @var string */
protected $group = '';
/**
@@ -23,6 +26,14 @@ class ActionScheduler_Action {
*/
protected $priority = 10;
/**
* Construct.
*
* @param string $hook Action's hook.
* @param mixed[] $args Action's arguments.
* @param null|ActionScheduler_Schedule $schedule Action's schedule.
* @param string $group Action's group.
*/
public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = NULL, $group = '' ) {
$schedule = empty( $schedule ) ? new ActionScheduler_NullSchedule() : $schedule;
$this->set_hook($hook);
@@ -57,16 +68,26 @@ class ActionScheduler_Action {
}
/**
* @param string $hook
* Set action's hook.
*
* @param string $hook Action's hook.
*/
protected function set_hook( $hook ) {
$this->hook = $hook;
}
/**
* Get action's hook.
*/
public function get_hook() {
return $this->hook;
}
/**
* Set action's schedule.
*
* @param ActionScheduler_Schedule $schedule Action's schedule.
*/
protected function set_schedule( ActionScheduler_Schedule $schedule ) {
$this->schedule = $schedule;
}
@@ -78,16 +99,26 @@ class ActionScheduler_Action {
return $this->schedule;
}
/**
* Set action's args.
*
* @param mixed[] $args Action's arguments.
*/
protected function set_args( array $args ) {
$this->args = $args;
}
/**
* Get action's args.
*/
public function get_args() {
return $this->args;
}
/**
* @param string $group
* Section action's group.
*
* @param string $group Action's group.
*/
protected function set_group( $group ) {
$this->group = $group;

View File

@@ -9,10 +9,12 @@
class ActionScheduler_CanceledAction extends ActionScheduler_FinishedAction {
/**
* @param string $hook
* @param array $args
* @param ActionScheduler_Schedule $schedule
* @param string $group
* Construct.
*
* @param string $hook Action's hook.
* @param array $args Action's arguments.
* @param null|ActionScheduler_Schedule $schedule Action's schedule.
* @param string $group Action's group.
*/
public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
parent::__construct( $hook, $args, $schedule, $group );

View File

@@ -5,12 +5,17 @@
*/
class ActionScheduler_FinishedAction extends ActionScheduler_Action {
/**
* Execute action.
*/
public function execute() {
// don't execute
// don't execute.
}
/**
* Get finished state.
*/
public function is_finished() {
return TRUE;
}
}

View File

@@ -5,12 +5,21 @@
*/
class ActionScheduler_NullAction extends ActionScheduler_Action {
/**
* Construct.
*
* @param string $hook Action hook.
* @param mixed[] $args Action arguments.
* @param null|ActionScheduler_Schedule $schedule Action schedule.
*/
public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = NULL ) {
$this->set_schedule( new ActionScheduler_NullSchedule() );
}
/**
* Execute action.
*/
public function execute() {
// don't execute
// don't execute.
}
}

View File

@@ -77,7 +77,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
* @param bool $unique Whether the action should be unique.
*
* @return int Action ID.
* @throws RuntimeException Throws exception when saving the action fails.
* @throws \RuntimeException Throws exception when saving the action fails.
*/
private function save_action_to_db( ActionScheduler_Action $action, DateTime $date = null, $unique = false ) {
global $wpdb;
@@ -388,7 +388,8 @@ AND `group_id` = %d
* @param string $select_or_count Whether the SQL should select and return the IDs or just the row count.
*
* @return string SQL statement already properly escaped.
* @throws InvalidArgumentException If the query is invalid.
* @throws \InvalidArgumentException If the query is invalid.
* @throws \RuntimeException When "unknown partial args matching value".
*/
protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
@@ -399,7 +400,7 @@ AND `group_id` = %d
$query = wp_parse_args( $query, array(
'hook' => '',
'args' => null,
'partial_args_matching' => 'off', // can be 'like' or 'json'
'partial_args_matching' => 'off', // can be 'like' or 'json'.
'date' => null,
'date_compare' => '<=',
'modified' => null,
@@ -435,15 +436,15 @@ AND `group_id` = %d
$sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
}
$sql .= " WHERE 1=1";
$sql .= ' WHERE 1=1';
if ( ! empty( $query['group'] ) ) {
$sql .= " AND g.slug=%s";
$sql .= ' AND g.slug=%s';
$sql_params[] = $query['group'];
}
if ( ! empty( $query['hook'] ) ) {
$sql .= " AND a.hook=%s";
$sql .= ' AND a.hook=%s';
$sql_params[] = $query['hook'];
}
@@ -472,8 +473,8 @@ AND `group_id` = %d
$value_type
) );
}
$sql .= ' AND JSON_EXTRACT(a.args, %s)='.$placeholder;
$sql_params[] = '$.'.$key;
$sql .= ' AND JSON_EXTRACT(a.args, %s)=' . $placeholder;
$sql_params[] = '$.' . $key;
$sql_params[] = $value;
}
break;
@@ -485,7 +486,7 @@ AND `group_id` = %d
}
break;
case 'off':
$sql .= " AND a.args=%s";
$sql .= ' AND a.args=%s';
$sql_params[] = $this->get_args_for_query( $query['args'] );
break;
default:
@@ -823,7 +824,7 @@ AND `group_id` = %d
* Set a claim filter.
*
* @param string $filter_name Claim filter name.
* @param mixed $filter_values Values to filter.
* @param mixed $filter_values Values to filter.
* @return void
*/
public function set_claim_filter( $filter_name, $filter_values ) {
@@ -1017,6 +1018,7 @@ AND `group_id` = %d
* Release actions from a claim and delete the claim.
*
* @param ActionScheduler_ActionClaim $claim Claim object.
* @throws \RuntimeException When unable to release actions from claim.
*/
public function release_claim( ActionScheduler_ActionClaim $claim ) {
/** @var \wpdb $wpdb */

View File

@@ -15,8 +15,11 @@ use Action_Scheduler\Migration\Controller;
class ActionScheduler_HybridStore extends Store {
const DEMARKATION_OPTION = 'action_scheduler_hybrid_store_demarkation';
/** @var ActionScheduler_Store */
private $primary_store;
/** @var ActionScheduler_Store */
private $secondary_store;
/** @var Action_Scheduler\Migration\Runner */
private $migration_runner;
/**
@@ -64,8 +67,8 @@ class ActionScheduler_HybridStore extends Store {
* value to be one higher than the posts table to ensure that
* there are no ID collisions.
*
* @param string $table_name
* @param string $table_suffix
* @param string $table_name Table name.
* @param string $table_suffix Suffix of table name.
*
* @return void
* @codeCoverageIgnore
@@ -78,7 +81,7 @@ class ActionScheduler_HybridStore extends Store {
/** @var \wpdb $wpdb */
global $wpdb;
/**
* A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with
* A default date of '0000-00-00 00:00:00' is invalid in MySQL 5.7 when configured with
* sql_mode including both STRICT_TRANS_TABLES and NO_ZERO_DATE.
*/
$default_date = new DateTime( 'tomorrow' );
@@ -135,8 +138,8 @@ class ActionScheduler_HybridStore extends Store {
* After it migrates, the secondary store will logically contain
* the next matching action, so return the result thence.
*
* @param string $hook
* @param array $params
* @param string $hook Action's hook.
* @param array $params Action's arguments.
*
* @return string
*/
@@ -154,7 +157,7 @@ class ActionScheduler_HybridStore extends Store {
* If any are found, migrate them immediately. Then the secondary
* store will contain the canonical results.
*
* @param array $query
* @param array $query Query arguments.
* @param string $query_type Whether to select or count the results. Default, select.
*
* @return int[]
@@ -203,8 +206,10 @@ class ActionScheduler_HybridStore extends Store {
* migrate them immediately, then ask the primary store for the
* canonical claim.
*
* @param int $max_actions
* @param DateTime|null $before_date
* @param int $max_actions Maximum number of actions to claim.
* @param null|DateTime $before_date Latest timestamp of actions to claim.
* @param string[] $hooks Hook of actions to claim.
* @param string $group Group of actions to claim.
*
* @return ActionScheduler_ActionClaim
*/
@@ -376,10 +381,12 @@ class ActionScheduler_HybridStore extends Store {
return null;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * *
/**
* * * * * * * * * * * * * * * * * * * * * * * * * * *
* All claim-related functions should operate solely
* on the primary store.
* * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
/**
* Get the claim count from the table data store.

View File

@@ -8,9 +8,11 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
const TYPE = 'action_log';
/**
* @param string $action_id
* @param string $message
* @param DateTime $date
* Create log entry.
*
* @param string $action_id Action ID.
* @param string $message Action log's message.
* @param DateTime $date Action log's timestamp.
*
* @return string The log entry ID
*/
@@ -24,6 +26,13 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
return $comment_id;
}
/**
* Create comment.
*
* @param int $action_id Action ID.
* @param string $message Action log's message.
* @param DateTime $date Action log entry's timestamp.
*/
protected function create_wp_comment( $action_id, $message, DateTime $date ) {
$comment_date_gmt = $date->format('Y-m-d H:i:s');
@@ -41,7 +50,9 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
}
/**
* @param string $entry_id
* Get single log entry for action.
*
* @param string $entry_id Entry ID.
*
* @return ActionScheduler_LogEntry
*/
@@ -57,7 +68,9 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
}
/**
* @param string $action_id
* Get action's logs.
*
* @param string $action_id Action ID.
*
* @return ActionScheduler_LogEntry[]
*/
@@ -83,6 +96,11 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
return $logs;
}
/**
* Get comment.
*
* @param int $comment_id Comment ID.
*/
protected function get_comment( $comment_id ) {
return get_comment( $comment_id );
}
@@ -90,12 +108,14 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
/**
* @param WP_Comment_Query $query
* Filter comment queries.
*
* @param WP_Comment_Query $query Comment query object.
*/
public function filter_comment_queries( $query ) {
foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) {
if ( !empty($query->query_vars[$key]) ) {
return; // don't slow down queries that wouldn't include action_log comments anyway
return; // don't slow down queries that wouldn't include action_log comments anyway.
}
}
$query->query_vars['action_log_filter'] = TRUE;
@@ -103,8 +123,10 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
}
/**
* @param array $clauses
* @param WP_Comment_Query $query
* Filter comment queries.
*
* @param array $clauses Query's clauses.
* @param WP_Comment_Query $query Query object.
*
* @return array
*/
@@ -119,8 +141,8 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
* Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not
* the WP_Comment_Query class handled by @see self::filter_comment_queries().
*
* @param string $where
* @param WP_Query $query
* @param string $where Query's `where` clause.
* @param WP_Query $query Query object.
*
* @return string
*/
@@ -144,8 +166,8 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
/**
* Remove action log entries from wp_count_comments()
*
* @param array $stats
* @param int $post_id
* @param array $stats Comment count.
* @param int $post_id Post ID.
*
* @return object
*/
@@ -179,7 +201,7 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
$approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
foreach ( (array) $count as $row ) {
// Don't count post-trashed toward totals
// Don't count post-trashed toward totals.
if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
$total += $row['num_comments'];
}
@@ -213,6 +235,8 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
}
/**
* Initialize.
*
* @codeCoverageIgnore
*/
public function init() {
@@ -222,17 +246,24 @@ class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
parent::init();
add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 );
add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs.
add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 );
// Delete comments count cache whenever there is a new comment or a comment status changes
// Delete comments count cache whenever there is a new comment or a comment status changes.
add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) );
add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) );
}
/**
* Defer comment counting.
*/
public function disable_comment_counting() {
wp_defer_comment_counting(true);
}
/**
* Enable comment counting.
*/
public function enable_comment_counting() {
wp_defer_comment_counting(false);
}

View File

@@ -5,6 +5,10 @@
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_PostStatusRegistrar {
/**
* Registrar.
*/
public function register() {
register_post_status( ActionScheduler_Store::STATUS_RUNNING, array_merge( $this->post_status_args(), $this->post_status_running_labels() ) );
register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) );

View File

@@ -5,6 +5,9 @@
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_PostTypeRegistrar {
/**
* Registrar.
*/
public function register() {
register_post_type( ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args() );
}
@@ -47,4 +50,3 @@ class ActionScheduler_wpPostStore_PostTypeRegistrar {
return $args;
}
}

View File

@@ -5,10 +5,17 @@
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_TaxonomyRegistrar {
/**
* Registrar.
*/
public function register() {
register_taxonomy( ActionScheduler_wpPostStore::GROUP_TAXONOMY, ActionScheduler_wpPostStore::POST_TYPE, $this->taxonomy_args() );
}
/**
* Get taxonomy arguments.
*/
protected function taxonomy_args() {
$args = array(
'label' => __( 'Action Group', 'woocommerce' ),
@@ -23,4 +30,3 @@ class ActionScheduler_wpPostStore_TaxonomyRegistrar {
return $args;
}
}

View File

@@ -13,21 +13,21 @@ namespace Action_Scheduler\Migration;
* @codeCoverageIgnore
*/
class ActionMigrator {
/** var ActionScheduler_Store */
/** @var ActionScheduler_Store */
private $source;
/** var ActionScheduler_Store */
/** @var ActionScheduler_Store */
private $destination;
/** var LogMigrator */
/** @var LogMigrator */
private $log_migrator;
/**
* ActionMigrator constructor.
*
* @param ActionScheduler_Store $source_store Source store object.
* @param ActionScheduler_Store $destination_store Destination store object.
* @param LogMigrator $log_migrator Log migrator object.
* @param \ActionScheduler_Store $source_store Source store object.
* @param \ActionScheduler_Store $destination_store Destination store object.
* @param LogMigrator $log_migrator Log migrator object.
*/
public function __construct( \ActionScheduler_Store $source_store, \ActionScheduler_Store $destination_store, LogMigrator $log_migrator ) {
$this->source = $source_store;
@@ -41,6 +41,7 @@ class ActionMigrator {
* @param int $source_action_id Action ID.
*
* @return int 0|new action ID
* @throws \RuntimeException When unable to delete action from the source store.
*/
public function migrate( $source_action_id ) {
try {
@@ -52,13 +53,13 @@ class ActionMigrator {
}
if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) {
// null action or empty status means the fetch operation failed or the action didn't exist
// null schedule means it's missing vital data
// delete it and move on
// null action or empty status means the fetch operation failed or the action didn't exist.
// null schedule means it's missing vital data.
// delete it and move on.
try {
$this->source->delete_action( $source_action_id );
} catch ( \Exception $e ) {
// nothing to do, it didn't exist in the first place
// nothing to do, it didn't exist in the first place.
}
do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination );
@@ -67,14 +68,14 @@ class ActionMigrator {
try {
// Make sure the last attempt date is set correctly for completed and failed actions
// Make sure the last attempt date is set correctly for completed and failed actions.
$last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null;
$destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date );
} catch ( \Exception $e ) {
do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination );
return 0; // could not save the action in the new store
return 0; // could not save the action in the new store.
}
try {
@@ -99,7 +100,7 @@ class ActionMigrator {
return $destination_action_id;
} catch ( \Exception $e ) {
// could not delete from the old store
// could not delete from the old store.
$this->source->mark_migrated( $source_action_id );
do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination );
do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );

View File

@@ -16,9 +16,9 @@ class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore {
* it can't have been attempted yet, but migrated completed actions will have an attempted date, so we need to save
* that when first saving the action.
*
* @param ActionScheduler_Action $action
* @param \DateTime $scheduled_date Optional date of the first instance to store.
* @param \DateTime $last_attempt_date Optional date the action was last attempted.
* @param ActionScheduler_Action $action Action to migrate.
* @param null|\DateTime $scheduled_date Optional date of the first instance to store.
* @param null|\DateTime $last_attempt_date Optional date the action was last attempted.
*
* @return string The action ID
* @throws \RuntimeException When the action is not saved.

View File

@@ -16,7 +16,7 @@ use ActionScheduler_Store as Store;
* @codeCoverageIgnore
*/
class BatchFetcher {
/** var ActionScheduler_Store */
/** @var ActionScheduler_Store */
private $store;
/**
@@ -31,7 +31,7 @@ class BatchFetcher {
/**
* Retrieve a list of actions.
*
* @param int $count The number of actions to retrieve
* @param int $count The number of actions to retrieve.
*
* @return int[] A list of action IDs
*/
@@ -69,7 +69,7 @@ class BatchFetcher {
Store::STATUS_CANCELED,
Store::STATUS_COMPLETE,
Store::STATUS_RUNNING,
'', // any other unanticipated status
'', // any other unanticipated status.
];
foreach ( $priorities as $status ) {
@@ -83,4 +83,4 @@ class BatchFetcher {
], $args );
}
}
}
}

View File

@@ -46,6 +46,7 @@ class Config {
* Get the configured source store.
*
* @return ActionScheduler_Store
* @throws \RuntimeException When source store is not configured.
*/
public function get_source_store() {
if ( empty( $this->source_store ) ) {
@@ -68,6 +69,7 @@ class Config {
* Get the configured source logger.
*
* @return ActionScheduler_Logger
* @throws \RuntimeException When source logger is not configured.
*/
public function get_source_logger() {
if ( empty( $this->source_logger ) ) {
@@ -80,7 +82,7 @@ class Config {
/**
* Set the configured source logger.
*
* @param ActionScheduler_Logger $logger
* @param ActionScheduler_Logger $logger Logger object.
*/
public function set_source_logger( Logger $logger ) {
$this->source_logger = $logger;
@@ -90,6 +92,7 @@ class Config {
* Get the configured destination store.
*
* @return ActionScheduler_Store
* @throws \RuntimeException When destination store is not configured.
*/
public function get_destination_store() {
if ( empty( $this->destination_store ) ) {
@@ -102,7 +105,7 @@ class Config {
/**
* Set the configured destination store.
*
* @param ActionScheduler_Store $store
* @param ActionScheduler_Store $store Action store object.
*/
public function set_destination_store( Store $store ) {
$this->destination_store = $store;
@@ -112,6 +115,7 @@ class Config {
* Get the configured destination logger.
*
* @return ActionScheduler_Logger
* @throws \RuntimeException When destination logger is not configured.
*/
public function get_destination_logger() {
if ( empty( $this->destination_logger ) ) {
@@ -124,7 +128,7 @@ class Config {
/**
* Set the configured destination logger.
*
* @param ActionScheduler_Logger $logger
* @param ActionScheduler_Logger $logger Logger object.
*/
public function set_destination_logger( Logger $logger ) {
$this->destination_logger = $logger;
@@ -142,7 +146,7 @@ class Config {
/**
* Set flag indicating whether it's a dry run.
*
* @param bool $dry_run
* @param bool $dry_run Dry run toggle.
*/
public function set_dry_run( $dry_run ) {
$this->dry_run = (bool) $dry_run;
@@ -160,7 +164,7 @@ class Config {
/**
* Set progress bar object.
*
* @param ActionScheduler\WPCLI\ProgressBar $progress_bar
* @param ActionScheduler\WPCLI\ProgressBar $progress_bar Progress bar object.
*/
public function set_progress_bar( ProgressBar $progress_bar ) {
$this->progress_bar = $progress_bar;

View File

@@ -19,6 +19,7 @@ use Action_Scheduler\WP_CLI\ProgressBar;
* @codeCoverageIgnore
*/
class Controller {
/** @var self */
private static $instance;
/** @var Action_Scheduler\Migration\Scheduler */
@@ -171,7 +172,7 @@ class Controller {
add_action( 'init', array( $this, 'maybe_hook_migration' ) );
add_action( 'wp_loaded', array( $this, 'schedule_migration' ) );
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen.
add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 );
add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 );
}

View File

@@ -18,6 +18,6 @@ class DryRun_LogMigrator extends LogMigrator {
* @param int $destination_action_id Destination logger object.
*/
public function migrate( $source_action_id, $destination_action_id ) {
// no-op
// no-op.
}
}
}

View File

@@ -7,11 +7,13 @@ class ActionScheduler_CanceledSchedule extends ActionScheduler_SimpleSchedule {
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null
*/
private $timestamp = NULL;
/**
* @param DateTime $after
* @param DateTime $after Timestamp.
*
* @return DateTime|null
*/
@@ -23,7 +25,7 @@ class ActionScheduler_CanceledSchedule extends ActionScheduler_SimpleSchedule {
* Cancelled actions should never have a next schedule, even if get_next()
* is called with $after < $this->scheduled_date.
*
* @param DateTime $after
* @param DateTime $after Timestamp.
* @return DateTime|null
*/
public function get_next( DateTime $after ) {

View File

@@ -7,21 +7,25 @@ class ActionScheduler_CronSchedule extends ActionScheduler_Abstract_RecurringSch
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null
*/
private $start_timestamp = NULL;
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null
*/
private $cron = NULL;
/**
* Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this
* objects $recurrence property.
*
* @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used.
* @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used.
* @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance.
* @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
* @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance.
*/
public function __construct( DateTime $start, $recurrence, DateTime $first = null ) {
if ( ! is_a( $recurrence, 'CronExpression' ) ) {
@@ -41,7 +45,7 @@ class ActionScheduler_CronSchedule extends ActionScheduler_Abstract_RecurringSch
* Calculate when an instance of this schedule would start based on a given
* date & time using its the CronExpression.
*
* @param DateTime $after
* @param DateTime $after Timestamp.
* @return DateTime
*/
protected function calculate_next( DateTime $after ) {

View File

@@ -7,19 +7,23 @@ class ActionScheduler_IntervalSchedule extends ActionScheduler_Abstract_Recurrin
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null
*/
private $start_timestamp = NULL;
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null
*/
private $interval_in_seconds = NULL;
/**
* Calculate when this schedule should start after a given date & time using
* the number of seconds between recurrences.
*
* @param DateTime $after
* @param DateTime $after Timestamp.
* @return DateTime
*/
protected function calculate_next( DateTime $after ) {

View File

@@ -11,7 +11,7 @@ class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule {
/**
* Make the $date param optional and default to null.
*
* @param null $date The date & time to run the action.
* @param null|DateTime $date The date & time to run the action.
*/
public function __construct( DateTime $date = null ) {
$this->scheduled_date = null;
@@ -25,6 +25,9 @@ class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule {
return array();
}
/**
* Wakeup.
*/
public function __wakeup() {
$this->scheduled_date = null;
}

View File

@@ -5,7 +5,7 @@
*/
interface ActionScheduler_Schedule {
/**
* @param DateTime $after
* @param null|DateTime $after Timestamp.
* @return DateTime|null
*/
public function next( DateTime $after = NULL );
@@ -15,4 +15,3 @@ interface ActionScheduler_Schedule {
*/
public function is_recurring();
}

View File

@@ -7,11 +7,13 @@ class ActionScheduler_SimpleSchedule extends ActionScheduler_Abstract_Schedule {
/**
* Deprecated property @see $this->__wakeup() for details.
**/
*
* @var null|DateTime
*/
private $timestamp = NULL;
/**
* @param DateTime $after
* @param DateTime $after Timestamp.
*
* @return DateTime|null
*/

View File

@@ -15,6 +15,9 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
*/
protected $schema_version = 3;
/**
* Construct.
*/
public function __construct() {
$this->tables = [
self::LOG_TABLE,
@@ -28,6 +31,11 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
add_action( 'action_scheduler_before_schema_update', array( $this, 'update_schema_3_0' ), 10, 2 );
}
/**
* Get table definition.
*
* @param string $table Table name.
*/
protected function get_table_definition( $table ) {
global $wpdb;
$table_name = $wpdb->$table;

View File

@@ -18,6 +18,9 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
*/
protected $schema_version = 7;
/**
* Construct.
*/
public function __construct() {
$this->tables = [
self::ACTIONS_TABLE,
@@ -33,10 +36,16 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
add_action( 'action_scheduler_before_schema_update', array( $this, 'update_schema_5_0' ), 10, 2 );
}
/**
* Get table definition.
*
* @param string $table Table name.
*/
protected function get_table_definition( $table ) {
global $wpdb;
$table_name = $wpdb->$table;
$charset_collate = $wpdb->get_charset_collate();
// phpcs:ignore Squiz.PHP.CommentedOutCode
$max_index_length = 191; // @see wp_get_db_schema()
$hook_status_scheduled_date_gmt_max_index_length = $max_index_length - 20 - 8; // - status, - scheduled_date_gmt
$default_date = self::DEFAULT_DATE;

View File

@@ -35,8 +35,9 @@ function as_enqueue_async_action( $hook, $args = array(), $group = '', $unique =
* @param array $args Action arguments.
* @param string $group Action group.
* @param int $priority Action priority.
* @param bool $unique Unique action.
*/
$pre = apply_filters( 'pre_as_enqueue_async_action', null, $hook, $args, $group, $priority );
$pre = apply_filters( 'pre_as_enqueue_async_action', null, $hook, $args, $group, $priority, $unique );
if ( null !== $pre ) {
return is_int( $pre ) ? $pre : 0;
}

View File

@@ -1,10 +1,10 @@
=== Action Scheduler ===
Contributors: Automattic, wpmuguru, claudiosanches, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, royho, barryhughes-1
Tags: scheduler, cron
Stable tag: 3.8.1
Stable tag: 3.8.2
License: GPLv3
Requires at least: 6.3
Tested up to: 6.5
Requires at least: 6.4
Tested up to: 6.6
Requires PHP: 7.0
Action Scheduler - Job Queue for WordPress
@@ -47,6 +47,12 @@ Collaboration is cool. We'd love to work with you to improve Action Scheduler. [
== Changelog ==
= 3.8.2 - 2024-09-12 =
* Add missing parameter to the `pre_as_enqueue_async_action` hook.
* Bump minimum PHP version to 7.0.
* Bump minimum WordPress version to 6.4.
* Make the batch size adjustable during processing.
= 3.8.1 - 2024-06-20 =
* Fix typos.
* Improve the messaging in our unidentified action exceptions.