Version Description
- added support for Polish (zloty - z) and Moldovan Leu currencies
- update currency code for Belarusian Rouble
- queue performance enhancement
Download this release
Release Info
Developer | ryanhungate |
Plugin | MailChimp for WooCommerce |
Version | 2.1.5 |
Comparing to | |
See all releases |
Code changes from version 2.1.4 to 2.1.5
- README.txt +27 -5
- includes/api/class-mailchimp-woocommerce-transform-products.php +31 -3
- includes/api/helpers/class-mailchimp-woocommerce-api-currency-codes.php +3 -1
- includes/class-mailchimp-woocommerce-activator.php +4 -2
- includes/class-mailchimp-woocommerce.php +9 -8
- includes/processes/class-mailchimp-woocommerce-abstract-sync.php +14 -3
- includes/vendor/queue.php +56 -9
- includes/vendor/queue/classes/cli/queue-command.php +276 -17
- includes/vendor/queue/classes/worker/wp-http-worker.php +58 -23
- includes/vendor/queue/classes/worker/wp-worker.php +7 -8
- includes/vendor/queue/classes/wp-queue.php +1 -6
- mailchimp-woocommerce.php +37 -12
README.txt
CHANGED
@@ -4,14 +4,14 @@ Tags: ecommerce,email,workflows,mailchimp
|
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.3
|
6 |
Tested up to: 4.9
|
7 |
-
Stable tag: 2.1.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
11 |
Connect your store to your MailChimp list to track sales, create targeted emails, send abandoned cart emails, and more.
|
12 |
|
13 |
== Description ==
|
14 |
-
Join the
|
15 |
|
16 |
With MailChimp for WooCommerce, you’ll have the power to:
|
17 |
|
@@ -20,9 +20,10 @@ With MailChimp for WooCommerce, you’ll have the power to:
|
|
20 |
- Showcase product recommendations.
|
21 |
- Track and segment customers based on purchase history and purchase frequency.
|
22 |
- View detailed data on your marketing performance in your MailChimp Dashboard.
|
23 |
-
-
|
24 |
- Automatically embed a pop-up form that converts your website visitors to subscribers.
|
25 |
- Add discount codes created in WooCommerce to your emails and automations with a Promo Code content block
|
|
|
26 |
|
27 |
###Important Notes
|
28 |
This plugin supports our most powerful API 3.0 features, and is intended for users who have not yet integrated their WooCommerce stores with MailChimp.
|
@@ -31,7 +32,7 @@ You can run this new integration at the same time as your current WooCommerce in
|
|
31 |
|
32 |
WordPress.com compatibility is limited to Business tier users only.
|
33 |
|
34 |
-
|
35 |
###Before You Start
|
36 |
Here are some things to know before you begin this process.
|
37 |
|
@@ -49,9 +50,30 @@ You’ll need to do a few things to connect your WooCommerce store to MailChimp.
|
|
49 |
- Connect the plugin with your MailChimp API Key.
|
50 |
- Configure your list settings to complete the data sync process.
|
51 |
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
55 |
= 2.1.4 =
|
56 |
* updated wordpress compatibility
|
57 |
* updated sync details tab to show more informative stats
|
4 |
Donate link: https://mailchimp.com
|
5 |
Requires at least: 4.3
|
6 |
Tested up to: 4.9
|
7 |
+
Stable tag: 2.1.5
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
11 |
Connect your store to your MailChimp list to track sales, create targeted emails, send abandoned cart emails, and more.
|
12 |
|
13 |
== Description ==
|
14 |
+
Join the 17 million customers who use MailChimp, the world's largest marketing automation platform, to develop their e-commerce marketing strategy. With the official MailChimp for WooCommerce integration, your customers and their purchase data are automatically synced with your MailChimp account, making it easy to send targeted campaigns, automatically follow up with customers post-purchase, recommend products, recover abandoned carts, and measure the ROI of your marketing efforts. And it's completely free.
|
15 |
|
16 |
With MailChimp for WooCommerce, you’ll have the power to:
|
17 |
|
20 |
- Showcase product recommendations.
|
21 |
- Track and segment customers based on purchase history and purchase frequency.
|
22 |
- View detailed data on your marketing performance in your MailChimp Dashboard.
|
23 |
+
- Find new customers, connect with current ones, and drive them all to your website with [Facebook](https://mailchimp.com/features/facebook-ads/) and [Instagram](https://mailchimp.com/features/instagram-ads/) ads. Then, set up [Google remarketing](https://mailchimp.com/features/google-remarketing-ads/) ads to turn your site visitors into shoppers.
|
24 |
- Automatically embed a pop-up form that converts your website visitors to subscribers.
|
25 |
- Add discount codes created in WooCommerce to your emails and automations with a Promo Code content block
|
26 |
+
- Create beautiful landing pages that make it easy to highlight your products, promote a sale or giveaway, and grow your list.
|
27 |
|
28 |
###Important Notes
|
29 |
This plugin supports our most powerful API 3.0 features, and is intended for users who have not yet integrated their WooCommerce stores with MailChimp.
|
32 |
|
33 |
WordPress.com compatibility is limited to Business tier users only.
|
34 |
|
35 |
+
=== Installation ===
|
36 |
###Before You Start
|
37 |
Here are some things to know before you begin this process.
|
38 |
|
50 |
- Connect the plugin with your MailChimp API Key.
|
51 |
- Configure your list settings to complete the data sync process.
|
52 |
|
53 |
+
###Advanced Queue Setup In CLI mode
|
54 |
+
To optimize the performance of your MailChimp integration - it is recommended that you run the queue in CLI mode.
|
55 |
+
|
56 |
+
First define a constant in your config file
|
57 |
+
|
58 |
+
`define('DISABLE_WP_HTTP_WORKER', true);`
|
59 |
+
|
60 |
+
You have 2 options to run this process:
|
61 |
+
|
62 |
+
1. On a cron schedule every minute:
|
63 |
+
|
64 |
+
`* * * * * /usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
|
65 |
+
|
66 |
+
2. Using a process manager like Monit or Supervisord:
|
67 |
+
|
68 |
+
`/usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
|
69 |
+
|
70 |
|
71 |
== Changelog ==
|
72 |
+
= 2.1.5 =
|
73 |
+
* added support for Polish (zloty - zł) and Moldovan Leu currencies
|
74 |
+
* update currency code for Belarusian Rouble
|
75 |
+
* queue performance enhancement
|
76 |
+
|
77 |
= 2.1.4 =
|
78 |
* updated wordpress compatibility
|
79 |
* updated sync details tab to show more informative stats
|
includes/api/class-mailchimp-woocommerce-transform-products.php
CHANGED
@@ -56,7 +56,7 @@ class MailChimp_WooCommerce_Transform_Products
|
|
56 |
|
57 |
$product->setId($woo->get_id());
|
58 |
$product->setHandle($post->post_name);
|
59 |
-
$product->setImageUrl(
|
60 |
$product->setDescription($post->post_content);
|
61 |
$product->setPublishedAtForeign(mailchimp_date_utc($post->post_date));
|
62 |
$product->setTitle($woo->get_title());
|
@@ -106,7 +106,7 @@ class MailChimp_WooCommerce_Transform_Products
|
|
106 |
|
107 |
$variant->setId($woo->get_id());
|
108 |
$variant->setUrl($woo->get_permalink());
|
109 |
-
$variant->setImageUrl(
|
110 |
$variant->setPrice($woo->get_price());
|
111 |
$variant->setSku($woo->get_sku());
|
112 |
$variant->setBackorders($woo->backorders_allowed());
|
@@ -202,9 +202,37 @@ class MailChimp_WooCommerce_Transform_Products
|
|
202 |
return $variants;
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
/**
|
206 |
* @param $id
|
207 |
-
* @return MailChimp_WooCommerce_Product
|
|
|
208 |
*/
|
209 |
public static function deleted($id)
|
210 |
{
|
56 |
|
57 |
$product->setId($woo->get_id());
|
58 |
$product->setHandle($post->post_name);
|
59 |
+
$product->setImageUrl($this->getProductImage($post));
|
60 |
$product->setDescription($post->post_content);
|
61 |
$product->setPublishedAtForeign(mailchimp_date_utc($post->post_date));
|
62 |
$product->setTitle($woo->get_title());
|
106 |
|
107 |
$variant->setId($woo->get_id());
|
108 |
$variant->setUrl($woo->get_permalink());
|
109 |
+
$variant->setImageUrl($this->getProductImage($post));
|
110 |
$variant->setPrice($woo->get_price());
|
111 |
$variant->setSku($woo->get_sku());
|
112 |
$variant->setBackorders($woo->backorders_allowed());
|
202 |
return $variants;
|
203 |
}
|
204 |
|
205 |
+
/**
|
206 |
+
* @param $post_id
|
207 |
+
* @return false|string
|
208 |
+
*/
|
209 |
+
public function getProductImage($post_id)
|
210 |
+
{
|
211 |
+
$meta = get_post_meta($post_id);
|
212 |
+
$key = '_thumbnail_id';
|
213 |
+
$image_key = $this->getProductImageKey();
|
214 |
+
|
215 |
+
if ($meta && is_array($meta) && array_key_exists($key, $meta) && isset($meta[$key][0])) {
|
216 |
+
$img = wp_get_attachment_image($meta[$key][0], $image_key);
|
217 |
+
if (!empty($img)) return $img;
|
218 |
+
}
|
219 |
+
|
220 |
+
return get_the_post_thumbnail_url($post_id, $image_key);
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* @return null|string
|
225 |
+
*/
|
226 |
+
public function getProductImageKey()
|
227 |
+
{
|
228 |
+
// going to add a setting for this.
|
229 |
+
return 'post-thumbnail';
|
230 |
+
}
|
231 |
+
|
232 |
/**
|
233 |
* @param $id
|
234 |
+
* @return bool|MailChimp_WooCommerce_Product
|
235 |
+
* @throws Exception
|
236 |
*/
|
237 |
public static function deleted($id)
|
238 |
{
|
includes/api/helpers/class-mailchimp-woocommerce-api-currency-codes.php
CHANGED
@@ -24,7 +24,7 @@ class MailChimp_WooCommerce_CurrencyCodes
|
|
24 |
'BSD' => array('Bahamian Dollar', '044'),
|
25 |
'BDT' => array('Bangladeshi Taka', '050'),
|
26 |
'BBD' => array('Barbados Dollar', '052'),
|
27 |
-
'
|
28 |
'BOB' => array('Bolivian Boliviano', '068'),
|
29 |
'BRL' => array('Brazilian Real', '986'),
|
30 |
'GBP' => array('British Pounds Sterling', '826'),
|
@@ -65,6 +65,7 @@ class MailChimp_WooCommerce_CurrencyCodes
|
|
65 |
'LVL' => array('Latvia Lat', '428'),
|
66 |
'LBP' => array('Lebanese Pound', '422'),
|
67 |
'LTL' => array('Lithuania Litas', '440'),
|
|
|
68 |
'MOP' => array('Macau Pataca', '446'),
|
69 |
'MKD' => array('Macedonian Denar', '807'),
|
70 |
'MGA' => array('Malagascy Ariary', '969'),
|
@@ -87,6 +88,7 @@ class MailChimp_WooCommerce_CurrencyCodes
|
|
87 |
'PYG' => array('Paraguay Guarani', '600'),
|
88 |
'PEN' => array('Peru New Sol', '604'),
|
89 |
'PHP' => array('Philippine Pesos', '608'),
|
|
|
90 |
'QAR' => array('Qatari Riyal', '634'),
|
91 |
'RON' => array('Romanian New Leu', '946'),
|
92 |
'RUB' => array('Russian Federation Ruble', '643'),
|
24 |
'BSD' => array('Bahamian Dollar', '044'),
|
25 |
'BDT' => array('Bangladeshi Taka', '050'),
|
26 |
'BBD' => array('Barbados Dollar', '052'),
|
27 |
+
'BYN' => array('Belarussian Rouble', '974'),
|
28 |
'BOB' => array('Bolivian Boliviano', '068'),
|
29 |
'BRL' => array('Brazilian Real', '986'),
|
30 |
'GBP' => array('British Pounds Sterling', '826'),
|
65 |
'LVL' => array('Latvia Lat', '428'),
|
66 |
'LBP' => array('Lebanese Pound', '422'),
|
67 |
'LTL' => array('Lithuania Litas', '440'),
|
68 |
+
'MDL' => array('Moldovan Leu', '498'),
|
69 |
'MOP' => array('Macau Pataca', '446'),
|
70 |
'MKD' => array('Macedonian Denar', '807'),
|
71 |
'MGA' => array('Malagascy Ariary', '969'),
|
88 |
'PYG' => array('Paraguay Guarani', '600'),
|
89 |
'PEN' => array('Peru New Sol', '604'),
|
90 |
'PHP' => array('Philippine Pesos', '608'),
|
91 |
+
'PLN' => array('Polish Zloty', '985'),
|
92 |
'QAR' => array('Qatari Riyal', '634'),
|
93 |
'RON' => array('Romanian New Leu', '946'),
|
94 |
'RUB' => array('Russian Federation Ruble', '643'),
|
includes/class-mailchimp-woocommerce-activator.php
CHANGED
@@ -43,8 +43,10 @@ class MailChimp_Woocommerce_Activator {
|
|
43 |
update_option('mailchimp-woocommerce-store_id', uniqid(), 'yes');
|
44 |
}
|
45 |
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
}
|
49 |
|
50 |
/**
|
43 |
update_option('mailchimp-woocommerce-store_id', uniqid(), 'yes');
|
44 |
}
|
45 |
|
46 |
+
if (class_exists('MailChimp_WooCommerce_MailChimpApi')) {
|
47 |
+
// try this now for existing stores on an update.
|
48 |
+
mailchimp_update_connected_site_script();
|
49 |
+
}
|
50 |
}
|
51 |
|
52 |
/**
|
includes/class-mailchimp-woocommerce.php
CHANGED
@@ -295,14 +295,15 @@ class MailChimp_Woocommerce {
|
|
295 |
|
296 |
// adding the ability to render the checkbox on another screen of the checkout page.
|
297 |
$render_on = $service->getOption('mailchimp_checkbox_action', 'woocommerce_after_checkout_billing_form');
|
298 |
-
$this->loader->add_action($render_on, $service, 'applyNewsletterField', 5);
|
299 |
|
300 |
-
$this->loader->add_action(
|
301 |
-
$this->loader->add_action('woocommerce_register_form', $service, 'applyNewsletterField', 5);
|
302 |
|
303 |
-
$this->loader->add_action('
|
304 |
-
$this->loader->add_action('
|
305 |
-
|
|
|
|
|
|
|
306 |
}
|
307 |
}
|
308 |
|
@@ -329,9 +330,9 @@ class MailChimp_Woocommerce {
|
|
329 |
$this->loader->add_action( 'init', $service, 'handleCampaignTracking' );
|
330 |
|
331 |
// order hooks
|
332 |
-
$this->loader->add_action('woocommerce_thankyou', $service, 'onNewOrder',
|
333 |
$this->loader->add_action('woocommerce_api_create_order', $service, 'onNewOrder', 10);
|
334 |
-
$this->loader->add_action('woocommerce_order_status_changed', $service, 'handleOrderStatusChanged',
|
335 |
|
336 |
// partially refunded
|
337 |
$this->loader->add_action('woocommerce_order_partially_refunded', $service, 'onPartiallyRefunded', 10);
|
295 |
|
296 |
// adding the ability to render the checkbox on another screen of the checkout page.
|
297 |
$render_on = $service->getOption('mailchimp_checkbox_action', 'woocommerce_after_checkout_billing_form');
|
|
|
298 |
|
299 |
+
$this->loader->add_action($render_on, $service, 'applyNewsletterField', 10);
|
|
|
300 |
|
301 |
+
$this->loader->add_action('woocommerce_ppe_checkout_order_review', $service, 'applyNewsletterField', 10);
|
302 |
+
$this->loader->add_action('woocommerce_register_form', $service, 'applyNewsletterField', 10);
|
303 |
+
|
304 |
+
$this->loader->add_action('woocommerce_checkout_order_processed', $service, 'processNewsletterField', 10, 2);
|
305 |
+
$this->loader->add_action('woocommerce_ppe_do_payaction', $service, 'processPayPalNewsletterField', 10, 1);
|
306 |
+
$this->loader->add_action('woocommerce_register_post', $service, 'processRegistrationForm', 10, 3);
|
307 |
}
|
308 |
}
|
309 |
|
330 |
$this->loader->add_action( 'init', $service, 'handleCampaignTracking' );
|
331 |
|
332 |
// order hooks
|
333 |
+
$this->loader->add_action('woocommerce_thankyou', $service, 'onNewOrder', 10);
|
334 |
$this->loader->add_action('woocommerce_api_create_order', $service, 'onNewOrder', 10);
|
335 |
+
$this->loader->add_action('woocommerce_order_status_changed', $service, 'handleOrderStatusChanged', 10);
|
336 |
|
337 |
// partially refunded
|
338 |
$this->loader->add_action('woocommerce_order_partially_refunded', $service, 'onPartiallyRefunded', 10);
|
includes/processes/class-mailchimp-woocommerce-abstract-sync.php
CHANGED
@@ -74,16 +74,20 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
|
|
74 |
*
|
75 |
* @return mixed
|
76 |
*/
|
77 |
-
public function handle()
|
|
|
|
|
78 |
|
79 |
if (!($this->store_id = $this->getStoreID())) {
|
80 |
mailchimp_debug(get_called_class().'@handle', 'store id not loaded');
|
|
|
81 |
return false;
|
82 |
}
|
83 |
|
84 |
// don't let recursion happen.
|
85 |
if ($this->getResourceType() === 'orders' && $this->getResourceCompleteTime()) {
|
86 |
mailchimp_log('sync.stop', "halting the sync for :: {$this->getResourceType()}");
|
|
|
87 |
return false;
|
88 |
}
|
89 |
|
@@ -94,6 +98,8 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
|
|
94 |
// call the completed event to process further
|
95 |
$this->resourceComplete($this->getResourceType());
|
96 |
$this->complete();
|
|
|
|
|
97 |
return false;
|
98 |
}
|
99 |
|
@@ -110,6 +116,8 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
|
|
110 |
// call the completed event to process further
|
111 |
$this->complete();
|
112 |
|
|
|
|
|
113 |
return false;
|
114 |
}
|
115 |
|
@@ -118,11 +126,14 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
|
|
118 |
$this->iterate($resource);
|
119 |
}
|
120 |
|
121 |
-
|
|
|
|
|
|
|
122 |
|
123 |
// this will paginate through all records for the resource type until they return no records.
|
124 |
wp_queue(new static());
|
125 |
-
|
126 |
return false;
|
127 |
}
|
128 |
|
74 |
*
|
75 |
* @return mixed
|
76 |
*/
|
77 |
+
public function handle()
|
78 |
+
{
|
79 |
+
global $wpdb;
|
80 |
|
81 |
if (!($this->store_id = $this->getStoreID())) {
|
82 |
mailchimp_debug(get_called_class().'@handle', 'store id not loaded');
|
83 |
+
$this->delete();
|
84 |
return false;
|
85 |
}
|
86 |
|
87 |
// don't let recursion happen.
|
88 |
if ($this->getResourceType() === 'orders' && $this->getResourceCompleteTime()) {
|
89 |
mailchimp_log('sync.stop', "halting the sync for :: {$this->getResourceType()}");
|
90 |
+
$this->delete();
|
91 |
return false;
|
92 |
}
|
93 |
|
98 |
// call the completed event to process further
|
99 |
$this->resourceComplete($this->getResourceType());
|
100 |
$this->complete();
|
101 |
+
$this->delete();
|
102 |
+
|
103 |
return false;
|
104 |
}
|
105 |
|
116 |
// call the completed event to process further
|
117 |
$this->complete();
|
118 |
|
119 |
+
$this->delete();
|
120 |
+
|
121 |
return false;
|
122 |
}
|
123 |
|
126 |
$this->iterate($resource);
|
127 |
}
|
128 |
|
129 |
+
$this->delete();
|
130 |
+
|
131 |
+
$class_name = get_called_class();
|
132 |
+
$wpdb->query("DELETE FROM {$wpdb->prefix}queue WHERE job LIKE '%{$class_name}%'");
|
133 |
|
134 |
// this will paginate through all records for the resource type until they return no records.
|
135 |
wp_queue(new static());
|
136 |
+
mailchimp_debug(get_called_class().'@handle', 'queuing up the next job');
|
137 |
return false;
|
138 |
}
|
139 |
|
includes/vendor/queue.php
CHANGED
@@ -21,22 +21,69 @@ $wp_queue = new WP_Queue();
|
|
21 |
// Add WP CLI commands
|
22 |
if (defined( 'WP_CLI' ) && WP_CLI) {
|
23 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
require_once $queue_folder_path . 'queue/classes/cli/queue-command.php';
|
25 |
WP_CLI::add_command( 'queue', 'Queue_Command' );
|
26 |
} catch (\Exception $e) {}
|
27 |
}
|
28 |
|
|
|
|
|
|
|
|
|
|
|
29 |
// if we're not running in the console, and the http_worker is not running
|
30 |
-
if (
|
31 |
try {
|
32 |
-
//
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
40 |
}
|
41 |
} catch (\Exception $e) {}
|
42 |
}
|
21 |
// Add WP CLI commands
|
22 |
if (defined( 'WP_CLI' ) && WP_CLI) {
|
23 |
try {
|
24 |
+
/**
|
25 |
+
* Service push to MailChimp
|
26 |
+
*
|
27 |
+
* <type>
|
28 |
+
* : product_sync order_sync order product
|
29 |
+
*/
|
30 |
+
function mailchimp_cli_push_command( $args, $assoc_args ) {
|
31 |
+
if (is_array($args) && isset($args[0])) {
|
32 |
+
switch($args[0]) {
|
33 |
+
|
34 |
+
case 'product_sync':
|
35 |
+
wp_queue(new MailChimp_WooCommerce_Process_Products());
|
36 |
+
WP_CLI::success("queued up the product sync!");
|
37 |
+
break;
|
38 |
+
|
39 |
+
case 'order_sync':
|
40 |
+
wp_queue(new MailChimp_WooCommerce_Process_Orders());
|
41 |
+
WP_CLI::success("queued up the order sync!");
|
42 |
+
break;
|
43 |
+
|
44 |
+
case 'order':
|
45 |
+
if (!isset($args[1])) {
|
46 |
+
wp_die('You must specify an order id as the 2nd parameter.');
|
47 |
+
}
|
48 |
+
wp_queue(new MailChimp_WooCommerce_Single_Order($args[1]));
|
49 |
+
WP_CLI::success("queued up the order {$args[1]}!");
|
50 |
+
break;
|
51 |
+
|
52 |
+
case 'product':
|
53 |
+
if (!isset($args[1])) {
|
54 |
+
wp_die('You must specify a product id as the 2nd parameter.');
|
55 |
+
}
|
56 |
+
wp_queue(new MailChimp_WooCommerce_Single_Product($args[1]));
|
57 |
+
WP_CLI::success("queued up the product {$args[1]}!");
|
58 |
+
break;
|
59 |
+
}
|
60 |
+
}
|
61 |
+
};
|
62 |
+
|
63 |
+
WP_CLI::add_command( 'mailchimp_push', 'mailchimp_cli_push_command');
|
64 |
+
|
65 |
require_once $queue_folder_path . 'queue/classes/cli/queue-command.php';
|
66 |
WP_CLI::add_command( 'queue', 'Queue_Command' );
|
67 |
} catch (\Exception $e) {}
|
68 |
}
|
69 |
|
70 |
+
if (!mailchimp_running_in_console() && mailchimp_is_configured()) {
|
71 |
+
// fire up the http worker container
|
72 |
+
new WP_Http_Worker($wp_queue);
|
73 |
+
}
|
74 |
+
|
75 |
// if we're not running in the console, and the http_worker is not running
|
76 |
+
if (mailchimp_should_init_queue()) {
|
77 |
try {
|
78 |
+
// if we do not have a site transient for the queue listener
|
79 |
+
if (!get_site_transient('http_worker_queue_listen')) {
|
80 |
+
// set the site transient to expire in 50 seconds so this will not happen too many times
|
81 |
+
// but still work for cron scripts on the minute mark.
|
82 |
+
set_site_transient( 'http_worker_queue_listen', microtime(), 50);
|
83 |
+
// if we have available jobs, call the http worker manually
|
84 |
+
if ($wp_queue->available_jobs()) {
|
85 |
+
mailchimp_call_http_worker_manually();
|
86 |
+
}
|
87 |
}
|
88 |
} catch (\Exception $e) {}
|
89 |
}
|
includes/vendor/queue/classes/cli/queue-command.php
CHANGED
@@ -7,15 +7,69 @@
|
|
7 |
*/
|
8 |
class Queue_Command extends WP_CLI_Command {
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
public function flush()
|
11 |
{
|
12 |
global $wpdb;
|
|
|
13 |
$wpdb->query("DELETE FROM {$wpdb->prefix}queue");
|
14 |
}
|
15 |
|
|
|
|
|
|
|
16 |
public function show()
|
17 |
{
|
18 |
global $wpdb;
|
|
|
19 |
print_r($wpdb->get_results("SELECT * FROM {$wpdb->prefix}queue"));
|
20 |
}
|
21 |
|
@@ -25,6 +79,8 @@ class Queue_Command extends WP_CLI_Command {
|
|
25 |
* @subcommand create-tables
|
26 |
*/
|
27 |
public function create_tables( $args, $assoc_args = array() ) {
|
|
|
|
|
28 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
29 |
|
30 |
global $wpdb;
|
@@ -58,34 +114,128 @@ class Queue_Command extends WP_CLI_Command {
|
|
58 |
WP_CLI::success( "Table {$wpdb->prefix}queue created." );
|
59 |
}
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
public function listen( $args, $assoc_args = array() ) {
|
65 |
global $wp_queue;
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
$worker = new WP_Worker( $wp_queue );
|
68 |
|
69 |
-
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
|
|
|
|
80 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* Process the next job in the queue.
|
|
|
85 |
*/
|
86 |
public function work( $args, $assoc_args = array() ) {
|
87 |
global $wp_queue;
|
88 |
|
|
|
|
|
89 |
$worker = new WP_Worker( $wp_queue );
|
90 |
|
91 |
if ( $worker->should_run() ) {
|
@@ -104,7 +254,7 @@ class Queue_Command extends WP_CLI_Command {
|
|
104 |
*/
|
105 |
public function status( $args, $assoc_args = array() ) {
|
106 |
global $wp_queue;
|
107 |
-
|
108 |
WP_CLI::log( $wp_queue->available_jobs() . ' jobs in the queue' );
|
109 |
WP_CLI::log( $wp_queue->failed_jobs() . ' failed jobs' );
|
110 |
}
|
@@ -116,17 +266,126 @@ class Queue_Command extends WP_CLI_Command {
|
|
116 |
*/
|
117 |
public function restart_failed( $args, $assoc_args = array() ) {
|
118 |
global $wp_queue;
|
119 |
-
|
120 |
if ( ! $wp_queue->failed_jobs() ) {
|
121 |
WP_CLI::log( 'No failed jobs to restart...' );
|
122 |
-
|
123 |
return;
|
124 |
}
|
125 |
-
|
126 |
$count = $wp_queue->restart_failed_jobs();
|
127 |
-
|
128 |
WP_CLI::success( $count . ' failed jobs pushed to the queue' );
|
129 |
}
|
130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
}
|
132 |
|
7 |
*/
|
8 |
class Queue_Command extends WP_CLI_Command {
|
9 |
|
10 |
+
/**
|
11 |
+
* Timestamp of when this worker started processing the queue.
|
12 |
+
*
|
13 |
+
* @var int
|
14 |
+
*/
|
15 |
+
protected $start_time;
|
16 |
+
protected $pid;
|
17 |
+
protected $command_called;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Queue_Command constructor.
|
21 |
+
*/
|
22 |
+
public function __construct()
|
23 |
+
{
|
24 |
+
$this->pid = getmypid();
|
25 |
+
register_shutdown_function(array($this, 'on_shutdown'));
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* make sure we remove the site transient
|
30 |
+
*/
|
31 |
+
public function on_shutdown()
|
32 |
+
{
|
33 |
+
switch ($this->command_called) {
|
34 |
+
case 'listen':
|
35 |
+
$this->deleteQueueTimer();
|
36 |
+
break;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Get the expiration for the single cron job
|
42 |
+
*
|
43 |
+
* @throws \WP_CLI\ExitException
|
44 |
+
*/
|
45 |
+
public function expired_at()
|
46 |
+
{
|
47 |
+
$time = $this->getQueueTimer();
|
48 |
+
if (empty($time)) {
|
49 |
+
WP_CLI::error('no timer running');
|
50 |
+
wp_die();
|
51 |
+
}
|
52 |
+
WP_CLI::success("Next iteration will happen no later than ".(string) mailchimp_date_utc($time));
|
53 |
+
wp_die();
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Flush all of the records in the queue.
|
58 |
+
*/
|
59 |
public function flush()
|
60 |
{
|
61 |
global $wpdb;
|
62 |
+
$this->command_called = 'flush';
|
63 |
$wpdb->query("DELETE FROM {$wpdb->prefix}queue");
|
64 |
}
|
65 |
|
66 |
+
/**
|
67 |
+
* Show all the records in the queue.
|
68 |
+
*/
|
69 |
public function show()
|
70 |
{
|
71 |
global $wpdb;
|
72 |
+
$this->command_called = 'show';
|
73 |
print_r($wpdb->get_results("SELECT * FROM {$wpdb->prefix}queue"));
|
74 |
}
|
75 |
|
79 |
* @subcommand create-tables
|
80 |
*/
|
81 |
public function create_tables( $args, $assoc_args = array() ) {
|
82 |
+
$this->command_called = 'create_tables';
|
83 |
+
|
84 |
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
85 |
|
86 |
global $wpdb;
|
114 |
WP_CLI::success( "Table {$wpdb->prefix}queue created." );
|
115 |
}
|
116 |
|
117 |
+
/**
|
118 |
+
* Run the queue listener to process jobs
|
119 |
+
*
|
120 |
+
* ## OPTIONS
|
121 |
+
*
|
122 |
+
* [--force=<0>]
|
123 |
+
* : Force the listener to ignore the transient and run
|
124 |
+
*
|
125 |
+
* [--daemon=<0>]
|
126 |
+
* : Running the command as a true process using a manager to keep alive.
|
127 |
+
* If using WP CRON use --daemon=0
|
128 |
+
* If using a process manager, do nothing or pass in 1
|
129 |
+
*
|
130 |
+
* [--multiple=<0>]
|
131 |
+
* : Allow multiple processes to run at the same time. ( default is 0 )
|
132 |
+
*
|
133 |
+
* [--sleep_processing=<1>]
|
134 |
+
* : How long to sleep between jobs. ( default is 1 second )
|
135 |
+
*
|
136 |
+
* [--sleep_empty=<5>]
|
137 |
+
* : How long to sleep between jobs when nothing is in the queue. ( default is 5 seconds )
|
138 |
+
* ---
|
139 |
+
*
|
140 |
+
* ## EXAMPLES
|
141 |
+
*
|
142 |
+
* wp queue listen --daemon=1
|
143 |
+
* wp queue listen --daemon=0 --sleep_empty=10
|
144 |
+
*
|
145 |
+
* ---
|
146 |
+
*
|
147 |
+
* @subcommand listen
|
148 |
+
* @param $args
|
149 |
+
* @param array $assoc_args
|
150 |
+
*/
|
151 |
public function listen( $args, $assoc_args = array() ) {
|
152 |
global $wp_queue;
|
153 |
|
154 |
+
$this->command_called = 'listen';
|
155 |
+
|
156 |
+
$this->start_time = time(); // Set start time of current command
|
157 |
+
|
158 |
+
$allow_multiple = (isset($assoc_args['multiple']) ? (bool) $assoc_args['multiple'] : null) === true;
|
159 |
+
$running_as_daemon = (isset($assoc_args['daemon']) ? (bool) $assoc_args['daemon'] : null) === true;
|
160 |
+
$force = (isset($assoc_args['force']) ? (bool) $assoc_args['force'] : null) === true;
|
161 |
+
|
162 |
+
$sleep_between_jobs = isset($assoc_args['sleep_processing']) ? (int) $assoc_args['sleep_processing'] : 1;
|
163 |
+
$sleep_when_empty = isset($assoc_args['sleep_empty']) ? (int) $assoc_args['sleep_empty'] : 5;
|
164 |
+
|
165 |
+
$expire_time = $this->getQueueTimer();
|
166 |
+
|
167 |
+
if (!$force && !$allow_multiple) {
|
168 |
+
if (!empty($expire_time) && ($expire_time+100) > $this->start_time) {
|
169 |
+
WP_CLI::log('Currently running in another process');
|
170 |
+
//mailchimp_debug("queue", $message = "wp queue listen is running in another process or waiting to restart at [{$expire_time}] but clock says [{$this->start_time}].");
|
171 |
+
wp_die();
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
$this->updateQueueTimer();
|
176 |
+
|
177 |
+
mailchimp_debug("queue", $message = "[start] queue listen process_id [{$this->pid}] :: max_time [{$this->getServerMaxExecutionTime()}] :: memory limit [{$this->getServerMemoryLimit()}]");
|
178 |
+
|
179 |
+
WP_CLI::log($message);
|
180 |
+
|
181 |
$worker = new WP_Worker( $wp_queue );
|
182 |
|
183 |
+
$loop_counter = 0;
|
184 |
|
185 |
+
// if the user specifies that they want to run as a daemon we need to allow that.
|
186 |
+
while ($running_as_daemon || $this->all_good_under_the_hood()) {
|
187 |
+
|
188 |
+
$loop_counter++;
|
189 |
+
|
190 |
+
// if we're doing single processing only, set the transient
|
191 |
+
if (!$allow_multiple) {
|
192 |
+
if ($loop_counter % 5 === 0) {
|
193 |
+
$this->updateQueueTimer(time() + 300);
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
// allow queue to break out of the forever loop if something is going wrong by adding a transient
|
198 |
+
if ((bool) get_site_transient('kill_wp_queue_listener')) {
|
199 |
+
break;
|
200 |
+
}
|
201 |
+
|
202 |
+
// log it in increments of 20 to be lighter on the log file
|
203 |
+
if ($loop_counter % 20 === 0) {
|
204 |
+
mailchimp_debug("queue listen", $message = "process id {$this->pid} :: loop #{$loop_counter}");
|
205 |
+
WP_CLI::log($message);
|
206 |
+
}
|
207 |
+
|
208 |
+
$sleep = $sleep_when_empty;
|
209 |
+
|
210 |
+
// if the worker has a job, apply the sleep between job timeout
|
211 |
+
if ($worker->should_run() && $worker->process_next_job()) {
|
212 |
+
$sleep = $sleep_between_jobs;
|
213 |
+
if (($job_name = $worker->get_job_name()) !== 'WP_Worker') {
|
214 |
+
WP_CLI::success('Processed: ' . $job_name);
|
215 |
+
}
|
216 |
}
|
217 |
+
|
218 |
+
sleep($sleep);
|
219 |
}
|
220 |
+
|
221 |
+
if (!$allow_multiple) {
|
222 |
+
$this->deleteQueueTimer();
|
223 |
+
}
|
224 |
+
|
225 |
+
mailchimp_debug("queue", $message = '[end] queue listen process_id = '.$this->pid);
|
226 |
+
WP_CLI::log($message);
|
227 |
+
exit;
|
228 |
}
|
229 |
|
230 |
/**
|
231 |
* Process the next job in the queue.
|
232 |
+
* @subcommand work
|
233 |
*/
|
234 |
public function work( $args, $assoc_args = array() ) {
|
235 |
global $wp_queue;
|
236 |
|
237 |
+
$this->command_called = 'work';
|
238 |
+
|
239 |
$worker = new WP_Worker( $wp_queue );
|
240 |
|
241 |
if ( $worker->should_run() ) {
|
254 |
*/
|
255 |
public function status( $args, $assoc_args = array() ) {
|
256 |
global $wp_queue;
|
257 |
+
$this->command_called = 'status';
|
258 |
WP_CLI::log( $wp_queue->available_jobs() . ' jobs in the queue' );
|
259 |
WP_CLI::log( $wp_queue->failed_jobs() . ' failed jobs' );
|
260 |
}
|
266 |
*/
|
267 |
public function restart_failed( $args, $assoc_args = array() ) {
|
268 |
global $wp_queue;
|
269 |
+
$this->command_called = 'restart_failed';
|
270 |
if ( ! $wp_queue->failed_jobs() ) {
|
271 |
WP_CLI::log( 'No failed jobs to restart...' );
|
|
|
272 |
return;
|
273 |
}
|
|
|
274 |
$count = $wp_queue->restart_failed_jobs();
|
|
|
275 |
WP_CLI::success( $count . ' failed jobs pushed to the queue' );
|
276 |
}
|
277 |
|
278 |
+
/**
|
279 |
+
* @return mixed
|
280 |
+
*/
|
281 |
+
protected function deleteQueueTimer()
|
282 |
+
{
|
283 |
+
global $wpdb;
|
284 |
+
$key = 'mailchimp_woocommerce_queue_listen';
|
285 |
+
$sql = $wpdb->prepare("DELETE FROM {$wpdb->options} WHERE option_name = %s", $key);
|
286 |
+
return $wpdb->query($sql);
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* @return null
|
291 |
+
*/
|
292 |
+
protected function getQueueTimer()
|
293 |
+
{
|
294 |
+
global $wpdb;
|
295 |
+
$key = 'mailchimp_woocommerce_queue_listen';
|
296 |
+
$row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $key));
|
297 |
+
return is_object($row) ? (int) unserialize($row->option_value) : null;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* @param null $time
|
302 |
+
* @return mixed
|
303 |
+
*/
|
304 |
+
protected function updateQueueTimer($time = null)
|
305 |
+
{
|
306 |
+
global $wpdb;
|
307 |
+
if (empty($this->start_time)) {
|
308 |
+
$this->start_time = time();
|
309 |
+
}
|
310 |
+
$value = $time ?: $this->start_time+600;
|
311 |
+
$values = array(
|
312 |
+
'option_value' => serialize($value),
|
313 |
+
'autoload' => 'no',
|
314 |
+
);
|
315 |
+
$key = 'mailchimp_woocommerce_queue_listen';
|
316 |
+
$updated = $wpdb->update($wpdb->options, $values, array('option_name' => $key));
|
317 |
+
if ($updated) {
|
318 |
+
return $updated;
|
319 |
+
}
|
320 |
+
$values['option_name'] = $key;
|
321 |
+
return $wpdb->insert($wpdb->options, $values);
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* @return bool
|
326 |
+
*/
|
327 |
+
protected function all_good_under_the_hood()
|
328 |
+
{
|
329 |
+
return !$this->time_exceeded() && !$this->memory_exceeded();
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Memory exceeded
|
334 |
+
*
|
335 |
+
* Ensures the worker process never exceeds 80%
|
336 |
+
* of the maximum allowed PHP memory.
|
337 |
+
*
|
338 |
+
* @return bool
|
339 |
+
*/
|
340 |
+
protected function memory_exceeded() {
|
341 |
+
return memory_get_usage( true ) >= ($this->get_memory_limit() * 0.8);
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Get memory limit
|
346 |
+
*
|
347 |
+
* @return int
|
348 |
+
*/
|
349 |
+
protected function get_memory_limit() {
|
350 |
+
return intval($this->getServerMemoryLimit()) * 1024 * 1024;
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Time exceeded
|
355 |
+
*
|
356 |
+
* Ensures the worker never exceeds a sensible time limit (50s by default).
|
357 |
+
* A timeout limit of 30s is common on shared hosting.
|
358 |
+
*
|
359 |
+
* @return bool
|
360 |
+
*/
|
361 |
+
protected function time_exceeded() {
|
362 |
+
return time() >= $this->start_time + apply_filters( 'cli_worker_default_time_limit', ($this->getServerMaxExecutionTime() - 10));
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* @return int
|
367 |
+
*/
|
368 |
+
protected function getServerMaxExecutionTime()
|
369 |
+
{
|
370 |
+
$time_limit = (int) function_exists( 'ini_get' ) ? ini_get( 'max_execution_time' ) : 30;
|
371 |
+
if (!$time_limit || -1 == $time_limit) {
|
372 |
+
$time_limit = 1800;
|
373 |
+
}
|
374 |
+
return $time_limit;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* @return string
|
379 |
+
*/
|
380 |
+
protected function getServerMemoryLimit()
|
381 |
+
{
|
382 |
+
$memory_limit = function_exists( 'ini_get' ) ? ini_get( 'memory_limit' ) : '128M';
|
383 |
+
if (!$memory_limit || -1 == $memory_limit) {
|
384 |
+
$memory_limit = '32000M';
|
385 |
+
}
|
386 |
+
return (int) preg_replace_callback('/(\-?\d+)(.?)/', function ($m) {
|
387 |
+
return $m[1] * pow(1024, strpos('BKMG', $m[2]));
|
388 |
+
}, strtoupper($memory_limit));
|
389 |
+
}
|
390 |
}
|
391 |
|
includes/vendor/queue/classes/worker/wp-http-worker.php
CHANGED
@@ -28,6 +28,7 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
|
|
28 |
// Cron health check
|
29 |
add_action( 'http_worker_cron', array( $this, 'handle_cron' ) );
|
30 |
add_filter( 'cron_schedules', array( $this, 'schedule_cron' ) );
|
|
|
31 |
$this->maybe_schedule_cron();
|
32 |
|
33 |
// Dispatch handlers
|
@@ -36,6 +37,10 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
|
|
36 |
|
37 |
// Dispatch listener
|
38 |
add_action( 'wp_queue_job_pushed', array( $this, 'maybe_dispatch_worker' ) );
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
|
41 |
/**
|
@@ -47,35 +52,62 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
|
|
47 |
* jobs remain in the queue and server limits reached.
|
48 |
*/
|
49 |
public function maybe_handle() {
|
|
|
50 |
check_ajax_referer( 'http_worker', 'nonce' );
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
wp_die();
|
55 |
-
}
|
56 |
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
if ( $this->should_run() ) {
|
63 |
-
$this->process_next_job();
|
64 |
-
} else {
|
65 |
-
break;
|
66 |
-
}
|
67 |
-
}
|
68 |
|
69 |
-
|
70 |
-
$this->unlock_worker();
|
71 |
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
/**
|
81 |
* Memory exceeded
|
@@ -115,7 +147,9 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
|
|
115 |
$memory_limit = '32000M';
|
116 |
}
|
117 |
|
118 |
-
|
|
|
|
|
119 |
}
|
120 |
|
121 |
/**
|
@@ -257,6 +291,7 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
|
|
257 |
* @return bool
|
258 |
*/
|
259 |
public function handle_cron() {
|
|
|
260 |
if ($this->is_worker_running()) {
|
261 |
wp_die();
|
262 |
}
|
28 |
// Cron health check
|
29 |
add_action( 'http_worker_cron', array( $this, 'handle_cron' ) );
|
30 |
add_filter( 'cron_schedules', array( $this, 'schedule_cron' ) );
|
31 |
+
|
32 |
$this->maybe_schedule_cron();
|
33 |
|
34 |
// Dispatch handlers
|
37 |
|
38 |
// Dispatch listener
|
39 |
add_action( 'wp_queue_job_pushed', array( $this, 'maybe_dispatch_worker' ) );
|
40 |
+
|
41 |
+
if (isset($_REQUEST['action']) && $_REQUEST['action'] === 'http_worker' && check_ajax_referer( 'http_worker', 'nonce', false)) {
|
42 |
+
add_action('init', array($this, 'handle'));
|
43 |
+
}
|
44 |
}
|
45 |
|
46 |
/**
|
52 |
* jobs remain in the queue and server limits reached.
|
53 |
*/
|
54 |
public function maybe_handle() {
|
55 |
+
|
56 |
check_ajax_referer( 'http_worker', 'nonce' );
|
57 |
|
58 |
+
$this->handle();
|
59 |
+
}
|
|
|
|
|
60 |
|
61 |
+
/**
|
62 |
+
*
|
63 |
+
*/
|
64 |
+
public function handle()
|
65 |
+
{
|
66 |
+
if ( $this->is_worker_running() ) {
|
67 |
+
// Worker already running, die
|
68 |
+
wp_die();
|
69 |
+
}
|
70 |
|
71 |
+
// Lock worker to prevent multiple instances spawning
|
72 |
+
$this->lock_worker();
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
+
$processed_something = false;
|
|
|
75 |
|
76 |
+
// Loop over jobs while within server limits
|
77 |
+
while ( ! $this->time_exceeded() && ! $this->memory_exceeded() ) {
|
78 |
+
if ( $this->should_run() ) {
|
79 |
+
$this->process_next_job();
|
80 |
+
$processed_something = true;
|
81 |
+
} else {
|
82 |
+
break;
|
83 |
+
}
|
84 |
+
}
|
85 |
|
86 |
+
// Unlock worker to allow another instance to be spawned
|
87 |
+
$this->unlock_worker();
|
88 |
+
|
89 |
+
$available_jobs = $this->queue->available_jobs();
|
90 |
+
|
91 |
+
if (!$processed_something && $available_jobs) {
|
92 |
+
mailchimp_debug('queue_tracer', "HTTPWorker@handle", array(
|
93 |
+
'jobs' => $available_jobs,
|
94 |
+
'time_exceeded' => $this->time_exceeded(),
|
95 |
+
'memory_exceeded' => $this->memory_exceeded(),
|
96 |
+
'memory_limit' => $this->get_memory_limit(),
|
97 |
+
'memory_usage' => memory_get_usage(true),
|
98 |
+
'ini_memory' => ini_get('memory_limit'),
|
99 |
+
'php_version' => phpversion(),
|
100 |
+
));
|
101 |
+
wp_die();
|
102 |
+
}
|
103 |
+
|
104 |
+
if ($available_jobs) {
|
105 |
+
// Job queue not empty, dispatch async worker request
|
106 |
+
$this->dispatch();
|
107 |
+
}
|
108 |
+
|
109 |
+
wp_die();
|
110 |
+
}
|
111 |
|
112 |
/**
|
113 |
* Memory exceeded
|
147 |
$memory_limit = '32000M';
|
148 |
}
|
149 |
|
150 |
+
return (int) preg_replace_callback('/(\-?\d+)(.?)/', function ($m) {
|
151 |
+
return $m[1] * pow(1024, strpos('BKMG', $m[2]));
|
152 |
+
}, strtoupper($memory_limit));
|
153 |
}
|
154 |
|
155 |
/**
|
291 |
* @return bool
|
292 |
*/
|
293 |
public function handle_cron() {
|
294 |
+
|
295 |
if ($this->is_worker_running()) {
|
296 |
wp_die();
|
297 |
}
|
includes/vendor/queue/classes/worker/wp-worker.php
CHANGED
@@ -44,7 +44,7 @@ if ( ! class_exists( 'WP_Worker' ) ) {
|
|
44 |
$job = $this->queue->get_next_job();
|
45 |
|
46 |
if (empty($job)) {
|
47 |
-
return
|
48 |
}
|
49 |
|
50 |
$this->payload = unserialize( $job->job );
|
@@ -53,20 +53,19 @@ if ( ! class_exists( 'WP_Worker' ) ) {
|
|
53 |
$this->payload->set_job( $job );
|
54 |
|
55 |
try {
|
56 |
-
//mailchimp_debug('mc_events', 'wp_worker.process_next_job.start', array('payload' => $this->payload));
|
57 |
$this->payload->handle();
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
if ( $this->payload->is_released() ) {
|
61 |
// Job manually released, release back onto queue
|
62 |
$this->queue->release( $job, $this->payload->get_delay() );
|
63 |
}
|
64 |
|
65 |
-
if ( $this->payload->is_deleted() ) {
|
66 |
-
// Job manually deleted, delete from queue
|
67 |
-
$this->queue->delete( $job );
|
68 |
-
}
|
69 |
-
|
70 |
if ( ! $this->payload->is_deleted_or_released() ) {
|
71 |
// Job completed, delete from queue
|
72 |
$this->queue->delete( $job );
|
44 |
$job = $this->queue->get_next_job();
|
45 |
|
46 |
if (empty($job)) {
|
47 |
+
return false;
|
48 |
}
|
49 |
|
50 |
$this->payload = unserialize( $job->job );
|
53 |
$this->payload->set_job( $job );
|
54 |
|
55 |
try {
|
|
|
56 |
$this->payload->handle();
|
57 |
+
|
58 |
+
if ( $this->payload->is_deleted() ) {
|
59 |
+
// Job manually deleted, delete from queue
|
60 |
+
$this->queue->delete( $job );
|
61 |
+
return true;
|
62 |
+
}
|
63 |
|
64 |
if ( $this->payload->is_released() ) {
|
65 |
// Job manually released, release back onto queue
|
66 |
$this->queue->release( $job, $this->payload->get_delay() );
|
67 |
}
|
68 |
|
|
|
|
|
|
|
|
|
|
|
69 |
if ( ! $this->payload->is_deleted_or_released() ) {
|
70 |
// Job completed, delete from queue
|
71 |
$this->queue->delete( $job );
|
includes/vendor/queue/classes/wp-queue.php
CHANGED
@@ -107,12 +107,7 @@ if ( ! class_exists( 'WP_Queue' ) ) {
|
|
107 |
*/
|
108 |
public function delete( $job ) {
|
109 |
global $wpdb;
|
110 |
-
|
111 |
-
$where = array(
|
112 |
-
'id' => $job->id,
|
113 |
-
);
|
114 |
-
|
115 |
-
$wpdb->delete( $this->table, $where );
|
116 |
}
|
117 |
|
118 |
/**
|
107 |
*/
|
108 |
public function delete( $job ) {
|
109 |
global $wpdb;
|
110 |
+
$wpdb->delete($this->table, array('id' => $job->id));
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
112 |
|
113 |
/**
|
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: MailChimp - WooCommerce plugin
|
19 |
-
* Version: 2.1.
|
20 |
* Author: MailChimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|
@@ -43,7 +43,7 @@ function mailchimp_environment_variables() {
|
|
43 |
return (object) array(
|
44 |
'repo' => 'master',
|
45 |
'environment' => 'production',
|
46 |
-
'version' => '2.1.
|
47 |
'php_version' => phpversion(),
|
48 |
'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
|
49 |
'wc_version' => class_exists('WC') ? WC()->version : null,
|
@@ -51,16 +51,32 @@ function mailchimp_environment_variables() {
|
|
51 |
);
|
52 |
}
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
/**
|
55 |
* @return bool|int
|
56 |
*/
|
57 |
function mailchimp_get_list_id() {
|
58 |
-
|
59 |
-
if (isset($options['mailchimp_list'])) {
|
60 |
-
return $options['mailchimp_list'];
|
61 |
-
}
|
62 |
-
}
|
63 |
-
return false;
|
64 |
}
|
65 |
|
66 |
/**
|
@@ -74,14 +90,13 @@ function mailchimp_get_store_id() {
|
|
74 |
return $store_id;
|
75 |
}
|
76 |
|
|
|
77 |
/**
|
78 |
* @return bool|MailChimp_WooCommerce_MailChimpApi
|
79 |
*/
|
80 |
function mailchimp_get_api() {
|
81 |
-
if (($
|
82 |
-
|
83 |
-
return new MailChimp_WooCommerce_MailChimpApi($options['mailchimp_api_key']);
|
84 |
-
}
|
85 |
}
|
86 |
return false;
|
87 |
}
|
@@ -390,6 +405,16 @@ function mailchimp_update_connected_site_script() {
|
|
390 |
return false;
|
391 |
}
|
392 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
/**
|
394 |
* @return string|false
|
395 |
*/
|
16 |
* Plugin Name: MailChimp for WooCommerce
|
17 |
* Plugin URI: https://mailchimp.com/connect-your-store/
|
18 |
* Description: MailChimp - WooCommerce plugin
|
19 |
+
* Version: 2.1.5
|
20 |
* Author: MailChimp
|
21 |
* Author URI: https://mailchimp.com
|
22 |
* License: GPL-2.0+
|
43 |
return (object) array(
|
44 |
'repo' => 'master',
|
45 |
'environment' => 'production',
|
46 |
+
'version' => '2.1.5',
|
47 |
'php_version' => phpversion(),
|
48 |
'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
|
49 |
'wc_version' => class_exists('WC') ? WC()->version : null,
|
51 |
);
|
52 |
}
|
53 |
|
54 |
+
/**
|
55 |
+
* @return bool
|
56 |
+
*/
|
57 |
+
function mailchimp_should_init_queue() {
|
58 |
+
return mailchimp_detect_admin_ajax() && mailchimp_is_configured() && !mailchimp_running_in_console() && !mailchimp_http_worker_is_running();
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
function mailchimp_is_configured() {
|
65 |
+
return (bool) (mailchimp_get_api_key() && mailchimp_get_list_id());
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @return bool|int
|
70 |
+
*/
|
71 |
+
function mailchimp_get_api_key() {
|
72 |
+
return mailchimp_get_option('mailchimp_api_key', false);
|
73 |
+
}
|
74 |
+
|
75 |
/**
|
76 |
* @return bool|int
|
77 |
*/
|
78 |
function mailchimp_get_list_id() {
|
79 |
+
return mailchimp_get_option('mailchimp_list', false);
|
|
|
|
|
|
|
|
|
|
|
80 |
}
|
81 |
|
82 |
/**
|
90 |
return $store_id;
|
91 |
}
|
92 |
|
93 |
+
|
94 |
/**
|
95 |
* @return bool|MailChimp_WooCommerce_MailChimpApi
|
96 |
*/
|
97 |
function mailchimp_get_api() {
|
98 |
+
if (($key = mailchimp_get_api_key())) {
|
99 |
+
return new MailChimp_WooCommerce_MailChimpApi($key);
|
|
|
|
|
100 |
}
|
101 |
return false;
|
102 |
}
|
405 |
return false;
|
406 |
}
|
407 |
|
408 |
+
/**
|
409 |
+
* @return bool
|
410 |
+
*/
|
411 |
+
function mailchimp_detect_admin_ajax() {
|
412 |
+
if (defined('DOING_CRON') && DOING_CRON) return true;
|
413 |
+
if (!is_admin()) return false;
|
414 |
+
if (!defined('DOING_AJAX')) return false;
|
415 |
+
return DOING_AJAX;
|
416 |
+
}
|
417 |
+
|
418 |
/**
|
419 |
* @return string|false
|
420 |
*/
|