MailChimp for WooCommerce - Version 2.1.13

Version Description

  • fixed spelling issues in plugin meta
  • changed submission sequence for products to use the PATCH endpoint when applicable
  • fallback on order submissions when products are not found in Mailchimp.
Download this release

Release Info

Developer ryanhungate
Plugin Icon wp plugin MailChimp for WooCommerce
Version 2.1.13
Comparing to
See all releases

Code changes from version 2.1.12 to 2.1.13

README.txt CHANGED
@@ -3,10 +3,10 @@ Contributors: ryanhungate, Mailchimp
3
  Tags: ecommerce,email,workflows,mailchimp
4
  Donate link: https://mailchimp.com
5
  Requires at least: 4.3
6
- Tested up to: 5.0
7
- Stable tag: 2.1.12
8
  Requires PHP: 7.0
9
- WC tested up to: 3.5.2
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  Connect your store to your Mailchimp list to track sales, create targeted emails, send abandoned cart emails, and more.
@@ -54,6 +54,7 @@ You have 2 options to run this process:
54
  ### Optional on-demand queue processing
55
  If you would like to turn off the background queue processing and handle jobs "on-demand" you can do so by adding a constant in your wp-config.php file:
56
  `define('MAILCHIMP_DISABLE_QUEUE', true);`
 
57
  ### Multi-site Setups
58
  The Mailchimp for WooCommerce supports Wordpress Multi Sites and below are a few things to note.
59
  - Each site that has the plugin installed is a separate connection to Mailchimp.
@@ -61,9 +62,13 @@ The Mailchimp for WooCommerce supports Wordpress Multi Sites and below are a few
61
  - Deleting removes the connection between Mailchimp and WooCommerce, and uninstalls the plugin from your site.
62
  Refer to the Wordpress Codex for more information about [Multisite Network Administration](https://codex.wordpress.org/Multisite_Network_Administration)
63
  == Changelog ==
 
 
 
 
64
  = 2.1.12 =
65
  * adds error handling for blocked admin-ajax.php files
66
- * adds support for customer merge variables
67
  * removes global variable overwrite of REMOTE_ADDR
68
  * fixes signup form not adding customers to Mailchimp
69
  * support for rate limiting
3
  Tags: ecommerce,email,workflows,mailchimp
4
  Donate link: https://mailchimp.com
5
  Requires at least: 4.3
6
+ Tested up to: 5.0.3
7
+ Stable tag: 2.1.13
8
  Requires PHP: 7.0
9
+ WC tested up to: 3.5.4
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  Connect your store to your Mailchimp list to track sales, create targeted emails, send abandoned cart emails, and more.
54
  ### Optional on-demand queue processing
55
  If you would like to turn off the background queue processing and handle jobs "on-demand" you can do so by adding a constant in your wp-config.php file:
56
  `define('MAILCHIMP_DISABLE_QUEUE', true);`
57
+ This is helpful with high CPU usage on small servers by making a call to the admin-ajax file and manually processing a single request at a time.
58
  ### Multi-site Setups
59
  The Mailchimp for WooCommerce supports Wordpress Multi Sites and below are a few things to note.
60
  - Each site that has the plugin installed is a separate connection to Mailchimp.
62
  - Deleting removes the connection between Mailchimp and WooCommerce, and uninstalls the plugin from your site.
63
  Refer to the Wordpress Codex for more information about [Multisite Network Administration](https://codex.wordpress.org/Multisite_Network_Administration)
64
  == Changelog ==
65
+ = 2.1.13 =
66
+ * fixed spelling issues in plugin meta
67
+ * changed submission sequence for products to use the PATCH endpoint when applicable
68
+ * fallback on order submissions when products are not found in Mailchimp.
69
  = 2.1.12 =
70
  * adds error handling for blocked admin-ajax.php files
71
+ * adds support for custom merge variables
72
  * removes global variable overwrite of REMOTE_ADDR
73
  * fixes signup form not adding customers to Mailchimp
74
  * support for rate limiting
bootstrap.php CHANGED
@@ -88,7 +88,7 @@ function mailchimp_environment_variables() {
88
  return (object) array(
89
  'repo' => 'master',
90
  'environment' => 'production',
91
- 'version' => '2.1.12',
92
  'php_version' => phpversion(),
93
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
94
  'wc_version' => class_exists('WC') ? WC()->version : null,
@@ -196,7 +196,11 @@ function mailchimp_get_http_lock_expiration($max = 300) {
196
  if (empty($lock_duration) || !is_numeric($lock_duration) || ($lock_duration >= $max)) {
197
  $lock_duration = $max;
198
  }
199
- return new \DateTime(((int) $parts[1] + $lock_duration));
 
 
 
 
200
  }
201
  }
202
  } catch (\Exception $e) {}
@@ -540,7 +544,7 @@ function mailchimp_error($action, $message, $data = array()) {
540
  * @return string
541
  */
542
  function mailchimp_error_trace(\Exception $e, $wrap = "") {
543
- $error = "{$e->getMessage()} on {$e->getLine()} in {$e->getFile()}";
544
  if (empty($wrap)) return $error;
545
  return "{$wrap} :: {$error}";
546
  }
88
  return (object) array(
89
  'repo' => 'master',
90
  'environment' => 'production',
91
+ 'version' => '2.1.13',
92
  'php_version' => phpversion(),
93
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
94
  'wc_version' => class_exists('WC') ? WC()->version : null,
196
  if (empty($lock_duration) || !is_numeric($lock_duration) || ($lock_duration >= $max)) {
197
  $lock_duration = $max;
198
  }
199
+ // craft a new date time object
200
+ $date = new \DateTime();
201
+ // set the timestamp with the lock duration
202
+ $date->setTimestamp(((int) $parts[1] + $lock_duration));
203
+ return $date;
204
  }
205
  }
206
  } catch (\Exception $e) {}
544
  * @return string
545
  */
546
  function mailchimp_error_trace(\Exception $e, $wrap = "") {
547
+ $error = "Error Code {$e->getCode()} :: {$e->getMessage()} on {$e->getLine()} in {$e->getFile()}";
548
  if (empty($wrap)) return $error;
549
  return "{$wrap} :: {$error}";
550
  }
includes/api/class-mailchimp-api.php CHANGED
@@ -989,6 +989,47 @@ class MailChimp_WooCommerce_MailChimpApi
989
  }
990
  }
991
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
  /**
993
  * @param $store_id
994
  * @param $product_id
@@ -1436,7 +1477,7 @@ class MailChimp_WooCommerce_MailChimpApi
1436
  {
1437
  $env = mailchimp_environment_variables();
1438
 
1439
- return array(
1440
  CURLOPT_USERPWD => "mailchimp:{$this->api_key}",
1441
  CURLOPT_CUSTOMREQUEST => strtoupper($method),
1442
  CURLOPT_URL => $this->url($url, $params),
@@ -1451,6 +1492,13 @@ class MailChimp_WooCommerce_MailChimpApi
1451
  "user-agent: MailChimp for WooCommerce/{$env->version}; PHP/{$env->php_version}; WordPress/{$env->wp_version}; Woo/{$env->wc_version};",
1452
  ), $headers)
1453
  );
 
 
 
 
 
 
 
1454
  }
1455
 
1456
  /**
989
  }
990
  }
991
 
992
+ /**
993
+ * @param $store_id
994
+ * @param MailChimp_WooCommerce_Product $product
995
+ * @param bool $silent
996
+ * @return bool|MailChimp_WooCommerce_Product
997
+ * @throws Exception
998
+ */
999
+ public function updateStoreProduct($store_id, MailChimp_WooCommerce_Product $product, $silent = true)
1000
+ {
1001
+ try {
1002
+ if (!$this->validateStoreSubmission($product)) {
1003
+ return false;
1004
+ }
1005
+ $data = $this->patch("ecommerce/stores/$store_id/products/{$product->getId()}", $product->toArray());
1006
+ update_option('mailchimp-woocommerce-resource-last-updated', time());
1007
+ $product = new MailChimp_WooCommerce_Product();
1008
+ return $product->fromArray($data);
1009
+ } catch (\Exception $e) {
1010
+ if (!$silent) throw $e;
1011
+ mailchimp_log('api.update_product.error', $e->getMessage(), array('submission' => $product->toArray()));
1012
+ return false;
1013
+ }
1014
+ }
1015
+
1016
+ /**
1017
+ * @param MailChimp_WooCommerce_Order $order
1018
+ * @return array
1019
+ */
1020
+ public function handleProductsMissingFromAPI(MailChimp_WooCommerce_Order $order)
1021
+ {
1022
+ $missing_products = array();
1023
+ foreach ($order->items() as $order_item) {
1024
+ /** @var \MailChimp_WooCommerce_LineItem $order_item */
1025
+ $job = new MailChimp_WooCommerce_Single_Product($order_item->getId());
1026
+ if ($missing_products[$order_item->getId()] = $job->createModeOnly()->handle()) {
1027
+ mailchimp_log("missing_products.fallback", "Product {$order_item->getId()} had to be re-pushed into Mailchimp");
1028
+ }
1029
+ }
1030
+ return $missing_products;
1031
+ }
1032
+
1033
  /**
1034
  * @param $store_id
1035
  * @param $product_id
1477
  {
1478
  $env = mailchimp_environment_variables();
1479
 
1480
+ $curl_options = array(
1481
  CURLOPT_USERPWD => "mailchimp:{$this->api_key}",
1482
  CURLOPT_CUSTOMREQUEST => strtoupper($method),
1483
  CURLOPT_URL => $this->url($url, $params),
1492
  "user-agent: MailChimp for WooCommerce/{$env->version}; PHP/{$env->php_version}; WordPress/{$env->wp_version}; Woo/{$env->wc_version};",
1493
  ), $headers)
1494
  );
1495
+
1496
+ // if we have a dedicated IP address, and have set a configuration for it, we'll use it here.
1497
+ if (defined('MAILCHIMP_USE_OUTBOUND_IP')) {
1498
+ $curl_options[CURLOPT_INTERFACE] = MAILCHIMP_USE_OUTBOUND_IP;
1499
+ }
1500
+
1501
+ return $curl_options;
1502
  }
1503
 
1504
  /**
includes/processes/class-mailchimp-woocommerce-process-orders.php CHANGED
@@ -65,8 +65,21 @@ class MailChimp_WooCommerce_Process_Orders extends MailChimp_WooCommerce_Abstrac
65
  return false;
66
  }
67
 
68
- // make the call
69
- $response = $this->mailchimp()->$call($this->store_id, $item, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  if (empty($response)) {
72
  mailchimp_error('order_submit.failure', "$call :: #{$item->getId()} :: email: {$item->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
65
  return false;
66
  }
67
 
68
+ try {
69
+ // make the call
70
+ $response = $this->mailchimp()->$call($this->store_id, $item, false);
71
+ } catch (\Exception $e) {
72
+ // if for whatever reason we get a product not found error, we need to iterate
73
+ // through the order items, and use a "create mode only" on each product
74
+ // then re-submit the order once they're in the database again.
75
+ if (mailchimp_string_contains($e->getMessage(), 'product with the provided ID')) {
76
+ $this->mailchimp()->handleProductsMissingFromAPI($item);
77
+ // make the call again after the product updates
78
+ $response = $this->mailchimp()->$call($this->store_id, $item, false);
79
+ } else {
80
+ throw $e;
81
+ }
82
+ }
83
 
84
  if (empty($response)) {
85
  mailchimp_error('order_submit.failure', "$call :: #{$item->getId()} :: email: {$item->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
includes/processes/class-mailchimp-woocommerce-process-products.php CHANGED
@@ -43,24 +43,28 @@ class MailChimp_WooCommerce_Process_Products extends MailChimp_WooCommerce_Abstr
43
 
44
  mailchimp_debug('product_sync', "#{$item->getId()}", $item->toArray());
45
 
46
- // need to run the delete option on this before submitting because the API does not support PATCH yet.
47
- $this->mailchimp()->deleteStoreProduct($this->store_id, $item->getId());
48
-
49
- // add the product.
50
  try {
51
- // make the call
52
- $response = $this->mailchimp()->addStoreProduct($this->store_id, $item, false);
 
 
 
53
 
54
- mailchimp_log('product_sync.success', "addStoreProduct :: #{$response->getId()}");
 
55
 
 
 
 
 
 
56
  return $response;
57
-
58
  } catch (MailChimp_WooCommerce_ServerError $e) {
59
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "addStoreProduct :: {$item->getId()}"));
60
  } catch (MailChimp_WooCommerce_Error $e) {
61
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "addStoreProduct :: {$item->getId()}"));
62
  } catch (Exception $e) {
63
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "addStoreProduct :: {$item->getId()}"));
64
  }
65
  }
66
 
43
 
44
  mailchimp_debug('product_sync', "#{$item->getId()}", $item->toArray());
45
 
 
 
 
 
46
  try {
47
+ // pull the product from Mailchimp first to see what method we need to call next.
48
+ $mailchimp_product = $this->mailchimp()->getStoreProduct($this->store_id, $item->getId());
49
+ } catch (\Exception $e) {
50
+ $mailchimp_product = false;
51
+ }
52
 
53
+ // depending on if it's existing or not - we change the method call
54
+ $method = $mailchimp_product ? 'updateStoreProduct' : 'addStoreProduct';
55
 
56
+ // need to run the delete option on this before submitting because the API does not support PATCH yet.
57
+ try {
58
+ // make the call
59
+ $response = $this->mailchimp()->{$method}($this->store_id, $item, false);
60
+ mailchimp_log('product_sync.success', "{$method} :: #{$response->getId()}");
61
  return $response;
 
62
  } catch (MailChimp_WooCommerce_ServerError $e) {
63
+ mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
64
  } catch (MailChimp_WooCommerce_Error $e) {
65
+ mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
66
  } catch (Exception $e) {
67
+ mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
68
  }
69
  }
70
 
includes/processes/class-mailchimp-woocommerce-single-order.php CHANGED
@@ -151,8 +151,21 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
151
  }
152
  }
153
 
154
- // update or create
155
- $api_response = $api->$call($store_id, $order, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  if (empty($api_response)) {
158
  mailchimp_error('order_submit.failure', "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
151
  }
152
  }
153
 
154
+ try {
155
+ // update or create
156
+ $api_response = $api->$call($store_id, $order, false);
157
+ } catch (\Exception $e) {
158
+ // if for whatever reason we get a product not found error, we need to iterate
159
+ // through the order items, and use a "create mode only" on each product
160
+ // then re-submit the order once they're in the database again.
161
+ if (mailchimp_string_contains($e->getMessage(), 'product with the provided ID')) {
162
+ $api->handleProductsMissingFromAPI($order);
163
+ // make another attempt again to add the order.
164
+ $api_response = $api->$call($store_id, $order, false);
165
+ } else {
166
+ throw $e;
167
+ }
168
+ }
169
 
170
  if (empty($api_response)) {
171
  mailchimp_error('order_submit.failure', "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
includes/processes/class-mailchimp-woocommerce-single-product.php CHANGED
@@ -14,6 +14,7 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
14
  protected $store_id;
15
  protected $api;
16
  protected $service;
 
17
 
18
  /**
19
  * MailChimp_WooCommerce_Single_Order constructor.
@@ -26,6 +27,35 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
26
  }
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  /**
30
  * @return bool
31
  */
@@ -50,9 +80,7 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
50
  return false;
51
  }
52
 
53
- if ($this->api()->getStoreProduct($this->store_id, $this->product_id)) {
54
- $this->api()->deleteStoreProduct($this->store_id, $this->product_id);
55
- }
56
 
57
  try {
58
 
@@ -60,13 +88,30 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
60
  return false;
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  $product = $this->transformer()->transform($product_post);
64
 
65
  mailchimp_debug('product_submit.debug', "#{$this->product_id}", $product->toArray());
66
 
67
- $this->api()->addStoreProduct($this->store_id, $product, false);
 
68
 
69
- mailchimp_log('product_submit.success', "addStoreProduct :: #{$product->getId()}");
70
 
71
  update_option('mailchimp-woocommerce-last_product_updated', $product->getId());
72
 
@@ -77,11 +122,11 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
77
  $this->release();
78
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "RateLimited :: #{$this->product_id}"));
79
  } catch (MailChimp_WooCommerce_ServerError $e) {
80
- mailchimp_error('product_submit.error', mailchimp_error_trace($e, "addStoreProduct :: #{$this->product_id}"));
81
  } catch (MailChimp_WooCommerce_Error $e) {
82
- mailchimp_log('product_submit.error', mailchimp_error_trace($e, "addStoreProduct :: #{$this->product_id}"));
83
  } catch (Exception $e) {
84
- mailchimp_log('product_submit.error', mailchimp_error_trace($e, "addStoreProduct :: #{$this->product_id}"));
85
  }
86
 
87
  return false;
14
  protected $store_id;
15
  protected $api;
16
  protected $service;
17
+ protected $mode = 'update_or_create';
18
 
19
  /**
20
  * MailChimp_WooCommerce_Single_Order constructor.
27
  }
28
  }
29
 
30
+ /**
31
+ * @return $this
32
+ */
33
+ public function createModeOnly()
34
+ {
35
+ $this->mode = 'create';
36
+ return $this;
37
+ }
38
+
39
+ /**
40
+ * @return $this
41
+ */
42
+ public function updateModeOnly()
43
+ {
44
+ $this->mode = 'update';
45
+
46
+ return $this;
47
+ }
48
+
49
+ /**
50
+ * @return $this
51
+ */
52
+ public function updateOrCreateMode()
53
+ {
54
+ $this->mode = 'update_or_create';
55
+
56
+ return $this;
57
+ }
58
+
59
  /**
60
  * @return bool
61
  */
80
  return false;
81
  }
82
 
83
+ $method = "no action";
 
 
84
 
85
  try {
86
 
88
  return false;
89
  }
90
 
91
+ // pull the product from Mailchimp first to see what method we need to call next.
92
+ $mailchimp_product = $this->api()->getStoreProduct($this->store_id, $this->product_id);
93
+
94
+ // depending on if it's existing or not - we change the method call
95
+ $method = $mailchimp_product ? 'updateStoreProduct' : 'addStoreProduct';
96
+
97
+ // if the mode set is "create" and the product is in Mailchimp - just return the product.
98
+ if ($this->mode === 'create' && !empty($mailchimp_product)) {
99
+ return $mailchimp_product;
100
+ }
101
+
102
+ // if the mode is set to "update" and the product is not currently in Mailchimp - skip it.
103
+ if ($this->mode === 'update' && empty($mailchimp_product)) {
104
+ return false;
105
+ }
106
+
107
  $product = $this->transformer()->transform($product_post);
108
 
109
  mailchimp_debug('product_submit.debug', "#{$this->product_id}", $product->toArray());
110
 
111
+ // either updating or creating the product
112
+ $this->api()->{$method}($this->store_id, $product, false);
113
 
114
+ mailchimp_log('product_submit.success', "{$method} :: #{$product->getId()}");
115
 
116
  update_option('mailchimp-woocommerce-last_product_updated', $product->getId());
117
 
122
  $this->release();
123
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "RateLimited :: #{$this->product_id}"));
124
  } catch (MailChimp_WooCommerce_ServerError $e) {
125
+ mailchimp_error('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->product_id}"));
126
  } catch (MailChimp_WooCommerce_Error $e) {
127
+ mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->product_id}"));
128
  } catch (Exception $e) {
129
+ mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->product_id}"));
130
  }
131
 
132
  return false;
includes/processes/class-mailchimp-woocommerce-user-submit.php CHANGED
@@ -124,21 +124,21 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
124
 
125
  $api = new MailChimp_WooCommerce_MailChimpApi($api_key);
126
 
127
- $merge_vars = array();
128
 
129
  $fn = trim($user->first_name);
130
  $ln = trim($user->last_name);
131
 
132
- if (!empty($fn)) $merge_vars['FNAME'] = $fn;
133
- if (!empty($ln)) $merge_vars['LNAME'] = $ln;
134
 
135
  // allow users to hook into the merge tag submission
136
- $merge_vars = apply_filters('mailchimp_sync_user_mergetags', $user, $merge_vars);
137
 
138
  // for whatever reason if this isn't an array we need to skip it.
139
  if (!is_array($merge_vars)) {
140
- mailchimp_error("custom.merge_tags", "the filter for mailchimp_sync_user_mergetags needs to return an array.");
141
- return false;
142
  }
143
 
144
  // pull the transient key for this job.
124
 
125
  $api = new MailChimp_WooCommerce_MailChimpApi($api_key);
126
 
127
+ $merge_vars_system = array();
128
 
129
  $fn = trim($user->first_name);
130
  $ln = trim($user->last_name);
131
 
132
+ if (!empty($fn)) $merge_vars_system['FNAME'] = $fn;
133
+ if (!empty($ln)) $merge_vars_system['LNAME'] = $ln;
134
 
135
  // allow users to hook into the merge tag submission
136
+ $merge_vars = apply_filters('mailchimp_sync_user_mergetags', $user, $merge_vars_system);
137
 
138
  // for whatever reason if this isn't an array we need to skip it.
139
  if (!is_array($merge_vars)) {
140
+ mailchimp_error("custom.merge_tags", "the filter for mailchimp_sync_user_mergetags needs to return an array, we're using the default setup instead.");
141
+ $merge_vars = $merge_vars_system;
142
  }
143
 
144
  // pull the transient key for this job.
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.12
20
  * Author: Mailchimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
@@ -24,7 +24,7 @@
24
  * Text Domain: mailchimp-woocommerce
25
  * Domain Path: /languages
26
  * Requires at least: 4.4
27
- * Tested up to: 4.9.6
28
  */
29
 
30
  // If this file is called directly, abort.
16
  * Plugin Name: Mailchimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
  * Description: Mailchimp - WooCommerce plugin
19
+ * Version: 2.1.13
20
  * Author: Mailchimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
24
  * Text Domain: mailchimp-woocommerce
25
  * Domain Path: /languages
26
  * Requires at least: 4.4
27
+ * Tested up to: 5.0.3
28
  */
29
 
30
  // If this file is called directly, abort.