Version Description
- fixes abandoned cart issues with Paypal
- resolves Action Scheduler 3.0 compatiblity issues
- Fixes missing product images
Download this release
Release Info
Developer | ryanhungate |
Plugin | MailChimp for WooCommerce |
Version | 2.3.3 |
Comparing to | |
See all releases |
Code changes from version 2.3.2 to 2.3.3
- README.txt +5 -1
- admin/js/mailchimp-woocommerce-admin.js +9 -3
- includes/api/class-mailchimp-woocommerce-transform-products.php +10 -11
- includes/processes/class-mailchimp-woocommerce-single-order.php +4 -2
- includes/vendor/action-scheduler/.travis.yml +17 -9
- includes/vendor/action-scheduler/action-scheduler.php +15 -8
- includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php +2 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php +2 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php +10 -5
- includes/vendor/action-scheduler/classes/ActionScheduler_QueueRunner.php +14 -1
- includes/vendor/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php +9 -2
- includes/vendor/action-scheduler/classes/ActionScheduler_wcSystemStatus.php +10 -0
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php +11 -1
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php +1 -0
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php +10 -2
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php +1 -1
- includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Store.php +6 -6
- includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php +46 -5
- includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php +32 -30
- includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php +2 -2
- includes/vendor/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php +0 -1
- includes/vendor/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php +2 -1
- includes/vendor/action-scheduler/composer.json +7 -0
- includes/vendor/action-scheduler/docs/_layouts/default.html +1 -1
- includes/vendor/action-scheduler/docs/api.md +1 -1
- includes/vendor/action-scheduler/docs/usage.md +1 -1
- includes/vendor/action-scheduler/docs/version3-0.md +48 -0
- mailchimp-woocommerce.php +1 -1
README.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: ecommerce,email,workflows,mailchimp
|
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 5.3.2
|
7 |
-
Stable tag: 2.3.
|
8 |
Requires PHP: 7.0
|
9 |
WC requires at least: 3.5
|
10 |
WC tested up to: 3.9
|
@@ -63,6 +63,10 @@ The Mailchimp for WooCommerce supports Wordpress Multi Sites and below are a few
|
|
63 |
- Deleting removes the connection between Mailchimp and WooCommerce, and uninstalls the plugin from your site.
|
64 |
Refer to the Wordpress Codex for more information about [Multisite Network Administration](https://codex.wordpress.org/Multisite_Network_Administration)
|
65 |
== Changelog ==
|
|
|
|
|
|
|
|
|
66 |
= 2.3.2 =
|
67 |
* update to action scheduler v3.0.1
|
68 |
* adds low-bandwidth setting on sync
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 5.3.2
|
7 |
+
Stable tag: 2.3.3
|
8 |
Requires PHP: 7.0
|
9 |
WC requires at least: 3.5
|
10 |
WC tested up to: 3.9
|
63 |
- Deleting removes the connection between Mailchimp and WooCommerce, and uninstalls the plugin from your site.
|
64 |
Refer to the Wordpress Codex for more information about [Multisite Network Administration](https://codex.wordpress.org/Multisite_Network_Administration)
|
65 |
== Changelog ==
|
66 |
+
= 2.3.3 =
|
67 |
+
* fixes abandoned cart issues with Paypal
|
68 |
+
* resolves Action Scheduler 3.0 compatiblity issues
|
69 |
+
* Fixes missing product images
|
70 |
= 2.3.2 =
|
71 |
* update to action scheduler v3.0.1
|
72 |
* adds low-bandwidth setting on sync
|
admin/js/mailchimp-woocommerce-admin.js
CHANGED
@@ -57,7 +57,9 @@
|
|
57 |
}
|
58 |
|
59 |
e.preventDefault();
|
60 |
-
|
|
|
|
|
61 |
const swalWithBootstrapButtons = Swal.mixin({
|
62 |
customClass: {
|
63 |
confirmButton: 'button button-primary tab-content-submit disconnect-button',
|
@@ -81,8 +83,12 @@
|
|
81 |
history.replaceState({}, "", query[1]);
|
82 |
$('input[name=_wp_http_referer]').val(query[1]);
|
83 |
}
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
})
|
88 |
});
|
57 |
}
|
58 |
|
59 |
e.preventDefault();
|
60 |
+
|
61 |
+
var me = $(e.target);
|
62 |
+
|
63 |
const swalWithBootstrapButtons = Swal.mixin({
|
64 |
customClass: {
|
65 |
confirmButton: 'button button-primary tab-content-submit disconnect-button',
|
83 |
history.replaceState({}, "", query[1]);
|
84 |
$('input[name=_wp_http_referer]').val(query[1]);
|
85 |
}
|
86 |
+
try {
|
87 |
+
me.click();
|
88 |
+
mailchimp_woocommerce_disconnect_done = true;
|
89 |
+
} catch (e) {
|
90 |
+
console.error('clicking event for disconnect failed', e);
|
91 |
+
}
|
92 |
}
|
93 |
})
|
94 |
});
|
includes/api/class-mailchimp-woocommerce-transform-products.php
CHANGED
@@ -256,22 +256,21 @@ class MailChimp_WooCommerce_Transform_Products
|
|
256 |
return $variants;
|
257 |
}
|
258 |
|
259 |
-
|
260 |
-
* @param $post_id
|
261 |
-
* @return false|string
|
262 |
-
*/
|
263 |
-
public function getProductImage($post_id)
|
264 |
{
|
265 |
-
$meta = get_post_meta($
|
266 |
$key = '_thumbnail_id';
|
267 |
$image_key = $this->getProductImageKey();
|
268 |
-
|
269 |
if ($meta && is_array($meta) && array_key_exists($key, $meta) && isset($meta[$key][0])) {
|
270 |
-
$img =
|
271 |
-
if (!empty($img))
|
|
|
|
|
|
|
|
|
|
|
272 |
}
|
273 |
-
|
274 |
-
return get_the_post_thumbnail_url($post_id, $image_key);
|
275 |
}
|
276 |
|
277 |
/**
|
256 |
return $variants;
|
257 |
}
|
258 |
|
259 |
+
public function getProductImage($post)
|
|
|
|
|
|
|
|
|
260 |
{
|
261 |
+
$meta = get_post_meta($post->ID);
|
262 |
$key = '_thumbnail_id';
|
263 |
$image_key = $this->getProductImageKey();
|
|
|
264 |
if ($meta && is_array($meta) && array_key_exists($key, $meta) && isset($meta[$key][0])) {
|
265 |
+
$img = wp_get_attachment_image_src($meta[$key][0], $image_key);
|
266 |
+
if (!empty($img[0])) {
|
267 |
+
if (substr($img[0], 0, 4) !== 'http') {
|
268 |
+
return rtrim(get_option('siteurl'), '/').'/'.ltrim($img[0], '/');
|
269 |
+
}
|
270 |
+
return $img[0];
|
271 |
+
}
|
272 |
}
|
273 |
+
return get_the_post_thumbnail_url($post->ID, $image_key);
|
|
|
274 |
}
|
275 |
|
276 |
/**
|
includes/processes/class-mailchimp-woocommerce-single-order.php
CHANGED
@@ -142,8 +142,10 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
|
|
142 |
}
|
143 |
}
|
144 |
|
145 |
-
|
146 |
-
|
|
|
|
|
147 |
|
148 |
// skip amazon orders and skip privacy protected orders.
|
149 |
if ($order->isFlaggedAsAmazonOrder()) {
|
142 |
}
|
143 |
}
|
144 |
|
145 |
+
if ($order->getOriginalWooStatus() !== 'pending') {
|
146 |
+
// delete the AC cart record.
|
147 |
+
$deleted_abandoned_cart = !empty($this->cart_session_id) && $api->deleteCartByID($store_id, $this->cart_session_id);
|
148 |
+
}
|
149 |
|
150 |
// skip amazon orders and skip privacy protected orders.
|
151 |
if ($order->isFlaggedAsAmazonOrder()) {
|
includes/vendor/action-scheduler/.travis.yml
CHANGED
@@ -9,29 +9,37 @@ dist: precise
|
|
9 |
# Versions of PHP to test against
|
10 |
php:
|
11 |
- "5.3"
|
12 |
-
- "5.4"
|
13 |
-
- "5.5"
|
14 |
- "5.6"
|
15 |
- "7.0"
|
16 |
- "7.1"
|
|
|
|
|
17 |
|
18 |
# Specify versions of WordPress to test against
|
19 |
# WP_VERSION = WordPress version number (use "master" for SVN trunk)
|
20 |
# WP_MULTISITE = whether to test multisite (use either "0" or "1")
|
21 |
env:
|
22 |
-
- WP_VERSION=
|
23 |
-
- WP_VERSION=
|
24 |
-
- WP_VERSION=
|
25 |
-
- WP_VERSION=
|
26 |
-
- WP_VERSION=
|
27 |
-
- WP_VERSION=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
# Grab the setup script and execute
|
30 |
before_script:
|
31 |
- source tests/travis/setup.sh $TRAVIS_PHP_VERSION
|
32 |
|
33 |
script:
|
34 |
-
- if [[ "$TRAVIS_PHP_VERSION" == "7.
|
35 |
|
36 |
after_script:
|
37 |
- bash <(curl -s https://codecov.io/bash)
|
9 |
# Versions of PHP to test against
|
10 |
php:
|
11 |
- "5.3"
|
|
|
|
|
12 |
- "5.6"
|
13 |
- "7.0"
|
14 |
- "7.1"
|
15 |
+
- "7.2"
|
16 |
+
- "7.3"
|
17 |
|
18 |
# Specify versions of WordPress to test against
|
19 |
# WP_VERSION = WordPress version number (use "master" for SVN trunk)
|
20 |
# WP_MULTISITE = whether to test multisite (use either "0" or "1")
|
21 |
env:
|
22 |
+
- WP_VERSION=5.3 WP_MULTISITE=0
|
23 |
+
- WP_VERSION=5.2 WP_MULTISITE=0
|
24 |
+
- WP_VERSION=5.1 WP_MULTISITE=0
|
25 |
+
- WP_VERSION=5.3 WP_MULTISITE=1
|
26 |
+
- WP_VERSION=5.2 WP_MULTISITE=1
|
27 |
+
- WP_VERSION=5.1 WP_MULTISITE=1
|
28 |
+
|
29 |
+
# WordPress 5.3 requires PHP 5.6. Exclude WP 5.3 + PHP 5.3
|
30 |
+
jobs:
|
31 |
+
exclude:
|
32 |
+
- php: "5.3"
|
33 |
+
env: WP_VERSION=5.3 WP_MULTISITE=0
|
34 |
+
- php: "5.3"
|
35 |
+
env: WP_VERSION=5.3 WP_MULTISITE=1
|
36 |
|
37 |
# Grab the setup script and execute
|
38 |
before_script:
|
39 |
- source tests/travis/setup.sh $TRAVIS_PHP_VERSION
|
40 |
|
41 |
script:
|
42 |
+
- if [[ "$TRAVIS_PHP_VERSION" == "7.3" ]] && [[ "$WP_VERSION" == "5.3" ]] && [[ "$WP_MULTISITE" == "0" ]] && [[ "$TRAVIS_BRANCH" == "master" ]]; then phpunit --configuration tests/phpunit.xml.dist --coverage-clover clover.xml; else phpunit --configuration tests/phpunit.xml.dist; fi
|
43 |
|
44 |
after_script:
|
45 |
- bash <(curl -s https://codecov.io/bash)
|
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.0
|
9 |
* License: GPLv3
|
10 |
*
|
11 |
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
@@ -25,28 +25,35 @@
|
|
25 |
*
|
26 |
*/
|
27 |
|
28 |
-
if ( ! function_exists( '
|
29 |
|
30 |
if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
|
31 |
require_once( 'classes/ActionScheduler_Versions.php' );
|
32 |
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
|
33 |
}
|
34 |
|
35 |
-
add_action( 'plugins_loaded', '
|
36 |
|
37 |
-
function
|
38 |
$versions = ActionScheduler_Versions::instance();
|
39 |
-
$versions->register( '3.0
|
40 |
}
|
41 |
|
42 |
-
function
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
ActionScheduler::init( __FILE__ );
|
45 |
}
|
46 |
|
47 |
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
48 |
if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) {
|
49 |
-
|
50 |
do_action( 'action_scheduler_pre_theme_init' );
|
51 |
ActionScheduler_Versions::initialize_latest_version();
|
52 |
}
|
5 |
* Description: A robust scheduling library for use in WordPress plugins.
|
6 |
* Author: Automattic
|
7 |
* Author URI: https://automattic.com/
|
8 |
+
* Version: 3.1.0
|
9 |
* License: GPLv3
|
10 |
*
|
11 |
* Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
|
25 |
*
|
26 |
*/
|
27 |
|
28 |
+
if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_0' ) ) {
|
29 |
|
30 |
if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
|
31 |
require_once( 'classes/ActionScheduler_Versions.php' );
|
32 |
add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
|
33 |
}
|
34 |
|
35 |
+
add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_0', 0, 0 );
|
36 |
|
37 |
+
function action_scheduler_register_3_dot_1_dot_0() {
|
38 |
$versions = ActionScheduler_Versions::instance();
|
39 |
+
$versions->register( '3.1.0', 'action_scheduler_initialize_3_dot_1_dot_0' );
|
40 |
}
|
41 |
|
42 |
+
function action_scheduler_initialize_3_dot_1_dot_0() {
|
43 |
+
$autoloader = __DIR__ . '/vendor/autoload.php';
|
44 |
+
if ( is_readable( $autoloader ) ) {
|
45 |
+
require_once( $autoloader );
|
46 |
+
define( 'AS_COMPOSER_AUTOLOADING', true );
|
47 |
+
} else {
|
48 |
+
define( 'AS_COMPOSER_AUTOLOADING', false );
|
49 |
+
require_once( 'classes/abstracts/ActionScheduler.php' );
|
50 |
+
}
|
51 |
ActionScheduler::init( __FILE__ );
|
52 |
}
|
53 |
|
54 |
// Support usage in themes - load this version if no plugin has loaded a version yet.
|
55 |
if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) {
|
56 |
+
action_scheduler_register_3_dot_1_dot_0();
|
57 |
do_action( 'action_scheduler_pre_theme_init' );
|
58 |
ActionScheduler_Versions::initialize_latest_version();
|
59 |
}
|
includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php
CHANGED
@@ -104,12 +104,13 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
|
|
104 |
return;
|
105 |
}
|
106 |
|
|
|
107 |
$screen->add_help_tab(
|
108 |
array(
|
109 |
'id' => 'action_scheduler_about',
|
110 |
'title' => __( 'About', 'action-scheduler' ),
|
111 |
'content' =>
|
112 |
-
'<h2>' . __( 'About Action Scheduler', 'action-scheduler' ) . '</h2>' .
|
113 |
'<p>' .
|
114 |
__( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) .
|
115 |
'</p>',
|
104 |
return;
|
105 |
}
|
106 |
|
107 |
+
$as_version = ActionScheduler_Versions::instance()->latest_version();
|
108 |
$screen->add_help_tab(
|
109 |
array(
|
110 |
'id' => 'action_scheduler_about',
|
111 |
'title' => __( 'About', 'action-scheduler' ),
|
112 |
'content' =>
|
113 |
+
'<h2>' . sprintf( __( 'About Action Scheduler %s', 'action-scheduler' ), $as_version ) . '</h2>' .
|
114 |
'<p>' .
|
115 |
__( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'action-scheduler' ) .
|
116 |
'</p>',
|
includes/vendor/action-scheduler/classes/ActionScheduler_AsyncRequest_QueueRunner.php
CHANGED
@@ -69,6 +69,7 @@ class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request {
|
|
69 |
}
|
70 |
|
71 |
$this->dispatch();
|
|
|
72 |
}
|
73 |
|
74 |
/**
|
@@ -91,6 +92,6 @@ class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request {
|
|
91 |
* Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that.
|
92 |
*/
|
93 |
protected function get_sleep_seconds() {
|
94 |
-
return apply_filters( 'action_scheduler_async_request_sleep_seconds',
|
95 |
}
|
96 |
}
|
69 |
}
|
70 |
|
71 |
$this->dispatch();
|
72 |
+
ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request();
|
73 |
}
|
74 |
|
75 |
/**
|
92 |
* Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that.
|
93 |
*/
|
94 |
protected function get_sleep_seconds() {
|
95 |
+
return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this );
|
96 |
}
|
97 |
}
|
includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php
CHANGED
@@ -252,7 +252,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|
252 |
*/
|
253 |
public function column_args( array $row ) {
|
254 |
if ( empty( $row['args'] ) ) {
|
255 |
-
return '';
|
256 |
}
|
257 |
|
258 |
$row_html = '<ul>';
|
@@ -319,17 +319,22 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|
319 |
*
|
320 |
* Notifications:
|
321 |
* 1. When the maximum number of tasks are being executed simultaneously
|
322 |
-
* 2. Notifications when a task
|
323 |
*/
|
324 |
public function display_admin_notices() {
|
325 |
-
|
326 |
if ( $this->runner->has_maximum_concurrent_batches() ) {
|
|
|
327 |
$this->admin_notices[] = array(
|
328 |
'class' => 'updated',
|
329 |
'message' => sprintf(
|
330 |
/* translators: %s: amount of claims */
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
333 |
),
|
334 |
);
|
335 |
} elseif ( $this->store->has_pending_actions_due() ) {
|
252 |
*/
|
253 |
public function column_args( array $row ) {
|
254 |
if ( empty( $row['args'] ) ) {
|
255 |
+
return apply_filters( 'action_scheduler_list_table_column_args', '', $row );
|
256 |
}
|
257 |
|
258 |
$row_html = '<ul>';
|
319 |
*
|
320 |
* Notifications:
|
321 |
* 1. When the maximum number of tasks are being executed simultaneously
|
322 |
+
* 2. Notifications when a task is manually executed
|
323 |
*/
|
324 |
public function display_admin_notices() {
|
|
|
325 |
if ( $this->runner->has_maximum_concurrent_batches() ) {
|
326 |
+
$claim_count = $this->store->get_claim_count();
|
327 |
$this->admin_notices[] = array(
|
328 |
'class' => 'updated',
|
329 |
'message' => sprintf(
|
330 |
/* translators: %s: amount of claims */
|
331 |
+
_n(
|
332 |
+
'Maximum simultaneous queues already in progress (%s queue). No additional queues will begin processing until the current queues are complete.',
|
333 |
+
'Maximum simultaneous queues already in progress (%s queues). No additional queues will begin processing until the current queues are complete.',
|
334 |
+
$claim_count,
|
335 |
+
'action-scheduler'
|
336 |
+
),
|
337 |
+
$claim_count
|
338 |
),
|
339 |
);
|
340 |
} elseif ( $this->store->has_pending_actions_due() ) {
|
includes/vendor/action-scheduler/classes/ActionScheduler_QueueRunner.php
CHANGED
@@ -65,8 +65,21 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
|
|
65 |
}
|
66 |
|
67 |
add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) );
|
|
|
|
|
68 |
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
71 |
|
72 |
/**
|
65 |
}
|
66 |
|
67 |
add_action( self::WP_CRON_HOOK, array( self::instance(), 'run' ) );
|
68 |
+
$this->hook_dispatch_async_request();
|
69 |
+
}
|
70 |
|
71 |
+
/**
|
72 |
+
* Hook check for dispatching an async request.
|
73 |
+
*/
|
74 |
+
public function hook_dispatch_async_request() {
|
75 |
+
add_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Unhook check for dispatching an async request.
|
80 |
+
*/
|
81 |
+
public function unhook_dispatch_async_request() {
|
82 |
+
remove_action( 'shutdown', array( $this, 'maybe_dispatch_async_request' ) );
|
83 |
}
|
84 |
|
85 |
/**
|
includes/vendor/action-scheduler/classes/ActionScheduler_WPCommentCleaner.php
CHANGED
@@ -46,8 +46,8 @@ class ActionScheduler_WPCommentCleaner {
|
|
46 |
add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 );
|
47 |
|
48 |
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
|
49 |
-
add_action( 'load-tools_page_action-scheduler', array( __CLASS__, '
|
50 |
-
add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, '
|
51 |
}
|
52 |
|
53 |
/**
|
@@ -84,6 +84,13 @@ class ActionScheduler_WPCommentCleaner {
|
|
84 |
delete_option( self::$has_logs_option_key );
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
* Prints details about the orphaned action logs and includes information on where to learn more.
|
89 |
*/
|
46 |
add_action( 'comment_feed_where', array( self::$wp_comment_logger, 'filter_comment_feed' ), 10, 2 );
|
47 |
|
48 |
// Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen
|
49 |
+
add_action( 'load-tools_page_action-scheduler', array( __CLASS__, 'register_admin_notice' ) );
|
50 |
+
add_action( 'load-woocommerce_page_wc-status', array( __CLASS__, 'register_admin_notice' ) );
|
51 |
}
|
52 |
|
53 |
/**
|
84 |
delete_option( self::$has_logs_option_key );
|
85 |
}
|
86 |
|
87 |
+
/**
|
88 |
+
* Registers admin notices about the orphaned action logs.
|
89 |
+
*/
|
90 |
+
public static function register_admin_notice() {
|
91 |
+
add_action( 'admin_notices', array( __CLASS__, 'print_admin_notice' ) );
|
92 |
+
}
|
93 |
+
|
94 |
/**
|
95 |
* Prints details about the orphaned action logs and includes information on where to learn more.
|
96 |
*/
|
includes/vendor/action-scheduler/classes/ActionScheduler_wcSystemStatus.php
CHANGED
@@ -92,6 +92,8 @@ class ActionScheduler_wcSystemStatus {
|
|
92 |
* @param array $oldest_and_newest Date of the oldest and newest action with each status.
|
93 |
*/
|
94 |
protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
|
|
|
|
|
95 |
?>
|
96 |
|
97 |
<table class="wc_status_table widefat" cellspacing="0">
|
@@ -99,6 +101,14 @@ class ActionScheduler_wcSystemStatus {
|
|
99 |
<tr>
|
100 |
<th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e( 'Action Scheduler', 'action-scheduler' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows scheduled action counts.', 'action-scheduler' ) ); ?></h2></th>
|
101 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
<tr>
|
103 |
<td><strong><?php esc_html_e( 'Action Status', 'action-scheduler' ); ?></strong></td>
|
104 |
<td class="help"> </td>
|
92 |
* @param array $oldest_and_newest Date of the oldest and newest action with each status.
|
93 |
*/
|
94 |
protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
|
95 |
+
$as_version = ActionScheduler_Versions::instance()->latest_version();
|
96 |
+
$autoloader = AS_COMPOSER_AUTOLOADING ? __( 'Composer', 'action-scheduler' ) : __( 'Internal', 'action-scheduler' );
|
97 |
?>
|
98 |
|
99 |
<table class="wc_status_table widefat" cellspacing="0">
|
101 |
<tr>
|
102 |
<th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e( 'Action Scheduler', 'action-scheduler' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows scheduled action counts.', 'action-scheduler' ) ); ?></h2></th>
|
103 |
</tr>
|
104 |
+
<tr>
|
105 |
+
<td colspan="2" data-export-label="Version"><?php esc_html_e( 'Version:', 'action-scheduler' ); ?></td>
|
106 |
+
<td colspan="3"><?php echo esc_html( $as_version ); ?></td>
|
107 |
+
</tr>
|
108 |
+
<tr>
|
109 |
+
<td colspan="2" data-export-label="Version"><?php esc_html_e( 'Autoloader:', 'action-scheduler' ); ?></td>
|
110 |
+
<td colspan="3"><?php echo esc_html( $autoloader ); ?></td>
|
111 |
+
</tr>
|
112 |
<tr>
|
113 |
<td><strong><?php esc_html_e( 'Action Status', 'action-scheduler' ); ?></strong></td>
|
114 |
<td class="help"> </td>
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php
CHANGED
@@ -130,7 +130,9 @@ abstract class ActionScheduler {
|
|
130 |
*/
|
131 |
public static function init( $plugin_file ) {
|
132 |
self::$plugin_file = $plugin_file;
|
133 |
-
|
|
|
|
|
134 |
|
135 |
/**
|
136 |
* Fires in the early stages of Action Scheduler init hook.
|
@@ -152,6 +154,14 @@ abstract class ActionScheduler {
|
|
152 |
$admin_view = self::admin_view();
|
153 |
add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init()
|
154 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) {
|
156 |
require_once( self::plugin_path('deprecated/functions.php') );
|
157 |
}
|
130 |
*/
|
131 |
public static function init( $plugin_file ) {
|
132 |
self::$plugin_file = $plugin_file;
|
133 |
+
if ( ! AS_COMPOSER_AUTOLOADING ) {
|
134 |
+
spl_autoload_register( array( __CLASS__, 'autoload' ) );
|
135 |
+
}
|
136 |
|
137 |
/**
|
138 |
* Fires in the early stages of Action Scheduler init hook.
|
154 |
$admin_view = self::admin_view();
|
155 |
add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init()
|
156 |
|
157 |
+
// Ensure initialization on plugin activation.
|
158 |
+
if ( did_action( 'init' ) ) {
|
159 |
+
$store->init();
|
160 |
+
$logger->init();
|
161 |
+
$runner->init();
|
162 |
+
$admin_view->init();
|
163 |
+
}
|
164 |
+
|
165 |
if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) {
|
166 |
require_once( self::plugin_path('deprecated/functions.php') );
|
167 |
}
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php
CHANGED
@@ -606,6 +606,7 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|
606 |
}
|
607 |
|
608 |
$status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name );
|
|
|
609 |
$status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) );
|
610 |
}
|
611 |
|
606 |
}
|
607 |
|
608 |
$status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name );
|
609 |
+
$status_filter_url = remove_query_arg( array( 'paged', 's' ), $status_filter_url );
|
610 |
$status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) );
|
611 |
}
|
612 |
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php
CHANGED
@@ -49,6 +49,7 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
|
|
49 |
*/
|
50 |
public function process_action( $action_id, $context = '' ) {
|
51 |
try {
|
|
|
52 |
do_action( 'action_scheduler_before_execute', $action_id, $context );
|
53 |
|
54 |
if ( ActionScheduler_Store::STATUS_PENDING !== $this->store->get_status( $action_id ) ) {
|
@@ -56,14 +57,21 @@ abstract class ActionScheduler_Abstract_QueueRunner extends ActionScheduler_Abst
|
|
56 |
return;
|
57 |
}
|
58 |
|
|
|
|
|
|
|
59 |
$action = $this->store->fetch_action( $action_id );
|
60 |
$this->store->log_execution( $action_id );
|
61 |
$action->execute();
|
62 |
do_action( 'action_scheduler_after_execute', $action_id, $action, $context );
|
63 |
$this->store->mark_complete( $action_id );
|
64 |
} catch ( Exception $e ) {
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
|
69 |
if ( isset( $action ) && is_a( $action, 'ActionScheduler_Action' ) && $action->get_schedule()->is_recurring() ) {
|
49 |
*/
|
50 |
public function process_action( $action_id, $context = '' ) {
|
51 |
try {
|
52 |
+
$valid_action = false;
|
53 |
do_action( 'action_scheduler_before_execute', $action_id, $context );
|
54 |
|
55 |
if ( ActionScheduler_Store::STATUS_PENDING !== $this->store->get_status( $action_id ) ) {
|
57 |
return;
|
58 |
}
|
59 |
|
60 |
+
$valid_action = true;
|
61 |
+
do_action( 'action_scheduler_begin_execute', $action_id, $context );
|
62 |
+
|
63 |
$action = $this->store->fetch_action( $action_id );
|
64 |
$this->store->log_execution( $action_id );
|
65 |
$action->execute();
|
66 |
do_action( 'action_scheduler_after_execute', $action_id, $action, $context );
|
67 |
$this->store->mark_complete( $action_id );
|
68 |
} catch ( Exception $e ) {
|
69 |
+
if ( $valid_action ) {
|
70 |
+
$this->store->mark_failure( $action_id );
|
71 |
+
do_action( 'action_scheduler_failed_execution', $action_id, $e, $context );
|
72 |
+
} else {
|
73 |
+
do_action( 'action_scheduler_failed_validation', $action_id, $e, $context );
|
74 |
+
}
|
75 |
}
|
76 |
|
77 |
if ( isset( $action ) && is_a( $action, 'ActionScheduler_Action' ) && $action->get_schedule()->is_recurring() ) {
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php
CHANGED
@@ -48,7 +48,7 @@ abstract class ActionScheduler_Logger {
|
|
48 |
public function init() {
|
49 |
$this->hook_stored_action();
|
50 |
add_action( 'action_scheduler_canceled_action', array( $this, 'log_canceled_action' ), 10, 1 );
|
51 |
-
add_action( '
|
52 |
add_action( 'action_scheduler_after_execute', array( $this, 'log_completed_action' ), 10, 3 );
|
53 |
add_action( 'action_scheduler_failed_execution', array( $this, 'log_failed_action' ), 10, 3 );
|
54 |
add_action( 'action_scheduler_failed_action', array( $this, 'log_timed_out_action' ), 10, 2 );
|
48 |
public function init() {
|
49 |
$this->hook_stored_action();
|
50 |
add_action( 'action_scheduler_canceled_action', array( $this, 'log_canceled_action' ), 10, 1 );
|
51 |
+
add_action( 'action_scheduler_begin_execute', array( $this, 'log_started_action' ), 10, 2 );
|
52 |
add_action( 'action_scheduler_after_execute', array( $this, 'log_completed_action' ), 10, 3 );
|
53 |
add_action( 'action_scheduler_failed_execution', array( $this, 'log_failed_action' ), 10, 3 );
|
54 |
add_action( 'action_scheduler_failed_action', array( $this, 'log_timed_out_action' ), 10, 2 );
|
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Store.php
CHANGED
@@ -16,7 +16,7 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
|
16 |
private static $store = NULL;
|
17 |
|
18 |
/** @var int */
|
19 |
-
|
20 |
|
21 |
/**
|
22 |
* @param ActionScheduler_Action $action
|
@@ -217,14 +217,14 @@ abstract class ActionScheduler_Store extends ActionScheduler_Store_Deprecated {
|
|
217 |
* InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
|
218 |
*
|
219 |
* Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
|
220 |
-
*
|
221 |
-
* developers of this impending requirement.
|
222 |
*
|
223 |
-
* @param
|
|
|
224 |
*/
|
225 |
protected function validate_action( ActionScheduler_Action $action ) {
|
226 |
-
if ( strlen( json_encode( $action->get_args() ) ) >
|
227 |
-
throw new InvalidArgumentException( __( 'ActionScheduler_Action::$args too long. To ensure the args column can be indexed, action args should not be more than
|
228 |
}
|
229 |
}
|
230 |
|
16 |
private static $store = NULL;
|
17 |
|
18 |
/** @var int */
|
19 |
+
protected static $max_args_length = 191;
|
20 |
|
21 |
/**
|
22 |
* @param ActionScheduler_Action $action
|
217 |
* InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
|
218 |
*
|
219 |
* Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
|
220 |
+
* with custom tables, we use an indexed VARCHAR column instead.
|
|
|
221 |
*
|
222 |
+
* @param ActionScheduler_Action $action Action to be validated.
|
223 |
+
* @throws InvalidArgumentException When json encoded args is too long.
|
224 |
*/
|
225 |
protected function validate_action( ActionScheduler_Action $action ) {
|
226 |
+
if ( strlen( json_encode( $action->get_args() ) ) > static::$max_args_length ) {
|
227 |
+
throw new InvalidArgumentException( sprintf( __( 'ActionScheduler_Action::$args too long. To ensure the args column can be indexed, action args should not be more than %d characters when encoded as JSON.', 'action-scheduler' ), static::$max_args_length ) );
|
228 |
}
|
229 |
}
|
230 |
|
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php
CHANGED
@@ -9,6 +9,12 @@
|
|
9 |
*/
|
10 |
class ActionScheduler_DBStore extends ActionScheduler_Store {
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Initialize the data store
|
14 |
*
|
@@ -39,10 +45,17 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
39 |
'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
|
40 |
'scheduled_date_gmt' => $this->get_scheduled_date_string( $action, $date ),
|
41 |
'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
|
42 |
-
'args' => json_encode( $action->get_args() ),
|
43 |
'schedule' => serialize( $action->get_schedule() ),
|
44 |
'group_id' => $this->get_group_id( $action->get_group() ),
|
45 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46 |
$wpdb->insert( $wpdb->actionscheduler_actions, $data );
|
47 |
$action_id = $wpdb->insert_id;
|
48 |
|
@@ -62,6 +75,29 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
62 |
}
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
/**
|
66 |
* Get a group's ID based on its name/slug.
|
67 |
*
|
@@ -118,6 +154,11 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
118 |
return $this->get_null_action();
|
119 |
}
|
120 |
|
|
|
|
|
|
|
|
|
|
|
121 |
try {
|
122 |
$action = $this->make_action_from_db_record( $data );
|
123 |
} catch ( ActionScheduler_InvalidActionException $exception ) {
|
@@ -188,7 +229,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
188 |
$args[] = $hook;
|
189 |
if ( ! is_null( $params[ 'args' ] ) ) {
|
190 |
$query .= " AND a.args=%s";
|
191 |
-
$args[] =
|
192 |
}
|
193 |
|
194 |
$order = 'ASC';
|
@@ -265,7 +306,7 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
265 |
}
|
266 |
if ( ! is_null( $query[ 'args' ] ) ) {
|
267 |
$sql .= " AND a.args=%s";
|
268 |
-
$sql_params[] =
|
269 |
}
|
270 |
|
271 |
if ( $query[ 'status' ] ) {
|
@@ -301,8 +342,8 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
|
|
301 |
}
|
302 |
|
303 |
if ( ! empty( $query['search'] ) ) {
|
304 |
-
$sql .= " AND (a.hook LIKE %s OR a.args LIKE %s";
|
305 |
-
for( $i = 0; $i <
|
306 |
$sql_params[] = sprintf( '%%%s%%', $query['search'] );
|
307 |
}
|
308 |
|
9 |
*/
|
10 |
class ActionScheduler_DBStore extends ActionScheduler_Store {
|
11 |
|
12 |
+
/** @var int */
|
13 |
+
protected static $max_args_length = 8000;
|
14 |
+
|
15 |
+
/** @var int */
|
16 |
+
protected static $max_index_length = 191;
|
17 |
+
|
18 |
/**
|
19 |
* Initialize the data store
|
20 |
*
|
45 |
'status' => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
|
46 |
'scheduled_date_gmt' => $this->get_scheduled_date_string( $action, $date ),
|
47 |
'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
|
|
|
48 |
'schedule' => serialize( $action->get_schedule() ),
|
49 |
'group_id' => $this->get_group_id( $action->get_group() ),
|
50 |
];
|
51 |
+
$args = wp_json_encode( $action->get_args() );
|
52 |
+
if ( strlen( $args ) <= static::$max_index_length ) {
|
53 |
+
$data['args'] = $args;
|
54 |
+
} else {
|
55 |
+
$data['args'] = $this->hash_args( $args );
|
56 |
+
$data['extended_args'] = $args;
|
57 |
+
}
|
58 |
+
|
59 |
$wpdb->insert( $wpdb->actionscheduler_actions, $data );
|
60 |
$action_id = $wpdb->insert_id;
|
61 |
|
75 |
}
|
76 |
}
|
77 |
|
78 |
+
/**
|
79 |
+
* Generate a hash from json_encoded $args using MD5 as this isn't for security.
|
80 |
+
*
|
81 |
+
* @param string $args JSON encoded action args.
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
protected function hash_args( $args ) {
|
85 |
+
return md5( $args );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Get action args query param value from action args.
|
90 |
+
*
|
91 |
+
* @param array $args Action args.
|
92 |
+
* @return string
|
93 |
+
*/
|
94 |
+
protected function get_args_for_query( $args ) {
|
95 |
+
$encoded = wp_json_encode( $args );
|
96 |
+
if ( strlen( $encoded ) <= static::$max_index_length ) {
|
97 |
+
return $encoded;
|
98 |
+
}
|
99 |
+
return $this->hash_args( $encoded );
|
100 |
+
}
|
101 |
/**
|
102 |
* Get a group's ID based on its name/slug.
|
103 |
*
|
154 |
return $this->get_null_action();
|
155 |
}
|
156 |
|
157 |
+
if ( ! empty( $data->extended_args ) ) {
|
158 |
+
$data->args = $data->extended_args;
|
159 |
+
unset( $data->extended_args );
|
160 |
+
}
|
161 |
+
|
162 |
try {
|
163 |
$action = $this->make_action_from_db_record( $data );
|
164 |
} catch ( ActionScheduler_InvalidActionException $exception ) {
|
229 |
$args[] = $hook;
|
230 |
if ( ! is_null( $params[ 'args' ] ) ) {
|
231 |
$query .= " AND a.args=%s";
|
232 |
+
$args[] = $this->get_args_for_query( $params[ 'args' ] );
|
233 |
}
|
234 |
|
235 |
$order = 'ASC';
|
306 |
}
|
307 |
if ( ! is_null( $query[ 'args' ] ) ) {
|
308 |
$sql .= " AND a.args=%s";
|
309 |
+
$sql_params[] = $this->get_args_for_query( $query[ 'args' ] );
|
310 |
}
|
311 |
|
312 |
if ( $query[ 'status' ] ) {
|
342 |
}
|
343 |
|
344 |
if ( ! empty( $query['search'] ) ) {
|
345 |
+
$sql .= " AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s";
|
346 |
+
for( $i = 0; $i < 3; $i++ ) {
|
347 |
$sql_params[] = sprintf( '%%%s%%', $query['search'] );
|
348 |
}
|
349 |
|
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php
CHANGED
@@ -22,7 +22,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
22 |
do_action( 'action_scheduler_stored_action', $post_id );
|
23 |
return $post_id;
|
24 |
} catch ( Exception $e ) {
|
25 |
-
throw new RuntimeException( sprintf( __('Error saving action: %s', 'action-scheduler'), $e->getMessage() ), 0 );
|
26 |
}
|
27 |
}
|
28 |
|
@@ -59,7 +59,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
59 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
60 |
|
61 |
if ( is_wp_error($post_id) || empty($post_id) ) {
|
62 |
-
throw new RuntimeException(__('Unable to save action.', 'action-scheduler'));
|
63 |
}
|
64 |
return $post_id;
|
65 |
}
|
@@ -280,7 +280,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
280 |
protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
|
281 |
|
282 |
if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
|
283 |
-
throw new InvalidArgumentException(__('Invalid schedule. Cannot save action.', 'action-scheduler'));
|
284 |
}
|
285 |
|
286 |
$query = wp_parse_args( $query, array(
|
@@ -452,20 +452,20 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
452 |
* @throws InvalidArgumentException
|
453 |
*/
|
454 |
public function cancel_action( $action_id ) {
|
455 |
-
$post = get_post($action_id);
|
456 |
-
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
457 |
-
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
458 |
}
|
459 |
do_action( 'action_scheduler_canceled_action', $action_id );
|
460 |
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
461 |
-
wp_trash_post($action_id);
|
462 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
463 |
}
|
464 |
|
465 |
public function delete_action( $action_id ) {
|
466 |
-
$post = get_post($action_id);
|
467 |
-
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
468 |
-
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
469 |
}
|
470 |
do_action( 'action_scheduler_deleted_action', $action_id );
|
471 |
|
@@ -490,14 +490,14 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
490 |
* @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
|
491 |
*/
|
492 |
public function get_date_gmt( $action_id ) {
|
493 |
-
$post = get_post($action_id);
|
494 |
-
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
495 |
-
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
496 |
}
|
497 |
if ( $post->post_status == 'publish' ) {
|
498 |
-
return as_get_datetime_object($post->post_modified_gmt);
|
499 |
} else {
|
500 |
-
return as_get_datetime_object($post->post_date_gmt);
|
501 |
}
|
502 |
}
|
503 |
|
@@ -675,18 +675,18 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
675 |
|
676 |
public function release_claim( ActionScheduler_ActionClaim $claim ) {
|
677 |
$action_ids = $this->find_actions_by_claim_id( $claim->get_id() );
|
678 |
-
if ( empty($action_ids) ) {
|
679 |
return; // nothing to do
|
680 |
}
|
681 |
-
$action_id_string = implode(',', array_map('intval', $action_ids));
|
682 |
/** @var wpdb $wpdb */
|
683 |
global $wpdb;
|
684 |
$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s";
|
685 |
$sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
|
686 |
-
$result = $wpdb->query($sql);
|
687 |
if ( $result === false ) {
|
688 |
/* translators: %s: claim ID */
|
689 |
-
throw new RuntimeException( sprintf( __('Unable to unlock claim %s. Database error.', 'action-scheduler'), $claim->get_id() ) );
|
690 |
}
|
691 |
}
|
692 |
|
@@ -698,10 +698,10 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
698 |
global $wpdb;
|
699 |
$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s";
|
700 |
$sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
|
701 |
-
$result = $wpdb->query($sql);
|
702 |
if ( $result === false ) {
|
703 |
/* translators: %s: action ID */
|
704 |
-
throw new RuntimeException( sprintf( __('Unable to unlock claim on action %s. Database error.', 'action-scheduler'), $action_id ) );
|
705 |
}
|
706 |
}
|
707 |
|
@@ -710,10 +710,10 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
710 |
global $wpdb;
|
711 |
$sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s";
|
712 |
$sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
|
713 |
-
$result = $wpdb->query($sql);
|
714 |
if ( $result === false ) {
|
715 |
/* translators: %s: action ID */
|
716 |
-
throw new RuntimeException( sprintf( __('Unable to mark failure on action %s. Database error.', 'action-scheduler'), $action_id ) );
|
717 |
}
|
718 |
}
|
719 |
|
@@ -768,9 +768,9 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
768 |
* @throws InvalidArgumentException|RuntimeException
|
769 |
*/
|
770 |
public function mark_complete( $action_id ) {
|
771 |
-
$post = get_post($action_id);
|
772 |
-
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
773 |
-
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
774 |
}
|
775 |
add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
|
776 |
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
@@ -780,8 +780,8 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
780 |
), TRUE);
|
781 |
remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
|
782 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
783 |
-
if ( is_wp_error($result) ) {
|
784 |
-
throw new RuntimeException($result->get_error_message());
|
785 |
}
|
786 |
}
|
787 |
|
@@ -809,9 +809,11 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|
809 |
|
810 |
$dependencies_met = get_transient( self::DEPENDENCIES_MET );
|
811 |
if ( empty( $dependencies_met ) ) {
|
812 |
-
$
|
|
|
813 |
$wpdb->prepare(
|
814 |
-
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) >
|
|
|
815 |
self::POST_TYPE
|
816 |
)
|
817 |
);
|
22 |
do_action( 'action_scheduler_stored_action', $post_id );
|
23 |
return $post_id;
|
24 |
} catch ( Exception $e ) {
|
25 |
+
throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
|
26 |
}
|
27 |
}
|
28 |
|
59 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
60 |
|
61 |
if ( is_wp_error($post_id) || empty($post_id) ) {
|
62 |
+
throw new RuntimeException( __( 'Unable to save action.', 'action-scheduler' ) );
|
63 |
}
|
64 |
return $post_id;
|
65 |
}
|
280 |
protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
|
281 |
|
282 |
if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
|
283 |
+
throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
|
284 |
}
|
285 |
|
286 |
$query = wp_parse_args( $query, array(
|
452 |
* @throws InvalidArgumentException
|
453 |
*/
|
454 |
public function cancel_action( $action_id ) {
|
455 |
+
$post = get_post( $action_id );
|
456 |
+
if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
|
457 |
+
throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
458 |
}
|
459 |
do_action( 'action_scheduler_canceled_action', $action_id );
|
460 |
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
461 |
+
wp_trash_post( $action_id );
|
462 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
463 |
}
|
464 |
|
465 |
public function delete_action( $action_id ) {
|
466 |
+
$post = get_post( $action_id );
|
467 |
+
if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
|
468 |
+
throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
469 |
}
|
470 |
do_action( 'action_scheduler_deleted_action', $action_id );
|
471 |
|
490 |
* @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
|
491 |
*/
|
492 |
public function get_date_gmt( $action_id ) {
|
493 |
+
$post = get_post( $action_id );
|
494 |
+
if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
|
495 |
+
throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
496 |
}
|
497 |
if ( $post->post_status == 'publish' ) {
|
498 |
+
return as_get_datetime_object( $post->post_modified_gmt );
|
499 |
} else {
|
500 |
+
return as_get_datetime_object( $post->post_date_gmt );
|
501 |
}
|
502 |
}
|
503 |
|
675 |
|
676 |
public function release_claim( ActionScheduler_ActionClaim $claim ) {
|
677 |
$action_ids = $this->find_actions_by_claim_id( $claim->get_id() );
|
678 |
+
if ( empty( $action_ids ) ) {
|
679 |
return; // nothing to do
|
680 |
}
|
681 |
+
$action_id_string = implode( ',', array_map( 'intval', $action_ids ) );
|
682 |
/** @var wpdb $wpdb */
|
683 |
global $wpdb;
|
684 |
$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s";
|
685 |
$sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
|
686 |
+
$result = $wpdb->query( $sql );
|
687 |
if ( $result === false ) {
|
688 |
/* translators: %s: claim ID */
|
689 |
+
throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'action-scheduler' ), $claim->get_id() ) );
|
690 |
}
|
691 |
}
|
692 |
|
698 |
global $wpdb;
|
699 |
$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s";
|
700 |
$sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
|
701 |
+
$result = $wpdb->query( $sql );
|
702 |
if ( $result === false ) {
|
703 |
/* translators: %s: action ID */
|
704 |
+
throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'action-scheduler' ), $action_id ) );
|
705 |
}
|
706 |
}
|
707 |
|
710 |
global $wpdb;
|
711 |
$sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s";
|
712 |
$sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
|
713 |
+
$result = $wpdb->query( $sql );
|
714 |
if ( $result === false ) {
|
715 |
/* translators: %s: action ID */
|
716 |
+
throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'action-scheduler' ), $action_id ) );
|
717 |
}
|
718 |
}
|
719 |
|
768 |
* @throws InvalidArgumentException|RuntimeException
|
769 |
*/
|
770 |
public function mark_complete( $action_id ) {
|
771 |
+
$post = get_post( $action_id );
|
772 |
+
if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
|
773 |
+
throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
|
774 |
}
|
775 |
add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
|
776 |
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
780 |
), TRUE);
|
781 |
remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
|
782 |
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
783 |
+
if ( is_wp_error( $result ) ) {
|
784 |
+
throw new RuntimeException( $result->get_error_message() );
|
785 |
}
|
786 |
}
|
787 |
|
809 |
|
810 |
$dependencies_met = get_transient( self::DEPENDENCIES_MET );
|
811 |
if ( empty( $dependencies_met ) ) {
|
812 |
+
$maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 );
|
813 |
+
$found_action = $wpdb->get_var(
|
814 |
$wpdb->prepare(
|
815 |
+
"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1",
|
816 |
+
$maximum_args_length,
|
817 |
self::POST_TYPE
|
818 |
)
|
819 |
);
|
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php
CHANGED
@@ -11,7 +11,7 @@ class ActionScheduler_wpPostStore_TaxonomyRegistrar {
|
|
11 |
|
12 |
protected function taxonomy_args() {
|
13 |
$args = array(
|
14 |
-
'label' => __('Action Group', 'action-scheduler'),
|
15 |
'public' => false,
|
16 |
'hierarchical' => false,
|
17 |
'show_admin_column' => true,
|
@@ -19,7 +19,7 @@ class ActionScheduler_wpPostStore_TaxonomyRegistrar {
|
|
19 |
'rewrite' => false,
|
20 |
);
|
21 |
|
22 |
-
$args = apply_filters('action_scheduler_taxonomy_args', $args);
|
23 |
return $args;
|
24 |
}
|
25 |
}
|
11 |
|
12 |
protected function taxonomy_args() {
|
13 |
$args = array(
|
14 |
+
'label' => __( 'Action Group', 'action-scheduler' ),
|
15 |
'public' => false,
|
16 |
'hierarchical' => false,
|
17 |
'show_admin_column' => true,
|
19 |
'rewrite' => false,
|
20 |
);
|
21 |
|
22 |
+
$args = apply_filters( 'action_scheduler_taxonomy_args', $args );
|
23 |
return $args;
|
24 |
}
|
25 |
}
|
includes/vendor/action-scheduler/classes/schema/ActionScheduler_LoggerSchema.php
CHANGED
@@ -25,7 +25,6 @@ class ActionScheduler_LoggerSchema extends ActionScheduler_Abstract_Schema {
|
|
25 |
global $wpdb;
|
26 |
$table_name = $wpdb->$table;
|
27 |
$charset_collate = $wpdb->get_charset_collate();
|
28 |
-
$max_index_length = 191; // @see wp_get_db_schema()
|
29 |
switch ( $table ) {
|
30 |
|
31 |
case self::LOG_TABLE:
|
25 |
global $wpdb;
|
26 |
$table_name = $wpdb->$table;
|
27 |
$charset_collate = $wpdb->get_charset_collate();
|
|
|
28 |
switch ( $table ) {
|
29 |
|
30 |
case self::LOG_TABLE:
|
includes/vendor/action-scheduler/classes/schema/ActionScheduler_StoreSchema.php
CHANGED
@@ -15,7 +15,7 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
|
|
15 |
/**
|
16 |
* @var int Increment this value to trigger a schema update.
|
17 |
*/
|
18 |
-
protected $schema_version =
|
19 |
|
20 |
public function __construct() {
|
21 |
$this->tables = [
|
@@ -47,6 +47,7 @@ class ActionScheduler_StoreSchema extends ActionScheduler_Abstract_Schema {
|
|
47 |
last_attempt_gmt datetime NOT NULL default '0000-00-00 00:00:00',
|
48 |
last_attempt_local datetime NOT NULL default '0000-00-00 00:00:00',
|
49 |
claim_id bigint(20) unsigned NOT NULL default '0',
|
|
|
50 |
PRIMARY KEY (action_id),
|
51 |
KEY hook (hook($max_index_length)),
|
52 |
KEY status (status),
|
15 |
/**
|
16 |
* @var int Increment this value to trigger a schema update.
|
17 |
*/
|
18 |
+
protected $schema_version = 3;
|
19 |
|
20 |
public function __construct() {
|
21 |
$this->tables = [
|
47 |
last_attempt_gmt datetime NOT NULL default '0000-00-00 00:00:00',
|
48 |
last_attempt_local datetime NOT NULL default '0000-00-00 00:00:00',
|
49 |
claim_id bigint(20) unsigned NOT NULL default '0',
|
50 |
+
extended_args varchar(8000) DEFAULT NULL,
|
51 |
PRIMARY KEY (action_id),
|
52 |
KEY hook (hook($max_index_length)),
|
53 |
KEY status (status),
|
includes/vendor/action-scheduler/composer.json
CHANGED
@@ -32,5 +32,12 @@
|
|
32 |
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
|
33 |
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
|
34 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
}
|
32 |
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
|
33 |
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
|
34 |
}
|
35 |
+
},
|
36 |
+
"autoload": {
|
37 |
+
"classmap": [
|
38 |
+
"classes/",
|
39 |
+
"deprecated/",
|
40 |
+
"lib/"
|
41 |
+
]
|
42 |
}
|
43 |
}
|
includes/vendor/action-scheduler/docs/_layouts/default.html
CHANGED
@@ -27,7 +27,7 @@
|
|
27 |
</svg>
|
28 |
</a>
|
29 |
<div class="container">
|
30 |
-
<p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a>
|
31 |
<h1><a href="/">action-scheduler</a></h1>
|
32 |
<h2>A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.</h2>
|
33 |
</div>
|
27 |
</svg>
|
28 |
</a>
|
29 |
<div class="container">
|
30 |
+
<p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a> | <a href="/version3-0/">Version 3.0</a>
|
31 |
<h1><a href="/">action-scheduler</a></h1>
|
32 |
<h2>A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.</h2>
|
33 |
</div>
|
includes/vendor/action-scheduler/docs/api.md
CHANGED
@@ -20,7 +20,7 @@ Functions return similar values and accept similar arguments to their WP-Cron co
|
|
20 |
|
21 |
## API Function Availability
|
22 |
|
23 |
-
As mentioned in the [Usage - Load Order](/usage/#load-order) section, Action Scheduler will initialize itself on the `'init'` hook with priority `1`. While API functions are loaded prior to this and
|
24 |
|
25 |
Do not use Action Scheduler API functions prior to `'init'` hook with priority `1`. Doing so could lead to unexpected results, like data being stored in the incorrect location.
|
26 |
|
20 |
|
21 |
## API Function Availability
|
22 |
|
23 |
+
As mentioned in the [Usage - Load Order](/usage/#load-order) section, Action Scheduler will initialize itself on the `'init'` hook with priority `1`. While API functions are loaded prior to this and can be called, they should not be called until after `'init'` with priority `1`, because each component, like the data store, has not yet been initialized.
|
24 |
|
25 |
Do not use Action Scheduler API functions prior to `'init'` hook with priority `1`. Doing so could lead to unexpected results, like data being stored in the incorrect location.
|
26 |
|
includes/vendor/action-scheduler/docs/usage.md
CHANGED
@@ -6,7 +6,7 @@ description: Learn how to use the Action Scheduler background processing job que
|
|
6 |
Using Action Scheduler requires:
|
7 |
|
8 |
1. installing the library
|
9 |
-
1. scheduling
|
10 |
1. attaching a callback to that action
|
11 |
|
12 |
## Scheduling an Action
|
6 |
Using Action Scheduler requires:
|
7 |
|
8 |
1. installing the library
|
9 |
+
1. scheduling an action
|
10 |
1. attaching a callback to that action
|
11 |
|
12 |
## Scheduling an Action
|
includes/vendor/action-scheduler/docs/version3-0.md
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Version 3.0 FAQ
|
2 |
+
|
3 |
+
### Do we need to wait for this to be bundled with WooCommerce?
|
4 |
+
|
5 |
+
No. Action Scheduler can be run as a standalone plugin. Action Scheduler 3.0 is also part of WooCommerce Subscriptions 3.0, so when updating WooCommerce Subscriptions, Action Scheduler will also be updated.
|
6 |
+
|
7 |
+
### Can we safely switch to action scheduler version 3.0 and ditch the custom tables plugin?
|
8 |
+
|
9 |
+
Yes! The Action Scheduler Custom Tables plugin code is now part of Action Scheduler itself (with a few improvements). We recommend disabling the Custom Tables plugin immediately after activating Action Scheduler 3.0, or a plugin containing Action Scheduler 3.0, like WooCommerce Subscriptions 3.0 and newer.
|
10 |
+
|
11 |
+
### How do we migrate from our own custom data store?
|
12 |
+
|
13 |
+
By default, Action Scheduler will only initiate a migration from the internal `WPPostStore` data store. To enable migration from any custom datastore add the following filter `add_filter( 'action_scheduler_migrate_data_store', '__return_true' );`.
|
14 |
+
|
15 |
+
### I'm currently on PHP <5.5. When I update PHP will the migration start automatically?
|
16 |
+
|
17 |
+
Yes! The migration is initiated as soon as all dependencies are met.
|
18 |
+
|
19 |
+
### I would like to update a plugin for testing that includes Action Scheduler 3.0 but would like to postpone the migration until that testing is complete. Is that possible?
|
20 |
+
|
21 |
+
Yes, while we recommend migrating to custom tables as soon as possible for performance reasons, you can use `add_filter( 'action_scheduler_migration_dependencies_met', '__return_false' );` to prevent the migration from initiating.
|
22 |
+
|
23 |
+
### Is there a strong likelihood of migration issues with any of the above?
|
24 |
+
|
25 |
+
There is always the possibilities of issues, but it is not a strong likelihood. We tested migrating from Action Scheduler 2.n with the custom data stores (including Action Scheduler Custom Tables plugin) active to Action Scheduler 3.0 on a number of test sites.
|
26 |
+
|
27 |
+
As with all major, and minor, upgrades, we still testing the update on a staging site before updating the live site. We also recommending taking a backup before updating the live site.
|
28 |
+
|
29 |
+
If you wish to undertake more comprehensive testing on a development or staging site before updating, or want to closely monitor the update on a live site, follow these steps:
|
30 |
+
|
31 |
+
#### Stage 1: Prepare your site:
|
32 |
+
|
33 |
+
1. Take a backup of your database (AS 3.0 migrates data to custom tables, this can not be undone, you’ll need to restore a backup to downgrade).
|
34 |
+
1. Go to Tools > Action Scheduler
|
35 |
+
1. Take a screenshot of the action status counts at the top of the page. Example screenshot: https://cld.wthms.co/kwIqv7
|
36 |
+
|
37 |
+
|
38 |
+
#### Stage 2: Install & Activate Action Scheduler 3.0 as a plugin
|
39 |
+
|
40 |
+
1. The migration will start almost immediately
|
41 |
+
1. Keep an eye on your error log
|
42 |
+
1. Report any notices, errors or other issues on GitHub
|
43 |
+
|
44 |
+
#### Stage 3: Verify Migration
|
45 |
+
|
46 |
+
1. Go to Tools > Action Scheduler
|
47 |
+
1. Take a screenshot of the action status counts at the top of the page.
|
48 |
+
1. Verify the counts match the status counts taken in Stage 1 (the Completed counts could be higher because actions will have been completed to run the migration).
|
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.3.
|
20 |
* Author: Mailchimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|
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.3.3
|
20 |
* Author: Mailchimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|