diff --git a/.github/workflows/lint_phpstan.yml b/.github/workflows/lint_phpstan.yml
index f9dd138bb2..405ba130d6 100644
--- a/.github/workflows/lint_phpstan.yml
+++ b/.github/workflows/lint_phpstan.yml
@@ -9,6 +9,7 @@ on:
- feature/*
- enhancement/*
- fix/*
+ - dev/*
jobs:
run:
@@ -18,7 +19,7 @@ jobs:
fail-fast: false
matrix:
operating-system: [ubuntu-latest]
- php-versions: ['8.2']
+ php-versions: ['8.4']
name: WPRocket lint with PHP Stan. PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }}.
steps:
@@ -36,5 +37,5 @@ jobs:
run: composer install --prefer-dist --no-interaction --no-scripts
- name: Lint with PHP Stan
- run: composer run-stan -- --error-format=github
+ run: composer run-stan
diff --git a/composer.json b/composer.json
index 8f3b7e9da8..a9348f689b 100644
--- a/composer.json
+++ b/composer.json
@@ -67,7 +67,7 @@
"psr/container": "1.1.1",
"roave/security-advisories": "dev-master",
"szepeviktor/phpstan-wordpress": "^1.3",
- "woocommerce/action-scheduler": "^3.8",
+ "woocommerce/action-scheduler": "^3.9",
"wp-coding-standards/wpcs": "^3",
"wp-media/background-processing": "^1.3",
"wp-media/monolog": "^0.0",
diff --git a/inc/Dependencies/ActionScheduler/action-scheduler.php b/inc/Dependencies/ActionScheduler/action-scheduler.php
index 1d5cf7b09f..4d0839c544 100644
--- a/inc/Dependencies/ActionScheduler/action-scheduler.php
+++ b/inc/Dependencies/ActionScheduler/action-scheduler.php
@@ -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.9.1
* License: GPLv3
- * Requires at least: 6.2
+ * Requires at least: 6.5
* Tested up to: 6.5
- * Requires PHP: 5.6
+ * Requires PHP: 7.1
*
* 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_9_dot_1' ) && 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_9_dot_1', 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_9_dot_1() { // 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.9.1', 'action_scheduler_initialize_3_dot_9_dot_1' ); // 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_9_dot_1() { // 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 @@ function action_scheduler_initialize_3_dot_8_dot_1() { // WRCS: DEFINED_VERSION.
// 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_9_dot_1(); // WRCS: DEFINED_VERSION.
do_action( 'action_scheduler_pre_theme_init' );
ActionScheduler_Versions::initialize_latest_version();
}
diff --git a/inc/Dependencies/ActionScheduler/changelog.txt b/inc/Dependencies/ActionScheduler/changelog.txt
index 97c537d9fd..e42c84e4f2 100644
--- a/inc/Dependencies/ActionScheduler/changelog.txt
+++ b/inc/Dependencies/ActionScheduler/changelog.txt
@@ -1,5 +1,26 @@
*** Changelog ***
+= 3.9.1 - 2025-01-21 =
+* A number of new WP CLI commands have been added, making it easier to manage actions in the terminal and from scripts.
+* New wp action-scheduler source command to help determine how Action Scheduler is being loaded.
+* Additional information about the active instance of Action Scheduler is now available in the Help pull-down drawer.
+* Make some other nullable parameters explicitly nullable.
+* Set option value to `no` rather than deleting.
+
+= 3.9.0 - 2024-11-14 =
+* Minimum required version of PHP is now 7.1.
+* Performance improvements for the `as_pending_actions_due()` function.
+* Existing filter hook `action_scheduler_claim_actions_order_by` enhanced to provide callbacks with additional information.
+* Improved compatibility with PHP 8.4, specifically by making implicitly nullable parameters explicitly nullable.
+* A large number of coding standards-enhancements, to help reduce friction when submitting plugins to marketplaces and plugin directories. Special props @crstauf for this effort.
+* Minor documentation tweaks and improvements.
+
+= 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.
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionClaim.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionClaim.php
index 8b5681620e..8eb01eaa9f 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionClaim.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionClaim.php
@@ -4,20 +4,42 @@
* Class ActionScheduler_ActionClaim
*/
class ActionScheduler_ActionClaim {
+ /**
+ * Claim ID.
+ *
+ * @var string
+ */
private $id = '';
+
+ /**
+ * Claimed action IDs.
+ *
+ * @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->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;
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionFactory.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionFactory.php
index c8d68af3fa..ea60d60ba8 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionFactory.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ActionFactory.php
@@ -8,17 +8,17 @@ class ActionScheduler_ActionFactory {
/**
* Return stored actions for given params.
*
- * @param string $status The action's status in the data store.
- * @param string $hook The hook to trigger when this action runs.
- * @param array $args Args to pass to callbacks when the hook is triggered.
- * @param ActionScheduler_Schedule $schedule The action's schedule.
- * @param string $group A group to put the action in.
+ * @param string $status The action's status in the data store.
+ * @param string $hook The hook to trigger when this action runs.
+ * @param array $args Args to pass to callbacks when the hook is triggered.
+ * @param ActionScheduler_Schedule|null $schedule The action's schedule.
+ * @param string $group A group to put the action in.
* phpcs:ignore Squiz.Commenting.FunctionComment.ExtraParamComment
- * @param int $priority The action priority.
+ * @param int $priority The action priority.
*
* @return ActionScheduler_Action An instance of the stored action.
*/
- public function get_stored_action( $status, $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
+ public function get_stored_action( $status, $hook, array $args = array(), ?ActionScheduler_Schedule $schedule = null, $group = '' ) {
// The 6th parameter ($priority) is not formally declared in the method signature to maintain compatibility with
// third-party subclasses created before this param was added.
$priority = func_num_args() >= 6 ? (int) func_get_arg( 5 ) : 10;
@@ -307,6 +307,7 @@ public function create( array $options = array() ) {
break;
default:
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
error_log( "Unknown action type '{$options['type']}' specified when trying to create an action for '{$options['hook']}'." );
return 0;
}
@@ -318,6 +319,7 @@ public function create( array $options = array() ) {
try {
$action_id = $options['unique'] ? $this->store_unique_action( $action ) : $this->store( $action );
} catch ( Exception $e ) {
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
error_log(
sprintf(
/* translators: %1$s is the name of the hook to be enqueued, %2$s is the exception message. */
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AdminView.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AdminView.php
index ed30950a73..0d715f5ba1 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AdminView.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AdminView.php
@@ -2,25 +2,42 @@
/**
* Class ActionScheduler_AdminView
+ *
* @codeCoverageIgnore
*/
class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
- private static $admin_view = NULL;
+ /**
+ * Instance.
+ *
+ * @var null|self
+ */
+ private static $admin_view = null;
+ /**
+ * Screen ID.
+ *
+ * @var string
+ */
private static $screen_id = 'tools_page_action-scheduler';
- /** @var ActionScheduler_ListTable */
+ /**
+ * ActionScheduler_ListTable instance.
+ *
+ * @var ActionScheduler_ListTable
+ */
protected $list_table;
/**
+ * Get instance.
+ *
* @return ActionScheduler_AdminView
* @codeCoverageIgnore
*/
public static function instance() {
if ( empty( self::$admin_view ) ) {
- $class = apply_filters('action_scheduler_admin_view_class', 'ActionScheduler_AdminView');
+ $class = apply_filters( 'action_scheduler_admin_view_class', 'ActionScheduler_AdminView' );
self::$admin_view = new $class();
}
@@ -28,10 +45,12 @@ public static function instance() {
}
/**
+ * Initialize.
+ *
* @codeCoverageIgnore
*/
public function init() {
- if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) {
+ if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
if ( class_exists( 'WooCommerce' ) ) {
add_action( 'woocommerce_admin_status_content_action-scheduler', array( $this, 'render_admin_ui' ) );
@@ -45,6 +64,9 @@ public function init() {
}
}
+ /**
+ * Print system status report.
+ */
public function system_status_report() {
$table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() );
$table->render();
@@ -78,7 +100,7 @@ public function register_menu() {
'action-scheduler',
array( $this, 'render_admin_ui' )
);
- add_action( 'load-' . $hook_suffix , array( $this, 'process_admin_ui' ) );
+ add_action( 'load-' . $hook_suffix, array( $this, 'process_admin_ui' ) );
}
/**
@@ -119,33 +141,31 @@ protected function get_list_table() {
*/
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();
}
/**
* Check past-due actions, and print notice.
- *
- * @todo update $link_url to "Past-due" filter when released (see issue #510, PR #511)
*/
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 +178,24 @@ protected function check_pastdue_actions() {
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' );
+ $store = ActionScheduler_Store::instance();
+ $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 );
@@ -183,28 +203,40 @@ protected function check_pastdue_actions() {
return;
}
- $actions_url = add_query_arg( array(
- 'page' => 'action-scheduler',
- 'status' => 'past-due',
- 'order' => 'asc',
- ), admin_url( 'tools.php' ) );
+ $actions_url = add_query_arg(
+ array(
+ 'page' => 'action-scheduler',
+ 'status' => 'past-due',
+ 'order' => 'asc',
+ ),
+ admin_url( 'tools.php' )
+ );
- # Print notice.
+ // Print notice.
echo '
';
printf(
- // translators: 1) is the number of affected actions, 2) is a link to an admin screen.
- _n(
- 'Action Scheduler: %1$d past-due action found; something may be wrong. Read documentation »',
- 'Action Scheduler: %1$d past-due actions found; something may be wrong. Read documentation »',
- $num_pastdue_actions,
- 'action-scheduler'
+ wp_kses(
+ // translators: 1) is the number of affected actions, 2) is a link to an admin screen.
+ _n(
+ 'Action Scheduler: %1$d past-due action found; something may be wrong. Read documentation »',
+ 'Action Scheduler: %1$d past-due actions found; something may be wrong. Read documentation »',
+ $num_pastdue_actions,
+ 'action-scheduler'
+ ),
+ array(
+ 'strong' => array(),
+ 'a' => array(
+ 'href' => true,
+ 'target' => true,
+ ),
+ )
),
- $num_pastdue_actions,
+ absint( $num_pastdue_actions ),
esc_attr( esc_url( $actions_url ) )
);
echo '
';
- # 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 );
}
@@ -214,11 +246,24 @@ protected function check_pastdue_actions() {
public function add_help_tabs() {
$screen = get_current_screen();
- if ( ! $screen || self::$screen_id != $screen->id ) {
+ if ( ! $screen || self::$screen_id !== $screen->id ) {
return;
}
- $as_version = ActionScheduler_Versions::instance()->latest_version();
+ $as_version = ActionScheduler_Versions::instance()->latest_version();
+ $as_source = ActionScheduler_Versions::instance()->active_source();
+ $as_source_path = ActionScheduler_Versions::instance()->active_source_path();
+ $as_source_markup = sprintf( '%s
', esc_html( $as_source_path ) );
+
+ if ( ! empty( $as_source ) ) {
+ $as_source_markup = sprintf(
+ '%s: %s',
+ ucfirst( $as_source['type'] ),
+ esc_attr( $as_source_path ),
+ esc_html( $as_source['name'] )
+ );
+ }
+
$screen->add_help_tab(
array(
'id' => 'action_scheduler_about',
@@ -228,6 +273,19 @@ public function add_help_tabs() {
'' . sprintf( __( 'About Action Scheduler %s', 'action-scheduler' ), $as_version ) . '
' .
'' .
__( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) .
+ '
' .
+ '' . esc_html__( 'Source', 'action-scheduler' ) . '
' .
+ '' .
+ esc_html__( 'Action Scheduler is currently being loaded from the following location. This can be useful when debugging, or if requested by the support team.', 'action-scheduler' ) .
+ '
' .
+ '' . $as_source_markup . '
' .
+ '' . esc_html__( 'WP CLI', 'action-scheduler' ) . '
' .
+ '' .
+ sprintf(
+ /* translators: %1$s is WP CLI command (not translatable) */
+ esc_html__( 'WP CLI commands are available: execute %1$s for a list of available commands.', 'action-scheduler' ),
+ 'wp help action-scheduler
'
+ ) .
'
',
)
);
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php
index 57706a24c4..2eaf86d5f4 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php
@@ -1,7 +1,4 @@
get_sleep_seconds();
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Compatibility.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Compatibility.php
index bb28023bc9..ede48aa6ed 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Compatibility.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Compatibility.php
@@ -49,7 +49,7 @@ public static function raise_memory_limit() {
return wp_raise_memory_limit( 'admin' );
}
- $current_limit = @ini_get( 'memory_limit' );
+ $current_limit = @ini_get( 'memory_limit' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
$current_limit_int = self::convert_hr_to_bytes( $current_limit );
if ( -1 === $current_limit_int ) {
@@ -61,6 +61,9 @@ public static function raise_memory_limit() {
$filtered_limit = apply_filters( 'admin_memory_limit', $wp_max_limit );
$filtered_limit_int = self::convert_hr_to_bytes( $filtered_limit );
+ // phpcs:disable WordPress.PHP.IniSet.memory_limit_Blacklisted
+ // phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
+
if ( -1 === $filtered_limit_int || ( $filtered_limit_int > $wp_max_limit_int && $filtered_limit_int > $current_limit_int ) ) {
if ( false !== @ini_set( 'memory_limit', $filtered_limit ) ) {
return $filtered_limit;
@@ -74,6 +77,9 @@ public static function raise_memory_limit() {
return false;
}
}
+
+ // phpcs:enable
+
return false;
}
@@ -85,7 +91,7 @@ public static function raise_memory_limit() {
* @param int $limit The time limit in seconds.
*/
public static function raise_time_limit( $limit = 0 ) {
- $limit = (int) $limit;
+ $limit = (int) $limit;
$max_execution_time = (int) ini_get( 'max_execution_time' );
// If the max execution time is already set to zero (unlimited), there is no reason to make a further change.
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DataController.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DataController.php
index eb69847b5f..8bceba2876 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DataController.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DataController.php
@@ -18,10 +18,10 @@ class ActionScheduler_DataController {
const DATASTORE_CLASS = 'ActionScheduler_DBStore';
/** Logger data store class name. */
- const LOGGER_CLASS = 'ActionScheduler_DBLogger';
+ const LOGGER_CLASS = 'ActionScheduler_DBLogger';
/** Migration status option name. */
- const STATUS_FLAG = 'action_scheduler_migration_status';
+ const STATUS_FLAG = 'action_scheduler_migration_status';
/** Migration status option value. */
const STATUS_COMPLETE = 'complete';
@@ -29,13 +29,25 @@ class ActionScheduler_DataController {
/** Migration minimum required PHP version. */
const MIN_PHP_VERSION = '5.5';
- /** @var ActionScheduler_DataController */
+ /**
+ * Instance.
+ *
+ * @var ActionScheduler_DataController
+ */
private static $instance;
- /** @var int */
+ /**
+ * Sleep time in seconds.
+ *
+ * @var int
+ */
private static $sleep_time = 0;
- /** @var int */
+ /**
+ * Tick count required for freeing memory.
+ *
+ * @var int
+ */
private static $free_ticks = 50;
/**
@@ -137,6 +149,8 @@ public static function free_memory() {
\WP_CLI::warning( __( 'Attempting to reduce used memory...', 'action-scheduler' ) );
/**
+ * Globals.
+ *
* @var $wpdb \wpdb
* @var $wp_object_cache \WP_Object_Cache
*/
@@ -154,7 +168,7 @@ public static function free_memory() {
$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!
}
}
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DateTime.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DateTime.php
index b142ca81cc..3d3f68bfc9 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DateTime.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_DateTime.php
@@ -15,7 +15,7 @@ class ActionScheduler_DateTime extends DateTime {
*
* @var int
*/
- protected $utcOffset = 0;
+ protected $utcOffset = 0; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.PropertyNotSnakeCase
/**
* Get the unix timestamp of the current object.
@@ -34,10 +34,10 @@ public function getTimestamp() {
*
* 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 );
+ $this->utcOffset = intval( $offset ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
/**
@@ -48,20 +48,20 @@ public function setUtcOffset( $offset ) {
*/
#[\ReturnTypeWillChange]
public function getOffset() {
- return $this->utcOffset ? $this->utcOffset : parent::getOffset();
+ return $this->utcOffset ? $this->utcOffset : parent::getOffset(); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
}
/**
* 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
*/
#[\ReturnTypeWillChange]
public function setTimezone( $timezone ) {
- $this->utcOffset = 0;
+ $this->utcOffset = 0; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
parent::setTimezone( $timezone );
return $this;
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_FatalErrorMonitor.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_FatalErrorMonitor.php
index 5fa67d681b..26eb93aef6 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_FatalErrorMonitor.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_FatalErrorMonitor.php
@@ -4,51 +4,94 @@
* Class ActionScheduler_FatalErrorMonitor
*/
class ActionScheduler_FatalErrorMonitor {
- /** @var ActionScheduler_ActionClaim */
- private $claim = NULL;
- /** @var ActionScheduler_Store */
- private $store = NULL;
+
+ /**
+ * ActionScheduler_ActionClaim instance.
+ *
+ * @var ActionScheduler_ActionClaim
+ */
+ private $claim = null;
+
+ /**
+ * ActionScheduler_Store instance.
+ *
+ * @var ActionScheduler_Store
+ */
+ private $store = null;
+
+ /**
+ * Current action's ID.
+ *
+ * @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' ) );
add_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0, 1 );
- add_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0, 0 );
- add_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0, 0 );
- add_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0, 0 );
+ add_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0, 0 );
+ add_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0, 0 );
+ add_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0, 0 );
}
+ /**
+ * Stop monitoring.
+ */
public function detach() {
- $this->claim = NULL;
+ $this->claim = null;
$this->untrack_action();
remove_action( 'shutdown', array( $this, 'handle_unexpected_shutdown' ) );
remove_action( 'action_scheduler_before_execute', array( $this, 'track_current_action' ), 0 );
- remove_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0 );
- remove_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0 );
- remove_action( 'action_scheduler_failed_execution', array( $this, 'untrack_action' ), 0 );
+ remove_action( 'action_scheduler_after_execute', array( $this, 'untrack_action' ), 0 );
+ remove_action( 'action_scheduler_execution_ignored', array( $this, 'untrack_action' ), 0 );
+ 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() ) {
- if ( in_array( $error['type'], array( E_ERROR, E_PARSE, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR ) ) ) {
- if ( !empty($this->action_id) ) {
+ $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 ), true ) ) {
+ if ( ! empty( $this->action_id ) ) {
$this->store->mark_failure( $this->action_id );
do_action( 'action_scheduler_unexpected_shutdown', $this->action_id, $error );
}
}
+
$this->store->release_claim( $this->claim );
}
}
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_InvalidActionException.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_InvalidActionException.php
index 40b4559932..c64e971ec1 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_InvalidActionException.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_InvalidActionException.php
@@ -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 ) {
@@ -20,7 +21,7 @@ public static function from_schedule( $action_id, $schedule ) {
/* translators: 1: action ID 2: schedule */
__( 'Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler' ),
$action_id,
- var_export( $schedule, true )
+ var_export( $schedule, true ) // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
);
return new static( $message );
@@ -29,9 +30,8 @@ public static function from_schedule( $action_id, $schedule ) {
/**
* Create a new exception when the action's args cannot be decoded to an array.
*
- * @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() ) {
@@ -39,7 +39,7 @@ public static function from_decoding_args( $action_id, $args = array() ) {
/* translators: 1: action ID 2: arguments */
__( 'Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler' ),
$action_id,
- var_export( $args, true )
+ var_export( $args, true ) // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
);
return new static( $message );
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ListTable.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ListTable.php
index abf767ce65..e8f1e4315a 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ListTable.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_ListTable.php
@@ -2,6 +2,7 @@
/**
* Implements the admin view of the actions.
+ *
* @codeCoverageIgnore
*/
class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
@@ -49,9 +50,8 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
protected $runner;
/**
- * Bulk actions. The key of the array is the method name of the implementation:
- *
- * bulk_(array $ids, string $sql_in).
+ * Bulk actions. The key of the array is the method name of the implementation.
+ * Example: bulk_(array $ids, string $sql_in).
*
* See the comments in the parent class for further details
*
@@ -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 ) {
@@ -118,16 +118,16 @@ public function __construct( ActionScheduler_Store $store, ActionScheduler_Logge
if ( empty( $request_status ) ) {
$this->sort_by[] = 'status';
- } elseif ( in_array( $request_status, array( 'in-progress', 'failed' ) ) ) {
+ } elseif ( in_array( $request_status, array( 'in-progress', 'failed' ), true ) ) {
$this->columns += array( 'claim_id' => __( 'Claim ID', 'action-scheduler' ) );
$this->sort_by[] = 'claim_id';
}
$this->row_actions = array(
'hook' => array(
- 'run' => array(
- 'name' => __( 'Run', 'action-scheduler' ),
- 'desc' => __( 'Process the action now as if it were run as part of a queue', 'action-scheduler' ),
+ 'run' => array(
+ 'name' => __( 'Run', 'action-scheduler' ),
+ 'desc' => __( 'Process the action now as if it were run as part of a queue', 'action-scheduler' ),
),
'cancel' => array(
'name' => __( 'Cancel', 'action-scheduler' ),
@@ -224,9 +224,10 @@ private static function human_interval( $interval, $periods_to_include = 2 ) {
return __( 'Now!', 'action-scheduler' );
}
- $output = '';
+ $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'] );
@@ -234,7 +235,7 @@ private static function human_interval( $interval, $periods_to_include = 2 ) {
if ( ! empty( $output ) ) {
$output .= ' ';
}
- $output .= sprintf( translate_nooped_plural( self::$time_periods[ $time_period_index ]['names'], $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
+ $output .= sprintf( translate_nooped_plural( self::$time_periods[ $time_period_index ]['names'], $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
$seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds'];
$periods_included++;
}
@@ -246,7 +247,7 @@ private static function human_interval( $interval, $periods_to_include = 2 ) {
/**
* 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 @@ protected function get_recurrence( $action ) {
/**
* 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
*/
@@ -280,7 +281,7 @@ public function column_args( array $row ) {
$row_html = '';
foreach ( $row['args'] as $key => $value ) {
- $row_html .= sprintf( '%s => %s
', esc_html( var_export( $key, true ) ), esc_html( var_export( $value, true ) ) );
+ $row_html .= sprintf( '%s => %s
', esc_html( var_export( $key, true ) ), esc_html( var_export( $value, true ) ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
}
$row_html .= '
';
@@ -311,8 +312,8 @@ public function column_log_entries( array $row ) {
/**
* 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,13 +325,13 @@ protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, Date
/**
* 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
*/
protected function maybe_render_actions( $row, $column_name ) {
- if ( 'pending' === strtolower( $row[ 'status_name' ] ) ) {
+ if ( 'pending' === strtolower( $row['status_name'] ) ) {
return parent::maybe_render_actions( $row, $column_name );
}
@@ -358,10 +359,10 @@ public function display_admin_notices() {
$found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
foreach ( $table_list as $table_name ) {
- if ( ! in_array( $wpdb->prefix . $table_name, $found_tables ) ) {
+ if ( ! in_array( $wpdb->prefix . $table_name, $found_tables, true ) ) {
$this->admin_notices[] = array(
'class' => 'error',
- 'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).' , 'action-scheduler' ),
+ 'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).', 'action-scheduler' ),
);
$this->recreate_tables();
parent::display_admin_notices();
@@ -390,9 +391,9 @@ public function display_admin_notices() {
$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' ) );
+ $in_progress_url = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) );
/* translators: %s: process URL */
$async_request_message = sprintf( __( 'A new queue has begun processing. View actions in-progress »', 'action-scheduler' ), esc_url( $in_progress_url ) );
} else {
@@ -411,20 +412,21 @@ public function display_admin_notices() {
if ( is_array( $notification ) ) {
delete_transient( 'action_scheduler_admin_notice' );
- $action = $this->store->fetch_action( $notification['action_id'] );
+ $action = $this->store->fetch_action( $notification['action_id'] );
$action_hook_html = '' . $action->get_hook() . '
';
- if ( 1 == $notification['success'] ) {
+
+ if ( 1 === absint( $notification['success'] ) ) {
$class = 'updated';
switch ( $notification['row_action_type'] ) {
- case 'run' :
+ case 'run':
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
break;
- case 'cancel' :
+ case 'cancel':
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
break;
- default :
+ default:
/* translators: %s: action HTML */
$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
break;
@@ -449,7 +451,7 @@ public function display_admin_notices() {
/**
* 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 +462,7 @@ public function column_schedule( $row ) {
/**
* 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 +494,13 @@ protected function get_schedule_display_string( ActionScheduler_Schedule $schedu
}
/**
- * 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 ) {
@@ -507,6 +509,7 @@ protected function bulk_delete( array $ids, $ids_sql ) {
} catch ( Exception $e ) {
// A possible reason for an exception would include a scenario where the same action is deleted by a
// concurrent request.
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
error_log(
sprintf(
/* translators: 1: action ID 2: exception message. */
@@ -523,7 +526,7 @@ protected function bulk_delete( array $ids, $ids_sql ) {
* 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 +536,7 @@ protected function row_action_cancel( $action_id ) {
* 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,23 +563,23 @@ protected function recreate_tables() {
/**
* 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 ) {
try {
switch ( $row_action_type ) {
- case 'run' :
+ case 'run':
$this->runner->process_action( $action_id, 'Admin List Table' );
break;
- case 'cancel' :
+ case 'cancel':
$this->store->cancel_action( $action_id );
break;
}
- $success = 1;
+ $success = 1;
$error_message = '';
} catch ( Exception $e ) {
- $success = 0;
+ $success = 0;
$error_message = $e->getMessage();
}
@@ -639,11 +642,13 @@ public function prepare_items() {
);
}
- $this->set_pagination_args( array(
- 'total_items' => $total_items,
- 'per_page' => $per_page,
- 'total_pages' => ceil( $total_items / $per_page ),
- ) );
+ $this->set_pagination_args(
+ array(
+ 'total_items' => $total_items,
+ 'per_page' => $per_page,
+ 'total_pages' => ceil( $total_items / $per_page ),
+ )
+ );
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_LogEntry.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_LogEntry.php
index 649636debf..726fea2ec4 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_LogEntry.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_LogEntry.php
@@ -6,16 +6,22 @@
class ActionScheduler_LogEntry {
/**
+ * Action's ID for log entry.
+ *
* @var int $action_id
*/
- protected $action_id = '';
+ protected $action_id = '';
/**
+ * Log entry's message.
+ *
* @var string $message
*/
- protected $message = '';
+ protected $message = '';
/**
+ * Log entry's date.
+ *
* @var Datetime $date
*/
protected $date;
@@ -23,13 +29,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
@@ -44,7 +49,7 @@ public function __construct( $action_id, $message, $date = null ) {
$this->action_id = $action_id;
$this->message = $message;
- $this->date = $date ? $date : new Datetime;
+ $this->date = $date ? $date : new Datetime();
}
/**
@@ -56,10 +61,16 @@ public function get_date() {
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;
}
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_NullLogEntry.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_NullLogEntry.php
index 6f8f218aab..4df0f05adc 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_NullLogEntry.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_NullLogEntry.php
@@ -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.
}
+
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_OptionLock.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_OptionLock.php
index 911f9b77c7..547857a0a2 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_OptionLock.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_OptionLock.php
@@ -5,6 +5,7 @@
* for up-to a given duration.
*
* Class ActionScheduler_OptionLock
+ *
* @since 3.0.0
*/
class ActionScheduler_OptionLock extends ActionScheduler_Lock {
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueCleaner.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueCleaner.php
index 6b066dca02..7029d0b215 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueCleaner.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueCleaner.php
@@ -5,10 +5,18 @@
*/
class ActionScheduler_QueueCleaner {
- /** @var int */
+ /**
+ * The batch size.
+ *
+ * @var int
+ */
protected $batch_size;
- /** @var ActionScheduler_Store */
+ /**
+ * ActionScheduler_Store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $store = null;
/**
@@ -19,21 +27,23 @@ class ActionScheduler_QueueCleaner {
private $month_in_seconds = 2678400;
/**
- * @var string[] Default list of statuses purged by the cleaner process.
+ * Default list of statuses purged by the cleaner process.
+ *
+ * @var string[]
*/
- private $default_statuses_to_purge = [
+ private $default_statuses_to_purge = array(
ActionScheduler_Store::STATUS_COMPLETE,
ActionScheduler_Store::STATUS_CANCELED,
- ];
+ );
/**
* ActionScheduler_QueueCleaner constructor.
*
- * @param ActionScheduler_Store $store The store instance.
- * @param int $batch_size The batch size.
+ * @param ActionScheduler_Store|null $store The store instance.
+ * @param int $batch_size The batch size.
*/
- public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) {
- $this->store = $store ? $store : ActionScheduler_Store::instance();
+ public function __construct( ?ActionScheduler_Store $store = null, $batch_size = 20 ) {
+ $this->store = $store ? $store : ActionScheduler_Store::instance();
$this->batch_size = $batch_size;
}
@@ -66,7 +76,6 @@ public function delete_old_actions() {
return array();
}
-
/**
* Filter the statuses when cleaning the queue.
*
@@ -83,26 +92,30 @@ public function delete_old_actions() {
* @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' ) {
- $batch_size = $batch_size !== null ? $batch_size : $this->batch_size;
- $cutoff = $cutoff_date !== null ? $cutoff_date : as_get_datetime_object( $this->month_in_seconds . ' seconds ago' );
+ $batch_size = ! is_null( $batch_size ) ? $batch_size : $this->batch_size;
+ $cutoff = ! is_null( $cutoff_date ) ? $cutoff_date : as_get_datetime_object( $this->month_in_seconds . ' seconds ago' );
$lifespan = time() - $cutoff->getTimestamp();
+
if ( empty( $statuses_to_purge ) ) {
$statuses_to_purge = $this->default_statuses_to_purge;
}
- $deleted_actions = [];
+ $deleted_actions = array();
+
foreach ( $statuses_to_purge as $status ) {
- $actions_to_delete = $this->store->query_actions( array(
- 'status' => $status,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'per_page' => $batch_size,
- 'orderby' => 'none',
- ) );
+ $actions_to_delete = $this->store->query_actions(
+ array(
+ 'status' => $status,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $batch_size,
+ 'orderby' => 'none',
+ )
+ );
$deleted_actions = array_merge( $deleted_actions, $this->delete_actions( $actions_to_delete, $lifespan, $context ) );
}
@@ -111,14 +124,17 @@ public function clean_actions( array $statuses_to_purge, DateTime $cutoff_date,
}
/**
- * @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.
*/
private function delete_actions( array $actions_to_delete, $lifespan = null, $context = 'old' ) {
- $deleted_actions = [];
- if ( $lifespan === null ) {
+ $deleted_actions = array();
+
+ if ( is_null( $lifespan ) ) {
$lifespan = $this->month_in_seconds;
}
@@ -138,7 +154,6 @@ private function delete_actions( array $actions_to_delete, $lifespan = null, $co
* @param int $lifespan The retention period, in seconds, for old actions
* @param int $count_of_actions_to_delete The number of old actions being deleted in this batch
* @since 2.0.0
- *
*/
do_action( "action_scheduler_failed_{$context}_action_deletion", $action_id, $e, $lifespan, count( $actions_to_delete ) );
}
@@ -156,18 +171,22 @@ private function delete_actions( array $actions_to_delete, $lifespan = null, $co
*/
public function reset_timeouts( $time_limit = 300 ) {
$timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit );
+
if ( $timeout < 0 ) {
return;
}
- $cutoff = as_get_datetime_object($timeout.' seconds ago');
- $actions_to_reset = $this->store->query_actions( array(
- 'status' => ActionScheduler_Store::STATUS_PENDING,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'claimed' => true,
- 'per_page' => $this->get_batch_size(),
- 'orderby' => 'none',
- ) );
+
+ $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
+ $actions_to_reset = $this->store->query_actions(
+ array(
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'claimed' => true,
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ )
+ );
foreach ( $actions_to_reset as $action_id ) {
$this->store->unclaim_action( $action_id );
@@ -186,17 +205,21 @@ public function reset_timeouts( $time_limit = 300 ) {
*/
public function mark_failures( $time_limit = 300 ) {
$timeout = apply_filters( 'action_scheduler_failure_period', $time_limit );
+
if ( $timeout < 0 ) {
return;
}
- $cutoff = as_get_datetime_object($timeout.' seconds ago');
- $actions_to_reset = $this->store->query_actions( array(
- 'status' => ActionScheduler_Store::STATUS_RUNNING,
- 'modified' => $cutoff,
- 'modified_compare' => '<=',
- 'per_page' => $this->get_batch_size(),
- 'orderby' => 'none',
- ) );
+
+ $cutoff = as_get_datetime_object( $timeout . ' seconds ago' );
+ $actions_to_reset = $this->store->query_actions(
+ array(
+ 'status' => ActionScheduler_Store::STATUS_RUNNING,
+ 'modified' => $cutoff,
+ 'modified_compare' => '<=',
+ 'per_page' => $this->get_batch_size(),
+ 'orderby' => 'none',
+ )
+ );
foreach ( $actions_to_reset as $action_id ) {
$this->store->mark_failure( $action_id );
@@ -208,7 +231,6 @@ public function mark_failures( $time_limit = 300 ) {
* Do all of the cleaning actions.
*
* @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes).
- * @author Jeremy Pry
*/
public function clean( $time_limit = 300 ) {
$this->delete_old_actions();
@@ -219,7 +241,6 @@ public function clean( $time_limit = 300 ) {
/**
* Get the batch size for cleaning the queue.
*
- * @author Jeremy Pry
* @return int
*/
protected function get_batch_size() {
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueRunner.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueRunner.php
index 90e64fc46e..13a71e796b 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueRunner.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_QueueRunner.php
@@ -8,35 +8,51 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
const WP_CRON_SCHEDULE = 'every_minute';
- /** @var ActionScheduler_AsyncRequest_QueueRunner */
+ /**
+ * ActionScheduler_AsyncRequest_QueueRunner instance.
+ *
+ * @var ActionScheduler_AsyncRequest_QueueRunner
+ */
protected $async_request;
- /** @var ActionScheduler_QueueRunner */
+ /**
+ * ActionScheduler_QueueRunner instance.
+ *
+ * @var ActionScheduler_QueueRunner
+ */
private static $runner = null;
- /** @var int */
+ /**
+ * Number of processed actions.
+ *
+ * @var int
+ */
private $processed_actions_count = 0;
/**
+ * Get instance.
+ *
* @return ActionScheduler_QueueRunner
* @codeCoverageIgnore
*/
public static function instance() {
- if ( empty(self::$runner) ) {
- $class = apply_filters('action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner');
+ if ( empty( self::$runner ) ) {
+ $class = apply_filters( 'action_scheduler_queue_runner_class', 'ActionScheduler_QueueRunner' );
self::$runner = new $class();
}
+
return self::$runner;
}
/**
* ActionScheduler_QueueRunner constructor.
*
- * @param ActionScheduler_Store $store
- * @param ActionScheduler_FatalErrorMonitor $monitor
- * @param ActionScheduler_QueueCleaner $cleaner
+ * @param ActionScheduler_Store|null $store Store object.
+ * @param ActionScheduler_FatalErrorMonitor|null $monitor Monitor object.
+ * @param ActionScheduler_QueueCleaner|null $cleaner Cleaner object.
+ * @param ActionScheduler_AsyncRequest_QueueRunner|null $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 ) {
+ 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 );
if ( is_null( $async_request ) ) {
@@ -47,13 +63,15 @@ public function __construct( ActionScheduler_Store $store = null, ActionSchedule
}
/**
+ * Initialize.
+ *
* @codeCoverageIgnore
*/
public function init() {
- add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) );
+ add_filter( 'cron_schedules', array( self::instance(), 'add_wp_cron_schedule' ) ); // phpcs:ignore WordPress.WP.CronInterval.CronSchedulesInterval
- // 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 );
@@ -120,6 +138,7 @@ public function maybe_dispatch_async_request() {
* that was the only context in which this method was run, and the self::WP_CRON_HOOK hook had no context
* passed along with it. New code calling this method directly, or by triggering the self::WP_CRON_HOOK,
* should set a context as the first parameter. For an example of this, refer to the code seen in
+ *
* @see ActionScheduler_AsyncRequest_QueueRunner::handle()
*
* @param string $context Optional identifier for the context in which this action is being processed, e.g. 'WP CLI' or 'WP Cron'
@@ -134,11 +153,11 @@ public function run( $context = 'WP Cron' ) {
$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,19 +170,19 @@ public function run( $context = 'WP Cron' ) {
* 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 = '' ) {
- $claim = $this->store->stake_claim($size);
- $this->monitor->attach($claim);
+ $claim = $this->store->stake_claim( $size );
+ $this->monitor->attach( $claim );
$processed_actions = 0;
foreach ( $claim->get_actions() as $action_id ) {
- // bail if we lost the claim
- if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ) ) ) {
+ // bail if we lost the claim.
+ if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $claim->get_id() ), true ) ) {
break;
}
$this->process_action( $action_id, $context );
@@ -173,7 +192,7 @@ protected function do_batch( $size = 100, $context = '' ) {
break;
}
}
- $this->store->release_claim($claim);
+ $this->store->release_claim( $claim );
$this->monitor->detach();
$this->clear_caches();
return $processed_actions;
@@ -218,9 +237,15 @@ protected function clear_caches() {
}
}
+ /**
+ * Add schedule to WP cron.
+ *
+ * @param array> $schedules Schedules.
+ * @return array>
+ */
public function add_wp_cron_schedule( $schedules ) {
$schedules['every_minute'] = array(
- 'interval' => 60, // in seconds
+ 'interval' => 60, // in seconds.
'display' => __( 'Every minute', 'action-scheduler' ),
);
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Versions.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Versions.php
index 915c2e6329..3c7bd26856 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Versions.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_Versions.php
@@ -5,58 +5,182 @@
*/
class ActionScheduler_Versions {
/**
+ * ActionScheduler_Versions instance.
+ *
* @var ActionScheduler_Versions
*/
- private static $instance = NULL;
+ private static $instance = null;
+ /**
+ * Versions.
+ *
+ * @var array
+ */
private $versions = array();
+ /**
+ * Registered sources.
+ *
+ * @var array
+ */
+ private $sources = 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;
+ if ( isset( $this->versions[ $version_string ] ) ) {
+ return false;
}
- $this->versions[$version_string] = $initialization_callback;
- return TRUE;
+
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
+ $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
+ $source = $backtrace[0]['file'];
+
+ $this->versions[ $version_string ] = $initialization_callback;
+ $this->sources[ $source ] = $version_string;
+ return true;
}
+ /**
+ * Get all versions.
+ */
public function get_versions() {
return $this->versions;
}
+ /**
+ * Get registered sources.
+ *
+ * @return array
+ */
+ public function get_sources() {
+ return $this->sources;
+ }
+
+ /**
+ * Get latest version registered.
+ */
public function latest_version() {
- $keys = array_keys($this->versions);
- if ( empty($keys) ) {
+ $keys = array_keys( $this->versions );
+ if ( empty( $keys ) ) {
return false;
}
uasort( $keys, 'version_compare' );
- return end($keys);
+ 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]) ) {
+
+ if ( empty( $latest ) || ! isset( $this->versions[ $latest ] ) ) {
return '__return_null';
}
- return $this->versions[$latest];
+
+ return $this->versions[ $latest ];
}
/**
+ * Get instance.
+ *
* @return ActionScheduler_Versions
* @codeCoverageIgnore
*/
public static function instance() {
- if ( empty(self::$instance) ) {
+ if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
+ * Initialize.
+ *
* @codeCoverageIgnore
*/
public static function initialize_latest_version() {
$self = self::instance();
- call_user_func($self->latest_version_callback());
+ call_user_func( $self->latest_version_callback() );
+ }
+
+ /**
+ * Returns information about the plugin or theme which contains the current active version
+ * of Action Scheduler.
+ *
+ * If this cannot be determined, or if Action Scheduler is being loaded via some other
+ * method, then it will return an empty array. Otherwise, if populated, the array will
+ * look like the following:
+ *
+ * [
+ * 'type' => 'plugin', # or 'theme'
+ * 'name' => 'Name',
+ * ]
+ *
+ * @return array
+ */
+ public function active_source(): array {
+ $file = __FILE__;
+ $dir = __DIR__;
+ $plugins = get_plugins();
+ $plugin_files = array_keys( $plugins );
+
+ foreach ( $plugin_files as $plugin_file ) {
+ $plugin_path = trailingslashit( WP_PLUGIN_DIR ) . dirname( $plugin_file );
+ $plugin_file = trailingslashit( WP_PLUGIN_DIR ) . $plugin_file;
+
+ if ( 0 !== strpos( dirname( $dir ), $plugin_path ) ) {
+ continue;
+ }
+
+ $plugin_data = get_plugin_data( $plugin_file );
+
+ if ( ! is_array( $plugin_data ) || empty( $plugin_data['Name'] ) ) {
+ continue;
+ }
+
+ return array(
+ 'type' => 'plugin',
+ 'name' => $plugin_data['Name'],
+ );
+ }
+
+ $themes = (array) search_theme_directories();
+
+ foreach ( $themes as $slug => $data ) {
+ $needle = trailingslashit( $data['theme_root'] ) . $slug . '/';
+
+ if ( 0 !== strpos( $file, $needle ) ) {
+ continue;
+ }
+
+ $theme = wp_get_theme( $slug );
+
+ if ( ! is_object( $theme ) || ! is_a( $theme, \WP_Theme::class ) ) {
+ continue;
+ }
+
+ return array(
+ 'type' => 'theme',
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ 'name' => $theme->Name,
+ );
+ }
+
+ return array();
+ }
+
+ /**
+ * Returns the directory path for the currently active installation of Action Scheduler.
+ *
+ * @return string
+ */
+ public function active_source_path(): string {
+ return trailingslashit( dirname( __DIR__ ) );
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_WPCommentCleaner.php b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_WPCommentCleaner.php
index 1ba552c50b..2725d1feeb 100644
--- a/inc/Dependencies/ActionScheduler/classes/ActionScheduler_WPCommentCleaner.php
+++ b/inc/Dependencies/ActionScheduler/classes/ActionScheduler_WPCommentCleaner.php
@@ -42,10 +42,10 @@ public static function init() {
// 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' ) );
}
@@ -66,13 +66,23 @@ public static function has_logs() {
* Attached to the migration complete hook 'action_scheduler/migration_complete'.
*/
public static function maybe_schedule_cleanup() {
- if ( (bool) get_comments( array( 'type' => ActionScheduler_wpCommentLogger::TYPE, 'number' => 1, 'fields' => 'ids' ) ) ) {
- update_option( self::$has_logs_option_key, 'yes' );
+ $has_logs = 'no';
+
+ $args = array(
+ 'type' => ActionScheduler_wpCommentLogger::TYPE,
+ 'number' => 1,
+ 'fields' => 'ids',
+ );
+
+ if ( (bool) get_comments( $args ) ) {
+ $has_logs = 'yes';
if ( ! as_next_scheduled_action( self::$cleanup_hook ) ) {
as_schedule_single_action( gmdate( 'U' ) + ( 6 * MONTH_IN_SECONDS ), self::$cleanup_hook );
}
}
+
+ update_option( self::$has_logs_option_key, $has_logs, true );
}
/**
@@ -80,8 +90,16 @@ public static function maybe_schedule_cleanup() {
*/
public static function delete_all_action_comments() {
global $wpdb;
- $wpdb->delete( $wpdb->comments, array( 'comment_type' => ActionScheduler_wpCommentLogger::TYPE, 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT ) );
- delete_option( self::$has_logs_option_key );
+
+ $wpdb->delete(
+ $wpdb->comments,
+ array(
+ 'comment_type' => ActionScheduler_wpCommentLogger::TYPE,
+ 'comment_agent' => ActionScheduler_wpCommentLogger::AGENT,
+ )
+ );
+
+ update_option( self::$has_logs_option_key, 'no', true );
}
/**
@@ -90,7 +108,7 @@ public static function delete_all_action_comments() {
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.
*/
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Cancel_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Cancel_Command.php
new file mode 100644
index 0000000000..e9eb9f2607
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Cancel_Command.php
@@ -0,0 +1,120 @@
+assoc_args, 'group', '' );
+ $callback_args = get_flag_value( $this->assoc_args, 'args', null );
+ $all = get_flag_value( $this->assoc_args, 'all', false );
+
+ if ( ! empty( $this->args[0] ) ) {
+ $hook = $this->args[0];
+ }
+
+ if ( ! empty( $callback_args ) ) {
+ $callback_args = json_decode( $callback_args, true );
+ }
+
+ if ( $all ) {
+ $this->cancel_all( $hook, $callback_args, $group );
+ return;
+ }
+
+ $this->cancel_single( $hook, $callback_args, $group );
+ }
+
+ /**
+ * Cancel single action.
+ *
+ * @param string $hook The hook that the job will trigger.
+ * @param array $callback_args Args that would have been passed to the job.
+ * @param string $group The group the job is assigned to.
+ * @return void
+ */
+ protected function cancel_single( $hook, $callback_args, $group ) {
+ if ( empty( $hook ) ) {
+ \WP_CLI::error( __( 'Please specify hook of action to cancel.', 'action-scheduler' ) );
+ }
+
+ try {
+ $result = as_unschedule_action( $hook, $callback_args, $group );
+ } catch ( \Exception $e ) {
+ $this->print_error( $e, false );
+ }
+
+ if ( null === $result ) {
+ $e = new \Exception( __( 'Unable to cancel scheduled action: check the logs.', 'action-scheduler' ) );
+ $this->print_error( $e, false );
+ }
+
+ $this->print_success( false );
+ }
+
+ /**
+ * Cancel all actions.
+ *
+ * @param string $hook The hook that the job will trigger.
+ * @param array $callback_args Args that would have been passed to the job.
+ * @param string $group The group the job is assigned to.
+ * @return void
+ */
+ protected function cancel_all( $hook, $callback_args, $group ) {
+ if ( empty( $hook ) && empty( $group ) ) {
+ \WP_CLI::error( __( 'Please specify hook and/or group of actions to cancel.', 'action-scheduler' ) );
+ }
+
+ try {
+ $result = as_unschedule_all_actions( $hook, $callback_args, $group );
+ } catch ( \Exception $e ) {
+ $this->print_error( $e, $multiple );
+ }
+
+ /**
+ * Because as_unschedule_all_actions() does not provide a result,
+ * neither confirm or deny actions cancelled.
+ */
+ \WP_CLI::success( __( 'Request to cancel scheduled actions completed.', 'action-scheduler' ) );
+ }
+
+ /**
+ * Print a success message.
+ *
+ * @return void
+ */
+ protected function print_success() {
+ \WP_CLI::success( __( 'Scheduled action cancelled.', 'action-scheduler' ) );
+ }
+
+ /**
+ * Convert an exception into a WP CLI error.
+ *
+ * @param \Exception $e The error object.
+ * @param bool $multiple Boolean if multiple actions.
+ * @throws \WP_CLI\ExitException When an error occurs.
+ * @return void
+ */
+ protected function print_error( \Exception $e, $multiple ) {
+ \WP_CLI::error(
+ sprintf(
+ /* translators: %1$s: singular or plural %2$s: refers to the exception error message. */
+ __( 'There was an error cancelling the %1$s: %2$s', 'action-scheduler' ),
+ $multiple ? __( 'scheduled actions', 'action-scheduler' ) : __( 'scheduled action', 'action-scheduler' ),
+ $e->getMessage()
+ )
+ );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Create_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Create_Command.php
new file mode 100644
index 0000000000..fedd417e23
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Create_Command.php
@@ -0,0 +1,151 @@
+args[0];
+ $schedule_start = $this->args[1];
+ $callback_args = get_flag_value( $this->assoc_args, 'args', array() );
+ $group = get_flag_value( $this->assoc_args, 'group', '' );
+ $interval = absint( get_flag_value( $this->assoc_args, 'interval', 0 ) );
+ $cron = get_flag_value( $this->assoc_args, 'cron', '' );
+ $unique = get_flag_value( $this->assoc_args, 'unique', false );
+ $priority = absint( get_flag_value( $this->assoc_args, 'priority', 10 ) );
+
+ if ( ! empty( $callback_args ) ) {
+ $callback_args = json_decode( $callback_args, true );
+ }
+
+ $function_args = array(
+ 'start' => $schedule_start,
+ 'cron' => $cron,
+ 'interval' => $interval,
+ 'hook' => $hook,
+ 'callback_args' => $callback_args,
+ 'group' => $group,
+ 'unique' => $unique,
+ 'priority' => $priority,
+ );
+
+ try {
+ // Generate schedule start if appropriate.
+ if ( ! in_array( $schedule_start, static::ASYNC_OPTS, true ) ) {
+ $schedule_start = as_get_datetime_object( $schedule_start );
+ $function_args['start'] = $schedule_start->format( 'U' );
+ }
+ } catch ( \Exception $e ) {
+ \WP_CLI::error( $e->getMessage() );
+ }
+
+ // Default to creating single action.
+ $action_type = 'single';
+ $function = 'as_schedule_single_action';
+
+ if ( ! empty( $interval ) ) { // Creating recurring action.
+ $action_type = 'recurring';
+ $function = 'as_schedule_recurring_action';
+
+ $function_args = array_filter(
+ $function_args,
+ static function( $key ) {
+ return in_array( $key, array( 'start', 'interval', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true );
+ },
+ ARRAY_FILTER_USE_KEY
+ );
+ } elseif ( ! empty( $cron ) ) { // Creating cron action.
+ $action_type = 'cron';
+ $function = 'as_schedule_cron_action';
+
+ $function_args = array_filter(
+ $function_args,
+ static function( $key ) {
+ return in_array( $key, array( 'start', 'cron', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true );
+ },
+ ARRAY_FILTER_USE_KEY
+ );
+ } elseif ( in_array( $function_args['start'], static::ASYNC_OPTS, true ) ) { // Enqueue async action.
+ $action_type = 'async';
+ $function = 'as_enqueue_async_action';
+
+ $function_args = array_filter(
+ $function_args,
+ static function( $key ) {
+ return in_array( $key, array( 'hook', 'callback_args', 'group', 'unique', 'priority' ), true );
+ },
+ ARRAY_FILTER_USE_KEY
+ );
+ } else { // Enqueue single action.
+ $function_args = array_filter(
+ $function_args,
+ static function( $key ) {
+ return in_array( $key, array( 'start', 'hook', 'callback_args', 'group', 'unique', 'priority' ), true );
+ },
+ ARRAY_FILTER_USE_KEY
+ );
+ }
+
+ $function_args = array_values( $function_args );
+
+ try {
+ $action_id = call_user_func_array( $function, $function_args );
+ } catch ( \Exception $e ) {
+ $this->print_error( $e );
+ }
+
+ if ( 0 === $action_id ) {
+ $e = new \Exception( __( 'Unable to create a scheduled action.', 'action-scheduler' ) );
+ $this->print_error( $e );
+ }
+
+ $this->print_success( $action_id, $action_type );
+ }
+
+ /**
+ * Print a success message with the action ID.
+ *
+ * @param int $action_id Created action ID.
+ * @param string $action_type Type of action.
+ *
+ * @return void
+ */
+ protected function print_success( $action_id, $action_type ) {
+ \WP_CLI::success(
+ sprintf(
+ /* translators: %1$s: type of action, %2$d: ID of the created action */
+ __( '%1$s action (%2$d) scheduled.', 'action-scheduler' ),
+ ucfirst( $action_type ),
+ $action_id
+ )
+ );
+ }
+
+ /**
+ * Convert an exception into a WP CLI error.
+ *
+ * @param \Exception $e The error object.
+ * @throws \WP_CLI\ExitException When an error occurs.
+ * @return void
+ */
+ protected function print_error( \Exception $e ) {
+ \WP_CLI::error(
+ sprintf(
+ /* translators: %s refers to the exception error message. */
+ __( 'There was an error creating the scheduled action: %s', 'action-scheduler' ),
+ $e->getMessage()
+ )
+ );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Delete_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Delete_Command.php
new file mode 100644
index 0000000000..a549e0b4e8
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Delete_Command.php
@@ -0,0 +1,108 @@
+
+ */
+ protected $action_counts = array(
+ 'deleted' => 0,
+ 'failed' => 0,
+ 'total' => 0,
+ );
+
+ /**
+ * Construct.
+ *
+ * @param string[] $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ */
+ public function __construct( array $args, array $assoc_args ) {
+ parent::__construct( $args, $assoc_args );
+
+ $this->action_ids = array_map( 'absint', $args );
+ $this->action_counts['total'] = count( $this->action_ids );
+
+ add_action( 'action_scheduler_deleted_action', array( $this, 'on_action_deleted' ) );
+ }
+
+ /**
+ * Execute.
+ *
+ * @return void
+ */
+ public function execute() {
+ $store = \ActionScheduler::store();
+
+ $progress_bar = \WP_CLI\Utils\make_progress_bar(
+ sprintf(
+ /* translators: %d: number of actions to be deleted */
+ _n( 'Deleting %d action', 'Deleting %d actions', $this->action_counts['total'], 'action-scheduler' ),
+ number_format_i18n( $this->action_counts['total'] )
+ ),
+ $this->action_counts['total']
+ );
+
+ foreach ( $this->action_ids as $action_id ) {
+ try {
+ $store->delete_action( $action_id );
+ } catch ( \Exception $e ) {
+ $this->action_counts['failed']++;
+ \WP_CLI::warning( $e->getMessage() );
+ }
+
+ $progress_bar->tick();
+ }
+
+ $progress_bar->finish();
+
+ /* translators: %1$d: number of actions deleted */
+ $format = _n( 'Deleted %1$d action', 'Deleted %1$d actions', $this->action_counts['deleted'], 'action-scheduler' ) . ', ';
+ /* translators: %2$d: number of actions deletions failed */
+ $format .= _n( '%2$d failure.', '%2$d failures.', $this->action_counts['failed'], 'action-scheduler' );
+
+ \WP_CLI::success(
+ sprintf(
+ $format,
+ number_format_i18n( $this->action_counts['deleted'] ),
+ number_format_i18n( $this->action_counts['failed'] )
+ )
+ );
+ }
+
+ /**
+ * Action: action_scheduler_deleted_action
+ *
+ * @param int $action_id Action ID.
+ * @return void
+ */
+ public function on_action_deleted( $action_id ) {
+ if ( 'action_scheduler_deleted_action' !== current_action() ) {
+ return;
+ }
+
+ $action_id = absint( $action_id );
+
+ if ( ! in_array( $action_id, $this->action_ids, true ) ) {
+ return;
+ }
+
+ $this->action_counts['deleted']++;
+ \WP_CLI::debug( sprintf( 'Action %d was deleted.', $action_id ) );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Generate_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Generate_Command.php
new file mode 100644
index 0000000000..6e6e8c77bd
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Generate_Command.php
@@ -0,0 +1,121 @@
+args[0];
+ $schedule_start = $this->args[1];
+ $callback_args = get_flag_value( $this->assoc_args, 'args', array() );
+ $group = get_flag_value( $this->assoc_args, 'group', '' );
+ $interval = (int) get_flag_value( $this->assoc_args, 'interval', 0 ); // avoid absint() to support negative intervals
+ $count = absint( get_flag_value( $this->assoc_args, 'count', 1 ) );
+
+ if ( ! empty( $callback_args ) ) {
+ $callback_args = json_decode( $callback_args, true );
+ }
+
+ $schedule_start = as_get_datetime_object( $schedule_start );
+
+ $function_args = array(
+ 'start' => absint( $schedule_start->format( 'U' ) ),
+ 'interval' => $interval,
+ 'count' => $count,
+ 'hook' => $hook,
+ 'callback_args' => $callback_args,
+ 'group' => $group,
+ );
+
+ $function_args = array_values( $function_args );
+
+ try {
+ $actions_added = $this->generate( ...$function_args );
+ } catch ( \Exception $e ) {
+ $this->print_error( $e );
+ }
+
+ $num_actions_added = count( (array) $actions_added );
+
+ $this->print_success( $num_actions_added, 'single' );
+ }
+
+ /**
+ * Schedule multiple single actions.
+ *
+ * @param int $schedule_start Starting timestamp of first action.
+ * @param int $interval How long to wait between runs.
+ * @param int $count Limit number of actions to schedule.
+ * @param string $hook The hook to trigger.
+ * @param array $args Arguments to pass when the hook triggers.
+ * @param string $group The group to assign this job to.
+ * @return int[] IDs of actions added.
+ */
+ protected function generate( $schedule_start, $interval, $count, $hook, array $args = array(), $group = '' ) {
+ $actions_added = array();
+
+ $progress_bar = \WP_CLI\Utils\make_progress_bar(
+ sprintf(
+ /* translators: %d is number of actions to create */
+ _n( 'Creating %d action', 'Creating %d actions', $count, 'action-scheduler' ),
+ number_format_i18n( $count )
+ ),
+ $count
+ );
+
+ for ( $i = 0; $i < $count; $i++ ) {
+ $actions_added[] = as_schedule_single_action( $schedule_start + ( $i * $interval ), $hook, $args, $group );
+ $progress_bar->tick();
+ }
+
+ $progress_bar->finish();
+
+ return $actions_added;
+ }
+
+ /**
+ * Print a success message with the action ID.
+ *
+ * @param int $actions_added Number of actions generated.
+ * @param string $action_type Type of actions scheduled.
+ * @return void
+ */
+ protected function print_success( $actions_added, $action_type ) {
+ \WP_CLI::success(
+ sprintf(
+ /* translators: %1$d refers to the total number of tasks added, %2$s is the action type */
+ _n( '%1$d %2$s action scheduled.', '%1$d %2$s actions scheduled.', $actions_added, 'action-scheduler' ),
+ number_format_i18n( $actions_added ),
+ $action_type
+ )
+ );
+ }
+
+ /**
+ * Convert an exception into a WP CLI error.
+ *
+ * @param \Exception $e The error object.
+ * @throws \WP_CLI\ExitException When an error occurs.
+ * @return void
+ */
+ protected function print_error( \Exception $e ) {
+ \WP_CLI::error(
+ sprintf(
+ /* translators: %s refers to the exception error message. */
+ __( 'There was an error creating the scheduled action: %s', 'action-scheduler' ),
+ $e->getMessage()
+ )
+ );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Get_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Get_Command.php
new file mode 100644
index 0000000000..95df595500
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Get_Command.php
@@ -0,0 +1,75 @@
+args[0];
+ $store = \ActionScheduler::store();
+ $logger = \ActionScheduler::logger();
+ $action = $store->fetch_action( $action_id );
+
+ if ( is_a( $action, ActionScheduler_NullAction::class ) ) {
+ /* translators: %d is action ID. */
+ \WP_CLI::error( sprintf( esc_html__( 'Unable to retrieve action %d.', 'action-scheduler' ), $action_id ) );
+ }
+
+ $only_logs = ! empty( $this->assoc_args['field'] ) && 'log_entries' === $this->assoc_args['field'];
+ $only_logs = $only_logs || ( ! empty( $this->assoc_args['fields'] && 'log_entries' === $this->assoc_args['fields'] ) );
+ $log_entries = array();
+
+ foreach ( $logger->get_logs( $action_id ) as $log_entry ) {
+ $log_entries[] = array(
+ 'date' => $log_entry->get_date()->format( static::DATE_FORMAT ),
+ 'message' => $log_entry->get_message(),
+ );
+ }
+
+ if ( $only_logs ) {
+ $args = array(
+ 'format' => \WP_CLI\Utils\get_flag_value( $this->assoc_args, 'format', 'table' ),
+ );
+
+ $formatter = new \WP_CLI\Formatter( $args, array( 'date', 'message' ) );
+ $formatter->display_items( $log_entries );
+
+ return;
+ }
+
+ try {
+ $status = $store->get_status( $action_id );
+ } catch ( \Exception $e ) {
+ \WP_CLI::error( $e->getMessage() );
+ }
+
+ $action_arr = array(
+ 'id' => $this->args[0],
+ 'hook' => $action->get_hook(),
+ 'status' => $status,
+ 'args' => $action->get_args(),
+ 'group' => $action->get_group(),
+ 'recurring' => $action->get_schedule()->is_recurring() ? 'yes' : 'no',
+ 'scheduled_date' => $this->get_schedule_display_string( $action->get_schedule() ),
+ 'log_entries' => $log_entries,
+ );
+
+ $fields = array_keys( $action_arr );
+
+ if ( ! empty( $this->assoc_args['fields'] ) ) {
+ $fields = explode( ',', $this->assoc_args['fields'] );
+ }
+
+ $formatter = new \WP_CLI\Formatter( $this->assoc_args, $fields );
+ $formatter->display_item( $action_arr );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/List_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/List_Command.php
new file mode 100644
index 0000000000..4a3e0835f7
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/List_Command.php
@@ -0,0 +1,133 @@
+process_csv_arguments_to_arrays();
+
+ if ( ! empty( $this->assoc_args['fields'] ) ) {
+ $fields = $this->assoc_args['fields'];
+ }
+
+ $formatter = new \WP_CLI\Formatter( $this->assoc_args, $fields );
+ $query_args = $this->assoc_args;
+
+ /**
+ * The `claimed` parameter expects a boolean or integer:
+ * check for string 'false', and set explicitly to `false` boolean.
+ */
+ if ( array_key_exists( 'claimed', $query_args ) && 'false' === strtolower( $query_args['claimed'] ) ) {
+ $query_args['claimed'] = false;
+ }
+
+ $return_format = 'OBJECT';
+
+ if ( in_array( $formatter->format, array( 'ids', 'count' ), true ) ) {
+ $return_format = '\'ids\'';
+ }
+
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
+ $params = var_export( $query_args, true );
+
+ if ( empty( $query_args ) ) {
+ $params = 'array()';
+ }
+
+ \WP_CLI::debug(
+ sprintf(
+ 'as_get_scheduled_actions( %s, %s )',
+ $params,
+ $return_format
+ )
+ );
+
+ if ( ! empty( $query_args['args'] ) ) {
+ $query_args['args'] = json_decode( $query_args['args'], true );
+ }
+
+ switch ( $formatter->format ) {
+
+ case 'ids':
+ $actions = as_get_scheduled_actions( $query_args, 'ids' );
+ echo implode( ' ', $actions );
+ break;
+
+ case 'count':
+ $actions = as_get_scheduled_actions( $query_args, 'ids' );
+ $formatter->display_items( $actions );
+ break;
+
+ default:
+ $actions = as_get_scheduled_actions( $query_args, OBJECT );
+
+ $actions_arr = array();
+
+ foreach ( $actions as $action_id => $action ) {
+ $action_arr = array(
+ 'id' => $action_id,
+ 'hook' => $action->get_hook(),
+ 'status' => $store->get_status( $action_id ),
+ 'args' => $action->get_args(),
+ 'group' => $action->get_group(),
+ 'recurring' => $action->get_schedule()->is_recurring() ? 'yes' : 'no',
+ 'scheduled_date' => $this->get_schedule_display_string( $action->get_schedule() ),
+ 'log_entries' => array(),
+ );
+
+ foreach ( $logger->get_logs( $action_id ) as $log_entry ) {
+ $action_arr['log_entries'][] = array(
+ 'date' => $log_entry->get_date()->format( static::DATE_FORMAT ),
+ 'message' => $log_entry->get_message(),
+ );
+ }
+
+ $actions_arr[] = $action_arr;
+ }
+
+ $formatter->display_items( $actions_arr );
+ break;
+
+ }
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Next_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Next_Command.php
new file mode 100644
index 0000000000..b71744597c
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Next_Command.php
@@ -0,0 +1,71 @@
+args[0];
+ $group = get_flag_value( $this->assoc_args, 'group', '' );
+ $callback_args = get_flag_value( $this->assoc_args, 'args', null );
+ $raw = (bool) get_flag_value( $this->assoc_args, 'raw', false );
+
+ if ( ! empty( $callback_args ) ) {
+ $callback_args = json_decode( $callback_args, true );
+ }
+
+ if ( $raw ) {
+ \WP_CLI::line( as_next_scheduled_action( $hook, $callback_args, $group ) );
+ return;
+ }
+
+ $params = array(
+ 'hook' => $hook,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ 'group' => $group,
+ );
+
+ if ( is_array( $callback_args ) ) {
+ $params['args'] = $callback_args;
+ }
+
+ $params['status'] = \ActionScheduler_Store::STATUS_RUNNING;
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
+ \WP_CLI::debug( 'ActionScheduler()::store()->query_action( ' . var_export( $params, true ) . ' )' );
+
+ $store = \ActionScheduler::store();
+ $action_id = $store->query_action( $params );
+
+ if ( $action_id ) {
+ echo $action_id;
+ return;
+ }
+
+ $params['status'] = \ActionScheduler_Store::STATUS_PENDING;
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export
+ \WP_CLI::debug( 'ActionScheduler()::store()->query_action( ' . var_export( $params, true ) . ' )' );
+
+ $action_id = $store->query_action( $params );
+
+ if ( $action_id ) {
+ echo $action_id;
+ return;
+ }
+
+ \WP_CLI::warning( 'No matching next action.' );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Run_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Run_Command.php
new file mode 100644
index 0000000000..efff37dd9a
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action/Run_Command.php
@@ -0,0 +1,194 @@
+
+ */
+ protected $action_counts = array(
+ 'executed' => 0,
+ 'failed' => 0,
+ 'ignored' => 0,
+ 'invalid' => 0,
+ 'total' => 0,
+ );
+
+ /**
+ * Construct.
+ *
+ * @param string[] $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ */
+ public function __construct( array $args, array $assoc_args ) {
+ parent::__construct( $args, $assoc_args );
+
+ $this->action_ids = array_map( 'absint', $args );
+ $this->action_counts['total'] = count( $this->action_ids );
+
+ add_action( 'action_scheduler_execution_ignored', array( $this, 'on_action_ignored' ) );
+ add_action( 'action_scheduler_after_execute', array( $this, 'on_action_executed' ) );
+ add_action( 'action_scheduler_failed_execution', array( $this, 'on_action_failed' ), 10, 2 );
+ add_action( 'action_scheduler_failed_validation', array( $this, 'on_action_invalid' ), 10, 2 );
+ }
+
+ /**
+ * Execute.
+ *
+ * @return void
+ */
+ public function execute() {
+ $runner = \ActionScheduler::runner();
+
+ $progress_bar = \WP_CLI\Utils\make_progress_bar(
+ sprintf(
+ /* translators: %d: number of actions */
+ _n( 'Executing %d action', 'Executing %d actions', $this->action_counts['total'], 'action-scheduler' ),
+ number_format_i18n( $this->action_counts['total'] )
+ ),
+ $this->action_counts['total']
+ );
+
+ foreach ( $this->action_ids as $action_id ) {
+ $runner->process_action( $action_id, 'Action Scheduler CLI' );
+ $progress_bar->tick();
+ }
+
+ $progress_bar->finish();
+
+ foreach ( array(
+ 'ignored',
+ 'invalid',
+ 'failed',
+ ) as $type ) {
+ $count = $this->action_counts[ $type ];
+
+ if ( empty( $count ) ) {
+ continue;
+ }
+
+ /*
+ * translators:
+ * %1$d: count of actions evaluated.
+ * %2$s: type of action evaluated.
+ */
+ $format = _n( '%1$d action %2$s.', '%1$d actions %2$s.', $count, 'action-scheduler' );
+
+ \WP_CLI::warning(
+ sprintf(
+ $format,
+ number_format_i18n( $count ),
+ $type
+ )
+ );
+ }
+
+ \WP_CLI::success(
+ sprintf(
+ /* translators: %d: number of executed actions */
+ _n( 'Executed %d action.', 'Executed %d actions.', $this->action_counts['executed'], 'action-scheduler' ),
+ number_format_i18n( $this->action_counts['executed'] )
+ )
+ );
+ }
+
+ /**
+ * Action: action_scheduler_execution_ignored
+ *
+ * @param int $action_id Action ID.
+ * @return void
+ */
+ public function on_action_ignored( $action_id ) {
+ if ( 'action_scheduler_execution_ignored' !== current_action() ) {
+ return;
+ }
+
+ $action_id = absint( $action_id );
+
+ if ( ! in_array( $action_id, $this->action_ids, true ) ) {
+ return;
+ }
+
+ $this->action_counts['ignored']++;
+ \WP_CLI::debug( sprintf( 'Action %d was ignored.', $action_id ) );
+ }
+
+ /**
+ * Action: action_scheduler_after_execute
+ *
+ * @param int $action_id Action ID.
+ * @return void
+ */
+ public function on_action_executed( $action_id ) {
+ if ( 'action_scheduler_after_execute' !== current_action() ) {
+ return;
+ }
+
+ $action_id = absint( $action_id );
+
+ if ( ! in_array( $action_id, $this->action_ids, true ) ) {
+ return;
+ }
+
+ $this->action_counts['executed']++;
+ \WP_CLI::debug( sprintf( 'Action %d was executed.', $action_id ) );
+ }
+
+ /**
+ * Action: action_scheduler_failed_execution
+ *
+ * @param int $action_id Action ID.
+ * @param \Exception $e Exception.
+ * @return void
+ */
+ public function on_action_failed( $action_id, \Exception $e ) {
+ if ( 'action_scheduler_failed_execution' !== current_action() ) {
+ return;
+ }
+
+ $action_id = absint( $action_id );
+
+ if ( ! in_array( $action_id, $this->action_ids, true ) ) {
+ return;
+ }
+
+ $this->action_counts['failed']++;
+ \WP_CLI::debug( sprintf( 'Action %d failed execution: %s', $action_id, $e->getMessage() ) );
+ }
+
+ /**
+ * Action: action_scheduler_failed_validation
+ *
+ * @param int $action_id Action ID.
+ * @param \Exception $e Exception.
+ * @return void
+ */
+ public function on_action_invalid( $action_id, \Exception $e ) {
+ if ( 'action_scheduler_failed_validation' !== current_action() ) {
+ return;
+ }
+
+ $action_id = absint( $action_id );
+
+ if ( ! in_array( $action_id, $this->action_ids, true ) ) {
+ return;
+ }
+
+ $this->action_counts['invalid']++;
+ \WP_CLI::debug( sprintf( 'Action %d failed validation: %s', $action_id, $e->getMessage() ) );
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php
index ff6e57aa31..b0ac4e301e 100644
--- a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Clean_Command.php
@@ -41,7 +41,7 @@ public function clean( $args, $assoc_args ) {
$batches_completed = 0;
$actions_deleted = 0;
- $unlimited = $batches === 0;
+ $unlimited = 0 === $batches;
try {
$lifespan = as_get_datetime_object( $before );
} catch ( Exception $e ) {
@@ -58,7 +58,7 @@ public function clean( $args, $assoc_args ) {
sleep( $sleep );
}
- $deleted = count( $cleaner->clean_actions( $status, $lifespan, null,'CLI' ) );
+ $deleted = count( $cleaner->clean_actions( $status, $lifespan, null, 'CLI' ) );
if ( $deleted <= 0 ) {
break;
}
@@ -79,7 +79,7 @@ public function clean( $args, $assoc_args ) {
/**
* 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(
@@ -95,8 +95,6 @@ protected function print_total_batches( int $batches_processed ) {
* Convert an exception into a WP CLI error.
*
* @param Exception $e The error object.
- *
- * @throws \WP_CLI\ExitException
*/
protected function print_error( Exception $e ) {
WP_CLI::error(
@@ -111,7 +109,7 @@ protected function print_error( Exception $e ) {
/**
* 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(
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
index 4681daa492..08cb0cd58d 100644
--- a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_QueueRunner.php
@@ -9,25 +9,37 @@
*/
class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
- /** @var array */
+ /**
+ * Claimed actions.
+ *
+ * @var array
+ */
protected $actions;
- /** @var ActionScheduler_ActionClaim */
+ /**
+ * ActionScheduler_ActionClaim instance.
+ *
+ * @var ActionScheduler_ActionClaim
+ */
protected $claim;
- /** @var \cli\progress\Bar */
+ /**
+ * Progress bar instance.
+ *
+ * @var \cli\progress\Bar
+ */
protected $progress_bar;
/**
* ActionScheduler_WPCLI_QueueRunner constructor.
*
- * @param ActionScheduler_Store $store
- * @param ActionScheduler_FatalErrorMonitor $monitor
- * @param ActionScheduler_QueueCleaner $cleaner
+ * @param ActionScheduler_Store|null $store Store object.
+ * @param ActionScheduler_FatalErrorMonitor|null $monitor Monitor object.
+ * @param ActionScheduler_QueueCleaner|null $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 ) {
+ public function __construct( ?ActionScheduler_Store $store = null, ?ActionScheduler_FatalErrorMonitor $monitor = null, ?ActionScheduler_QueueCleaner $cleaner = null ) {
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
/* translators: %s php class name */
throw new Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), __CLASS__ ) );
@@ -39,8 +51,6 @@ public function __construct( ActionScheduler_Store $store = null, ActionSchedule
/**
* Set up the Queue before processing.
*
- * @author Jeremy Pry
- *
* @param int $batch_size The batch size to process.
* @param array $hooks The hooks being used to filter the actions claimed in this batch.
* @param string $group The group of actions to claim with this batch.
@@ -72,8 +82,6 @@ public function setup( $batch_size, $hooks = array(), $group = '', $force = fals
/**
* Add our hooks to the appropriate actions.
- *
- * @author Jeremy Pry
*/
protected function add_hooks() {
add_action( 'action_scheduler_before_execute', array( $this, 'before_execute' ) );
@@ -83,8 +91,6 @@ protected function add_hooks() {
/**
* Set up the WP CLI progress bar.
- *
- * @author Jeremy Pry
*/
protected function setup_progress_bar() {
$count = count( $this->actions );
@@ -98,8 +104,6 @@ protected function setup_progress_bar() {
/**
* Process actions in the queue.
*
- * @author Jeremy Pry
- *
* @param string $context Optional runner context. Default 'WP CLI'.
*
* @return int The number of actions processed.
@@ -109,7 +113,7 @@ public function run( $context = 'WP CLI' ) {
$this->setup_progress_bar();
foreach ( $this->actions as $action_id ) {
// Error if we lost the claim.
- if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $this->claim->get_id() ) ) ) {
+ if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $this->claim->get_id() ), true ) ) {
WP_CLI::warning( __( 'The claim has been lost. Aborting current batch.', 'action-scheduler' ) );
break;
}
@@ -129,9 +133,7 @@ public function run( $context = 'WP CLI' ) {
/**
* Handle WP CLI message when the action is starting.
*
- * @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 */
@@ -141,13 +143,11 @@ public function before_execute( $action_id ) {
/**
* Handle WP CLI message when the action has completed.
*
- * @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 );
}
@@ -158,10 +158,8 @@ public function after_execute( $action_id, $action = null ) {
/**
* Handle WP CLI message when the action has failed.
*
- * @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 +173,7 @@ public function action_failed( $action_id, $exception ) {
/**
* 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 ) {
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php
index 2c68a3860d..d252680f4f 100644
--- a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php
@@ -91,12 +91,12 @@ public function run( $args, $assoc_args ) {
$batches_completed = 0;
$actions_completed = 0;
- $unlimited = $batches === 0;
- if ( is_callable( [ ActionScheduler::store(), 'set_claim_filter' ] ) ) {
+ $unlimited = 0 === $batches;
+ if ( is_callable( array( ActionScheduler::store(), 'set_claim_filter' ) ) ) {
$exclude_groups = $this->parse_comma_separated_string( $exclude_groups );
if ( ! empty( $exclude_groups ) ) {
- ActionScheduler::store()->set_claim_filter('exclude-groups', $exclude_groups );
+ ActionScheduler::store()->set_claim_filter( 'exclude-groups', $exclude_groups );
}
}
@@ -104,7 +104,7 @@ public function run( $args, $assoc_args ) {
// 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.
@@ -141,9 +141,7 @@ private function parse_comma_separated_string( $string ): array {
/**
* Print WP CLI message about how many actions are about to be processed.
*
- * @author Jeremy Pry
- *
- * @param int $total
+ * @param int $total Number of actions found.
*/
protected function print_total_actions( $total ) {
WP_CLI::log(
@@ -158,9 +156,7 @@ protected function print_total_actions( $total ) {
/**
* Print WP CLI message about how many batches of actions were processed.
*
- * @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(
@@ -175,11 +171,9 @@ protected function print_total_batches( $batches_completed ) {
/**
* Convert an exception into a WP CLI error.
*
- * @author Jeremy Pry
- *
* @param Exception $e The error object.
*
- * @throws \WP_CLI\ExitException
+ * @throws \WP_CLI\ExitException Under some conditions WP CLI may throw an exception.
*/
protected function print_error( Exception $e ) {
WP_CLI::error(
@@ -194,9 +188,7 @@ protected function print_error( Exception $e ) {
/**
* Print a success message with the number of completed actions.
*
- * @author Jeremy Pry
- *
- * @param int $actions_completed
+ * @param int $actions_completed Number of completed actions.
*/
protected function print_success( $actions_completed ) {
WP_CLI::success(
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action_Command.php
new file mode 100644
index 0000000000..b32eea31d7
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Action_Command.php
@@ -0,0 +1,353 @@
+]
+ * : Name of the action hook.
+ *
+ * [--group=]
+ * : The group the job is assigned to.
+ *
+ * [--args=]
+ * : JSON object of arguments assigned to the job.
+ * ---
+ * default: []
+ * ---
+ *
+ * [--all]
+ * : Cancel all occurrences of a scheduled action.
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function cancel( array $args, array $assoc_args ) {
+ require_once 'Action/Cancel_Command.php';
+ $command = new Action\Cancel_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Creates a new scheduled action.
+ *
+ * ## OPTIONS
+ *
+ *
+ * : Name of the action hook.
+ *
+ *
+ * : A unix timestamp representing the date you want the action to start. Also 'async' or 'now' to enqueue an async action.
+ *
+ * [--args=]
+ * : JSON object of arguments to pass to callbacks when the hook triggers.
+ * ---
+ * default: []
+ * ---
+ *
+ * [--cron=]
+ * : A cron-like schedule string (https://crontab.guru/).
+ * ---
+ * default: ''
+ * ---
+ *
+ * [--group=]
+ * : The group to assign this job to.
+ * ---
+ * default: ''
+ * ---
+ *
+ * [--interval=]
+ * : Number of seconds to wait between runs.
+ * ---
+ * default: 0
+ * ---
+ *
+ * ## EXAMPLES
+ *
+ * wp action-scheduler action create hook_async async
+ * wp action-scheduler action create hook_single 1627147598
+ * wp action-scheduler action create hook_recurring 1627148188 --interval=5
+ * wp action-scheduler action create hook_cron 1627147655 --cron='5 4 * * *'
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function create( array $args, array $assoc_args ) {
+ require_once 'Action/Create_Command.php';
+ $command = new Action\Create_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Delete existing scheduled action(s).
+ *
+ * ## OPTIONS
+ *
+ * ...
+ * : One or more IDs of actions to delete.
+ * ---
+ * default: 0
+ * ---
+ *
+ * ## EXAMPLES
+ *
+ * # Delete the action with id 100
+ * $ wp action-scheduler action delete 100
+ *
+ * # Delete the actions with ids 100 and 200
+ * $ wp action-scheduler action delete 100 200
+ *
+ * # Delete the first five pending actions in 'action-scheduler' group
+ * $ wp action-scheduler action delete $( wp action-scheduler action list --status=pending --group=action-scheduler --format=ids )
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function delete( array $args, array $assoc_args ) {
+ require_once 'Action/Delete_Command.php';
+ $command = new Action\Delete_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Generates some scheduled actions.
+ *
+ * ## OPTIONS
+ *
+ *
+ * : Name of the action hook.
+ *
+ *
+ * : The Unix timestamp representing the date you want the action to start.
+ *
+ * [--count=]
+ * : Number of actions to create.
+ * ---
+ * default: 1
+ * ---
+ *
+ * [--interval=]
+ * : Number of seconds to wait between runs.
+ * ---
+ * default: 0
+ * ---
+ *
+ * [--args=]
+ * : JSON object of arguments to pass to callbacks when the hook triggers.
+ * ---
+ * default: []
+ * ---
+ *
+ * [--group=]
+ * : The group to assign this job to.
+ * ---
+ * default: ''
+ * ---
+ *
+ * ## EXAMPLES
+ *
+ * wp action-scheduler action generate test_multiple 1627147598 --count=5 --interval=5
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function generate( array $args, array $assoc_args ) {
+ require_once 'Action/Generate_Command.php';
+ $command = new Action\Generate_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Get details about a scheduled action.
+ *
+ * ## OPTIONS
+ *
+ *
+ * : The ID of the action to get.
+ * ---
+ * default: 0
+ * ---
+ *
+ * [--field=]
+ * : Instead of returning the whole action, returns the value of a single field.
+ *
+ * [--fields=]
+ * : Limit the output to specific fields (comma-separated). Defaults to all fields.
+ *
+ * [--format=]
+ * : Render output in a particular format.
+ * ---
+ * default: table
+ * options:
+ * - table
+ * - csv
+ * - json
+ * - yaml
+ * ---
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function get( array $args, array $assoc_args ) {
+ require_once 'Action/Get_Command.php';
+ $command = new Action\Get_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Get a list of scheduled actions.
+ *
+ * Display actions based on all arguments supported by
+ * [as_get_scheduled_actions()](https://actionscheduler.org/api/#function-reference--as_get_scheduled_actions).
+ *
+ * ## OPTIONS
+ *
+ * [--=]
+ * : One or more arguments to pass to as_get_scheduled_actions().
+ *
+ * [--field=]
+ * : Prints the value of a single property for each action.
+ *
+ * [--fields=]
+ * : Limit the output to specific object properties.
+ *
+ * [--format=]
+ * : Render output in a particular format.
+ * ---
+ * default: table
+ * options:
+ * - table
+ * - csv
+ * - ids
+ * - json
+ * - count
+ * - yaml
+ * ---
+ *
+ * ## AVAILABLE FIELDS
+ *
+ * These fields will be displayed by default for each action:
+ *
+ * * id
+ * * hook
+ * * status
+ * * group
+ * * recurring
+ * * scheduled_date
+ *
+ * These fields are optionally available:
+ *
+ * * args
+ * * log_entries
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ *
+ * @subcommand list
+ */
+ public function subcommand_list( array $args, array $assoc_args ) {
+ require_once 'Action/List_Command.php';
+ $command = new Action\List_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Get logs for a scheduled action.
+ *
+ * ## OPTIONS
+ *
+ *
+ * : The ID of the action to get.
+ * ---
+ * default: 0
+ * ---
+ *
+ * @param array $args Positional arguments.
+ * @return void
+ */
+ public function logs( array $args ) {
+ $command = sprintf( 'action-scheduler action get %d --field=log_entries', $args[0] );
+ WP_CLI::runcommand( $command );
+ }
+
+ /**
+ * Get the ID or timestamp of the next scheduled action.
+ *
+ * ## OPTIONS
+ *
+ *
+ * : The hook of the next scheduled action.
+ *
+ * [--args=]
+ * : JSON object of arguments to search for next scheduled action.
+ * ---
+ * default: []
+ * ---
+ *
+ * [--group=]
+ * : The group to which the next scheduled action is assigned.
+ * ---
+ * default: ''
+ * ---
+ *
+ * [--raw]
+ * : Display the raw output of as_next_scheduled_action() (timestamp or boolean).
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function next( array $args, array $assoc_args ) {
+ require_once 'Action/Next_Command.php';
+ $command = new Action\Next_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+ /**
+ * Run existing scheduled action(s).
+ *
+ * ## OPTIONS
+ *
+ * ...
+ * : One or more IDs of actions to run.
+ * ---
+ * default: 0
+ * ---
+ *
+ * ## EXAMPLES
+ *
+ * # Run the action with id 100
+ * $ wp action-scheduler action run 100
+ *
+ * # Run the actions with ids 100 and 200
+ * $ wp action-scheduler action run 100 200
+ *
+ * # Run the first five pending actions in 'action-scheduler' group
+ * $ wp action-scheduler action run $( wp action-scheduler action list --status=pending --group=action-scheduler --format=ids )
+ *
+ * @param array $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @return void
+ */
+ public function run( array $args, array $assoc_args ) {
+ require_once 'Action/Run_Command.php';
+ $command = new Action\Run_Command( $args, $assoc_args );
+ $command->execute();
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Migration_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Migration_Command.php
index 066697e4e0..86f750fe86 100644
--- a/inc/Dependencies/ActionScheduler/classes/WP_CLI/Migration_Command.php
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/Migration_Command.php
@@ -21,7 +21,11 @@
*/
class Migration_Command extends WP_CLI_Command {
- /** @var int */
+ /**
+ * Number of actions migrated.
+ *
+ * @var int
+ */
private $total_processed = 0;
/**
@@ -32,38 +36,42 @@ public function register() {
return;
}
- WP_CLI::add_command( 'action-scheduler migrate', [ $this, 'migrate' ], [
- 'shortdesc' => 'Migrates actions to the DB tables store',
- 'synopsis' => [
- [
- 'type' => 'assoc',
- 'name' => 'batch-size',
- 'optional' => true,
- 'default' => 100,
- 'description' => 'The number of actions to process in each batch',
- ],
- [
- 'type' => 'assoc',
- 'name' => 'free-memory-on',
- 'optional' => true,
- 'default' => 50,
- 'description' => 'The number of actions to process between freeing memory. 0 disables freeing memory',
- ],
- [
- 'type' => 'assoc',
- 'name' => 'pause',
- 'optional' => true,
- 'default' => 0,
- 'description' => 'The number of seconds to pause when freeing memory',
- ],
- [
- 'type' => 'flag',
- 'name' => 'dry-run',
- 'optional' => true,
- 'description' => 'Reports on the actions that would have been migrated, but does not change any data',
- ],
- ],
- ] );
+ WP_CLI::add_command(
+ 'action-scheduler migrate',
+ array( $this, 'migrate' ),
+ array(
+ 'shortdesc' => 'Migrates actions to the DB tables store',
+ 'synopsis' => array(
+ array(
+ 'type' => 'assoc',
+ 'name' => 'batch-size',
+ 'optional' => true,
+ 'default' => 100,
+ 'description' => 'The number of actions to process in each batch',
+ ),
+ array(
+ 'type' => 'assoc',
+ 'name' => 'free-memory-on',
+ 'optional' => true,
+ 'default' => 50,
+ 'description' => 'The number of actions to process between freeing memory. 0 disables freeing memory',
+ ),
+ array(
+ 'type' => 'assoc',
+ 'name' => 'pause',
+ 'optional' => true,
+ 'default' => 0,
+ 'description' => 'The number of seconds to pause when freeing memory',
+ ),
+ array(
+ 'type' => 'flag',
+ 'name' => 'dry-run',
+ 'optional' => true,
+ 'description' => 'Reports on the actions that would have been migrated, but does not change any data',
+ ),
+ ),
+ )
+ );
}
/**
@@ -81,19 +89,19 @@ public function migrate( $positional_args, $assoc_args ) {
$runner = new Runner( $config );
$runner->init_destination();
- $batch_size = isset( $assoc_args[ 'batch-size' ] ) ? (int) $assoc_args[ 'batch-size' ] : 100;
- $free_on = isset( $assoc_args[ 'free-memory-on' ] ) ? (int) $assoc_args[ 'free-memory-on' ] : 50;
- $sleep = isset( $assoc_args[ 'pause' ] ) ? (int) $assoc_args[ 'pause' ] : 0;
+ $batch_size = isset( $assoc_args['batch-size'] ) ? (int) $assoc_args['batch-size'] : 100;
+ $free_on = isset( $assoc_args['free-memory-on'] ) ? (int) $assoc_args['free-memory-on'] : 50;
+ $sleep = isset( $assoc_args['pause'] ) ? (int) $assoc_args['pause'] : 0;
\ActionScheduler_DataController::set_free_ticks( $free_on );
\ActionScheduler_DataController::set_sleep_time( $sleep );
do {
- $actions_processed = $runner->run( $batch_size );
+ $actions_processed = $runner->run( $batch_size );
$this->total_processed += $actions_processed;
} 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();
}
@@ -109,12 +117,15 @@ public function migrate( $positional_args, $assoc_args ) {
* @return ActionScheduler\Migration\Config
*/
private function get_migration_config( $args ) {
- $args = wp_parse_args( $args, [
- 'dry-run' => false,
- ] );
+ $args = wp_parse_args(
+ $args,
+ array(
+ 'dry-run' => false,
+ )
+ );
$config = Controller::instance()->get_migration_config_object();
- $config->set_dry_run( ! empty( $args[ 'dry-run' ] ) );
+ $config->set_dry_run( ! empty( $args['dry-run'] ) );
return $config;
}
@@ -123,26 +134,57 @@ private function get_migration_config( $args ) {
* Hook command line logging into migration actions.
*/
private function init_logging() {
- add_action( 'action_scheduler/migrate_action_dry_run', function ( $action_id ) {
- WP_CLI::debug( sprintf( 'Dry-run: migrated action %d', $action_id ) );
- }, 10, 1 );
- add_action( 'action_scheduler/no_action_to_migrate', function ( $action_id ) {
- WP_CLI::debug( sprintf( 'No action found to migrate for ID %d', $action_id ) );
- }, 10, 1 );
- add_action( 'action_scheduler/migrate_action_failed', function ( $action_id ) {
- WP_CLI::warning( sprintf( 'Failed migrating action with ID %d', $action_id ) );
- }, 10, 1 );
- add_action( 'action_scheduler/migrate_action_incomplete', function ( $source_id, $destination_id ) {
- WP_CLI::warning( sprintf( 'Unable to remove source action with ID %d after migrating to new ID %d', $source_id, $destination_id ) );
- }, 10, 2 );
- add_action( 'action_scheduler/migrated_action', function ( $source_id, $destination_id ) {
- WP_CLI::debug( sprintf( 'Migrated source action with ID %d to new store with ID %d', $source_id, $destination_id ) );
- }, 10, 2 );
- add_action( 'action_scheduler/migration_batch_starting', function ( $batch ) {
- WP_CLI::debug( 'Beginning migration of batch: ' . print_r( $batch, true ) );
- }, 10, 1 );
- add_action( 'action_scheduler/migration_batch_complete', function ( $batch ) {
- WP_CLI::log( sprintf( 'Completed migration of %d actions', count( $batch ) ) );
- }, 10, 1 );
+ add_action(
+ 'action_scheduler/migrate_action_dry_run',
+ function ( $action_id ) {
+ WP_CLI::debug( sprintf( 'Dry-run: migrated action %d', $action_id ) );
+ }
+ );
+
+ add_action(
+ 'action_scheduler/no_action_to_migrate',
+ function ( $action_id ) {
+ WP_CLI::debug( sprintf( 'No action found to migrate for ID %d', $action_id ) );
+ }
+ );
+
+ add_action(
+ 'action_scheduler/migrate_action_failed',
+ function ( $action_id ) {
+ WP_CLI::warning( sprintf( 'Failed migrating action with ID %d', $action_id ) );
+ }
+ );
+
+ add_action(
+ 'action_scheduler/migrate_action_incomplete',
+ function ( $source_id, $destination_id ) {
+ WP_CLI::warning( sprintf( 'Unable to remove source action with ID %d after migrating to new ID %d', $source_id, $destination_id ) );
+ },
+ 10,
+ 2
+ );
+
+ add_action(
+ 'action_scheduler/migrated_action',
+ function ( $source_id, $destination_id ) {
+ WP_CLI::debug( sprintf( 'Migrated source action with ID %d to new store with ID %d', $source_id, $destination_id ) );
+ },
+ 10,
+ 2
+ );
+
+ add_action(
+ 'action_scheduler/migration_batch_starting',
+ function ( $batch ) {
+ WP_CLI::debug( 'Beginning migration of batch: ' . print_r( $batch, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
+ }
+ );
+
+ add_action(
+ 'action_scheduler/migration_batch_complete',
+ function ( $batch ) {
+ WP_CLI::log( sprintf( 'Completed migration of %d actions', count( $batch ) ) );
+ }
+ );
}
}
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ProgressBar.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ProgressBar.php
index c86c74e838..fb2ae8f586 100644
--- a/inc/Dependencies/ActionScheduler/classes/WP_CLI/ProgressBar.php
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/ProgressBar.php
@@ -17,19 +17,39 @@
*/
class ProgressBar {
- /** @var integer */
+ /**
+ * Current number of ticks.
+ *
+ * @var integer
+ */
protected $total_ticks;
- /** @var integer */
+ /**
+ * Total number of ticks.
+ *
+ * @var integer
+ */
protected $count;
- /** @var integer */
+ /**
+ * Progress bar update interval.
+ *
+ * @var integer
+ */
protected $interval;
- /** @var string */
+ /**
+ * Progress bar message.
+ *
+ * @var string
+ */
protected $message;
- /** @var \cli\progress\Bar */
+ /**
+ * Instance.
+ *
+ * @var \cli\progress\Bar
+ */
protected $progress_bar;
/**
@@ -38,8 +58,8 @@ class ProgressBar {
* @param string $message Text to display before the progress bar.
* @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 ) ) {
@@ -64,7 +84,7 @@ public function tick() {
$this->progress_bar->tick();
$this->total_ticks++;
- do_action( 'action_scheduler/progress_tick', $this->total_ticks );
+ do_action( 'action_scheduler/progress_tick', $this->total_ticks ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/WP_CLI/System_Command.php b/inc/Dependencies/ActionScheduler/classes/WP_CLI/System_Command.php
new file mode 100644
index 0000000000..79f2ae8c66
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/WP_CLI/System_Command.php
@@ -0,0 +1,276 @@
+store = \ActionScheduler::store();
+ }
+
+ /**
+ * Print in-use data store class.
+ *
+ * @param array $args Positional args.
+ * @param array $assoc_args Keyed args.
+ * @return void
+ *
+ * @subcommand data-store
+ */
+ public function datastore( array $args, array $assoc_args ) {
+ echo $this->get_current_datastore();
+ }
+
+ /**
+ * Print in-use runner class.
+ *
+ * @param array $args Positional args.
+ * @param array $assoc_args Keyed args.
+ * @return void
+ */
+ public function runner( array $args, array $assoc_args ) {
+ echo $this->get_current_runner();
+ }
+
+ /**
+ * Get system status.
+ *
+ * @param array $args Positional args.
+ * @param array $assoc_args Keyed args.
+ * @return void
+ */
+ public function status( array $args, array $assoc_args ) {
+ /**
+ * Get runner status.
+ *
+ * @link https://github.com/woocommerce/action-scheduler-disable-default-runner
+ */
+ $runner_enabled = has_action( 'action_scheduler_run_queue', array( \ActionScheduler::runner(), 'run' ) );
+
+ \WP_CLI::line( sprintf( 'Data store: %s', $this->get_current_datastore() ) );
+ \WP_CLI::line( sprintf( 'Runner: %s%s', $this->get_current_runner(), ( $runner_enabled ? '' : ' (disabled)' ) ) );
+ \WP_CLI::line( sprintf( 'Version: %s', $this->get_latest_version() ) );
+
+ $rows = array();
+ $action_counts = $this->store->action_counts();
+ $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $action_counts ) );
+
+ foreach ( $action_counts as $status => $count ) {
+ $rows[] = array(
+ 'status' => $status,
+ 'count' => $count,
+ 'oldest' => $oldest_and_newest[ $status ]['oldest'],
+ 'newest' => $oldest_and_newest[ $status ]['newest'],
+ );
+ }
+
+ $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'status', 'count', 'oldest', 'newest' ) );
+ $formatter->display_items( $rows );
+ }
+
+ /**
+ * Display the active version, or all registered versions.
+ *
+ * ## OPTIONS
+ *
+ * [--all]
+ * : List all registered versions.
+ *
+ * @param array $args Positional args.
+ * @param array $assoc_args Keyed args.
+ * @return void
+ */
+ public function version( array $args, array $assoc_args ) {
+ $all = (bool) get_flag_value( $assoc_args, 'all' );
+ $latest = $this->get_latest_version( $instance );
+
+ if ( ! $all ) {
+ echo $latest;
+ \WP_CLI::halt( 0 );
+ }
+
+ $instance = \ActionScheduler_Versions::instance();
+ $versions = $instance->get_versions();
+ $rows = array();
+
+ foreach ( $versions as $version => $callback ) {
+ $active = $version === $latest;
+
+ $rows[ $version ] = array(
+ 'version' => $version,
+ 'callback' => $callback,
+ 'active' => $active ? 'yes' : 'no',
+ );
+ }
+
+ uksort( $rows, 'version_compare' );
+
+ $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'version', 'callback', 'active' ) );
+ $formatter->display_items( $rows );
+ }
+
+ /**
+ * Display the current source, or all registered sources.
+ *
+ * ## OPTIONS
+ *
+ * [--all]
+ * : List all registered sources.
+ *
+ * [--fullpath]
+ * : List full path of source(s).
+ *
+ * @param array $args Positional args.
+ * @param array $assoc_args Keyed args.
+ * @uses \ActionScheduler_Versions::get_sources()
+ * @uses \WP_CLI\Formatter::display_items()
+ * @uses $this->get_latest_version()
+ * @return void
+ */
+ public function source( array $args, array $assoc_args ) {
+ $all = (bool) get_flag_value( $assoc_args, 'all' );
+ $fullpath = (bool) get_flag_value( $assoc_args, 'fullpath' );
+ $versions = \ActionScheduler_Versions::instance();
+ $source = $versions->active_source_path();
+ $path = $source;
+
+ if ( ! $fullpath ) {
+ $path = str_replace( ABSPATH, '', $path );
+ }
+
+ if ( ! $all ) {
+ echo $path;
+ \WP_CLI::halt( 0 );
+ }
+
+ $sources = $versions->get_sources();
+ $rows = array();
+
+ foreach ( $sources as $check_source => $version ) {
+ $active = dirname( $check_source ) === $source;
+ $path = $check_source;
+
+ if ( ! $fullpath ) {
+ $path = str_replace( ABSPATH, '', $path );
+ }
+
+ $rows[ $check_source ] = array(
+ 'source' => $path,
+ 'version' => $version,
+ 'active' => $active ? 'yes' : 'no',
+ );
+ }
+
+ ksort( $rows );
+
+ \WP_CLI::log( PHP_EOL . 'Please note there can only be one unique registered instance of Action Scheduler per ' . PHP_EOL . 'version number, so this list may not include all the currently present copies of ' . PHP_EOL . 'Action Scheduler.' . PHP_EOL );
+
+ $formatter = new \WP_CLI\Formatter( $assoc_args, array( 'source', 'version', 'active' ) );
+ $formatter->display_items( $rows );
+ }
+
+ /**
+ * Get current data store.
+ *
+ * @return string
+ */
+ protected function get_current_datastore() {
+ return get_class( $this->store );
+ }
+
+ /**
+ * Get latest version.
+ *
+ * @param null|\ActionScheduler_Versions $instance Versions.
+ * @return string
+ */
+ protected function get_latest_version( $instance = null ) {
+ if ( is_null( $instance ) ) {
+ $instance = \ActionScheduler_Versions::instance();
+ }
+
+ return $instance->latest_version();
+ }
+
+ /**
+ * Get current runner.
+ *
+ * @return string
+ */
+ protected function get_current_runner() {
+ return get_class( \ActionScheduler::runner() );
+ }
+
+ /**
+ * Get oldest and newest scheduled dates for a given set of statuses.
+ *
+ * @param array $status_keys Set of statuses to find oldest & newest action for.
+ * @return array
+ */
+ protected function get_oldest_and_newest( $status_keys ) {
+ $oldest_and_newest = array();
+
+ foreach ( $status_keys as $status ) {
+ $oldest_and_newest[ $status ] = array(
+ 'oldest' => '–',
+ 'newest' => '–',
+ );
+
+ if ( 'in-progress' === $status ) {
+ continue;
+ }
+
+ $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' );
+ $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' );
+ }
+
+ return $oldest_and_newest;
+ }
+
+ /**
+ * Get oldest or newest scheduled date for a given status.
+ *
+ * @param string $status Action status label/name string.
+ * @param string $date_type Oldest or Newest.
+ * @return string
+ */
+ protected function get_action_status_date( $status, $date_type = 'oldest' ) {
+ $order = 'oldest' === $date_type ? 'ASC' : 'DESC';
+
+ $args = array(
+ 'claimed' => false,
+ 'status' => $status,
+ 'per_page' => 1,
+ 'order' => $order,
+ );
+
+ $action = $this->store->query_actions( $args );
+
+ if ( ! empty( $action ) ) {
+ $date_object = $this->store->get_date( $action[0] );
+ $action_date = $date_object->format( 'Y-m-d H:i:s O' );
+ } else {
+ $action_date = '–';
+ }
+
+ return $action_date;
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler.php
index 0163f7072d..774abb1851 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler.php
@@ -5,67 +5,109 @@
/**
* Class ActionScheduler
+ *
* @codeCoverageIgnore
*/
abstract class ActionScheduler {
+
+ /**
+ * Plugin file path.
+ *
+ * @var string
+ */
private static $plugin_file = '';
- /** @var ActionScheduler_ActionFactory */
- private static $factory = NULL;
- /** @var bool */
+
+ /**
+ * ActionScheduler_ActionFactory instance.
+ *
+ * @var ActionScheduler_ActionFactory
+ */
+ private static $factory = null;
+
+ /**
+ * Data store is initialized.
+ *
+ * @var bool
+ */
private static $data_store_initialized = false;
+ /**
+ * Factory.
+ */
public static function factory() {
- if ( !isset(self::$factory) ) {
+ if ( ! isset( self::$factory ) ) {
self::$factory = new ActionScheduler_ActionFactory();
}
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();
}
/**
* 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);
+ $base = dirname( self::$plugin_file );
if ( $path ) {
- return trailingslashit($base).$path;
+ return trailingslashit( $base ) . $path;
} else {
- return untrailingslashit($base);
+ return untrailingslashit( $base );
}
}
/**
* 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);
+ 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 );
@@ -91,7 +133,7 @@ public static function autoload( $class ) {
$dir = $classes_dir . 'schema' . $d;
} elseif ( strpos( $class, 'ActionScheduler' ) === 0 ) {
$segments = explode( '_', $class );
- $type = isset( $segments[ 1 ] ) ? $segments[ 1 ] : '';
+ $type = isset( $segments[1] ) ? $segments[1] : '';
switch ( $type ) {
case 'WPCLI':
@@ -119,7 +161,7 @@ public static function autoload( $class ) {
}
if ( file_exists( $dir . "{$class}.php" ) ) {
- include( $dir . "{$class}.php" );
+ include $dir . "{$class}.php";
return;
}
}
@@ -128,7 +170,7 @@ public static function autoload( $class ) {
* 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;
@@ -139,7 +181,7 @@ public static function init( $plugin_file ) {
*/
do_action( 'action_scheduler_pre_init' );
- require_once( self::plugin_path( 'functions.php' ) );
+ require_once self::plugin_path( 'functions.php' );
ActionScheduler_DataController::init();
$store = self::store();
@@ -149,7 +191,8 @@ public static function init( $plugin_file ) {
// 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 );
@@ -191,12 +234,14 @@ function () {
}
if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) {
- require_once( self::plugin_path( 'deprecated/functions.php' ) );
+ require_once self::plugin_path( 'deprecated/functions.php' );
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'action-scheduler', 'ActionScheduler_WPCLI_Scheduler_command' );
WP_CLI::add_command( 'action-scheduler', 'ActionScheduler_WPCLI_Clean_Command' );
+ WP_CLI::add_command( 'action-scheduler action', '\Action_Scheduler\WP_CLI\Action_Command' );
+ WP_CLI::add_command( 'action-scheduler', '\Action_Scheduler\WP_CLI\System_Command' );
if ( ! ActionScheduler_DataController::is_migration_complete() && Controller::instance()->allow_migration() ) {
$command = new Migration_Command();
$command->register();
@@ -226,7 +271,7 @@ public static function is_initialized( $function_name = null ) {
__( '%s() was called before the Action Scheduler data store was initialized', 'action-scheduler' ),
esc_attr( $function_name )
);
- _doing_it_wrong( $function_name, $message, '3.1.6' );
+ _doing_it_wrong( esc_html( $function_name ), esc_html( $message ), '3.1.6' );
}
return self::$data_store_initialized;
@@ -253,6 +298,7 @@ protected static function is_class_abstract( $class ) {
'ActionScheduler_Abstract_Schema' => true,
'ActionScheduler_Store' => true,
'ActionScheduler_TimezoneHelper' => true,
+ 'ActionScheduler_WPCLI_Command' => true,
);
return isset( $abstracts[ $class ] ) && $abstracts[ $class ];
@@ -281,7 +327,7 @@ protected static function is_class_migration( $class ) {
);
$segments = explode( '_', $class );
- $segment = isset( $segments[ 1 ] ) ? $segments[ 1 ] : $class;
+ $segment = isset( $segments[1] ) ? $segments[1] : $class;
return isset( $migration_segments[ $segment ] ) && $migration_segments[ $segment ];
}
@@ -297,29 +343,46 @@ protected static function is_class_migration( $class ) {
*/
protected static function is_class_cli( $class ) {
static $cli_segments = array(
- 'QueueRunner' => true,
- 'Command' => true,
- 'ProgressBar' => true,
+ 'QueueRunner' => true,
+ 'Command' => true,
+ 'ProgressBar' => true,
+ '\Action_Scheduler\WP_CLI\Action_Command' => true,
+ '\Action_Scheduler\WP_CLI\System_Command' => true,
);
$segments = explode( '_', $class );
- $segment = isset( $segments[ 1 ] ) ? $segments[ 1 ] : $class;
+ $segment = isset( $segments[1] ) ? $segments[1] : $class;
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 ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
}
+ /**
+ * Wakeup.
+ */
final public function __wakeup() {
- trigger_error("Singleton. No serialization allowed!", E_USER_ERROR);
+ trigger_error( 'Singleton. No serialization allowed!', E_USER_ERROR ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_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 );
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
index 371917e3ca..1b51c30129 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
@@ -5,13 +5,25 @@
*/
abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abstract_QueueRunner_Deprecated {
- /** @var ActionScheduler_QueueCleaner */
+ /**
+ * ActionScheduler_QueueCleaner instance.
+ *
+ * @var ActionScheduler_QueueCleaner
+ */
protected $cleaner;
- /** @var ActionScheduler_FatalErrorMonitor */
+ /**
+ * ActionScheduler_FatalErrorMonitor instance.
+ *
+ * @var ActionScheduler_FatalErrorMonitor
+ */
protected $monitor;
- /** @var ActionScheduler_Store */
+ /**
+ * ActionScheduler_Store instance.
+ *
+ * @var ActionScheduler_Store
+ */
protected $store;
/**
@@ -27,11 +39,11 @@ 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|null $store Store object.
+ * @param ActionScheduler_FatalErrorMonitor|null $monitor Monitor object.
+ * @param ActionScheduler_QueueCleaner|null $cleaner Cleaner object.
*/
- public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null ) {
+ public function __construct( ?ActionScheduler_Store $store = null, ?ActionScheduler_FatalErrorMonitor $monitor = null, ?ActionScheduler_QueueCleaner $cleaner = null ) {
$this->created_time = microtime( true );
@@ -43,12 +55,14 @@ public function __construct( ActionScheduler_Store $store = null, ActionSchedule
/**
* 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.
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
set_error_handler(
/**
* Temporary error handler which can catch errors and convert them into exceptions. This facilitates more
@@ -141,8 +155,8 @@ private function handle_action_error( $action_id, $e, $context, $valid_action )
/**
* 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.
@@ -192,7 +206,7 @@ private function recurring_action_is_consistently_failing( ActionScheduler_Actio
'date' => date_create( 'now', timezone_open( 'UTC' ) )->format( 'Y-m-d H:i:s' ),
'date_compare' => '<',
'per_page' => 1,
- 'offset' => $consistent_failure_threshold - 1
+ 'offset' => $consistent_failure_threshold - 1,
);
$first_failing_action_id = $this->store->query_actions( $query_args );
@@ -222,8 +236,6 @@ private function recurring_action_is_consistently_failing( ActionScheduler_Actio
/**
* Run the queue cleaner.
- *
- * @author Jeremy Pry
*/
protected function run_cleanup() {
$this->cleaner->clean( 10 * $this->get_time_limit() );
@@ -256,7 +268,7 @@ protected function get_time_limit() {
$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 +300,7 @@ protected function get_execution_time() {
/**
* 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 +330,7 @@ protected function get_memory_limit() {
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 +365,7 @@ protected function memory_exceeded() {
*
* 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 ) {
@@ -363,7 +375,6 @@ protected function batch_limits_exceeded( $processed_actions ) {
/**
* Process actions in the queue.
*
- * @author Jeremy Pry
* @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.
* @return int The number of actions processed.
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
index 0ed8bc8e50..60d09e917e 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_RecurringSchedule.php
@@ -15,14 +15,14 @@ abstract class ActionScheduler_Abstract_RecurringSchedule extends ActionSchedule
*
* @var DateTime
*/
- private $first_date = NULL;
+ private $first_date = null;
/**
* Timestamp equivalent of @see $this->first_date
*
* @var int
*/
- protected $first_timestamp = NULL;
+ protected $first_timestamp = null;
/**
* The recurrence between each time an action is run using this schedule.
@@ -35,17 +35,21 @@ 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.
+ * Construct.
+ *
+ * @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 ) {
+ public function __construct( DateTime $date, $recurrence, ?DateTime $first = null ) {
parent::__construct( $date );
$this->first_date = empty( $first ) ? $date : $first;
$this->recurrence = $recurrence;
}
/**
+ * Schedule is recurring.
+ *
* @return bool
*/
public function is_recurring() {
@@ -62,6 +66,8 @@ public function get_first_date() {
}
/**
+ * Get the schedule's recurrence.
+ *
* @return string
*/
public function get_recurrence() {
@@ -70,15 +76,19 @@ public function get_recurrence() {
/**
* For PHP 5.2 compat, since DateTime objects can't be serialized
+ *
* @return array
*/
public function __sleep() {
- $sleep_params = parent::__sleep();
+ $sleep_params = parent::__sleep();
$this->first_timestamp = $this->first_date->getTimestamp();
- return array_merge( $sleep_params, array(
- 'first_timestamp',
- 'recurrence'
- ) );
+ return array_merge(
+ $sleep_params,
+ array(
+ 'first_timestamp',
+ 'recurrence',
+ )
+ );
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
index 2631ef554f..b7826b41ab 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schedule.php
@@ -10,16 +10,18 @@ abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedul
*
* @var DateTime
*/
- private $scheduled_date = NULL;
+ private $scheduled_date = null;
/**
* Timestamp equivalent of @see $this->scheduled_date
*
* @var int
*/
- protected $scheduled_timestamp = NULL;
+ protected $scheduled_timestamp = null;
/**
+ * Construct.
+ *
* @param DateTime $date The date & time to run the action.
*/
public function __construct( DateTime $date ) {
@@ -36,7 +38,7 @@ abstract public function is_recurring();
/**
* 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 +46,7 @@ abstract protected function calculate_next( DateTime $after );
/**
* 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 ) {
@@ -66,7 +68,8 @@ public function get_date() {
}
/**
- * For PHP 5.2 compat, since DateTime objects can't be serialized
+ * For PHP 5.2 compat, because DateTime objects can't be serialized
+ *
* @return array
*/
public function __sleep() {
@@ -76,6 +79,9 @@ public function __sleep() {
);
}
+ /**
+ * Wakeup.
+ */
public function __wakeup() {
$this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp );
unset( $this->scheduled_timestamp );
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
index 3fd259ea71..69817fe75d 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php
@@ -13,17 +13,23 @@
abstract class ActionScheduler_Abstract_Schema {
/**
- * @var int Increment this value in derived class to trigger a schema update.
+ * Increment this value in derived class to trigger a schema update.
+ *
+ * @var int
*/
protected $schema_version = 1;
/**
- * @var string Schema version stored in database.
+ * Schema version stored in database.
+ *
+ * @var string
*/
protected $db_version;
/**
- * @var array Names of tables that will be registered by this class.
+ * Names of tables that will be registered by this class.
+ *
+ * @var array
*/
protected $tables = array();
@@ -43,14 +49,14 @@ public function init() {}
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 +73,9 @@ public function register_tables( $force_update = false ) {
}
/**
- * @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 +92,7 @@ private function schema_update_required() {
$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 +123,7 @@ private function schema_update_required() {
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 +132,7 @@ private function mark_schema_update_complete() {
/**
* 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
*/
@@ -135,14 +143,16 @@ private function update_table( $table ) {
$updated = dbDelta( $definition );
foreach ( $updated as $updated_table => $update_description ) {
if ( strpos( $update_description, 'Created table' ) === 0 ) {
- do_action( 'action_scheduler/created_table', $updated_table, $table );
+ do_action( 'action_scheduler/created_table', $updated_table, $table ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
}
}
}
/**
- * @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
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Lock.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Lock.php
index e388a58faf..7280207737 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Lock.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Lock.php
@@ -7,10 +7,18 @@
*/
abstract class ActionScheduler_Lock {
- /** @var ActionScheduler_Lock */
- private static $locker = NULL;
+ /**
+ * Instance.
+ *
+ * @var ActionScheduler_Lock
+ */
+ private static $locker = null;
- /** @var int */
+ /**
+ * Duration of lock.
+ *
+ * @var int
+ */
protected static $lock_duration = MINUTE_IN_SECONDS;
/**
@@ -52,11 +60,13 @@ protected function get_duration( $lock_type ) {
}
/**
+ * Get instance.
+ *
* @return ActionScheduler_Lock
*/
public static function instance() {
if ( empty( self::$locker ) ) {
- $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' );
+ $class = apply_filters( 'action_scheduler_lock_class', 'ActionScheduler_OptionLock' );
self::$locker = new $class();
}
return self::$locker;
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Logger.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Logger.php
index 0627251cbb..94ee2a93af 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Logger.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Logger.php
@@ -2,40 +2,55 @@
/**
* Class ActionScheduler_Logger
+ *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Logger {
- private static $logger = NULL;
/**
+ * Instance.
+ *
+ * @var null|self
+ */
+ private static $logger = null;
+
+ /**
+ * Get instance.
+ *
* @return ActionScheduler_Logger
*/
public static function instance() {
- if ( empty(self::$logger) ) {
- $class = apply_filters('action_scheduler_logger_class', 'ActionScheduler_wpCommentLogger');
+ if ( empty( self::$logger ) ) {
+ $class = apply_filters( 'action_scheduler_logger_class', 'ActionScheduler_wpCommentLogger' );
self::$logger = new $class();
}
return self::$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|null $date Log date.
*
* @return string The log entry ID
*/
- abstract public function log( $action_id, $message, DateTime $date = NULL );
+ 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 +58,8 @@ abstract public function get_logs( $action_id );
/**
+ * Initialize.
+ *
* @codeCoverageIgnore
*/
public function init() {
@@ -60,22 +77,44 @@ public function init() {
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', 'action-scheduler' ) );
}
+ /**
+ * Log action cancellation.
+ *
+ * @param int $action_id Action ID.
+ */
public function log_canceled_action( $action_id ) {
$this->log( $action_id, __( 'action canceled', 'action-scheduler' ) );
}
+ /**
+ * 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,7 +125,14 @@ public function log_started_action( $action_id, $context = '' ) {
$this->log( $action_id, $message );
}
- public function log_completed_action( $action_id, $action = NULL, $context = '' ) {
+ /**
+ * Log action completion.
+ *
+ * @param int $action_id Action ID.
+ * @param null|ActionScheduler_Action $action Action.
+ * @param string $context Action execution context.
+ */
+ public function log_completed_action( $action_id, $action = null, $context = '' ) {
if ( ! empty( $context ) ) {
/* translators: %s: context */
$message = sprintf( __( 'action complete via %s', 'action-scheduler' ), $context );
@@ -96,6 +142,13 @@ public function log_completed_action( $action_id, $action = NULL, $context = ''
$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 +160,23 @@ public function log_failed_action( $action_id, Exception $exception, $context =
$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.', 'action-scheduler' ), $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 +184,21 @@ public function log_unexpected_shutdown( $action_id, $error ) {
}
}
+ /**
+ * Log action reset.
+ *
+ * @param int $action_id Action ID.
+ */
public function log_reset_action( $action_id ) {
$this->log( $action_id, __( 'action reset', 'action-scheduler' ) );
}
+ /**
+ * 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,12 +210,12 @@ public function log_ignored_action( $action_id, $context = '' ) {
}
/**
- * @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 ) {
+ public function log_failed_fetch_action( $action_id, ?Exception $exception = null ) {
if ( ! is_null( $exception ) ) {
/* translators: %s: exception message */
@@ -151,6 +227,12 @@ public function log_failed_fetch_action( $action_id, Exception $exception = NULL
$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', 'action-scheduler' ), $exception->getMessage() ) );
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Store.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Store.php
index 421f5a6716..bf6bc42946 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Store.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_Store.php
@@ -2,6 +2,7 @@
/**
* Class ActionScheduler_Store
+ *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
@@ -12,24 +13,36 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
const STATUS_CANCELED = 'canceled';
const DEFAULT_CLASS = 'ActionScheduler_wpPostStore';
- /** @var ActionScheduler_Store */
- private static $store = NULL;
+ /**
+ * ActionScheduler_Store instance.
+ *
+ * @var ActionScheduler_Store
+ */
+ private static $store = null;
- /** @var int */
+ /**
+ * Maximum length of args.
+ *
+ * @var int
+ */
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.
+ * Save action.
+ *
+ * @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 );
+ 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,10 +154,13 @@ abstract public function action_counts();
public function extra_action_counts() {
$extra_actions = array();
- $pastdue_action_counts = ( int ) $this->query_actions( array(
- 'status' => self::STATUS_PENDING,
- 'date' => as_get_datetime_object(),
- ), 'count' );
+ $pastdue_action_counts = (int) $this->query_actions(
+ array(
+ 'status' => self::STATUS_PENDING,
+ 'date' => as_get_datetime_object(),
+ ),
+ 'count'
+ );
if ( $pastdue_action_counts ) {
$extra_actions['past-due'] = $pastdue_action_counts;
@@ -160,17 +176,23 @@ public function extra_action_counts() {
}
/**
- * @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,87 +200,111 @@ abstract public function get_date( $action_id );
/**
- * @param int $max_actions
- * @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.
+ * Make a claim.
+ *
+ * @param int $max_actions Maximum number of actions to claim.
+ * @param DateTime|null $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.
*
* @return ActionScheduler_ActionClaim
*/
- abstract public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' );
+ 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 ) {
- if ( in_array( $comparison_operator, array('!=', '>', '>=', '<', '<=', '=') ) ) {
+ if ( in_array( $comparison_operator, array( '!=', '>', '>=', '<', '<=', '=' ), true ) ) {
return $comparison_operator;
}
+
return '=';
}
/**
* 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 ) {
- $next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
+ protected function get_scheduled_date_string( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ $next = is_null( $scheduled_date ) ? $action->get_schedule()->get_date() : $scheduled_date;
+
if ( ! $next ) {
$next = date_create();
}
+
$next->setTimezone( new DateTimeZone( 'UTC' ) );
return $next->format( 'Y-m-d H:i:s' );
@@ -267,12 +313,13 @@ protected function get_scheduled_date_string( ActionScheduler_Action $action, Da
/**
* 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|null $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 ) {
- $next = null === $scheduled_date ? $action->get_schedule()->get_date() : $scheduled_date;
+ protected function get_scheduled_date_string_local( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
+ $next = is_null( $scheduled_date ) ? $action->get_schedule()->get_date() : $scheduled_date;
+
if ( ! $next ) {
$next = date_create();
}
@@ -386,7 +433,7 @@ public function cancel_actions_by_group( $group ) {
*
* @since 3.0.0
*
- * @param array $action_ids List of action IDs.
+ * @param int[] $action_ids List of action IDs.
*
* @return void
*/
@@ -399,7 +446,9 @@ private function bulk_cancel_actions( $action_ids ) {
}
/**
- * @return array
+ * Get status labels.
+ *
+ * @return array
*/
public function get_status_labels() {
return array(
@@ -414,16 +463,18 @@ public function get_status_labels() {
/**
* 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,
- 'orderby' => 'none',
- ) );
+ $pending_actions = $this->query_actions(
+ array(
+ 'per_page' => 1,
+ 'date' => as_get_datetime_object(),
+ 'status' => self::STATUS_PENDING,
+ 'orderby' => 'none',
+ ),
+ 'count'
+ );
return ! empty( $pending_actions );
}
@@ -435,15 +486,19 @@ public function init() {}
/**
* 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 ) {}
/**
+ * Get instance.
+ *
* @return ActionScheduler_Store
*/
public static function instance() {
if ( empty( self::$store ) ) {
- $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS );
+ $class = apply_filters( 'action_scheduler_store_class', self::DEFAULT_CLASS );
self::$store = new $class();
}
return self::$store;
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
index 36529181dc..63813eba46 100644
--- a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_TimezoneHelper.php
@@ -4,7 +4,13 @@
* Class ActionScheduler_TimezoneHelper
*/
abstract class ActionScheduler_TimezoneHelper {
- private static $local_timezone = NULL;
+
+ /**
+ * DateTimeZone object.
+ *
+ * @var null|DateTimeZone
+ */
+ private static $local_timezone = null;
/**
* Set a DateTime's timezone to the WordPress site's timezone, or a UTC offset
@@ -12,12 +18,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 +48,7 @@ public static function set_local_timezone( DateTime $date ) {
* 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 +82,7 @@ protected static function get_local_timezone_string( $reset = false ) {
}
}
- // No timezone string
+ // No timezone string.
return '';
}
@@ -97,23 +104,26 @@ protected static function get_local_timezone_offset() {
}
/**
+ * Get local timezone.
+ *
+ * @param bool $reset Toggle to discard stored value.
* @deprecated 2.1.0
*/
- public static function get_local_timezone( $reset = FALSE ) {
+ public static function get_local_timezone( $reset = false ) {
_deprecated_function( __FUNCTION__, '2.1.0', 'ActionScheduler_TimezoneHelper::set_local_timezone()' );
if ( $reset ) {
- self::$local_timezone = NULL;
+ self::$local_timezone = null;
}
- if ( !isset(self::$local_timezone) ) {
- $tzstring = get_option('timezone_string');
+ if ( ! isset( self::$local_timezone ) ) {
+ $tzstring = get_option( 'timezone_string' );
- if ( empty($tzstring) ) {
- $gmt_offset = get_option('gmt_offset');
- if ( $gmt_offset == 0 ) {
+ if ( empty( $tzstring ) ) {
+ $gmt_offset = absint( get_option( 'gmt_offset' ) );
+ if ( 0 === $gmt_offset ) {
$tzstring = 'UTC';
} else {
$gmt_offset *= HOUR_IN_SECONDS;
- $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
+ $tzstring = timezone_name_from_abbr( '', $gmt_offset, 1 );
// If there's no timezone string, try again with no DST.
if ( false === $tzstring ) {
@@ -125,9 +135,9 @@ public static function get_local_timezone( $reset = FALSE ) {
$is_dst = date( 'I' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- we are actually interested in the runtime timezone.
foreach ( timezone_abbreviations_list() as $abbr ) {
foreach ( $abbr as $city ) {
- if ( $city['dst'] == $is_dst && $city['offset'] == $gmt_offset ) {
+ if ( $city['dst'] === $is_dst && $city['offset'] === $gmt_offset ) {
// If there's no valid timezone ID, keep looking.
- if ( null === $city['timezone_id'] ) {
+ if ( is_null( $city['timezone_id'] ) ) {
continue;
}
@@ -145,7 +155,7 @@ public static function get_local_timezone( $reset = FALSE ) {
}
}
- self::$local_timezone = new DateTimeZone($tzstring);
+ self::$local_timezone = new DateTimeZone( $tzstring );
}
return self::$local_timezone;
}
diff --git a/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php
new file mode 100644
index 0000000000..847c109ee6
--- /dev/null
+++ b/inc/Dependencies/ActionScheduler/classes/abstracts/ActionScheduler_WPCLI_Command.php
@@ -0,0 +1,83 @@
+
+ */
+ protected $assoc_args;
+
+ /**
+ * Construct.
+ *
+ * @param string[] $args Positional arguments.
+ * @param array $assoc_args Keyed arguments.
+ * @throws \Exception When loading a CLI command file outside of WP CLI context.
+ */
+ public function __construct( array $args, array $assoc_args ) {
+ if ( ! defined( 'WP_CLI' ) || ! constant( 'WP_CLI' ) ) {
+ /* translators: %s php class name */
+ throw new \Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), get_class( $this ) ) );
+ }
+
+ $this->args = $args;
+ $this->assoc_args = $assoc_args;
+ }
+
+ /**
+ * Execute command.
+ */
+ abstract public function execute();
+
+ /**
+ * Get the scheduled date in a human friendly format.
+ *
+ * @see ActionScheduler_ListTable::get_schedule_display_string()
+ * @param ActionScheduler_Schedule $schedule Schedule.
+ * @return string
+ */
+ protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
+
+ $schedule_display_string = '';
+
+ if ( ! $schedule->get_date() ) {
+ return '0000-00-00 00:00:00';
+ }
+
+ $next_timestamp = $schedule->get_date()->getTimestamp();
+
+ $schedule_display_string .= $schedule->get_date()->format( static::DATE_FORMAT );
+
+ return $schedule_display_string;
+ }
+
+ /**
+ * Transforms arguments with '__' from CSV into expected arrays.
+ *
+ * @see \WP_CLI\CommandWithDBObject::process_csv_arguments_to_arrays()
+ * @link https://github.com/wp-cli/entity-command/blob/c270cc9a2367cb8f5845f26a6b5e203397c91392/src/WP_CLI/CommandWithDBObject.php#L99
+ * @return void
+ */
+ protected function process_csv_arguments_to_arrays() {
+ foreach ( $this->assoc_args as $k => $v ) {
+ if ( false !== strpos( $k, '__' ) ) {
+ $this->assoc_args[ $k ] = explode( ',', $v );
+ }
+ }
+ }
+
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_Action.php b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_Action.php
index ddf33d5d99..1613efa197 100644
--- a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_Action.php
+++ b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_Action.php
@@ -4,10 +4,32 @@
* Class ActionScheduler_Action
*/
class ActionScheduler_Action {
+ /**
+ * Action's hook.
+ *
+ * @var string
+ */
protected $hook = '';
+
+ /**
+ * Action's args.
+ *
+ * @var array
+ */
protected $args = array();
- /** @var ActionScheduler_Schedule */
- protected $schedule = NULL;
+
+ /**
+ * Action's schedule.
+ *
+ * @var ActionScheduler_Schedule
+ */
+ protected $schedule = null;
+
+ /**
+ * Action's group.
+ *
+ * @var string
+ */
protected $group = '';
/**
@@ -23,12 +45,20 @@ class ActionScheduler_Action {
*/
protected $priority = 10;
- public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = NULL, $group = '' ) {
+ /**
+ * 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);
- $this->set_schedule($schedule);
- $this->set_args($args);
- $this->set_group($group);
+ $this->set_hook( $hook );
+ $this->set_schedule( $schedule );
+ $this->set_args( $args );
+ $this->set_group( $group );
}
/**
@@ -57,43 +87,67 @@ public function execute() {
}
/**
- * @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;
}
/**
+ * Action's schedule.
+ *
* @return ActionScheduler_Schedule
*/
public function get_schedule() {
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;
}
/**
+ * Action's group.
+ *
* @return string
*/
public function get_group() {
@@ -101,10 +155,12 @@ public function get_group() {
}
/**
- * @return bool If the action has been finished
+ * Action has not finished.
+ *
+ * @return bool
*/
public function is_finished() {
- return FALSE;
+ return false;
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_CanceledAction.php b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_CanceledAction.php
index 8bbc5d18d5..c60075287f 100644
--- a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_CanceledAction.php
+++ b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_CanceledAction.php
@@ -9,12 +9,14 @@
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 = '' ) {
+ public function __construct( $hook, array $args = array(), ?ActionScheduler_Schedule $schedule = null, $group = '' ) {
parent::__construct( $hook, $args, $schedule, $group );
if ( is_null( $schedule ) ) {
$this->set_schedule( new ActionScheduler_NullSchedule() );
diff --git a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_FinishedAction.php b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_FinishedAction.php
index b23a56c66b..d4e894210a 100644
--- a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_FinishedAction.php
+++ b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_FinishedAction.php
@@ -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;
+ return true;
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_NullAction.php b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_NullAction.php
index cd5dc3b0f9..2cfaea61fd 100644
--- a/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_NullAction.php
+++ b/inc/Dependencies/ActionScheduler/classes/actions/ActionScheduler_NullAction.php
@@ -5,12 +5,21 @@
*/
class ActionScheduler_NullAction extends ActionScheduler_Action {
- public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = NULL ) {
+ /**
+ * 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.
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBLogger.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBLogger.php
index d285c8d270..0976b066c8 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBLogger.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBLogger.php
@@ -12,13 +12,13 @@ class ActionScheduler_DBLogger extends ActionScheduler_Logger {
/**
* Add a record to an action log.
*
- * @param int $action_id Action ID.
- * @param string $message Message to be saved in the log entry.
- * @param DateTime $date Timestamp of the log entry.
+ * @param int $action_id Action ID.
+ * @param string $message Message to be saved in the log entry.
+ * @param DateTime|null $date Timestamp of the log entry.
*
* @return int The log entry ID.
*/
- public function log( $action_id, $message, DateTime $date = null ) {
+ public function log( $action_id, $message, ?DateTime $date = null ) {
if ( empty( $date ) ) {
$date = as_get_datetime_object();
} else {
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBStore.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBStore.php
index e19711ebd6..25a883abdf 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBStore.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_DBStore.php
@@ -19,18 +19,30 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
*/
private $claim_before_date = null;
- /** @var int */
+ /**
+ * Maximum length of args.
+ *
+ * @var int
+ */
protected static $max_args_length = 8000;
- /** @var int */
+ /**
+ * Maximum length of index.
+ *
+ * @var int
+ */
protected static $max_index_length = 191;
- /** @var array List of claim filters. */
- protected $claim_filters = [
+ /**
+ * List of claim filters.
+ *
+ * @var array
+ */
+ protected $claim_filters = array(
'group' => '',
'hooks' => '',
'exclude-groups' => '',
- ];
+ );
/**
* Initialize the data store
@@ -47,12 +59,12 @@ public function init() {
* Save an action, checks if this is a unique action before actually saving.
*
* @param ActionScheduler_Action $action Action object.
- * @param \DateTime $scheduled_date Optional schedule date. Default null.
+ * @param DateTime|null $scheduled_date Optional schedule date. Default null.
*
* @return int Action ID.
* @throws RuntimeException Throws exception when saving the action fails.
*/
- public function save_unique_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null ) {
+ public function save_unique_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
return $this->save_action_to_db( $action, $scheduled_date, true );
}
@@ -60,12 +72,12 @@ public function save_unique_action( ActionScheduler_Action $action, \DateTime $s
* Save an action. Can save duplicate action as well, prefer using `save_unique_action` instead.
*
* @param ActionScheduler_Action $action Action object.
- * @param \DateTime $scheduled_date Optional schedule date. Default null.
+ * @param DateTime|null $scheduled_date Optional schedule date. Default null.
*
* @return int Action ID.
* @throws RuntimeException Throws exception when saving the action fails.
*/
- public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null ) {
+ public function save_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
return $this->save_action_to_db( $action, $scheduled_date, false );
}
@@ -77,9 +89,9 @@ public function save_action( ActionScheduler_Action $action, \DateTime $schedule
* @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 ) {
+ private function save_action_to_db( ActionScheduler_Action $action, ?DateTime $date = null, $unique = false ) {
global $wpdb;
try {
@@ -137,6 +149,7 @@ private function save_action_to_db( ActionScheduler_Action $action, DateTime $da
*/
private function build_insert_sql( array $data, $unique ) {
global $wpdb;
+
$columns = array_keys( $data );
$values = array_values( $data );
$placeholders = array_map( array( $this, 'get_placeholder_for_column' ), $columns );
@@ -146,8 +159,9 @@ private function build_insert_sql( array $data, $unique ) {
$column_sql = '`' . implode( '`, `', $columns ) . '`';
$placeholder_sql = implode( ', ', $placeholders );
$where_clause = $this->build_where_clause_for_insert( $data, $table_name, $unique );
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- $column_sql and $where_clause are already prepared. $placeholder_sql is hardcoded.
- $insert_query = $wpdb->prepare(
+ $insert_query = $wpdb->prepare(
"
INSERT INTO $table_name ( $column_sql )
SELECT $placeholder_sql FROM DUAL
@@ -222,7 +236,7 @@ private function get_placeholder_for_column( $column_name ) {
'extended_args',
);
- return in_array( $column_name, $string_columns ) ? '%s' : '%d';
+ return in_array( $column_name, $string_columns, true ) ? '%s' : '%d';
}
/**
@@ -264,7 +278,11 @@ protected function get_group_ids( $slugs, $create_if_not_exists = true ) {
return array();
}
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
foreach ( $slugs as $slug ) {
@@ -290,8 +308,13 @@ protected function get_group_ids( $slugs, $create_if_not_exists = true ) {
* @return int Group ID.
*/
protected function create_group( $slug ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$wpdb->insert( $wpdb->actionscheduler_groups, array( 'slug' => $slug ) );
return (int) $wpdb->insert_id;
@@ -305,8 +328,13 @@ protected function create_group( $slug ) {
* @return ActionScheduler_Action
*/
public function fetch_action( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$data = $wpdb->get_row(
$wpdb->prepare(
"SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d",
@@ -388,7 +416,8 @@ protected function make_action_from_db_record( $data ) {
* @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' ) {
@@ -396,24 +425,31 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
}
- $query = wp_parse_args( $query, array(
- 'hook' => '',
- 'args' => null,
- 'partial_args_matching' => 'off', // can be 'like' or 'json'
- 'date' => null,
- 'date_compare' => '<=',
- 'modified' => null,
- 'modified_compare' => '<=',
- 'group' => '',
- 'status' => '',
- 'claimed' => null,
- 'per_page' => 5,
- 'offset' => 0,
- 'orderby' => 'date',
- 'order' => 'ASC',
- ) );
-
- /** @var \wpdb $wpdb */
+ $query = wp_parse_args(
+ $query,
+ array(
+ 'hook' => '',
+ 'args' => null,
+ 'partial_args_matching' => 'off', // can be 'like' or 'json'.
+ 'date' => null,
+ 'date_compare' => '<=',
+ 'modified' => null,
+ 'modified_compare' => '<=',
+ 'group' => '',
+ 'status' => '',
+ 'claimed' => null,
+ 'per_page' => 5,
+ 'offset' => 0,
+ 'orderby' => 'date',
+ 'order' => 'ASC',
+ )
+ );
+
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$db_server_info = is_callable( array( $wpdb, 'db_server_info' ) ) ? $wpdb->db_server_info() : $wpdb->db_version();
@@ -428,22 +464,22 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
}
$sql = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
- $sql .= " FROM {$wpdb->actionscheduler_actions} a";
+ $sql .= " FROM {$wpdb->actionscheduler_actions} a";
$sql_params = array();
if ( ! empty( $query['group'] ) || 'group' === $query['orderby'] ) {
$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'];
}
@@ -466,26 +502,28 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
}
$placeholder = isset( $supported_types[ $value_type ] ) ? $supported_types[ $value_type ] : false;
if ( ! $placeholder ) {
- throw new \RuntimeException( sprintf(
- /* translators: %s: provided value type */
- __( 'The value type for the JSON partial matching is not supported. Must be either integer, boolean, double or string. %s type provided.', 'action-scheduler' ),
- $value_type
- ) );
+ throw new \RuntimeException(
+ sprintf(
+ /* translators: %s: provided value type */
+ __( 'The value type for the JSON partial matching is not supported. Must be either integer, boolean, double or string. %s type provided.', 'action-scheduler' ),
+ $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;
case 'like':
foreach ( $query['args'] as $key => $value ) {
- $sql .= ' AND a.args LIKE %s';
+ $sql .= ' AND a.args LIKE %s';
$json_partial = $wpdb->esc_like( trim( wp_json_encode( array( $key => $value ) ), '{}' ) );
$sql_params[] = "%{$json_partial}%";
}
break;
case 'off':
- $sql .= " AND a.args=%s";
+ $sql .= ' AND a.args=%s';
$sql_params[] = $this->get_args_for_query( $query['args'] );
break;
default:
@@ -596,7 +634,11 @@ protected function get_query_actions_sql( array $query, $select_or_count = 'sele
* @return string|array|null The IDs of actions matching the query. Null on failure.
*/
public function query_actions( $query = array(), $query_type = 'select' ) {
- /** @var wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var wpdb $wpdb
+ */
global $wpdb;
$sql = $this->get_query_actions_sql( $query, $query_type );
@@ -638,7 +680,11 @@ public function action_counts() {
* @throws \InvalidArgumentException If the action update failed.
*/
public function cancel_action( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$updated = $wpdb->update(
@@ -687,7 +733,11 @@ public function cancel_actions_by_group( $group ) {
* @param array $query_args Query parameters.
*/
protected function bulk_cancel_actions( $query_args ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
if ( ! is_array( $query_args ) ) {
@@ -738,8 +788,13 @@ protected function bulk_cancel_actions( $query_args ) {
* @throws \InvalidArgumentException If the action deletion failed.
*/
public function delete_action( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$deleted = $wpdb->delete( $wpdb->actionscheduler_actions, array( 'action_id' => $action_id ), array( '%d' ) );
if ( empty( $deleted ) ) {
/* translators: %s is the action ID */
@@ -770,8 +825,13 @@ public function get_date( $action_id ) {
* @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
*/
protected function get_date_gmt( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) );
if ( empty( $record ) ) {
/* translators: %s is the action ID */
@@ -787,14 +847,14 @@ protected function get_date_gmt( $action_id ) {
/**
* Stake a claim on actions.
*
- * @param int $max_actions Maximum number of action to include in claim.
- * @param \DateTime $before_date Jobs must be schedule before this date. Defaults to now.
- * @param array $hooks Hooks to filter for.
- * @param string $group Group to filter for.
+ * @param int $max_actions Maximum number of action to include in claim.
+ * @param DateTime|null $before_date Jobs must be schedule before this date. Defaults to now.
+ * @param array $hooks Hooks to filter for.
+ * @param string $group Group to filter for.
*
* @return ActionScheduler_ActionClaim
*/
- public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
$claim_id = $this->generate_claim_id();
$this->claim_before_date = $before_date;
@@ -811,8 +871,13 @@ public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $
* @return int Claim ID.
*/
protected function generate_claim_id() {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$now = as_get_datetime_object();
$wpdb->insert( $wpdb->actionscheduler_claims, array( 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ) );
@@ -823,7 +888,7 @@ protected function generate_claim_id() {
* 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 ) {
@@ -849,22 +914,26 @@ public function get_claim_filter( $filter_name ) {
/**
* Mark actions claimed.
*
- * @param string $claim_id Claim Id.
- * @param int $limit Number of action to include in claim.
- * @param \DateTime $before_date Should use UTC timezone.
- * @param array $hooks Hooks to filter for.
- * @param string $group Group to filter for.
+ * @param string $claim_id Claim Id.
+ * @param int $limit Number of action to include in claim.
+ * @param DateTime|null $before_date Should use UTC timezone.
+ * @param array $hooks Hooks to filter for.
+ * @param string $group Group to filter for.
*
* @return int The number of actions that were claimed.
* @throws \InvalidArgumentException Throws InvalidArgumentException if group doesn't exist.
* @throws \RuntimeException Throws RuntimeException if unable to claim action.
*/
- protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
- /** @var \wpdb $wpdb */
+ 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;
+ $now = as_get_datetime_object();
+ $date = is_null( $before_date ) ? $now : clone $before_date;
// can't use $wpdb->update() because of the <= condition.
$update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
$params = array(
@@ -891,13 +960,13 @@ protected function claim_actions( $claim_id, $limit, \DateTime $before_date = nu
if ( ! empty( $hooks ) ) {
$placeholders = array_fill( 0, count( $hooks ), '%s' );
- $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
+ $where .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
$params = array_merge( $params, array_values( $hooks ) );
}
$group_operator = 'IN';
if ( empty( $group ) ) {
- $group = $this->get_claim_filter( 'exclude-groups' );
+ $group = $this->get_claim_filter( 'exclude-groups' );
$group_operator = 'NOT IN';
}
@@ -921,17 +990,20 @@ protected function claim_actions( $claim_id, $limit, \DateTime $before_date = nu
}
$id_list = implode( ',', array_map( 'intval', $group_ids ) );
- $where .= " AND group_id {$group_operator} ( $id_list )";
+ $where .= " AND group_id {$group_operator} ( $id_list )";
}
/**
* Sets the order-by clause used in the action claim query.
*
* @since 3.4.0
+ * @since 3.8.3 Made $claim_id and $hooks available.
*
* @param string $order_by_sql
+ * @param string $claim_id Claim Id.
+ * @param array $hooks Hooks to filter for.
*/
- $order = apply_filters( 'action_scheduler_claim_actions_order_by', 'ORDER BY priority ASC, attempts ASC, scheduled_date_gmt ASC, action_id ASC' );
+ $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 );
$params[] = $limit;
$sql = $wpdb->prepare( "{$update} {$where} {$order} LIMIT %d", $params ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders
@@ -974,7 +1046,11 @@ public function get_claim_count() {
* @return mixed
*/
public function get_claim_id( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
@@ -990,7 +1066,11 @@ public function get_claim_id( $action_id ) {
* @return int[]
*/
public function find_actions_by_claim_id( $claim_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$action_ids = array();
@@ -1017,10 +1097,16 @@ public function find_actions_by_claim_id( $claim_id ) {
* 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 */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
/**
* Deadlock warning: This function modifies actions to release them from claims that have been processed. Earlier, we used to it in a atomic query, i.e. we would update all actions belonging to a particular claim_id with claim_id = 0.
* While this was functionally correct, it would cause deadlock, since this update query will hold a lock on the claim_id_.. index on the action table.
@@ -1057,8 +1143,13 @@ public function release_claim( ActionScheduler_ActionClaim $claim ) {
* @return void
*/
public function unclaim_action( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$wpdb->update(
$wpdb->actionscheduler_actions,
array( 'claim_id' => 0 ),
@@ -1075,8 +1166,13 @@ public function unclaim_action( $action_id ) {
* @throws \InvalidArgumentException Throw an exception if action was not updated.
*/
public function mark_failure( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$updated = $wpdb->update(
$wpdb->actionscheduler_actions,
array( 'status' => self::STATUS_FAILED ),
@@ -1100,7 +1196,11 @@ public function mark_failure( $action_id ) {
* @return void
*/
public function log_execution( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d";
@@ -1130,8 +1230,13 @@ public function log_execution( $action_id ) {
* @throws \InvalidArgumentException Throw an exception if action was not updated.
*/
public function mark_complete( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$updated = $wpdb->update(
$wpdb->actionscheduler_actions,
array(
@@ -1168,13 +1273,18 @@ public function mark_complete( $action_id ) {
* @throws \RuntimeException Throw an exception if action status could not be retrieved.
*/
public function get_status( $action_id ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$sql = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
$sql = $wpdb->prepare( $sql, $action_id ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$status = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
- if ( null === $status ) {
+ if ( is_null( $status ) ) {
throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
} elseif ( empty( $status ) ) {
throw new \RuntimeException( __( 'Unknown status found for action.', 'action-scheduler' ) );
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_HybridStore.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_HybridStore.php
index 22d61a606a..c0845da4e0 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_HybridStore.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_HybridStore.php
@@ -15,13 +15,32 @@
class ActionScheduler_HybridStore extends Store {
const DEMARKATION_OPTION = 'action_scheduler_hybrid_store_demarkation';
+ /**
+ * Primary store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $primary_store;
+
+ /**
+ * Secondary store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $secondary_store;
+
+ /**
+ * Runner instance.
+ *
+ * @var Action_Scheduler\Migration\Runner
+ */
private $migration_runner;
/**
- * @var int The dividing line between IDs of actions created
- * by the primary and secondary stores.
+ * The dividing line between IDs of actions created
+ * by the primary and secondary stores.
+ *
+ * @var int
*
* Methods that accept an action ID will compare the ID against
* this to determine which store will contain that ID. In almost
@@ -35,9 +54,9 @@ class ActionScheduler_HybridStore extends Store {
/**
* ActionScheduler_HybridStore constructor.
*
- * @param Config $config Migration config object.
+ * @param Config|null $config Migration config object.
*/
- public function __construct( Config $config = null ) {
+ public function __construct( ?Config $config = null ) {
$this->demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 );
if ( empty( $config ) ) {
$config = Controller::instance()->get_migration_config_object();
@@ -53,10 +72,10 @@ public function __construct( Config $config = null ) {
* @codeCoverageIgnore
*/
public function init() {
- add_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10, 2 );
+ add_action( 'action_scheduler/created_table', array( $this, 'set_autoincrement' ), 10, 2 );
$this->primary_store->init();
$this->secondary_store->init();
- remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 );
+ remove_action( 'action_scheduler/created_table', array( $this, 'set_autoincrement' ), 10 );
}
/**
@@ -64,8 +83,8 @@ public function init() {
* 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
@@ -75,10 +94,16 @@ public function set_autoincrement( $table_name, $table_suffix ) {
if ( empty( $this->demarkation_id ) ) {
$this->demarkation_id = $this->set_demarkation_id();
}
- /** @var \wpdb $wpdb */
+
+ /**
+ * Global.
+ *
+ * @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' );
@@ -88,7 +113,7 @@ public function set_autoincrement( $table_name, $table_suffix ) {
$row_count = $wpdb->insert(
$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
- [
+ array(
'action_id' => $this->demarkation_id,
'hook' => '',
'status' => '',
@@ -96,12 +121,12 @@ public function set_autoincrement( $table_name, $table_suffix ) {
'scheduled_date_local' => $date_local,
'last_attempt_gmt' => $date_gmt,
'last_attempt_local' => $date_local,
- ]
+ )
);
if ( $row_count > 0 ) {
$wpdb->delete(
$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
- [ 'action_id' => $this->demarkation_id ]
+ array( 'action_id' => $this->demarkation_id )
);
}
}
@@ -119,10 +144,15 @@ public function set_autoincrement( $table_name, $table_suffix ) {
*/
private function set_demarkation_id( $id = null ) {
if ( empty( $id ) ) {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
+
$id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" );
- $id ++;
+ $id++;
}
update_option( self::DEMARKATION_OPTION, $id );
@@ -135,15 +165,15 @@ private function set_demarkation_id( $id = null ) {
* 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
*/
- public function find_action( $hook, $params = [] ) {
+ public function find_action( $hook, $params = array() ) {
$found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
if ( ! empty( $found_unmigrated_action ) ) {
- $this->migrate( [ $found_unmigrated_action ] );
+ $this->migrate( array( $found_unmigrated_action ) );
}
return $this->primary_store->find_action( $hook, $params );
@@ -154,12 +184,12 @@ public function find_action( $hook, $params = [] ) {
* 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[]
*/
- public function query_actions( $query = [], $query_type = 'select' ) {
+ public function query_actions( $query = array(), $query_type = 'select' ) {
$found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
if ( ! empty( $found_unmigrated_actions ) ) {
$this->migrate( $found_unmigrated_actions );
@@ -203,12 +233,14 @@ public function action_counts() {
* 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
*/
- public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
$claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
$claimed_actions = $claim->get_actions();
@@ -234,11 +266,11 @@ private function migrate( $action_ids ) {
* Save an action to the primary store.
*
* @param ActionScheduler_Action $action Action object to be saved.
- * @param DateTime $date Optional. Schedule date. Default null.
+ * @param DateTime|null $date Optional. Schedule date. Default null.
*
* @return int The action ID
*/
- public function save_action( ActionScheduler_Action $action, DateTime $date = null ) {
+ public function save_action( ActionScheduler_Action $action, ?DateTime $date = null ) {
return $this->primary_store->save_action( $action, $date );
}
@@ -352,19 +384,19 @@ public function get_status( $action_id ) {
*/
protected function get_store_from_action_id( $action_id, $primary_first = false ) {
if ( $primary_first ) {
- $stores = [
+ $stores = array(
$this->primary_store,
$this->secondary_store,
- ];
+ );
} elseif ( $action_id < $this->demarkation_id ) {
- $stores = [
+ $stores = array(
$this->secondary_store,
$this->primary_store,
- ];
+ );
} else {
- $stores = [
+ $stores = array(
$this->primary_store,
- ];
+ );
}
foreach ( $stores as $store ) {
@@ -376,10 +408,12 @@ protected function get_store_from_action_id( $action_id, $primary_first = false
return null;
}
- /* * * * * * * * * * * * * * * * * * * * * * * * * * *
+ /**
+ * * * * * * * * * * * * * * * * * * * * * * * * * * *
* All claim-related functions should operate solely
* on the primary store.
- * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ */
/**
* Get the claim count from the table data store.
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
index 7215ddd94a..a9d84d31e4 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php
@@ -5,17 +5,19 @@
*/
class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
const AGENT = 'ActionScheduler';
- const TYPE = 'action_log';
+ 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|null $date Action log's timestamp.
*
* @return string The log entry ID
*/
- public function log( $action_id, $message, DateTime $date = NULL ) {
- if ( empty($date) ) {
+ public function log( $action_id, $message, ?DateTime $date = null ) {
+ if ( empty( $date ) ) {
$date = as_get_datetime_object();
} else {
$date = as_get_datetime_object( clone $date );
@@ -24,30 +26,41 @@ public function log( $action_id, $message, DateTime $date = NULL ) {
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');
+ $comment_date_gmt = $date->format( 'Y-m-d H:i:s' );
ActionScheduler_TimezoneHelper::set_local_timezone( $date );
$comment_data = array(
- 'comment_post_ID' => $action_id,
- 'comment_date' => $date->format('Y-m-d H:i:s'),
+ 'comment_post_ID' => $action_id,
+ 'comment_date' => $date->format( 'Y-m-d H:i:s' ),
'comment_date_gmt' => $comment_date_gmt,
- 'comment_author' => self::AGENT,
- 'comment_content' => $message,
- 'comment_agent' => self::AGENT,
- 'comment_type' => self::TYPE,
+ 'comment_author' => self::AGENT,
+ 'comment_content' => $message,
+ 'comment_agent' => self::AGENT,
+ 'comment_type' => self::TYPE,
);
- return wp_insert_comment($comment_data);
+
+ return wp_insert_comment( $comment_data );
}
/**
- * @param string $entry_id
+ * Get single log entry for action.
+ *
+ * @param string $entry_id Entry ID.
*
* @return ActionScheduler_LogEntry
*/
public function get_entry( $entry_id ) {
$comment = $this->get_comment( $entry_id );
- if ( empty($comment) || $comment->comment_type != self::TYPE ) {
+
+ if ( empty( $comment ) || self::TYPE !== $comment->comment_type ) {
return new ActionScheduler_NullLogEntry();
}
@@ -57,59 +70,75 @@ public function get_entry( $entry_id ) {
}
/**
- * @param string $action_id
+ * Get action's logs.
+ *
+ * @param string $action_id Action ID.
*
* @return ActionScheduler_LogEntry[]
*/
public function get_logs( $action_id ) {
$status = 'all';
- if ( get_post_status($action_id) == 'trash' ) {
+ $logs = array();
+
+ if ( get_post_status( $action_id ) === 'trash' ) {
$status = 'post-trashed';
}
- $comments = get_comments(array(
- 'post_id' => $action_id,
- 'orderby' => 'comment_date_gmt',
- 'order' => 'ASC',
- 'type' => self::TYPE,
- 'status' => $status,
- ));
- $logs = array();
+
+ $comments = get_comments(
+ array(
+ 'post_id' => $action_id,
+ 'orderby' => 'comment_date_gmt',
+ 'order' => 'ASC',
+ 'type' => self::TYPE,
+ 'status' => $status,
+ )
+ );
+
foreach ( $comments as $c ) {
$entry = $this->get_entry( $c );
- if ( !empty($entry) ) {
+
+ if ( ! empty( $entry ) ) {
$logs[] = $entry;
}
}
+
return $logs;
}
+ /**
+ * Get comment.
+ *
+ * @param int $comment_id Comment ID.
+ */
protected function get_comment( $comment_id ) {
return get_comment( $comment_id );
}
-
-
/**
- * @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
+ 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.
}
}
- $query->query_vars['action_log_filter'] = TRUE;
+ $query->query_vars['action_log_filter'] = true;
add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
}
/**
- * @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
*/
public function filter_comment_query_clauses( $clauses, $query ) {
- if ( !empty($query->query_vars['action_log_filter']) ) {
+ if ( ! empty( $query->query_vars['action_log_filter'] ) ) {
$clauses['where'] .= $this->get_where_clause();
}
return $clauses;
@@ -119,8 +148,8 @@ public function filter_comment_query_clauses( $clauses, $query ) {
* 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 +173,8 @@ protected function get_where_clause() {
/**
* 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
*/
@@ -170,17 +199,21 @@ protected function get_comment_count() {
$stats = get_transient( 'as_comment_count' );
if ( ! $stats ) {
- $stats = array();
-
- $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
-
- $total = 0;
- $stats = array();
- $approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
+ $stats = array();
+ $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
+ $total = 0;
+ $stats = array();
+ $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
- if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
+ // Don't count post-trashed toward totals.
+ if ( 'post-trashed' !== $row['comment_approved'] && 'trash' !== $row['comment_approved'] ) {
$total += $row['num_comments'];
}
if ( isset( $approved[ $row['comment_approved'] ] ) ) {
@@ -213,6 +246,8 @@ public function delete_comment_count_cache() {
}
/**
+ * Initialize.
+ *
* @codeCoverageIgnore
*/
public function init() {
@@ -222,19 +257,26 @@ public function init() {
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);
+ wp_defer_comment_counting( true );
}
+
+ /**
+ * Enable comment counting.
+ */
public function enable_comment_counting() {
- wp_defer_comment_counting(false);
+ wp_defer_comment_counting( false );
}
}
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore.php
index 3971b3395b..a503c18308 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore.php
@@ -30,12 +30,12 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
* Save action.
*
* @param ActionScheduler_Action $action Scheduled Action.
- * @param DateTime $scheduled_date Scheduled Date.
+ * @param DateTime|null $scheduled_date Scheduled Date.
*
* @throws RuntimeException Throws an exception if the action could not be saved.
* @return int
*/
- public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = null ) {
+ public function save_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
try {
$this->validate_action( $action );
$post_array = $this->create_post_array( $action, $scheduled_date );
@@ -54,11 +54,11 @@ public function save_action( ActionScheduler_Action $action, DateTime $scheduled
* Create post array.
*
* @param ActionScheduler_Action $action Scheduled Action.
- * @param DateTime $scheduled_date Scheduled Date.
+ * @param DateTime|null $scheduled_date Scheduled Date.
*
* @return array Returns an array of post data.
*/
- protected function create_post_array( ActionScheduler_Action $action, DateTime $scheduled_date = null ) {
+ protected function create_post_array( ActionScheduler_Action $action, ?DateTime $scheduled_date = null ) {
$post = array(
'post_type' => self::POST_TYPE,
'post_title' => $action->get_hook(),
@@ -573,16 +573,16 @@ public function get_date_gmt( $action_id ) {
/**
* Stake claim.
*
- * @param int $max_actions Maximum number of actions.
- * @param DateTime $before_date Jobs must be schedule before this 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.
+ * @param int $max_actions Maximum number of actions.
+ * @param DateTime|null $before_date Jobs must be schedule before this 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.
*
* @return ActionScheduler_ActionClaim
* @throws RuntimeException When there is an error staking a claim.
* @throws InvalidArgumentException When the given group is not valid.
*/
- public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ public function stake_claim( $max_actions = 10, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
$this->claim_before_date = $before_date;
$claim_id = $this->generate_claim_id();
$this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
@@ -622,16 +622,16 @@ protected function generate_claim_id() {
/**
* Claim actions.
*
- * @param string $claim_id Claim ID.
- * @param int $limit Limit.
- * @param DateTime $before_date Should use UTC timezone.
- * @param array $hooks Claim only actions with a hook or hooks.
- * @param string $group Claim only actions in the given group.
+ * @param string $claim_id Claim ID.
+ * @param int $limit Limit.
+ * @param DateTime|null $before_date Should use UTC timezone.
+ * @param array $hooks Claim only actions with a hook or hooks.
+ * @param string $group Claim only actions in the given group.
*
* @return int The number of actions that were claimed.
* @throws RuntimeException When there is a database error.
*/
- protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) {
+ protected function claim_actions( $claim_id, $limit, ?DateTime $before_date = null, $hooks = array(), $group = '' ) {
// Set up initial variables.
$date = null === $before_date ? as_get_datetime_object() : clone $before_date;
$limit_ids = ! empty( $group );
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
index 246bc347bf..5f1f1fc0d2 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php
@@ -2,9 +2,14 @@
/**
* Class ActionScheduler_wpPostStore_PostStatusRegistrar
+ *
* @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() ) );
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
index e1bcf6bead..5252294529 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php
@@ -2,9 +2,13 @@
/**
* Class ActionScheduler_wpPostStore_PostTypeRegistrar
+ *
* @codeCoverageIgnore
*/
class ActionScheduler_wpPostStore_PostTypeRegistrar {
+ /**
+ * Registrar.
+ */
public function register() {
register_post_type( ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args() );
}
@@ -16,35 +20,34 @@ public function register() {
*/
protected function post_type_args() {
$args = array(
- 'label' => __( 'Scheduled Actions', 'action-scheduler' ),
- 'description' => __( 'Scheduled actions are hooks triggered on a certain date and time.', 'action-scheduler' ),
- 'public' => false,
+ 'label' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'description' => __( 'Scheduled actions are hooks triggered on a certain date and time.', 'action-scheduler' ),
+ 'public' => false,
'map_meta_cap' => true,
'hierarchical' => false,
- 'supports' => array('title', 'editor','comments'),
- 'rewrite' => false,
- 'query_var' => false,
- 'can_export' => true,
- 'ep_mask' => EP_NONE,
- 'labels' => array(
- 'name' => __( 'Scheduled Actions', 'action-scheduler' ),
- 'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
- 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
- 'add_new' => __( 'Add', 'action-scheduler' ),
- 'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
- 'edit' => __( 'Edit', 'action-scheduler' ),
- 'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
- 'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
- 'view' => __( 'View Action', 'action-scheduler' ),
- 'view_item' => __( 'View Action', 'action-scheduler' ),
- 'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
- 'not_found' => __( 'No actions found', 'action-scheduler' ),
+ 'supports' => array( 'title', 'editor', 'comments' ),
+ 'rewrite' => false,
+ 'query_var' => false,
+ 'can_export' => true,
+ 'ep_mask' => EP_NONE,
+ 'labels' => array(
+ 'name' => __( 'Scheduled Actions', 'action-scheduler' ),
+ 'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
+ 'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
+ 'add_new' => __( 'Add', 'action-scheduler' ),
+ 'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
+ 'edit' => __( 'Edit', 'action-scheduler' ),
+ 'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
+ 'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
+ 'view' => __( 'View Action', 'action-scheduler' ),
+ 'view_item' => __( 'View Action', 'action-scheduler' ),
+ 'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
+ 'not_found' => __( 'No actions found', 'action-scheduler' ),
'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
),
);
- $args = apply_filters('action_scheduler_post_type_args', $args);
+ $args = apply_filters( 'action_scheduler_post_type_args', $args );
return $args;
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
index 367401f7e2..e100fc9be8 100644
--- a/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
+++ b/inc/Dependencies/ActionScheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
@@ -2,25 +2,32 @@
/**
* Class ActionScheduler_wpPostStore_TaxonomyRegistrar
+ *
* @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', 'action-scheduler' ),
- 'public' => false,
- 'hierarchical' => false,
+ 'label' => __( 'Action Group', 'action-scheduler' ),
+ 'public' => false,
+ 'hierarchical' => false,
'show_admin_column' => true,
- 'query_var' => false,
- 'rewrite' => false,
+ 'query_var' => false,
+ 'rewrite' => false,
);
$args = apply_filters( 'action_scheduler_taxonomy_args', $args );
return $args;
}
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/ActionMigrator.php b/inc/Dependencies/ActionScheduler/classes/migration/ActionMigrator.php
index 1469de02fd..f0e04fe9f7 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/ActionMigrator.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/ActionMigrator.php
@@ -13,21 +13,33 @@
* @codeCoverageIgnore
*/
class ActionMigrator {
- /** var ActionScheduler_Store */
+ /**
+ * Source store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $source;
- /** var ActionScheduler_Store */
+ /**
+ * Destination store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $destination;
- /** var LogMigrator */
+ /**
+ * LogMigrator instance.
+ *
+ * @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 +53,7 @@ public function __construct( \ActionScheduler_Store $source_store, \ActionSchedu
* @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,37 +65,37 @@ public function migrate( $source_action_id ) {
}
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
+ } catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
+ // 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 );
+ do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
return 0;
}
try {
- // 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;
+ // Make sure the last attempt date is set correctly for completed and failed actions.
+ $last_attempt_date = ( \ActionScheduler_Store::STATUS_PENDING !== $status ) ? $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 );
+ do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
- return 0; // could not save the action in the new store
+ return 0; // could not save the action in the new store.
}
try {
switch ( $status ) {
- case \ActionScheduler_Store::STATUS_FAILED :
+ case \ActionScheduler_Store::STATUS_FAILED:
$this->destination->mark_failure( $destination_action_id );
break;
- case \ActionScheduler_Store::STATUS_CANCELED :
+ case \ActionScheduler_Store::STATUS_CANCELED:
$this->destination->cancel_action( $destination_action_id );
break;
}
@@ -95,14 +108,17 @@ public function migrate( $source_action_id ) {
// translators: %s is an action ID.
throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'action-scheduler' ), $source_action_id ) );
}
- do_action( 'action_scheduler/migrated_action', $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 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
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 );
+
+ // phpcs:disable WordPress.NamingConventions.ValidHookName.UseUnderscores
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 );
+ // phpcs:enable
return $destination_action_id;
}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/ActionScheduler_DBStoreMigrator.php b/inc/Dependencies/ActionScheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
index ae0785d44f..66ab997075 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
@@ -3,7 +3,7 @@
/**
* Class ActionScheduler_DBStoreMigrator
*
- * A class for direct saving of actions to the table data store during migration.
+ * A class for direct saving of actions to the table data store during migration.
*
* @since 3.0.0
*/
@@ -16,25 +16,29 @@ 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.
*/
- public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){
+ public function save_action( ActionScheduler_Action $action, ?DateTime $scheduled_date = null, ?DateTime $last_attempt_date = null ) {
try {
- /** @var \wpdb $wpdb */
+ /**
+ * Global.
+ *
+ * @var \wpdb $wpdb
+ */
global $wpdb;
$action_id = parent::save_action( $action, $scheduled_date );
if ( null !== $last_attempt_date ) {
- $data = [
+ $data = array(
'last_attempt_gmt' => $this->get_scheduled_date_string( $action, $last_attempt_date ),
'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ),
- ];
+ );
$wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) );
}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/BatchFetcher.php b/inc/Dependencies/ActionScheduler/classes/migration/BatchFetcher.php
index 48728010fe..20aa3d03f3 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/BatchFetcher.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/BatchFetcher.php
@@ -1,9 +1,7 @@
$now,
'per_page' => $count,
'offset' => 0,
'orderby' => 'date',
'order' => 'ASC',
- ];
+ );
- $priorities = [
+ $priorities = array(
Store::STATUS_PENDING,
Store::STATUS_FAILED,
Store::STATUS_CANCELED,
Store::STATUS_COMPLETE,
Store::STATUS_RUNNING,
- '', // any other unanticipated status
- ];
+ '', // any other unanticipated status.
+ );
foreach ( $priorities as $status ) {
- yield wp_parse_args( [
- 'status' => $status,
- 'date_compare' => '<=',
- ], $args );
- yield wp_parse_args( [
- 'status' => $status,
- 'date_compare' => '>=',
- ], $args );
+ yield wp_parse_args(
+ array(
+ 'status' => $status,
+ 'date_compare' => '<=',
+ ),
+ $args
+ );
+
+ yield wp_parse_args(
+ array(
+ 'status' => $status,
+ 'date_compare' => '>=',
+ ),
+ $args
+ );
}
}
-}
\ No newline at end of file
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/Config.php b/inc/Dependencies/ActionScheduler/classes/migration/Config.php
index cf91a5e246..f16b4c192d 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/Config.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/Config.php
@@ -17,22 +17,46 @@
* A config builder for the ActionScheduler\Migration\Runner class
*/
class Config {
- /** @var ActionScheduler_Store */
+ /**
+ * Source store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $source_store;
- /** @var ActionScheduler_Logger */
+ /**
+ * Source logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $source_logger;
- /** @var ActionScheduler_Store */
+ /**
+ * Destination store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $destination_store;
- /** @var ActionScheduler_Logger */
+ /**
+ * Destination logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $destination_logger;
- /** @var Progress bar */
+ /**
+ * Progress bar object.
+ *
+ * @var Action_Scheduler\WP_CLI\ProgressBar
+ */
private $progress_bar;
- /** @var bool */
+ /**
+ * Flag indicating a dryrun.
+ *
+ * @var bool
+ */
private $dry_run = false;
/**
@@ -46,6 +70,7 @@ public function __construct() {
* 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 +93,7 @@ public function set_source_store( Store $store ) {
* 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 +106,7 @@ public function get_source_logger() {
/**
* 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 +116,7 @@ public function set_source_logger( Logger $logger ) {
* 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 +129,7 @@ public function get_destination_store() {
/**
* 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 +139,7 @@ public function set_destination_store( Store $store ) {
* 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 +152,7 @@ public function get_destination_logger() {
/**
* 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 +170,7 @@ public function get_dry_run() {
/**
* 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 +188,7 @@ public function get_progress_bar() {
/**
* 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;
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/Controller.php b/inc/Dependencies/ActionScheduler/classes/migration/Controller.php
index b2b618d8f2..7c3df60799 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/Controller.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/Controller.php
@@ -19,18 +19,39 @@
* @codeCoverageIgnore
*/
class Controller {
+ /**
+ * Instance.
+ *
+ * @var self
+ */
private static $instance;
- /** @var Action_Scheduler\Migration\Scheduler */
+ /**
+ * Scheduler instance.
+ *
+ * @var Action_Scheduler\Migration\Scheduler
+ */
private $migration_scheduler;
- /** @var string */
+ /**
+ * Class name of the store object.
+ *
+ * @var string
+ */
private $store_classname;
- /** @var string */
+ /**
+ * Class name of the logger object.
+ *
+ * @var string
+ */
private $logger_classname;
- /** @var bool */
+ /**
+ * Flag to indicate migrating custom store.
+ *
+ * @var bool
+ */
private $migrate_custom_store;
/**
@@ -142,7 +163,7 @@ public function get_migration_config_object() {
}
}
- return apply_filters( 'action_scheduler/migration_config', $config );
+ return apply_filters( 'action_scheduler/migration_config', $config ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
@@ -171,15 +192,13 @@ private function hook() {
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 );
}
/**
* Possibly hook the migration scheduler action.
- *
- * @author Jeremy Pry
*/
public function maybe_hook_migration() {
if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) {
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/DryRun_ActionMigrator.php b/inc/Dependencies/ActionScheduler/classes/migration/DryRun_ActionMigrator.php
index ffc21c2875..ab7d670eea 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/DryRun_ActionMigrator.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/DryRun_ActionMigrator.php
@@ -21,7 +21,7 @@ class DryRun_ActionMigrator extends ActionMigrator {
* @return int
*/
public function migrate( $source_action_id ) {
- do_action( 'action_scheduler/migrate_action_dry_run', $source_action_id );
+ do_action( 'action_scheduler/migrate_action_dry_run', $source_action_id ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
return 0;
}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/DryRun_LogMigrator.php b/inc/Dependencies/ActionScheduler/classes/migration/DryRun_LogMigrator.php
index fc9e4d3d69..90bd637ad5 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/DryRun_LogMigrator.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/DryRun_LogMigrator.php
@@ -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.
}
-}
\ No newline at end of file
+}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/LogMigrator.php b/inc/Dependencies/ActionScheduler/classes/migration/LogMigrator.php
index b85da8550b..1bc41ace03 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/LogMigrator.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/LogMigrator.php
@@ -15,21 +15,29 @@
* @codeCoverageIgnore
*/
class LogMigrator {
- /** @var ActionScheduler_Logger */
+ /**
+ * Source logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $source;
- /** @var ActionScheduler_Logger */
+ /**
+ * Destination logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $destination;
/**
* ActionMigrator constructor.
*
* @param ActionScheduler_Logger $source_logger Source logger object.
- * @param ActionScheduler_Logger $destination_Logger Destination logger object.
+ * @param ActionScheduler_Logger $destination_logger Destination logger object.
*/
- public function __construct( ActionScheduler_Logger $source_logger, ActionScheduler_Logger $destination_Logger ) {
+ public function __construct( ActionScheduler_Logger $source_logger, ActionScheduler_Logger $destination_logger ) {
$this->source = $source_logger;
- $this->destination = $destination_Logger;
+ $this->destination = $destination_logger;
}
/**
@@ -40,8 +48,9 @@ public function __construct( ActionScheduler_Logger $source_logger, ActionSchedu
*/
public function migrate( $source_action_id, $destination_action_id ) {
$logs = $this->source->get_logs( $source_action_id );
+
foreach ( $logs as $log ) {
- if ( $log->get_action_id() == $source_action_id ) {
+ if ( absint( $log->get_action_id() ) === absint( $source_action_id ) ) {
$this->destination->log( $destination_action_id, $log->get_message(), $log->get_date() );
}
}
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/Runner.php b/inc/Dependencies/ActionScheduler/classes/migration/Runner.php
index 2304a79adc..85c7e04412 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/Runner.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/Runner.php
@@ -13,28 +13,60 @@
* @codeCoverageIgnore
*/
class Runner {
- /** @var ActionScheduler_Store */
+ /**
+ * Source store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $source_store;
- /** @var ActionScheduler_Store */
+ /**
+ * Destination store instance.
+ *
+ * @var ActionScheduler_Store
+ */
private $destination_store;
- /** @var ActionScheduler_Logger */
+ /**
+ * Source logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $source_logger;
- /** @var ActionScheduler_Logger */
+ /**
+ * Destination logger instance.
+ *
+ * @var ActionScheduler_Logger
+ */
private $destination_logger;
- /** @var BatchFetcher */
+ /**
+ * Batch fetcher instance.
+ *
+ * @var BatchFetcher
+ */
private $batch_fetcher;
- /** @var ActionMigrator */
+ /**
+ * Action migrator instance.
+ *
+ * @var ActionMigrator
+ */
private $action_migrator;
- /** @var LogMigrator */
+ /**
+ * Log migrator instance.
+ *
+ * @var LogMigrator
+ */
private $log_migrator;
- /** @var ProgressBar */
+ /**
+ * Progress bar instance.
+ *
+ * @var ProgressBar
+ */
private $progress_bar;
/**
@@ -70,7 +102,7 @@ public function __construct( Config $config ) {
* @return int Size of batch processed.
*/
public function run( $batch_size = 10 ) {
- $batch = $this->batch_fetcher->fetch( $batch_size );
+ $batch = $this->batch_fetcher->fetch( $batch_size );
$batch_size = count( $batch );
if ( ! $batch_size ) {
@@ -94,7 +126,7 @@ public function run( $batch_size = 10 ) {
* @param array $action_ids List of action IDs to migrate.
*/
public function migrate_actions( array $action_ids ) {
- do_action( 'action_scheduler/migration_batch_starting', $action_ids );
+ do_action( 'action_scheduler/migration_batch_starting', $action_ids ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
\ActionScheduler::logger()->unhook_stored_action();
$this->destination_logger->unhook_stored_action();
@@ -102,14 +134,17 @@ public function migrate_actions( array $action_ids ) {
foreach ( $action_ids as $source_action_id ) {
$destination_action_id = $this->action_migrator->migrate( $source_action_id );
if ( $destination_action_id ) {
- $this->destination_logger->log( $destination_action_id, sprintf(
- /* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */
- __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
- $source_action_id,
- get_class( $this->source_store ),
+ $this->destination_logger->log(
$destination_action_id,
- get_class( $this->destination_store )
- ) );
+ sprintf(
+ /* translators: 1: source action ID 2: source store class 3: destination action ID 4: destination store class */
+ __( 'Migrated action with ID %1$d in %2$s to ID %3$d in %4$s', 'action-scheduler' ),
+ $source_action_id,
+ get_class( $this->source_store ),
+ $destination_action_id,
+ get_class( $this->destination_store )
+ )
+ );
}
if ( $this->progress_bar ) {
@@ -123,7 +158,7 @@ public function migrate_actions( array $action_ids ) {
\ActionScheduler::logger()->hook_stored_action();
- do_action( 'action_scheduler/migration_batch_complete', $action_ids );
+ do_action( 'action_scheduler/migration_batch_complete', $action_ids ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/migration/Scheduler.php b/inc/Dependencies/ActionScheduler/classes/migration/Scheduler.php
index dcbe2db5fa..d6c320d91f 100644
--- a/inc/Dependencies/ActionScheduler/classes/migration/Scheduler.php
+++ b/inc/Dependencies/ActionScheduler/classes/migration/Scheduler.php
@@ -14,10 +14,10 @@
*/
class Scheduler {
/** Migration action hook. */
- const HOOK = 'action_scheduler/migration_hook';
+ const HOOK = 'action_scheduler/migration_hook';
/** Migration action group. */
- const GROUP = 'action-scheduler-migration';
+ const GROUP = 'action-scheduler-migration';
/**
* Set up the callback for the scheduled job.
@@ -40,7 +40,7 @@ public function run_migration() {
$migration_runner = $this->get_migration_runner();
$count = $migration_runner->run( $this->get_batch_size() );
- if ( $count === 0 ) {
+ if ( 0 === $count ) {
$this->mark_complete();
} else {
$this->schedule_migration( time() + $this->get_schedule_interval() );
@@ -54,7 +54,7 @@ public function mark_complete() {
$this->unschedule_migration();
\ActionScheduler_DataController::mark_migration_complete();
- do_action( 'action_scheduler/migration_complete' );
+ do_action( 'action_scheduler/migration_complete' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
@@ -102,7 +102,7 @@ public function unschedule_migration() {
* @return int Seconds between migration runs. Defaults to 0 seconds to allow chaining migration via Async Runners.
*/
private function get_schedule_interval() {
- return (int) apply_filters( 'action_scheduler/migration_interval', 0 );
+ return (int) apply_filters( 'action_scheduler/migration_interval', 0 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
@@ -111,7 +111,7 @@ private function get_schedule_interval() {
* @return int Number of actions to migrate in each batch. Defaults to 250.
*/
private function get_batch_size() {
- return (int) apply_filters( 'action_scheduler/migration_batch_size', 250 );
+ return (int) apply_filters( 'action_scheduler/migration_batch_size', 250 ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CanceledSchedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CanceledSchedule.php
index 840e482c15..4f90c8333c 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CanceledSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CanceledSchedule.php
@@ -7,11 +7,15 @@ class ActionScheduler_CanceledSchedule extends ActionScheduler_SimpleSchedule {
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $timestamp = NULL;
+ *
+ * @var null
+ */
+ private $timestamp = null;
/**
- * @param DateTime $after
+ * Calculate when the next instance of this schedule would run based on a given date & time.
+ *
+ * @param DateTime $after Timestamp.
*
* @return DateTime|null
*/
@@ -23,7 +27,7 @@ public function calculate_next( DateTime $after ) {
* 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 ) {
@@ -31,6 +35,8 @@ public function get_next( DateTime $after ) {
}
/**
+ * Action is not recurring.
+ *
* @return bool
*/
public function is_recurring() {
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CronSchedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CronSchedule.php
index bc70c0f24b..6ac43c943d 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CronSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_CronSchedule.php
@@ -7,23 +7,27 @@ class ActionScheduler_CronSchedule extends ActionScheduler_Abstract_RecurringSch
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $start_timestamp = NULL;
+ *
+ * @var null
+ */
+ private $start_timestamp = null;
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $cron = NULL;
+ *
+ * @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 ) {
+ public function __construct( DateTime $start, $recurrence, ?DateTime $first = null ) {
if ( ! is_a( $recurrence, 'CronExpression' ) ) {
$recurrence = CronExpression::factory( $recurrence );
}
@@ -41,7 +45,7 @@ public function __construct( DateTime $start, $recurrence, DateTime $first = nul
* 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 ) {
@@ -49,6 +53,8 @@ protected function calculate_next( DateTime $after ) {
}
/**
+ * Get the schedule's recurrence.
+ *
* @return string
*/
public function get_recurrence() {
@@ -75,10 +81,13 @@ public function __sleep() {
$this->start_timestamp = $this->scheduled_timestamp;
$this->cron = $this->recurrence;
- return array_merge( $sleep_params, array(
- 'start_timestamp',
- 'cron'
- ) );
+ return array_merge(
+ $sleep_params,
+ array(
+ 'start_timestamp',
+ 'cron',
+ )
+ );
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_IntervalSchedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
index ba4d508dff..228ef4c2c0 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_IntervalSchedule.php
@@ -7,19 +7,23 @@ class ActionScheduler_IntervalSchedule extends ActionScheduler_Abstract_Recurrin
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $start_timestamp = NULL;
+ *
+ * @var null
+ */
+ private $start_timestamp = null;
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $interval_in_seconds = NULL;
+ *
+ * @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 ) {
@@ -28,6 +32,8 @@ protected function calculate_next( DateTime $after ) {
}
/**
+ * Schedule interval in seconds.
+ *
* @return int
*/
public function interval_in_seconds() {
@@ -55,10 +61,13 @@ public function __sleep() {
$this->start_timestamp = $this->scheduled_timestamp;
$this->interval_in_seconds = $this->recurrence;
- return array_merge( $sleep_params, array(
- 'start_timestamp',
- 'interval_in_seconds'
- ) );
+ return array_merge(
+ $sleep_params,
+ array(
+ 'start_timestamp',
+ 'interval_in_seconds',
+ )
+ );
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_NullSchedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_NullSchedule.php
index 1b1afec021..77c7c4ed44 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_NullSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_NullSchedule.php
@@ -5,26 +5,34 @@
*/
class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule {
- /** @var DateTime|null */
+ /**
+ * DateTime instance.
+ *
+ * @var DateTime|null
+ */
protected $scheduled_date;
/**
* 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 ) {
+ public function __construct( ?DateTime $date = null ) {
$this->scheduled_date = null;
}
/**
- * This schedule has no scheduled DateTime, so we need to override the parent __sleep()
+ * This schedule has no scheduled DateTime, so we need to override the parent __sleep().
+ *
* @return array
*/
public function __sleep() {
return array();
}
+ /**
+ * Wakeup.
+ */
public function __wakeup() {
$this->scheduled_date = null;
}
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_Schedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_Schedule.php
index d61a9f7c92..e3803e1840 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_Schedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_Schedule.php
@@ -5,14 +5,18 @@
*/
interface ActionScheduler_Schedule {
/**
- * @param DateTime $after
+ * Get the date & time this schedule was created to run, or calculate when it should be run
+ * after a given date & time.
+ *
+ * @param null|DateTime $after Timestamp.
* @return DateTime|null
*/
- public function next( DateTime $after = NULL );
+ public function next( ?DateTime $after = null );
/**
+ * Identify the schedule as (not) recurring.
+ *
* @return bool
*/
public function is_recurring();
}
-
\ No newline at end of file
diff --git a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_SimpleSchedule.php b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
index 454174c2ae..f1ce2e0138 100644
--- a/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
+++ b/inc/Dependencies/ActionScheduler/classes/schedules/ActionScheduler_SimpleSchedule.php
@@ -7,11 +7,16 @@ class ActionScheduler_SimpleSchedule extends ActionScheduler_Abstract_Schedule {
/**
* Deprecated property @see $this->__wakeup() for details.
- **/
- private $timestamp = NULL;
+ *
+ * @var null|DateTime
+ */
+ private $timestamp = null;
/**
- * @param DateTime $after
+ * Calculate when this schedule should start after a given date & time using
+ * the number of seconds between recurrences.
+ *
+ * @param DateTime $after Timestamp.
*
* @return DateTime|null
*/
@@ -20,6 +25,8 @@ public function calculate_next( DateTime $after ) {
}
/**
+ * Schedule is not recurring.
+ *
* @return bool
*/
public function is_recurring() {
@@ -45,9 +52,12 @@ public function __sleep() {
$this->timestamp = $this->scheduled_timestamp;
- return array_merge( $sleep_params, array(
- 'timestamp',
- ) );
+ return array_merge(
+ $sleep_params,
+ array(
+ 'timestamp',
+ )
+ );
}
/**
diff --git a/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_LoggerSchema.php b/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_LoggerSchema.php
index c52d37ce0b..27e1c7ff9d 100644
--- a/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_LoggerSchema.php
+++ b/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_LoggerSchema.php
@@ -11,14 +11,21 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
const LOG_TABLE = 'actionscheduler_logs';
/**
- * @var int Increment this value to trigger a schema update.
+ * Schema version.
+ *
+ * Increment this value to trigger a schema update.
+ *
+ * @var int
*/
protected $schema_version = 3;
+ /**
+ * Construct.
+ */
public function __construct() {
- $this->tables = [
+ $this->tables = array(
self::LOG_TABLE,
- ];
+ );
}
/**
@@ -28,14 +35,18 @@ public function init() {
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;
- $charset_collate = $wpdb->get_charset_collate();
+ $table_name = $wpdb->$table;
+ $charset_collate = $wpdb->get_charset_collate();
switch ( $table ) {
case self::LOG_TABLE:
-
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
return "CREATE TABLE $table_name (
log_id bigint(20) unsigned NOT NULL auto_increment,
diff --git a/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_StoreSchema.php b/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_StoreSchema.php
index a0bd8cb20f..37df226bc6 100644
--- a/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_StoreSchema.php
+++ b/inc/Dependencies/ActionScheduler/classes/schema/ActionScheduler_StoreSchema.php
@@ -14,16 +14,23 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
const DEFAULT_DATE = '0000-00-00 00:00:00';
/**
- * @var int Increment this value to trigger a schema update.
+ * Schema version.
+ *
+ * Increment this value to trigger a schema update.
+ *
+ * @var int
*/
protected $schema_version = 7;
+ /**
+ * Construct.
+ */
public function __construct() {
- $this->tables = [
+ $this->tables = array(
self::ACTIONS_TABLE,
self::CLAIMS_TABLE,
self::GROUPS_TABLE,
- ];
+ );
}
/**
@@ -33,17 +40,24 @@ public function init() {
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();
+ $table_name = $wpdb->$table;
+ $charset_collate = $wpdb->get_charset_collate();
+ $default_date = self::DEFAULT_DATE;
+ // 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;
+
switch ( $table ) {
case self::ACTIONS_TABLE:
-
return "CREATE TABLE {$table_name} (
action_id bigint(20) unsigned NOT NULL auto_increment,
hook varchar(191) NOT NULL,
@@ -70,7 +84,6 @@ protected function get_table_definition( $table ) {
) $charset_collate";
case self::CLAIMS_TABLE:
-
return "CREATE TABLE {$table_name} (
claim_id bigint(20) unsigned NOT NULL auto_increment,
date_created_gmt datetime NULL default '{$default_date}',
@@ -79,7 +92,6 @@ protected function get_table_definition( $table ) {
) $charset_collate";
case self::GROUPS_TABLE:
-
return "CREATE TABLE {$table_name} (
group_id bigint(20) unsigned NOT NULL auto_increment,
slug varchar(255) NOT NULL,
diff --git a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php
index dac17aa42e..e24ddca16d 100644
--- a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php
+++ b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Abstract_QueueRunner_Deprecated.php
@@ -16,7 +16,7 @@ protected function get_maximum_execution_time() {
$maximum_execution_time = 30;
- // Apply deprecated filter
+ // Apply deprecated filter.
if ( has_filter( 'action_scheduler_maximum_execution_time' ) ) {
_deprecated_function( 'action_scheduler_maximum_execution_time', '2.1.1', 'action_scheduler_queue_runner_time_limit' );
$maximum_execution_time = apply_filters( 'action_scheduler_maximum_execution_time', $maximum_execution_time );
diff --git a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_AdminView_Deprecated.php b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
index 62d964e0ff..46935ec69e 100644
--- a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
+++ b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_AdminView_Deprecated.php
@@ -10,6 +10,11 @@
*/
class ActionScheduler_AdminView_Deprecated {
+ /**
+ * Adjust parameters for custom post type.
+ *
+ * @param array $args Args.
+ */
public function action_scheduler_post_type_args( $args ) {
_deprecated_function( __METHOD__, '2.0.0' );
return $args;
@@ -68,7 +73,7 @@ public static function list_table_sortable_columns( $columns ) {
* Print the content for our custom columns.
*
* @param string $column_name The key for the column for which we should output our content.
- * @param int $post_id The ID of the 'scheduled-action' post for which this row relates.
+ * @param int $post_id The ID of the 'scheduled-action' post for which this row relates.
*/
public static function list_table_column_content( $column_name, $post_id ) {
_deprecated_function( __METHOD__, '2.0.0' );
@@ -79,7 +84,8 @@ public static function list_table_column_content( $column_name, $post_id ) {
*
* Hooked to the 'post_row_actions' filter.
*
- * @param array $actions An associative array of actions which can be performed on the 'scheduled-action' post type.
+ * @param array $actions An associative array of actions which can be performed on the 'scheduled-action' post type.
+ * @param WP_Post $post The 'scheduled-action' post object.
* @return array $actions An associative array of actions which can be performed on the 'scheduled-action' post type.
*/
public static function row_actions( $actions, $post ) {
@@ -105,8 +111,7 @@ public static function maybe_execute_action() {
*
* Based on Crontrol::interval() function by Edward Dale: https://wordpress.org/plugins/wp-crontrol/
*
- * @param int $interval A interval in seconds.
- * @return string A human friendly string representation of the interval.
+ * @return void
*/
public static function admin_notices() {
_deprecated_function( __METHOD__, '2.0.0' );
@@ -115,20 +120,20 @@ public static function admin_notices() {
/**
* Filter search queries to allow searching by Claim ID (i.e. post_password).
*
- * @param string $orderby MySQL orderby string.
- * @param WP_Query $query Instance of a WP_Query object
- * @return string MySQL orderby string.
+ * @param string $orderby MySQL orderby string.
+ * @param WP_Query $query Instance of a WP_Query object.
+ * @return void
*/
- public function custom_orderby( $orderby, $query ){
+ public function custom_orderby( $orderby, $query ) {
_deprecated_function( __METHOD__, '2.0.0' );
}
/**
* Filter search queries to allow searching by Claim ID (i.e. post_password).
*
- * @param string $search MySQL search string.
- * @param WP_Query $query Instance of a WP_Query object
- * @return string MySQL search string.
+ * @param string $search MySQL search string.
+ * @param WP_Query $query Instance of a WP_Query object.
+ * @return void
*/
public function search_post_password( $search, $query ) {
_deprecated_function( __METHOD__, '2.0.0' );
@@ -137,11 +142,12 @@ public function search_post_password( $search, $query ) {
/**
* Change messages when a scheduled action is updated.
*
- * @param array $messages
+ * @param array $messages Messages.
* @return array
*/
public function post_updated_messages( $messages ) {
_deprecated_function( __METHOD__, '2.0.0' );
return $messages;
}
-}
\ No newline at end of file
+
+}
diff --git a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Schedule_Deprecated.php b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Schedule_Deprecated.php
index 496d67b840..af200bca78 100644
--- a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Schedule_Deprecated.php
+++ b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Schedule_Deprecated.php
@@ -13,7 +13,7 @@ abstract class ActionScheduler_Schedule_Deprecated implements ActionScheduler_Sc
*
* @return DateTime|null
*/
- public function next( DateTime $after = null ) {
+ public function next( ?DateTime $after = null ) {
if ( empty( $after ) ) {
$return_value = $this->get_date();
$replacement_method = 'get_date()';
diff --git a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Store_Deprecated.php b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Store_Deprecated.php
index 002dc75b41..02dc8b7c12 100644
--- a/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Store_Deprecated.php
+++ b/inc/Dependencies/ActionScheduler/deprecated/ActionScheduler_Store_Deprecated.php
@@ -2,6 +2,7 @@
/**
* Class ActionScheduler_Store_Deprecated
+ *
* @codeCoverageIgnore
*/
abstract class ActionScheduler_Store_Deprecated {
diff --git a/inc/Dependencies/ActionScheduler/deprecated/functions.php b/inc/Dependencies/ActionScheduler/deprecated/functions.php
index f782c4b7f0..76ac019561 100644
--- a/inc/Dependencies/ActionScheduler/deprecated/functions.php
+++ b/inc/Dependencies/ActionScheduler/deprecated/functions.php
@@ -1,20 +1,21 @@
'' - the name of the action that will be triggered
* 'args' => NULL - the args array that will be passed with the action
* 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
@@ -113,8 +116,8 @@ function wc_next_scheduled_action( $hook, $args = NULL, $group = '' ) {
* 'per_page' => 5 - Number of results to return
* 'offset' => 0
* 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', or 'date'
- * 'order' => 'ASC'
- * @param string $return_format OBJECT, ARRAY_A, or ids
+ * 'order' => 'ASC'.
+ * @param string $return_format OBJECT, ARRAY_A, or ids.
*
* @deprecated 2.1.0
*
diff --git a/inc/Dependencies/ActionScheduler/functions.php b/inc/Dependencies/ActionScheduler/functions.php
index 66bc54ff53..59e5542c3f 100644
--- a/inc/Dependencies/ActionScheduler/functions.php
+++ b/inc/Dependencies/ActionScheduler/functions.php
@@ -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;
}
@@ -126,6 +127,7 @@ function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
// We expect an integer and allow it to be passed using float and string types, but otherwise
// should reject unexpected values.
+ // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
if ( ! is_numeric( $interval_in_seconds ) || $interval_in_seconds != $interval ) {
_doing_it_wrong(
__METHOD__,
@@ -455,7 +457,7 @@ function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
$actions[ $action_id ] = $store->fetch_action( $action_id );
}
- if ( ARRAY_A == $return_format ) {
+ if ( ARRAY_A === $return_format ) {
foreach ( $actions as $action_id => $action_object ) {
$actions[ $action_id ] = get_object_vars( $action_object );
}
diff --git a/inc/Dependencies/ActionScheduler/lib/WP_Async_Request.php b/inc/Dependencies/ActionScheduler/lib/WP_Async_Request.php
index ff5e29b301..a40c80a1db 100644
--- a/inc/Dependencies/ActionScheduler/lib/WP_Async_Request.php
+++ b/inc/Dependencies/ActionScheduler/lib/WP_Async_Request.php
@@ -4,6 +4,7 @@
*
* @package WP-Background-Processing
*/
+
/*
Library URI: https://github.com/deliciousbrains/wp-background-processing/blob/fbbc56f2480910d7959972ec9ec0819a13c6150a/classes/wp-async-request.php
Author: Delicious Brains Inc.
@@ -27,7 +28,6 @@ abstract class WP_Async_Request {
* (default value: 'wp')
*
* @var string
- * @access protected
*/
protected $prefix = 'wp';
@@ -37,7 +37,6 @@ abstract class WP_Async_Request {
* (default value: 'async_request')
*
* @var string
- * @access protected
*/
protected $action = 'async_request';
@@ -45,7 +44,6 @@ abstract class WP_Async_Request {
* Identifier
*
* @var mixed
- * @access protected
*/
protected $identifier;
@@ -55,7 +53,6 @@ abstract class WP_Async_Request {
* (default value: array())
*
* @var array
- * @access protected
*/
protected $data = array();
@@ -169,7 +166,7 @@ protected function get_post_args() {
* Check for correct nonce and pass to handler.
*/
public function maybe_handle() {
- // Don't lock up other requests while processing
+ // Don't lock up other requests while processing.
session_write_close();
check_ajax_referer( $this->identifier, 'nonce' );
diff --git a/inc/Dependencies/ActionScheduler/lib/cron-expression/CronExpression.php b/inc/Dependencies/ActionScheduler/lib/cron-expression/CronExpression.php
index 7f33c378f9..33040eddfe 100644
--- a/inc/Dependencies/ActionScheduler/lib/cron-expression/CronExpression.php
+++ b/inc/Dependencies/ActionScheduler/lib/cron-expression/CronExpression.php
@@ -54,7 +54,7 @@ class CronExpression
*
* @return CronExpression
*/
- public static function factory($expression, CronExpression_FieldFactory $fieldFactory = null)
+ public static function factory($expression, ?CronExpression_FieldFactory $fieldFactory = null)
{
$mappings = array(
'@yearly' => '0 0 1 1 *',
diff --git a/inc/Dependencies/ActionScheduler/readme.txt b/inc/Dependencies/ActionScheduler/readme.txt
index d2ee033bf3..359747638e 100644
--- a/inc/Dependencies/ActionScheduler/readme.txt
+++ b/inc/Dependencies/ActionScheduler/readme.txt
@@ -1,11 +1,11 @@
=== 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.9.1
License: GPLv3
-Requires at least: 6.3
+Requires at least: 6.5
Tested up to: 6.5
-Requires PHP: 7.0
+Requires PHP: 7.1
Action Scheduler - Job Queue for WordPress
@@ -47,6 +47,27 @@ Collaboration is cool. We'd love to work with you to improve Action Scheduler. [
== Changelog ==
+= 3.9.1 - 2025-01-21 =
+* A number of new WP CLI commands have been added, making it easier to manage actions in the terminal and from scripts.
+* New wp action-scheduler source command to help determine how Action Scheduler is being loaded.
+* Additional information about the active instance of Action Scheduler is now available in the Help pull-down drawer.
+* Make some other nullable parameters explicitly nullable.
+* Set option value to `no` rather than deleting.
+
+= 3.9.0 - 2024-11-14 =
+* Minimum required version of PHP is now 7.1.
+* Performance improvements for the `as_pending_actions_due()` function.
+* Existing filter hook `action_scheduler_claim_actions_order_by` enhanced to provide callbacks with additional information.
+* Improved compatibility with PHP 8.4, specifically by making implicitly nullable parameters explicitly nullable.
+* A large number of coding standards-enhancements, to help reduce friction when submitting plugins to marketplaces and plugin directories. Special props @crstauf for this effort.
+* Minor documentation tweaks and improvements.
+
+= 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.
diff --git a/inc/Engine/Common/Cache/FilesystemCache.php b/inc/Engine/Common/Cache/FilesystemCache.php
index ee6fbc7602..7096898174 100644
--- a/inc/Engine/Common/Cache/FilesystemCache.php
+++ b/inc/Engine/Common/Cache/FilesystemCache.php
@@ -27,7 +27,7 @@ class FilesystemCache implements CacheInterface {
* @param string $root_folder Root folder from the path.
* @param WP_Filesystem_Direct|null $filesystem WordPress filesystem.
*/
- public function __construct( string $root_folder, WP_Filesystem_Direct $filesystem = null ) {
+ public function __construct( string $root_folder, ?WP_Filesystem_Direct $filesystem = null ) {
$this->root_folder = $root_folder;
$this->filesystem = $filesystem ?: rocket_direct_filesystem();
}
diff --git a/inc/Engine/Common/PerformanceHints/Frontend/Processor.php b/inc/Engine/Common/PerformanceHints/Frontend/Processor.php
index 4540404392..8b9d24dcf8 100644
--- a/inc/Engine/Common/PerformanceHints/Frontend/Processor.php
+++ b/inc/Engine/Common/PerformanceHints/Frontend/Processor.php
@@ -36,7 +36,7 @@ class Processor {
* @param Options_Data $options Options instance.
* @param WP_Filesystem_Direct|null $filesystem WordPress filesystem.
*/
- public function __construct( array $factories, Options_Data $options, WP_Filesystem_Direct $filesystem = null ) {
+ public function __construct( array $factories, Options_Data $options, ?WP_Filesystem_Direct $filesystem = null ) {
$this->factories = $factories;
$this->options = $options;
$this->filesystem = $filesystem ?: rocket_direct_filesystem();
diff --git a/inc/Engine/Common/Queue/Cleaner.php b/inc/Engine/Common/Queue/Cleaner.php
index 124257c9ca..ae351e3434 100644
--- a/inc/Engine/Common/Queue/Cleaner.php
+++ b/inc/Engine/Common/Queue/Cleaner.php
@@ -46,7 +46,7 @@ class Cleaner extends ActionScheduler_QueueCleaner {
* @param int $batch_size The batch size.
* @param string $group Current queue group.
*/
- public function __construct( ActionScheduler_Store $store = null, $batch_size = 20, $group = '' ) {
+ public function __construct( ?ActionScheduler_Store $store = null, $batch_size = 20, $group = '' ) {
parent::__construct( $store, $batch_size );
$this->store = $store ? $store : ActionScheduler_Store::instance();
$this->group = $group;
diff --git a/inc/Engine/Common/Queue/RUCSSQueueRunner.php b/inc/Engine/Common/Queue/RUCSSQueueRunner.php
index b1aad54c51..2af712f130 100644
--- a/inc/Engine/Common/Queue/RUCSSQueueRunner.php
+++ b/inc/Engine/Common/Queue/RUCSSQueueRunner.php
@@ -5,6 +5,9 @@
use WP_Rocket\Logger\Logger;
use ActionScheduler_Abstract_QueueRunner;
+use ActionScheduler_Store;
+use ActionScheduler_FatalErrorMonitor;
+use ActionScheduler_AsyncRequest_QueueRunner;
class RUCSSQueueRunner extends ActionScheduler_Abstract_QueueRunner {
@@ -55,12 +58,12 @@ public static function instance() {
/**
* ActionScheduler_QueueRunner constructor.
*
- * @param \ActionScheduler_Store|null $store Store Instance.
- * @param \ActionScheduler_FatalErrorMonitor|null $monitor Fatal Error monitor instance.
- * @param Cleaner|null $cleaner Cleaner instance.
- * @param \ActionScheduler_AsyncRequest_QueueRunner|null $async_request Async Request Queue Runner instance.
+ * @param ActionScheduler_Store|null $store Store Instance.
+ * @param ActionScheduler_FatalErrorMonitor|null $monitor Fatal Error monitor instance.
+ * @param Cleaner|null $cleaner Cleaner instance.
+ * @param ActionScheduler_AsyncRequest_QueueRunner|null $async_request Async Request Queue Runner instance.
*/
- public function __construct( \ActionScheduler_Store $store = null, \ActionScheduler_FatalErrorMonitor $monitor = null, Cleaner $cleaner = null, \ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) {
+ public function __construct( ?ActionScheduler_Store $store = null, ?ActionScheduler_FatalErrorMonitor $monitor = null, ?Cleaner $cleaner = null, ?ActionScheduler_AsyncRequest_QueueRunner $async_request = null ) {
if ( is_null( $cleaner ) ) {
/**
* Filters the clean batch size.
diff --git a/inc/Engine/Media/Lazyload/CSS/Front/ContentFetcher.php b/inc/Engine/Media/Lazyload/CSS/Front/ContentFetcher.php
index fc04878851..9425dca9d2 100644
--- a/inc/Engine/Media/Lazyload/CSS/Front/ContentFetcher.php
+++ b/inc/Engine/Media/Lazyload/CSS/Front/ContentFetcher.php
@@ -19,9 +19,9 @@ class ContentFetcher {
/**
* Instance.
*
- * @param WP_Filesystem_Direct $filesystem WordPress filesystem.
+ * @param WP_Filesystem_Direct|null $filesystem WordPress filesystem.
*/
- public function __construct( WP_Filesystem_Direct $filesystem = null ) {
+ public function __construct( ?WP_Filesystem_Direct $filesystem = null ) {
$this->filesystem = $filesystem ?: rocket_direct_filesystem();
}
diff --git a/inc/Engine/Media/Lazyload/CSS/Subscriber.php b/inc/Engine/Media/Lazyload/CSS/Subscriber.php
index bd3051d6a7..4badab49bd 100644
--- a/inc/Engine/Media/Lazyload/CSS/Subscriber.php
+++ b/inc/Engine/Media/Lazyload/CSS/Subscriber.php
@@ -118,7 +118,7 @@ class Subscriber implements Subscriber_Interface, LoggerAwareInterface {
* @param LazyloadCSSContentFactory $lazyloaded_content_factory Make LazyloadedContent instance.
* @param WP_Filesystem_Direct|null $filesystem WordPress filesystem.
*/
- public function __construct( Extractor $extractor, RuleFormatter $rule_formatter, FileResolver $file_resolver, CacheInterface $cache, MappingFormatter $mapping_formatter, TagGenerator $tag_generator, ContentFetcher $fetcher, ContextInterface $context, Options_Data $options, LazyloadCSSContentFactory $lazyloaded_content_factory, WP_Filesystem_Direct $filesystem = null ) {
+ public function __construct( Extractor $extractor, RuleFormatter $rule_formatter, FileResolver $file_resolver, CacheInterface $cache, MappingFormatter $mapping_formatter, TagGenerator $tag_generator, ContentFetcher $fetcher, ContextInterface $context, Options_Data $options, LazyloadCSSContentFactory $lazyloaded_content_factory, ?WP_Filesystem_Direct $filesystem = null ) {
$this->extractor = $extractor;
$this->cache = $cache;
$this->rule_formatter = $rule_formatter;
diff --git a/inc/ThirdParty/Plugins/I18n/WPML.php b/inc/ThirdParty/Plugins/I18n/WPML.php
index 7a82910e92..055fe32d9e 100644
--- a/inc/ThirdParty/Plugins/I18n/WPML.php
+++ b/inc/ThirdParty/Plugins/I18n/WPML.php
@@ -22,9 +22,9 @@ class WPML implements Subscriber_Interface {
/**
* Instantiate class.
*
- * @param WP_Filesystem_Direct $filesystem Filesystem instance.
+ * @param WP_Filesystem_Direct|null $filesystem Filesystem instance.
*/
- public function __construct( WP_Filesystem_Direct $filesystem = null ) {
+ public function __construct( ?WP_Filesystem_Direct $filesystem = null ) {
$this->filesystem = ! empty( $filesystem ) ? $filesystem : rocket_direct_filesystem();
}