MailChimp for WooCommerce - Version 2.1.10

Version Description

  • skip product when no variant can be loaded
  • better validation for the view order url
  • Add Initial sync label on Sync Tab
  • Multisite Delete and deactivate improvements
  • Mailchimp Order Notification issues support for downloadable and virtual products
  • http worker lock improvement
  • Add documentation about Multisite setup
  • Add documentaiton for on-demand syncing
Download this release

Release Info

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

Code changes from version 2.1.9 to 2.1.10

README.md CHANGED
@@ -1,105 +0,0 @@
1
- # MailChimp for Woocommerce Integration
2
-
3
- In this article, you’ll learn how to connect MailChimp for WooCommerce.
4
-
5
- ## Before You Start
6
-
7
- **Here are some things to know before you begin this process.**
8
-
9
- - For the most up-to-date install instructions, read [Connect or Disconnect MailChimp for WooCommerce](http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce).
10
-
11
- - This plugin requires you to have the [WooCommerce plugin](https://wordpress.org/plugins/woocommerce) already installed and activated in WordPress.
12
-
13
- - Your host environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
14
-
15
- - We recommend you use this plugin in a staging environment before installing it on production servers.
16
-
17
- - MailChimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
18
-
19
- - WooCommerce customers who haven't signed up for marketing emails will appear in the Transactional portion of your list, and cannot be exported.
20
-
21
- ## A Note for Current WooCommerce Integration Users
22
-
23
- 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. If your WooCommerce store is already integrated with MailChimp via an integration that runs on an older version of MailChimp’s API, consider your current sales volume before you make any changes that might disrupt business.
24
-
25
- You can run this new integration at the same time as your current WooCommerce integration for MailChimp. However, data from the older integration will display separately in subscriber profiles, and can’t be used with e-commerce features that require API 3.0.
26
-
27
- ## Task Roadmap
28
- **Here’s a brief overview of this multi-step process.**
29
-
30
- - Install the plugin on your WordPress Admin site.
31
- - Connect the plugin with your MailChimp API Key.
32
- - Configure your list settings to complete the data sync process.
33
- - Troubleshoot any sync or data feed issues by sharing logs with MailChimp support.
34
-
35
- ## Install the Plugin
36
- **To install the plugin, follow these steps.**
37
-
38
- 1) Log in to your WordPress admin panel.
39
- 2) In the left navigation panel, click **Plugins**, and choose **Add New**.
40
-
41
- ![Add new](https://cloud.githubusercontent.com/assets/6547700/18677991/a7622bcc-7f28-11e6-8e8c-9bbdfa9861c7.png)
42
-
43
- 3) Click **Upload Plugin**.
44
-
45
- ![Upload](https://cloud.githubusercontent.com/assets/6547700/18677997/a76dab82-7f28-11e6-98e4-4309739cd840.png)
46
-
47
- 4) Click **Choose File** to select the ZIP file for the plugin, then click **Install Now**.
48
-
49
- ![Install Now](https://cloud.githubusercontent.com/assets/6547700/18677988/a760949c-7f28-11e6-9e13-13c23d044ad4.png)
50
-
51
- 5) Click **Activate Plugin**.
52
-
53
- ![Activate plugin](https://cloud.githubusercontent.com/assets/6547700/18677990/a760d7c2-7f28-11e6-8741-12c1efa7a991.png)
54
-
55
- After you activate the plugin, you’ll be taken to the **Settings** page, where you will add your API key and configure your list settings.
56
-
57
- ## Configure and Sync
58
- **To configure your MailChimp settings for WooCommerce customers and sync them to MailChimp, follow these steps.**
59
-
60
- 1) On the **Connect** tab, paste your MailChimp API key into the field, choose whether or not you want to send debugging logs to MailChimp, and click **Save all changes**. To learn how to generate a MailChimp API Key, read [About API Keys](http://kb.mailchimp.com/integrations/api-integrations/about-api-keys).
61
-
62
- ![API key](https://cloud.githubusercontent.com/assets/19805049/18877771/3fca90e8-849c-11e6-9e3a-161a7b3936dd.png)
63
-
64
- 2) Navigate to the **Store Settings** tab.
65
-
66
- ![Store Settings](https://cloud.githubusercontent.com/assets/6547700/18677998/a76e5640-7f28-11e6-9fd3-d66949fa1413.png)
67
-
68
- 3) Enter the contact and location details for your WooCommerce Store, and click **Save all changes**.
69
-
70
- ![Save all changes](https://cloud.githubusercontent.com/assets/6547700/18677996/a76d126c-7f28-11e6-9150-4b289d20f057.png)
71
-
72
- 4) Navigate to the **List Settings** tab.
73
-
74
- ![List Settings tab](https://cloud.githubusercontent.com/assets/19805049/18878446/961221d0-849e-11e6-99bb-175c22bf921e.png)
75
-
76
- 5) Choose the list you want to sync, decide whether or not you want to auto-subscribe existing customers, set the subscribe message you want customers to see at checkout, and click **Save all changes**.
77
-
78
- ![Save all changes](https://cloud.githubusercontent.com/assets/19805049/18877772/3fd24162-849c-11e6-8442-79ec4550b8ac.png)
79
-
80
- All set! When you click **Save all changes**, we’ll start syncing your WooCommerce customers to MailChimp. To view progress, check the **Sync Status** tab.
81
-
82
- If you have no lists in your MailChimp account, you will be given the option to create a new list on the **List Defaults** tab. To create a new list, set your list defaults, and click **Save all Changes** when you’re done. We’ll create a MailChimp list for you, and begin the data sync.
83
-
84
- ![List Defaults tab](https://cloud.githubusercontent.com/assets/19805049/18956260/cffd3926-8628-11e6-9c68-9fe3c964c75c.png)
85
-
86
- ## Next Steps
87
- After you connect, you can do a lot with the the data you collect, like build segments, send Automation workflows, track purchases, and view results.
88
-
89
- Find out everything MailChimp has to offer in our article, [How to Use MailChimp for E-Commerce](http://kb.mailchimp.com/integrations/e-commerce/how-to-use-mailchimp-for-e-commerce).
90
-
91
- # Deactivate or Delete the Plugin
92
- When you deactivate MailChimp for WooCommerce, it stops the sync but doesn’t remove the plugin. You can always re-activate the sync, which will backfill data at a later point in time.
93
- To deactivate MailChimp for WooCommerce, follow these steps.
94
-
95
- 1) Log in to your WordPress admin panel.
96
-
97
- 2) In the left navigation panel, click **Plugins**, and choose **Installed Plugins**.
98
-
99
- ![Installed Plugins](https://cloud.githubusercontent.com/assets/6547700/18677993/a76542ee-7f28-11e6-99dd-cfd6c1f5c24a.png)
100
-
101
- 3) Click the box next to the MailChimp for WooCommerce plugin, and click **Deactivate**.
102
-
103
- ![Deactivate](https://cloud.githubusercontent.com/assets/6547700/18677992/a762b844-7f28-11e6-9679-8d6c6a1d731d.png)
104
-
105
- After you deactivate the plugin, you will have the option to **Delete** it. If you delete the plugin, you will retain customers’ email addresses in your list, but remove all associated e-commerce data.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.txt CHANGED
@@ -1,81 +1,79 @@
1
- === MailChimp for WooCommerce ===
2
- 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: 4.9.6
7
- Stable tag: 2.1.9
 
 
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
-
18
  - Sync list and purchase data.
19
  - Set up marketing automations to remind customers about items they left in their cart or viewed on your site, win back lapsed customers, and follow up post-purchase. (Now available for free accounts!)
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.
30
-
31
- You can run this new integration at the same time as your current WooCommerce integration for MailChimp. However, data from the older integration will display separately in subscriber profiles, and can’t be used with e-commerce features that require API 3.0.
32
-
33
  WordPress.com compatibility is limited to Business tier users only.
34
-
35
- At this time, the synchronization of product categories from WooCommerce to MailChimp is not supported.
36
-
37
- === Installation ===
38
  ###Before You Start
39
  Here are some things to know before you begin this process.
40
-
41
  - This plugin requires you to have the [WooCommerce plugin](https://woocommerce.com/) already installed and activated in WordPress.
42
  - Your hosting environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
43
  - We recommend you use this plugin in a staging environment before installing it on production servers. To learn more about staging environments, [check out these related Wordpress plugins](https://wordpress.org/plugins/search.php?q=staging).
44
- - MailChimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
45
  - WooCommerce customers who haven't signed up for marketing emails will appear in the **Transactional** portion of your list, and cannot be exported.
46
-
47
  ###Task Roadmap
48
- You’ll need to do a few things to connect your WooCommerce store to MailChimp.
49
-
50
  - Download the plugin.
51
  - Install the plugin on your WordPress Admin site.
52
- - Connect the plugin with your MailChimp API Key.
53
  - Configure your list settings to complete the data sync process.
54
-
55
  ###Advanced Queue Setup In CLI mode
56
- To optimize the performance of your MailChimp integration - it is recommended that you run the queue in CLI mode.
57
-
58
  First define a constant in your config file
59
-
60
  `define('DISABLE_WP_HTTP_WORKER', true);`
61
-
62
  You have 2 options to run this process:
63
-
64
  1. On a cron schedule every minute:
65
-
66
  `* * * * * /usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
67
-
68
  2. Using a process manager like Monit or Supervisord:
69
-
70
  `/usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
71
-
72
-
 
 
 
 
 
 
 
73
  == Changelog ==
 
 
 
 
 
 
 
 
 
74
  = 2.1.9 =
75
  * Improved UI feedback when API key is invalid
76
  * Add documentation about product categories not being supported.
77
  * Fix order count and order total with guest accounts.
78
-
79
  = 2.1.8 =
80
  * GDPR compliance
81
  * changed css class on checkbox for registration issues
@@ -87,10 +85,8 @@ You have 2 options to run this process:
87
  * fix logged in user abandoned cart tracking
88
  * WPML support
89
  * uninstall - reinstall clean ups
90
-
91
  = 2.1.7 =
92
  * fixed autoloader filepath for queue command
93
-
94
  = 2.1.6 =
95
  * moved to an autoloader for performance enhancement
96
  * flush database tables on un-installation to assist with stale records in the queue
@@ -102,21 +98,17 @@ You have 2 options to run this process:
102
  * fix the multisite network activation issue
103
  * hide the opt in checkbox for already logged in customers that were previously subscribed
104
  * miscellaneous UI enhancements
105
-
106
  = 2.1.5 =
107
  * is_configured filters applied before certain jobs were firing and failing.
108
-
109
  = 2.1.5 =
110
  * added support for Polish (zloty - zł) and Moldovan Leu currencies
111
  * update currency code for Belarusian Rouble
112
  * queue performance enhancement
113
-
114
  = 2.1.4 =
115
  * updated wordpress compatibility
116
  * updated sync details tab to show more informative stats
117
  * queue job processing performance enhancement
118
  * added an integrity check for queued jobs that were not getting processed
119
-
120
  = 2.1.3 =
121
  * Fix subscriber status for repeat transactional customers to stay transactional.
122
  * Remove shipping and billing address requirements for order submission.
@@ -124,128 +116,96 @@ You have 2 options to run this process:
124
  * Update newsletter checkbox style to be consistent with WooCommerce styles.
125
  * Make sure WooCommerce plugin is running before running any plugin code.
126
  * Fix compatibility issue with WP-Cron
127
-
128
  = 2.1.2 =
129
  * Fix store deletion on plugin deactivation
130
  * Correct shipping name is now used on order notifications.
131
  * Admin orders are now handled appropriately.
132
  * Skip incomplete or cancelled orders from being submitted when new.
133
  * fix hidden or inactive products from being recommended.
134
-
135
  = 2.1.1 =
136
  * To address performance issues previously reported, we've changed the action hook of "woocommerce_cart_updated" to use a filter "woocommerce_update_cart_action_cart_updated"
137
-
138
  = 2.1.0 =
139
  * Added Promo Code support.
140
-
141
  = 2.0.2 =
142
  * Added new logs feature to help troubleshoot isolated sync and data feed issues.
143
  * Fixed bug with setting customers as Transactional during checkout if they had already opted in previously.
144
  * Fixed bug where abandoned cart automation still fired after a customer completed an order.
145
-
146
  = 2.0.1 =
147
  * Added support for "Connected Site" scripts.
148
  * Made physical address a required field for store setup.
149
  * Fixed order, cart timestamps to begin using UTC.
150
-
151
- = 2.0 =
152
- * Support WooComerce 3.0
153
  * Support for manually uploaded WooCommerce
154
- * Fix for sync issues
155
  * Fix for guest orders sync issue
156
- * Remove MailChimp debug logger
157
-
158
- = 1.1.1 =
159
- * Support for site url changes
160
- * Fix for WP Version 4.4 compatibility issues
161
-
162
  = 1.1.0 =
163
  * Fix for persisting opt-in status
164
- * Pass order URLs to MailChimp
165
- * Pass partial refund status to MailChimp
166
-
167
  = 1.0.9 =
168
  * billing and shipping address support for orders
169
-
170
  = 1.0.8 =
171
  * add landing_site, financial status and discount information for orders
172
  * fix to support php 5.3
173
-
174
  = 1.0.7 =
175
  * add options to move, hide and change defaults for opt-in checkbox
176
  * add ability to re-sync and display connection details
177
  * support for subscriptions without orders
178
  * additional small fixes and some internal logging removal
179
-
180
  = 1.0.6 =
181
  * fixed conflict with the plugin updater where the class could not be loaded correctly.
182
  * fixed error validation for store name.
183
  * fixed cross device abandoned cart url's
184
-
185
  = 1.0.4 =
186
  * fix for Abandoned Carts without cookies
187
-
188
  = 1.0.3 =
189
  * fixed cart posts on dollar amounts greater than 1000
190
-
191
  = 1.0.2 =
192
  * title correction for Product Variants
193
  * added installation checks for WooCommerce and phone contact info
194
  * support for free orders
195
-
196
  = 1.0 =
197
  * added is_synicng flag to prevent sends during backfill
198
  * fix for conflicts with Gravity Forms Pro and installation issues
199
  * skip all Amazon orders
200
  * allow users to set opt-in for pre-existing customers during first sync
201
  * add Plugin Updater
202
-
203
  = 0.1.22 =
204
  * flag quantity as 1 if the product does not manage inventory
205
-
206
  = 0.1.21 =
207
  * php version check to display warnings < 5.5
208
-
209
  = 0.1.19 =
210
  * fix campaign tracking on new orders
211
-
212
  = 0.1.18 =
213
  * check woocommerce dependency before activating the plugin
214
-
215
  = 0.1.17 =
216
  * fix php version syntax errors for array's
217
-
218
  = 0.1.16 =
219
  * fix namespace conflicts
220
  * fix free order 0.00 issue
221
  * fix product variant naming issue
222
-
223
  = 0.1.15 =
224
- * adding special MailChimp header to requests
225
-
226
  = 0.1.14 =
227
  * removing jquery dependencies
228
-
229
  = 0.1.13 =
230
  * fixing a number format issue on total_spent
231
-
232
  = 0.1.12 =
233
  * skipping orders placed through amazon due to seller agreements
234
-
235
  = 0.1.11 =
236
  * removed an extra debug log that was not needed
237
-
238
  = 0.1.10 =
239
  * altered debug logging and fixed store settings validation requirements
240
-
241
  = 0.1.9 =
242
  * using fallback to stream context during failed patch requests
243
-
244
  = 0.1.8 =
245
  * fixing http request header for larger patch requests
246
-
247
  = 0.1.7 =
248
  * fixing various bugs with the sync and product issues.
249
-
250
  = 0.1.2 =
251
  * fixed admin order update hook.
1
+ === Mailchimp for WooCommerce ===
2
+ 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: 4.9.8
7
+ Stable tag: 2.1.10
8
+ Requires PHP: 5.6
9
+ WC tested up to: 3.4.5
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.
 
13
 
14
  == Description ==
15
+ 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.
16
+ With Mailchimp for WooCommerce, you’ll have the power to:
 
 
17
  - Sync list and purchase data.
18
  - Set up marketing automations to remind customers about items they left in their cart or viewed on your site, win back lapsed customers, and follow up post-purchase. (Now available for free accounts!)
19
  - Showcase product recommendations.
20
  - Track and segment customers based on purchase history and purchase frequency.
21
+ - View detailed data on your marketing performance in your Mailchimp Dashboard.
22
  - 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.
23
  - Automatically embed a pop-up form that converts your website visitors to subscribers.
24
  - Add discount codes created in WooCommerce to your emails and automations with a Promo Code content block
25
  - Create beautiful landing pages that make it easy to highlight your products, promote a sale or giveaway, and grow your list.
 
26
  ###Important Notes
27
+ 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.
28
+ You can run this new integration at the same time as your current WooCommerce integration for Mailchimp. However, data from the older integration will display separately in subscriber profiles, and can’t be used with e-commerce features that require API 3.0.
 
 
29
  WordPress.com compatibility is limited to Business tier users only.
30
+ At this time, the synchronization of product categories from WooCommerce to Mailchimp is not supported.
31
+ == Installation ==
 
 
32
  ###Before You Start
33
  Here are some things to know before you begin this process.
 
34
  - This plugin requires you to have the [WooCommerce plugin](https://woocommerce.com/) already installed and activated in WordPress.
35
  - Your hosting environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
36
  - We recommend you use this plugin in a staging environment before installing it on production servers. To learn more about staging environments, [check out these related Wordpress plugins](https://wordpress.org/plugins/search.php?q=staging).
37
+ - Mailchimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
38
  - WooCommerce customers who haven't signed up for marketing emails will appear in the **Transactional** portion of your list, and cannot be exported.
 
39
  ###Task Roadmap
40
+ You’ll need to do a few things to connect your WooCommerce store to Mailchimp.
 
41
  - Download the plugin.
42
  - Install the plugin on your WordPress Admin site.
43
+ - Connect the plugin with your Mailchimp API Key.
44
  - Configure your list settings to complete the data sync process.
 
45
  ###Advanced Queue Setup In CLI mode
46
+ To optimize the performance of your Mailchimp integration - it is recommended that you run the queue in CLI mode.
 
47
  First define a constant in your config file
 
48
  `define('DISABLE_WP_HTTP_WORKER', true);`
 
49
  You have 2 options to run this process:
 
50
  1. On a cron schedule every minute:
 
51
  `* * * * * /usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
 
52
  2. Using a process manager like Monit or Supervisord:
 
53
  `/usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
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.
60
+ - Deactivating - disables the plugin from sending data to Mailchimp. Upon reactivating the plugins original setup details will be intact. Deleting is necessary to connect a different Mailchimp list with WooCommerce.
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.10 =
65
+ * skip product when no variant can be loaded
66
+ * better validation for the view order url
67
+ * Add Initial sync label on Sync Tab
68
+ * Multisite Delete and deactivate improvements
69
+ * Mailchimp Order Notification issues support for downloadable and virtual products
70
+ * http worker lock improvement
71
+ * Add documentation about Multisite setup
72
+ * Add documentaiton for on-demand syncing
73
  = 2.1.9 =
74
  * Improved UI feedback when API key is invalid
75
  * Add documentation about product categories not being supported.
76
  * Fix order count and order total with guest accounts.
 
77
  = 2.1.8 =
78
  * GDPR compliance
79
  * changed css class on checkbox for registration issues
85
  * fix logged in user abandoned cart tracking
86
  * WPML support
87
  * uninstall - reinstall clean ups
 
88
  = 2.1.7 =
89
  * fixed autoloader filepath for queue command
 
90
  = 2.1.6 =
91
  * moved to an autoloader for performance enhancement
92
  * flush database tables on un-installation to assist with stale records in the queue
98
  * fix the multisite network activation issue
99
  * hide the opt in checkbox for already logged in customers that were previously subscribed
100
  * miscellaneous UI enhancements
 
101
  = 2.1.5 =
102
  * is_configured filters applied before certain jobs were firing and failing.
 
103
  = 2.1.5 =
104
  * added support for Polish (zloty - zł) and Moldovan Leu currencies
105
  * update currency code for Belarusian Rouble
106
  * queue performance enhancement
 
107
  = 2.1.4 =
108
  * updated wordpress compatibility
109
  * updated sync details tab to show more informative stats
110
  * queue job processing performance enhancement
111
  * added an integrity check for queued jobs that were not getting processed
 
112
  = 2.1.3 =
113
  * Fix subscriber status for repeat transactional customers to stay transactional.
114
  * Remove shipping and billing address requirements for order submission.
116
  * Update newsletter checkbox style to be consistent with WooCommerce styles.
117
  * Make sure WooCommerce plugin is running before running any plugin code.
118
  * Fix compatibility issue with WP-Cron
 
119
  = 2.1.2 =
120
  * Fix store deletion on plugin deactivation
121
  * Correct shipping name is now used on order notifications.
122
  * Admin orders are now handled appropriately.
123
  * Skip incomplete or cancelled orders from being submitted when new.
124
  * fix hidden or inactive products from being recommended.
 
125
  = 2.1.1 =
126
  * To address performance issues previously reported, we've changed the action hook of "woocommerce_cart_updated" to use a filter "woocommerce_update_cart_action_cart_updated"
 
127
  = 2.1.0 =
128
  * Added Promo Code support.
 
129
  = 2.0.2 =
130
  * Added new logs feature to help troubleshoot isolated sync and data feed issues.
131
  * Fixed bug with setting customers as Transactional during checkout if they had already opted in previously.
132
  * Fixed bug where abandoned cart automation still fired after a customer completed an order.
 
133
  = 2.0.1 =
134
  * Added support for "Connected Site" scripts.
135
  * Made physical address a required field for store setup.
136
  * Fixed order, cart timestamps to begin using UTC.
137
+ = 2.0 =
138
+ * Support WooComerce 3.0
 
139
  * Support for manually uploaded WooCommerce
140
+ * Fix for sync issues
141
  * Fix for guest orders sync issue
142
+ * Remove Mailchimp debug logger
143
+ = 1.1.1 =
144
+ * Support for site url changes
145
+ * Fix for WP Version 4.4 compatibility issues
 
 
146
  = 1.1.0 =
147
  * Fix for persisting opt-in status
148
+ * Pass order URLs to Mailchimp
149
+ * Pass partial refund status to Mailchimp
 
150
  = 1.0.9 =
151
  * billing and shipping address support for orders
 
152
  = 1.0.8 =
153
  * add landing_site, financial status and discount information for orders
154
  * fix to support php 5.3
 
155
  = 1.0.7 =
156
  * add options to move, hide and change defaults for opt-in checkbox
157
  * add ability to re-sync and display connection details
158
  * support for subscriptions without orders
159
  * additional small fixes and some internal logging removal
 
160
  = 1.0.6 =
161
  * fixed conflict with the plugin updater where the class could not be loaded correctly.
162
  * fixed error validation for store name.
163
  * fixed cross device abandoned cart url's
 
164
  = 1.0.4 =
165
  * fix for Abandoned Carts without cookies
 
166
  = 1.0.3 =
167
  * fixed cart posts on dollar amounts greater than 1000
 
168
  = 1.0.2 =
169
  * title correction for Product Variants
170
  * added installation checks for WooCommerce and phone contact info
171
  * support for free orders
 
172
  = 1.0 =
173
  * added is_synicng flag to prevent sends during backfill
174
  * fix for conflicts with Gravity Forms Pro and installation issues
175
  * skip all Amazon orders
176
  * allow users to set opt-in for pre-existing customers during first sync
177
  * add Plugin Updater
 
178
  = 0.1.22 =
179
  * flag quantity as 1 if the product does not manage inventory
 
180
  = 0.1.21 =
181
  * php version check to display warnings < 5.5
 
182
  = 0.1.19 =
183
  * fix campaign tracking on new orders
 
184
  = 0.1.18 =
185
  * check woocommerce dependency before activating the plugin
 
186
  = 0.1.17 =
187
  * fix php version syntax errors for array's
 
188
  = 0.1.16 =
189
  * fix namespace conflicts
190
  * fix free order 0.00 issue
191
  * fix product variant naming issue
 
192
  = 0.1.15 =
193
+ * adding special Mailchimp header to requests
 
194
  = 0.1.14 =
195
  * removing jquery dependencies
 
196
  = 0.1.13 =
197
  * fixing a number format issue on total_spent
 
198
  = 0.1.12 =
199
  * skipping orders placed through amazon due to seller agreements
 
200
  = 0.1.11 =
201
  * removed an extra debug log that was not needed
 
202
  = 0.1.10 =
203
  * altered debug logging and fixed store settings validation requirements
 
204
  = 0.1.9 =
205
  * using fallback to stream context during failed patch requests
 
206
  = 0.1.8 =
207
  * fixing http request header for larger patch requests
 
208
  = 0.1.7 =
209
  * fixing various bugs with the sync and product issues.
 
210
  = 0.1.2 =
211
  * fixed admin order update hook.
admin/class-mailchimp-woocommerce-admin.php CHANGED
@@ -69,12 +69,11 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
69
  */
70
  public function add_plugin_admin_menu() {
71
  add_menu_page(
72
- 'MailChimp - WooCommerce Setup',
73
- 'MailChimp',
74
  'manage_options',
75
  $this->plugin_name,
76
- array($this, 'display_plugin_setup_page'),
77
- 'data:image/svg+xml;base64,'.$this->mailchimp_svg()
78
  );
79
  }
80
 
@@ -83,22 +82,7 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
83
  */
84
  protected function mailchimp_svg()
85
  {
86
- return base64_encode('<?xml version="1.0" encoding="UTF-8"?>
87
- <svg width="111px" height="116px" viewBox="0 0 111 116" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
88
- <!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
89
- <title>Group</title>
90
- <desc>Created with Sketch.</desc>
91
- <defs></defs>
92
- <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
93
- <g id="Group">
94
- <path d="M76.5859,0.7017 L76.5849,0.7017 C71.6089,0.7017 65.7009,2.4987 59.7709,5.7927 C58.6459,4.8877 57.3339,3.8317 57.2839,3.7927 C55.0919,2.0667 52.4549,1.1907 49.4489,1.1897 C39.2019,1.1897 27.9399,11.1957 22.1389,17.1607 C12.9849,26.5727 5.6129,37.8427 2.4179,47.3087 C-1.5161,58.9627 1.8869,64.6287 5.4329,67.3307 L8.1899,69.4387 C6.2259,78.2517 11.1159,87.7027 19.6639,90.8437 C21.2849,91.4397 22.9629,91.7857 24.6639,91.8777 C28.2049,97.4237 41.6679,115.5347 66.4699,115.5417 C80.1529,115.5417 91.7799,109.9377 100.1089,99.3337 C105.7329,92.1747 108.1719,84.8867 108.8149,82.7097 C109.6379,81.3307 111.6759,77.2977 110.0739,73.4267 L110.0479,73.3637 L110.0189,73.3007 C109.1609,71.4697 107.6859,70.0227 105.8399,69.1577 C105.6629,68.5617 105.4829,68.0447 105.3149,67.6077 C106.7299,65.4787 107.0949,62.8477 106.2809,60.4207 C105.4089,57.8187 103.3169,55.7857 100.6029,54.8587 C98.0479,52.5407 95.7049,51.3697 93.9629,50.4987 L93.6009,50.3177 C93.1359,50.0857 92.8879,49.9617 92.6859,49.8647 C92.6089,49.1767 92.5369,48.3707 92.4619,47.5407 C92.2669,45.3737 92.0449,42.9177 91.6319,40.8417 C90.9369,37.3437 89.4899,34.6077 87.3279,32.6967 C86.8749,31.7957 86.2689,30.7457 85.4899,29.7127 C91.4609,19.6007 92.1439,10.1877 87.1759,4.8097 C84.6939,2.1217 81.0319,0.7017 76.5859,0.7017 M76.5859,3.7017 C80.0809,3.7017 83.0039,4.7137 84.9719,6.8447 C89.3919,11.6297 87.8029,20.7677 81.7689,30.0187 C83.0659,31.2507 84.1419,32.9257 84.9099,34.5887 C86.8279,36.0687 88.0709,38.3197 88.6899,41.4277 C89.3779,44.8837 89.5209,49.8057 89.9519,51.9207 C91.5789,52.6557 90.8869,52.3157 92.6209,53.1827 C94.4309,54.0867 96.6339,55.1877 99.0679,57.5307 C103.3969,58.6147 105.0489,63.2157 102.5169,66.3567 C102.4479,66.4407 102.1429,66.8027 101.8259,67.1627 C101.9009,67.3627 102.7319,68.7067 103.3309,71.4447 C105.1239,71.8687 106.5529,72.9727 107.3019,74.5737 C108.5989,77.7077 106.0479,81.4777 106.0479,81.4777 C105.9629,81.7547 97.9549,112.5417 66.4849,112.5417 L66.4709,112.5417 C39.2589,112.5337 26.3599,88.8807 26.3599,88.8807 C26.0989,88.8947 25.8389,88.9027 25.5799,88.9027 C23.8749,88.9027 22.2309,88.5907 20.6979,88.0277 C12.7149,85.0947 8.8839,75.9607 11.6389,68.2977 L7.2499,64.9447 C-8.0381,53.2977 29.3809,4.1887 49.4489,4.1897 C51.6919,4.1907 53.7189,4.8037 55.4309,6.1517 C55.5169,6.2197 59.4949,9.4217 59.4949,9.4217 C65.6079,5.7087 71.6629,3.7017 76.5849,3.7017 L76.5859,3.7017" id="Fill-40" fill="#FFFFFF"></path>
95
- <path d="M79.1367,27.5845 L79.1377,27.5835 C79.1297,27.5625 79.0647,27.3825 79.0387,27.3335 C78.0087,25.1455 75.6057,23.6175 73.4647,23.0045 C73.8397,23.3955 74.3827,24.1095 74.6037,24.5345 C72.9877,23.4245 70.8397,22.4465 68.5987,21.9825 C68.5987,21.9825 68.8657,22.1745 68.9117,22.2165 C69.3587,22.6325 69.9527,23.2905 70.1967,23.8555 C68.0547,22.9955 65.3467,22.5135 63.0297,22.9595 C62.9957,22.9655 62.7397,23.0265 62.7397,23.0265 C62.7397,23.0265 63.0407,23.1015 63.1087,23.1215 C63.8767,23.3495 64.9737,23.8175 65.4567,24.4595 C61.6097,23.7825 57.3767,24.5315 55.0947,25.8085 C55.3887,25.7955 55.3857,25.7945 55.6337,25.8015 C56.4727,25.8235 58.1647,25.9375 58.8747,26.3895 C56.4487,26.8825 52.9367,27.9685 51.0457,29.5945 C51.3787,29.5555 53.2737,29.3145 54.0487,29.4385 C43.6427,35.3935 38.9067,44.3965 38.9067,44.3965 C41.9747,40.3985 45.9547,36.5505 51.3827,33.0325 C63.2387,25.3485 75.0797,24.4655 79.1367,27.5845" id="Fill-42" fill="#FFFFFE"></path>
96
- <path d="M27.9473,80.7656 C26.3263,80.8026 25.4413,79.7896 25.6003,79.5686 C25.6743,79.4626 25.9213,79.5096 26.3013,79.5656 C28.3663,79.8866 29.6193,78.6266 29.9223,77.3066 C29.9263,77.2856 30.0083,76.9336 30.0043,76.6886 C30.0203,76.4766 29.9973,76.2606 29.9653,76.0676 C29.7203,74.7016 28.1543,74.4446 27.1473,73.3576 C26.2433,72.3756 26.4223,71.1166 26.9893,70.5126 C27.6723,69.8396 28.6483,70.0846 28.6353,70.3236 C28.6343,70.4496 28.3993,70.5446 28.1073,70.7446 C27.7283,71.0116 27.6783,71.2696 27.7743,71.7126 C27.8393,71.9556 27.9473,72.1156 28.1813,72.2996 C29.0283,72.9756 31.3043,73.4466 31.7183,75.7366 C32.1753,78.3656 30.2603,80.7166 27.9473,80.7656 M24.3623,68.1646 C23.9123,68.2606 24.1643,68.2056 23.7193,68.3306 C23.6503,68.3506 23.5873,68.3696 23.5323,68.3926 C23.3923,68.4586 23.2633,68.5036 23.1393,68.5696 C23.0363,68.6266 22.1513,69.0216 21.4313,69.9016 C20.4633,71.1046 20.1113,72.6796 20.1703,74.1956 C20.2283,75.6676 20.6603,76.4826 20.7403,76.6816 C21.0743,77.4006 20.2913,77.5476 19.5763,76.7756 L19.5743,76.7736 C19.0033,76.1676 18.6353,75.2456 18.4573,74.4276 L18.4573,74.4266 L18.4573,74.4276 C17.7313,71.0386 19.2443,67.6326 22.7353,66.2716 C22.9303,66.1946 23.1583,66.1466 23.3423,66.0926 L23.3413,66.0936 C23.6973,65.9876 24.9743,65.7286 26.2723,65.9306 C27.6973,66.1516 28.9563,66.8666 29.7543,67.7936 L29.7563,67.7956 C30.3703,68.4946 30.8333,69.4786 30.7503,70.3546 L30.7503,70.3566 C30.7193,70.7206 30.5573,71.2436 30.2293,71.3786 C30.1073,71.4286 29.9853,71.4026 29.8993,71.3186 C29.6623,71.0856 29.8453,70.6076 29.2663,69.7876 C28.4993,68.6996 26.7633,67.6566 24.3623,68.1646 M34.8423,74.1896 C34.9993,71.6386 34.5973,69.1156 33.8133,66.7166 C33.8133,66.7166 33.4683,68.1466 32.7823,69.8896 C32.1243,64.3126 29.7833,63.1316 29.7833,63.1316 C28.4263,62.5036 26.9273,62.1546 25.3503,62.1546 C19.2683,62.1546 14.3393,67.3446 14.3393,73.7476 C14.3393,80.1516 19.2683,85.3416 25.3503,85.3416 C32.2013,85.3416 37.4013,78.8196 36.1913,71.6936 C36.1913,71.6936 35.4923,73.3246 34.8423,74.1896" id="Fill-44" fill="#FFFFFF"></path>
97
- <path d="M55.2637,15.4038 C54.6187,15.8608 54.0497,16.2798 53.5687,16.6428 L50.2657,13.8778 L55.2637,15.4038 Z M57.7737,13.7038 C57.2307,14.0548 56.7147,14.3998 56.2307,14.7308 L55.3507,11.6728 L57.7737,13.7038 Z M18.5667,60.1648 L18.3907,60.1708 C22.0977,47.2248 32.0597,33.9258 42.2127,25.2628 C44.7447,23.1018 49.8377,19.6738 49.8377,19.6738 L44.0837,14.6028 L43.6637,11.6738 L51.5817,18.2108 C51.5807,18.2118 51.5797,18.2128 51.5797,18.2128 C51.2217,18.5058 50.8627,18.8068 50.5027,19.1138 C49.7227,19.7818 48.9407,20.4808 48.1597,21.2078 C47.0237,22.2638 45.8907,23.3788 44.7697,24.5368 C42.3547,27.0338 39.9957,29.7368 37.7857,32.5168 C33.8777,37.4318 32.2517,39.7248 29.7837,44.3968 C29.7727,44.4108 43.2807,28.2128 46.6437,24.8758 C52.8167,18.7528 62.9197,11.9348 63.0257,11.8738 C67.3387,9.2338 70.9807,7.6838 73.9687,7.0118 C69.0587,7.5128 63.8067,10.0368 59.6847,12.5108 C59.6777,12.5048 53.6927,7.4468 53.6847,7.4408 L51.4907,8.2808 L52.6747,12.5858 L51.2097,12.1118 L50.7927,10.4258 L51.4907,8.2808 C43.5097,6.3878 25.9397,19.6458 15.3837,36.4458 C11.1127,43.2428 5.1097,55.2008 8.5607,61.0238 C9.1437,62.0148 13.2437,65.0248 13.2867,65.0358 C14.8877,62.8148 16.7207,61.1818 18.5667,60.1648 Z" id="Fill-46" fill="#FFFFFF"></path>
98
- <path d="M62.7568,61.0156 C62.6058,60.8996 62.7548,60.4276 63.2788,59.9196 C63.7368,59.4816 64.2098,59.2346 64.7548,59.0046 C64.8408,58.9686 64.9288,58.9356 65.0208,58.9126 C65.2728,58.8456 65.5278,58.7596 65.8048,58.7176 C68.0218,58.3406 69.6438,59.5706 69.4328,59.9276 C69.3378,60.0936 68.9278,60.0566 68.3158,60.0156 C67.0468,59.9276 65.7148,59.9486 63.8318,60.7316 C63.2698,60.9576 62.9058,61.1346 62.7568,61.0156 M60.2968,57.2016 C59.4678,57.5176 58.8788,57.7626 58.5968,57.7206 C58.1368,57.6526 58.5818,56.8096 59.5878,55.9936 C61.6108,54.3786 64.3888,53.8776 66.7638,54.7616 C67.8028,55.1446 68.9698,55.9076 69.5798,56.8006 C69.8118,57.1386 69.8738,57.3946 69.7798,57.4996 C69.5938,57.7176 68.9288,57.4236 67.9448,57.0406 C65.4308,56.1026 63.5768,55.9596 60.2968,57.2016 M76.5508,58.4516 C76.8948,57.8226 77.8728,57.6966 78.7348,58.1676 C79.5958,58.6406 80.0158,59.5326 79.6708,60.1616 C79.3268,60.7886 78.3488,60.9156 77.4868,60.4436 C76.6258,59.9716 76.2058,59.0786 76.5508,58.4516 M80.1828,47.5176 L80.1818,47.5176 C80.1828,47.5176 80.1828,47.5176 80.1838,47.5176 C81.4978,47.0616 83.2388,50.4286 83.3188,53.4166 C82.2798,52.8976 81.0598,52.6766 79.8038,52.7856 C79.4878,51.8236 79.3368,50.9166 79.2998,49.9356 C79.2828,49.1196 79.4128,47.7686 80.1828,47.5176 M84.3258,57.6766 C84.1928,58.5366 83.5748,59.1536 82.9488,59.0556 C82.3218,58.9576 81.9228,58.1826 82.0578,57.3236 C82.1918,56.4636 82.8078,55.8466 83.4348,55.9446 C84.0608,56.0416 84.4598,56.8186 84.3258,57.6766 M101.6328,74.9486 C100.7498,74.9486 100.0828,75.1816 100.0828,75.1816 C100.0828,75.1816 100.0938,71.5046 98.3928,68.6416 C97.0818,70.1166 93.4438,73.0366 88.6678,75.3036 C84.1908,77.4296 78.2158,79.2906 70.8118,79.5376 C68.7378,79.6276 67.4548,79.2896 66.7338,81.7066 C66.6748,81.9226 66.6378,82.1646 66.6178,82.4116 C74.7338,84.9606 87.5698,79.9886 88.8158,79.6996 C88.8678,79.6876 88.9008,79.6806 88.9318,79.6796 C89.7358,79.7446 82.0398,84.5996 71.3608,84.5996 C69.5578,84.5996 68.0038,84.4426 66.7768,84.1966 C67.3608,86.1986 68.8858,87.0806 70.8948,87.5476 C72.4178,87.9026 74.0348,87.9366 74.0348,87.9366 C88.8308,88.3516 101.0058,76.8876 101.5088,76.2986 C101.5088,76.2986 101.3758,76.6096 101.3608,76.6446 C99.1918,81.5226 86.6338,90.3676 74.1338,90.1146 L74.0928,90.1276 C71.1948,90.1176 67.6718,89.3706 65.8408,87.1006 C62.9438,83.5076 64.4468,77.5356 69.0648,77.3946 C69.0698,77.3946 70.1318,77.3696 70.6048,77.3586 C82.0368,77.0066 92.2948,72.8066 99.6398,64.0356 C100.6498,62.7816 99.5218,61.0576 97.3328,61.0046 L97.3018,61.0046 C97.3018,61.0046 97.2888,60.9906 97.2808,60.9826 C94.6868,58.2026 92.4048,57.2216 90.3758,56.1906 C86.1208,54.0236 86.5218,55.8956 85.5308,45.3816 C85.2638,42.5476 84.7268,38.6816 82.2368,37.1996 C81.5838,36.8106 80.8708,36.6446 80.1298,36.6446 C79.3988,36.6446 79.0418,36.7936 78.8978,36.8256 C77.5338,37.1276 76.7578,37.9016 75.7858,38.7966 C71.1948,43.0306 67.5268,41.8816 62.0488,41.8326 C56.9048,41.7876 52.3628,45.3756 51.4948,50.8866 L51.4928,50.8896 C51.0708,53.7746 51.3448,56.7046 51.7958,58.0226 C51.7958,58.0226 50.4008,57.0936 49.7348,56.2716 C50.5398,61.3056 55.1328,64.5956 55.1328,64.5956 C54.4088,64.7616 53.3688,64.6926 53.3688,64.6926 C53.3728,64.6966 55.9898,66.7666 58.2618,67.4886 C57.6698,67.8566 54.6758,70.8106 53.1318,74.8776 C51.6878,78.6836 52.2758,83.2536 52.2758,83.2536 L53.5298,81.3826 C53.5298,81.3826 52.7108,85.5516 54.2968,89.5886 C54.8228,88.3886 55.9738,86.2446 55.9738,86.2446 C55.9738,86.2446 55.7908,90.7206 57.9458,94.3866 C58.0018,93.5406 58.3248,91.3866 58.3248,91.3866 C58.3248,91.3866 59.5628,95.2086 62.4188,97.8816 C67.7678,102.6276 81.9298,103.4856 92.7078,95.0156 C101.2448,88.3076 102.7358,80.2286 102.8788,79.9506 C104.9798,77.4306 104.4078,74.9486 101.6328,74.9486" id="Fill-48" fill="#FFFFFF"></path>
99
- </g>
100
- </g>
101
- </svg>');
102
  }
103
 
104
  /**
@@ -274,9 +258,12 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
274
  $data['mailchimp_account_info_id'] = $profile['account_id'];
275
  $data['mailchimp_account_info_username'] = $profile['username'];
276
  }
 
277
  } catch (Exception $e) {
278
  unset($data['mailchimp_api_key']);
279
  $data['active_tab'] = 'api_key';
 
 
280
  add_settings_error('mailchimp_store_settings', $e->getCode(), $e->getMessage());
281
  return $data;
282
  }
@@ -405,7 +392,7 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
405
  */
406
  protected function addInvalidAddressAlert()
407
  {
408
- add_settings_error('mailchimp_store_settings', '', 'As part of the MailChimp Terms of Use, we require a contact email and a physical mailing address.');
409
  }
410
 
411
  /**
@@ -413,7 +400,7 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
413
  */
414
  protected function addInvalidPhoneAlert()
415
  {
416
- add_settings_error('mailchimp_store_settings', '', 'As part of the MailChimp Terms of Use, we require a valid phone number for your store.');
417
  }
418
 
419
  /**
@@ -421,7 +408,7 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
421
  */
422
  protected function addInvalidStoreNameAlert()
423
  {
424
- add_settings_error('mailchimp_store_settings', '', 'MailChimp for WooCommerce requires a Store Name to connect your store.');
425
  }
426
 
427
  /**
@@ -538,32 +525,37 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
538
  ), $data);
539
  }
540
 
541
- /**
542
- * @param null|array $data
543
- * @return bool
544
- */
545
- public function hasValidApiKey($data = null)
 
 
546
  {
547
  if (!$this->validateOptions(array('mailchimp_api_key'), $data)) {
548
  return false;
549
  }
550
 
551
  if (($pinged = $this->getCached('api-ping-check', null)) === null) {
552
- if (($pinged = $this->api()->ping())) {
553
- $this->setCached('api-ping-check', true, 120);
554
- }
555
- return $pinged;
556
  }
 
557
  return $pinged;
558
  }
559
 
560
- /**
561
- * @return bool
562
- */
 
 
 
563
  public function hasValidMailChimpList()
564
  {
565
  if (!$this->hasValidApiKey()) {
566
- add_settings_error('mailchimp_api_key', '', 'You must supply your MailChimp API key to pull the lists.');
567
  return false;
568
  }
569
 
@@ -575,9 +567,10 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
575
  }
576
 
577
 
578
- /**
579
- * @return array|bool|mixed|null
580
- */
 
581
  public function getAccountDetails()
582
  {
583
  if (!$this->hasValidApiKey()) {
@@ -861,7 +854,7 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
861
  return true;
862
  }
863
 
864
- /**
865
  * Start the sync
866
  */
867
  private function startSync()
@@ -869,11 +862,11 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
869
  mailchimp_flush_sync_pointers();
870
 
871
  $coupon_sync = new MailChimp_WooCommerce_Process_Coupons();
872
- wp_queue($coupon_sync);
873
 
874
  $job = new MailChimp_WooCommerce_Process_Products();
875
  $job->flagStartSync();
876
- wp_queue($job);
877
  }
878
 
879
  /**
69
  */
70
  public function add_plugin_admin_menu() {
71
  add_menu_page(
72
+ 'Mailchimp - WooCommerce Setup',
73
+ 'Mailchimp',
74
  'manage_options',
75
  $this->plugin_name,
76
+ array($this, 'display_plugin_setup_page'), 'data:image/svg+xml;base64,'.$this->mailchimp_svg()
 
77
  );
78
  }
79
 
82
  */
83
  protected function mailchimp_svg()
84
  {
85
+ return base64_encode('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52.03 55"><defs><style>.cls-1{fill:#fff;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M11.64,28.54a4.75,4.75,0,0,0-1.17.08c-2.79.56-4.36,2.94-4.05,6a6.24,6.24,0,0,0,5.72,5.21,4.17,4.17,0,0,0,.8-.06c2.83-.48,3.57-3.55,3.1-6.57C15.51,29.83,13.21,28.63,11.64,28.54Zm2.77,8.07a1.17,1.17,0,0,1-1.1.55,1.53,1.53,0,0,1-1.37-1.58A4,4,0,0,1,12.23,34a1.44,1.44,0,0,0-.55-1.74,1.48,1.48,0,0,0-1.12-.21,1.44,1.44,0,0,0-.92.64,3.39,3.39,0,0,0-.34.79l0,.11c-.13.34-.33.45-.47.43s-.16-.05-.21-.21a3,3,0,0,1,.78-2.55,2.46,2.46,0,0,1,2.11-.76,2.5,2.5,0,0,1,1.91,1.39,3.19,3.19,0,0,1-.23,2.82l-.09.2A1.16,1.16,0,0,0,13,36a.74.74,0,0,0,.63.32,1.38,1.38,0,0,0,.34,0c.15,0,.3-.07.39,0A.24.24,0,0,1,14.41,36.61Z"/><path class="cls-1" d="M51,33.88a3.84,3.84,0,0,0-1.15-1l-.11-.37-.14-.42a5.57,5.57,0,0,0,.5-3.32,5.43,5.43,0,0,0-1.54-3,10.09,10.09,0,0,0-4.24-2.26c0-.67,0-1.43-.06-1.9a12.83,12.83,0,0,0-.49-3.25,10.46,10.46,0,0,0-1.3-2.92c2.14-2.56,3.29-5.21,3.29-7.57,0-3.83-3-6.3-7.59-6.3a19.3,19.3,0,0,0-7.22,1.6l-.34.14L28.7,1.52A6.31,6.31,0,0,0,24.43,0,14.07,14.07,0,0,0,17.6,2.2a36.93,36.93,0,0,0-6.78,5.21c-4.6,4.38-8.3,9.63-9.91,14A12.51,12.51,0,0,0,0,26.54a6.16,6.16,0,0,0,2.13,4.4l.78.66A10.44,10.44,0,0,0,2.74,35a9.36,9.36,0,0,0,3.21,6,10,10,0,0,0,5.13,2.43,20.19,20.19,0,0,0,7.31,8A23.33,23.33,0,0,0,30.17,55H31a23.27,23.27,0,0,0,12-3.16,19.1,19.1,0,0,0,7.82-9.06l0,0A16.89,16.89,0,0,0,52,37.23,5.17,5.17,0,0,0,51,33.88Zm-1.78,8.21c-3,7.29-10.3,11.35-19,11.09-8.06-.24-14.94-4.5-18-11.43a7.94,7.94,0,0,1-5.12-2.06,7.56,7.56,0,0,1-2.61-4.85A8.31,8.31,0,0,1,5,31L3.32,29.56C-4.42,23,19.77-3.86,27.51,2.89l2.64,2.58,1.44-.61c6.79-2.81,12.3-1.45,12.3,3,0,2.33-1.48,5.05-3.86,7.52a7.54,7.54,0,0,1,2,3.48,11,11,0,0,1,.42,2.82c0,1,.09,3.16.09,3.2l1,.27A8.64,8.64,0,0,1,47.2,27a3.66,3.66,0,0,1,1.06,2.06A4,4,0,0,1,47.55,32,10.15,10.15,0,0,1,48,33.08c.2.64.35,1.18.37,1.25.74,0,1.89.85,1.89,2.89A15.29,15.29,0,0,1,49.18,42.09Z"/><path class="cls-1" d="M48,36a1.36,1.36,0,0,0-.86-.16,11.76,11.76,0,0,0-.82-2.78A17.89,17.89,0,0,1,40.45,36a23.64,23.64,0,0,1-7.81.84c-1.69-.14-2.81-.63-3.23.74a18.3,18.3,0,0,0,8,.81.14.14,0,0,1,.16.13.15.15,0,0,1-.09.15s-3.14,1.46-8.14-.08a2.58,2.58,0,0,0,1.83,1.91,8.24,8.24,0,0,0,1.44.39c6.19,1.06,12-2.47,13.27-3.36.1-.07.16,0,.08.12l-.13.18c-1.59,2.06-5.88,4.44-11.45,4.44-2.43,0-4.86-.86-5.75-2.17-1.38-2-.07-5,2.24-4.71l1,.11a21.13,21.13,0,0,0,10.5-1.68c3.15-1.46,4.34-3.07,4.16-4.37A1.87,1.87,0,0,0,46,28.34a6.8,6.8,0,0,0-3-1.41c-.5-.14-.84-.23-1.2-.35-.65-.21-1-.39-1-1.61,0-.53-.12-2.4-.16-3.16-.06-1.35-.22-3.19-1.36-4a1.92,1.92,0,0,0-1-.31,1.86,1.86,0,0,0-.58.06,3.07,3.07,0,0,0-1.52.86,5.24,5.24,0,0,1-4,1.32c-.8,0-1.65-.16-2.62-.22l-.57,0a5.22,5.22,0,0,0-5,4.57c-.56,3.83,2.22,5.81,3,7a1,1,0,0,1,.22.52.83.83,0,0,1-.28.55h0a9.8,9.8,0,0,0-2.16,9.2,7.59,7.59,0,0,0,.41,1.12c2,4.73,8.3,6.93,14.43,4.93a15.06,15.06,0,0,0,2.33-1,12.23,12.23,0,0,0,3.57-2.67,10.61,10.61,0,0,0,3-5.82C48.6,36.7,48.33,36.23,48,36Zm-8.25-7.82c0,.5-.31.91-.68.9s-.66-.42-.65-.92.31-.91.68-.9S39.72,27.68,39.71,28.18Zm-1.68-6c.71-.12,1.06.62,1.32,1.85a3.64,3.64,0,0,1-.05,2,4.14,4.14,0,0,0-1.06,0,4.13,4.13,0,0,1-.68-1.64C37.29,23.23,37.31,22.34,38,22.23Zm-2.4,6.57a.82.82,0,0,1,1.11-.19c.45.22.69.67.53,1a.82.82,0,0,1-1.11.19C35.7,29.58,35.47,29.13,35.63,28.8Zm-2.8-.37c-.07.11-.23.09-.57.06a4.24,4.24,0,0,0-2.14.22,2,2,0,0,1-.49.14.16.16,0,0,1-.11,0,.15.15,0,0,1-.05-.12.81.81,0,0,1,.32-.51,2.41,2.41,0,0,1,1.27-.53,1.94,1.94,0,0,1,1.75.57A.19.19,0,0,1,32.83,28.43Zm-5.11-1.26c-.12,0-.17-.07-.19-.14s.28-.56.62-.81a3.6,3.6,0,0,1,3.51-.42A3,3,0,0,1,33,26.87c.12.2.15.35.07.44s-.44,0-.95-.24a4.18,4.18,0,0,0-2-.43A21.85,21.85,0,0,0,27.71,27.17Z"/><path class="cls-1" d="M35.5,13.29c.1,0,.16-.15.07-.2a11,11,0,0,0-4.69-1.23.09.09,0,0,1-.07-.14,4.78,4.78,0,0,1,.88-.89.09.09,0,0,0-.06-.16,12.46,12.46,0,0,0-5.61,2,.09.09,0,0,1-.13-.09,6.16,6.16,0,0,1,.59-1.45.08.08,0,0,0-.11-.11A22.79,22.79,0,0,0,20,16.24a.09.09,0,0,0,.12.13A19.53,19.53,0,0,1,27,13.32,19.1,19.1,0,0,1,35.5,13.29Z"/><path class="cls-1" d="M28.34,6.42S26.23,4,25.6,3.8C21.69,2.74,13.24,8.57,7.84,16.27,5.66,19.39,2.53,24.9,4,27.74a11.43,11.43,0,0,0,1.79,1.72A6.65,6.65,0,0,1,10,26.78,34.21,34.21,0,0,1,20.8,11.62,55.09,55.09,0,0,1,28.34,6.42Z"/></g></g></svg>');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
 
88
  /**
258
  $data['mailchimp_account_info_id'] = $profile['account_id'];
259
  $data['mailchimp_account_info_username'] = $profile['username'];
260
  }
261
+ $data['api_ping_error'] = false;
262
  } catch (Exception $e) {
263
  unset($data['mailchimp_api_key']);
264
  $data['active_tab'] = 'api_key';
265
+ $data['api_ping_error'] = $e->getCode().' :: '.$e->getMessage().' on '.$e->getLine().' in '.$e->getFile();
266
+ mailchimp_error('admin@validatePostApiKey', $e->getCode().' :: '.$e->getMessage().' on '.$e->getLine().' in '.$e->getFile());
267
  add_settings_error('mailchimp_store_settings', $e->getCode(), $e->getMessage());
268
  return $data;
269
  }
392
  */
393
  protected function addInvalidAddressAlert()
394
  {
395
+ add_settings_error('mailchimp_store_settings', '', 'As part of the Mailchimp Terms of Use, we require a contact email and a physical mailing address.');
396
  }
397
 
398
  /**
400
  */
401
  protected function addInvalidPhoneAlert()
402
  {
403
+ add_settings_error('mailchimp_store_settings', '', 'As part of the Mailchimp Terms of Use, we require a valid phone number for your store.');
404
  }
405
 
406
  /**
408
  */
409
  protected function addInvalidStoreNameAlert()
410
  {
411
+ add_settings_error('mailchimp_store_settings', '', 'Mailchimp for WooCommerce requires a Store Name to connect your store.');
412
  }
413
 
414
  /**
525
  ), $data);
526
  }
527
 
528
+ /**
529
+ * @param null $data
530
+ * @param bool $throw_if_not_valid
531
+ * @return array|bool|mixed|null|object
532
+ * @throws Exception
533
+ */
534
+ public function hasValidApiKey($data = null, $throw_if_not_valid = false)
535
  {
536
  if (!$this->validateOptions(array('mailchimp_api_key'), $data)) {
537
  return false;
538
  }
539
 
540
  if (($pinged = $this->getCached('api-ping-check', null)) === null) {
541
+ if (($pinged = $this->api()->ping(false, $throw_if_not_valid === true))) {
542
+ $this->setCached('api-ping-check', true, 120);
543
+ }
 
544
  }
545
+
546
  return $pinged;
547
  }
548
 
549
+ /**
550
+ * @return array|bool|mixed|null|object
551
+ * @throws Exception
552
+ * @throws MailChimp_WooCommerce_Error
553
+ * @throws MailChimp_WooCommerce_ServerError
554
+ */
555
  public function hasValidMailChimpList()
556
  {
557
  if (!$this->hasValidApiKey()) {
558
+ add_settings_error('mailchimp_api_key', '', 'You must supply your Mailchimp API key to pull the lists.');
559
  return false;
560
  }
561
 
567
  }
568
 
569
 
570
+ /**
571
+ * @return array|bool|mixed|null|object
572
+ * @throws Exception
573
+ */
574
  public function getAccountDetails()
575
  {
576
  if (!$this->hasValidApiKey()) {
854
  return true;
855
  }
856
 
857
+ /**a:4:{s:19:"mailchimp_debugging";b:0;s:25:"mailchimp_account_info_id";N;s:31:"mailchimp_account_info_username";N;s:10:"active_tab";s:7:"api_key";}
858
  * Start the sync
859
  */
860
  private function startSync()
862
  mailchimp_flush_sync_pointers();
863
 
864
  $coupon_sync = new MailChimp_WooCommerce_Process_Coupons();
865
+ mailchimp_handle_or_queue($coupon_sync);
866
 
867
  $job = new MailChimp_WooCommerce_Process_Products();
868
  $job->flagStartSync();
869
+ mailchimp_handle_or_queue($job);
870
  }
871
 
872
  /**
admin/partials/mailchimp-woocommerce-admin-tabs.php CHANGED
@@ -15,20 +15,25 @@ $show_sync_tab = isset($_GET['resync']) ? $_GET['resync'] === '1' : false;;
15
  $show_campaign_defaults = true;
16
  $has_valid_api_key = false;
17
  $allow_new_list = true;
18
-
19
  $clicked_sync_button = $is_mailchimp_post&& $active_tab == 'sync';
20
-
21
- if (isset($options['mailchimp_api_key']) && $handler->hasValidApiKey()) {
22
- $has_valid_api_key = true;
23
- // if we don't have a valid api key we need to redirect back to the 'api_key' tab.
24
- if (($mailchimp_lists = $handler->getMailChimpLists()) && is_array($mailchimp_lists)) {
25
- $show_campaign_defaults = false;
26
- $allow_new_list = false;
27
- }
28
-
29
- // only display this button if the data is not syncing and we have a valid api key
30
- if ((bool) $this->getData('sync.started_at', false)) {
31
- $show_sync_tab = true;
 
 
 
 
 
 
32
  }
33
  }
34
  ?>
@@ -62,14 +67,20 @@ if (isset($options['mailchimp_api_key']) && $handler->hasValidApiKey()) {
62
 
63
  <?php if (!defined('PHP_VERSION_ID') || (PHP_VERSION_ID < 70000)): ?>
64
  <div data-dismissible="notice-php-version" class="error notice notice-error is-dismissible">
65
- <p><?php _e('MailChimp says: Please upgrade your PHP version to a minimum of 7.0', 'mailchimp-woocommerce'); ?></p>
 
 
 
 
 
 
66
  </div>
67
  <?php endif; ?>
68
 
69
  <!-- Create a header in the default WordPress 'wrap' container -->
70
  <div class="wrap">
71
  <div id="icon-themes" class="icon32"></div>
72
- <h2>MailChimp Settings</h2>
73
 
74
  <h2 class="nav-tab-wrapper">
75
  <a href="?page=mailchimp-woocommerce&tab=api_key" class="nav-tab <?php echo $active_tab == 'api_key' ? 'nav-tab-active' : ''; ?>">Connect</a>
@@ -135,9 +146,9 @@ if (isset($options['mailchimp_api_key']) && $handler->hasValidApiKey()) {
135
  <ul>
136
  <li>Have a larger store or having issues syncing? Consider using <a href="https://github.com/mailchimp/mc-woocommerce/issues/158" target="_blank">WP-CLI</a>.</li>
137
  <li>Order and customer information will not sync if they contain an Amazon or generic email address.</li>
138
- <li>Need help to connect your store? Visit the MailChimp <a href="http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce/" target="_blank">Knowledge Base</a>.</li>
139
  <li>Want to tell us how we're doing? <a href="https://wordpress.org/support/plugin/mailchimp-for-woocommerce/reviews/" target="_blank">Leave a review on Wordpress.org</a>.</li>
140
- <li>By using this plugin, MailChimp will process customer information in accordance with their <a href="https://mailchimp.com/legal/privacy/ " target="_blank">Privacy Policy</a>.</li>
141
  </ul>
142
  <?php endif; ?>
143
 
15
  $show_campaign_defaults = true;
16
  $has_valid_api_key = false;
17
  $allow_new_list = true;
 
18
  $clicked_sync_button = $is_mailchimp_post&& $active_tab == 'sync';
19
+ $has_api_error = isset($options['api_ping_error']) && !empty($options['api_ping_error']) ? $options['api_ping_error'] : null;
20
+
21
+ if (isset($options['mailchimp_api_key'])) {
22
+ try {
23
+ if ($handler->hasValidApiKey(null, true)) {
24
+ $has_valid_api_key = true;
25
+ // if we don't have a valid api key we need to redirect back to the 'api_key' tab.
26
+ if (($mailchimp_lists = $handler->getMailChimpLists()) && is_array($mailchimp_lists)) {
27
+ $show_campaign_defaults = false;
28
+ $allow_new_list = false;
29
+ }
30
+ // only display this button if the data is not syncing and we have a valid api key
31
+ if ((bool) $this->getData('sync.started_at', false)) {
32
+ $show_sync_tab = true;
33
+ }
34
+ }
35
+ } catch (\Exception $e) {
36
+ $has_api_error = $e->getMessage().' on '.$e->getLine().' in '.$e->getFile();
37
  }
38
  }
39
  ?>
67
 
68
  <?php if (!defined('PHP_VERSION_ID') || (PHP_VERSION_ID < 70000)): ?>
69
  <div data-dismissible="notice-php-version" class="error notice notice-error is-dismissible">
70
+ <p><?php _e('Mailchimp says: Please upgrade your PHP version to a minimum of 7.0', 'mailchimp-woocommerce'); ?></p>
71
+ </div>
72
+ <?php endif; ?>
73
+
74
+ <?php if (!empty($has_api_error)): ?>
75
+ <div data-dismissible="notice-api-error" class="error notice notice-error is-dismissible">
76
+ <p><?php _e("Mailchimp says: API Request Error - ".$has_api_error, 'mailchimp-woocommerce'); ?></p>
77
  </div>
78
  <?php endif; ?>
79
 
80
  <!-- Create a header in the default WordPress 'wrap' container -->
81
  <div class="wrap">
82
  <div id="icon-themes" class="icon32"></div>
83
+ <h2>Mailchimp Settings</h2>
84
 
85
  <h2 class="nav-tab-wrapper">
86
  <a href="?page=mailchimp-woocommerce&tab=api_key" class="nav-tab <?php echo $active_tab == 'api_key' ? 'nav-tab-active' : ''; ?>">Connect</a>
146
  <ul>
147
  <li>Have a larger store or having issues syncing? Consider using <a href="https://github.com/mailchimp/mc-woocommerce/issues/158" target="_blank">WP-CLI</a>.</li>
148
  <li>Order and customer information will not sync if they contain an Amazon or generic email address.</li>
149
+ <li>Need help to connect your store? Visit the Mailchimp <a href="http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce/" target="_blank">Knowledge Base</a>.</li>
150
  <li>Want to tell us how we're doing? <a href="https://wordpress.org/support/plugin/mailchimp-for-woocommerce/reviews/" target="_blank">Leave a review on Wordpress.org</a>.</li>
151
+ <li>By using this plugin, Mailchimp will process customer information in accordance with their <a href="https://mailchimp.com/legal/privacy/ " target="_blank">Privacy Policy</a>.</li>
152
  </ul>
153
  <?php endif; ?>
154
 
admin/partials/tabs/api_key.php CHANGED
@@ -1,25 +1,15 @@
1
-
2
-
3
-
4
- <?php
5
-
6
- if (isset($options['mailchimp_api_key']) && !$handler->hasValidApiKey()) {
7
- // we need to fix this.
8
- }
9
-
10
- ?>
11
  <input type="hidden" name="mailchimp_active_settings_tab" value="api_key"/>
12
 
13
  <h2 style="padding-top: 1em;">API Information</h2>
14
- <p>To find your MailChimp API key, log into your account settings > Extras > API keys. From there, either grab an existing key or generate a new one for your WooCommerce store. </p>
15
 
16
  <!-- remove some meta and generators from the <head> -->
17
  <fieldset>
18
  <legend class="screen-reader-text">
19
- <span>MailChimp API Key</span>
20
  </legend>
21
  <label for="<?php echo $this->plugin_name; ?>-mailchimp-api-key">
22
  <input style="width: 30%;" type="password" id="<?php echo $this->plugin_name; ?>-mailchimp-api-key" name="<?php echo $this->plugin_name; ?>[mailchimp_api_key]" value="<?php echo isset($options['mailchimp_api_key']) ? $options['mailchimp_api_key'] : '' ?>" />
23
- <span><?php esc_attr_e('Enter your MailChimp API key.', $this->plugin_name); ?></span>
24
  </label>
25
  </fieldset>
 
 
 
 
 
 
 
 
 
 
1
  <input type="hidden" name="mailchimp_active_settings_tab" value="api_key"/>
2
 
3
  <h2 style="padding-top: 1em;">API Information</h2>
4
+ <p>To find your Mailchimp API key, log into your account settings > Extras > API keys. From there, either grab an existing key or generate a new one for your WooCommerce store. </p>
5
 
6
  <!-- remove some meta and generators from the <head> -->
7
  <fieldset>
8
  <legend class="screen-reader-text">
9
+ <span>Mailchimp API Key</span>
10
  </legend>
11
  <label for="<?php echo $this->plugin_name; ?>-mailchimp-api-key">
12
  <input style="width: 30%;" type="password" id="<?php echo $this->plugin_name; ?>-mailchimp-api-key" name="<?php echo $this->plugin_name; ?>[mailchimp_api_key]" value="<?php echo isset($options['mailchimp_api_key']) ? $options['mailchimp_api_key'] : '' ?>" />
13
+ <span><?php esc_attr_e('Enter your Mailchimp API key.', $this->plugin_name); ?></span>
14
  </label>
15
  </fieldset>
admin/partials/tabs/logs.php CHANGED
@@ -36,7 +36,7 @@ $handle = !empty($viewed_log) ? substr($viewed_log, 0, strlen($viewed_log) > 37
36
  <p>
37
  Advanced troubleshooting can be conducted with the logging capability turned on.
38
  By default, it’s set to “none” and you may toggle to either “standard” or “debug” as needed.
39
- With standard logging, you can see basic information about the data submission to MailChimp including any errors.
40
  “Debug” gives a much deeper insight that is useful to share with support if problems arise.
41
  </p>
42
  <fieldset>
36
  <p>
37
  Advanced troubleshooting can be conducted with the logging capability turned on.
38
  By default, it’s set to “none” and you may toggle to either “standard” or “debug” as needed.
39
+ With standard logging, you can see basic information about the data submission to Mailchimp including any errors.
40
  “Debug” gives a much deeper insight that is useful to share with support if problems arise.
41
  </p>
42
  <fieldset>
admin/partials/tabs/notices.php CHANGED
@@ -3,19 +3,19 @@
3
  <?php
4
  switch($_GET['error_notice']) {
5
  case 'missing_api_key':
6
- _e('MailChimp says: You must enter in a valid API key.', 'mailchimp-woocommerce');
7
  break;
8
  case 'missing_campaign_defaults':
9
- _e('MailChimp says: Sorry you must set up your campaign defaults before you proceed!', 'mailchimp-woocommerce');
10
  break;
11
  case 'missing_list':
12
- _e('MailChimp says: You must select a marketing list.', 'mailchimp-woocommerce');
13
  break;
14
  case 'missing_store':
15
- _e('MailChimp says: Sorry you must set up your store before you proceed!', 'mailchimp-woocommerce');
16
  break;
17
  case 'not_ready_for_sync':
18
- _e('MailChimp says: You are not fully ready to run the Store Sync, please verify your settings before proceeding.', 'mailchimp-woocommerce');
19
  break;
20
  default:
21
 
@@ -29,7 +29,7 @@
29
  <?php
30
  switch($_GET['error_notice']) {
31
  case 're-sync-started':
32
- _e('MailChimp says: Your re-sync has been started!', 'mailchimp-woocommerce');
33
  break;
34
  default:
35
  }
3
  <?php
4
  switch($_GET['error_notice']) {
5
  case 'missing_api_key':
6
+ _e('Mailchimp says: You must enter in a valid API key.', 'mailchimp-woocommerce');
7
  break;
8
  case 'missing_campaign_defaults':
9
+ _e('Mailchimp says: Sorry you must set up your campaign defaults before you proceed!', 'mailchimp-woocommerce');
10
  break;
11
  case 'missing_list':
12
+ _e('Mailchimp says: You must select a marketing list.', 'mailchimp-woocommerce');
13
  break;
14
  case 'missing_store':
15
+ _e('Mailchimp says: Sorry you must set up your store before you proceed!', 'mailchimp-woocommerce');
16
  break;
17
  case 'not_ready_for_sync':
18
+ _e('Mailchimp says: You are not fully ready to run the Store Sync, please verify your settings before proceeding.', 'mailchimp-woocommerce');
19
  break;
20
  default:
21
 
29
  <?php
30
  switch($_GET['error_notice']) {
31
  case 're-sync-started':
32
+ _e('Mailchimp says: Your re-sync has been started!', 'mailchimp-woocommerce');
33
  break;
34
  default:
35
  }
admin/partials/tabs/store_sync.php CHANGED
@@ -47,12 +47,8 @@ if (($mailchimp_api = mailchimp_get_api()) && ($store = $mailchimp_api->getStore
47
 
48
  <h2 style="padding-top: 1em;">Sync Information</h2>
49
 
50
- <?php if ($sync_started_at): ?>
51
- <p><strong>Started:</strong> <i><?php echo $sync_started_at->format('D, M j, Y g:i A'); ?></i></p>
52
- <?php endif; ?>
53
-
54
- <?php if ($sync_completed_at): ?>
55
- <p><strong>Finished:</strong> <i><?php echo $sync_completed_at->format('D, M j, Y g:i A'); ?></i></p>
56
  <?php endif; ?>
57
 
58
  <?php if ($last_updated_time): ?>
47
 
48
  <h2 style="padding-top: 1em;">Sync Information</h2>
49
 
50
+ <?php if ($sync_started_at && !$sync_completed_at): ?>
51
+ <p><strong>Initial Sync:</strong> <i>In Progress</i></p>
 
 
 
 
52
  <?php endif; ?>
53
 
54
  <?php if ($last_updated_time): ?>
bootstrap.php CHANGED
@@ -87,7 +87,7 @@ function mailchimp_environment_variables() {
87
  return (object) array(
88
  'repo' => 'master',
89
  'environment' => 'production',
90
- 'version' => '2.1.9',
91
  'php_version' => phpversion(),
92
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
93
  'wc_version' => class_exists('WC') ? WC()->version : null,
@@ -109,12 +109,12 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
109
  switch($args[0]) {
110
 
111
  case 'product_sync':
112
- wp_queue(new MailChimp_WooCommerce_Process_Products());
113
  WP_CLI::success("queued up the product sync!");
114
  break;
115
 
116
  case 'order_sync':
117
- wp_queue(new MailChimp_WooCommerce_Process_Orders());
118
  WP_CLI::success("queued up the order sync!");
119
  break;
120
 
@@ -122,7 +122,7 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
122
  if (!isset($args[1])) {
123
  wp_die('You must specify an order id as the 2nd parameter.');
124
  }
125
- wp_queue(new MailChimp_WooCommerce_Single_Order($args[1]));
126
  WP_CLI::success("queued up the order {$args[1]}!");
127
  break;
128
 
@@ -130,7 +130,7 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
130
  if (!isset($args[1])) {
131
  wp_die('You must specify a product id as the 2nd parameter.');
132
  }
133
- wp_queue(new MailChimp_WooCommerce_Single_Product($args[1]));
134
  WP_CLI::success("queued up the product {$args[1]}!");
135
  break;
136
  }
@@ -158,14 +158,104 @@ if (!function_exists( 'wp_queue')) {
158
  }
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  /**
163
  * @return bool
164
  */
165
  function mailchimp_should_init_queue() {
166
- return mailchimp_detect_admin_ajax() && mailchimp_is_configured() && !mailchimp_running_in_console() && !mailchimp_http_worker_is_running();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  * @return bool
171
  */
@@ -328,11 +418,9 @@ function mailchimp_check_woocommerce_plugin_status()
328
  if (in_array('woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option('active_plugins')))) {
329
  return true;
330
  }
331
- // lets check for network activation woo installs now too.
332
- if (function_exists('is_plugin_active_for_network')) {
333
- return is_plugin_active_for_network( 'woocommerce/woocommerce.php');
334
- }
335
- return false;
336
  }
337
 
338
  /**
@@ -372,18 +460,33 @@ function mailchimp_woocommerce_get_all_image_sizes_list() {
372
  }
373
 
374
  /**
375
- * The code that runs during plugin activation.
376
- * This action is documented in includes/class-mailchimp-woocommerce-activator.php
377
  */
378
- function activate_mailchimp_woocommerce() {
379
- // if we don't have woocommerce we need to display a horrible error message before the plugin is installed.
380
- if (!mailchimp_check_woocommerce_plugin_status()) {
381
- // Deactivate the plugin
382
- deactivate_plugins(__FILE__);
383
- $error_message = __('The MailChimp For WooCommerce plugin requires the <a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a> plugin to be active!', 'woocommerce');
384
- wp_die($error_message);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  }
386
- MailChimp_WooCommerce_Activator::activate();
387
  }
388
 
389
  /**
@@ -585,13 +688,37 @@ function mailchimp_running_in_console() {
585
  return (bool) (defined( 'DISABLE_WP_HTTP_WORKER' ) && true === DISABLE_WP_HTTP_WORKER);
586
  }
587
 
 
 
 
 
 
 
 
588
  /**
589
  * @return bool
590
  */
591
  function mailchimp_http_worker_is_running() {
 
 
 
 
 
592
  return (bool) get_site_transient('http_worker_lock');
593
  }
594
 
 
 
 
 
 
 
 
 
 
 
 
 
595
  /**
596
  * @param $email
597
  * @return bool
@@ -636,6 +763,97 @@ function mailchimp_call_http_worker_manually() {
636
  return wp_remote_post(esc_url_raw($url), $post_args);
637
  }
638
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  function mailchimp_flush_queue_tables() {
640
  try {
641
  /** @var \ */
87
  return (object) array(
88
  'repo' => 'master',
89
  'environment' => 'production',
90
+ 'version' => '2.1.10',
91
  'php_version' => phpversion(),
92
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
93
  'wc_version' => class_exists('WC') ? WC()->version : null,
109
  switch($args[0]) {
110
 
111
  case 'product_sync':
112
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Products());
113
  WP_CLI::success("queued up the product sync!");
114
  break;
115
 
116
  case 'order_sync':
117
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
118
  WP_CLI::success("queued up the order sync!");
119
  break;
120
 
122
  if (!isset($args[1])) {
123
  wp_die('You must specify an order id as the 2nd parameter.');
124
  }
125
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Order($args[1]));
126
  WP_CLI::success("queued up the order {$args[1]}!");
127
  break;
128
 
130
  if (!isset($args[1])) {
131
  wp_die('You must specify a product id as the 2nd parameter.');
132
  }
133
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($args[1]));
134
  WP_CLI::success("queued up the product {$args[1]}!");
135
  break;
136
  }
158
  }
159
  }
160
 
161
+ /**
162
+ * @param WP_Job $job
163
+ * @param $delay
164
+ */
165
+ function mailchimp_handle_or_queue(WP_Job $job, $delay = 0)
166
+ {
167
+ wp_queue($job, $delay);
168
+ if (mailchimp_queue_is_disabled()) {
169
+ mailchimp_call_http_worker_manually();
170
+ }
171
+ }
172
 
173
  /**
174
  * @return bool
175
  */
176
  function mailchimp_should_init_queue() {
177
+ return !mailchimp_queue_is_disabled() &&
178
+ !mailchimp_running_in_console() &&
179
+ !mailchimp_detect_request_contains_http_worker() &&
180
+ mailchimp_detect_admin_ajax() &&
181
+ mailchimp_is_configured() &&
182
+ !mailchimp_http_worker_is_running();
183
+ }
184
+
185
+ /**
186
+ * @param int $max
187
+ * @return bool|DateTime
188
+ */
189
+ function mailchimp_get_http_lock_expiration($max = 300) {
190
+ try {
191
+ if (($lock_time = (string) get_site_transient('http_worker_lock')) && !empty($lock_time)) {
192
+ $parts = str_getcsv($lock_time, ' ');
193
+ if (count($parts) >= 2 && is_numeric($parts[1])) {
194
+ $lock_duration = apply_filters('http_worker_lock_time', 60);
195
+ if (empty($lock_duration) || !is_numeric($lock_duration) || ($lock_duration >= $max)) {
196
+ $lock_duration = $max;
197
+ }
198
+ return new \DateTime(((int) $parts[1] + $lock_duration));
199
+ }
200
+ }
201
+ } catch (\Exception $e) {}
202
+ return false;
203
+ }
204
+
205
+ /**
206
+ * @return bool
207
+ */
208
+ function mailchimp_should_reset_http_lock() {
209
+ return ($lock = mailchimp_get_http_lock_expiration()) && $lock->getTimestamp() < time();
210
+ }
211
+
212
+ /**
213
+ * @return bool
214
+ */
215
+ function mailchimp_reset_http_lock() {
216
+ return delete_site_transient( 'http_worker_lock' );
217
+ }
218
+
219
+ /**
220
+ * @return bool
221
+ */
222
+ function mailchimp_detect_request_contains_http_worker() {
223
+ global $wp;
224
+ if (empty($wp) || !is_object($wp) || !isset($wp->request)) return false;
225
+ $current_url = home_url(add_query_arg(array(), $wp->request));
226
+ return mailchimp_string_contains($current_url, 'action=http_worker');
227
  }
228
 
229
+ /**
230
+ * @param bool $force
231
+ * @return bool
232
+ */
233
+ function mailchimp_list_has_double_optin($force = false) {
234
+ if (!mailchimp_is_configured()) {
235
+ return false;
236
+ }
237
+
238
+ $key = 'mailchimp_double_optin';
239
+
240
+ $double_optin = get_site_transient($key);
241
+
242
+ if (!$force && ($double_optin === 'yes' || $double_optin === 'no')) {
243
+ return $double_optin === 'yes';
244
+ }
245
+
246
+ try {
247
+ $data = mailchimp_get_api()->getList(mailchimp_get_list_id());
248
+ $double_optin = array_key_exists('double_optin', $data) ? ($data['double_optin'] ? 'yes' : 'no') : 'no';
249
+ set_site_transient($key, $double_optin, 600);
250
+ return $double_optin === 'yes';
251
+ } catch (\Exception $e) {
252
+ set_site_transient($key, 'no', 600);
253
+ }
254
+
255
+ return $double_optin === 'yes';
256
+ }
257
+
258
+
259
  /**
260
  * @return bool
261
  */
418
  if (in_array('woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option('active_plugins')))) {
419
  return true;
420
  }
421
+ if (!is_multisite()) return false;
422
+ $plugins = get_site_option( 'active_sitewide_plugins');
423
+ return isset($plugins['woocommerce/woocommerce.php']);
 
 
424
  }
425
 
426
  /**
460
  }
461
 
462
  /**
463
+ * @param null $network_wide
 
464
  */
465
+ function activate_mailchimp_woocommerce($network_wide = null) {
466
+ if (is_multisite() && $network_wide ) {
467
+ global $wpdb;
468
+ mailchimp_log('plugin.activation.multisite', "Installing Mailchimp Tables.");
469
+ foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $blog_id) {
470
+ switch_to_blog($blog_id);
471
+ if (mailchimp_check_woocommerce_plugin_status()) {
472
+ MailChimp_WooCommerce_Activator::activate();
473
+ }
474
+ restore_current_blog();
475
+ }
476
+ } else {
477
+ // if we don't have woocommerce we need to display a horrible error message before the plugin is installed.
478
+ if (!mailchimp_check_woocommerce_plugin_status()) {
479
+ // Deactivate the plugin
480
+ deactivate_plugins(__FILE__);
481
+ $error_message = __('The Mailchimp For WooCommerce plugin requires the <a href="http://wordpress.org/extend/plugins/woocommerce/">WooCommerce</a> plugin to be active!', 'woocommerce');
482
+ wp_die($error_message);
483
+ }
484
+
485
+ $site_name = get_option('siteurl');
486
+ mailchimp_log('plugin.activation.single_site', "Installing Mailchimp Tables For :: {$site_name}");
487
+ MailChimp_WooCommerce_Activator::activate();
488
+ mailchimp_log('plugin.activation.single_site', "Installed Mailchimp Tables For :: {$site_name}");
489
  }
 
490
  }
491
 
492
  /**
688
  return (bool) (defined( 'DISABLE_WP_HTTP_WORKER' ) && true === DISABLE_WP_HTTP_WORKER);
689
  }
690
 
691
+ /**
692
+ * @return bool
693
+ */
694
+ function mailchimp_queue_is_disabled() {
695
+ return (bool) (defined( 'MAILCHIMP_DISABLE_QUEUE' ) && true === MAILCHIMP_DISABLE_QUEUE);
696
+ }
697
+
698
  /**
699
  * @return bool
700
  */
701
  function mailchimp_http_worker_is_running() {
702
+ if (mailchimp_should_reset_http_lock()) {
703
+ mailchimp_reset_http_lock();
704
+ mailchimp_log('http_worker_lock', "HTTP worker lock needed to be deleted to initiate the queue.");
705
+ return false;
706
+ }
707
  return (bool) get_site_transient('http_worker_lock');
708
  }
709
 
710
+ /**
711
+ * @param $email
712
+ * @return bool
713
+ */
714
+ function mailchimp_email_is_allowed($email) {
715
+ if (!is_email($email) || mailchimp_email_is_amazon($email) || mailchimp_email_is_privacy_protected($email)) {
716
+ return false;
717
+ }
718
+ return true;
719
+ }
720
+
721
+
722
  /**
723
  * @param $email
724
  * @return bool
763
  return wp_remote_post(esc_url_raw($url), $post_args);
764
  }
765
 
766
+ /**
767
+ * @param $key
768
+ * @param null $default
769
+ * @return mixed|null
770
+ */
771
+ function mailchimp_get_transient($key, $default = null) {
772
+ $transient = get_site_transient("mailchimp-woocommerce.{$key}");
773
+ return empty($transient) ? $default : $transient;
774
+ }
775
+
776
+ /**
777
+ * @param $key
778
+ * @param $value
779
+ * @param int $seconds
780
+ * @return bool
781
+ */
782
+ function mailchimp_set_transient($key, $value, $seconds = 60) {
783
+ mailchimp_delete_transient($key);
784
+ return set_site_transient("mailchimp-woocommerce.{$key}", array(
785
+ 'value' => $value,
786
+ 'expires' => time()+$seconds,
787
+ ));
788
+ }
789
+
790
+ /**
791
+ * @param $key
792
+ * @return bool
793
+ */
794
+ function mailchimp_delete_transient($key) {
795
+ return delete_site_transient("mailchimp-woocommerce.{$key}");
796
+ }
797
+
798
+ /**
799
+ * @param $key
800
+ * @param null $default
801
+ * @return mixed|null
802
+ */
803
+ function mailchimp_get_transient_value($key, $default = null) {
804
+ $transient = mailchimp_get_transient($key, false);
805
+ return (is_array($transient) && array_key_exists('value', $transient)) ? $transient['value'] : $default;
806
+ }
807
+
808
+ /**
809
+ * @param $key
810
+ * @param $value
811
+ * @return bool|null
812
+ */
813
+ function mailchimp_check_serialized_transient_changed($key, $value) {
814
+ if (($saved = mailchimp_get_transient_value($key)) && !empty($saved)) {
815
+ return serialize($saved) === serialize($value);
816
+ }
817
+ return null;
818
+ }
819
+
820
+ /**
821
+ * @param $email
822
+ * @return bool|string
823
+ */
824
+ function mailchimp_get_transient_email_key($email) {
825
+ $email = md5(trim(strtolower($email)));
826
+ return empty($email) ? false : 'MailChimp_WooCommerce_User_Submit@'.$email;
827
+ }
828
+
829
+ /**
830
+ * @param $email
831
+ * @param $status_meta
832
+ * @param int $seconds
833
+ * @return bool
834
+ */
835
+ function mailchimp_tell_system_about_user_submit($email, $status_meta, $seconds = 60) {
836
+ return mailchimp_set_transient(mailchimp_get_transient_email_key($email), $status_meta, $seconds);
837
+ }
838
+
839
+ /**
840
+ * @param $subscribed
841
+ * @return array
842
+ */
843
+ function mailchimp_get_subscriber_status_options($subscribed) {
844
+ $requires = mailchimp_list_has_double_optin();
845
+
846
+ // if it's true - we set this value to NULL so that we do a 'pending' association on the member.
847
+ $status_if_new = $requires ? null : $subscribed;
848
+ $status_if_update = $requires ? 'pending' : $subscribed;
849
+
850
+ // set an array of status meta that we will use for comparison below to the transient data
851
+ return array(
852
+ 'created' => $status_if_new,
853
+ 'updated' => $status_if_update
854
+ );
855
+ }
856
+
857
  function mailchimp_flush_queue_tables() {
858
  try {
859
  /** @var \ */
includes/api/assets/class-mailchimp-customer.php CHANGED
@@ -19,6 +19,7 @@ class MailChimp_WooCommerce_Customer
19
  protected $orders_count = null;
20
  protected $total_spent = null;
21
  protected $address;
 
22
 
23
  /**
24
  * @return array
@@ -211,6 +212,37 @@ class MailChimp_WooCommerce_Customer
211
  return $this;
212
  }
213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  /**
215
  * @return array
216
  */
19
  protected $orders_count = null;
20
  protected $total_spent = null;
21
  protected $address;
22
+ protected $requires_double_optin = false;
23
 
24
  /**
25
  * @return array
212
  return $this;
213
  }
214
 
215
+ /**
216
+ * @return bool
217
+ */
218
+ public function requiresDoubleOptIn()
219
+ {
220
+ return $this->requires_double_optin;
221
+ }
222
+
223
+ /**
224
+ * @param $bool
225
+ * @return $this
226
+ */
227
+ public function requireDoubleOptIn($bool)
228
+ {
229
+ $this->requires_double_optin = (bool) $bool;
230
+
231
+ if ($this->requires_double_optin) {
232
+ $this->opt_in_status = false;
233
+ }
234
+
235
+ return $this;
236
+ }
237
+
238
+ public function getMergeVars()
239
+ {
240
+ return array(
241
+ 'FNAME' => trim($this->getFirstName()),
242
+ 'LNAME' => trim($this->getLastName()),
243
+ );
244
+ }
245
+
246
  /**
247
  * @return array
248
  */
includes/api/class-mailchimp-api.php CHANGED
@@ -195,6 +195,8 @@ class MailChimp_WooCommerce_MailChimpApi
195
  unset($data['interests']);
196
  }
197
 
 
 
198
  return $this->post("lists/$list_id/members", $data);
199
  }
200
 
@@ -212,9 +214,19 @@ class MailChimp_WooCommerce_MailChimpApi
212
  {
213
  $hash = md5(strtolower(trim($email)));
214
 
 
 
 
 
 
 
 
 
 
 
215
  $data = array(
216
  'email_address' => $email,
217
- 'status' => ($subscribed === null ? 'cleaned' : ($subscribed === true ? 'subscribed' : 'unsubscribed')),
218
  'merge_fields' => $merge_fields,
219
  'interests' => $list_interests,
220
  );
@@ -228,6 +240,8 @@ class MailChimp_WooCommerce_MailChimpApi
228
  unset($data['interests']);
229
  }
230
 
 
 
231
  return $this->patch("lists/$list_id/members/$hash", $data);
232
  }
233
 
@@ -246,10 +260,24 @@ class MailChimp_WooCommerce_MailChimpApi
246
  {
247
  $hash = md5(strtolower(trim($email)));
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  $data = array(
250
  'email_address' => $email,
251
- 'status' => ($subscribed === null ? 'cleaned' : ($subscribed === true ? 'subscribed' : 'unsubscribed')),
252
- 'status_if_new' => ($subscribed === true ? 'subscribed' : 'pending'),
253
  'merge_fields' => $merge_fields,
254
  'interests' => $list_interests,
255
  );
@@ -262,6 +290,8 @@ class MailChimp_WooCommerce_MailChimpApi
262
  unset($data['interests']);
263
  }
264
 
 
 
265
  return $this->put("lists/$list_id/members/$hash", $data);
266
  }
267
 
@@ -656,10 +686,14 @@ class MailChimp_WooCommerce_MailChimpApi
656
  {
657
  try {
658
  $email = $cart->getCustomer()->getEmailAddress();
 
659
  if (mailchimp_email_is_privacy_protected($email) || mailchimp_email_is_amazon($email)) {
660
  return false;
661
  }
662
- $data = $this->post("ecommerce/stores/$store_id/carts", $cart->toArray());
 
 
 
663
  $cart = new MailChimp_WooCommerce_Cart();
664
  return $cart->setStoreID($store_id)->fromArray($data);
665
  } catch (MailChimp_WooCommerce_Error $e) {
@@ -684,10 +718,14 @@ class MailChimp_WooCommerce_MailChimpApi
684
  {
685
  try {
686
  $email = $cart->getCustomer()->getEmailAddress();
 
687
  if (mailchimp_email_is_privacy_protected($email) || mailchimp_email_is_amazon($email)) {
688
  return false;
689
  }
690
- $data = $this->patch("ecommerce/stores/$store_id/carts/{$cart->getId()}", $cart->toArrayForUpdate());
 
 
 
691
  $cart = new MailChimp_WooCommerce_Cart();
692
  return $cart->setStoreID($store_id)->fromArray($data);
693
  } catch (MailChimp_WooCommerce_Error $e) {
195
  unset($data['interests']);
196
  }
197
 
198
+ mailchimp_debug('api.subscribe', "Subscribing {$email}", $data);
199
+
200
  return $this->post("lists/$list_id/members", $data);
201
  }
202
 
214
  {
215
  $hash = md5(strtolower(trim($email)));
216
 
217
+ if ($subscribed === true) {
218
+ $status = 'subscribed';
219
+ } elseif ($subscribed === false) {
220
+ $status = 'unsubscribed';
221
+ } elseif ($subscribed === null) {
222
+ $status = 'cleaned';
223
+ } else {
224
+ $status = $subscribed;
225
+ }
226
+
227
  $data = array(
228
  'email_address' => $email,
229
+ 'status' => $status,
230
  'merge_fields' => $merge_fields,
231
  'interests' => $list_interests,
232
  );
240
  unset($data['interests']);
241
  }
242
 
243
+ mailchimp_debug('api.update_member', "Updating {$email}", $data);
244
+
245
  return $this->patch("lists/$list_id/members/$hash", $data);
246
  }
247
 
260
  {
261
  $hash = md5(strtolower(trim($email)));
262
 
263
+ if ($subscribed === true) {
264
+ $status = 'subscribed';
265
+ $status_if_new = 'subscribed';
266
+ } elseif ($subscribed === false) {
267
+ $status = 'unsubscribed';
268
+ $status_if_new = 'pending';
269
+ } elseif ($subscribed === null) {
270
+ $status = 'cleaned';
271
+ $status_if_new = 'subscribed';
272
+ } else {
273
+ $status = $subscribed;
274
+ $status_if_new = 'pending';
275
+ }
276
+
277
  $data = array(
278
  'email_address' => $email,
279
+ 'status' => $status,
280
+ 'status_if_new' => $status_if_new,
281
  'merge_fields' => $merge_fields,
282
  'interests' => $list_interests,
283
  );
290
  unset($data['interests']);
291
  }
292
 
293
+ mailchimp_debug('api.update_or_create', "Update Or Create {$email}", $data);
294
+
295
  return $this->put("lists/$list_id/members/$hash", $data);
296
  }
297
 
686
  {
687
  try {
688
  $email = $cart->getCustomer()->getEmailAddress();
689
+
690
  if (mailchimp_email_is_privacy_protected($email) || mailchimp_email_is_amazon($email)) {
691
  return false;
692
  }
693
+
694
+ mailchimp_debug('api.addCart', "Adding Cart :: {$email}", $data = $cart->toArray());
695
+
696
+ $data = $this->post("ecommerce/stores/$store_id/carts", $data);
697
  $cart = new MailChimp_WooCommerce_Cart();
698
  return $cart->setStoreID($store_id)->fromArray($data);
699
  } catch (MailChimp_WooCommerce_Error $e) {
718
  {
719
  try {
720
  $email = $cart->getCustomer()->getEmailAddress();
721
+
722
  if (mailchimp_email_is_privacy_protected($email) || mailchimp_email_is_amazon($email)) {
723
  return false;
724
  }
725
+
726
+ mailchimp_debug('api.updateCart', "Updating Cart :: {$email}", $data = $cart->toArrayForUpdate());
727
+
728
+ $data = $this->patch("ecommerce/stores/$store_id/carts/{$cart->getId()}", $data);
729
  $cart = new MailChimp_WooCommerce_Cart();
730
  return $cart->setStoreID($store_id)->fromArray($data);
731
  } catch (MailChimp_WooCommerce_Error $e) {
includes/api/class-mailchimp-woocommerce-transform-orders-wc3.php CHANGED
@@ -113,8 +113,10 @@ class MailChimp_WooCommerce_Transform_Orders
113
  // set the total
114
  $order->setOrderTotal($woo->get_total());
115
 
116
- // set the order URL
117
- $order->setOrderURL($woo->get_view_order_url());
 
 
118
 
119
  // if we have any tax
120
  $order->setTaxTotal($woo->get_total_tax());
@@ -205,14 +207,34 @@ class MailChimp_WooCommerce_Transform_Orders
205
  $subscribed_on_order = $subscriber_meta === '' ? false : (bool) $subscriber_meta;
206
  $customer->setOptInStatus($subscribed_on_order);
207
 
 
 
 
 
 
208
  // if they didn't subscribe on the order, we need to check to make sure they're not already a subscriber
209
  // if they are, we just need to make sure that we don't unsubscribe them just because they unchecked this box.
210
- if (!$subscribed_on_order) {
211
  try {
212
  $subscriber = mailchimp_get_api()->member(mailchimp_get_list_id(), $customer->getEmailAddress());
213
- $status = !in_array($subscriber['status'], array('unsubscribed', 'transactional'));
214
- $customer->setOptInStatus($status);
215
- } catch (\Exception $e) {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  }
217
 
218
  return $customer;
@@ -402,7 +424,7 @@ class MailChimp_WooCommerce_Transform_Orders
402
  ),
403
  // Order fulfilled and complete – requires no further action
404
  'completed' => (object) array(
405
- 'financial' => 'fulfilled',
406
  'fulfillment' => 'fulfilled'
407
  ),
408
  // Cancelled by an admin or the customer – no further action required
113
  // set the total
114
  $order->setOrderTotal($woo->get_total());
115
 
116
+ // set the order URL if it's valid.
117
+ if (($view_order_url = $woo->get_view_order_url()) && wc_is_valid_url($view_order_url)) {
118
+ $order->setOrderURL($woo->get_view_order_url());
119
+ }
120
 
121
  // if we have any tax
122
  $order->setTaxTotal($woo->get_total_tax());
207
  $subscribed_on_order = $subscriber_meta === '' ? false : (bool) $subscriber_meta;
208
  $customer->setOptInStatus($subscribed_on_order);
209
 
210
+ $doi = mailchimp_list_has_double_optin();
211
+ $status_if_new = $doi ? false : $subscribed_on_order;
212
+
213
+ $customer->setOptInStatus($status_if_new);
214
+
215
  // if they didn't subscribe on the order, we need to check to make sure they're not already a subscriber
216
  // if they are, we just need to make sure that we don't unsubscribe them just because they unchecked this box.
217
+ if ($doi || !$subscribed_on_order) {
218
  try {
219
  $subscriber = mailchimp_get_api()->member(mailchimp_get_list_id(), $customer->getEmailAddress());
220
+
221
+ if ($subscriber['status'] === 'transactional') {
222
+ $customer->setOptInStatus(false);
223
+ $customer->requireDoubleOptIn(true);
224
+ return $customer;
225
+ } elseif ($subscriber['status'] === 'pending') {
226
+ $customer->setOptInStatus(false);
227
+ return $customer;
228
+ }
229
+
230
+ $customer->setOptInStatus($subscriber['status'] === 'subscribed');
231
+ } catch (\Exception $e) {
232
+ // if double opt in is enabled - we need to make a request now that subscribes the customer as pending
233
+ // so that the double opt in will actually fire.
234
+ if ($doi && (!isset($subscriber) || empty($subscriber))) {
235
+ $customer->requireDoubleOptIn(true);
236
+ }
237
+ }
238
  }
239
 
240
  return $customer;
424
  ),
425
  // Order fulfilled and complete – requires no further action
426
  'completed' => (object) array(
427
+ 'financial' => 'paid',
428
  'fulfillment' => 'fulfilled'
429
  ),
430
  // Cancelled by an admin or the customer – no further action required
includes/api/class-mailchimp-woocommerce-transform-products.php CHANGED
@@ -66,7 +66,9 @@ class MailChimp_WooCommerce_Transform_Products
66
 
67
  foreach ($variants as $variant) {
68
 
69
- $product_variant = $this->variant($is_variant, $variant, $woo->get_title());
 
 
70
 
71
  $product_variant_title = $product_variant->getTitle();
72
 
@@ -87,12 +89,11 @@ class MailChimp_WooCommerce_Transform_Products
87
  }
88
 
89
  /**
90
- * @param $is_variant
91
  * @param WP_Post $post
92
  * @param string $fallback_title
93
  * @return MailChimp_WooCommerce_ProductVariation
94
  */
95
- public function variant($is_variant, $post, $fallback_title = null)
96
  {
97
  if ($post instanceof WC_Product || $post instanceof WC_Product_Variation) {
98
  $woo = $post;
@@ -106,6 +107,10 @@ class MailChimp_WooCommerce_Transform_Products
106
 
107
  $variant = new MailChimp_WooCommerce_ProductVariation();
108
 
 
 
 
 
109
  $variant->setId($woo->get_id());
110
  $variant->setUrl($woo->get_permalink());
111
  $variant->setImageUrl($this->getProductImage($post));
@@ -273,7 +278,7 @@ class MailChimp_WooCommerce_Transform_Products
273
  $product->setDescription($post->post_content);
274
  $product->setImageUrl($this->getProductImage($post));
275
 
276
- $variant = $this->variant(false, $post, $post->post_name);
277
 
278
  if (!$variant->getImageUrl()) {
279
  $variant->setImageUrl($product->getImageUrl());
66
 
67
  foreach ($variants as $variant) {
68
 
69
+ $product_variant = $this->variant($variant, $woo->get_title());
70
+
71
+ if (!$product_variant) continue;
72
 
73
  $product_variant_title = $product_variant->getTitle();
74
 
89
  }
90
 
91
  /**
 
92
  * @param WP_Post $post
93
  * @param string $fallback_title
94
  * @return MailChimp_WooCommerce_ProductVariation
95
  */
96
+ public function variant($post, $fallback_title = null)
97
  {
98
  if ($post instanceof WC_Product || $post instanceof WC_Product_Variation) {
99
  $woo = $post;
107
 
108
  $variant = new MailChimp_WooCommerce_ProductVariation();
109
 
110
+ if (!$woo) {
111
+ return $variant;
112
+ }
113
+
114
  $variant->setId($woo->get_id());
115
  $variant->setUrl($woo->get_permalink());
116
  $variant->setImageUrl($this->getProductImage($post));
278
  $product->setDescription($post->post_content);
279
  $product->setImageUrl($this->getProductImage($post));
280
 
281
+ $variant = $this->variant($post, $post->post_name);
282
 
283
  if (!$variant->getImageUrl()) {
284
  $variant->setImageUrl($product->getImageUrl());
includes/class-mailchimp-woocommerce-service.php CHANGED
@@ -86,7 +86,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
86
 
87
  // queue up the single order to be processed.
88
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, $campaign_id, $landing_site);
89
- wp_queue($handler, 60);
90
  }
91
 
92
  /**
@@ -106,7 +106,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
106
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, null, null);
107
  $handler->is_update = true;
108
  $handler->is_admin_save = $is_admin;
109
- wp_queue($handler, 90);
110
  }
111
 
112
  /**
@@ -118,7 +118,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
118
 
119
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, null, null);
120
  $handler->partially_refunded = true;
121
- wp_queue($handler);
122
  }
123
 
124
  /**
@@ -184,7 +184,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
184
 
185
  // fire up the job handler
186
  $handler = new MailChimp_WooCommerce_Cart_Update($uid, $user_email, $campaign, $this->cart);
187
- wp_queue($handler);
188
  }
189
 
190
  return !is_null($updated) ? $updated : true;
@@ -210,7 +210,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
210
  if (!mailchimp_is_configured()) return;
211
 
212
  if ($coupon instanceof WC_Coupon) {
213
- wp_queue(new MailChimp_WooCommerce_SingleCoupon($post_id));
214
  }
215
  }
216
 
@@ -233,9 +233,10 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
233
  {
234
  if (!mailchimp_is_configured()) return;
235
 
236
- if ($post->post_status !== 'auto-draft') {
 
237
  if ('product' == $post->post_type) {
238
- wp_queue(new MailChimp_WooCommerce_Single_Product($post_id), 5);
239
  } elseif ('shop_order' == $post->post_type) {
240
  $this->handleOrderStatusChanged($post_id, is_admin());
241
  }
@@ -251,8 +252,20 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
251
 
252
  switch (get_post_type($post_id)) {
253
  case 'shop_coupon':
254
- mailchimp_get_api()->deletePromoRule(mailchimp_get_store_id(), $post_id);
255
- mailchimp_log('promo_code.deleted', "deleted promo code {$post_id}");
 
 
 
 
 
 
 
 
 
 
 
 
256
  break;
257
  }
258
  }
@@ -262,12 +275,21 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
262
  */
263
  public function handlePostRestored($post_id)
264
  {
265
- if (!mailchimp_is_configured()) return;
 
 
 
 
 
266
 
267
  switch(get_post_type($post_id)) {
268
  case 'shop_coupon':
269
  return $this->handleCouponRestored($post_id);
270
  break;
 
 
 
 
271
  }
272
  }
273
 
@@ -285,7 +307,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
285
  update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
286
 
287
  if ($subscribed) {
288
- wp_queue(new MailChimp_WooCommerce_User_Submit($user_id, $subscribed));
289
  }
290
  }
291
 
@@ -304,7 +326,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
304
  if ($is_subscribed === '' || $is_subscribed === null) return;
305
 
306
  // only send this update if the user actually has a boolean value.
307
- wp_queue(new MailChimp_WooCommerce_User_Submit($user_id, (bool) $is_subscribed, $old_user_data));
308
  }
309
 
310
  /**
@@ -330,7 +352,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
330
  if (!$this->isAdmin()) return false;
331
  $this->removePointers(false, true);
332
  // since the products are all good, let's sync up the orders now.
333
- wp_queue(new MailChimp_WooCommerce_Process_Orders());
334
  return true;
335
  }
336
 
86
 
87
  // queue up the single order to be processed.
88
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, $campaign_id, $landing_site);
89
+ mailchimp_handle_or_queue($handler, 60);
90
  }
91
 
92
  /**
106
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, null, null);
107
  $handler->is_update = true;
108
  $handler->is_admin_save = $is_admin;
109
+ mailchimp_handle_or_queue($handler, 90);
110
  }
111
 
112
  /**
118
 
119
  $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, null, null);
120
  $handler->partially_refunded = true;
121
+ mailchimp_handle_or_queue($handler);
122
  }
123
 
124
  /**
184
 
185
  // fire up the job handler
186
  $handler = new MailChimp_WooCommerce_Cart_Update($uid, $user_email, $campaign, $this->cart);
187
+ mailchimp_handle_or_queue($handler);
188
  }
189
 
190
  return !is_null($updated) ? $updated : true;
210
  if (!mailchimp_is_configured()) return;
211
 
212
  if ($coupon instanceof WC_Coupon) {
213
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_SingleCoupon($post_id));
214
  }
215
  }
216
 
233
  {
234
  if (!mailchimp_is_configured()) return;
235
 
236
+ // don't handle any of these statuses because they're not ready for the show
237
+ if (!in_array($post->post_status, array('trash', 'auto-draft', 'draft', 'pending'))) {
238
  if ('product' == $post->post_type) {
239
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($post_id), 5);
240
  } elseif ('shop_order' == $post->post_type) {
241
  $this->handleOrderStatusChanged($post_id, is_admin());
242
  }
252
 
253
  switch (get_post_type($post_id)) {
254
  case 'shop_coupon':
255
+ try {
256
+ mailchimp_get_api()->deletePromoRule(mailchimp_get_store_id(), $post_id);
257
+ mailchimp_log('promo_code.deleted', "deleted promo code {$post_id}");
258
+ } catch (\Exception $e) {
259
+ mailchimp_error('delete promo code', $e->getMessage());
260
+ }
261
+ break;
262
+ case 'product':
263
+ try {
264
+ mailchimp_get_api()->deleteStoreProduct(mailchimp_get_store_id(), $post_id);
265
+ mailchimp_log('product.deleted', "deleted product {$post_id}");
266
+ } catch (\Exception $e) {
267
+ mailchimp_error('delete product', $e->getMessage());
268
+ }
269
  break;
270
  }
271
  }
275
  */
276
  public function handlePostRestored($post_id)
277
  {
278
+ if (!mailchimp_is_configured() || !($post = get_post($post_id))) return;
279
+
280
+ // don't handle any of these statuses because they're not ready for the show
281
+ if (in_array($post->post_status, array('trash', 'auto-draft', 'draft', 'pending'))) {
282
+ return;
283
+ }
284
 
285
  switch(get_post_type($post_id)) {
286
  case 'shop_coupon':
287
  return $this->handleCouponRestored($post_id);
288
  break;
289
+
290
+ case 'product':
291
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($post_id), 5);
292
+ break;
293
  }
294
  }
295
 
307
  update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
308
 
309
  if ($subscribed) {
310
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, $subscribed));
311
  }
312
  }
313
 
326
  if ($is_subscribed === '' || $is_subscribed === null) return;
327
 
328
  // only send this update if the user actually has a boolean value.
329
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, (bool) $is_subscribed, $old_user_data));
330
  }
331
 
332
  /**
352
  if (!$this->isAdmin()) return false;
353
  $this->removePointers(false, true);
354
  // since the products are all good, let's sync up the orders now.
355
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
356
  return true;
357
  }
358
 
includes/processes/class-mailchimp-woocommerce-abstract-sync.php CHANGED
@@ -137,7 +137,7 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends WP_Job
137
  $wpdb->query("DELETE FROM {$wpdb->prefix}queue WHERE job LIKE '%{$class_name}%'");
138
 
139
  // this will paginate through all records for the resource type until they return no records.
140
- wp_queue(new static());
141
  mailchimp_debug(get_called_class().'@handle', 'queuing up the next job');
142
  return false;
143
  }
137
  $wpdb->query("DELETE FROM {$wpdb->prefix}queue WHERE job LIKE '%{$class_name}%'");
138
 
139
  // this will paginate through all records for the resource type until they return no records.
140
+ mailchimp_handle_or_queue(new static());
141
  mailchimp_debug(get_called_class().'@handle', 'queuing up the next job');
142
  return false;
143
  }
includes/processes/class-mailchimp-woocommerce-process-products.php CHANGED
@@ -20,7 +20,7 @@ class MailChimp_WooCommerce_Process_Products extends MailChimp_WooCommerce_Abstr
20
  {
21
  $job = new MailChimp_WooCommerce_Process_Products();
22
  $job->flagStartSync();
23
- wp_queue($job);
24
  }
25
 
26
 
@@ -82,7 +82,7 @@ class MailChimp_WooCommerce_Process_Products extends MailChimp_WooCommerce_Abstr
82
  // only do this if we're not strictly syncing products ( which is the default ).
83
  if (!$prevent_order_sync) {
84
  // since the products are all good, let's sync up the orders now.
85
- wp_queue(new MailChimp_WooCommerce_Process_Orders());
86
  }
87
 
88
  // since we skipped the orders feed we can delete this option.
20
  {
21
  $job = new MailChimp_WooCommerce_Process_Products();
22
  $job->flagStartSync();
23
+ mailchimp_handle_or_queue($job);
24
  }
25
 
26
 
82
  // only do this if we're not strictly syncing products ( which is the default ).
83
  if (!$prevent_order_sync) {
84
  // since the products are all good, let's sync up the orders now.
85
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
86
  }
87
 
88
  // since we skipped the orders feed we can delete this option.
includes/processes/class-mailchimp-woocommerce-single-order.php CHANGED
@@ -76,13 +76,15 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
76
 
77
  $call = ($api_response = $api->getStoreOrder($store_id, $woo_order_number)) ? 'updateStoreOrder' : 'addStoreOrder';
78
 
79
- if (!$this->is_admin_save && $call === 'addStoreOrder' && $this->is_update === true) {
 
 
80
  return false;
81
  }
82
 
83
  // if we already pushed this order into the system, we need to unset it now just in case there
84
  // was another campaign that had been sent and this was only an order update.
85
- if ($call === 'updateStoreOrder') {
86
  $job->campaign_id = null;
87
  $this->campaign_id = null;
88
  $this->landing_site = null;
@@ -114,10 +116,17 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
114
  }
115
 
116
  // if the order is in failed or cancelled status - and it's brand new, we shouldn't submit it.
117
- if ($call === 'addStoreOrder' && in_array($order->getFinancialStatus(), array('failed', 'cancelled'))) {
118
  return false;
119
  }
120
 
 
 
 
 
 
 
 
121
  mailchimp_debug('order_submit', "#{$woo_order_number}", $order->toArray());
122
 
123
  // if we're overriding this we need to set it here.
@@ -128,8 +137,7 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
128
  $log = "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
129
 
130
  // only do this stuff on new orders
131
- if ($call === 'addStoreOrder') {
132
-
133
  // apply a campaign id if we have one.
134
  if (!empty($this->campaign_id)) {
135
  $log .= ' :: campaign id ' . $this->campaign_id;
@@ -141,7 +149,6 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
141
  $log .= ' :: landing site ' . $this->landing_site;
142
  $order->setLandingSite($this->landing_site);
143
  }
144
-
145
  }
146
 
147
  // update or create
@@ -158,48 +165,63 @@ class MailChimp_WooCommerce_Single_Order extends WP_Job
158
 
159
  mailchimp_log('order_submit.success', $log);
160
 
161
- return $api_response;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
 
163
  } catch (\Exception $e) {
164
-
165
  $message = strtolower($e->getMessage());
166
-
167
  mailchimp_error('order_submit.tracing_error', $e);
168
-
169
  if (!isset($order)) {
170
  // transform the order
171
  $order = $job->transform(get_post($this->order_id));
172
  $this->cart_session_id = $order->getCustomer()->getId();
173
  }
174
-
175
  // this can happen when a customer changes their email.
176
  if (isset($order) && strpos($message, 'not be changed')) {
177
-
178
  try {
179
-
180
  mailchimp_log('order_submit.deleting_customer', "#{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}");
181
-
182
  // delete the customer before adding it again.
183
  $api->deleteCustomer($store_id, $order->getCustomer()->getId());
184
-
185
  // update or create
186
  $api_response = $api->$call($store_id, $order, false);
187
-
188
  $log = "Deleted Customer :: $call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
189
-
190
  if (!empty($job->campaign_id)) {
191
  $log .= ' :: campaign id '.$job->campaign_id;
192
  }
193
-
194
  mailchimp_log('order_submit.success', $log);
195
-
196
  // if we're adding a new order and the session id is here, we need to delete the AC cart record.
197
  if (!empty($this->cart_session_id)) {
198
  $api->deleteCartByID($store_id, $this->cart_session_id);
199
  }
200
-
201
  return $api_response;
202
-
203
  } catch (\Exception $e) {
204
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, 'deleting-customer-re-add :: #'.$this->order_id));
205
  }
76
 
77
  $call = ($api_response = $api->getStoreOrder($store_id, $woo_order_number)) ? 'updateStoreOrder' : 'addStoreOrder';
78
 
79
+ $new_order = $call === 'addStoreOrder';
80
+
81
+ if (!$this->is_admin_save && $new_order && $this->is_update === true) {
82
  return false;
83
  }
84
 
85
  // if we already pushed this order into the system, we need to unset it now just in case there
86
  // was another campaign that had been sent and this was only an order update.
87
+ if (!$new_order) {
88
  $job->campaign_id = null;
89
  $this->campaign_id = null;
90
  $this->landing_site = null;
116
  }
117
 
118
  // if the order is in failed or cancelled status - and it's brand new, we shouldn't submit it.
119
+ if ($new_order && in_array($order->getFinancialStatus(), array('failed', 'cancelled'))) {
120
  return false;
121
  }
122
 
123
+ // if the order is brand new, and we already have a paid status,
124
+ // we need to double up the post to force the confirmation + the invoice.
125
+ if ($new_order && $order->getFinancialStatus() === 'paid') {
126
+ $order->setFinancialStatus('pending');
127
+ $order->confirmAndPay(true);
128
+ }
129
+
130
  mailchimp_debug('order_submit', "#{$woo_order_number}", $order->toArray());
131
 
132
  // if we're overriding this we need to set it here.
137
  $log = "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
138
 
139
  // only do this stuff on new orders
140
+ if ($new_order) {
 
141
  // apply a campaign id if we have one.
142
  if (!empty($this->campaign_id)) {
143
  $log .= ' :: campaign id ' . $this->campaign_id;
149
  $log .= ' :: landing site ' . $this->landing_site;
150
  $order->setLandingSite($this->landing_site);
151
  }
 
152
  }
153
 
154
  // update or create
165
 
166
  mailchimp_log('order_submit.success', $log);
167
 
168
+ // if the customer has a flag to double opt in - we need to push this data over to MailChimp as pending
169
+ // before the order is submitted.
170
+ if ($order->getCustomer()->requiresDoubleOptIn()) {
171
+ try {
172
+ $list_id = mailchimp_get_list_id();
173
+ $merge_vars = $order->getCustomer()->getMergeVars();
174
+ $email = $order->getCustomer()->getEmailAddress();
175
+
176
+ try {
177
+ $member = $api->member($list_id, $email);
178
+ if ($member['status'] === 'transactional') {
179
+ $api->update($list_id, $email, 'pending', $merge_vars);
180
+ mailchimp_tell_system_about_user_submit($email, mailchimp_get_subscriber_status_options('pending'), 60);
181
+ mailchimp_log('double_opt_in', "Updated {$email} Using Double Opt In - previous status was '{$member['status']}'", $merge_vars);
182
+ }
183
+ } catch (\Exception $e) {
184
+ // if the error code is 404 - need to subscribe them becausce it means they were not on the list.
185
+ if ($e->getCode() == 404) {
186
+ $api->subscribe($list_id, $email, false, $merge_vars);
187
+ mailchimp_tell_system_about_user_submit($email, mailchimp_get_subscriber_status_options(false), 60);
188
+ mailchimp_log('double_opt_in', "Subscribed {$email} Using Double Opt In", $merge_vars);
189
+ } else {
190
+ mailchimp_error('double_opt_in.update', $e->getMessage());
191
+ }
192
+ }
193
+ } catch (\Exception $e) {
194
+ mailchimp_error('double_opt_in.create', $e->getMessage());
195
+ }
196
+ }
197
 
198
+ return $api_response;
199
  } catch (\Exception $e) {
 
200
  $message = strtolower($e->getMessage());
 
201
  mailchimp_error('order_submit.tracing_error', $e);
 
202
  if (!isset($order)) {
203
  // transform the order
204
  $order = $job->transform(get_post($this->order_id));
205
  $this->cart_session_id = $order->getCustomer()->getId();
206
  }
 
207
  // this can happen when a customer changes their email.
208
  if (isset($order) && strpos($message, 'not be changed')) {
 
209
  try {
 
210
  mailchimp_log('order_submit.deleting_customer', "#{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}");
 
211
  // delete the customer before adding it again.
212
  $api->deleteCustomer($store_id, $order->getCustomer()->getId());
 
213
  // update or create
214
  $api_response = $api->$call($store_id, $order, false);
 
215
  $log = "Deleted Customer :: $call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
 
216
  if (!empty($job->campaign_id)) {
217
  $log .= ' :: campaign id '.$job->campaign_id;
218
  }
 
219
  mailchimp_log('order_submit.success', $log);
 
220
  // if we're adding a new order and the session id is here, we need to delete the AC cart record.
221
  if (!empty($this->cart_session_id)) {
222
  $api->deleteCartByID($store_id, $this->cart_session_id);
223
  }
 
224
  return $api_response;
 
225
  } catch (\Exception $e) {
226
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, 'deleting-customer-re-add :: #'.$this->order_id));
227
  }
includes/processes/class-mailchimp-woocommerce-user-submit.php CHANGED
@@ -10,9 +10,12 @@
10
  */
11
  class MailChimp_WooCommerce_User_Submit extends WP_Job
12
  {
 
 
13
  public $user_id;
14
  public $subscribed;
15
  public $updated_data;
 
16
 
17
  /**
18
  * MailChimp_WooCommerce_User_Submit constructor.
@@ -23,7 +26,11 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
23
  public function __construct($user_id = null, $subscribed = null, $updated_data = null)
24
  {
25
  if (!empty($user_id)) {
 
 
 
26
  $this->user_id = $user_id;
 
27
  }
28
 
29
  if (is_bool($subscribed)) {
@@ -42,6 +49,13 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
42
  {
43
  if (!mailchimp_is_configured()) {
44
  mailchimp_debug(get_called_class(), 'mailchimp is not configured properly');
 
 
 
 
 
 
 
45
  return false;
46
  }
47
 
@@ -56,7 +70,7 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
56
 
57
  // seems as if the database records are not being set by the time this queue job is fired,
58
  // just a precautionary to make sure it's available during
59
- sleep(3);
60
 
61
  $options = get_option('mailchimp-woocommerce', array());
62
  $store_id = mailchimp_get_store_id();
@@ -66,6 +80,7 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
66
 
67
  if ($user->ID <= 0 || empty($store_id) || !is_array($options)) {
68
  mailchimp_log('member.sync', "Invalid Data For Submission :: {$user->ID}");
 
69
  return false;
70
  }
71
  }
@@ -73,7 +88,8 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
73
  $email = $user->user_email;
74
 
75
  // make sure we don't need to skip this email
76
- if (!is_email($email) || mailchimp_email_is_amazon($email) || mailchimp_email_is_privacy_protected($email)) {
 
77
  return false;
78
  }
79
 
@@ -82,6 +98,7 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
82
  $user_subscribed = get_user_meta($this->user_id, 'mailchimp_woocommerce_is_subscribed', true);
83
  if ($user_subscribed === '' || $user_subscribed === null) {
84
  mailchimp_log('member.sync', "Skipping sync for {$email} because no subscriber status has been set");
 
85
  return false;
86
  }
87
  $this->subscribed = (bool) $user_subscribed;
@@ -93,12 +110,14 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
93
  // we need a valid api key and list id to continue
94
  if (empty($api_key) || empty($list_id)) {
95
  mailchimp_log('member.sync', "Invalid Api Key or ListID :: {$email}");
 
96
  return false;
97
  }
98
 
99
  // don't let anyone be unsubscribed from the list - that should only happen on email campaigns
100
  // and someone clicking the unsubscribe linkage.
101
  if (!$this->subscribed) {
 
102
  return false;
103
  }
104
 
@@ -112,50 +131,83 @@ class MailChimp_WooCommerce_User_Submit extends WP_Job
112
  if (!empty($fn)) $merge_vars['FNAME'] = $fn;
113
  if (!empty($ln)) $merge_vars['LNAME'] = $ln;
114
 
 
 
 
 
115
  try {
116
 
 
 
 
 
 
 
 
117
  // see if we have a member.
118
- $api->member($list_id, $email);
119
 
120
  // if we're updating a member and the email is different, we need to delete the old person
121
  if (is_array($this->updated_data) && isset($this->updated_data['user_email'])) {
122
-
123
  if ($this->updated_data['user_email'] !== $email) {
124
-
125
  // delete the old
126
  $api->deleteMember($list_id, $this->updated_data['user_email']);
127
-
128
  // subscribe the new
129
- $api->subscribe($list_id, $email, $this->subscribed, $merge_vars);
130
-
131
- mailchimp_log('member.sync', 'Subscriber Swap '.$this->updated_data['user_email'].' to '.$email, $merge_vars);
132
-
 
 
 
 
 
 
 
 
 
 
 
133
  return false;
134
  }
135
  }
136
-
 
 
 
 
137
  // ok let's update this member
138
- $api->update($list_id, $email, $this->subscribed, $merge_vars);
139
-
140
- mailchimp_log('member.sync', "Updated Member {$email}", $merge_vars);
 
 
 
 
 
141
  } catch (\Exception $e) {
142
-
143
  // if we have a 404 not found, we can create the member
144
  if ($e->getCode() == 404) {
145
 
146
  try {
147
- $api->subscribe($list_id, $user->user_email, $this->subscribed, $merge_vars);
148
- mailchimp_log('member.sync', "Subscribed Member {$user->user_email}", $merge_vars);
 
 
 
 
 
149
  } catch (\Exception $e) {
150
  mailchimp_log('member.sync', $e->getMessage());
151
  }
152
-
153
  return false;
154
  }
155
-
156
  mailchimp_error('member.sync', mailchimp_error_trace($e, $user->user_email));
157
  }
158
 
 
 
159
  return false;
160
  }
161
  }
10
  */
11
  class MailChimp_WooCommerce_User_Submit extends WP_Job
12
  {
13
+ public static $handling_for = null;
14
+
15
  public $user_id;
16
  public $subscribed;
17
  public $updated_data;
18
+ public $should_ignore = false;
19
 
20
  /**
21
  * MailChimp_WooCommerce_User_Submit constructor.
26
  public function __construct($user_id = null, $subscribed = null, $updated_data = null)
27
  {
28
  if (!empty($user_id)) {
29
+ if (static::$handling_for === $this->user_id) {
30
+ $this->should_ignore = true;
31
+ }
32
  $this->user_id = $user_id;
33
+ static::$handling_for = $this->user_id;
34
  }
35
 
36
  if (is_bool($subscribed)) {
49
  {
50
  if (!mailchimp_is_configured()) {
51
  mailchimp_debug(get_called_class(), 'mailchimp is not configured properly');
52
+ static::$handling_for = null;
53
+ return false;
54
+ }
55
+
56
+ if ($this->should_ignore) {
57
+ mailchimp_debug(get_called_class(), "{$this->user_id} is currently in motion - skipping this one.");
58
+ static::$handling_for = null;
59
  return false;
60
  }
61
 
70
 
71
  // seems as if the database records are not being set by the time this queue job is fired,
72
  // just a precautionary to make sure it's available during
73
+ sleep(1);
74
 
75
  $options = get_option('mailchimp-woocommerce', array());
76
  $store_id = mailchimp_get_store_id();
80
 
81
  if ($user->ID <= 0 || empty($store_id) || !is_array($options)) {
82
  mailchimp_log('member.sync', "Invalid Data For Submission :: {$user->ID}");
83
+ static::$handling_for = null;
84
  return false;
85
  }
86
  }
88
  $email = $user->user_email;
89
 
90
  // make sure we don't need to skip this email
91
+ if (!mailchimp_email_is_allowed($email)) {
92
+ static::$handling_for = null;
93
  return false;
94
  }
95
 
98
  $user_subscribed = get_user_meta($this->user_id, 'mailchimp_woocommerce_is_subscribed', true);
99
  if ($user_subscribed === '' || $user_subscribed === null) {
100
  mailchimp_log('member.sync', "Skipping sync for {$email} because no subscriber status has been set");
101
+ static::$handling_for = null;
102
  return false;
103
  }
104
  $this->subscribed = (bool) $user_subscribed;
110
  // we need a valid api key and list id to continue
111
  if (empty($api_key) || empty($list_id)) {
112
  mailchimp_log('member.sync', "Invalid Api Key or ListID :: {$email}");
113
+ static::$handling_for = null;
114
  return false;
115
  }
116
 
117
  // don't let anyone be unsubscribed from the list - that should only happen on email campaigns
118
  // and someone clicking the unsubscribe linkage.
119
  if (!$this->subscribed) {
120
+ static::$handling_for = null;
121
  return false;
122
  }
123
 
131
  if (!empty($fn)) $merge_vars['FNAME'] = $fn;
132
  if (!empty($ln)) $merge_vars['LNAME'] = $ln;
133
 
134
+ // pull the transient key for this job.
135
+ $transient_id = mailchimp_get_transient_email_key($email);
136
+ $status_meta = mailchimp_get_subscriber_status_options($this->subscribed);
137
+
138
  try {
139
 
140
+ // check to see if the status meta has changed when a false response is given
141
+ if (mailchimp_check_serialized_transient_changed($transient_id, $status_meta) === false) {
142
+ mailchimp_debug(get_called_class(), "Skipping sync for {$email} because it was just pushed less than a minute ago.");
143
+ static::$handling_for = null;
144
+ return false;
145
+ }
146
+
147
  // see if we have a member.
148
+ $member_data = $api->member($list_id, $email);
149
 
150
  // if we're updating a member and the email is different, we need to delete the old person
151
  if (is_array($this->updated_data) && isset($this->updated_data['user_email'])) {
 
152
  if ($this->updated_data['user_email'] !== $email) {
 
153
  // delete the old
154
  $api->deleteMember($list_id, $this->updated_data['user_email']);
 
155
  // subscribe the new
156
+ $api->subscribe($list_id, $email, $status_meta['created'], $merge_vars);
157
+ mailchimp_tell_system_about_user_submit($email, $status_meta, 60);
158
+
159
+ if ($status_meta['created']) {
160
+ mailchimp_log('member.sync', 'Subscriber Swap '.$this->updated_data['user_email'].' to '.$email, array(
161
+ 'status' => $status_meta['created'],
162
+ 'merge_vars' => $merge_vars
163
+ ));
164
+ } else {
165
+ mailchimp_log('member.sync', 'Subscriber Swap '.$this->updated_data['user_email'].' to '.$email.' Pending Double OptIn', array(
166
+ 'status' => $status_meta['created'],
167
+ 'merge_vars' => $merge_vars
168
+ ));
169
+ }
170
+ static::$handling_for = null;
171
  return false;
172
  }
173
  }
174
+ if (isset($member_data['status']) && in_array($member_data['status'], array('unsubscribed', 'pending'))) {
175
+ mailchimp_log('member.sync', "Skipped Member Sync For {$email} because the current status is {$member_data['status']}", $merge_vars);
176
+ static::$handling_for = null;
177
+ return false;
178
+ }
179
  // ok let's update this member
180
+ $api->update($list_id, $email, $status_meta['updated'], $merge_vars);
181
+ mailchimp_tell_system_about_user_submit($email, $status_meta, 60);
182
+ mailchimp_log('member.sync', "Updated Member {$email}", array(
183
+ 'previous_status' => isset($member_data['status']) ? $member_data['status'] : 'no status on customer',
184
+ 'status' => $status_meta['updated'],
185
+ 'merge_vars' => $merge_vars
186
+ ));
187
+ static::$handling_for = null;
188
  } catch (\Exception $e) {
 
189
  // if we have a 404 not found, we can create the member
190
  if ($e->getCode() == 404) {
191
 
192
  try {
193
+ $api->subscribe($list_id, $user->user_email, $status_meta['created'], $merge_vars);
194
+ mailchimp_tell_system_about_user_submit($email, $status_meta, 60);
195
+ if ($status_meta['created']) {
196
+ mailchimp_log('member.sync', "Subscribed Member {$user->user_email}", array('status_if_new' => $status_meta['created'], 'merge_vars' => $merge_vars));
197
+ } else {
198
+ mailchimp_log('member.sync', "{$user->user_email} is Pending Double OptIn");
199
+ }
200
  } catch (\Exception $e) {
201
  mailchimp_log('member.sync', $e->getMessage());
202
  }
203
+ static::$handling_for = null;
204
  return false;
205
  }
 
206
  mailchimp_error('member.sync', mailchimp_error_trace($e, $user->user_email));
207
  }
208
 
209
+ static::$handling_for = null;
210
+
211
  return false;
212
  }
213
  }
includes/vendor/queue.php CHANGED
@@ -32,12 +32,12 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
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
 
@@ -45,7 +45,7 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
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
 
@@ -53,7 +53,7 @@ if (defined( 'WP_CLI' ) && WP_CLI) {
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
  }
32
  switch($args[0]) {
33
 
34
  case 'product_sync':
35
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Products());
36
  WP_CLI::success("queued up the product sync!");
37
  break;
38
 
39
  case 'order_sync':
40
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
41
  WP_CLI::success("queued up the order sync!");
42
  break;
43
 
45
  if (!isset($args[1])) {
46
  wp_die('You must specify an order id as the 2nd parameter.');
47
  }
48
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Order($args[1]));
49
  WP_CLI::success("queued up the order {$args[1]}!");
50
  break;
51
 
53
  if (!isset($args[1])) {
54
  wp_die('You must specify a product id as the 2nd parameter.');
55
  }
56
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($args[1]));
57
  WP_CLI::success("queued up the product {$args[1]}!");
58
  break;
59
  }
includes/vendor/queue/classes/worker/wp-http-worker.php CHANGED
@@ -63,8 +63,14 @@ if ( ! class_exists( 'WP_Http_Worker' ) ) {
63
  */
64
  public function handle()
65
  {
 
 
 
 
 
 
 
66
  if ( $this->is_worker_running() ) {
67
- // Worker already running, die
68
  wp_die();
69
  }
70
 
63
  */
64
  public function handle()
65
  {
66
+ // if we have the queue runner disabled, process 1 and exit.
67
+ if (mailchimp_queue_is_disabled()) {
68
+ $this->process_next_job();
69
+ wp_die();
70
+ }
71
+
72
+ // Worker already running, die
73
  if ( $this->is_worker_running() ) {
 
74
  wp_die();
75
  }
76
 
includes/vendor/queue/classes/wp-queue.php CHANGED
@@ -47,6 +47,11 @@ if ( ! class_exists( 'WP_Queue' ) ) {
47
 
48
  $id = $wpdb->insert( $this->table, $data );
49
 
 
 
 
 
 
50
  return $this;
51
  }
52
 
47
 
48
  $id = $wpdb->insert( $this->table, $data );
49
 
50
+ if (!$id) {
51
+ $name = get_class($job);
52
+ mailchimp_error("queue.failure", "Could not queue job {$name}, your database tables might not be properly set!");
53
+ }
54
+
55
  return $this;
56
  }
57
 
mailchimp-woocommerce.php CHANGED
@@ -13,11 +13,11 @@
13
  * @package MailChimp_WooCommerce
14
  *
15
  * @wordpress-plugin
16
- * Plugin Name: MailChimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
- * Description: MailChimp - WooCommerce plugin
19
- * Version: 2.1.9
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
13
  * @package MailChimp_WooCommerce
14
  *
15
  * @wordpress-plugin
16
+ * Plugin Name: Mailchimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
+ * Description: Mailchimp - WooCommerce plugin
19
+ * Version: 2.1.10
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
plugin_overview.md ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MailChimp for Woocommerce Integration
2
+
3
+ In this article, you’ll learn how to connect MailChimp for WooCommerce.
4
+
5
+ ## Before You Start
6
+
7
+ **Here are some things to know before you begin this process.**
8
+
9
+ - For the most up-to-date install instructions, read [Connect or Disconnect MailChimp for WooCommerce](http://kb.mailchimp.com/integrations/e-commerce/connect-or-disconnect-mailchimp-for-woocommerce).
10
+
11
+ - This plugin requires you to have the [WooCommerce plugin](https://wordpress.org/plugins/woocommerce) already installed and activated in WordPress.
12
+
13
+ - Your host environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
14
+
15
+ - We recommend you use this plugin in a staging environment before installing it on production servers.
16
+
17
+ - MailChimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
18
+
19
+ - WooCommerce customers who haven't signed up for marketing emails will appear in the Transactional portion of your list, and cannot be exported.
20
+
21
+ ## A Note for Current WooCommerce Integration Users
22
+
23
+ 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. If your WooCommerce store is already integrated with MailChimp via an integration that runs on an older version of MailChimp’s API, consider your current sales volume before you make any changes that might disrupt business.
24
+
25
+ You can run this new integration at the same time as your current WooCommerce integration for MailChimp. However, data from the older integration will display separately in subscriber profiles, and can’t be used with e-commerce features that require API 3.0.
26
+
27
+ ## Task Roadmap
28
+ **Here’s a brief overview of this multi-step process.**
29
+
30
+ - Install the plugin on your WordPress Admin site.
31
+ - Connect the plugin with your MailChimp API Key.
32
+ - Configure your list settings to complete the data sync process.
33
+ - Troubleshoot any sync or data feed issues by sharing logs with MailChimp support.
34
+
35
+ ## Install the Plugin
36
+ **To install the plugin, follow these steps.**
37
+
38
+ 1) Log in to your WordPress admin panel.
39
+ 2) In the left navigation panel, click **Plugins**, and choose **Add New**.
40
+
41
+ ![Add new](https://cloud.githubusercontent.com/assets/6547700/18677991/a7622bcc-7f28-11e6-8e8c-9bbdfa9861c7.png)
42
+
43
+ 3) Click **Upload Plugin**.
44
+
45
+ ![Upload](https://cloud.githubusercontent.com/assets/6547700/18677997/a76dab82-7f28-11e6-98e4-4309739cd840.png)
46
+
47
+ 4) Click **Choose File** to select the ZIP file for the plugin, then click **Install Now**.
48
+
49
+ ![Install Now](https://cloud.githubusercontent.com/assets/6547700/18677988/a760949c-7f28-11e6-9e13-13c23d044ad4.png)
50
+
51
+ 5) Click **Activate Plugin**.
52
+
53
+ ![Activate plugin](https://cloud.githubusercontent.com/assets/6547700/18677990/a760d7c2-7f28-11e6-8741-12c1efa7a991.png)
54
+
55
+ After you activate the plugin, you’ll be taken to the **Settings** page, where you will add your API key and configure your list settings.
56
+
57
+ ## Configure and Sync
58
+ **To configure your MailChimp settings for WooCommerce customers and sync them to MailChimp, follow these steps.**
59
+
60
+ 1) On the **Connect** tab, paste your MailChimp API key into the field, choose whether or not you want to send debugging logs to MailChimp, and click **Save all changes**. To learn how to generate a MailChimp API Key, read [About API Keys](http://kb.mailchimp.com/integrations/api-integrations/about-api-keys).
61
+
62
+ ![API key](https://cloud.githubusercontent.com/assets/19805049/18877771/3fca90e8-849c-11e6-9e3a-161a7b3936dd.png)
63
+
64
+ 2) Navigate to the **Store Settings** tab.
65
+
66
+ ![Store Settings](https://cloud.githubusercontent.com/assets/6547700/18677998/a76e5640-7f28-11e6-9fd3-d66949fa1413.png)
67
+
68
+ 3) Enter the contact and location details for your WooCommerce Store, and click **Save all changes**.
69
+
70
+ ![Save all changes](https://cloud.githubusercontent.com/assets/6547700/18677996/a76d126c-7f28-11e6-9150-4b289d20f057.png)
71
+
72
+ 4) Navigate to the **List Settings** tab.
73
+
74
+ ![List Settings tab](https://cloud.githubusercontent.com/assets/19805049/18878446/961221d0-849e-11e6-99bb-175c22bf921e.png)
75
+
76
+ 5) Choose the list you want to sync, decide whether or not you want to auto-subscribe existing customers, set the subscribe message you want customers to see at checkout, and click **Save all changes**.
77
+
78
+ ![Save all changes](https://cloud.githubusercontent.com/assets/19805049/18877772/3fd24162-849c-11e6-8442-79ec4550b8ac.png)
79
+
80
+ All set! When you click **Save all changes**, we’ll start syncing your WooCommerce customers to MailChimp. To view progress, check the **Sync Status** tab.
81
+
82
+ If you have no lists in your MailChimp account, you will be given the option to create a new list on the **List Defaults** tab. To create a new list, set your list defaults, and click **Save all Changes** when you’re done. We’ll create a MailChimp list for you, and begin the data sync.
83
+
84
+ ![List Defaults tab](https://cloud.githubusercontent.com/assets/19805049/18956260/cffd3926-8628-11e6-9c68-9fe3c964c75c.png)
85
+
86
+ ## Next Steps
87
+ After you connect, you can do a lot with the the data you collect, like build segments, send Automation workflows, track purchases, and view results.
88
+
89
+ Find out everything MailChimp has to offer in our article, [How to Use MailChimp for E-Commerce](http://kb.mailchimp.com/integrations/e-commerce/how-to-use-mailchimp-for-e-commerce).
90
+
91
+ # Deactivate or Delete the Plugin
92
+ When you deactivate MailChimp for WooCommerce, it stops the sync but doesn’t remove the plugin. You can always re-activate the sync, which will backfill data at a later point in time.
93
+ To deactivate MailChimp for WooCommerce, follow these steps.
94
+
95
+ 1) Log in to your WordPress admin panel.
96
+
97
+ 2) In the left navigation panel, click **Plugins**, and choose **Installed Plugins**.
98
+
99
+ ![Installed Plugins](https://cloud.githubusercontent.com/assets/6547700/18677993/a76542ee-7f28-11e6-99dd-cfd6c1f5c24a.png)
100
+
101
+ 3) Click the box next to the MailChimp for WooCommerce plugin, and click **Deactivate**.
102
+
103
+ ![Deactivate](https://cloud.githubusercontent.com/assets/6547700/18677992/a762b844-7f28-11e6-9679-8d6c6a1d731d.png)
104
+
105
+ After you deactivate the plugin, you will have the option to **Delete** it. If you delete the plugin, you will retain customers’ email addresses in your list, but remove all associated e-commerce data.
uninstall.php CHANGED
@@ -34,19 +34,35 @@ if (!isset($mailchimp_woocommerce_spl_autoloader) || $mailchimp_woocommerce_spl_
34
  include_once "bootstrap.php";
35
  }
36
 
37
- try {
38
- if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
39
- if (isset($options['mailchimp_api_key'])) {
40
- $store_id = get_option('mailchimp-woocommerce-store_id', false);
41
- if (!empty($store_id)) {
42
- $api = new MailChimp_WooCommerce_MailChimpApi($options['mailchimp_api_key']);
43
- $result = $api->deleteStore($store_id) ? 'has been deleted' : 'did not delete';
44
- error_log("store id {$store_id} {$result} MailChimp");
 
 
45
  }
46
  }
 
 
47
  }
48
- } catch (\Exception $e) {
49
- error_log($e->getMessage().' on '.$e->getLine().' in '.$e->getFile());
50
  }
51
 
52
- mailchimp_clean_database();
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  include_once "bootstrap.php";
35
  }
36
 
37
+ function mailchimp_woocommerce_uninstall() {
38
+ try {
39
+ if (($options = get_option('mailchimp-woocommerce', false)) && is_array($options)) {
40
+ if (isset($options['mailchimp_api_key'])) {
41
+ $store_id = get_option('mailchimp-woocommerce-store_id', false);
42
+ if (!empty($store_id)) {
43
+ $api = new MailChimp_WooCommerce_MailChimpApi($options['mailchimp_api_key']);
44
+ $result = $api->deleteStore($store_id) ? 'has been deleted' : 'did not delete';
45
+ error_log("store id {$store_id} {$result} MailChimp");
46
+ }
47
  }
48
  }
49
+ } catch (\Exception $e) {
50
+ error_log($e->getMessage().' on '.$e->getLine().' in '.$e->getFile());
51
  }
52
+ mailchimp_clean_database();
 
53
  }
54
 
55
+ if (!is_multisite()) {
56
+ mailchimp_woocommerce_uninstall();
57
+ } else {
58
+ global $wpdb;
59
+ try {
60
+ foreach ($wpdb->get_col("SELECT blog_id FROM $wpdb->blogs") as $mailchimp_current_blog_id) {
61
+ switch_to_blog($mailchimp_current_blog_id);
62
+ mailchimp_woocommerce_uninstall();
63
+ }
64
+ restore_current_blog();
65
+ } catch (\Exception $e) {}
66
+ }
67
+
68
+