plugin updates
This commit is contained in:
@@ -5,8 +5,11 @@
|
||||
* Description: A robust scheduling library for use in WordPress plugins.
|
||||
* Author: Automattic
|
||||
* Author URI: https://automattic.com/
|
||||
* Version: 3.6.1
|
||||
* Version: 3.7.1
|
||||
* License: GPLv3
|
||||
* Requires at least: 6.2
|
||||
* Tested up to: 6.4
|
||||
* Requires PHP: 5.6
|
||||
*
|
||||
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
||||
*
|
||||
@@ -26,27 +29,29 @@
|
||||
* @package ActionScheduler
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'action_scheduler_register_3_dot_6_dot_1' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.
|
||||
if ( ! function_exists( 'action_scheduler_register_3_dot_7_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_6_dot_1', 0, 0 ); // WRCS: DEFINED_VERSION.
|
||||
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_7_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_6_dot_1() { // WRCS: DEFINED_VERSION.
|
||||
function action_scheduler_register_3_dot_7_dot_1() { // WRCS: DEFINED_VERSION.
|
||||
$versions = ActionScheduler_Versions::instance();
|
||||
$versions->register( '3.6.1', 'action_scheduler_initialize_3_dot_6_dot_1' ); // WRCS: DEFINED_VERSION.
|
||||
$versions->register( '3.7.1', 'action_scheduler_initialize_3_dot_7_dot_1' ); // WRCS: DEFINED_VERSION.
|
||||
}
|
||||
|
||||
// phpcs:disable Generic.Functions.OpeningFunctionBraceKernighanRitchie.ContentAfterBrace
|
||||
/**
|
||||
* Initializes this version of Action Scheduler.
|
||||
*/
|
||||
function action_scheduler_initialize_3_dot_6_dot_1() { // WRCS: DEFINED_VERSION.
|
||||
function action_scheduler_initialize_3_dot_7_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).
|
||||
@@ -58,7 +63,7 @@ if ( ! function_exists( 'action_scheduler_register_3_dot_6_dot_1' ) && function_
|
||||
|
||||
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
||||
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
|
||||
action_scheduler_initialize_3_dot_6_dot_1(); // WRCS: DEFINED_VERSION.
|
||||
action_scheduler_initialize_3_dot_7_dot_1(); // WRCS: DEFINED_VERSION.
|
||||
do_action( 'action_scheduler_pre_theme_init' );
|
||||
ActionScheduler_Versions::initialize_latest_version();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
*** Changelog ***
|
||||
|
||||
= 3.7.1 - 2023-12-13 =
|
||||
* Release/3.7.0.
|
||||
* Tweak - WP 6.4 compatibility.
|
||||
* update semver to 5.7.2 because of a security vulnerability in 5.7.1.
|
||||
|
||||
= 3.7.0 - 2023-11-20 =
|
||||
* Important: starting with this release, Action Scheduler follows an L-2 version policy (WordPress, and consequently PHP).
|
||||
* Add extended indexes for hook_status_scheduled_date_gmt and status_sheduled_date_gmt.
|
||||
* Catch and log exceptions thrown when actions can't be created, e.g. under a corrupt database schema.
|
||||
* Release/3.6.4.
|
||||
* Tweak - WP 6.4 compatibility.
|
||||
* Update unit tests for upcoming dependency version policy.
|
||||
* make sure hook action_scheduler_failed_execution can access original exception object.
|
||||
* mention dependency version policy in usage.md.
|
||||
|
||||
= 3.6.4 - 2023-10-11 =
|
||||
* Performance improvements when bulk cancelling actions.
|
||||
* Dev-related fixes.
|
||||
|
||||
= 3.6.3 - 2023-09-13 =
|
||||
* Use `_doing_it_wrong` in initialization check.
|
||||
|
||||
= 3.6.2 - 2023-08-09 =
|
||||
* Add guidance about passing arguments.
|
||||
* Atomic option locking.
|
||||
* Improve bulk delete handling.
|
||||
* Include database error in the exception message.
|
||||
* Tweak - WP 6.3 compatibility.
|
||||
|
||||
= 3.6.1 - 2023-06-14 =
|
||||
* Document new optional `$priority` arg for various API functions.
|
||||
* Document the new `--exclude-groups` WP CLI option.
|
||||
|
||||
@@ -13,6 +13,7 @@ class ActionScheduler_ActionFactory {
|
||||
* @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.
|
||||
* phpcs:ignore Squiz.Commenting.FunctionComment.ExtraParamComment
|
||||
* @param int $priority The action priority.
|
||||
*
|
||||
* @return ActionScheduler_Action An instance of the stored action.
|
||||
@@ -246,7 +247,6 @@ class ActionScheduler_ActionFactory {
|
||||
* async_unique(), single() or single_unique(), etc.
|
||||
*
|
||||
* @internal Not intended for public use, should not be overriden by subclasses.
|
||||
* @throws Exception May be thrown if invalid options are passed.
|
||||
*
|
||||
* @param array $options {
|
||||
* Describes the action we wish to schedule.
|
||||
@@ -263,7 +263,7 @@ class ActionScheduler_ActionFactory {
|
||||
* @type int $priority Lower values means higher priority. Should be in the range 0-255.
|
||||
* }
|
||||
*
|
||||
* @return int
|
||||
* @return int The action ID. Zero if there was an error scheduling the action.
|
||||
*/
|
||||
public function create( array $options = array() ) {
|
||||
$defaults = array(
|
||||
@@ -307,12 +307,27 @@ class ActionScheduler_ActionFactory {
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception( "Unknown action type '{$options['type']}' specified when trying to create an action for '{$options['hook']}'." );
|
||||
error_log( "Unknown action type '{$options['type']}' specified when trying to create an action for '{$options['hook']}'." );
|
||||
return 0;
|
||||
}
|
||||
|
||||
$action = new ActionScheduler_Action( $options['hook'], $options['arguments'], $schedule, $options['group'] );
|
||||
$action->set_priority( $options['priority'] );
|
||||
return $options['unique'] ? $this->store_unique_action( $action ) : $this->store( $action );
|
||||
|
||||
$action_id = 0;
|
||||
try {
|
||||
$action_id = $options['unique'] ? $this->store_unique_action( $action ) : $this->store( $action );
|
||||
} catch ( Exception $e ) {
|
||||
error_log(
|
||||
sprintf(
|
||||
/* translators: %1$s is the name of the hook to be enqueued, %2$s is the exception message. */
|
||||
__( 'Caught exception while enqueuing action "%1$s": %2$s', 'action-scheduler' ),
|
||||
$options['hook'],
|
||||
$e->getMessage()
|
||||
)
|
||||
);
|
||||
}
|
||||
return $action_id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -502,7 +502,20 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
||||
*/
|
||||
protected function bulk_delete( array $ids, $ids_sql ) {
|
||||
foreach ( $ids as $id ) {
|
||||
$this->store->delete_action( $id );
|
||||
try {
|
||||
$this->store->delete_action( $id );
|
||||
} catch ( Exception $e ) {
|
||||
// A possible reason for an exception would include a scenario where the same action is deleted by a
|
||||
// concurrent request.
|
||||
error_log(
|
||||
sprintf(
|
||||
/* translators: 1: action ID 2: exception message. */
|
||||
__( 'Action Scheduler was unable to delete action %1$d. Reason: %2$s', 'action-scheduler' ),
|
||||
$id,
|
||||
$e->getMessage()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,37 @@ class ActionScheduler_OptionLock extends ActionScheduler_Lock {
|
||||
* @bool True if lock value has changed, false if not or if set failed.
|
||||
*/
|
||||
public function set( $lock_type ) {
|
||||
return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) );
|
||||
global $wpdb;
|
||||
|
||||
$lock_key = $this->get_key( $lock_type );
|
||||
$existing_lock_value = $this->get_existing_lock( $lock_type );
|
||||
$new_lock_value = $this->new_lock_value( $lock_type );
|
||||
|
||||
// The lock may not exist yet, or may have been deleted.
|
||||
if ( empty( $existing_lock_value ) ) {
|
||||
return (bool) $wpdb->insert(
|
||||
$wpdb->options,
|
||||
array(
|
||||
'option_name' => $lock_key,
|
||||
'option_value' => $new_lock_value,
|
||||
'autoload' => 'no',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->get_expiration_from( $existing_lock_value ) >= time() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, try to obtain the lock.
|
||||
return (bool) $wpdb->update(
|
||||
$wpdb->options,
|
||||
array( 'option_value' => $new_lock_value ),
|
||||
array(
|
||||
'option_name' => $lock_key,
|
||||
'option_value' => $existing_lock_value,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +64,30 @@ class ActionScheduler_OptionLock extends ActionScheduler_Lock {
|
||||
* @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire.
|
||||
*/
|
||||
public function get_expiration( $lock_type ) {
|
||||
return get_option( $this->get_key( $lock_type ) );
|
||||
return $this->get_expiration_from( $this->get_existing_lock( $lock_type ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the lock string, derives the lock expiration timestamp (or false if it cannot be determined).
|
||||
*
|
||||
* @param string $lock_value String containing a timestamp, or pipe-separated combination of unique value and timestamp.
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
private function get_expiration_from( $lock_value ) {
|
||||
$lock_string = explode( '|', $lock_value );
|
||||
|
||||
// Old style lock?
|
||||
if ( count( $lock_string ) === 1 && is_numeric( $lock_string[0] ) ) {
|
||||
return (int) $lock_string[0];
|
||||
}
|
||||
|
||||
// New style lock?
|
||||
if ( count( $lock_string ) === 2 && is_numeric( $lock_string[1] ) ) {
|
||||
return (int) $lock_string[1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,4 +99,37 @@ class ActionScheduler_OptionLock extends ActionScheduler_Lock {
|
||||
protected function get_key( $lock_type ) {
|
||||
return sprintf( 'action_scheduler_lock_%s', $lock_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplies the existing lock value, or an empty string if not set.
|
||||
*
|
||||
* @param string $lock_type A string to identify different lock types.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_existing_lock( $lock_type ) {
|
||||
global $wpdb;
|
||||
|
||||
// Now grab the existing lock value, if there is one.
|
||||
return (string) $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT option_value FROM $wpdb->options WHERE option_name = %s",
|
||||
$this->get_key( $lock_type )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplies a lock value consisting of a unique value and the current timestamp, which are separated by a pipe
|
||||
* character.
|
||||
*
|
||||
* Example: (string) "649de012e6b262.09774912|1688068114"
|
||||
*
|
||||
* @param string $lock_type A string to identify different lock types.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function new_lock_value( $lock_type ) {
|
||||
return uniqid( '', true ) . '|' . ( time() + $this->get_duration( $lock_type ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +103,12 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
|
||||
* should dispatch a request to process pending actions.
|
||||
*/
|
||||
public function maybe_dispatch_async_request() {
|
||||
if ( is_admin() && ! ActionScheduler::lock()->is_locked( 'async-request-runner' ) ) {
|
||||
// Only start an async queue at most once every 60 seconds
|
||||
ActionScheduler::lock()->set( 'async-request-runner' );
|
||||
// Only start an async queue at most once every 60 seconds.
|
||||
if (
|
||||
is_admin()
|
||||
&& ! ActionScheduler::lock()->is_locked( 'async-request-runner' )
|
||||
&& ActionScheduler::lock()->set( 'async-request-runner' )
|
||||
) {
|
||||
$this->async_request->maybe_dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ abstract class ActionScheduler {
|
||||
__( '%s() was called before the Action Scheduler data store was initialized', 'action-scheduler' ),
|
||||
esc_attr( $function_name )
|
||||
);
|
||||
error_log( $message );
|
||||
_doing_it_wrong( $function_name, $message, '3.1.6' );
|
||||
}
|
||||
|
||||
return self::$data_store_initialized;
|
||||
|
||||
@@ -91,7 +91,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
|
||||
} catch ( Throwable $e ) {
|
||||
// Throwable is defined when executing under PHP 7.0 and up. We convert it to an exception, for
|
||||
// compatibility with ActionScheduler_Logger.
|
||||
throw new Exception( $e->getMessage(), $e->getCode(), $e->getPrevious() );
|
||||
throw new Exception( $e->getMessage(), $e->getCode(), $e );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
// This catch block exists for compatibility with PHP 5.6.
|
||||
|
||||
@@ -26,6 +26,8 @@ abstract class ActionScheduler_Lock {
|
||||
/**
|
||||
* Set a lock.
|
||||
*
|
||||
* To prevent race conditions, implementations should avoid setting the lock if the lock is already held.
|
||||
*
|
||||
* @param string $lock_type A string to identify different lock types.
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -347,7 +347,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
||||
'hook' => $hook,
|
||||
'status' => self::STATUS_PENDING,
|
||||
'per_page' => 1000,
|
||||
'orderby' => 'action_id',
|
||||
'orderby' => 'none',
|
||||
)
|
||||
);
|
||||
|
||||
@@ -372,7 +372,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
||||
'group' => $group,
|
||||
'status' => self::STATUS_PENDING,
|
||||
'per_page' => 1000,
|
||||
'orderby' => 'action_id',
|
||||
'orderby' => 'none',
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class ActionScheduler_DBLogger extends ActionScheduler_Logger {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the an action's log entries from the database.
|
||||
* Retrieve an action's log entries from the database.
|
||||
*
|
||||
* @param int $action_id Action ID.
|
||||
*
|
||||
|
||||
@@ -705,7 +705,7 @@ AND `group_id` = %d
|
||||
array(
|
||||
'per_page' => 1000,
|
||||
'status' => self::STATUS_PENDING,
|
||||
'orderby' => 'action_id',
|
||||
'orderby' => 'none',
|
||||
)
|
||||
);
|
||||
|
||||
@@ -935,7 +935,17 @@ AND `group_id` = %d
|
||||
$sql = $wpdb->prepare( "{$update} {$where} {$order} LIMIT %d", $params ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders
|
||||
$rows_affected = $wpdb->query( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
||||
if ( false === $rows_affected ) {
|
||||
throw new \RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
|
||||
$error = empty( $wpdb->last_error )
|
||||
? _x( 'unknown', 'database error', 'action-scheduler' )
|
||||
: $wpdb->last_error;
|
||||
|
||||
throw new \RuntimeException(
|
||||
sprintf(
|
||||
/* translators: %s database error. */
|
||||
__( 'Unable to claim actions. Database error: %s.', 'action-scheduler' ),
|
||||
$error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $rows_affected;
|
||||
|
||||
@@ -38,6 +38,7 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
|
||||
$table_name = $wpdb->$table;
|
||||
$charset_collate = $wpdb->get_charset_collate();
|
||||
$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 ) {
|
||||
|
||||
@@ -59,8 +60,8 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
|
||||
claim_id bigint(20) unsigned NOT NULL default '0',
|
||||
extended_args varchar(8000) DEFAULT NULL,
|
||||
PRIMARY KEY (action_id),
|
||||
KEY hook (hook($max_index_length)),
|
||||
KEY status (status),
|
||||
KEY hook_status_scheduled_date_gmt (hook($hook_status_scheduled_date_gmt_max_index_length), status, scheduled_date_gmt),
|
||||
KEY status_scheduled_date_gmt (status, scheduled_date_gmt),
|
||||
KEY scheduled_date_gmt (scheduled_date_gmt),
|
||||
KEY args (args($max_index_length)),
|
||||
KEY group_id (group_id),
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* @param bool $unique Whether the action should be unique.
|
||||
* @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
|
||||
*
|
||||
* @return int The action ID.
|
||||
* @return int The action ID. Zero if there was an error scheduling the action.
|
||||
*/
|
||||
function as_enqueue_async_action( $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
@@ -63,7 +63,7 @@ function as_enqueue_async_action( $hook, $args = array(), $group = '', $unique =
|
||||
* @param bool $unique Whether the action should be unique.
|
||||
* @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
|
||||
*
|
||||
* @return int The action ID.
|
||||
* @return int The action ID. Zero if there was an error scheduling the action.
|
||||
*/
|
||||
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
@@ -115,7 +115,7 @@ function as_schedule_single_action( $timestamp, $hook, $args = array(), $group =
|
||||
* @param bool $unique Whether the action should be unique.
|
||||
* @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
|
||||
*
|
||||
* @return int The action ID.
|
||||
* @return int The action ID. Zero if there was an error scheduling the action.
|
||||
*/
|
||||
function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
@@ -200,7 +200,7 @@ function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
|
||||
* @param bool $unique Whether the action should be unique.
|
||||
* @param int $priority Lower values take precedence over higher values. Defaults to 10, with acceptable values falling in the range 0-255.
|
||||
*
|
||||
* @return int The action ID.
|
||||
* @return int The action ID. Zero if there was an error scheduling the action.
|
||||
*/
|
||||
function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '', $unique = false, $priority = 10 ) {
|
||||
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
||||
@@ -283,9 +283,10 @@ function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
||||
ActionScheduler::logger()->log(
|
||||
$action_id,
|
||||
sprintf(
|
||||
/* translators: %s is the name of the hook to be cancelled. */
|
||||
__( 'Caught exception while cancelling action: %s', 'action-scheduler' ),
|
||||
esc_attr( $hook )
|
||||
/* translators: %1$s is the name of the hook to be cancelled, %2$s is the exception message. */
|
||||
__( 'Caught exception while cancelling action "%1$s": %2$s', 'action-scheduler' ),
|
||||
$hook,
|
||||
$exception->getMessage()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
=== Action Scheduler ===
|
||||
Contributors: Automattic, wpmuguru, claudiosanches, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, royho, barryhughes-1
|
||||
Tags: scheduler, cron
|
||||
Requires at least: 5.2
|
||||
Tested up to: 6.0
|
||||
Stable tag: 3.6.1
|
||||
Stable tag: 3.7.1
|
||||
License: GPLv3
|
||||
Requires at least: 6.2
|
||||
Tested up to: 6.4
|
||||
Requires PHP: 5.6
|
||||
|
||||
Action Scheduler - Job Queue for WordPress
|
||||
@@ -47,6 +47,35 @@ Collaboration is cool. We'd love to work with you to improve Action Scheduler. [
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.7.1 - 2023-12-13 =
|
||||
* Release/3.7.0.
|
||||
* Tweak - WP 6.4 compatibility.
|
||||
* update semver to 5.7.2 because of a security vulnerability in 5.7.1.
|
||||
|
||||
= 3.7.0 - 2023-11-20 =
|
||||
* Important: starting with this release, Action Scheduler follows an L-2 version policy (WordPress, and consequently PHP).
|
||||
* Add extended indexes for hook_status_scheduled_date_gmt and status_sheduled_date_gmt.
|
||||
* Catch and log exceptions thrown when actions can't be created, e.g. under a corrupt database schema.
|
||||
* Release/3.6.4.
|
||||
* Tweak - WP 6.4 compatibility.
|
||||
* Update unit tests for upcoming dependency version policy.
|
||||
* make sure hook action_scheduler_failed_execution can access original exception object.
|
||||
* mention dependency version policy in usage.md.
|
||||
|
||||
= 3.6.4 - 2023-10-11 =
|
||||
* Performance improvements when bulk cancelling actions.
|
||||
* Dev-related fixes.
|
||||
|
||||
= 3.6.3 - 2023-09-13 =
|
||||
* Use `_doing_it_wrong` in initialization check.
|
||||
|
||||
= 3.6.2 - 2023-08-09 =
|
||||
* Add guidance about passing arguments.
|
||||
* Atomic option locking.
|
||||
* Improve bulk delete handling.
|
||||
* Include database error in the exception message.
|
||||
* Tweak - WP 6.3 compatibility.
|
||||
|
||||
= 3.6.1 - 2023-06-14 =
|
||||
* Document new optional `$priority` arg for various API functions.
|
||||
* Document the new `--exclude-groups` WP CLI option.
|
||||
|
||||
Reference in New Issue
Block a user