MailChimp for WooCommerce - Version 2.0.0

Version Description

Download this release

Release Info

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

Code changes from version 1.1.1 to 2.0.0

README.txt CHANGED
@@ -49,6 +49,13 @@ You’ll need to do a few things to connect your WooCommerce store to MailChimp.
49
  For more information on settings and configuration, please visit our Knowledge Base: [http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce](http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce)
50
 
51
  == Changelog ==
 
 
 
 
 
 
 
52
  = 1.1.1 =
53
  * Support for site url changes
54
  * Fix for WP Version 4.4 compatibility issues
49
  For more information on settings and configuration, please visit our Knowledge Base: [http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce](http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce)
50
 
51
  == Changelog ==
52
+ = 2.0 =
53
+ * Support WooComerce 3.0
54
+ * Support for manually uploaded WooCommerce
55
+ * Fix for sync issues
56
+ * Fix for guest orders sync issue
57
+ * Remove MailChimp debug logger
58
+
59
  = 1.1.1 =
60
  * Support for site url changes
61
  * Fix for WP Version 4.4 compatibility issues
admin/class-mailchimp-woocommerce-admin.php CHANGED
@@ -245,6 +245,7 @@ class MailChimp_Woocommerce_Admin extends MailChimp_Woocommerce_Options {
245
  case 'sync':
246
  $this->startSync();
247
  $this->showSyncStartedMessage();
 
248
  break;
249
  }
250
 
@@ -765,7 +766,7 @@ class MailChimp_Woocommerce_Admin extends MailChimp_Woocommerce_Options {
765
  {
766
  $job = new MailChimp_WooCommerce_Process_Products();
767
  $job->flagStartSync();
768
- wp_queue($job);
769
  }
770
 
771
  /**
245
  case 'sync':
246
  $this->startSync();
247
  $this->showSyncStartedMessage();
248
+ $this->setData('sync.config.resync', true);
249
  break;
250
  }
251
 
766
  {
767
  $job = new MailChimp_WooCommerce_Process_Products();
768
  $job->flagStartSync();
769
+ wp_queue($job, 10);
770
  }
771
 
772
  /**
admin/partials/mailchimp-woocommerce-admin-tabs.php CHANGED
@@ -6,7 +6,7 @@ $handler = MailChimp_Woocommerce_Admin::connect();
6
  //Grab all options for this particular tab we're viewing.
7
  $options = get_option($this->plugin_name, array());
8
 
9
- $show_sync_tab = false;
10
  $show_campaign_defaults = true;
11
  $has_valid_api_key = false;
12
  $allow_new_list = true;
6
  //Grab all options for this particular tab we're viewing.
7
  $options = get_option($this->plugin_name, array());
8
 
9
+ $show_sync_tab = isset($_GET['resync']) ? $_GET['resync'] === '1' : false;;
10
  $show_campaign_defaults = true;
11
  $has_valid_api_key = false;
12
  $allow_new_list = true;
admin/partials/tabs/api_key.php CHANGED
@@ -23,25 +23,3 @@ if (isset($options['mailchimp_api_key']) && !$handler->hasValidApiKey()) {
23
  <span><?php esc_attr_e('Enter your MailChimp API key.', $this->plugin_name); ?></span>
24
  </label>
25
  </fieldset>
26
-
27
- <fieldset>
28
- <legend class="screen-reader-text">
29
- <span>Enable Debugging</span>
30
- </legend>
31
- <label for="<?php echo $this->plugin_name; ?>-mailchimp-debugging">
32
- <select name="<?php echo $this->plugin_name; ?>[mailchimp_debugging]" style="width:30%">
33
-
34
- <?php
35
-
36
- $enable_mailchimp_debugging = (array_key_exists('mailchimp_debugging', $options) && !is_null($options['mailchimp_debugging'])) ? $options['mailchimp_debugging'] : '1';
37
-
38
- foreach (array('0' => 'No', '1' => 'Yes') as $key => $value ) {
39
- echo '<option value="' . esc_attr($key) . '" ' . selected($key == $enable_mailchimp_debugging, true, false ) . '>' . esc_html( $value ) . '</option>';
40
- }
41
- ?>
42
-
43
- </select>
44
- <span><?php esc_attr_e('Enable debugging logs to be sent to MailChimp.', $this->plugin_name); ?></span>
45
- </label>
46
- </fieldset>
47
-
23
  <span><?php esc_attr_e('Enter your MailChimp API key.', $this->plugin_name); ?></span>
24
  </label>
25
  </fieldset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/partials/tabs/elements/enable_debugging.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <fieldset>
2
+ <legend class="screen-reader-text">
3
+ <span>Enable Debugging</span>
4
+ </legend>
5
+ <label for="<?php echo $this->plugin_name; ?>-mailchimp-debugging">
6
+ <select name="<?php echo $this->plugin_name; ?>[mailchimp_debugging]" style="width:30%">
7
+
8
+ <?php
9
+
10
+ $enable_mailchimp_debugging = (array_key_exists('mailchimp_debugging', $options) && !is_null($options['mailchimp_debugging'])) ? $options['mailchimp_debugging'] : '1';
11
+
12
+ foreach (array('0' => 'No', '1' => 'Yes') as $key => $value ) {
13
+ echo '<option value="' . esc_attr($key) . '" ' . selected($key == $enable_mailchimp_debugging, true, false ) . '>' . esc_html( $value ) . '</option>';
14
+ }
15
+ ?>
16
+
17
+ </select>
18
+ <span><?php esc_attr_e('Enable debugging logs to be sent to MailChimp.', $this->plugin_name); ?></span>
19
+ </label>
20
+ </fieldset>
changelog.md CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  ** 1.1.1 **
2
  * Support for site url changes
3
  * Fix for WP Version 4.4 Compatibility issues
1
+ ** 2.0 **
2
+ * Support WooComerce 3.0
3
+ * Support for manually uploaded WooCommerce plugin
4
+ * Fix for sync issues
5
+ * Fix for guest orders sync issue
6
+ * Remove MailChimp debug logger
7
+
8
  ** 1.1.1 **
9
  * Support for site url changes
10
  * Fix for WP Version 4.4 Compatibility issues
includes/api/class-mailchimp-woocommerce-api.php CHANGED
@@ -33,7 +33,7 @@ class MailChimp_WooCommerce_Api
33
  }
34
 
35
  if (empty($page)) $page = 1;
36
- if (empty($per)) $per = 10;
37
 
38
  return array($page, $per);
39
  }
@@ -64,7 +64,7 @@ class MailChimp_WooCommerce_Api
64
  * @param int $per
65
  * @return object|stdClass
66
  */
67
- public function paginate($resource, $page = 1, $per = 10)
68
  {
69
  if (($sync = $this->engine($resource))) {
70
  return $sync->compile($page, $per);
33
  }
34
 
35
  if (empty($page)) $page = 1;
36
+ if (empty($per)) $per = 5;
37
 
38
  return array($page, $per);
39
  }
64
  * @param int $per
65
  * @return object|stdClass
66
  */
67
+ public function paginate($resource, $page = 1, $per = 5)
68
  {
69
  if (($sync = $this->engine($resource))) {
70
  return $sync->compile($page, $per);
includes/api/class-mailchimp-woocommerce-transform-orders-wc3.php ADDED
@@ -0,0 +1,362 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Created by Vextras.
5
+ *
6
+ * Name: Ryan Hungate
7
+ * Email: ryan@mailchimp.com
8
+ * Date: 7/13/16
9
+ * Time: 8:29 AM
10
+ */
11
+ class MailChimp_WooCommerce_Transform_Orders
12
+ {
13
+ public $campaign_id = null;
14
+
15
+ /**
16
+ * @param int $page
17
+ * @param int $limit
18
+ * @return \stdClass
19
+ */
20
+ public function compile($page = 1, $limit = 5)
21
+ {
22
+ $response = (object) array(
23
+ 'endpoint' => 'orders',
24
+ 'page' => $page ? $page : 1,
25
+ 'limit' => (int) $limit,
26
+ 'count' => 0,
27
+ 'valid' => 0,
28
+ 'drafts' => 0,
29
+ 'stuffed' => false,
30
+ 'items' => array(),
31
+ );
32
+
33
+ if ((($orders = $this->getOrderPosts($page, $limit)) && !empty($orders))) {
34
+ foreach ($orders as $post) {
35
+ $response->count++;
36
+ if ($post->post_status === 'auto-draft') {
37
+ $response->drafts++;
38
+ continue;
39
+ }
40
+
41
+ $response->valid++;
42
+ $response->items[] = $this->transform($post);
43
+ }
44
+ }
45
+
46
+ $response->stuffed = ($response->count > 0 && (int) $response->count === (int) $limit) ? true : false;
47
+
48
+ return $response;
49
+ }
50
+
51
+ /**
52
+ * @param WP_Post $post
53
+ * @return MailChimp_WooCommerce_Order
54
+ */
55
+ public function transform(WP_Post $post)
56
+ {
57
+ $woo = new WC_Order($post);
58
+
59
+ $order = new MailChimp_WooCommerce_Order();
60
+
61
+ $order->setId($woo->get_id());
62
+
63
+ // if we have a campaign id let's set it now.
64
+ if (!empty($this->campaign_id)) {
65
+ $order->setCampaignId($this->campaign_id);
66
+ }
67
+
68
+ $order->setProcessedAt($woo->get_date_created());
69
+
70
+ $order->setCurrencyCode($woo->get_currency());
71
+
72
+ // grab the current statuses - this will end up being custom at some point.
73
+ $statuses = $this->getOrderStatuses();
74
+
75
+ // grab the order status
76
+ $status = $woo->get_status();
77
+
78
+ // map the fulfillment and financial statuses based on the map above.
79
+ $fulfillment_status = array_key_exists($status, $statuses) ? $statuses[$status]->fulfillment : null;
80
+ $financial_status = array_key_exists($status, $statuses) ? $statuses[$status]->financial : $status;
81
+
82
+ // set the fulfillment_status
83
+ $order->setFulfillmentStatus($fulfillment_status);
84
+
85
+ // set the financial status
86
+ $order->setFinancialStatus($financial_status);
87
+
88
+ // only set this if the order is cancelled.
89
+ if ($status === 'cancelled') $order->setCancelledAt($woo->get_date_modified());
90
+
91
+ // set the total
92
+ $order->setOrderTotal($woo->get_total());
93
+
94
+ // set the order URL
95
+ $order->setOrderURL($woo->get_view_order_url());
96
+
97
+ // if we have any tax
98
+ $order->setTaxTotal($woo->get_total_tax());
99
+
100
+ // if we have shipping.
101
+ $order->setShippingTotal($woo->get_shipping_total());
102
+
103
+ // set the order discount
104
+ $order->setDiscountTotal($woo->get_total_discount());
105
+
106
+ // set the customer
107
+ $order->setCustomer($this->buildCustomerFromOrder($woo));
108
+
109
+ // apply the addresses to the order
110
+ $order->setShippingAddress($this->transformShippingAddress($woo));
111
+ $order->setBillingAddress($this->transformBillingAddress($woo));
112
+
113
+ // loop through all the order items
114
+ foreach ($woo->get_items() as $key => $order_detail) {
115
+ /** @var WC_Order_Item_Product $order_detail */
116
+
117
+ // add it into the order item container.
118
+ $item = $this->transformLineItem($key, $order_detail);
119
+
120
+ // if we don't have a product post with this id, we need to add a deleted product to the MC side
121
+ if (!($product = $order_detail->get_product()) || 'trash' === $product->get_status()) {
122
+
123
+ $pid = $order_detail->get_product_id();
124
+
125
+ // check if it exists, otherwise create a new one.
126
+ if (($deleted_product = MailChimp_WooCommerce_Transform_Products::deleted($pid))) {
127
+ // swap out the old item id and product variant id with the deleted version.
128
+ $item->setProductId("deleted_{$pid}");
129
+ $item->setProductVariantId("deleted_{$pid}");
130
+
131
+ // add the item and continue on the loop.
132
+ $order->addItem($item);
133
+ continue;
134
+ }
135
+
136
+ mailchimp_log('order.items.error', "Order #{$woo->get_id()} :: Product {$pid} does not exist!");
137
+ continue;
138
+ }
139
+
140
+ $order->addItem($item);
141
+ }
142
+
143
+ //if (($refund = $woo->get_total_refunded()) && $refund > 0){
144
+ // this is where we would be altering the submission to tell us about the refund.
145
+ //}
146
+
147
+ return $order;
148
+ }
149
+
150
+ /**
151
+ * @param WC_Order $order
152
+ * @return MailChimp_WooCommerce_Customer
153
+ */
154
+ public function buildCustomerFromOrder(WC_Order $order)
155
+ {
156
+ $customer = new MailChimp_WooCommerce_Customer();
157
+
158
+ $customer->setId(md5(trim(strtolower($order->get_billing_email()))));
159
+ $customer->setCompany($order->get_billing_company());
160
+ $customer->setEmailAddress(trim($order->get_billing_email()));
161
+ $customer->setFirstName($order->get_billing_first_name());
162
+ $customer->setLastName($order->get_billing_last_name());
163
+ $customer->setAddress($this->transformBillingAddress($order));
164
+
165
+ if (!($stats = $this->getCustomerOrderTotals($order->get_user_id()))) {
166
+ $stats = (object) array('count' => 0, 'total' => 0);
167
+ }
168
+ $customer->setOrdersCount($stats->count);
169
+ $customer->setTotalSpent($stats->total);
170
+
171
+ // we are saving the post meta for subscribers on each order... so if they have subscribed on checkout
172
+ $subscriber_meta = get_post_meta($order->get_id(), 'mailchimp_woocommerce_is_subscribed', true);
173
+ $subscribed_on_order = $subscriber_meta === '' ? false : (bool) $subscriber_meta;
174
+
175
+ $customer->setOptInStatus($subscribed_on_order);
176
+
177
+ return $customer;
178
+ }
179
+
180
+ /**
181
+ * @param $key
182
+ * @param WC_Order_Item_Product $order_detail
183
+ * @return MailChimp_WooCommerce_LineItem
184
+ */
185
+ protected function transformLineItem($key, $order_detail)
186
+ {
187
+ // fire up a new MC line item
188
+ $item = new MailChimp_WooCommerce_LineItem();
189
+ $item->setId($key);
190
+
191
+ $item->setPrice($order_detail->get_total());
192
+ $item->setProductId($order_detail->get_product_id());
193
+ $variation_id = $order_detail->get_variation_id();
194
+ if (empty($variation_id)) $variation_id = $order_detail->get_product_id();
195
+ $item->setProductVariantId($variation_id);
196
+ $item->setQuantity($order_detail->get_quantity());
197
+
198
+ if ($item->getQuantity() > 1) {
199
+ $current_price = $item->getPrice();
200
+ $price = ($current_price/$item->getQuantity());
201
+ $item->setPrice($price);
202
+ }
203
+
204
+ return $item;
205
+ }
206
+
207
+ /**
208
+ * @param WC_Order $order
209
+ * @return MailChimp_WooCommerce_Address
210
+ */
211
+ public function transformBillingAddress(WC_Order $order)
212
+ {
213
+ // use the info from the order to compile an address.
214
+ $address = new MailChimp_WooCommerce_Address();
215
+ $address->setAddress1($order->get_billing_address_1());
216
+ $address->setAddress2($order->get_billing_address_2());
217
+ $address->setCity($order->get_billing_city());
218
+ $address->setProvince($order->get_billing_state());
219
+ $address->setPostalCode($order->get_billing_postcode());
220
+ $address->setCountry($order->get_billing_country());
221
+ $address->setPhone($order->get_billing_phone());
222
+
223
+ $bfn = $order->get_billing_first_name();
224
+ $bln = $order->get_billing_last_name();
225
+
226
+ // if we have billing names set it here
227
+ if (!empty($bfn) && !empty($bln)) {
228
+ $address->setName("{$bfn} {$bln}");
229
+ }
230
+
231
+ return $address;
232
+ }
233
+
234
+ /**
235
+ * @param WC_Order $order
236
+ * @return MailChimp_WooCommerce_Address
237
+ */
238
+ public function transformShippingAddress(WC_Order $order)
239
+ {
240
+ $address = new MailChimp_WooCommerce_Address();
241
+
242
+ $address->setAddress1($order->get_shipping_address_1());
243
+ $address->setAddress2($order->get_shipping_address_2());
244
+ $address->setCity($order->get_shipping_city());
245
+ $address->setProvince($order->get_shipping_state());
246
+ $address->setPostalCode($order->get_shipping_postcode());
247
+ $address->setCountry($order->get_shipping_country());
248
+
249
+ // shipping does not have a phone number, so maybe use this?
250
+ $address->setPhone($order->get_billing_phone());
251
+
252
+ $sfn = $order->get_billing_first_name();
253
+ $sln = $order->get_billing_last_name();
254
+
255
+ // if we have billing names set it here
256
+ if (!empty($sfn) && !empty($sln)) {
257
+ $address->setName("{$sfn} {$sln}");
258
+ }
259
+
260
+ return $address;
261
+ }
262
+
263
+ /**
264
+ * @param int $page
265
+ * @param int $posts
266
+ * @return array|bool
267
+ */
268
+ public function getOrderPosts($page = 1, $posts = 5)
269
+ {
270
+ $orders = get_posts(array(
271
+ 'post_type' => wc_get_order_types(),
272
+ 'post_status' => array_keys(wc_get_order_statuses()),
273
+ 'posts_per_page' => $posts,
274
+ 'paged' => $page,
275
+ 'orderby' => 'id',
276
+ 'order' => 'ASC'
277
+ ));
278
+
279
+ if (empty($orders)) {
280
+ sleep(2);
281
+
282
+ $orders = get_posts(array(
283
+ 'post_type' => wc_get_order_types(),
284
+ 'post_status' => array_keys(wc_get_order_statuses()),
285
+ 'posts_per_page' => $posts,
286
+ 'paged' => $page,
287
+ 'orderby' => 'id',
288
+ 'order' => 'ASC'
289
+ ));
290
+
291
+ if (empty($orders)) {
292
+ return false;
293
+ }
294
+ }
295
+
296
+ return $orders;
297
+ }
298
+
299
+ /**
300
+ * returns an object with a 'total' and a 'count'.
301
+ *
302
+ * @param $user_id
303
+ * @return object
304
+ */
305
+ public function getCustomerOrderTotals($user_id)
306
+ {
307
+ $customer = new WC_Customer($user_id);
308
+ $customer->get_order_count();
309
+ $customer->get_total_spent();
310
+
311
+ return (object) array(
312
+ 'count' => $customer->get_order_count(),
313
+ 'total' => $customer->get_total_spent()
314
+ );
315
+ }
316
+
317
+ /**
318
+ * @return array
319
+ */
320
+ public function getOrderStatuses()
321
+ {
322
+ return array(
323
+ // Order received (unpaid)
324
+ 'pending' => (object) array(
325
+ 'financial' => 'pending',
326
+ 'fulfillment' => null
327
+ ),
328
+ // Payment received and stock has been reduced – the order is awaiting fulfillment.
329
+ // All product orders require processing, except those for digital downloads
330
+ 'processing' => (object) array(
331
+ 'financial' => 'processing',
332
+ 'fulfillment' => null
333
+ ),
334
+ // Awaiting payment – stock is reduced, but you need to confirm payment
335
+ 'on-hold' => (object) array(
336
+ 'financial' => 'on-hold',
337
+ 'fulfillment' => null
338
+ ),
339
+ // Order fulfilled and complete – requires no further action
340
+ 'completed' => (object) array(
341
+ 'financial' => 'fulfilled',
342
+ 'fulfillment' => 'fulfilled'
343
+ ),
344
+ // Cancelled by an admin or the customer – no further action required
345
+ 'cancelled' => (object) array(
346
+ 'financial' => 'cancelled',
347
+ 'fulfillment' => null
348
+ ),
349
+ // Refunded by an admin – no further action required
350
+ 'refunded' => (object) array(
351
+ 'financial' => 'refunded',
352
+ 'fulfillment' => null
353
+ ),
354
+ // Payment failed or was declined (unpaid). Note that this status may not show immediately and
355
+ // instead show as Pending until verified (i.e., PayPal)
356
+ 'failed' => (object) array(
357
+ 'financial' => 'failed',
358
+ 'fulfillment' => null
359
+ ),
360
+ );
361
+ }
362
+ }
includes/api/class-mailchimp-woocommerce-transform-orders.php CHANGED
@@ -17,11 +17,11 @@ class MailChimp_WooCommerce_Transform_Orders
17
  * @param int $limit
18
  * @return \stdClass
19
  */
20
- public function compile($page = 1, $limit = 10)
21
  {
22
  $response = (object) array(
23
  'endpoint' => 'orders',
24
- 'page' => $page,
25
  'limit' => (int) $limit,
26
  'count' => 0,
27
  'valid' => 0,
@@ -142,7 +142,7 @@ class MailChimp_WooCommerce_Transform_Orders
142
  }
143
 
144
  //if (($refund = $woo->get_total_refunded()) && $refund > 0){
145
- // this is where we would be altering the submission to tell us about the refund.
146
  //}
147
 
148
  return $order;
@@ -310,7 +310,7 @@ class MailChimp_WooCommerce_Transform_Orders
310
  * @param int $posts
311
  * @return array|bool
312
  */
313
- public function getOrderPosts($page = 1, $posts = 10)
314
  {
315
  $orders = get_posts(array(
316
  'post_type' => 'shop_order',
@@ -322,7 +322,21 @@ class MailChimp_WooCommerce_Transform_Orders
322
  ));
323
 
324
  if (empty($orders)) {
325
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  }
327
 
328
  return $orders;
17
  * @param int $limit
18
  * @return \stdClass
19
  */
20
+ public function compile($page = 1, $limit = 5)
21
  {
22
  $response = (object) array(
23
  'endpoint' => 'orders',
24
+ 'page' => $page ? $page : 1,
25
  'limit' => (int) $limit,
26
  'count' => 0,
27
  'valid' => 0,
142
  }
143
 
144
  //if (($refund = $woo->get_total_refunded()) && $refund > 0){
145
+ // this is where we would be altering the submission to tell us about the refund.
146
  //}
147
 
148
  return $order;
310
  * @param int $posts
311
  * @return array|bool
312
  */
313
+ public function getOrderPosts($page = 1, $posts = 5)
314
  {
315
  $orders = get_posts(array(
316
  'post_type' => 'shop_order',
322
  ));
323
 
324
  if (empty($orders)) {
325
+
326
+ sleep(2);
327
+
328
+ $orders = get_posts(array(
329
+ 'post_type' => 'shop_order',
330
+ //'post_status' => 'publish',
331
+ 'posts_per_page' => $posts,
332
+ 'paged' => $page,
333
+ 'orderby' => 'id',
334
+ 'order' => 'ASC'
335
+ ));
336
+
337
+ if (empty($orders)) {
338
+ return false;
339
+ }
340
  }
341
 
342
  return $orders;
includes/api/class-mailchimp-woocommerce-transform-products.php CHANGED
@@ -15,11 +15,11 @@ class MailChimp_WooCommerce_Transform_Products
15
  * @param int $limit
16
  * @return \stdClass
17
  */
18
- public function compile($page = 1, $limit = 10)
19
  {
20
  $response = (object) array(
21
  'endpoint' => 'products',
22
- 'page' => $page,
23
  'limit' => (int) $limit,
24
  'count' => 0,
25
  'stuffed' => false,
@@ -141,10 +141,10 @@ class MailChimp_WooCommerce_Transform_Products
141
  * @param int $posts
142
  * @return array|bool
143
  */
144
- public function getProductPosts($page = 1, $posts = 10)
145
  {
146
  $products = get_posts(array(
147
- 'post_type' => array('product'),
148
  'posts_per_page' => $posts,
149
  'paged' => $page,
150
  'orderby' => 'ID',
@@ -152,7 +152,20 @@ class MailChimp_WooCommerce_Transform_Products
152
  ));
153
 
154
  if (empty($products)) {
155
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  }
157
 
158
  return $products;
15
  * @param int $limit
16
  * @return \stdClass
17
  */
18
+ public function compile($page = 1, $limit = 5)
19
  {
20
  $response = (object) array(
21
  'endpoint' => 'products',
22
+ 'page' => $page ? $page : 1,
23
  'limit' => (int) $limit,
24
  'count' => 0,
25
  'stuffed' => false,
141
  * @param int $posts
142
  * @return array|bool
143
  */
144
+ public function getProductPosts($page = 1, $posts = 5)
145
  {
146
  $products = get_posts(array(
147
+ 'post_type' => array_merge(array_keys(wc_get_product_types()), array('product')),
148
  'posts_per_page' => $posts,
149
  'paged' => $page,
150
  'orderby' => 'ID',
152
  ));
153
 
154
  if (empty($products)) {
155
+
156
+ sleep(2);
157
+
158
+ $products = get_posts(array(
159
+ 'post_type' => array_merge(array_keys(wc_get_product_types()), array('product')),
160
+ 'posts_per_page' => $posts,
161
+ 'paged' => $page,
162
+ 'orderby' => 'ID',
163
+ 'order' => 'ASC',
164
+ ));
165
+
166
+ if (empty($products)) {
167
+ return false;
168
+ }
169
  }
170
 
171
  return $products;
includes/api/helpers/class-mailchimp-woocommerce-api-locales.php CHANGED
@@ -13,7 +13,7 @@ class MailChimp_Api_Locales
13
  /**
14
  * @return array
15
  */
16
- public function all()
17
  {
18
  return array(
19
  "af_NA"=> "Afrikaans (Namibia)",
13
  /**
14
  * @return array
15
  */
16
+ public static function all()
17
  {
18
  return array(
19
  "af_NA"=> "Afrikaans (Namibia)",
includes/class-mailchimp-woocommerce-options.php CHANGED
@@ -108,6 +108,14 @@ abstract class MailChimp_Woocommerce_Options
108
  return (bool) $this->getOption($key, $default);
109
  }
110
 
 
 
 
 
 
 
 
 
111
  /**
112
  * @return array
113
  */
@@ -126,7 +134,7 @@ abstract class MailChimp_Woocommerce_Options
126
  */
127
  public function setData($key, $value)
128
  {
129
- update_option($this->plugin_name.'-'.$key, $value);
130
  return $this;
131
  }
132
 
@@ -244,25 +252,46 @@ abstract class MailChimp_Woocommerce_Options
244
  public function removePointers($products = true, $orders = true)
245
  {
246
  if ($products) {
247
- delete_option('mailchimp-woocommerce-sync.products.completed_at');
248
- delete_option('mailchimp-woocommerce-sync.products.current_page');
249
  }
250
 
251
  if ($orders) {
252
- delete_option('mailchimp-woocommerce-sync.orders.prevent');
253
- delete_option('mailchimp-woocommerce-sync.orders.completed_at');
254
- delete_option('mailchimp-woocommerce-sync.orders.current_page');
255
  }
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  delete_option('mailchimp-woocommerce-sync.orders.prevent');
258
- delete_option('mailchimp-woocommerce-errors.store_info');
259
  delete_option('mailchimp-woocommerce-sync.syncing');
260
  delete_option('mailchimp-woocommerce-sync.started_at');
261
  delete_option('mailchimp-woocommerce-sync.completed_at');
 
 
 
 
 
262
  delete_option('mailchimp-woocommerce-validation.api.ping');
263
  delete_option('mailchimp-woocommerce-cached-api-lists');
264
  delete_option('mailchimp-woocommerce-cached-api-ping-check');
265
-
266
- return $this;
267
  }
268
  }
108
  return (bool) $this->getOption($key, $default);
109
  }
110
 
111
+ /**
112
+ * @return array
113
+ */
114
+ public function resetOptions()
115
+ {
116
+ return $this->plugin_options = get_option($this->plugin_name);
117
+ }
118
+
119
  /**
120
  * @return array
121
  */
134
  */
135
  public function setData($key, $value)
136
  {
137
+ update_option($this->plugin_name.'-'.$key, $value, 'yes');
138
  return $this;
139
  }
140
 
252
  public function removePointers($products = true, $orders = true)
253
  {
254
  if ($products) {
255
+ $this->removeProductPointers();
 
256
  }
257
 
258
  if ($orders) {
259
+ $this->removeOrderPointers();
 
 
260
  }
261
 
262
+ $this->removeSyncPointers();
263
+
264
+ $this->removeMiscPointers();
265
+
266
+ return $this;
267
+ }
268
+
269
+ public function removeProductPointers()
270
+ {
271
+ delete_option('mailchimp-woocommerce-sync.products.completed_at');
272
+ delete_option('mailchimp-woocommerce-sync.products.current_page');
273
+ }
274
+
275
+ public function removeOrderPointers()
276
+ {
277
+ delete_option('mailchimp-woocommerce-sync.orders.prevent');
278
+ delete_option('mailchimp-woocommerce-sync.orders.completed_at');
279
+ delete_option('mailchimp-woocommerce-sync.orders.current_page');
280
+ }
281
+
282
+ public function removeSyncPointers()
283
+ {
284
  delete_option('mailchimp-woocommerce-sync.orders.prevent');
 
285
  delete_option('mailchimp-woocommerce-sync.syncing');
286
  delete_option('mailchimp-woocommerce-sync.started_at');
287
  delete_option('mailchimp-woocommerce-sync.completed_at');
288
+ }
289
+
290
+ public function removeMiscPointers()
291
+ {
292
+ delete_option('mailchimp-woocommerce-errors.store_info');
293
  delete_option('mailchimp-woocommerce-validation.api.ping');
294
  delete_option('mailchimp-woocommerce-cached-api-lists');
295
  delete_option('mailchimp-woocommerce-cached-api-ping-check');
 
 
296
  }
297
  }
includes/class-mailchimp-woocommerce-service.php CHANGED
@@ -24,6 +24,14 @@ class MailChimp_Service extends MailChimp_Woocommerce_Options
24
  */
25
  public function wooIsRunning()
26
  {
 
 
 
 
 
 
 
 
27
  // make sure the site option for setting the mailchimp_carts has been saved.
28
  $this->validated_cart_db = get_site_option('mailchimp_woocommerce_db_mailchimp_carts', false);
29
  $this->is_admin = current_user_can('administrator');
24
  */
25
  public function wooIsRunning()
26
  {
27
+ $path = plugin_dir_path( dirname( __FILE__ ) );
28
+
29
+ if (function_exists('WC') && (int) WC()->version >= 3) {
30
+ require_once $path . 'includes/api/class-mailchimp-woocommerce-transform-orders-wc3.php';
31
+ } else {
32
+ require_once $path . 'includes/api/class-mailchimp-woocommerce-transform-orders.php';
33
+ }
34
+
35
  // make sure the site option for setting the mailchimp_carts has been saved.
36
  $this->validated_cart_db = get_site_option('mailchimp_woocommerce_db_mailchimp_carts', false);
37
  $this->is_admin = current_user_can('administrator');
includes/class-mailchimp-woocommerce.php CHANGED
@@ -174,7 +174,6 @@ class MailChimp_Woocommerce {
174
  require_once $path . 'includes/api/class-mailchimp-woocommerce-api.php';
175
  require_once $path . 'includes/api/class-mailchimp-woocommerce-create-list-submission.php';
176
  require_once $path . 'includes/api/class-mailchimp-woocommerce-transform-products.php';
177
- require_once $path . 'includes/api/class-mailchimp-woocommerce-transform-orders.php';
178
 
179
  /** Require all the mailchimp api asset classes */
180
  require_once $path . 'includes/api/assets/class-mailchimp-address.php';
174
  require_once $path . 'includes/api/class-mailchimp-woocommerce-api.php';
175
  require_once $path . 'includes/api/class-mailchimp-woocommerce-create-list-submission.php';
176
  require_once $path . 'includes/api/class-mailchimp-woocommerce-transform-products.php';
 
177
 
178
  /** Require all the mailchimp api asset classes */
179
  require_once $path . 'includes/api/assets/class-mailchimp-address.php';
includes/processes/class-mailchimp-woocommerce-abstract-sync.php CHANGED
@@ -76,15 +76,28 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
76
  */
77
  public function handle() {
78
 
79
- if (!($page = $this->getResources()) || !($this->store_id = $this->getStoreID())) {
 
80
  return false;
81
  }
82
 
83
- $this->setResourcePagePointer($page->page + 1, $this->getResourceType());
 
 
 
 
 
 
 
 
 
 
84
 
85
  // if we've got a 0 count, that means we're done.
86
  if ($page->count <= 0) {
87
 
 
 
88
  // reset the resource page back to 1
89
  $this->resourceComplete($this->getResourceType());
90
 
@@ -99,6 +112,8 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
99
  $this->iterate($resource);
100
  }
101
 
 
 
102
  // this will paginate through all records for the resource type until they return no records.
103
  wp_queue(new static());
104
 
@@ -110,14 +125,24 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
110
  */
111
  public function flagStartSync()
112
  {
113
- mailchimp_log('sync.started', "Starting Sync :: ".date('D, M j, Y g:i A'));
114
 
115
- // this is the last thing we're doing so it's complete as of now.
 
 
 
 
116
  $this->setData('sync.syncing', true);
117
  $this->setData('sync.started_at', time());
118
 
119
- $this->removeData('sync.products.current_page');
120
- $this->removeData('sync.orders.current_page');
 
 
 
 
 
 
121
 
122
  // flag the store as syncing
123
  mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), true);
@@ -130,12 +155,16 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
130
  */
131
  public function flagStopSync()
132
  {
133
- mailchimp_log('sync.completed', "Finished Sync :: ".date('D, M j, Y g:i A'));
134
-
135
  // this is the last thing we're doing so it's complete as of now.
136
  $this->setData('sync.syncing', false);
137
  $this->setData('sync.completed_at', time());
138
 
 
 
 
 
 
 
139
  // flag the store as sync_finished
140
  mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), false);
141
 
@@ -150,17 +179,23 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
150
  $current_page = $this->getResourcePagePointer($this->getResourceType());
151
 
152
  if ($current_page === 'complete') {
153
- return false;
 
 
 
 
 
 
154
  }
155
 
156
- return $this->api()->paginate($this->getResourceType(), $current_page, 10);
157
  }
158
 
159
  /**
160
  * @param null|string $resource
161
  * @return $this
162
  */
163
- protected function resetResourcePagePointer($resource = null)
164
  {
165
  if (empty($resource)) $resource = $this->getResourceType();
166
 
@@ -173,7 +208,7 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
173
  * @param null|string $resource
174
  * @return null
175
  */
176
- protected function getResourcePagePointer($resource = null)
177
  {
178
  if (empty($resource)) $resource = $this->getResourceType();
179
 
@@ -185,7 +220,7 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
185
  * @param null $resource
186
  * @return MailChimp_WooCommerce_Abtstract_Sync
187
  */
188
- protected function setResourcePagePointer($page, $resource = null)
189
  {
190
  if (empty($resource)) $resource = $this->getResourceType();
191
 
@@ -285,7 +320,7 @@ abstract class MailChimp_WooCommerce_Abtstract_Sync extends WP_Job
285
  */
286
  public function setData($key, $value)
287
  {
288
- update_option($this->plugin_name.'-'.$key, $value);
289
  return $this;
290
  }
291
 
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
+ $page = $this->getResources();
85
+
86
+ if (empty($page)) {
87
+ mailchimp_debug(get_called_class().'@handle', 'could not find any more '.$this->getResourceType().' records ending on page '.$this->getResourcePagePointer());
88
+ // call the completed event to process further
89
+ $this->resourceComplete($this->getResourceType());
90
+ $this->complete();
91
+ return false;
92
+ }
93
+
94
+ $this->setResourcePagePointer(($page->page + 1), $this->getResourceType());
95
 
96
  // if we've got a 0 count, that means we're done.
97
  if ($page->count <= 0) {
98
 
99
+ mailchimp_debug(get_called_class().'@handle', $this->getResourceType().' :: count is 0 : completing now!');
100
+
101
  // reset the resource page back to 1
102
  $this->resourceComplete($this->getResourceType());
103
 
112
  $this->iterate($resource);
113
  }
114
 
115
+ mailchimp_debug(get_called_class().'@handle', 'queuing up the next job');
116
+
117
  // this will paginate through all records for the resource type until they return no records.
118
  wp_queue(new static());
119
 
125
  */
126
  public function flagStartSync()
127
  {
128
+ $job = new MailChimp_Service();
129
 
130
+ $job->removeSyncPointers();
131
+
132
+ $this->setData('sync.config.resync', false);
133
+ $this->setData('sync.orders.current_page', 1);
134
+ $this->setData('sync.products.current_page', 1);
135
  $this->setData('sync.syncing', true);
136
  $this->setData('sync.started_at', time());
137
 
138
+ global $wpdb;
139
+ try {
140
+ $wpdb->show_errors(false);
141
+ $wpdb->query("DELETE FROM {$wpdb->prefix}queue");
142
+ $wpdb->show_errors(true);
143
+ } catch (\Exception $e) {}
144
+
145
+ mailchimp_log('sync.started', "Starting Sync :: ".date('D, M j, Y g:i A'));
146
 
147
  // flag the store as syncing
148
  mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), true);
155
  */
156
  public function flagStopSync()
157
  {
 
 
158
  // this is the last thing we're doing so it's complete as of now.
159
  $this->setData('sync.syncing', false);
160
  $this->setData('sync.completed_at', time());
161
 
162
+ // set the current sync pages back to 1 if the user hits resync.
163
+ $this->setData('sync.orders.current_page', 1);
164
+ $this->setData('sync.products.current_page', 1);
165
+
166
+ mailchimp_log('sync.completed', "Finished Sync :: ".date('D, M j, Y g:i A'));
167
+
168
  // flag the store as sync_finished
169
  mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), false);
170
 
179
  $current_page = $this->getResourcePagePointer($this->getResourceType());
180
 
181
  if ($current_page === 'complete') {
182
+ if (!$this->getData('sync.config.resync', false)) {
183
+ return false;
184
+ }
185
+
186
+ $current_page = 1;
187
+ $this->setResourcePagePointer($current_page);
188
+ $this->setData('sync.config.resync', false);
189
  }
190
 
191
+ return $this->api()->paginate($this->getResourceType(), $current_page, 5);
192
  }
193
 
194
  /**
195
  * @param null|string $resource
196
  * @return $this
197
  */
198
+ public function resetResourcePagePointer($resource = null)
199
  {
200
  if (empty($resource)) $resource = $this->getResourceType();
201
 
208
  * @param null|string $resource
209
  * @return null
210
  */
211
+ public function getResourcePagePointer($resource = null)
212
  {
213
  if (empty($resource)) $resource = $this->getResourceType();
214
 
220
  * @param null $resource
221
  * @return MailChimp_WooCommerce_Abtstract_Sync
222
  */
223
+ public function setResourcePagePointer($page, $resource = null)
224
  {
225
  if (empty($resource)) $resource = $this->getResourceType();
226
 
320
  */
321
  public function setData($key, $value)
322
  {
323
+ update_option($this->plugin_name.'-'.$key, $value, 'yes');
324
  return $this;
325
  }
326
 
includes/processes/class-mailchimp-woocommerce-process-orders.php CHANGED
@@ -64,13 +64,18 @@ class MailChimp_WooCommerce_Process_Orders extends MailChimp_WooCommerce_Abtstra
64
 
65
  } catch (MailChimp_WooCommerce_Error $e) {
66
  mailchimp_log('sync.orders.error', "$call :: MailChimp_WooCommerce_Error :: {$e->getMessage()}");
 
67
  } catch (MailChimp_WooCommerce_ServerError $e) {
68
  mailchimp_log('sync.orders.error', "$call :: MailChimp_WooCommerce_ServerError :: {$e->getMessage()}");
 
69
  } catch (Exception $e) {
70
  mailchimp_log('sync.orders.error', "$call :: Uncaught Exception :: {$e->getMessage()}");
 
71
  }
72
  }
73
 
 
 
74
  return false;
75
  }
76
 
64
 
65
  } catch (MailChimp_WooCommerce_Error $e) {
66
  mailchimp_log('sync.orders.error', "$call :: MailChimp_WooCommerce_Error :: {$e->getMessage()}");
67
+ return false;
68
  } catch (MailChimp_WooCommerce_ServerError $e) {
69
  mailchimp_log('sync.orders.error', "$call :: MailChimp_WooCommerce_ServerError :: {$e->getMessage()}");
70
+ return false;
71
  } catch (Exception $e) {
72
  mailchimp_log('sync.orders.error', "$call :: Uncaught Exception :: {$e->getMessage()}");
73
+ return false;
74
  }
75
  }
76
 
77
+ mailchimp_debug('iterate.order', 'no order found', $item);
78
+
79
  return false;
80
  }
81
 
includes/processes/class-mailchimp-woocommerce-process-products.php CHANGED
@@ -46,12 +46,10 @@ class MailChimp_WooCommerce_Process_Products extends MailChimp_WooCommerce_Abtst
46
 
47
  // add the product.
48
  try {
49
- mailchimp_log('sync.products.submitting', "addStoreProduct :: #{$item->getId()}");
50
-
51
  // make the call
52
- $response = $this->mailchimp()->addStoreProduct($this->store_id, $item);
53
 
54
- mailchimp_log('sync.products.success', "addStoreProduct :: #{$item->getId()}");
55
 
56
  return $response;
57
 
46
 
47
  // add the product.
48
  try {
 
 
49
  // make the call
50
+ $response = $this->mailchimp()->addStoreProduct($this->store_id, $item, false);
51
 
52
+ mailchimp_log('sync.products.success', "addStoreProduct :: #{$response->getId()}");
53
 
54
  return $response;
55
 
includes/processes/class-mailchimp-woocommerce-single-order.php CHANGED
@@ -43,6 +43,10 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
43
 
44
  public function process()
45
  {
 
 
 
 
46
  $options = get_option('mailchimp-woocommerce', array());
47
  $store_id = mailchimp_get_store_id();
48
 
@@ -72,8 +76,12 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
72
  // will either add or update the order
73
  try {
74
 
 
 
 
 
75
  // transform the order
76
- $order = $job->transform(get_post($this->order_id));
77
 
78
  // if we're overriding this we need to set it here.
79
  if ($this->partially_refunded) {
43
 
44
  public function process()
45
  {
46
+ if (empty($this->order_id)) {
47
+ return false;
48
+ }
49
+
50
  $options = get_option('mailchimp-woocommerce', array());
51
  $store_id = mailchimp_get_store_id();
52
 
76
  // will either add or update the order
77
  try {
78
 
79
+ if (!($order_post = get_post($this->order_id))) {
80
+ return false;
81
+ }
82
+
83
  // transform the order
84
+ $order = $job->transform($order_post);
85
 
86
  // if we're overriding this we need to set it here.
87
  if ($this->partially_refunded) {
includes/processes/class-mailchimp-woocommerce-single-product.php CHANGED
@@ -37,18 +37,25 @@ class MailChimp_WooCommerce_Single_Product extends WP_Job
37
  }
38
 
39
  /**
40
- * @return MailChimp_WooCommerce_Product
41
- * @throws Exception
42
  */
43
  public function process()
44
  {
 
 
 
 
45
  if ($this->api()->getStoreProduct($this->store_id, $this->product_id)) {
46
  $this->api()->deleteStoreProduct($this->store_id, $this->product_id);
47
  }
48
 
49
  try {
50
 
51
- $product = $this->transformer()->transform(get_post($this->product_id));
 
 
 
 
52
 
53
  mailchimp_log('product_submit.submitting', "addStoreProduct :: #{$product->getId()}");
54
 
37
  }
38
 
39
  /**
40
+ * @return bool|MailChimp_WooCommerce_Product
 
41
  */
42
  public function process()
43
  {
44
+ if (empty($this->product_id)) {
45
+ return false;
46
+ }
47
+
48
  if ($this->api()->getStoreProduct($this->store_id, $this->product_id)) {
49
  $this->api()->deleteStoreProduct($this->store_id, $this->product_id);
50
  }
51
 
52
  try {
53
 
54
+ if (!($product_post = get_post($this->product_id))) {
55
+ return false;
56
+ }
57
+
58
+ $product = $this->transformer()->transform($product_post);
59
 
60
  mailchimp_log('product_submit.submitting', "addStoreProduct :: #{$product->getId()}");
61
 
includes/vendor/queue.php CHANGED
@@ -15,6 +15,9 @@ require_once $queue_folder_path . 'queue/classes/wp-queue.php';
15
  require_once $queue_folder_path . 'queue/classes/worker/wp-worker.php';
16
  require_once $queue_folder_path . 'queue/classes/worker/wp-http-worker.php';
17
 
 
 
 
18
  // Add WP CLI commands
19
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
20
  require_once $queue_folder_path . 'queue/classes/cli/queue-command.php';
@@ -22,9 +25,6 @@ if ( defined( 'WP_CLI' ) && WP_CLI ) {
22
  WP_CLI::add_command( 'queue', 'Queue_Command' );
23
  }
24
 
25
- global $wp_queue;
26
- $wp_queue = new WP_Queue();
27
-
28
  // Instantiate HTTP queue worker
29
  new WP_Http_Worker($wp_queue);
30
 
15
  require_once $queue_folder_path . 'queue/classes/worker/wp-worker.php';
16
  require_once $queue_folder_path . 'queue/classes/worker/wp-http-worker.php';
17
 
18
+ global $wp_queue;
19
+ $wp_queue = new WP_Queue();
20
+
21
  // Add WP CLI commands
22
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
23
  require_once $queue_folder_path . 'queue/classes/cli/queue-command.php';
25
  WP_CLI::add_command( 'queue', 'Queue_Command' );
26
  }
27
 
 
 
 
28
  // Instantiate HTTP queue worker
29
  new WP_Http_Worker($wp_queue);
30
 
includes/vendor/queue/classes/cli/queue-command.php CHANGED
@@ -7,6 +7,18 @@
7
  */
8
  class Queue_Command extends WP_CLI_Command {
9
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  /**
11
  * Creates the queue tables.
12
  *
@@ -60,8 +72,7 @@ class Queue_Command extends WP_CLI_Command {
60
  if ( $worker->should_run() ) {
61
  if ( $worker->process_next_job() ) {
62
  WP_CLI::success( 'Processed: ' . $worker->get_job_name() );
63
- } else {
64
- WP_CLI::warning( 'Failed: ' . $worker->get_job_name() );
65
  }
66
  } else {
67
  sleep( 5 );
@@ -117,4 +128,5 @@ class Queue_Command extends WP_CLI_Command {
117
  WP_CLI::success( $count . ' failed jobs pushed to the queue' );
118
  }
119
 
120
- }
 
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
+
22
  /**
23
  * Creates the queue tables.
24
  *
72
  if ( $worker->should_run() ) {
73
  if ( $worker->process_next_job() ) {
74
  WP_CLI::success( 'Processed: ' . $worker->get_job_name() );
75
+ sleep(1);
 
76
  }
77
  } else {
78
  sleep( 5 );
128
  WP_CLI::success( $count . ' failed jobs pushed to the queue' );
129
  }
130
 
131
+ }
132
+
includes/vendor/queue/classes/worker/wp-worker.php CHANGED
@@ -41,7 +41,13 @@ if ( ! class_exists( 'WP_Worker' ) ) {
41
  * @return bool
42
  */
43
  public function process_next_job() {
44
- $job = $this->queue->get_next_job();
 
 
 
 
 
 
45
  $this->payload = unserialize( $job->job );
46
 
47
  $this->queue->lock_job( $job );
@@ -70,6 +76,10 @@ if ( ! class_exists( 'WP_Worker' ) ) {
70
  return false;
71
  }
72
 
 
 
 
 
73
  return true;
74
  }
75
 
41
  * @return bool
42
  */
43
  public function process_next_job() {
44
+ $job = $this->queue->get_next_job();
45
+
46
+ if (empty($job)) {
47
+ mailchimp_debug('wp-worker@process_next_job', 'empty job data');
48
+ return true;
49
+ }
50
+
51
  $this->payload = unserialize( $job->job );
52
 
53
  $this->queue->lock_job( $job );
76
  return false;
77
  }
78
 
79
+ if (defined('WP_CLI') && WP_CLI && property_exists($this->payload, 'should_kill_queue_listener') && $this->payload->should_kill_queue_listener === true) {
80
+ wp_die('killing queue listener');
81
+ }
82
+
83
  return true;
84
  }
85
 
includes/vendor/queue/classes/wp-job.php CHANGED
@@ -3,6 +3,8 @@
3
  if ( ! class_exists( 'WP_Job' ) ) {
4
  abstract class WP_Job {
5
 
 
 
6
  /**
7
  * @var stdClass
8
  */
@@ -100,4 +102,4 @@ if ( ! class_exists( 'WP_Job' ) ) {
100
  abstract public function handle();
101
 
102
  }
103
- }
3
  if ( ! class_exists( 'WP_Job' ) ) {
4
  abstract class WP_Job {
5
 
6
+ public $should_kill_queue_listener = false;
7
+
8
  /**
9
  * @var stdClass
10
  */
102
  abstract public function handle();
103
 
104
  }
105
+ }
mailchimp-woocommerce.php CHANGED
@@ -16,51 +16,54 @@
16
  * Plugin Name: MailChimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
  * Description: MailChimp - WooCommerce plugin
19
- * Version: 1.1.1
20
  * Author: MailChimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
23
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
24
  * Text Domain: mailchimp-woocommerce
25
  * Domain Path: /languages
 
 
26
  */
27
 
28
  // If this file is called directly, abort.
29
  if ( ! defined( 'WPINC' ) ) {
30
- die;
31
  }
32
 
33
  /**
34
  * @return object
35
  */
36
  function mailchimp_environment_variables() {
37
- global $wp_version;
38
-
39
- return (object) array(
40
- 'repo' => 'master',
41
- 'environment' => 'production',
42
- 'version' => '1.1.1',
43
- 'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
44
- );
 
45
  }
46
 
47
  /**
48
  * @return bool|int
49
  */
50
  function mailchimp_get_list_id() {
51
- if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
52
- if (isset($options['mailchimp_list'])) {
53
- return $options['mailchimp_list'];
54
- }
55
- }
56
- return false;
57
  }
58
 
59
  /**
60
  * @return string
61
  */
62
  function mailchimp_get_store_id() {
63
- $store_id = mailchimp_get_data('store_id', false);
64
  if (empty($store_id)) {
65
  // this is for the previous installs that had been applying the MC store id as the siteurl.
66
  // patched to the random hash because people were changing this value for various reasons.
@@ -74,12 +77,12 @@ function mailchimp_get_store_id() {
74
  * @return bool|MailChimp_WooCommerce_MailChimpApi
75
  */
76
  function mailchimp_get_api() {
77
- if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
78
- if (isset($options['mailchimp_api_key'])) {
79
- return new MailChimp_WooCommerce_MailChimpApi($options['mailchimp_api_key']);
80
- }
81
- }
82
- return false;
83
  }
84
 
85
  /**
@@ -88,14 +91,14 @@ function mailchimp_get_api() {
88
  * @return null
89
  */
90
  function mailchimp_get_option($key, $default = null) {
91
- $options = get_option('mailchimp-woocommerce');
92
- if (!is_array($options)) {
93
- return $default;
94
- }
95
- if (!array_key_exists($key, $options)) {
96
- return $default;
97
- }
98
- return $options[$key];
99
  }
100
 
101
  /**
@@ -104,7 +107,7 @@ function mailchimp_get_option($key, $default = null) {
104
  * @return mixed
105
  */
106
  function mailchimp_get_data($key, $default = null) {
107
- return get_option('mailchimp-woocommerce-'.$key, $default);
108
  }
109
 
110
  /**
@@ -122,18 +125,18 @@ function mailchimp_set_data($key, $value, $autoload = 'yes') {
122
  * @return DateTime
123
  */
124
  function mailchimp_date_utc($date) {
125
- $timezone = wc_timezone_string();
126
- //$timezone = mailchimp_get_option('store_timezone', 'America/New_York');
127
- if (is_numeric($date)) {
128
- $stamp = $date;
129
- $date = new \DateTime('now', new DateTimeZone($timezone));
130
- $date->setTimestamp($stamp);
131
- } else {
132
- $date = new \DateTime($date, new DateTimeZone($timezone));
133
- }
134
-
135
- $date->setTimezone(new DateTimeZone('UTC'));
136
- return $date;
137
  }
138
 
139
  /**
@@ -142,13 +145,13 @@ function mailchimp_date_utc($date) {
142
  */
143
  function mailchimp_date_local($date) {
144
  $timezone = mailchimp_get_option('store_timezone', 'America/New_York');
145
- if (is_numeric($date)) {
146
- $stamp = $date;
147
- $date = new \DateTime('now', new DateTimeZone('UTC'));
148
- $date->setTimestamp($stamp);
149
- } else {
150
- $date = new \DateTime($date, new DateTimeZone('UTC'));
151
- }
152
 
153
  $date->setTimezone(new DateTimeZone($timezone));
154
  return $date;
@@ -159,34 +162,34 @@ function mailchimp_date_local($date) {
159
  * @return mixed
160
  */
161
  function mailchimp_array_remove_empty($data) {
162
- if (empty($data) || !is_array($data)) {
163
- return array();
164
- }
165
- foreach ($data as $key => $value) {
166
- if ($value === null || $value === '') {
167
- unset($data[$key]);
168
- }
169
- }
170
- return $data;
171
  }
172
 
173
  /**
174
  * @return array
175
  */
176
  function mailchimp_get_timezone_list() {
177
- $zones_array = array();
178
- $timestamp = time();
179
- $current = date_default_timezone_get();
180
-
181
- foreach(timezone_identifiers_list() as $key => $zone) {
182
- date_default_timezone_set($zone);
183
- $zones_array[$key]['zone'] = $zone;
184
- $zones_array[$key]['diff_from_GMT'] = 'UTC/GMT ' . date('P', $timestamp);
185
- }
186
 
187
- date_default_timezone_set($current);
 
 
 
 
188
 
189
- return $zones_array;
 
 
190
  }
191
 
192
  /**
@@ -195,18 +198,31 @@ function mailchimp_get_timezone_list() {
195
  */
196
  function activate_mailchimp_woocommerce()
197
  {
198
- // if we don't have woocommerce we need to display a horrible error message before the plugin is installed.
199
- if (!is_plugin_active('woocommerce/woocommerce.php')) {
200
- // Deactivate the plugin
201
- deactivate_plugins(__FILE__);
202
- $error_message = __('The MailChimp For WooCommerce plugin requires the <a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a> plugin to be active!', 'woocommerce');
203
- wp_die($error_message);
204
- }
205
 
206
- // ok we can activate this thing.
207
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-activator.php';
208
 
209
- MailChimp_Woocommerce_Activator::activate();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
 
212
  /**
@@ -214,8 +230,8 @@ function activate_mailchimp_woocommerce()
214
  */
215
  function install_mailchimp_queue()
216
  {
217
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-activator.php';
218
- MailChimp_Woocommerce_Activator::create_queue_tables();
219
  }
220
 
221
  /**
@@ -223,25 +239,32 @@ function install_mailchimp_queue()
223
  * This action is documented in includes/class-mailchimp-woocommerce-deactivator.php
224
  */
225
  function deactivate_mailchimp_woocommerce() {
226
- require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-deactivator.php';
227
- MailChimp_Woocommerce_Deactivator::deactivate();
228
  }
229
 
230
  /**
231
  * See if we need to run any updates.
232
  */
233
  function run_mailchimp_plugin_updater() {
234
- if (!class_exists('PucFactory')) {
235
- require plugin_dir_path( __FILE__ ) . 'includes/plugin-update-checker/plugin-update-checker.php';
236
- }
237
-
238
- /** @var \PucGitHubChecker_3_1 $checker */
239
- $updater = PucFactory::getLatestClassVersion('PucGitHubChecker');
 
 
 
 
 
 
 
240
 
241
- if (class_exists($updater)) {
242
- $env = mailchimp_environment_variables();
243
- $checker = new $updater('https://github.com/mailchimp/mc-woocommerce/', __FILE__, $env->repo, 1);
244
- $checker->handleManualCheck();
245
  }
246
  }
247
 
@@ -255,27 +278,14 @@ function mailchimp_log($action, $message, $data = array())
255
  {
256
  $options = MailChimp_Woocommerce::getLoggingConfig();
257
 
258
- if (!$options->enable_logging || !$options->account_id || !$options->username) {
259
- return false;
260
- }
261
 
262
- $data = array(
263
- 'account_id' => $options->account_id,
264
- 'username' => $options->username,
265
- 'store_domain' => site_url(),
266
- 'platform' => 'woocommerce',
267
- 'action' => $action,
268
- 'message' => $message,
269
- 'data' => $data,
270
- );
271
-
272
- return wp_remote_post($options->endpoint, array(
273
- 'headers' => array(
274
- 'Accept: application/json',
275
- 'Content-Type: application/json'
276
- ),
277
- 'body' => json_encode($data),
278
- ));
279
  }
280
 
281
  /**
@@ -287,13 +297,13 @@ function mailchimp_log($action, $message, $data = array())
287
  */
288
  function mailchimp_string_contains($haystack, $needles)
289
  {
290
- foreach ((array) $needles as $needle) {
291
- if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
292
- return true;
293
- }
294
- }
295
 
296
- return false;
297
  }
298
 
299
 
@@ -301,25 +311,26 @@ function mailchimp_string_contains($haystack, $needles)
301
  * @return int
302
  */
303
  function mailchimp_get_product_count() {
304
- $posts = mailchimp_count_posts('product');
305
- $total = 0;
306
- foreach ($posts as $status => $count) {
307
- $total += $count;
308
- }
309
- return $total;
 
310
  }
311
 
312
  /**
313
  * @return int
314
  */
315
  function mailchimp_get_order_count() {
316
- $posts = mailchimp_count_posts('shop_order');
317
- unset($posts['auto-draft']);
318
- $total = 0;
319
- foreach ($posts as $status => $count) {
320
- $total += $count;
321
- }
322
- return $total;
323
  }
324
 
325
  /**
@@ -327,14 +338,14 @@ function mailchimp_get_order_count() {
327
  * @return array|null|object
328
  */
329
  function mailchimp_count_posts($type) {
330
- global $wpdb;
331
- $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s GROUP BY post_status";
332
- $posts = $wpdb->get_results( $wpdb->prepare($query, $type));
333
- $response = array();
334
- foreach ($posts as $post) {
335
- $response[$post->post_status] = $post->num_posts;
336
- }
337
- return $response;
338
  }
339
 
340
  register_activation_hook( __FILE__, 'activate_mailchimp_woocommerce' );
@@ -357,14 +368,14 @@ require plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce.php'
357
  * @since 1.0.0
358
  */
359
  function run_mailchimp_woocommerce() {
360
- $env = mailchimp_environment_variables();
361
- $plugin = new MailChimp_Woocommerce($env->environment, $env->version);
362
- $plugin->run();
363
  }
364
 
365
  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
366
- $forwarded_address = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
367
- $_SERVER['REMOTE_ADDR'] = $forwarded_address[0];
368
  }
369
 
370
  function mailchimp_woocommerce_add_meta_tags() {
16
  * Plugin Name: MailChimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
  * Description: MailChimp - WooCommerce plugin
19
+ * Version: 2.0.0
20
  * Author: MailChimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
23
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
24
  * Text Domain: mailchimp-woocommerce
25
  * Domain Path: /languages
26
+ * Requires at least: 4.4
27
+ * Tested up to: 4.7
28
  */
29
 
30
  // If this file is called directly, abort.
31
  if ( ! defined( 'WPINC' ) ) {
32
+ die;
33
  }
34
 
35
  /**
36
  * @return object
37
  */
38
  function mailchimp_environment_variables() {
39
+ global $wp_version;
40
+
41
+ return (object) array(
42
+ 'repo' => 'master',
43
+ 'environment' => 'production',
44
+ 'version' => '2.0.0',
45
+ 'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
46
+ 'wc_version' => function_exists('WC') ? WC()->version : null,
47
+ );
48
  }
49
 
50
  /**
51
  * @return bool|int
52
  */
53
  function mailchimp_get_list_id() {
54
+ if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
55
+ if (isset($options['mailchimp_list'])) {
56
+ return $options['mailchimp_list'];
57
+ }
58
+ }
59
+ return false;
60
  }
61
 
62
  /**
63
  * @return string
64
  */
65
  function mailchimp_get_store_id() {
66
+ $store_id = mailchimp_get_data('store_id', false);
67
  if (empty($store_id)) {
68
  // this is for the previous installs that had been applying the MC store id as the siteurl.
69
  // patched to the random hash because people were changing this value for various reasons.
77
  * @return bool|MailChimp_WooCommerce_MailChimpApi
78
  */
79
  function mailchimp_get_api() {
80
+ if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
81
+ if (isset($options['mailchimp_api_key'])) {
82
+ return new MailChimp_WooCommerce_MailChimpApi($options['mailchimp_api_key']);
83
+ }
84
+ }
85
+ return false;
86
  }
87
 
88
  /**
91
  * @return null
92
  */
93
  function mailchimp_get_option($key, $default = null) {
94
+ $options = get_option('mailchimp-woocommerce');
95
+ if (!is_array($options)) {
96
+ return $default;
97
+ }
98
+ if (!array_key_exists($key, $options)) {
99
+ return $default;
100
+ }
101
+ return $options[$key];
102
  }
103
 
104
  /**
107
  * @return mixed
108
  */
109
  function mailchimp_get_data($key, $default = null) {
110
+ return get_option('mailchimp-woocommerce-'.$key, $default);
111
  }
112
 
113
  /**
125
  * @return DateTime
126
  */
127
  function mailchimp_date_utc($date) {
128
+ $timezone = wc_timezone_string();
129
+ //$timezone = mailchimp_get_option('store_timezone', 'America/New_York');
130
+ if (is_numeric($date)) {
131
+ $stamp = $date;
132
+ $date = new \DateTime('now', new DateTimeZone($timezone));
133
+ $date->setTimestamp($stamp);
134
+ } else {
135
+ $date = new \DateTime($date, new DateTimeZone($timezone));
136
+ }
137
+
138
+ $date->setTimezone(new DateTimeZone('UTC'));
139
+ return $date;
140
  }
141
 
142
  /**
145
  */
146
  function mailchimp_date_local($date) {
147
  $timezone = mailchimp_get_option('store_timezone', 'America/New_York');
148
+ if (is_numeric($date)) {
149
+ $stamp = $date;
150
+ $date = new \DateTime('now', new DateTimeZone('UTC'));
151
+ $date->setTimestamp($stamp);
152
+ } else {
153
+ $date = new \DateTime($date, new DateTimeZone('UTC'));
154
+ }
155
 
156
  $date->setTimezone(new DateTimeZone($timezone));
157
  return $date;
162
  * @return mixed
163
  */
164
  function mailchimp_array_remove_empty($data) {
165
+ if (empty($data) || !is_array($data)) {
166
+ return array();
167
+ }
168
+ foreach ($data as $key => $value) {
169
+ if ($value === null || $value === '') {
170
+ unset($data[$key]);
171
+ }
172
+ }
173
+ return $data;
174
  }
175
 
176
  /**
177
  * @return array
178
  */
179
  function mailchimp_get_timezone_list() {
180
+ $zones_array = array();
181
+ $timestamp = time();
182
+ $current = date_default_timezone_get();
 
 
 
 
 
 
183
 
184
+ foreach(timezone_identifiers_list() as $key => $zone) {
185
+ date_default_timezone_set($zone);
186
+ $zones_array[$key]['zone'] = $zone;
187
+ $zones_array[$key]['diff_from_GMT'] = 'UTC/GMT ' . date('P', $timestamp);
188
+ }
189
 
190
+ date_default_timezone_set($current);
191
+
192
+ return $zones_array;
193
  }
194
 
195
  /**
198
  */
199
  function activate_mailchimp_woocommerce()
200
  {
201
+ // if we don't have woocommerce we need to display a horrible error message before the plugin is installed.
202
+ if (!is_plugin_active('woocommerce/woocommerce.php')) {
 
 
 
 
 
203
 
204
+ $active = false;
 
205
 
206
+ // some people may have uploaded a specific version of woo, so we need a fallback checker here.
207
+ foreach (array_keys(get_plugins()) as $plugin) {
208
+ if (mailchimp_string_contains($plugin, 'woocommerce.php')) {
209
+ $active = true;
210
+ break;
211
+ }
212
+ }
213
+
214
+ if (!$active) {
215
+ // Deactivate the plugin
216
+ deactivate_plugins(__FILE__);
217
+ $error_message = __('The MailChimp For WooCommerce plugin requires the <a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a> plugin to be active!', 'woocommerce');
218
+ wp_die($error_message);
219
+ }
220
+ }
221
+
222
+ // ok we can activate this thing.
223
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-activator.php';
224
+
225
+ MailChimp_Woocommerce_Activator::activate();
226
  }
227
 
228
  /**
230
  */
231
  function install_mailchimp_queue()
232
  {
233
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-activator.php';
234
+ MailChimp_Woocommerce_Activator::create_queue_tables();
235
  }
236
 
237
  /**
239
  * This action is documented in includes/class-mailchimp-woocommerce-deactivator.php
240
  */
241
  function deactivate_mailchimp_woocommerce() {
242
+ require_once plugin_dir_path( __FILE__ ) . 'includes/class-mailchimp-woocommerce-deactivator.php';
243
+ MailChimp_Woocommerce_Deactivator::deactivate();
244
  }
245
 
246
  /**
247
  * See if we need to run any updates.
248
  */
249
  function run_mailchimp_plugin_updater() {
250
+ if (!class_exists('PucFactory')) {
251
+ require plugin_dir_path( __FILE__ ) . 'includes/plugin-update-checker/plugin-update-checker.php';
252
+ }
253
+
254
+ /** @var \PucGitHubChecker_3_1 $checker */
255
+ $updater = PucFactory::getLatestClassVersion('PucGitHubChecker');
256
+
257
+ if (class_exists($updater)) {
258
+ $env = mailchimp_environment_variables();
259
+ $checker = new $updater('https://github.com/mailchimp/mc-woocommerce/', __FILE__, $env->repo, 1);
260
+ $checker->handleManualCheck();
261
+ }
262
+ }
263
 
264
+ function mailchimp_debug($action, $message, $data = null)
265
+ {
266
+ if (defined('WP_CLI') && WP_CLI) {
267
+ WP_CLI::debug(print_r(array('message' => $message, 'data' => $data), true));
268
  }
269
  }
270
 
278
  {
279
  $options = MailChimp_Woocommerce::getLoggingConfig();
280
 
281
+ if (!$options->enable_logging || !$options->account_id || !$options->username) {
282
+ return false;
283
+ }
284
 
285
+ if (defined('WP_CLI') && WP_CLI) {
286
+ WP_CLI::log(print_r(array('message' => $message, 'data' => $data), true));
287
+ return null;
288
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  }
290
 
291
  /**
297
  */
298
  function mailchimp_string_contains($haystack, $needles)
299
  {
300
+ foreach ((array) $needles as $needle) {
301
+ if ($needle != '' && mb_strpos($haystack, $needle) !== false) {
302
+ return true;
303
+ }
304
+ }
305
 
306
+ return false;
307
  }
308
 
309
 
311
  * @return int
312
  */
313
  function mailchimp_get_product_count() {
314
+ $posts = mailchimp_count_posts('product');
315
+ unset($posts['auto-draft'], $posts['trash']);
316
+ $total = 0;
317
+ foreach ($posts as $status => $count) {
318
+ $total += $count;
319
+ }
320
+ return $total;
321
  }
322
 
323
  /**
324
  * @return int
325
  */
326
  function mailchimp_get_order_count() {
327
+ $posts = mailchimp_count_posts('shop_order');
328
+ unset($posts['auto-draft'], $posts['trash']);
329
+ $total = 0;
330
+ foreach ($posts as $status => $count) {
331
+ $total += $count;
332
+ }
333
+ return $total;
334
  }
335
 
336
  /**
338
  * @return array|null|object
339
  */
340
  function mailchimp_count_posts($type) {
341
+ global $wpdb;
342
+ $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s GROUP BY post_status";
343
+ $posts = $wpdb->get_results( $wpdb->prepare($query, $type));
344
+ $response = array();
345
+ foreach ($posts as $post) {
346
+ $response[$post->post_status] = $post->num_posts;
347
+ }
348
+ return $response;
349
  }
350
 
351
  register_activation_hook( __FILE__, 'activate_mailchimp_woocommerce' );
368
  * @since 1.0.0
369
  */
370
  function run_mailchimp_woocommerce() {
371
+ $env = mailchimp_environment_variables();
372
+ $plugin = new MailChimp_Woocommerce($env->environment, $env->version);
373
+ $plugin->run();
374
  }
375
 
376
  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
377
+ $forwarded_address = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
378
+ $_SERVER['REMOTE_ADDR'] = $forwarded_address[0];
379
  }
380
 
381
  function mailchimp_woocommerce_add_meta_tags() {