Version Description
Download this release
Release Info
Developer | ryanhungate |
Plugin | MailChimp for WooCommerce |
Version | 2.7.6 |
Comparing to | |
See all releases |
Code changes from version 2.7.5 to 2.7.6
- CHANGELOG.txt +4 -0
- README.txt +6 -5
- blocks/woocommerce-blocks-integration.php +4 -1
- bootstrap.php +1 -1
- includes/api/class-mailchimp-woocommerce-log-viewer.php +10 -1
- includes/api/class-mailchimp-woocommerce-logs.php +3 -0
- includes/api/class-mailchimp-woocommerce-tower.php +10 -1
- includes/api/class-mailchimp-woocommerce-transform-coupons.php +1 -1
- includes/api/class-mailchimp-woocommerce-transform-products.php +2 -2
- includes/vendor/action-scheduler/action-scheduler.php +7 -7
- includes/vendor/action-scheduler/classes/ActionScheduler_ActionFactory.php +132 -49
- includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php +91 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_DateTime.php +3 -0
- includes/vendor/action-scheduler/classes/ActionScheduler_Exception.php +1 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php +15 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_QueueRunner.php +25 -6
- includes/vendor/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php +30 -0
- includes/vendor/action-scheduler/classes/WP_CLI/ProgressBar.php +1 -1
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php +2 -2
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php +1 -1
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php +58 -0
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php +1 -1
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Store.php +30 -2
- includes/vendor/action-scheduler/classes/actions/ActionScheduler_Action.php +22 -1
- includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php +158 -20
- includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php +10 -1
- includes/vendor/action-scheduler/classes/migration/ActionMigrator.php +4 -4
- includes/vendor/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php +4 -4
- includes/vendor/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php +7 -7
- includes/vendor/action-scheduler/functions.php +76 -56
- includes/vendor/action-scheduler/lib/WP_Async_Request.php +24 -3
- mailchimp-woocommerce.php +2 -2
- public/class-mailchimp-woocommerce-public.php +1 -1
CHANGELOG.txt
CHANGED
@@ -1,4 +1,8 @@
|
|
1 |
== Changelog ==
|
|
|
|
|
|
|
|
|
2 |
= 2.7.5 =
|
3 |
* fix admin subscription status checkbox flow
|
4 |
* remove support flag on plugin uninstall
|
1 |
== Changelog ==
|
2 |
+
= 2.7.6 =
|
3 |
+
* deprecated ExtendRestAPI filling logs
|
4 |
+
* update action scheduler version
|
5 |
+
* fix for saving profile unsubscribes
|
6 |
= 2.7.5 =
|
7 |
* fix admin subscription status checkbox flow
|
8 |
* remove support flag on plugin uninstall
|
README.txt
CHANGED
@@ -4,10 +4,10 @@ Tags: ecommerce,email,workflows,mailchimp
|
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 6.0
|
7 |
-
Stable tag: 2.7.
|
8 |
Requires PHP: 7.4
|
9 |
WC requires at least: 3.5
|
10 |
-
WC tested up to:
|
11 |
License: GPLv2 or later
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
13 |
Connect your store to your Mailchimp audience to track sales, create targeted emails, send abandoned cart emails, and more.
|
@@ -78,8 +78,9 @@ At this time, the synchronization of product categories from WooCommerce to Mail
|
|
78 |
If you are unable to sync or connect with Mailchimp, you can open a ticket on our [Github plugin page](https://github.com/mailchimp/mc-woocommerce/issues). Please provide the version of the plugin and PHP you're using, any fatal errors in the WooCommerce logs (WooCommerce -> Status -> Logs) you're seeing, along with relevant information to the problem you're experiencing.
|
79 |
|
80 |
== Changelog ==
|
81 |
-
= 2.7.
|
82 |
-
*
|
83 |
-
*
|
|
|
84 |
|
85 |
[Historical Changelog](https://raw.githubusercontent.com/mailchimp/mc-woocommerce/master/CHANGELOG.txt)
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 6.0
|
7 |
+
Stable tag: 2.7.6
|
8 |
Requires PHP: 7.4
|
9 |
WC requires at least: 3.5
|
10 |
+
WC tested up to: 7.1
|
11 |
License: GPLv2 or later
|
12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
13 |
Connect your store to your Mailchimp audience to track sales, create targeted emails, send abandoned cart emails, and more.
|
78 |
If you are unable to sync or connect with Mailchimp, you can open a ticket on our [Github plugin page](https://github.com/mailchimp/mc-woocommerce/issues). Please provide the version of the plugin and PHP you're using, any fatal errors in the WooCommerce logs (WooCommerce -> Status -> Logs) you're seeing, along with relevant information to the problem you're experiencing.
|
79 |
|
80 |
== Changelog ==
|
81 |
+
= 2.7.6 =
|
82 |
+
* Deprecated ExtendRestAPI filling logs
|
83 |
+
* update action scheduler version
|
84 |
+
* fix for saving profile unsubscribes
|
85 |
|
86 |
[Historical Changelog](https://raw.githubusercontent.com/mailchimp/mc-woocommerce/master/CHANGELOG.txt)
|
blocks/woocommerce-blocks-integration.php
CHANGED
@@ -4,6 +4,8 @@ use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;
|
|
4 |
use Automattic\WooCommerce\Blocks\Package;
|
5 |
use Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi;
|
6 |
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;
|
|
|
|
|
7 |
defined( 'ABSPATH' ) || exit;
|
8 |
|
9 |
/**
|
@@ -177,7 +179,8 @@ class Mailchimp_Woocommerce_Newsletter_Blocks_Integration implements Integration
|
|
177 |
public function extend_store_api()
|
178 |
{
|
179 |
/** @var ExtendRestApi $extend */
|
180 |
-
|
|
|
181 |
|
182 |
$extend->register_endpoint_data(
|
183 |
array(
|
4 |
use Automattic\WooCommerce\Blocks\Package;
|
5 |
use Automattic\WooCommerce\Blocks\Domain\Services\ExtendRestApi;
|
6 |
use Automattic\WooCommerce\Blocks\StoreApi\Schemas\CheckoutSchema;
|
7 |
+
use Automattic\WooCommerce\StoreApi\StoreApi;
|
8 |
+
use Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema;
|
9 |
defined( 'ABSPATH' ) || exit;
|
10 |
|
11 |
/**
|
179 |
public function extend_store_api()
|
180 |
{
|
181 |
/** @var ExtendRestApi $extend */
|
182 |
+
/** @var ExtendSchema $extend */
|
183 |
+
$extend = class_exists('Automattic\WooCommerce\StoreApi\Schemas\ExtendSchema') ? StoreApi::container()->get(ExtendSchema::class) : Package::container()->get(ExtendRestApi::class);
|
184 |
|
185 |
$extend->register_endpoint_data(
|
186 |
array(
|
bootstrap.php
CHANGED
@@ -94,7 +94,7 @@ function mailchimp_environment_variables() {
|
|
94 |
return (object) array(
|
95 |
'repo' => 'master',
|
96 |
'environment' => 'production', // staging or production
|
97 |
-
'version' => '2.7.
|
98 |
'php_version' => phpversion(),
|
99 |
'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
|
100 |
'wc_version' => function_exists('WC') ? WC()->version : null,
|
94 |
return (object) array(
|
95 |
'repo' => 'master',
|
96 |
'environment' => 'production', // staging or production
|
97 |
+
'version' => '2.7.6',
|
98 |
'php_version' => phpversion(),
|
99 |
'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
|
100 |
'wc_version' => function_exists('WC') ? WC()->version : null,
|
includes/api/class-mailchimp-woocommerce-log-viewer.php
CHANGED
@@ -158,7 +158,7 @@ class MailChimp_WooCommerce_Log_Viewer {
|
|
158 |
$files = array_filter(
|
159 |
$files,
|
160 |
function( $value ) {
|
161 |
-
return static::stringEndsWith( $value, '.log' );
|
162 |
}
|
163 |
);
|
164 |
if ( $basename && is_array( $files ) ) {
|
@@ -189,4 +189,13 @@ class MailChimp_WooCommerce_Log_Viewer {
|
|
189 |
}
|
190 |
return false;
|
191 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
}
|
158 |
$files = array_filter(
|
159 |
$files,
|
160 |
function( $value ) {
|
161 |
+
return static::stringEndsWith( $value, '.log' ) && static::isValidLogFile( $value );
|
162 |
}
|
163 |
);
|
164 |
if ( $basename && is_array( $files ) ) {
|
189 |
}
|
190 |
return false;
|
191 |
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* @param $file
|
195 |
+
*
|
196 |
+
* @return bool
|
197 |
+
*/
|
198 |
+
public static function isValidLogFile( $file ) {
|
199 |
+
return mailchimp_string_contains( $file, array('mailchimp_', 'fatal-') );
|
200 |
+
}
|
201 |
}
|
includes/api/class-mailchimp-woocommerce-logs.php
CHANGED
@@ -72,6 +72,9 @@ class MailChimp_WooCommerce_Logs {
|
|
72 |
if ( ! isset( $matches[2] ) ) {
|
73 |
continue;
|
74 |
}
|
|
|
|
|
|
|
75 |
$files[] = array(
|
76 |
'value' => base64_encode( $file ),
|
77 |
'filename' => $file,
|
72 |
if ( ! isset( $matches[2] ) ) {
|
73 |
continue;
|
74 |
}
|
75 |
+
if ( !mailchimp_string_contains($file, array('mailchimp_', 'fatal-')) ) {
|
76 |
+
continue;
|
77 |
+
}
|
78 |
$files[] = array(
|
79 |
'value' => base64_encode( $file ),
|
80 |
'filename' => $file,
|
includes/api/class-mailchimp-woocommerce-tower.php
CHANGED
@@ -102,15 +102,24 @@ class MailChimp_WooCommerce_Tower extends Mailchimp_Woocommerce_Job {
|
|
102 |
|
103 |
if ( is_array( $stores ) && ! empty( $stores ) ) {
|
104 |
foreach ( $stores as $mc_store ) {
|
|
|
105 |
$store_url = $this->baseDomain( $mc_store->getDomain() );
|
106 |
$public_key_matched = $mc_store->getId() === $store_id;
|
107 |
// make sure the current store in context is inside the Mailchimp array of stores.
|
108 |
if ( $public_key_matched ) {
|
109 |
$shop = $mc_store;
|
110 |
-
$syncing_mc =
|
111 |
$store_attached = true;
|
112 |
$list_is_valid = $mc_store->getListId() === $list_id;
|
113 |
$has_mailchimp_script = (bool) $mc_store->getConnectedSiteScriptFragment();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
if ( $store_url === $compare_url ) {
|
116 |
if ( ! $public_key_matched && $mc_store->getPlatform() === 'Woocommerce' ) {
|
102 |
|
103 |
if ( is_array( $stores ) && ! empty( $stores ) ) {
|
104 |
foreach ( $stores as $mc_store ) {
|
105 |
+
/** @var MailChimp_WooCommerce_Store $mc_store */
|
106 |
$store_url = $this->baseDomain( $mc_store->getDomain() );
|
107 |
$public_key_matched = $mc_store->getId() === $store_id;
|
108 |
// make sure the current store in context is inside the Mailchimp array of stores.
|
109 |
if ( $public_key_matched ) {
|
110 |
$shop = $mc_store;
|
111 |
+
$syncing_mc = (bool) mailchimp_get_data('sync.syncing' );
|
112 |
$store_attached = true;
|
113 |
$list_is_valid = $mc_store->getListId() === $list_id;
|
114 |
$has_mailchimp_script = (bool) $mc_store->getConnectedSiteScriptFragment();
|
115 |
+
|
116 |
+
// if the store is not syncing locally, but is still marked as syncing on Mailchimp,
|
117 |
+
// clean it up by toggling to false.
|
118 |
+
if ( !$syncing_mc && $mc_store->isSyncing() ) {
|
119 |
+
if ( $api->flagStoreSync($store_id, false) ) {
|
120 |
+
mailchimp_log('tower', 'Toggled Mailchimp store to not syncing historical data');
|
121 |
+
}
|
122 |
+
}
|
123 |
}
|
124 |
if ( $store_url === $compare_url ) {
|
125 |
if ( ! $public_key_matched && $mc_store->getPlatform() === 'Woocommerce' ) {
|
includes/api/class-mailchimp-woocommerce-transform-coupons.php
CHANGED
@@ -98,7 +98,7 @@ class MailChimp_WooCommerce_Transform_Coupons {
|
|
98 |
// attach the rule for use.
|
99 |
$code->attachPromoRule( $rule );
|
100 |
|
101 |
-
return $code;
|
102 |
}
|
103 |
|
104 |
/**
|
98 |
// attach the rule for use.
|
99 |
$code->attachPromoRule( $rule );
|
100 |
|
101 |
+
return apply_filters('mailchimp_sync_promocode', $code, $resource);
|
102 |
}
|
103 |
|
104 |
/**
|
includes/api/class-mailchimp-woocommerce-transform-products.php
CHANGED
@@ -62,7 +62,7 @@ class MailChimp_WooCommerce_Transform_Products {
|
|
62 |
|
63 |
$product->addVariant( $variant );
|
64 |
|
65 |
-
return $product;
|
66 |
}
|
67 |
|
68 |
/**
|
@@ -129,7 +129,7 @@ class MailChimp_WooCommerce_Transform_Products {
|
|
129 |
$product->addVariant( $product_variant );
|
130 |
}
|
131 |
|
132 |
-
return $product;
|
133 |
}
|
134 |
|
135 |
/**
|
62 |
|
63 |
$product->addVariant( $variant );
|
64 |
|
65 |
+
return apply_filters('mailchimp_sync_lineitem', $product);
|
66 |
}
|
67 |
|
68 |
/**
|
129 |
$product->addVariant( $product_variant );
|
130 |
}
|
131 |
|
132 |
+
return apply_filters('mailchimp_sync_product', $product, $woo);
|
133 |
}
|
134 |
|
135 |
/**
|
includes/vendor/action-scheduler/action-scheduler.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Description: A robust scheduling library for use in WordPress plugins.
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com/
|
8 |
-
* Version: 3.
|
9 |
* License: GPLv3
|
10 |
*
|
11 |
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
@@ -26,27 +26,27 @@
|
|
26 |
* @package ActionScheduler
|
27 |
*/
|
28 |
|
29 |
-
if ( ! function_exists( '
|
30 |
|
31 |
if ( ! class_exists( 'ActionScheduler_Versions', false ) ) {
|
32 |
require_once __DIR__ . '/classes/ActionScheduler_Versions.php';
|
33 |
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
|
34 |
}
|
35 |
|
36 |
-
add_action( 'plugins_loaded', '
|
37 |
|
38 |
/**
|
39 |
* Registers this version of Action Scheduler.
|
40 |
*/
|
41 |
-
function
|
42 |
$versions = ActionScheduler_Versions::instance();
|
43 |
-
$versions->register( '3.
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* Initializes this version of Action Scheduler.
|
48 |
*/
|
49 |
-
function
|
50 |
// A final safety check is required even here, because historic versions of Action Scheduler
|
51 |
// followed a different pattern (in some unusual cases, we could reach this point and the
|
52 |
// ActionScheduler class is already defined—so we need to guard against that).
|
@@ -58,7 +58,7 @@ if ( ! function_exists( 'action_scheduler_register_3_dot_4_dot_0' ) && function_
|
|
58 |
|
59 |
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
60 |
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
|
61 |
-
|
62 |
do_action( 'action_scheduler_pre_theme_init' );
|
63 |
ActionScheduler_Versions::initialize_latest_version();
|
64 |
}
|
5 |
* Description: A robust scheduling library for use in WordPress plugins.
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com/
|
8 |
+
* Version: 3.5.2
|
9 |
* License: GPLv3
|
10 |
*
|
11 |
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
26 |
* @package ActionScheduler
|
27 |
*/
|
28 |
|
29 |
+
if ( ! function_exists( 'action_scheduler_register_3_dot_5_dot_2' ) && function_exists( 'add_action' ) ) { // WRCS: DEFINED_VERSION.
|
30 |
|
31 |
if ( ! class_exists( 'ActionScheduler_Versions', false ) ) {
|
32 |
require_once __DIR__ . '/classes/ActionScheduler_Versions.php';
|
33 |
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
|
34 |
}
|
35 |
|
36 |
+
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_5_dot_2', 0, 0 ); // WRCS: DEFINED_VERSION.
|
37 |
|
38 |
/**
|
39 |
* Registers this version of Action Scheduler.
|
40 |
*/
|
41 |
+
function action_scheduler_register_3_dot_5_dot_2() { // WRCS: DEFINED_VERSION.
|
42 |
$versions = ActionScheduler_Versions::instance();
|
43 |
+
$versions->register( '3.5.2', 'action_scheduler_initialize_3_dot_5_dot_2' ); // WRCS: DEFINED_VERSION.
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* Initializes this version of Action Scheduler.
|
48 |
*/
|
49 |
+
function action_scheduler_initialize_3_dot_5_dot_2() { // WRCS: DEFINED_VERSION.
|
50 |
// A final safety check is required even here, because historic versions of Action Scheduler
|
51 |
// followed a different pattern (in some unusual cases, we could reach this point and the
|
52 |
// ActionScheduler class is already defined—so we need to guard against that).
|
58 |
|
59 |
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
60 |
if ( did_action( 'plugins_loaded' ) && ! doing_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler', false ) ) {
|
61 |
+
action_scheduler_initialize_3_dot_5_dot_2(); // WRCS: DEFINED_VERSION.
|
62 |
do_action( 'action_scheduler_pre_theme_init' );
|
63 |
ActionScheduler_Versions::initialize_latest_version();
|
64 |
}
|
includes/vendor/action-scheduler/classes/ActionScheduler_ActionFactory.php
CHANGED
@@ -6,27 +6,29 @@
|
|
6 |
class ActionScheduler_ActionFactory {
|
7 |
|
8 |
/**
|
9 |
-
*
|
10 |
-
* @param string $hook The hook to trigger when this action runs
|
11 |
-
* @param array $args Args to pass to callbacks when the hook is triggered
|
12 |
-
* @param ActionScheduler_Schedule $schedule The action's schedule
|
13 |
-
* @param string $group A group to put the action in
|
14 |
*
|
15 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
*/
|
17 |
public function get_stored_action( $status, $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
|
18 |
|
19 |
switch ( $status ) {
|
20 |
-
case ActionScheduler_Store::STATUS_PENDING
|
21 |
$action_class = 'ActionScheduler_Action';
|
22 |
break;
|
23 |
-
case ActionScheduler_Store::STATUS_CANCELED
|
24 |
$action_class = 'ActionScheduler_CanceledAction';
|
25 |
if ( ! is_null( $schedule ) && ! is_a( $schedule, 'ActionScheduler_CanceledSchedule' ) && ! is_a( $schedule, 'ActionScheduler_NullSchedule' ) ) {
|
26 |
$schedule = new ActionScheduler_CanceledSchedule( $schedule->get_date() );
|
27 |
}
|
28 |
break;
|
29 |
-
default
|
30 |
$action_class = 'ActionScheduler_FinishedAction';
|
31 |
break;
|
32 |
}
|
@@ -57,76 +59,142 @@ class ActionScheduler_ActionFactory {
|
|
57 |
* given priority in queue processing. This has the added advantage of making sure async actions can be
|
58 |
* claimed by both the existing WP Cron and WP CLI runners, as well as a new async request runner.
|
59 |
*
|
60 |
-
* @param string $hook The hook to trigger when this action runs
|
61 |
-
* @param array
|
62 |
-
* @param string $group A group to put the action in
|
63 |
*
|
64 |
-
* @return int The ID of the stored action
|
65 |
*/
|
66 |
public function async( $hook, $args = array(), $group = '' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
$schedule = new ActionScheduler_NullSchedule();
|
68 |
-
$action
|
69 |
-
return $this->store( $action );
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
-
*
|
74 |
-
* @param array $args Args to pass when the hook is triggered
|
75 |
-
* @param int $when Unix timestamp when the action will run
|
76 |
-
* @param string $group A group to put the action in
|
77 |
*
|
78 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
79 |
*/
|
80 |
public function single( $hook, $args = array(), $when = null, $group = '' ) {
|
81 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
$schedule = new ActionScheduler_SimpleSchedule( $date );
|
83 |
-
$action
|
84 |
-
return $this->store( $action );
|
85 |
}
|
86 |
|
87 |
/**
|
88 |
* Create the first instance of an action recurring on a given interval.
|
89 |
*
|
90 |
-
* @param string $hook The hook to trigger when this action runs
|
91 |
-
* @param array
|
92 |
-
* @param int
|
93 |
-
* @param int
|
94 |
-
* @param string $group A group to put the action in
|
95 |
*
|
96 |
-
* @return int The ID of the stored action
|
97 |
*/
|
98 |
public function recurring( $hook, $args = array(), $first = null, $interval = null, $group = '' ) {
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
}
|
102 |
-
$date
|
103 |
$schedule = new ActionScheduler_IntervalSchedule( $date, $interval );
|
104 |
-
$action
|
105 |
-
return $this->store( $action );
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
* Create the first instance of an action recurring on a Cron schedule.
|
110 |
*
|
111 |
-
* @param string $hook The hook to trigger when this action runs
|
112 |
-
* @param array
|
113 |
-
* @param int
|
114 |
* to run at a time calculated after this timestamp matching the cron
|
115 |
* expression. This can be used to delay the first instance of the action.
|
116 |
-
* @param int
|
117 |
-
* @param string $group A group to put the action in
|
118 |
*
|
119 |
-
* @return int The ID of the stored action
|
120 |
*/
|
121 |
public function cron( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '' ) {
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
-
$date
|
126 |
-
$cron
|
127 |
$schedule = new ActionScheduler_CronSchedule( $date, $cron );
|
128 |
-
$action
|
129 |
-
return $this->store( $action );
|
130 |
}
|
131 |
|
132 |
/**
|
@@ -162,13 +230,15 @@ class ActionScheduler_ActionFactory {
|
|
162 |
}
|
163 |
|
164 |
$schedule_class = get_class( $schedule );
|
165 |
-
$new_schedule
|
166 |
-
$new_action
|
167 |
return $this->store( $new_action );
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
-
*
|
|
|
|
|
172 |
*
|
173 |
* @return int The ID of the stored action
|
174 |
*/
|
@@ -176,4 +246,17 @@ class ActionScheduler_ActionFactory {
|
|
176 |
$store = ActionScheduler_Store::instance();
|
177 |
return $store->save_action( $action );
|
178 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
6 |
class ActionScheduler_ActionFactory {
|
7 |
|
8 |
/**
|
9 |
+
* Return stored actions for given params.
|
|
|
|
|
|
|
|
|
10 |
*
|
11 |
+
* @param string $status The action's status in the data store.
|
12 |
+
* @param string $hook The hook to trigger when this action runs.
|
13 |
+
* @param array $args Args to pass to callbacks when the hook is triggered.
|
14 |
+
* @param ActionScheduler_Schedule $schedule The action's schedule.
|
15 |
+
* @param string $group A group to put the action in.
|
16 |
+
*
|
17 |
+
* @return ActionScheduler_Action An instance of the stored action.
|
18 |
*/
|
19 |
public function get_stored_action( $status, $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) {
|
20 |
|
21 |
switch ( $status ) {
|
22 |
+
case ActionScheduler_Store::STATUS_PENDING:
|
23 |
$action_class = 'ActionScheduler_Action';
|
24 |
break;
|
25 |
+
case ActionScheduler_Store::STATUS_CANCELED:
|
26 |
$action_class = 'ActionScheduler_CanceledAction';
|
27 |
if ( ! is_null( $schedule ) && ! is_a( $schedule, 'ActionScheduler_CanceledSchedule' ) && ! is_a( $schedule, 'ActionScheduler_NullSchedule' ) ) {
|
28 |
$schedule = new ActionScheduler_CanceledSchedule( $schedule->get_date() );
|
29 |
}
|
30 |
break;
|
31 |
+
default:
|
32 |
$action_class = 'ActionScheduler_FinishedAction';
|
33 |
break;
|
34 |
}
|
59 |
* given priority in queue processing. This has the added advantage of making sure async actions can be
|
60 |
* claimed by both the existing WP Cron and WP CLI runners, as well as a new async request runner.
|
61 |
*
|
62 |
+
* @param string $hook The hook to trigger when this action runs.
|
63 |
+
* @param array $args Args to pass when the hook is triggered.
|
64 |
+
* @param string $group A group to put the action in.
|
65 |
*
|
66 |
+
* @return int The ID of the stored action.
|
67 |
*/
|
68 |
public function async( $hook, $args = array(), $group = '' ) {
|
69 |
+
return $this->async_unique( $hook, $args, $group, false );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Same as async, but also supports $unique param.
|
74 |
+
*
|
75 |
+
* @param string $hook The hook to trigger when this action runs.
|
76 |
+
* @param array $args Args to pass when the hook is triggered.
|
77 |
+
* @param string $group A group to put the action in.
|
78 |
+
* @param bool $unique Whether to ensure the action is unique.
|
79 |
+
*
|
80 |
+
* @return int The ID of the stored action.
|
81 |
+
*/
|
82 |
+
public function async_unique( $hook, $args = array(), $group = '', $unique = true ) {
|
83 |
$schedule = new ActionScheduler_NullSchedule();
|
84 |
+
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
|
85 |
+
return $unique ? $this->store_unique_action( $action, $unique ) : $this->store( $action );
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
+
* Create single action.
|
|
|
|
|
|
|
90 |
*
|
91 |
+
* @param string $hook The hook to trigger when this action runs.
|
92 |
+
* @param array $args Args to pass when the hook is triggered.
|
93 |
+
* @param int $when Unix timestamp when the action will run.
|
94 |
+
* @param string $group A group to put the action in.
|
95 |
+
*
|
96 |
+
* @return int The ID of the stored action.
|
97 |
*/
|
98 |
public function single( $hook, $args = array(), $when = null, $group = '' ) {
|
99 |
+
return $this->single_unique( $hook, $args, $when, $group, false );
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Create single action only if there is no pending or running action with same name and params.
|
104 |
+
*
|
105 |
+
* @param string $hook The hook to trigger when this action runs.
|
106 |
+
* @param array $args Args to pass when the hook is triggered.
|
107 |
+
* @param int $when Unix timestamp when the action will run.
|
108 |
+
* @param string $group A group to put the action in.
|
109 |
+
* @param bool $unique Whether action scheduled should be unique.
|
110 |
+
*
|
111 |
+
* @return int The ID of the stored action.
|
112 |
+
*/
|
113 |
+
public function single_unique( $hook, $args = array(), $when = null, $group = '', $unique = true ) {
|
114 |
+
$date = as_get_datetime_object( $when );
|
115 |
$schedule = new ActionScheduler_SimpleSchedule( $date );
|
116 |
+
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
|
117 |
+
return $unique ? $this->store_unique_action( $action ) : $this->store( $action );
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
* Create the first instance of an action recurring on a given interval.
|
122 |
*
|
123 |
+
* @param string $hook The hook to trigger when this action runs.
|
124 |
+
* @param array $args Args to pass when the hook is triggered.
|
125 |
+
* @param int $first Unix timestamp for the first run.
|
126 |
+
* @param int $interval Seconds between runs.
|
127 |
+
* @param string $group A group to put the action in.
|
128 |
*
|
129 |
+
* @return int The ID of the stored action.
|
130 |
*/
|
131 |
public function recurring( $hook, $args = array(), $first = null, $interval = null, $group = '' ) {
|
132 |
+
return $this->recurring_unique( $hook, $args, $first, $interval, $group, false );
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Create the first instance of an action recurring on a given interval only if there is no pending or running action with same name and params.
|
137 |
+
*
|
138 |
+
* @param string $hook The hook to trigger when this action runs.
|
139 |
+
* @param array $args Args to pass when the hook is triggered.
|
140 |
+
* @param int $first Unix timestamp for the first run.
|
141 |
+
* @param int $interval Seconds between runs.
|
142 |
+
* @param string $group A group to put the action in.
|
143 |
+
* @param bool $unique Whether action scheduled should be unique.
|
144 |
+
*
|
145 |
+
* @return int The ID of the stored action.
|
146 |
+
*/
|
147 |
+
public function recurring_unique( $hook, $args = array(), $first = null, $interval = null, $group = '', $unique = true ) {
|
148 |
+
if ( empty( $interval ) ) {
|
149 |
+
return $this->single_unique( $hook, $unique, $args, $first, $group );
|
150 |
}
|
151 |
+
$date = as_get_datetime_object( $first );
|
152 |
$schedule = new ActionScheduler_IntervalSchedule( $date, $interval );
|
153 |
+
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
|
154 |
+
return $unique ? $this->store_unique_action( $action ) : $this->store( $action );
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
* Create the first instance of an action recurring on a Cron schedule.
|
159 |
*
|
160 |
+
* @param string $hook The hook to trigger when this action runs.
|
161 |
+
* @param array $args Args to pass when the hook is triggered.
|
162 |
+
* @param int $base_timestamp The first instance of the action will be scheduled
|
163 |
* to run at a time calculated after this timestamp matching the cron
|
164 |
* expression. This can be used to delay the first instance of the action.
|
165 |
+
* @param int $schedule A cron definition string.
|
166 |
+
* @param string $group A group to put the action in.
|
167 |
*
|
168 |
+
* @return int The ID of the stored action.
|
169 |
*/
|
170 |
public function cron( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '' ) {
|
171 |
+
return $this->cron_unique( $hook, $args, $base_timestamp, $schedule, $group, false );
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Create the first instance of an action recurring on a Cron schedule only if there is no pending or running action with same name and params.
|
177 |
+
*
|
178 |
+
* @param string $hook The hook to trigger when this action runs.
|
179 |
+
* @param array $args Args to pass when the hook is triggered.
|
180 |
+
* @param int $base_timestamp The first instance of the action will be scheduled
|
181 |
+
* to run at a time calculated after this timestamp matching the cron
|
182 |
+
* expression. This can be used to delay the first instance of the action.
|
183 |
+
* @param int $schedule A cron definition string.
|
184 |
+
* @param string $group A group to put the action in.
|
185 |
+
* @param bool $unique Whether action scheduled should be unique.
|
186 |
+
*
|
187 |
+
* @return int The ID of the stored action.
|
188 |
+
**/
|
189 |
+
public function cron_unique( $hook, $args = array(), $base_timestamp = null, $schedule = null, $group = '', $unique = true ) {
|
190 |
+
if ( empty( $schedule ) ) {
|
191 |
+
return $this->single_unique( $hook, $unique, $args, $base_timestamp, $group );
|
192 |
}
|
193 |
+
$date = as_get_datetime_object( $base_timestamp );
|
194 |
+
$cron = CronExpression::factory( $schedule );
|
195 |
$schedule = new ActionScheduler_CronSchedule( $date, $cron );
|
196 |
+
$action = new ActionScheduler_Action( $hook, $args, $schedule, $group );
|
197 |
+
return $unique ? $this->store_unique_action( $action ) : $this->store( $action );
|
198 |
}
|
199 |
|
200 |
/**
|
230 |
}
|
231 |
|
232 |
$schedule_class = get_class( $schedule );
|
233 |
+
$new_schedule = new $schedule( $next, $schedule->get_recurrence(), $schedule->get_first_date() );
|
234 |
+
$new_action = new ActionScheduler_Action( $action->get_hook(), $action->get_args(), $new_schedule, $action->get_group() );
|
235 |
return $this->store( $new_action );
|
236 |
}
|
237 |
|
238 |
/**
|
239 |
+
* Save action to database.
|
240 |
+
*
|
241 |
+
* @param ActionScheduler_Action $action Action object to save.
|
242 |
*
|
243 |
* @return int The ID of the stored action
|
244 |
*/
|
246 |
$store = ActionScheduler_Store::instance();
|
247 |
return $store->save_action( $action );
|
248 |
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Store action if it's unique.
|
252 |
+
*
|
253 |
+
* @param ActionScheduler_Action $action Action object to store.
|
254 |
+
*
|
255 |
+
* @return int ID of the created action. Will be 0 if action was not created.
|
256 |
+
*/
|
257 |
+
protected function store_unique_action( ActionScheduler_Action $action ) {
|
258 |
+
$store = ActionScheduler_Store::instance();
|
259 |
+
return method_exists( $store, 'save_unique_action' ) ?
|
260 |
+
$store->save_unique_action( $action ) : $store->save_action( $action );
|
261 |
+
}
|
262 |
}
|
includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php
CHANGED
@@ -40,7 +40,7 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
|
|
40 |
}
|
41 |
|
42 |
add_action( 'admin_menu', array( $this, 'register_menu' ) );
|
43 |
-
|
44 |
add_action( 'current_screen', array( $this, 'add_help_tabs' ) );
|
45 |
}
|
46 |
}
|
@@ -110,6 +110,96 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
|
|
110 |
return $this->list_table;
|
111 |
}
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
/**
|
114 |
* Provide more information about the screen and its data in the help tab.
|
115 |
*/
|
40 |
}
|
41 |
|
42 |
add_action( 'admin_menu', array( $this, 'register_menu' ) );
|
43 |
+
add_action( 'admin_notices', array( $this, 'maybe_check_pastdue_actions' ) );
|
44 |
add_action( 'current_screen', array( $this, 'add_help_tabs' ) );
|
45 |
}
|
46 |
}
|
110 |
return $this->list_table;
|
111 |
}
|
112 |
|
113 |
+
/**
|
114 |
+
* Action: admin_notices
|
115 |
+
*
|
116 |
+
* Maybe check past-due actions, and print notice.
|
117 |
+
*
|
118 |
+
* @uses $this->check_pastdue_actions()
|
119 |
+
*/
|
120 |
+
public function maybe_check_pastdue_actions() {
|
121 |
+
|
122 |
+
# Filter to prevent checking actions (ex: inappropriate user).
|
123 |
+
if ( ! apply_filters( 'action_scheduler_check_pastdue_actions', current_user_can( 'manage_options' ) ) ) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
# Get last check transient.
|
128 |
+
$last_check = get_transient( 'action_scheduler_last_pastdue_actions_check' );
|
129 |
+
|
130 |
+
# If transient exists, we're within interval, so bail.
|
131 |
+
if ( ! empty( $last_check ) ) {
|
132 |
+
return;
|
133 |
+
}
|
134 |
+
|
135 |
+
# Perform the check.
|
136 |
+
$this->check_pastdue_actions();
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Check past-due actions, and print notice.
|
141 |
+
*
|
142 |
+
* @todo update $link_url to "Past-due" filter when released (see issue #510, PR #511)
|
143 |
+
*/
|
144 |
+
protected function check_pastdue_actions() {
|
145 |
+
|
146 |
+
# Set thresholds.
|
147 |
+
$threshold_seconds = ( int ) apply_filters( 'action_scheduler_pastdue_actions_seconds', DAY_IN_SECONDS );
|
148 |
+
$threshhold_min = ( int ) apply_filters( 'action_scheduler_pastdue_actions_min', 1 );
|
149 |
+
|
150 |
+
# Allow third-parties to preempt the default check logic.
|
151 |
+
$check = apply_filters( 'action_scheduler_pastdue_actions_check_pre', null );
|
152 |
+
|
153 |
+
# Scheduled actions query arguments.
|
154 |
+
$query_args = array(
|
155 |
+
'date' => as_get_datetime_object( time() - $threshold_seconds ),
|
156 |
+
'status' => ActionScheduler_Store::STATUS_PENDING,
|
157 |
+
'per_page' => $threshhold_min,
|
158 |
+
);
|
159 |
+
|
160 |
+
# If no third-party preempted, run default check.
|
161 |
+
if ( is_null( $check ) ) {
|
162 |
+
$store = ActionScheduler_Store::instance();
|
163 |
+
$num_pastdue_actions = ( int ) $store->query_actions( $query_args, 'count' );
|
164 |
+
|
165 |
+
# Check if past-due actions count is greater than or equal to threshold.
|
166 |
+
$check = ( $num_pastdue_actions >= $threshhold_min );
|
167 |
+
$check = ( bool ) apply_filters( 'action_scheduler_pastdue_actions_check', $check, $num_pastdue_actions, $threshold_seconds, $threshhold_min );
|
168 |
+
}
|
169 |
+
|
170 |
+
# If check failed, set transient and abort.
|
171 |
+
if ( ! boolval( $check ) ) {
|
172 |
+
$interval = apply_filters( 'action_scheduler_pastdue_actions_check_interval', round( $threshold_seconds / 4 ), $threshold_seconds );
|
173 |
+
set_transient( 'action_scheduler_last_pastdue_actions_check', time(), $interval );
|
174 |
+
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
$actions_url = add_query_arg( array(
|
179 |
+
'page' => 'action-scheduler',
|
180 |
+
'status' => 'past-due',
|
181 |
+
'order' => 'asc',
|
182 |
+
), admin_url( 'tools.php' ) );
|
183 |
+
|
184 |
+
# Print notice.
|
185 |
+
echo '<div class="notice notice-warning"><p>';
|
186 |
+
printf(
|
187 |
+
_n(
|
188 |
+
// translators: 1) is the number of affected actions, 2) is a link to an admin screen.
|
189 |
+
'<strong>Action Scheduler:</strong> %1$d <a href="%2$s">past-due action</a> found; something may be wrong. <a href="https://actionscheduler.org/faq/#my-site-has-past-due-actions-what-can-i-do" target="_blank">Read documentation »</a>',
|
190 |
+
'<strong>Action Scheduler:</strong> %1$d <a href="%2$s">past-due actions</a> found; something may be wrong. <a href="https://actionscheduler.org/faq/#my-site-has-past-due-actions-what-can-i-do" target="_blank">Read documentation »</a>',
|
191 |
+
$num_pastdue_actions,
|
192 |
+
'action-scheduler'
|
193 |
+
),
|
194 |
+
$num_pastdue_actions,
|
195 |
+
esc_attr( esc_url( $actions_url ) )
|
196 |
+
);
|
197 |
+
echo '</p></div>';
|
198 |
+
|
199 |
+
# Facilitate third-parties to evaluate and print notices.
|
200 |
+
do_action( 'action_scheduler_pastdue_actions_extra_notices', $query_args );
|
201 |
+
}
|
202 |
+
|
203 |
/**
|
204 |
* Provide more information about the screen and its data in the help tab.
|
205 |
*/
|
includes/vendor/action-scheduler/classes/ActionScheduler_DateTime.php
CHANGED
@@ -24,6 +24,7 @@ class ActionScheduler_DateTime extends DateTime {
|
|
24 |
*
|
25 |
* @return int
|
26 |
*/
|
|
|
27 |
public function getTimestamp() {
|
28 |
return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' );
|
29 |
}
|
@@ -45,6 +46,7 @@ class ActionScheduler_DateTime extends DateTime {
|
|
45 |
* @return int
|
46 |
* @link http://php.net/manual/en/datetime.getoffset.php
|
47 |
*/
|
|
|
48 |
public function getOffset() {
|
49 |
return $this->utcOffset ? $this->utcOffset : parent::getOffset();
|
50 |
}
|
@@ -57,6 +59,7 @@ class ActionScheduler_DateTime extends DateTime {
|
|
57 |
* @return static
|
58 |
* @link http://php.net/manual/en/datetime.settimezone.php
|
59 |
*/
|
|
|
60 |
public function setTimezone( $timezone ) {
|
61 |
$this->utcOffset = 0;
|
62 |
parent::setTimezone( $timezone );
|
24 |
*
|
25 |
* @return int
|
26 |
*/
|
27 |
+
#[\ReturnTypeWillChange]
|
28 |
public function getTimestamp() {
|
29 |
return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' );
|
30 |
}
|
46 |
* @return int
|
47 |
* @link http://php.net/manual/en/datetime.getoffset.php
|
48 |
*/
|
49 |
+
#[\ReturnTypeWillChange]
|
50 |
public function getOffset() {
|
51 |
return $this->utcOffset ? $this->utcOffset : parent::getOffset();
|
52 |
}
|
59 |
* @return static
|
60 |
* @link http://php.net/manual/en/datetime.settimezone.php
|
61 |
*/
|
62 |
+
#[\ReturnTypeWillChange]
|
63 |
public function setTimezone( $timezone ) {
|
64 |
$this->utcOffset = 0;
|
65 |
parent::setTimezone( $timezone );
|
includes/vendor/action-scheduler/classes/ActionScheduler_Exception.php
CHANGED
@@ -6,6 +6,6 @@
|
|
6 |
* Facilitates catching Exceptions unique to Action Scheduler.
|
7 |
*
|
8 |
* @package ActionScheduler
|
9 |
-
* @since
|
10 |
*/
|
11 |
interface ActionScheduler_Exception {}
|
6 |
* Facilitates catching Exceptions unique to Action Scheduler.
|
7 |
*
|
8 |
* @package ActionScheduler
|
9 |
+
* @since 2.1.0
|
10 |
*/
|
11 |
interface ActionScheduler_Exception {}
|
includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php
CHANGED
@@ -467,6 +467,10 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|
467 |
|
468 |
$schedule_display_string = '';
|
469 |
|
|
|
|
|
|
|
|
|
470 |
if ( ! $schedule->get_date() ) {
|
471 |
return '0000-00-00 00:00:00';
|
472 |
}
|
@@ -583,6 +587,16 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|
583 |
'search' => $this->get_request_search_query(),
|
584 |
);
|
585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
586 |
$this->items = array();
|
587 |
|
588 |
$total_items = $this->store->query_actions( $query, 'count' );
|
@@ -623,7 +637,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|
623 |
* Prints the available statuses so the user can click to filter.
|
624 |
*/
|
625 |
protected function display_filter_by_status() {
|
626 |
-
$this->status_counts = $this->store->action_counts();
|
627 |
parent::display_filter_by_status();
|
628 |
}
|
629 |
|
467 |
|
468 |
$schedule_display_string = '';
|
469 |
|
470 |
+
if ( is_a( $schedule, 'ActionScheduler_NullSchedule' ) ) {
|
471 |
+
return __( 'async', 'action-scheduler' );
|
472 |
+
}
|
473 |
+
|
474 |
if ( ! $schedule->get_date() ) {
|
475 |
return '0000-00-00 00:00:00';
|
476 |
}
|
587 |
'search' => $this->get_request_search_query(),
|
588 |
);
|
589 |
|
590 |
+
/**
|
591 |
+
* Change query arguments to query for past-due actions.
|
592 |
+
* Past-due actions have the 'pending' status and are in the past.
|
593 |
+
* This is needed because registering 'past-due' as a status is overkill.
|
594 |
+
*/
|
595 |
+
if ( 'past-due' === $this->get_request_status() ) {
|
596 |
+
$query['status'] = ActionScheduler_Store::STATUS_PENDING;
|
597 |
+
$query['date'] = as_get_datetime_object();
|
598 |
+
}
|
599 |
+
|
600 |
$this->items = array();
|
601 |
|
602 |
$total_items = $this->store->query_actions( $query, 'count' );
|
637 |
* Prints the available statuses so the user can click to filter.
|
638 |
*/
|
639 |
protected function display_filter_by_status() {
|
640 |
+
$this->status_counts = $this->store->action_counts() + $this->store->extra_action_counts();
|
641 |
parent::display_filter_by_status();
|
642 |
}
|
643 |
|
includes/vendor/action-scheduler/classes/ActionScheduler_QueueRunner.php
CHANGED
@@ -173,15 +173,34 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
|
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
-
*
|
177 |
*
|
178 |
-
*
|
179 |
-
*
|
180 |
-
*
|
181 |
-
* add_filter( 'action_scheduler_queue_runner_flush_cache', '__return_true' );
|
182 |
*/
|
183 |
protected function clear_caches() {
|
184 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
wp_cache_flush();
|
186 |
}
|
187 |
}
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
+
* Flush the cache if possible (intended for use after a batch of actions has been processed).
|
177 |
*
|
178 |
+
* This is useful because running large batches can eat up memory and because invalid data can accrue in the
|
179 |
+
* runtime cache, which may lead to unexpected results.
|
|
|
|
|
180 |
*/
|
181 |
protected function clear_caches() {
|
182 |
+
/*
|
183 |
+
* Calling wp_cache_flush_runtime() lets us clear the runtime cache without invalidating the external object
|
184 |
+
* cache, so we will always prefer this when it is available (but it was only introduced in WordPress 6.0).
|
185 |
+
*/
|
186 |
+
if ( function_exists( 'wp_cache_flush_runtime' ) ) {
|
187 |
+
wp_cache_flush_runtime();
|
188 |
+
} elseif (
|
189 |
+
! wp_using_ext_object_cache()
|
190 |
+
/**
|
191 |
+
* When an external object cache is in use, and when wp_cache_flush_runtime() is not available, then
|
192 |
+
* normally the cache will not be flushed after processing a batch of actions (to avoid a performance
|
193 |
+
* penalty for other processes).
|
194 |
+
*
|
195 |
+
* This filter makes it possible to override this behavior and always flush the cache, even if an external
|
196 |
+
* object cache is in use.
|
197 |
+
*
|
198 |
+
* @since 1.0
|
199 |
+
*
|
200 |
+
* @param bool $flush_cache If the cache should be flushed.
|
201 |
+
*/
|
202 |
+
|| apply_filters( 'action_scheduler_queue_runner_flush_cache', false )
|
203 |
+
) {
|
204 |
wp_cache_flush();
|
205 |
}
|
206 |
}
|
includes/vendor/action-scheduler/classes/WP_CLI/ActionScheduler_WPCLI_Scheduler_command.php
CHANGED
@@ -5,6 +5,36 @@
|
|
5 |
*/
|
6 |
class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
/**
|
9 |
* Run the Action Scheduler
|
10 |
*
|
5 |
*/
|
6 |
class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
7 |
|
8 |
+
/**
|
9 |
+
* Force tables schema creation for Action Scheduler
|
10 |
+
*
|
11 |
+
* ## OPTIONS
|
12 |
+
*
|
13 |
+
* @param array $args Positional arguments.
|
14 |
+
* @param array $assoc_args Keyed arguments.
|
15 |
+
*
|
16 |
+
* @subcommand fix-schema
|
17 |
+
*/
|
18 |
+
public function fix_schema( $args, $assoc_args ) {
|
19 |
+
$schema_classes = array( ActionScheduler_LoggerSchema::class, ActionScheduler_StoreSchema::class );
|
20 |
+
|
21 |
+
foreach ( $schema_classes as $classname ) {
|
22 |
+
if ( is_subclass_of( $classname, ActionScheduler_Abstract_Schema::class ) ) {
|
23 |
+
$obj = new $classname();
|
24 |
+
$obj->init();
|
25 |
+
$obj->register_tables( true );
|
26 |
+
|
27 |
+
WP_CLI::success(
|
28 |
+
sprintf(
|
29 |
+
/* translators: %s refers to the schema name*/
|
30 |
+
__( 'Registered schema for %s', 'action-scheduler' ),
|
31 |
+
$classname
|
32 |
+
)
|
33 |
+
);
|
34 |
+
}
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
/**
|
39 |
* Run the Action Scheduler
|
40 |
*
|
includes/vendor/action-scheduler/classes/WP_CLI/ProgressBar.php
CHANGED
@@ -44,7 +44,7 @@ class ProgressBar {
|
|
44 |
public function __construct( $message, $count, $interval = 100 ) {
|
45 |
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
|
46 |
/* translators: %s php class name */
|
47 |
-
throw new Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), __CLASS__ ) );
|
48 |
}
|
49 |
|
50 |
$this->total_ticks = 0;
|
44 |
public function __construct( $message, $count, $interval = 100 ) {
|
45 |
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
|
46 |
/* translators: %s php class name */
|
47 |
+
throw new \Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), __CLASS__ ) );
|
48 |
}
|
49 |
|
50 |
$this->total_ticks = 0;
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php
CHANGED
@@ -118,8 +118,8 @@ abstract class ActionScheduler {
|
|
118 |
return;
|
119 |
}
|
120 |
|
121 |
-
if ( file_exists(
|
122 |
-
include(
|
123 |
return;
|
124 |
}
|
125 |
}
|
118 |
return;
|
119 |
}
|
120 |
|
121 |
+
if ( file_exists( $dir . "{$class}.php" ) ) {
|
122 |
+
include( $dir . "{$class}.php" );
|
123 |
return;
|
124 |
}
|
125 |
}
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php
CHANGED
@@ -683,7 +683,7 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|
683 |
}
|
684 |
|
685 |
if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) {
|
686 |
-
$status_list_item = '<li class="%1$s"><
|
687 |
} else {
|
688 |
$status_list_item = '<li class="%1$s"><a href="%2$s">%3$s</a> (%4$d)</li>';
|
689 |
}
|
683 |
}
|
684 |
|
685 |
if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) {
|
686 |
+
$status_list_item = '<li class="%1$s"><a href="%2$s" class="current">%3$s</a> (%4$d)</li>';
|
687 |
} else {
|
688 |
$status_list_item = '<li class="%1$s"><a href="%2$s">%3$s</a> (%4$d)</li>';
|
689 |
}
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
CHANGED
@@ -86,6 +86,19 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
|
|
86 |
* @param int $action_id
|
87 |
*/
|
88 |
protected function schedule_next_instance( ActionScheduler_Action $action, $action_id ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
try {
|
90 |
ActionScheduler::factory()->repeat( $action );
|
91 |
} catch ( Exception $e ) {
|
@@ -93,6 +106,51 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
|
|
93 |
}
|
94 |
}
|
95 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
/**
|
97 |
* Run the queue cleaner.
|
98 |
*
|
86 |
* @param int $action_id
|
87 |
*/
|
88 |
protected function schedule_next_instance( ActionScheduler_Action $action, $action_id ) {
|
89 |
+
// If a recurring action has been consistently failing, we may wish to stop rescheduling it.
|
90 |
+
if (
|
91 |
+
ActionScheduler_Store::STATUS_FAILED === $this->store->get_status( $action_id )
|
92 |
+
&& $this->recurring_action_is_consistently_failing( $action, $action_id )
|
93 |
+
) {
|
94 |
+
ActionScheduler_Logger::instance()->log(
|
95 |
+
$action_id,
|
96 |
+
__( 'This action appears to be consistently failing. A new instance will not be scheduled.', 'action-scheduler' )
|
97 |
+
);
|
98 |
+
|
99 |
+
return;
|
100 |
+
}
|
101 |
+
|
102 |
try {
|
103 |
ActionScheduler::factory()->repeat( $action );
|
104 |
} catch ( Exception $e ) {
|
106 |
}
|
107 |
}
|
108 |
|
109 |
+
/**
|
110 |
+
* Determine if the specified recurring action has been consistently failing.
|
111 |
+
*
|
112 |
+
* @param ActionScheduler_Action $action The recurring action to be rescheduled.
|
113 |
+
* @param int $action_id The ID of the recurring action.
|
114 |
+
*
|
115 |
+
* @return bool
|
116 |
+
*/
|
117 |
+
private function recurring_action_is_consistently_failing( ActionScheduler_Action $action, $action_id ) {
|
118 |
+
/**
|
119 |
+
* Controls the failure threshold for recurring actions.
|
120 |
+
*
|
121 |
+
* Before rescheduling a recurring action, we look at its status. If it failed, we then check if all of the most
|
122 |
+
* recent actions (upto the threshold set by this filter) sharing the same hook have also failed: if they have,
|
123 |
+
* that is considered consistent failure and a new instance of the action will not be scheduled.
|
124 |
+
*
|
125 |
+
* @param int $failure_threshold Number of actions of the same hook to examine for failure. Defaults to 5.
|
126 |
+
*/
|
127 |
+
$consistent_failure_threshold = (int) apply_filters( 'action_scheduler_recurring_action_failure_threshold', 5 );
|
128 |
+
|
129 |
+
// This query should find the earliest *failing* action (for the hook we are interested in) within our threshold.
|
130 |
+
$query_args = array(
|
131 |
+
'hook' => $action->get_hook(),
|
132 |
+
'status' => ActionScheduler_Store::STATUS_FAILED,
|
133 |
+
'date' => date_create( 'now', timezone_open( 'UTC' ) )->format( 'Y-m-d H:i:s' ),
|
134 |
+
'date_compare' => '<',
|
135 |
+
'per_page' => 1,
|
136 |
+
'offset' => $consistent_failure_threshold - 1
|
137 |
+
);
|
138 |
+
|
139 |
+
$first_failing_action_id = $this->store->query_actions( $query_args );
|
140 |
+
|
141 |
+
// If we didn't retrieve an action ID, then there haven't been enough failures for us to worry about.
|
142 |
+
if ( empty( $first_failing_action_id ) ) {
|
143 |
+
return false;
|
144 |
+
}
|
145 |
+
|
146 |
+
// Now let's fetch the first action (having the same hook) of *any status*ithin the same window.
|
147 |
+
unset( $query_args['status'] );
|
148 |
+
$first_action_id_with_the_same_hook = $this->store->query_actions( $query_args );
|
149 |
+
|
150 |
+
// If the IDs match, then actions for this hook must be consistently failing.
|
151 |
+
return $first_action_id_with_the_same_hook === $first_failing_action_id;
|
152 |
+
}
|
153 |
+
|
154 |
/**
|
155 |
* Run the queue cleaner.
|
156 |
*
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
CHANGED
@@ -109,7 +109,7 @@ abstract class ActionScheduler_Logger {
|
|
109 |
|
110 |
public function log_timed_out_action( $action_id, $timeout ) {
|
111 |
/* translators: %s: amount of time */
|
112 |
-
$this->log( $action_id, sprintf( __( 'action
|
113 |
}
|
114 |
|
115 |
public function log_unexpected_shutdown( $action_id, $error ) {
|
109 |
|
110 |
public function log_timed_out_action( $action_id, $timeout ) {
|
111 |
/* translators: %s: amount of time */
|
112 |
+
$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 ) );
|
113 |
}
|
114 |
|
115 |
public function log_unexpected_shutdown( $action_id, $error ) {
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Store.php
CHANGED
@@ -76,7 +76,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
|
76 |
/**
|
77 |
* Query for action count or list of action IDs.
|
78 |
*
|
79 |
-
* @since
|
80 |
*
|
81 |
* @param array $query {
|
82 |
* Query filtering options.
|
@@ -104,7 +104,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
|
104 |
/**
|
105 |
* Run query to get a single action ID.
|
106 |
*
|
107 |
-
* @since
|
108 |
*
|
109 |
* @see ActionScheduler_Store::query_actions for $query arg usage but 'per_page' and 'offset' can't be used.
|
110 |
*
|
@@ -131,6 +131,34 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
|
131 |
*/
|
132 |
abstract public function action_counts();
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
/**
|
135 |
* @param string $action_id
|
136 |
*/
|
76 |
/**
|
77 |
* Query for action count or list of action IDs.
|
78 |
*
|
79 |
+
* @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
|
80 |
*
|
81 |
* @param array $query {
|
82 |
* Query filtering options.
|
104 |
/**
|
105 |
* Run query to get a single action ID.
|
106 |
*
|
107 |
+
* @since 3.3.0
|
108 |
*
|
109 |
* @see ActionScheduler_Store::query_actions for $query arg usage but 'per_page' and 'offset' can't be used.
|
110 |
*
|
131 |
*/
|
132 |
abstract public function action_counts();
|
133 |
|
134 |
+
/**
|
135 |
+
* Get additional action counts.
|
136 |
+
*
|
137 |
+
* - add past-due actions
|
138 |
+
*
|
139 |
+
* @return array
|
140 |
+
*/
|
141 |
+
public function extra_action_counts() {
|
142 |
+
$extra_actions = array();
|
143 |
+
|
144 |
+
$pastdue_action_counts = ( int ) $this->query_actions( array(
|
145 |
+
'status' => self::STATUS_PENDING,
|
146 |
+
'date' => as_get_datetime_object(),
|
147 |
+
), 'count' );
|
148 |
+
|
149 |
+
if ( $pastdue_action_counts ) {
|
150 |
+
$extra_actions['past-due'] = $pastdue_action_counts;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Allows 3rd party code to add extra action counts (used in filters in the list table).
|
155 |
+
*
|
156 |
+
* @since 3.5.0
|
157 |
+
* @param $extra_actions array Array with format action_count_identifier => action count.
|
158 |
+
*/
|
159 |
+
return apply_filters( 'action_scheduler_extra_action_counts', $extra_actions );
|
160 |
+
}
|
161 |
+
|
162 |
/**
|
163 |
* @param string $action_id
|
164 |
*/
|
includes/vendor/action-scheduler/classes/actions/ActionScheduler_Action.php
CHANGED
@@ -18,8 +18,29 @@ class ActionScheduler_Action {
|
|
18 |
$this->set_group($group);
|
19 |
}
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
public function execute() {
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
|
25 |
/**
|
18 |
$this->set_group($group);
|
19 |
}
|
20 |
|
21 |
+
/**
|
22 |
+
* Executes the action.
|
23 |
+
*
|
24 |
+
* If no callbacks are registered, an exception will be thrown and the action will not be
|
25 |
+
* fired. This is useful to help detect cases where the code responsible for setting up
|
26 |
+
* a scheduled action no longer exists.
|
27 |
+
*
|
28 |
+
* @throws Exception If no callbacks are registered for this action.
|
29 |
+
*/
|
30 |
public function execute() {
|
31 |
+
$hook = $this->get_hook();
|
32 |
+
|
33 |
+
if ( ! has_action( $hook ) ) {
|
34 |
+
throw new Exception(
|
35 |
+
sprintf(
|
36 |
+
/* translators: 1: action hook. */
|
37 |
+
__( 'Scheduled action for %1$s will not be executed as no callbacks are registered.', 'action-scheduler' ),
|
38 |
+
$hook
|
39 |
+
)
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
do_action_ref_array( $hook, array_values( $this->get_args() ) );
|
44 |
}
|
45 |
|
46 |
/**
|
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
CHANGED
@@ -36,22 +36,48 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
36 |
$table_maker->register_tables();
|
37 |
}
|
38 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
/**
|
40 |
* Save an action.
|
41 |
*
|
42 |
* @param ActionScheduler_Action $action Action object.
|
43 |
-
* @param DateTime $date Optional schedule date. Default null.
|
|
|
44 |
*
|
45 |
* @return int Action ID.
|
46 |
* @throws RuntimeException Throws exception when saving the action fails.
|
47 |
*/
|
48 |
-
|
49 |
-
|
50 |
|
|
|
51 |
$this->validate_action( $action );
|
52 |
|
53 |
-
/** @var \wpdb $wpdb */
|
54 |
-
global $wpdb;
|
55 |
$data = array(
|
56 |
'hook' => $action->get_hook(),
|
57 |
'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
|
@@ -60,6 +86,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
60 |
'schedule' => serialize( $action->get_schedule() ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
|
61 |
'group_id' => $this->get_group_id( $action->get_group() ),
|
62 |
);
|
|
|
63 |
$args = wp_json_encode( $action->get_args() );
|
64 |
if ( strlen( $args ) <= static::$max_index_length ) {
|
65 |
$data['args'] = $args;
|
@@ -68,25 +95,127 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
68 |
$data['extended_args'] = $args;
|
69 |
}
|
70 |
|
71 |
-
$
|
72 |
-
|
|
|
|
|
73 |
$action_id = $wpdb->insert_id;
|
74 |
|
75 |
if ( is_wp_error( $action_id ) ) {
|
76 |
throw new \RuntimeException( $action_id->get_error_message() );
|
77 |
} elseif ( empty( $action_id ) ) {
|
|
|
|
|
|
|
78 |
throw new \RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
|
79 |
}
|
80 |
|
81 |
do_action( 'action_scheduler_stored_action', $action_id );
|
82 |
|
83 |
return $action_id;
|
84 |
-
} catch ( Exception $e ) {
|
85 |
/* translators: %s: error message */
|
86 |
throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
87 |
}
|
88 |
}
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
/**
|
91 |
* Generate a hash from json_encoded $args using MD5 as this isn't for security.
|
92 |
*
|
@@ -232,7 +361,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
232 |
/**
|
233 |
* Returns the SQL statement to query (or count) actions.
|
234 |
*
|
235 |
-
* @since
|
236 |
*
|
237 |
* @param array $query Filtering options.
|
238 |
* @param string $select_or_count Whether the SQL should select and return the IDs or just the row count.
|
@@ -298,7 +427,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
298 |
$sql_params = array_merge( $sql_params, array_values( $statuses ) );
|
299 |
}
|
300 |
|
301 |
-
if ( $query['date'] instanceof DateTime ) {
|
302 |
$date = clone $query['date'];
|
303 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
304 |
$date_string = $date->format( 'Y-m-d H:i:s' );
|
@@ -307,7 +436,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
307 |
$sql_params[] = $date_string;
|
308 |
}
|
309 |
|
310 |
-
if ( $query['modified'] instanceof DateTime ) {
|
311 |
$modified = clone $query['modified'];
|
312 |
$modified->setTimezone( new \DateTimeZone( 'UTC' ) );
|
313 |
$date_string = $modified->format( 'Y-m-d H:i:s' );
|
@@ -384,7 +513,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
384 |
/**
|
385 |
* Query for action count or list of action IDs.
|
386 |
*
|
387 |
-
* @since
|
388 |
*
|
389 |
* @see ActionScheduler_Store::query_actions for $query arg usage.
|
390 |
*
|
@@ -446,7 +575,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
446 |
array( '%s' ),
|
447 |
array( '%d' )
|
448 |
);
|
449 |
-
if (
|
450 |
/* translators: %s: action ID */
|
451 |
throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
452 |
}
|
@@ -550,7 +679,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
550 |
*
|
551 |
* @param string $action_id Action ID.
|
552 |
*
|
553 |
-
* @return DateTime The local date the action is scheduled to run, or the date that it ran.
|
554 |
*/
|
555 |
public function get_date( $action_id ) {
|
556 |
$date = $this->get_date_gmt( $action_id );
|
@@ -564,7 +693,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
564 |
* @param int $action_id Action ID.
|
565 |
*
|
566 |
* @throws \InvalidArgumentException If action cannot be identified.
|
567 |
-
* @return DateTime The GMT date the action is scheduled to run, or the date that it ran.
|
568 |
*/
|
569 |
protected function get_date_gmt( $action_id ) {
|
570 |
/** @var \wpdb $wpdb */
|
@@ -584,13 +713,13 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
584 |
* Stake a claim on actions.
|
585 |
*
|
586 |
* @param int $max_actions Maximum number of action to include in claim.
|
587 |
-
* @param DateTime $before_date Jobs must be schedule before this date. Defaults to now.
|
588 |
* @param array $hooks Hooks to filter for.
|
589 |
* @param string $group Group to filter for.
|
590 |
*
|
591 |
* @return ActionScheduler_ActionClaim
|
592 |
*/
|
593 |
-
public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
|
594 |
$claim_id = $this->generate_claim_id();
|
595 |
|
596 |
$this->claim_before_date = $before_date;
|
@@ -620,7 +749,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
620 |
*
|
621 |
* @param string $claim_id Claim Id.
|
622 |
* @param int $limit Number of action to include in claim.
|
623 |
-
* @param DateTime $before_date Should use UTC timezone.
|
624 |
* @param array $hooks Hooks to filter for.
|
625 |
* @param string $group Group to filter for.
|
626 |
*
|
@@ -628,7 +757,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
628 |
* @throws \InvalidArgumentException Throws InvalidArgumentException if group doesn't exist.
|
629 |
* @throws \RuntimeException Throws RuntimeException if unable to claim action.
|
630 |
*/
|
631 |
-
protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) {
|
632 |
/** @var \wpdb $wpdb */
|
633 |
global $wpdb;
|
634 |
|
@@ -670,7 +799,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
670 |
/**
|
671 |
* Sets the order-by clause used in the action claim query.
|
672 |
*
|
673 |
-
* @since
|
674 |
*
|
675 |
* @param string $order_by_sql
|
676 |
*/
|
@@ -839,6 +968,15 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
839 |
if ( empty( $updated ) ) {
|
840 |
throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) ); //phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
|
841 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
842 |
}
|
843 |
|
844 |
/**
|
36 |
$table_maker->register_tables();
|
37 |
}
|
38 |
|
39 |
+
/**
|
40 |
+
* Save an action, checks if this is a unique action before actually saving.
|
41 |
+
*
|
42 |
+
* @param ActionScheduler_Action $action Action object.
|
43 |
+
* @param \DateTime $scheduled_date Optional schedule date. Default null.
|
44 |
+
*
|
45 |
+
* @return int Action ID.
|
46 |
+
* @throws RuntimeException Throws exception when saving the action fails.
|
47 |
+
*/
|
48 |
+
public function save_unique_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null ) {
|
49 |
+
return $this->save_action_to_db( $action, $scheduled_date, true );
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Save an action. Can save duplicate action as well, prefer using `save_unique_action` instead.
|
54 |
+
*
|
55 |
+
* @param ActionScheduler_Action $action Action object.
|
56 |
+
* @param \DateTime $scheduled_date Optional schedule date. Default null.
|
57 |
+
*
|
58 |
+
* @return int Action ID.
|
59 |
+
* @throws RuntimeException Throws exception when saving the action fails.
|
60 |
+
*/
|
61 |
+
public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null ) {
|
62 |
+
return $this->save_action_to_db( $action, $scheduled_date, false );
|
63 |
+
}
|
64 |
+
|
65 |
/**
|
66 |
* Save an action.
|
67 |
*
|
68 |
* @param ActionScheduler_Action $action Action object.
|
69 |
+
* @param ?DateTime $date Optional schedule date. Default null.
|
70 |
+
* @param bool $unique Whether the action should be unique.
|
71 |
*
|
72 |
* @return int Action ID.
|
73 |
* @throws RuntimeException Throws exception when saving the action fails.
|
74 |
*/
|
75 |
+
private function save_action_to_db( ActionScheduler_Action $action, DateTime $date = null, $unique = false ) {
|
76 |
+
global $wpdb;
|
77 |
|
78 |
+
try {
|
79 |
$this->validate_action( $action );
|
80 |
|
|
|
|
|
81 |
$data = array(
|
82 |
'hook' => $action->get_hook(),
|
83 |
'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
|
86 |
'schedule' => serialize( $action->get_schedule() ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
|
87 |
'group_id' => $this->get_group_id( $action->get_group() ),
|
88 |
);
|
89 |
+
|
90 |
$args = wp_json_encode( $action->get_args() );
|
91 |
if ( strlen( $args ) <= static::$max_index_length ) {
|
92 |
$data['args'] = $args;
|
95 |
$data['extended_args'] = $args;
|
96 |
}
|
97 |
|
98 |
+
$insert_sql = $this->build_insert_sql( $data, $unique );
|
99 |
+
|
100 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $insert_sql should be already prepared.
|
101 |
+
$wpdb->query( $insert_sql );
|
102 |
$action_id = $wpdb->insert_id;
|
103 |
|
104 |
if ( is_wp_error( $action_id ) ) {
|
105 |
throw new \RuntimeException( $action_id->get_error_message() );
|
106 |
} elseif ( empty( $action_id ) ) {
|
107 |
+
if ( $unique ) {
|
108 |
+
return 0;
|
109 |
+
}
|
110 |
throw new \RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
|
111 |
}
|
112 |
|
113 |
do_action( 'action_scheduler_stored_action', $action_id );
|
114 |
|
115 |
return $action_id;
|
116 |
+
} catch ( \Exception $e ) {
|
117 |
/* translators: %s: error message */
|
118 |
throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
119 |
}
|
120 |
}
|
121 |
|
122 |
+
/**
|
123 |
+
* Helper function to build insert query.
|
124 |
+
*
|
125 |
+
* @param array $data Row data for action.
|
126 |
+
* @param bool $unique Whether the action should be unique.
|
127 |
+
*
|
128 |
+
* @return string Insert query.
|
129 |
+
*/
|
130 |
+
private function build_insert_sql( array $data, $unique ) {
|
131 |
+
global $wpdb;
|
132 |
+
$columns = array_keys( $data );
|
133 |
+
$values = array_values( $data );
|
134 |
+
$placeholders = array_map( array( $this, 'get_placeholder_for_column' ), $columns );
|
135 |
+
|
136 |
+
$table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
|
137 |
+
|
138 |
+
$column_sql = '`' . implode( '`, `', $columns ) . '`';
|
139 |
+
$placeholder_sql = implode( ', ', $placeholders );
|
140 |
+
$where_clause = $this->build_where_clause_for_insert( $data, $table_name, $unique );
|
141 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $column_sql and $where_clause are already prepared. $placeholder_sql is hardcoded.
|
142 |
+
$insert_query = $wpdb->prepare(
|
143 |
+
"
|
144 |
+
INSERT INTO $table_name ( $column_sql )
|
145 |
+
SELECT $placeholder_sql FROM DUAL
|
146 |
+
WHERE ( $where_clause ) IS NULL",
|
147 |
+
$values
|
148 |
+
);
|
149 |
+
// phpcs:enable
|
150 |
+
|
151 |
+
return $insert_query;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Helper method to build where clause for action insert statement.
|
156 |
+
*
|
157 |
+
* @param array $data Row data for action.
|
158 |
+
* @param string $table_name Action table name.
|
159 |
+
* @param bool $unique Where action should be unique.
|
160 |
+
*
|
161 |
+
* @return string Where clause to be used with insert.
|
162 |
+
*/
|
163 |
+
private function build_where_clause_for_insert( $data, $table_name, $unique ) {
|
164 |
+
global $wpdb;
|
165 |
+
|
166 |
+
if ( ! $unique ) {
|
167 |
+
return 'SELECT NULL FROM DUAL';
|
168 |
+
}
|
169 |
+
|
170 |
+
$pending_statuses = array(
|
171 |
+
ActionScheduler_Store::STATUS_PENDING,
|
172 |
+
ActionScheduler_Store::STATUS_RUNNING,
|
173 |
+
);
|
174 |
+
$pending_status_placeholders = implode( ', ', array_fill( 0, count( $pending_statuses ), '%s' ) );
|
175 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $pending_status_placeholders is hardcoded.
|
176 |
+
$where_clause = $wpdb->prepare(
|
177 |
+
"
|
178 |
+
SELECT action_id FROM $table_name
|
179 |
+
WHERE status IN ( $pending_status_placeholders )
|
180 |
+
AND hook = %s
|
181 |
+
AND `group_id` = %d
|
182 |
+
",
|
183 |
+
array_merge(
|
184 |
+
$pending_statuses,
|
185 |
+
array(
|
186 |
+
$data['hook'],
|
187 |
+
$data['group_id'],
|
188 |
+
)
|
189 |
+
)
|
190 |
+
);
|
191 |
+
// phpcs:enable
|
192 |
+
|
193 |
+
return "$where_clause" . ' LIMIT 1';
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Helper method to get $wpdb->prepare placeholder for a given column name.
|
198 |
+
*
|
199 |
+
* @param string $column_name Name of column in actions table.
|
200 |
+
*
|
201 |
+
* @return string Placeholder to use for given column.
|
202 |
+
*/
|
203 |
+
private function get_placeholder_for_column( $column_name ) {
|
204 |
+
$string_columns = array(
|
205 |
+
'hook',
|
206 |
+
'status',
|
207 |
+
'scheduled_date_gmt',
|
208 |
+
'scheduled_date_local',
|
209 |
+
'args',
|
210 |
+
'schedule',
|
211 |
+
'last_attempt_gmt',
|
212 |
+
'last_attempt_local',
|
213 |
+
'extended_args',
|
214 |
+
);
|
215 |
+
|
216 |
+
return in_array( $column_name, $string_columns ) ? '%s' : '%d';
|
217 |
+
}
|
218 |
+
|
219 |
/**
|
220 |
* Generate a hash from json_encoded $args using MD5 as this isn't for security.
|
221 |
*
|
361 |
/**
|
362 |
* Returns the SQL statement to query (or count) actions.
|
363 |
*
|
364 |
+
* @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
|
365 |
*
|
366 |
* @param array $query Filtering options.
|
367 |
* @param string $select_or_count Whether the SQL should select and return the IDs or just the row count.
|
427 |
$sql_params = array_merge( $sql_params, array_values( $statuses ) );
|
428 |
}
|
429 |
|
430 |
+
if ( $query['date'] instanceof \DateTime ) {
|
431 |
$date = clone $query['date'];
|
432 |
$date->setTimezone( new \DateTimeZone( 'UTC' ) );
|
433 |
$date_string = $date->format( 'Y-m-d H:i:s' );
|
436 |
$sql_params[] = $date_string;
|
437 |
}
|
438 |
|
439 |
+
if ( $query['modified'] instanceof \DateTime ) {
|
440 |
$modified = clone $query['modified'];
|
441 |
$modified->setTimezone( new \DateTimeZone( 'UTC' ) );
|
442 |
$date_string = $modified->format( 'Y-m-d H:i:s' );
|
513 |
/**
|
514 |
* Query for action count or list of action IDs.
|
515 |
*
|
516 |
+
* @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
|
517 |
*
|
518 |
* @see ActionScheduler_Store::query_actions for $query arg usage.
|
519 |
*
|
575 |
array( '%s' ),
|
576 |
array( '%d' )
|
577 |
);
|
578 |
+
if ( false === $updated ) {
|
579 |
/* translators: %s: action ID */
|
580 |
throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
581 |
}
|
679 |
*
|
680 |
* @param string $action_id Action ID.
|
681 |
*
|
682 |
+
* @return \DateTime The local date the action is scheduled to run, or the date that it ran.
|
683 |
*/
|
684 |
public function get_date( $action_id ) {
|
685 |
$date = $this->get_date_gmt( $action_id );
|
693 |
* @param int $action_id Action ID.
|
694 |
*
|
695 |
* @throws \InvalidArgumentException If action cannot be identified.
|
696 |
+
* @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
|
697 |
*/
|
698 |
protected function get_date_gmt( $action_id ) {
|
699 |
/** @var \wpdb $wpdb */
|
713 |
* Stake a claim on actions.
|
714 |
*
|
715 |
* @param int $max_actions Maximum number of action to include in claim.
|
716 |
+
* @param \DateTime $before_date Jobs must be schedule before this date. Defaults to now.
|
717 |
* @param array $hooks Hooks to filter for.
|
718 |
* @param string $group Group to filter for.
|
719 |
*
|
720 |
* @return ActionScheduler_ActionClaim
|
721 |
*/
|
722 |
+
public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
|
723 |
$claim_id = $this->generate_claim_id();
|
724 |
|
725 |
$this->claim_before_date = $before_date;
|
749 |
*
|
750 |
* @param string $claim_id Claim Id.
|
751 |
* @param int $limit Number of action to include in claim.
|
752 |
+
* @param \DateTime $before_date Should use UTC timezone.
|
753 |
* @param array $hooks Hooks to filter for.
|
754 |
* @param string $group Group to filter for.
|
755 |
*
|
757 |
* @throws \InvalidArgumentException Throws InvalidArgumentException if group doesn't exist.
|
758 |
* @throws \RuntimeException Throws RuntimeException if unable to claim action.
|
759 |
*/
|
760 |
+
protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
|
761 |
/** @var \wpdb $wpdb */
|
762 |
global $wpdb;
|
763 |
|
799 |
/**
|
800 |
* Sets the order-by clause used in the action claim query.
|
801 |
*
|
802 |
+
* @since 3.4.0
|
803 |
*
|
804 |
* @param string $order_by_sql
|
805 |
*/
|
968 |
if ( empty( $updated ) ) {
|
969 |
throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) ); //phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment
|
970 |
}
|
971 |
+
|
972 |
+
/**
|
973 |
+
* Fires after a scheduled action has been completed.
|
974 |
+
*
|
975 |
+
* @since 3.4.2
|
976 |
+
*
|
977 |
+
* @param int $action_id Action ID.
|
978 |
+
*/
|
979 |
+
do_action( 'action_scheduler_completed_action', $action_id );
|
980 |
}
|
981 |
|
982 |
/**
|
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
CHANGED
@@ -452,7 +452,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
452 |
/**
|
453 |
* Query for action count or list of action IDs.
|
454 |
*
|
455 |
-
* @since
|
456 |
*
|
457 |
* @see ActionScheduler_Store::query_actions for $query arg usage.
|
458 |
*
|
@@ -987,6 +987,15 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
987 |
if ( is_wp_error( $result ) ) {
|
988 |
throw new RuntimeException( $result->get_error_message() );
|
989 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
990 |
}
|
991 |
|
992 |
/**
|
452 |
/**
|
453 |
* Query for action count or list of action IDs.
|
454 |
*
|
455 |
+
* @since 3.3.0 $query['status'] accepts array of statuses instead of a single status.
|
456 |
*
|
457 |
* @see ActionScheduler_Store::query_actions for $query arg usage.
|
458 |
*
|
987 |
if ( is_wp_error( $result ) ) {
|
988 |
throw new RuntimeException( $result->get_error_message() );
|
989 |
}
|
990 |
+
|
991 |
+
/**
|
992 |
+
* Fires after a scheduled action has been completed.
|
993 |
+
*
|
994 |
+
* @since 3.4.2
|
995 |
+
*
|
996 |
+
* @param int $action_id Action ID.
|
997 |
+
*/
|
998 |
+
do_action( 'action_scheduler_completed_action', $action_id );
|
999 |
}
|
1000 |
|
1001 |
/**
|
includes/vendor/action-scheduler/classes/migration/ActionMigrator.php
CHANGED
@@ -46,7 +46,7 @@ class ActionMigrator {
|
|
46 |
try {
|
47 |
$action = $this->source->fetch_action( $source_action_id );
|
48 |
$status = $this->source->get_status( $source_action_id );
|
49 |
-
} catch ( Exception $e ) {
|
50 |
$action = null;
|
51 |
$status = '';
|
52 |
}
|
@@ -57,7 +57,7 @@ class ActionMigrator {
|
|
57 |
// delete it and move on
|
58 |
try {
|
59 |
$this->source->delete_action( $source_action_id );
|
60 |
-
} catch ( Exception $e ) {
|
61 |
// nothing to do, it didn't exist in the first place
|
62 |
}
|
63 |
do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination );
|
@@ -71,7 +71,7 @@ class ActionMigrator {
|
|
71 |
$last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null;
|
72 |
|
73 |
$destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date );
|
74 |
-
} catch ( Exception $e ) {
|
75 |
do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination );
|
76 |
|
77 |
return 0; // could not save the action in the new store
|
@@ -97,7 +97,7 @@ class ActionMigrator {
|
|
97 |
do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
98 |
|
99 |
return $destination_action_id;
|
100 |
-
} catch ( Exception $e ) {
|
101 |
// could not delete from the old store
|
102 |
$this->source->mark_migrated( $source_action_id );
|
103 |
do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
46 |
try {
|
47 |
$action = $this->source->fetch_action( $source_action_id );
|
48 |
$status = $this->source->get_status( $source_action_id );
|
49 |
+
} catch ( \Exception $e ) {
|
50 |
$action = null;
|
51 |
$status = '';
|
52 |
}
|
57 |
// delete it and move on
|
58 |
try {
|
59 |
$this->source->delete_action( $source_action_id );
|
60 |
+
} catch ( \Exception $e ) {
|
61 |
// nothing to do, it didn't exist in the first place
|
62 |
}
|
63 |
do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination );
|
71 |
$last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null;
|
72 |
|
73 |
$destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date );
|
74 |
+
} catch ( \Exception $e ) {
|
75 |
do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination );
|
76 |
|
77 |
return 0; // could not save the action in the new store
|
97 |
do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
98 |
|
99 |
return $destination_action_id;
|
100 |
+
} catch ( \Exception $e ) {
|
101 |
// could not delete from the old store
|
102 |
$this->source->mark_migrated( $source_action_id );
|
103 |
do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination );
|
includes/vendor/action-scheduler/classes/migration/ActionScheduler_DBStoreMigrator.php
CHANGED
@@ -17,13 +17,13 @@ class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore {
|
|
17 |
* that when first saving the action.
|
18 |
*
|
19 |
* @param ActionScheduler_Action $action
|
20 |
-
* @param DateTime $scheduled_date Optional date of the first instance to store.
|
21 |
-
* @param DateTime $last_attempt_date Optional date the action was last attempted.
|
22 |
*
|
23 |
* @return string The action ID
|
24 |
* @throws \RuntimeException When the action is not saved.
|
25 |
*/
|
26 |
-
public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = null, DateTime $last_attempt_date = null ){
|
27 |
try {
|
28 |
/** @var \wpdb $wpdb */
|
29 |
global $wpdb;
|
@@ -40,7 +40,7 @@ class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore {
|
|
40 |
}
|
41 |
|
42 |
return $action_id;
|
43 |
-
} catch ( Exception $e ) {
|
44 |
throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
45 |
}
|
46 |
}
|
17 |
* that when first saving the action.
|
18 |
*
|
19 |
* @param ActionScheduler_Action $action
|
20 |
+
* @param \DateTime $scheduled_date Optional date of the first instance to store.
|
21 |
+
* @param \DateTime $last_attempt_date Optional date the action was last attempted.
|
22 |
*
|
23 |
* @return string The action ID
|
24 |
* @throws \RuntimeException When the action is not saved.
|
25 |
*/
|
26 |
+
public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){
|
27 |
try {
|
28 |
/** @var \wpdb $wpdb */
|
29 |
global $wpdb;
|
40 |
}
|
41 |
|
42 |
return $action_id;
|
43 |
+
} catch ( \Exception $e ) {
|
44 |
throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
45 |
}
|
46 |
}
|
includes/vendor/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
CHANGED
@@ -37,12 +37,12 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
|
|
37 |
case self::LOG_TABLE:
|
38 |
|
39 |
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
|
40 |
-
return "CREATE TABLE
|
41 |
log_id bigint(20) unsigned NOT NULL auto_increment,
|
42 |
action_id bigint(20) unsigned NOT NULL,
|
43 |
message text NOT NULL,
|
44 |
-
log_date_gmt datetime NULL default '$
|
45 |
-
log_date_local datetime NULL default '$
|
46 |
PRIMARY KEY (log_id),
|
47 |
KEY action_id (action_id),
|
48 |
KEY log_date_gmt (log_date_gmt)
|
@@ -74,14 +74,14 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
|
|
74 |
|
75 |
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
76 |
$table_name = $wpdb->prefix . 'actionscheduler_logs';
|
77 |
-
$table_list = $wpdb->get_col( "SHOW TABLES LIKE '$
|
78 |
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
|
79 |
|
80 |
if ( ! empty( $table_list ) ) {
|
81 |
$query = "
|
82 |
-
ALTER TABLE $
|
83 |
-
MODIFY COLUMN log_date_gmt datetime NULL default '$
|
84 |
-
MODIFY COLUMN log_date_local datetime NULL default '$
|
85 |
";
|
86 |
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
87 |
}
|
37 |
case self::LOG_TABLE:
|
38 |
|
39 |
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
|
40 |
+
return "CREATE TABLE $table_name (
|
41 |
log_id bigint(20) unsigned NOT NULL auto_increment,
|
42 |
action_id bigint(20) unsigned NOT NULL,
|
43 |
message text NOT NULL,
|
44 |
+
log_date_gmt datetime NULL default '{$default_date}',
|
45 |
+
log_date_local datetime NULL default '{$default_date}',
|
46 |
PRIMARY KEY (log_id),
|
47 |
KEY action_id (action_id),
|
48 |
KEY log_date_gmt (log_date_gmt)
|
74 |
|
75 |
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
76 |
$table_name = $wpdb->prefix . 'actionscheduler_logs';
|
77 |
+
$table_list = $wpdb->get_col( "SHOW TABLES LIKE '{$table_name}'" );
|
78 |
$default_date = ActionScheduler_StoreSchema::DEFAULT_DATE;
|
79 |
|
80 |
if ( ! empty( $table_list ) ) {
|
81 |
$query = "
|
82 |
+
ALTER TABLE {$table_name}
|
83 |
+
MODIFY COLUMN log_date_gmt datetime NULL default '{$default_date}',
|
84 |
+
MODIFY COLUMN log_date_local datetime NULL default '{$default_date}'
|
85 |
";
|
86 |
$wpdb->query( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
87 |
}
|
includes/vendor/action-scheduler/functions.php
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* General API functions for scheduling actions
|
|
|
|
|
5 |
*/
|
6 |
|
7 |
/**
|
@@ -10,57 +11,61 @@
|
|
10 |
* @param string $hook The hook to trigger.
|
11 |
* @param array $args Arguments to pass when the hook triggers.
|
12 |
* @param string $group The group to assign this job to.
|
|
|
|
|
13 |
* @return int The action ID.
|
14 |
*/
|
15 |
-
function as_enqueue_async_action( $hook, $args = array(), $group = '' ) {
|
16 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
17 |
return 0;
|
18 |
}
|
19 |
-
return ActionScheduler::factory()->
|
20 |
}
|
21 |
|
22 |
/**
|
23 |
* Schedule an action to run one time
|
24 |
*
|
25 |
-
* @param int
|
26 |
* @param string $hook The hook to trigger.
|
27 |
-
* @param array
|
28 |
* @param string $group The group to assign this job to.
|
|
|
29 |
*
|
30 |
* @return int The action ID.
|
31 |
*/
|
32 |
-
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '' ) {
|
33 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
34 |
return 0;
|
35 |
}
|
36 |
-
return ActionScheduler::factory()->
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
* Schedule a recurring action
|
41 |
*
|
42 |
-
* @param int
|
43 |
-
* @param int
|
44 |
* @param string $hook The hook to trigger.
|
45 |
-
* @param array
|
46 |
* @param string $group The group to assign this job to.
|
|
|
47 |
*
|
48 |
* @return int The action ID.
|
49 |
*/
|
50 |
-
function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) {
|
51 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
52 |
return 0;
|
53 |
}
|
54 |
-
return ActionScheduler::factory()->
|
55 |
}
|
56 |
|
57 |
/**
|
58 |
* Schedule an action that recurs on a cron-like schedule.
|
59 |
*
|
60 |
-
* @param int
|
61 |
-
*
|
62 |
-
*
|
63 |
-
* @param string $schedule A cron-link schedule string
|
64 |
* @see http://en.wikipedia.org/wiki/Cron
|
65 |
* * * * * * *
|
66 |
* ┬ ┬ ┬ ┬ ┬ ┬
|
@@ -72,16 +77,17 @@ function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook,
|
|
72 |
* | +-------------------- hour (0 - 23)
|
73 |
* +------------------------- min (0 - 59)
|
74 |
* @param string $hook The hook to trigger.
|
75 |
-
* @param array
|
76 |
* @param string $group The group to assign this job to.
|
|
|
77 |
*
|
78 |
* @return int The action ID.
|
79 |
*/
|
80 |
-
function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '' ) {
|
81 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
82 |
return 0;
|
83 |
}
|
84 |
-
return ActionScheduler::factory()->
|
85 |
}
|
86 |
|
87 |
/**
|
@@ -95,10 +101,10 @@ function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(),
|
|
95 |
* by this method also.
|
96 |
*
|
97 |
* @param string $hook The hook that the job will trigger.
|
98 |
-
* @param array
|
99 |
* @param string $group The group the job is assigned to.
|
100 |
*
|
101 |
-
* @return
|
102 |
*/
|
103 |
function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
104 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
@@ -116,8 +122,22 @@ function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
|
116 |
}
|
117 |
|
118 |
$action_id = ActionScheduler::store()->query_action( $params );
|
|
|
119 |
if ( $action_id ) {
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
|
123 |
return $action_id;
|
@@ -127,7 +147,7 @@ function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
|
127 |
* Cancel all occurrences of a scheduled action.
|
128 |
*
|
129 |
* @param string $hook The hook that the job will trigger.
|
130 |
-
* @param array
|
131 |
* @param string $group The group the job is assigned to.
|
132 |
*/
|
133 |
function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
|
@@ -158,9 +178,9 @@ function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
|
|
158 |
* returned. Or there may be no async, in-progress or pending action for this hook, in which case,
|
159 |
* boolean false will be the return value.
|
160 |
*
|
161 |
-
* @param string $hook
|
162 |
-
* @param array
|
163 |
-
* @param string $group
|
164 |
*
|
165 |
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
|
166 |
*/
|
@@ -196,7 +216,7 @@ function as_next_scheduled_action( $hook, $args = null, $group = '' ) {
|
|
196 |
$scheduled_date = $action->get_schedule()->get_date();
|
197 |
if ( $scheduled_date ) {
|
198 |
return (int) $scheduled_date->format( 'U' );
|
199 |
-
} elseif ( null === $scheduled_date ) { // pending async action with NullSchedule
|
200 |
return true;
|
201 |
}
|
202 |
|
@@ -209,7 +229,7 @@ function as_next_scheduled_action( $hook, $args = null, $group = '' ) {
|
|
209 |
* It's recommended to use this function when you need to know whether a specific action is currently scheduled
|
210 |
* (pending or in-progress).
|
211 |
*
|
212 |
-
* @since
|
213 |
*
|
214 |
* @param string $hook The hook of the action.
|
215 |
* @param array $args Args that have been passed to the action. Null will matches any args.
|
@@ -223,10 +243,10 @@ function as_has_scheduled_action( $hook, $args = null, $group = '' ) {
|
|
223 |
}
|
224 |
|
225 |
$query_args = array(
|
226 |
-
'hook'
|
227 |
-
'status'
|
228 |
-
'group'
|
229 |
-
'orderby'
|
230 |
);
|
231 |
|
232 |
if ( null !== $args ) {
|
@@ -235,26 +255,26 @@ function as_has_scheduled_action( $hook, $args = null, $group = '' ) {
|
|
235 |
|
236 |
$action_id = ActionScheduler::store()->query_action( $query_args );
|
237 |
|
238 |
-
return
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
* Find scheduled actions
|
243 |
*
|
244 |
-
* @param array
|
245 |
-
*
|
246 |
-
*
|
247 |
-
*
|
248 |
-
*
|
249 |
-
*
|
250 |
-
*
|
251 |
-
*
|
252 |
-
*
|
253 |
-
*
|
254 |
-
*
|
255 |
-
*
|
256 |
-
*
|
257 |
-
*
|
258 |
*
|
259 |
* @param string $return_format OBJECT, ARRAY_A, or ids.
|
260 |
*
|
@@ -265,25 +285,25 @@ function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
|
|
265 |
return array();
|
266 |
}
|
267 |
$store = ActionScheduler::store();
|
268 |
-
foreach ( array('date', 'modified') as $key ) {
|
269 |
-
if ( isset($args[$key]) ) {
|
270 |
-
$args[$key] = as_get_datetime_object($args[$key]);
|
271 |
}
|
272 |
}
|
273 |
$ids = $store->query_actions( $args );
|
274 |
|
275 |
-
if (
|
276 |
return $ids;
|
277 |
}
|
278 |
|
279 |
$actions = array();
|
280 |
foreach ( $ids as $action_id ) {
|
281 |
-
$actions[$action_id] = $store->fetch_action( $action_id );
|
282 |
}
|
283 |
|
284 |
-
if (
|
285 |
foreach ( $actions as $action_id => $action_object ) {
|
286 |
-
$actions[$action_id] = get_object_vars($action_object);
|
287 |
}
|
288 |
}
|
289 |
|
@@ -302,7 +322,7 @@ function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
|
|
302 |
* timezone when instantiating datetimes rather than leaving it up to
|
303 |
* the PHP default.
|
304 |
*
|
305 |
-
* @param mixed
|
306 |
* @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php.
|
307 |
*
|
308 |
* @return ActionScheduler_DateTime
|
@@ -313,7 +333,7 @@ function as_get_datetime_object( $date_string = null, $timezone = 'UTC' ) {
|
|
313 |
} elseif ( is_numeric( $date_string ) ) {
|
314 |
$date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) );
|
315 |
} else {
|
316 |
-
$date = new ActionScheduler_DateTime( $date_string, new DateTimeZone( $timezone ) );
|
317 |
}
|
318 |
return $date;
|
319 |
}
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* General API functions for scheduling actions
|
4 |
+
*
|
5 |
+
* @package ActionScheduler.
|
6 |
*/
|
7 |
|
8 |
/**
|
11 |
* @param string $hook The hook to trigger.
|
12 |
* @param array $args Arguments to pass when the hook triggers.
|
13 |
* @param string $group The group to assign this job to.
|
14 |
+
* @param bool $unique Whether the action should be unique.
|
15 |
+
*
|
16 |
* @return int The action ID.
|
17 |
*/
|
18 |
+
function as_enqueue_async_action( $hook, $args = array(), $group = '', $unique = false ) {
|
19 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
20 |
return 0;
|
21 |
}
|
22 |
+
return ActionScheduler::factory()->async_unique( $hook, $args, $group, $unique );
|
23 |
}
|
24 |
|
25 |
/**
|
26 |
* Schedule an action to run one time
|
27 |
*
|
28 |
+
* @param int $timestamp When the job will run.
|
29 |
* @param string $hook The hook to trigger.
|
30 |
+
* @param array $args Arguments to pass when the hook triggers.
|
31 |
* @param string $group The group to assign this job to.
|
32 |
+
* @param bool $unique Whether the action should be unique.
|
33 |
*
|
34 |
* @return int The action ID.
|
35 |
*/
|
36 |
+
function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '', $unique = false ) {
|
37 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
38 |
return 0;
|
39 |
}
|
40 |
+
return ActionScheduler::factory()->single_unique( $hook, $args, $timestamp, $group, $unique );
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
* Schedule a recurring action
|
45 |
*
|
46 |
+
* @param int $timestamp When the first instance of the job will run.
|
47 |
+
* @param int $interval_in_seconds How long to wait between runs.
|
48 |
* @param string $hook The hook to trigger.
|
49 |
+
* @param array $args Arguments to pass when the hook triggers.
|
50 |
* @param string $group The group to assign this job to.
|
51 |
+
* @param bool $unique Whether the action should be unique.
|
52 |
*
|
53 |
* @return int The action ID.
|
54 |
*/
|
55 |
+
function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '', $unique = false ) {
|
56 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
57 |
return 0;
|
58 |
}
|
59 |
+
return ActionScheduler::factory()->recurring_unique( $hook, $args, $timestamp, $interval_in_seconds, $group, $unique );
|
60 |
}
|
61 |
|
62 |
/**
|
63 |
* Schedule an action that recurs on a cron-like schedule.
|
64 |
*
|
65 |
+
* @param int $timestamp The first instance of the action will be scheduled
|
66 |
+
* to run at a time calculated after this timestamp matching the cron
|
67 |
+
* expression. This can be used to delay the first instance of the action.
|
68 |
+
* @param string $schedule A cron-link schedule string.
|
69 |
* @see http://en.wikipedia.org/wiki/Cron
|
70 |
* * * * * * *
|
71 |
* ┬ ┬ ┬ ┬ ┬ ┬
|
77 |
* | +-------------------- hour (0 - 23)
|
78 |
* +------------------------- min (0 - 59)
|
79 |
* @param string $hook The hook to trigger.
|
80 |
+
* @param array $args Arguments to pass when the hook triggers.
|
81 |
* @param string $group The group to assign this job to.
|
82 |
+
* @param bool $unique Whether the action should be unique.
|
83 |
*
|
84 |
* @return int The action ID.
|
85 |
*/
|
86 |
+
function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '', $unique = false ) {
|
87 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
88 |
return 0;
|
89 |
}
|
90 |
+
return ActionScheduler::factory()->cron_unique( $hook, $args, $timestamp, $schedule, $group, $unique );
|
91 |
}
|
92 |
|
93 |
/**
|
101 |
* by this method also.
|
102 |
*
|
103 |
* @param string $hook The hook that the job will trigger.
|
104 |
+
* @param array $args Args that would have been passed to the job.
|
105 |
* @param string $group The group the job is assigned to.
|
106 |
*
|
107 |
+
* @return int|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
|
108 |
*/
|
109 |
function as_unschedule_action( $hook, $args = array(), $group = '' ) {
|
110 |
if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
|
122 |
}
|
123 |
|
124 |
$action_id = ActionScheduler::store()->query_action( $params );
|
125 |
+
|
126 |
if ( $action_id ) {
|
127 |
+
try {
|
128 |
+
ActionScheduler::store()->cancel_action( $action_id );
|
129 |
+
} catch ( Exception $exception ) {
|
130 |
+
ActionScheduler::logger()->log(
|
131 |
+
$action_id,
|
132 |
+
sprintf(
|
133 |
+
/* translators: %s is the name of the hook to be cancelled. */
|
134 |
+
__( 'Caught exception while cancelling action: %s', 'action-scheduler' ),
|
135 |
+
esc_attr( $hook )
|
136 |
+
)
|
137 |
+
);
|
138 |
+
|
139 |
+
$action_id = null;
|
140 |
+
}
|
141 |
}
|
142 |
|
143 |
return $action_id;
|
147 |
* Cancel all occurrences of a scheduled action.
|
148 |
*
|
149 |
* @param string $hook The hook that the job will trigger.
|
150 |
+
* @param array $args Args that would have been passed to the job.
|
151 |
* @param string $group The group the job is assigned to.
|
152 |
*/
|
153 |
function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
|
178 |
* returned. Or there may be no async, in-progress or pending action for this hook, in which case,
|
179 |
* boolean false will be the return value.
|
180 |
*
|
181 |
+
* @param string $hook Name of the hook to search for.
|
182 |
+
* @param array $args Arguments of the action to be searched.
|
183 |
+
* @param string $group Group of the action to be searched.
|
184 |
*
|
185 |
* @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
|
186 |
*/
|
216 |
$scheduled_date = $action->get_schedule()->get_date();
|
217 |
if ( $scheduled_date ) {
|
218 |
return (int) $scheduled_date->format( 'U' );
|
219 |
+
} elseif ( null === $scheduled_date ) { // pending async action with NullSchedule.
|
220 |
return true;
|
221 |
}
|
222 |
|
229 |
* It's recommended to use this function when you need to know whether a specific action is currently scheduled
|
230 |
* (pending or in-progress).
|
231 |
*
|
232 |
+
* @since 3.3.0
|
233 |
*
|
234 |
* @param string $hook The hook of the action.
|
235 |
* @param array $args Args that have been passed to the action. Null will matches any args.
|
243 |
}
|
244 |
|
245 |
$query_args = array(
|
246 |
+
'hook' => $hook,
|
247 |
+
'status' => array( ActionScheduler_Store::STATUS_RUNNING, ActionScheduler_Store::STATUS_PENDING ),
|
248 |
+
'group' => $group,
|
249 |
+
'orderby' => 'none',
|
250 |
);
|
251 |
|
252 |
if ( null !== $args ) {
|
255 |
|
256 |
$action_id = ActionScheduler::store()->query_action( $query_args );
|
257 |
|
258 |
+
return null !== $action_id;
|
259 |
}
|
260 |
|
261 |
/**
|
262 |
* Find scheduled actions
|
263 |
*
|
264 |
+
* @param array $args Possible arguments, with their default values.
|
265 |
+
* 'hook' => '' - the name of the action that will be triggered.
|
266 |
+
* 'args' => NULL - the args array that will be passed with the action.
|
267 |
+
* '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.
|
268 |
+
* 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='.
|
269 |
+
* 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
|
270 |
+
* 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='.
|
271 |
+
* 'group' => '' - the group the action belongs to.
|
272 |
+
* 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING.
|
273 |
+
* 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID.
|
274 |
+
* 'per_page' => 5 - Number of results to return.
|
275 |
+
* 'offset' => 0.
|
276 |
+
* 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', 'date' or 'none'.
|
277 |
+
* 'order' => 'ASC'.
|
278 |
*
|
279 |
* @param string $return_format OBJECT, ARRAY_A, or ids.
|
280 |
*
|
285 |
return array();
|
286 |
}
|
287 |
$store = ActionScheduler::store();
|
288 |
+
foreach ( array( 'date', 'modified' ) as $key ) {
|
289 |
+
if ( isset( $args[ $key ] ) ) {
|
290 |
+
$args[ $key ] = as_get_datetime_object( $args[ $key ] );
|
291 |
}
|
292 |
}
|
293 |
$ids = $store->query_actions( $args );
|
294 |
|
295 |
+
if ( 'ids' === $return_format || 'int' === $return_format ) {
|
296 |
return $ids;
|
297 |
}
|
298 |
|
299 |
$actions = array();
|
300 |
foreach ( $ids as $action_id ) {
|
301 |
+
$actions[ $action_id ] = $store->fetch_action( $action_id );
|
302 |
}
|
303 |
|
304 |
+
if ( ARRAY_A == $return_format ) {
|
305 |
foreach ( $actions as $action_id => $action_object ) {
|
306 |
+
$actions[ $action_id ] = get_object_vars( $action_object );
|
307 |
}
|
308 |
}
|
309 |
|
322 |
* timezone when instantiating datetimes rather than leaving it up to
|
323 |
* the PHP default.
|
324 |
*
|
325 |
+
* @param mixed $date_string A date/time string. Valid formats are explained in http://php.net/manual/en/datetime.formats.php.
|
326 |
* @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php.
|
327 |
*
|
328 |
* @return ActionScheduler_DateTime
|
333 |
} elseif ( is_numeric( $date_string ) ) {
|
334 |
$date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) );
|
335 |
} else {
|
336 |
+
$date = new ActionScheduler_DateTime( null === $date_string ? 'now' : $date_string, new DateTimeZone( $timezone ) );
|
337 |
}
|
338 |
return $date;
|
339 |
}
|
includes/vendor/action-scheduler/lib/WP_Async_Request.php
CHANGED
@@ -104,10 +104,17 @@ if ( ! class_exists( 'WP_Async_Request' ) ) {
|
|
104 |
return $this->query_args;
|
105 |
}
|
106 |
|
107 |
-
|
108 |
'action' => $this->identifier,
|
109 |
'nonce' => wp_create_nonce( $this->identifier ),
|
110 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
112 |
|
113 |
/**
|
@@ -120,7 +127,14 @@ if ( ! class_exists( 'WP_Async_Request' ) ) {
|
|
120 |
return $this->query_url;
|
121 |
}
|
122 |
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
/**
|
@@ -133,13 +147,20 @@ if ( ! class_exists( 'WP_Async_Request' ) ) {
|
|
133 |
return $this->post_args;
|
134 |
}
|
135 |
|
136 |
-
|
137 |
'timeout' => 0.01,
|
138 |
'blocking' => false,
|
139 |
'body' => $this->data,
|
140 |
'cookies' => $_COOKIE,
|
141 |
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
142 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
}
|
144 |
|
145 |
/**
|
104 |
return $this->query_args;
|
105 |
}
|
106 |
|
107 |
+
$args = array(
|
108 |
'action' => $this->identifier,
|
109 |
'nonce' => wp_create_nonce( $this->identifier ),
|
110 |
);
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Filters the post arguments used during an async request.
|
114 |
+
*
|
115 |
+
* @param array $url
|
116 |
+
*/
|
117 |
+
return apply_filters( $this->identifier . '_query_args', $args );
|
118 |
}
|
119 |
|
120 |
/**
|
127 |
return $this->query_url;
|
128 |
}
|
129 |
|
130 |
+
$url = admin_url( 'admin-ajax.php' );
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Filters the post arguments used during an async request.
|
134 |
+
*
|
135 |
+
* @param string $url
|
136 |
+
*/
|
137 |
+
return apply_filters( $this->identifier . '_query_url', $url );
|
138 |
}
|
139 |
|
140 |
/**
|
147 |
return $this->post_args;
|
148 |
}
|
149 |
|
150 |
+
$args = array(
|
151 |
'timeout' => 0.01,
|
152 |
'blocking' => false,
|
153 |
'body' => $this->data,
|
154 |
'cookies' => $_COOKIE,
|
155 |
'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
|
156 |
);
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Filters the post arguments used during an async request.
|
160 |
+
*
|
161 |
+
* @param array $args
|
162 |
+
*/
|
163 |
+
return apply_filters( $this->identifier . '_post_args', $args );
|
164 |
}
|
165 |
|
166 |
/**
|
mailchimp-woocommerce.php
CHANGED
@@ -16,7 +16,7 @@
|
|
16 |
* Plugin Name: Mailchimp for WooCommerce
|
17 |
* Plugin URI: https://mailchimp.com/connect-your-store/
|
18 |
* Description: Connects WooCommerce to Mailchimp to sync your store data, send targeted campaigns to your customers, and sell more stuff.
|
19 |
-
* Version: 2.7.
|
20 |
* Author: Mailchimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|
@@ -26,7 +26,7 @@
|
|
26 |
* Requires at least: 4.9
|
27 |
* Tested up to: 6.0
|
28 |
* WC requires at least: 3.5
|
29 |
-
* WC tested up to:
|
30 |
*/
|
31 |
|
32 |
// If this file is called directly, abort.
|
16 |
* Plugin Name: Mailchimp for WooCommerce
|
17 |
* Plugin URI: https://mailchimp.com/connect-your-store/
|
18 |
* Description: Connects WooCommerce to Mailchimp to sync your store data, send targeted campaigns to your customers, and sell more stuff.
|
19 |
+
* Version: 2.7.6
|
20 |
* Author: Mailchimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|
26 |
* Requires at least: 4.9
|
27 |
* Tested up to: 6.0
|
28 |
* WC requires at least: 3.5
|
29 |
+
* WC tested up to: 7.1
|
30 |
*/
|
31 |
|
32 |
// If this file is called directly, abort.
|
public/class-mailchimp-woocommerce-public.php
CHANGED
@@ -108,7 +108,7 @@ class MailChimp_WooCommerce_Public {
|
|
108 |
public function user_my_account_opt_in_save($user_id)
|
109 |
{
|
110 |
$subscribed = isset($_POST['mailchimp_woocommerce_is_subscribed_checkbox']) &&
|
111 |
-
$_POST['mailchimp_woocommerce_is_subscribed_checkbox'] == 'on';
|
112 |
update_user_meta( $user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
|
113 |
}
|
114 |
|
108 |
public function user_my_account_opt_in_save($user_id)
|
109 |
{
|
110 |
$subscribed = isset($_POST['mailchimp_woocommerce_is_subscribed_checkbox']) &&
|
111 |
+
( $_POST['mailchimp_woocommerce_is_subscribed_checkbox'] == 'on' || $_POST['mailchimp_woocommerce_is_subscribed_checkbox'] == '1');
|
112 |
update_user_meta( $user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
|
113 |
}
|
114 |
|