MailChimp for WooCommerce - Version 2.4.0

Version Description

Download this release

Release Info

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

Code changes from version 2.3.6 to 2.4.0

Files changed (85) hide show
  1. CHANGELOG.txt +245 -0
  2. README.txt +37 -264
  3. admin/class-mailchimp-woocommerce-admin.php +94 -34
  4. bootstrap.php +143 -64
  5. includes/api/class-mailchimp-woocommerce-transform-coupons.php +9 -13
  6. includes/api/class-mailchimp-woocommerce-transform-orders-wc3.php +6 -18
  7. includes/api/class-mailchimp-woocommerce-transform-products.php +5 -4
  8. includes/class-mailchimp-woocommerce-queue.php +0 -226
  9. includes/class-mailchimp-woocommerce-rest-api.php +36 -22
  10. includes/class-mailchimp-woocommerce-service.php +46 -8
  11. includes/class-mailchimp-woocommerce.php +6 -3
  12. includes/processes/class-mailchimp-woocommerce-abstract-sync.php +77 -153
  13. includes/processes/class-mailchimp-woocommerce-cart-update.php +9 -1
  14. includes/processes/class-mailchimp-woocommerce-full-sync-manager.php +166 -0
  15. includes/processes/class-mailchimp-woocommerce-job.php +12 -15
  16. includes/processes/class-mailchimp-woocommerce-process-coupons-initial-sync.php +0 -21
  17. includes/processes/class-mailchimp-woocommerce-process-coupons.php +1 -37
  18. includes/processes/class-mailchimp-woocommerce-process-orders.php +1 -164
  19. includes/processes/class-mailchimp-woocommerce-process-products.php +1 -59
  20. includes/processes/class-mailchimp-woocommerce-single-coupon.php +17 -5
  21. includes/processes/class-mailchimp-woocommerce-single-order.php +134 -42
  22. includes/processes/class-mailchimp-woocommerce-single-product.php +9 -1
  23. includes/vendor/action-scheduler/.editorconfig +0 -24
  24. includes/vendor/action-scheduler/.gitattributes +0 -13
  25. includes/vendor/action-scheduler/.gitignore +0 -4
  26. includes/vendor/action-scheduler/.travis.yml +0 -45
  27. includes/vendor/action-scheduler/Gruntfile.js +0 -57
  28. includes/vendor/action-scheduler/action-scheduler.php +7 -7
  29. includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php +19 -3
  30. includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php +49 -2
  31. includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php +12 -14
  32. includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php +5 -6
  33. includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php +4 -2
  34. includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php +1 -1
  35. includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php +2 -1
  36. includes/vendor/action-scheduler/codecov.yml +0 -13
  37. includes/vendor/action-scheduler/composer.json +0 -36
  38. includes/vendor/action-scheduler/composer.lock +0 -4878
  39. includes/vendor/action-scheduler/docs/_layouts/default.html +5 -2
  40. includes/vendor/action-scheduler/docs/android-chrome-192x192.png +0 -0
  41. includes/vendor/action-scheduler/docs/android-chrome-256x256.png +0 -0
  42. includes/vendor/action-scheduler/docs/api.md +8 -53
  43. includes/vendor/action-scheduler/docs/apple-touch-icon.png +0 -0
  44. includes/vendor/action-scheduler/docs/assets/css/style.scss +2 -2
  45. includes/vendor/action-scheduler/docs/faq.md +16 -22
  46. includes/vendor/action-scheduler/docs/favicon-16x16.png +0 -0
  47. includes/vendor/action-scheduler/docs/favicon-32x32.png +0 -0
  48. includes/vendor/action-scheduler/docs/favicon.ico +0 -0
  49. includes/vendor/action-scheduler/docs/index.md +13 -13
  50. includes/vendor/action-scheduler/docs/perf.md +16 -21
  51. includes/vendor/action-scheduler/docs/usage.md +4 -8
  52. includes/vendor/action-scheduler/docs/version3-0.md +0 -48
  53. includes/vendor/action-scheduler/docs/wp-cli.md +1 -1
  54. includes/vendor/action-scheduler/package-lock.json +0 -2138
  55. includes/vendor/action-scheduler/package.json +0 -39
  56. includes/vendor/action-scheduler/phpcs.xml +0 -39
  57. includes/vendor/action-scheduler/tests/bootstrap.php +0 -3
  58. includes/vendor/action-scheduler/tests/phpunit.xml.dist +1 -17
  59. includes/vendor/action-scheduler/tests/phpunit/ActionScheduler_Mock_Async_Request_QueueRunner.php +0 -19
  60. includes/vendor/action-scheduler/tests/phpunit/ActionScheduler_Mocker.php +0 -35
  61. includes/vendor/action-scheduler/tests/phpunit/jobs/ActionScheduler_NullAction_Test.php +1 -1
  62. includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_DBStoreMigrator_Test.php +0 -26
  63. includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_DBStore_Test.php +0 -396
  64. includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_HybridStore_Test.php +0 -272
  65. includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_wpPostStore_Test.php +4 -43
  66. includes/vendor/action-scheduler/tests/phpunit/lock/ActionScheduler_OptionLock_Test.php +0 -45
  67. includes/vendor/action-scheduler/tests/phpunit/logging/ActionScheduler_DBLogger_Test.php +0 -139
  68. includes/vendor/action-scheduler/tests/phpunit/logging/ActionScheduler_wpCommentLogger_Test.php +10 -43
  69. includes/vendor/action-scheduler/tests/phpunit/migration/ActionMigrator_Test.php +0 -145
  70. includes/vendor/action-scheduler/tests/phpunit/migration/BatchFetcher_Test.php +0 -76
  71. includes/vendor/action-scheduler/tests/phpunit/migration/Config_Test.php +0 -33
  72. includes/vendor/action-scheduler/tests/phpunit/migration/LogMigrator_Test.php +0 -44
  73. includes/vendor/action-scheduler/tests/phpunit/migration/Runner_Test.php +0 -92
  74. includes/vendor/action-scheduler/tests/phpunit/migration/Scheduler_Test.php +0 -122
  75. includes/vendor/action-scheduler/tests/phpunit/procedural_api/procedural_api_Test.php +9 -46
  76. includes/vendor/action-scheduler/tests/phpunit/runner/ActionScheduler_QueueCleaner_Test.php +2 -2
  77. includes/vendor/action-scheduler/tests/phpunit/runner/ActionScheduler_QueueRunner_Test.php +34 -102
  78. includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_CronSchedule_Test.php +9 -40
  79. includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_IntervalSchedule_Test.php +4 -13
  80. includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_NullSchedule_Test.php +1 -1
  81. includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_SimpleSchedule_Test.php +4 -4
  82. mailchimp-woocommerce.php +1 -1
  83. public/class-mailchimp-woocommerce-public.php +1 -0
  84. public/js/mailchimp-woocommerce-public.js +1 -1
  85. public/js/mailchimp-woocommerce-public.min.js +1 -1
CHANGELOG.txt ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ == Changelog ==
2
+ = 2.4.0 =
3
+ * update for latest Action Scheduler v3.1.4
4
+ * adds customer language on Cart and Order sync
5
+ * adds batch processing for queues
6
+ * support for Brazilian Portuguese pt_BR Language
7
+ = 2.3.6 =
8
+ * fix for Audience Defaults and Settings not visible
9
+ * improved campaign tracking on external payment gateways and API endpoints
10
+ * fix for transactionals being subscribed after force resync
11
+ = 2.3.5 - =
12
+ * updates to Action Scheduler
13
+ * create new audience option
14
+ * fixes small oauth screen layout
15
+ * number format on sync stats
16
+ * update readme description
17
+ = 2.3.4 =
18
+ * updates to Action Scheduler
19
+ = 2.3.3 =
20
+ * fixes abandoned cart issues with Paypal
21
+ * resolves Action Scheduler 3.0 compatiblity issues
22
+ * Fixes missing product images
23
+ = 2.3.2 =
24
+ * update to action scheduler v3.0.1
25
+ * adds low-bandwidth setting on sync
26
+ * fixes audience defaults settings to Mailchimp not passed
27
+ * tweaks to review banner behavior
28
+ * required fields API update
29
+ * fix for orders with deleted products
30
+ * support for orders with 0 line items
31
+ = 2.3.1 =
32
+ * adds fallback for mb_strpos if extension is not installed
33
+ * implements communications box on sync page
34
+ * adds account create for Mailchimp
35
+ * fixes Pending Payment and On-hold status orders passed to Mailchimp
36
+ * fixes for WooCommerce Fatal-errors
37
+ * support for WooCommerce vendor feature
38
+ * support for Shop Manager role by Woocommerce
39
+ * update to Text Domain for wp translation
40
+ * adds banner to review plugin after audience is synced
41
+ * support for user language based on wp get_locale() at order placement
42
+ = 2.3 =
43
+ * adds action scheduler queue system
44
+ * documentation for Custom Merge Tags
45
+ * adds more specific installation requirements
46
+ * fixes PHP Error in class-mailchimp-order.php
47
+ * fixes pop up blocks on connection
48
+ * fixes unable to sync without accepting to auto subscribe existing customers
49
+ * documentation for wp-cli class queue-command
50
+ = 2.2 =
51
+ * plugin reskin
52
+ * support for oauth to Mailchimp
53
+ * fixes sync issues with altered order IDs
54
+ * fixes issues with trashed coupons
55
+ = 2.1.17 =
56
+ * re add resync button to sync tab, after sync finishes
57
+ * renamed 'merge_vars' to 'merge_fields' as per new Mailchimp naming convention
58
+ * fixes issues with cloudflare
59
+ * honors woo currency settings
60
+ * fix for failing custom coupon type
61
+ = 2.1.16 =
62
+ * support for HTML in opt-in checkbox
63
+ * support for language translation
64
+ * fixes abandoned_cart.error
65
+ * support for audience tags
66
+ * adds responsive checkboxes for newsletter settings
67
+ * adds sanitizing function to order ids
68
+ * copy change from List terminology to Audience
69
+ = 2.1.15 =
70
+ * adds optional feedback survey on deactivate
71
+ * updates syncing engine to use REST API
72
+ * fixes edited orders syncing old and new products into Mailchimp
73
+ * adds support for remove_action
74
+ = 2.1.14 =
75
+ * Adds support for filter on newsletter field
76
+ * fixes inactive log delete button
77
+ * fixes Mailchimp option page flow and displays list defaults tab
78
+ * fixes resource not found error on logs
79
+ * fixes API Key Request errors
80
+ * fixes transactional to pending double opt in issue
81
+ * updated Variables passed to filter
82
+ = 2.1.13 =
83
+ * fixed spelling issues in plugin meta
84
+ * changed submission sequence for products to use the PATCH endpoint when applicable
85
+ * fallback on order submissions when products are not found in Mailchimp.
86
+ = 2.1.12 =
87
+ * adds error handling for blocked admin-ajax.php files
88
+ * adds support for custom merge variables
89
+ * removes global variable overwrite of REMOTE_ADDR
90
+ * fixes signup form not adding customers to Mailchimp
91
+ * support for rate limiting
92
+ * PHP 7.0 requirement messaging
93
+ * support for WooCommerce 3.5.0
94
+ * ignores amazon marketplace addresses
95
+ * fixes cart entries never being removed
96
+ = 2.1.11 =
97
+ * fix double opt in sending on transactional customers
98
+ = 2.1.10 =
99
+ * skip product when no variant can be loaded
100
+ * better validation for the view order url
101
+ * Add Initial sync label on Sync Tab
102
+ * Multisite Delete and deactivate improvements
103
+ * Mailchimp Order Notification issues support for downloadable and virtual products
104
+ * http worker lock improvement
105
+ * Add documentation about Multisite setup
106
+ * Add documentaiton for on-demand syncing
107
+ = 2.1.9 =
108
+ * Improved UI feedback when API key is invalid
109
+ * Add documentation about product categories not being supported.
110
+ * Fix order count and order total with guest accounts.
111
+ = 2.1.8 =
112
+ * GDPR compliance
113
+ * changed css class on checkbox for registration issues
114
+ * added translation for newsletter checkbox text
115
+ * only show newsletter checkbox when plugin is fully configured
116
+ * fixed various sign up form conflicts with newsletter registration button
117
+ * added link to privacy policy
118
+ * force javascript into footer for performance gains
119
+ * fix logged in user abandoned cart tracking
120
+ * WPML support
121
+ * uninstall - reinstall clean ups
122
+ = 2.1.7 =
123
+ * fixed autoloader filepath for queue command
124
+ = 2.1.6 =
125
+ * moved to an autoloader for performance enhancement
126
+ * flush database tables on un-installation to assist with stale records in the queue
127
+ * turn on standard debugging by default to help troubleshoot issues
128
+ * moved the plugin button to the left main navigation
129
+ * allow store owners to select the image size being used for products
130
+ * fix paypal new order bug where it did not send on initial placement
131
+ * add additional configuration success checks for the plugin being configured before pushing any jobs into the queue
132
+ * fix the multisite network activation issue
133
+ * hide the opt in checkbox for already logged in customers that were previously subscribed
134
+ * miscellaneous UI enhancements
135
+ = 2.1.5 =
136
+ * is_configured filters applied before certain jobs were firing and failing.
137
+ = 2.1.5 =
138
+ * added support for Polish (zloty - zł) and Moldovan Leu currencies
139
+ * update currency code for Belarusian Rouble
140
+ * queue performance enhancement
141
+ = 2.1.4 =
142
+ * updated wordpress compatibility
143
+ * updated sync details tab to show more informative stats
144
+ * queue job processing performance enhancement
145
+ * added an integrity check for queued jobs that were not getting processed
146
+ = 2.1.3 =
147
+ * Fix subscriber status for repeat transactional customers to stay transactional.
148
+ * Remove shipping and billing address requirements for order submission.
149
+ * Do not unsubscribe someone who has previously subscribed when unchecking the newsletter sign up box.
150
+ * Update newsletter checkbox style to be consistent with WooCommerce styles.
151
+ * Make sure WooCommerce plugin is running before running any plugin code.
152
+ * Fix compatibility issue with WP-Cron
153
+ = 2.1.2 =
154
+ * Fix store deletion on plugin deactivation
155
+ * Correct shipping name is now used on order notifications.
156
+ * Admin orders are now handled appropriately.
157
+ * Skip incomplete or cancelled orders from being submitted when new.
158
+ * fix hidden or inactive products from being recommended.
159
+ = 2.1.1 =
160
+ * 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"
161
+ = 2.1.0 =
162
+ * Added Promo Code support.
163
+ = 2.0.2 =
164
+ * Added new logs feature to help troubleshoot isolated sync and data feed issues.
165
+ * Fixed bug with setting customers as Transactional during checkout if they had already opted in previously.
166
+ * Fixed bug where abandoned cart automation still fired after a customer completed an order.
167
+ = 2.0.1 =
168
+ * Added support for "Connected Site" scripts.
169
+ * Made physical address a required field for store setup.
170
+ * Fixed order, cart timestamps to begin using UTC.
171
+ = 2.0 =
172
+ * Support WooComerce 3.0
173
+ * Support for manually uploaded WooCommerce
174
+ * Fix for sync issues
175
+ * Fix for guest orders sync issue
176
+ * Remove Mailchimp debug logger
177
+ = 1.1.1 =
178
+ * Support for site url changes
179
+ * Fix for WP Version 4.4 compatibility issues
180
+ = 1.1.0 =
181
+ * Fix for persisting opt-in status
182
+ * Pass order URLs to Mailchimp
183
+ * Pass partial refund status to Mailchimp
184
+ = 1.0.9 =
185
+ * billing and shipping address support for orders
186
+ = 1.0.8 =
187
+ * add landing_site, financial status and discount information for orders
188
+ * fix to support php 5.3
189
+ = 1.0.7 =
190
+ * add options to move, hide and change defaults for opt-in checkbox
191
+ * add ability to re-sync and display connection details
192
+ * support for subscriptions without orders
193
+ * additional small fixes and some internal logging removal
194
+ = 1.0.6 =
195
+ * fixed conflict with the plugin updater where the class could not be loaded correctly.
196
+ * fixed error validation for store name.
197
+ * fixed cross device abandoned cart url's
198
+ = 1.0.4 =
199
+ * fix for Abandoned Carts without cookies
200
+ = 1.0.3 =
201
+ * fixed cart posts on dollar amounts greater than 1000
202
+ = 1.0.2 =
203
+ * title correction for Product Variants
204
+ * added installation checks for WooCommerce and phone contact info
205
+ * support for free orders
206
+ = 1.0 =
207
+ * added is_synicng flag to prevent sends during backfill
208
+ * fix for conflicts with Gravity Forms Pro and installation issues
209
+ * skip all Amazon orders
210
+ * allow users to set opt-in for pre-existing customers during first sync
211
+ * add Plugin Updater
212
+ = 0.1.22 =
213
+ * flag quantity as 1 if the product does not manage inventory
214
+ = 0.1.21 =
215
+ * php version check to display warnings < 5.5
216
+ = 0.1.19 =
217
+ * fix campaign tracking on new orders
218
+ = 0.1.18 =
219
+ * check woocommerce dependency before activating the plugin
220
+ = 0.1.17 =
221
+ * fix php version syntax errors for array's
222
+ = 0.1.16 =
223
+ * fix namespace conflicts
224
+ * fix free order 0.00 issue
225
+ * fix product variant naming issue
226
+ = 0.1.15 =
227
+ * adding special Mailchimp header to requests
228
+ = 0.1.14 =
229
+ * removing jquery dependencies
230
+ = 0.1.13 =
231
+ * fixing a number format issue on total_spent
232
+ = 0.1.12 =
233
+ * skipping orders placed through amazon due to seller agreements
234
+ = 0.1.11 =
235
+ * removed an extra debug log that was not needed
236
+ = 0.1.10 =
237
+ * altered debug logging and fixed store settings validation requirements
238
+ = 0.1.9 =
239
+ * using fallback to stream context during failed patch requests
240
+ = 0.1.8 =
241
+ * fixing http request header for larger patch requests
242
+ = 0.1.7 =
243
+ * fixing various bugs with the sync and product issues.
244
+ = 0.1.2 =
245
+ * fixed admin order update hook.
README.txt CHANGED
@@ -4,7 +4,7 @@ Tags: ecommerce,email,workflows,mailchimp
4
  Donate link: https://mailchimp.com
5
  Requires at least: 4.9
6
  Tested up to: 5.4
7
- Stable tag: 2.3.6
8
  Requires PHP: 7.0
9
  WC requires at least: 3.5
10
  WC tested up to: 4.0
@@ -14,8 +14,8 @@ Connect your store to your Mailchimp audience to track sales, create targeted em
14
 
15
  == Description ==
16
  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.
17
- With Mailchimp for WooCommerce, you’ll have the power to:
18
- - Sync audience 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.
@@ -28,277 +28,50 @@ With Mailchimp for WooCommerce, you’ll have the power to:
28
  This plugin supports our most powerful API 3.0 features, and is intended for users who have not yet integrated their WooCommerce stores with Mailchimp.
29
  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.
30
  WordPress.com compatibility is limited to Business tier users only.
31
- At this time, the synchronization of product categories from WooCommerce to Mailchimp is not supported.
32
  == Installation ==
33
  ###Before You Start
34
  Here are some things to know before you begin this process.
35
  - This plugin requires you to have the [WooCommerce plugin](https://woocommerce.com/) already installed and activated in WordPress.
36
  - Your hosting environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
 
37
  - 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).
38
  - Mailchimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
39
  - WooCommerce customers who haven't signed up for marketing emails will appear in the **Transactional** portion of your audience, and cannot be exported.
40
- ###Task Roadmap
 
41
  You’ll need to do a few things to connect your WooCommerce store to Mailchimp.
42
  - Download the plugin.
43
  - Install the plugin on your WordPress Admin site.
44
  - Connect securely to your Mailchimp account via secure OAuth pop-up window.
45
- - Configure your audience settings to complete the data sync process.
46
- ###Advanced Queue Setup In CLI mode
47
- To optimize the performance of your Mailchimp integration - it is recommended that you run the queue in CLI mode.
48
- First define a constant in your config file
49
- `define('DISABLE_WP_HTTP_WORKER', true);`
50
- You have 2 options to run this process:
51
- 1. On a cron schedule every minute:
52
- `* * * * * /usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
53
- 2. Using a process manager like Monit or Supervisord:
54
- `/usr/bin/wp --url=http://yourdomain.com --path=/full/path/to/install/ queue listen`
55
- ### Optional on-demand queue processing
56
- 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:
57
- `define('MAILCHIMP_DISABLE_QUEUE', true);`
58
- This is helpful with high CPU usage on small servers by making a call to the admin-ajax file and manually processing a single request at a time.
59
- ### Multi-site Setups
60
- The Mailchimp for WooCommerce supports Wordpress Multi Sites and below are a few things to note.
61
- - Each site that has the plugin installed is a separate connection to Mailchimp.
62
- - 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 Audience with WooCommerce.
63
- - Deleting removes the connection between Mailchimp and WooCommerce, and uninstalls the plugin from your site.
64
- Refer to the Wordpress Codex for more information about [Multisite Network Administration](https://codex.wordpress.org/Multisite_Network_Administration)
 
 
 
 
 
65
  == Changelog ==
66
- = 2.3.6 =
67
- * fix for Audience Defaults and Settings not visible
68
- * improved campaign tracking on external payment gateways and API endpoints
69
- * fix for transactionals being subscribed after force resync
70
- = 2.3.5 =
71
- * updates to Action Scheduler
72
- * create new audience option
73
- * fixes small oauth screen layout
74
- * number format on sync stats
75
- * update readme description
76
- = 2.3.4 =
77
- * updates to Action Scheduler
78
- = 2.3.3 =
79
- * fixes abandoned cart issues with Paypal
80
- * resolves Action Scheduler 3.0 compatiblity issues
81
- * Fixes missing product images
82
- = 2.3.2 =
83
- * update to action scheduler v3.0.1
84
- * adds low-bandwidth setting on sync
85
- * fixes audience defaults settings to Mailchimp not passed
86
- * tweaks to review banner behavior
87
- * required fields API update
88
- * fix for orders with deleted products
89
- * support for orders with 0 line items
90
- = 2.3.1 =
91
- * adds fallback for mb_strpos if extension is not installed
92
- * implements communications box on sync page
93
- * adds account create for Mailchimp
94
- * fixes Pending Payment and On-hold status orders passed to Mailchimp
95
- * fixes for WooCommerce Fatal-errors
96
- * support for WooCommerce vendor feature
97
- * support for Shop Manager role by Woocommerce
98
- * update to Text Domain for wp translation
99
- * adds banner to review plugin after audience is synced
100
- * support for user language based on wp get_locale() at order placement
101
- = 2.3 =
102
- * adds action scheduler queue system
103
- * documentation for Custom Merge Tags
104
- * adds more specific installation requirements
105
- * fixes PHP Error in class-mailchimp-order.php
106
- * fixes pop up blocks on connection
107
- * fixes unable to sync without accepting to auto subscribe existing customers
108
- * documentation for wp-cli class queue-command
109
- = 2.2 =
110
- * plugin reskin
111
- * support for oauth to Mailchimp
112
- * fixes sync issues with altered order IDs
113
- * fixes issues with trashed coupons
114
- = 2.1.17 =
115
- * re add resync button to sync tab, after sync finishes
116
- * renamed 'merge_vars' to 'merge_fields' as per new Mailchimp naming convention
117
- * fixes issues with cloudflare
118
- * honors woo currency settings
119
- * fix for failing custom coupon type
120
- = 2.1.16 =
121
- * support for HTML in opt-in checkbox
122
- * support for language translation
123
- * fixes abandoned_cart.error
124
- * support for audience tags
125
- * adds responsive checkboxes for newsletter settings
126
- * adds sanitizing function to order ids
127
- * copy change from List terminology to Audience
128
- = 2.1.15 =
129
- * adds optional feedback survey on deactivate
130
- * updates syncing engine to use REST API
131
- * fixes edited orders syncing old and new products into Mailchimp
132
- * adds support for remove_action
133
- = 2.1.14 =
134
- * Adds support for filter on newsletter field
135
- * fixes inactive log delete button
136
- * fixes Mailchimp option page flow and displays list defaults tab
137
- * fixes resource not found error on logs
138
- * fixes API Key Request errors
139
- * fixes transactional to pending double opt in issue
140
- * updated Variables passed to filter
141
- = 2.1.13 =
142
- * fixed spelling issues in plugin meta
143
- * changed submission sequence for products to use the PATCH endpoint when applicable
144
- * fallback on order submissions when products are not found in Mailchimp.
145
- = 2.1.12 =
146
- * adds error handling for blocked admin-ajax.php files
147
- * adds support for custom merge variables
148
- * removes global variable overwrite of REMOTE_ADDR
149
- * fixes signup form not adding customers to Mailchimp
150
- * support for rate limiting
151
- * PHP 7.0 requirement messaging
152
- * support for WooCommerce 3.5.0
153
- * ignores amazon marketplace addresses
154
- * fixes cart entries never being removed
155
- = 2.1.11 =
156
- * fix double opt in sending on transactional customers
157
- = 2.1.10 =
158
- * skip product when no variant can be loaded
159
- * better validation for the view order url
160
- * Add Initial sync label on Sync Tab
161
- * Multisite Delete and deactivate improvements
162
- * Mailchimp Order Notification issues support for downloadable and virtual products
163
- * http worker lock improvement
164
- * Add documentation about Multisite setup
165
- * Add documentaiton for on-demand syncing
166
- = 2.1.9 =
167
- * Improved UI feedback when API key is invalid
168
- * Add documentation about product categories not being supported.
169
- * Fix order count and order total with guest accounts.
170
- = 2.1.8 =
171
- * GDPR compliance
172
- * changed css class on checkbox for registration issues
173
- * added translation for newsletter checkbox text
174
- * only show newsletter checkbox when plugin is fully configured
175
- * fixed various sign up form conflicts with newsletter registration button
176
- * added link to privacy policy
177
- * force javascript into footer for performance gains
178
- * fix logged in user abandoned cart tracking
179
- * WPML support
180
- * uninstall - reinstall clean ups
181
- = 2.1.7 =
182
- * fixed autoloader filepath for queue command
183
- = 2.1.6 =
184
- * moved to an autoloader for performance enhancement
185
- * flush database tables on un-installation to assist with stale records in the queue
186
- * turn on standard debugging by default to help troubleshoot issues
187
- * moved the plugin button to the left main navigation
188
- * allow store owners to select the image size being used for products
189
- * fix paypal new order bug where it did not send on initial placement
190
- * add additional configuration success checks for the plugin being configured before pushing any jobs into the queue
191
- * fix the multisite network activation issue
192
- * hide the opt in checkbox for already logged in customers that were previously subscribed
193
- * miscellaneous UI enhancements
194
- = 2.1.5 =
195
- * is_configured filters applied before certain jobs were firing and failing.
196
- = 2.1.5 =
197
- * added support for Polish (zloty - zł) and Moldovan Leu currencies
198
- * update currency code for Belarusian Rouble
199
- * queue performance enhancement
200
- = 2.1.4 =
201
- * updated wordpress compatibility
202
- * updated sync details tab to show more informative stats
203
- * queue job processing performance enhancement
204
- * added an integrity check for queued jobs that were not getting processed
205
- = 2.1.3 =
206
- * Fix subscriber status for repeat transactional customers to stay transactional.
207
- * Remove shipping and billing address requirements for order submission.
208
- * Do not unsubscribe someone who has previously subscribed when unchecking the newsletter sign up box.
209
- * Update newsletter checkbox style to be consistent with WooCommerce styles.
210
- * Make sure WooCommerce plugin is running before running any plugin code.
211
- * Fix compatibility issue with WP-Cron
212
- = 2.1.2 =
213
- * Fix store deletion on plugin deactivation
214
- * Correct shipping name is now used on order notifications.
215
- * Admin orders are now handled appropriately.
216
- * Skip incomplete or cancelled orders from being submitted when new.
217
- * fix hidden or inactive products from being recommended.
218
- = 2.1.1 =
219
- * 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"
220
- = 2.1.0 =
221
- * Added Promo Code support.
222
- = 2.0.2 =
223
- * Added new logs feature to help troubleshoot isolated sync and data feed issues.
224
- * Fixed bug with setting customers as Transactional during checkout if they had already opted in previously.
225
- * Fixed bug where abandoned cart automation still fired after a customer completed an order.
226
- = 2.0.1 =
227
- * Added support for "Connected Site" scripts.
228
- * Made physical address a required field for store setup.
229
- * Fixed order, cart timestamps to begin using UTC.
230
- = 2.0 =
231
- * Support WooComerce 3.0
232
- * Support for manually uploaded WooCommerce
233
- * Fix for sync issues
234
- * Fix for guest orders sync issue
235
- * Remove Mailchimp debug logger
236
- = 1.1.1 =
237
- * Support for site url changes
238
- * Fix for WP Version 4.4 compatibility issues
239
- = 1.1.0 =
240
- * Fix for persisting opt-in status
241
- * Pass order URLs to Mailchimp
242
- * Pass partial refund status to Mailchimp
243
- = 1.0.9 =
244
- * billing and shipping address support for orders
245
- = 1.0.8 =
246
- * add landing_site, financial status and discount information for orders
247
- * fix to support php 5.3
248
- = 1.0.7 =
249
- * add options to move, hide and change defaults for opt-in checkbox
250
- * add ability to re-sync and display connection details
251
- * support for subscriptions without orders
252
- * additional small fixes and some internal logging removal
253
- = 1.0.6 =
254
- * fixed conflict with the plugin updater where the class could not be loaded correctly.
255
- * fixed error validation for store name.
256
- * fixed cross device abandoned cart url's
257
- = 1.0.4 =
258
- * fix for Abandoned Carts without cookies
259
- = 1.0.3 =
260
- * fixed cart posts on dollar amounts greater than 1000
261
- = 1.0.2 =
262
- * title correction for Product Variants
263
- * added installation checks for WooCommerce and phone contact info
264
- * support for free orders
265
- = 1.0 =
266
- * added is_synicng flag to prevent sends during backfill
267
- * fix for conflicts with Gravity Forms Pro and installation issues
268
- * skip all Amazon orders
269
- * allow users to set opt-in for pre-existing customers during first sync
270
- * add Plugin Updater
271
- = 0.1.22 =
272
- * flag quantity as 1 if the product does not manage inventory
273
- = 0.1.21 =
274
- * php version check to display warnings < 5.5
275
- = 0.1.19 =
276
- * fix campaign tracking on new orders
277
- = 0.1.18 =
278
- * check woocommerce dependency before activating the plugin
279
- = 0.1.17 =
280
- * fix php version syntax errors for array's
281
- = 0.1.16 =
282
- * fix namespace conflicts
283
- * fix free order 0.00 issue
284
- * fix product variant naming issue
285
- = 0.1.15 =
286
- * adding special Mailchimp header to requests
287
- = 0.1.14 =
288
- * removing jquery dependencies
289
- = 0.1.13 =
290
- * fixing a number format issue on total_spent
291
- = 0.1.12 =
292
- * skipping orders placed through amazon due to seller agreements
293
- = 0.1.11 =
294
- * removed an extra debug log that was not needed
295
- = 0.1.10 =
296
- * altered debug logging and fixed store settings validation requirements
297
- = 0.1.9 =
298
- * using fallback to stream context during failed patch requests
299
- = 0.1.8 =
300
- * fixing http request header for larger patch requests
301
- = 0.1.7 =
302
- * fixing various bugs with the sync and product issues.
303
- = 0.1.2 =
304
- * fixed admin order update hook.
4
  Donate link: https://mailchimp.com
5
  Requires at least: 4.9
6
  Tested up to: 5.4
7
+ Stable tag: 2.4.0
8
  Requires PHP: 7.0
9
  WC requires at least: 3.5
10
  WC tested up to: 4.0
14
 
15
  == Description ==
16
  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.
17
+ ###What you can do with this plugin
18
+ - Sync to your Audience in Mailchimp with 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.
28
  This plugin supports our most powerful API 3.0 features, and is intended for users who have not yet integrated their WooCommerce stores with Mailchimp.
29
  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.
30
  WordPress.com compatibility is limited to Business tier users only.
31
+
32
  == Installation ==
33
  ###Before You Start
34
  Here are some things to know before you begin this process.
35
  - This plugin requires you to have the [WooCommerce plugin](https://woocommerce.com/) already installed and activated in WordPress.
36
  - Your hosting environment must meet [WooCommerce's minimum requirements](https://docs.woocommerce.com/document/server-requirements), including PHP 7.0 or greater.
37
+ - `WP_CRON` must be activated with your hosting provider to sync data. Please verify that it is enabled.
38
  - 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).
39
  - Mailchimp for WooCommerce syncs the customer’s first name, last name, email address, and orders.
40
  - WooCommerce customers who haven't signed up for marketing emails will appear in the **Transactional** portion of your audience, and cannot be exported.
41
+
42
+ ###Getting Started
43
  You’ll need to do a few things to connect your WooCommerce store to Mailchimp.
44
  - Download the plugin.
45
  - Install the plugin on your WordPress Admin site.
46
  - Connect securely to your Mailchimp account via secure OAuth pop-up window.
47
+ - Configure your Audience settings to complete the data sync process.
48
+ - If you have more advanced configuration needs, please refer to our [GitHub wiki](https://github.com/mailchimp/mc-woocommerce/wiki)
49
+
50
+ == Frequently Asked Questions ==
51
+
52
+ = What is the recommended way to sync larger stores? =
53
+
54
+ To optimize the performance of your Mailchimp integration we recommend running the queue in CLI mode. Please refer to [this guide](https://github.com/mailchimp/mc-woocommerce/wiki/Advanced-Queue-Setup-In-CLI-mode) in our Wiki.
55
+
56
+ = Are multisite configurations supported?
57
+
58
+ Multisites are supported, with a few caveats. Please refer to our [Wiki page](https://github.com/mailchimp/mc-woocommerce/wiki/Multisite-Setups) on this topic for more information.
59
+
60
+ = Why aren't product categories being sent to Mailchimp? =
61
+ At this time, the synchronization of product categories from WooCommerce to Mailchimp is not supported by the Mailchimp API.
62
+
63
+ = My sync is slow, or has stalled =
64
+ - If you're using the current version of the plugin, it utilizes a queue system powered by [Action Scheduler](https://actionscheduler.org/). It depends on `WP_CRON` to be activated with your hosting provider. Please verify that it is enabled.
65
+ - If you're using a host that makes use of CPU throttling, please check to see if you've hit your limit after initiating the sync.
66
+ - If you're using Redis, Nginx or MemCache, check to see if you or your hosting provider can exclude certain paths to the `REST API` and `/wp-json/mailchimp-for-woocommerce`.
67
+ - If you have a large number of plugins being used, you may need to bump up your memory limit on your server (1GB for example) to accommodate the initial sync.
68
+
69
+ = My question is not listed =
70
+ If you are unable to sync or connect with Mailchimp, you can open a ticket on our [Github plugin page](https://github.com/mailchimp/mc-woocommerce/issues). Please provide the version of the plugin and PHP you're using, any fatal errors in the WooCommerce logs (WooCommerce -> Status -> Logs) you're seeing, along with relevant information to the problem you're experiencing.
71
+
72
  == Changelog ==
73
+ = 2.4.0 =
74
+ * update for latest Action Scheduler v3.1.4
75
+ * adds customer language on Cart and Order sync
76
+ * adds batch processing for queues
77
+ * support for Brazilian Portuguese pt_BR Language
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/class-mailchimp-woocommerce-admin.php CHANGED
@@ -60,13 +60,8 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
60
  $options['active_tab'] = 'api_key';
61
  $options['mailchimp_list'] = null;
62
 
63
- update_option('mailchimp-woocommerce-validation.store_info', false);
64
- update_option('mailchimp-woocommerce-validation.campaign_defaults', false);
65
- update_option('mailchimp-woocommerce-validation.newsletter_settings', false);
66
- update_option('mailchimp-woocommerce-sync.started_at', false);
67
- update_option('mailchimp-woocommerce-sync.completed_at', false);
68
- update_option('mailchimp-woocommerce-resource-last-updated', false);
69
- update_option('mailchimp-woocommerce-empty_line_item_placeholder', false);
70
 
71
  // remove user from our marketing status audience
72
  mailchimp_remove_communication_status();
@@ -129,13 +124,87 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
129
  * @since 1.0.0
130
  */
131
  public function add_plugin_admin_menu() {
132
- add_menu_page(
133
- __('Mailchimp - WooCommerce Setup', 'mailchimp-for-woocommerce'),
134
- 'Mailchimp',
135
- mailchimp_get_allowed_capability(),
136
- $this->plugin_name,
137
- array($this, 'display_plugin_setup_page'), 'data:image/svg+xml;base64,'.$this->mailchimp_svg()
138
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  /**
@@ -1158,9 +1227,6 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1158
  if (response.promo_rules_in_mailchimp == 0) {
1159
  promo_rulesProgress = 0;
1160
  promo_rulesPartial = "0 / " + response.promo_rules_in_store;
1161
- } else if (response.promo_rules_in_mailchimp == response.promo_rules_in_store) {
1162
- promo_rulesProgress = (100 / Math.ceil(response.promo_rules_in_store / 5) + 1) * (response.promo_rules_page - 1) ;
1163
- promo_rulesPartial = (((response.promo_rules_page - 1) * 5) < response.promo_rules_in_mailchimp ? (response.promo_rules_page - 1) * 5 : response.promo_rules_in_mailchimp) + " / " + response.promo_rules_in_store;
1164
  } else {
1165
  promo_rulesProgress = response.promo_rules_in_mailchimp / response.promo_rules_in_store * 100
1166
  promo_rulesPartial = response.promo_rules_in_mailchimp + " / " + response.promo_rules_in_store;
@@ -1178,9 +1244,6 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1178
  if (response.products_in_mailchimp == 0) {
1179
  productsProgress = 0;
1180
  productsPartial = "0 / " + response.products_in_store;
1181
- } else if (response.products_in_mailchimp == response.products_in_store) {
1182
- productsProgress = (100 / Math.ceil(response.products_in_store / 5) + 1) * (response.products_page - 1) ;
1183
- productsPartial = (((response.products_page - 1) * 5) < response.products_in_mailchimp ? (response.products_page - 1) * 5 : response.products_in_mailchimp) + " / " + response.products_in_store;
1184
  } else {
1185
  productsProgress = response.products_in_mailchimp / response.products_in_store * 100
1186
  productsPartial = response.products_in_mailchimp + " / " + response.products_in_store;
@@ -1198,9 +1261,6 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1198
  if (response.orders_in_mailchimp == 0) {
1199
  ordersProgress = 0;
1200
  ordersPartial = "0 / " + response.orders_in_store;
1201
- } else if (response.orders_in_mailchimp == response.orders_in_store) {
1202
- ordersProgress = (100 / Math.ceil(response.orders_in_store / 5) + 1) * (response.orders_page - 1) ;
1203
- ordersPartial = (((response.orders_page - 1) * 5) < response.orders_in_mailchimp ? (response.orders_page - 1) * 5 : response.orders_in_mailchimp) + " / " + response.orders_in_store;
1204
  } else {
1205
  ordersProgress = response.orders_in_mailchimp / response.orders_in_store * 100
1206
  ordersPartial = response.orders_in_mailchimp + " / " + response.orders_in_store;
@@ -1266,6 +1326,10 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1266
  // set the store name if the list id is not set.
1267
  if (empty($list_id)) {
1268
  $submission->setName($data['store_name']);
 
 
 
 
1269
  }
1270
 
1271
  // set the campaign defaults
@@ -1279,11 +1343,6 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1279
  // set the permission reminder message.
1280
  $submission->setPermissionReminder($data['campaign_permission_reminder']);
1281
 
1282
- if (isset($data['admin_email']) && !empty($data['admin_email'])) {
1283
- $submission->setNotifyOnSubscribe($data['admin_email']);
1284
- $submission->setNotifyOnUnSubscribe($data['admin_email']);
1285
- }
1286
-
1287
  $submission->setContact($this->address($data));
1288
 
1289
  // let's turn this on for debugging purposes.
@@ -1471,13 +1530,14 @@ class MailChimp_WooCommerce_Admin extends MailChimp_WooCommerce_Options {
1471
  // delete the transient so this only happens one time.
1472
  delete_site_transient('mailchimp_woocommerce_start_sync');
1473
 
1474
- $coupon_sync = new MailChimp_WooCommerce_Process_Coupons_Initial_Sync();
1475
-
1476
  // tell Mailchimp that we're syncing
1477
- $coupon_sync->flagStartSync();
1478
-
1479
- // queue up the jobs
1480
- mailchimp_handle_or_queue($coupon_sync, 0);
 
1481
  }
1482
 
1483
  /**
60
  $options['active_tab'] = 'api_key';
61
  $options['mailchimp_list'] = null;
62
 
63
+ // clean database
64
+ mailchimp_clean_database();
 
 
 
 
 
65
 
66
  // remove user from our marketing status audience
67
  mailchimp_remove_communication_status();
124
  * @since 1.0.0
125
  */
126
  public function add_plugin_admin_menu() {
127
+ // Add top level menu item
128
+ add_menu_page(
129
+ __('Mailchimp - WooCommerce Setup', 'mailchimp-for-woocommerce'),
130
+ 'Mailchimp',
131
+ mailchimp_get_allowed_capability(),
132
+ $this->plugin_name,
133
+ array($this, 'display_plugin_setup_page'), 'data:image/svg+xml;base64,'.$this->mailchimp_svg()
134
+ );
135
+
136
+ // only shows submenus if initial wizard is complete
137
+ $show_submenus = ($this->getData('validation.store_info', false) && $this->getData('validation.campaign_defaults', false) && $this->getData('validation.newsletter_settings', false));
138
+ if ($show_submenus) {
139
+ // Add submenu items
140
+ add_submenu_page(
141
+ $this->plugin_name,
142
+ esc_html__('Overview', 'mailchimp-for-woocommerce'),
143
+ esc_html__('Overview', 'mailchimp-for-woocommerce'),
144
+ mailchimp_get_allowed_capability(),
145
+ $this->plugin_name . '&amp;tab=sync',
146
+ array($this, 'display_plugin_setup_page')
147
+ );
148
+
149
+ add_submenu_page(
150
+ $this->plugin_name,
151
+ esc_html__('Store Settings', 'mailchimp-for-woocommerce'),
152
+ esc_html__('Store Settings', 'mailchimp-for-woocommerce'),
153
+ mailchimp_get_allowed_capability(),
154
+ $this->plugin_name . '&amp;tab=store_info',
155
+ array($this, 'display_plugin_setup_page')
156
+ );
157
+
158
+ add_submenu_page(
159
+ $this->plugin_name,
160
+ esc_html__('Audience Defaults', 'mailchimp-for-woocommerce'),
161
+ esc_html__('Audience Defaults', 'mailchimp-for-woocommerce'),
162
+ mailchimp_get_allowed_capability(),
163
+ $this->plugin_name . '&amp;tab=campaign_defaults',
164
+ array($this, 'display_plugin_setup_page')
165
+ );
166
+
167
+ add_submenu_page(
168
+ $this->plugin_name,
169
+ esc_html__('Audience Settings', 'mailchimp-for-woocommerce'),
170
+ esc_html__('Audience Settings', 'mailchimp-for-woocommerce'),
171
+ mailchimp_get_allowed_capability(),
172
+ $this->plugin_name . '&amp;tab=newsletter_settings',
173
+ array($this, 'display_plugin_setup_page')
174
+ );
175
+
176
+ add_submenu_page(
177
+ $this->plugin_name,
178
+ esc_html__('Logs', 'mailchimp-for-woocommerce'),
179
+ esc_html__('Logs', 'mailchimp-for-woocommerce'),
180
+ mailchimp_get_allowed_capability(),
181
+ $this->plugin_name . '&amp;tab=logs',
182
+ array($this, 'display_plugin_setup_page')
183
+ );
184
+
185
+ // Remove submenu duplicate of top level menu item
186
+ remove_submenu_page( $this->plugin_name, $this->plugin_name );
187
+
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Highlight correct item on admin plugin's submenu
193
+ *
194
+ * because of the nature of our settings pages being all the same url as opposed to separate php files,
195
+ * we need to force highlight on correct item based on the $_GET[tab] param.
196
+ *
197
+ * @since 2.4.1
198
+ */
199
+ function highlight_admin_menu($parent_file){
200
+ global $current_screen;
201
+ global $submenu_file;
202
+
203
+ if( $current_screen->base == 'toplevel_page_mailchimp-woocommerce' ) :
204
+ $submenu_file = $parent_file . (isset($_GET['tab']) ? "&amp;tab=" . $_GET['tab'] : "&amp;tab=sync");
205
+ endif;
206
+
207
+ return $parent_file;
208
  }
209
 
210
  /**
1227
  if (response.promo_rules_in_mailchimp == 0) {
1228
  promo_rulesProgress = 0;
1229
  promo_rulesPartial = "0 / " + response.promo_rules_in_store;
 
 
 
1230
  } else {
1231
  promo_rulesProgress = response.promo_rules_in_mailchimp / response.promo_rules_in_store * 100
1232
  promo_rulesPartial = response.promo_rules_in_mailchimp + " / " + response.promo_rules_in_store;
1244
  if (response.products_in_mailchimp == 0) {
1245
  productsProgress = 0;
1246
  productsPartial = "0 / " + response.products_in_store;
 
 
 
1247
  } else {
1248
  productsProgress = response.products_in_mailchimp / response.products_in_store * 100
1249
  productsPartial = response.products_in_mailchimp + " / " + response.products_in_store;
1261
  if (response.orders_in_mailchimp == 0) {
1262
  ordersProgress = 0;
1263
  ordersPartial = "0 / " + response.orders_in_store;
 
 
 
1264
  } else {
1265
  ordersProgress = response.orders_in_mailchimp / response.orders_in_store * 100
1266
  ordersPartial = response.orders_in_mailchimp + " / " + response.orders_in_store;
1326
  // set the store name if the list id is not set.
1327
  if (empty($list_id)) {
1328
  $submission->setName($data['store_name']);
1329
+ if (isset($data['admin_email']) && !empty($data['admin_email'])) {
1330
+ $submission->setNotifyOnSubscribe($data['admin_email']);
1331
+ $submission->setNotifyOnUnSubscribe($data['admin_email']);
1332
+ }
1333
  }
1334
 
1335
  // set the campaign defaults
1343
  // set the permission reminder message.
1344
  $submission->setPermissionReminder($data['campaign_permission_reminder']);
1345
 
 
 
 
 
 
1346
  $submission->setContact($this->address($data));
1347
 
1348
  // let's turn this on for debugging purposes.
1530
  // delete the transient so this only happens one time.
1531
  delete_site_transient('mailchimp_woocommerce_start_sync');
1532
 
1533
+ $full_sync = new MailChimp_WooCommerce_Process_Full_Sync_Manager();
1534
+
1535
  // tell Mailchimp that we're syncing
1536
+ $full_sync->start_sync();
1537
+
1538
+ // enqueue sync manager
1539
+ as_enqueue_async_action( 'MailChimp_WooCommerce_Process_Full_Sync_Manager', array(), 'mc-woocommerce' );
1540
+
1541
  }
1542
 
1543
  /**
bootstrap.php CHANGED
@@ -57,13 +57,13 @@ spl_autoload_register(function($class) {
57
  'MailChimp_WooCommerce_Abstract_Sync' => 'includes/processes/class-mailchimp-woocommerce-abstract-sync.php',
58
  'MailChimp_WooCommerce_Cart_Update' => 'includes/processes/class-mailchimp-woocommerce-cart-update.php',
59
  'MailChimp_WooCommerce_Process_Coupons' => 'includes/processes/class-mailchimp-woocommerce-process-coupons.php',
60
- 'MailChimp_WooCommerce_Process_Coupons_Initial_Sync' => 'includes/processes/class-mailchimp-woocommerce-process-coupons-initial-sync.php',
61
  'MailChimp_WooCommerce_Process_Orders' => 'includes/processes/class-mailchimp-woocommerce-process-orders.php',
62
  'MailChimp_WooCommerce_Process_Products' => 'includes/processes/class-mailchimp-woocommerce-process-products.php',
63
  'MailChimp_WooCommerce_SingleCoupon' => 'includes/processes/class-mailchimp-woocommerce-single-coupon.php',
64
  'MailChimp_WooCommerce_Single_Order' => 'includes/processes/class-mailchimp-woocommerce-single-order.php',
65
  'MailChimp_WooCommerce_Single_Product' => 'includes/processes/class-mailchimp-woocommerce-single-product.php',
66
  'MailChimp_WooCommerce_User_Submit' => 'includes/processes/class-mailchimp-woocommerce-user-submit.php',
 
67
 
68
  'MailChimp_WooCommerce_Public' => 'public/class-mailchimp-woocommerce-public.php',
69
  'MailChimp_WooCommerce_Admin' => 'admin/class-mailchimp-woocommerce-admin.php',
@@ -87,7 +87,7 @@ function mailchimp_environment_variables() {
87
  return (object) array(
88
  'repo' => 'master',
89
  'environment' => 'production', // staging or production
90
- 'version' => '2.3.6',
91
  'php_version' => phpversion(),
92
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
93
  'wc_version' => function_exists('WC') ? WC()->version : null,
@@ -105,56 +105,76 @@ function mailchimp_environment_variables() {
105
  */
106
  function mailchimp_as_push( Mailchimp_Woocommerce_Job $job, $delay = 0 ) {
107
  global $wpdb;
108
- $job_id = isset($job->id) ? $job->id : get_class($job);
109
-
110
- $args = array(
111
- 'job' => maybe_serialize($job),
112
- 'obj_id' => $job_id,
113
- 'created_at' => gmdate( 'Y-m-d H:i:s', time() )
114
- );
115
-
116
- $existing_actions = function_exists('as_get_scheduled_actions') ? as_get_scheduled_actions(array(
117
- 'hook' => get_class($job),
118
- 'status' => ActionScheduler_Store::STATUS_PENDING,
119
- 'args' => array(
120
- 'obj_id' => isset($job->id) ? $job->id : null),
121
- 'group' => 'mc-woocommerce'
122
- )
123
- ) : null;
124
 
125
- if (!empty($existing_actions)) {
126
- as_unschedule_action(get_class($job), array('obj_id' => $job->id), 'mc-woocommerce');
127
- }
128
- else {
129
- $inserted = $wpdb->insert($wpdb->prefix."mailchimp_jobs", $args);
130
- if (!$inserted) {
131
- try {
132
- if (mailchimp_string_contains($wpdb->last_error, 'Table')) {
133
- mailchimp_debug('DB Issue: `mailchimp_job` table was not found!', 'Creating Tables');
134
- install_mailchimp_queue();
135
- $inserted = $wpdb->insert($wpdb->prefix."mailchimp_jobs", $args);
136
- if (!$inserted) {
137
- mailchimp_debug('Queue Job '.get_class($job), $wpdb->last_error);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  }
 
 
139
  }
140
- } catch (\Exception $e) {
141
- mailchimp_error_trace($e, 'trying to create queue tables');
142
  }
143
  }
144
- }
 
 
 
145
 
146
- $action = as_schedule_single_action( strtotime( '+'.$delay.' seconds' ), get_class($job), array('obj_id' => $job_id), "mc-woocommerce");
 
 
 
 
 
 
 
 
 
 
 
147
 
148
- $message = ($job_id != get_class($job)) ? ' :: obj_id '.$job_id : '';
149
- $attempts = $job->get_attempts() > 0 ? ' attempt:' . $job->get_attempts() : '';
150
- if (!empty($existing_actions)) {
151
- mailchimp_debug('action_scheduler.reschedule_job', get_class($job) . ($delay > 0 ? ' restarts in '.$delay. ' seconds' : ' restarts in the next minute' ) . $message . $attempts);
152
- }
153
  else {
154
- mailchimp_log('action_scheduler.queue_job', get_class($job) . ($delay > 0 ? ' starts in '.$delay. ' seconds' : ' starts in the next minute' ) . $message . $attempts);
 
 
155
  }
156
-
157
- return $action;
158
  }
159
 
160
 
@@ -181,6 +201,19 @@ function mailchimp_handle_or_queue(Mailchimp_Woocommerce_Job $job, $delay = 0)
181
  }
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  /**
185
  * @param bool $force
186
  * @return bool
@@ -555,7 +588,7 @@ function mailchimp_error($action, $message, $data = array()) {
555
  * @param string $wrap
556
  * @return string
557
  */
558
- function mailchimp_error_trace(\Exception $e, $wrap = "") {
559
  $error = "Error Code {$e->getCode()} :: {$e->getMessage()} on {$e->getLine()} in {$e->getFile()}";
560
  if (empty($wrap)) return $error;
561
  return "{$wrap} :: {$error}";
@@ -581,6 +614,18 @@ function mailchimp_string_contains($haystack, $needles) {
581
  return false;
582
  }
583
 
 
 
 
 
 
 
 
 
 
 
 
 
584
 
585
  /**
586
  * @return int
@@ -617,6 +662,9 @@ function mailchimp_count_posts($type) {
617
  if ($type === 'shop_order') {
618
  $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s";
619
  $posts = $wpdb->get_results( $wpdb->prepare($query, $type, 'wc-completed'));
 
 
 
620
  } else {
621
  $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s";
622
  $posts = $wpdb->get_results( $wpdb->prepare($query, $type, 'publish'));
@@ -895,6 +943,17 @@ function mailchimp_flush_database_tables() {
895
  } catch (\Exception $e) {}
896
  }
897
 
 
 
 
 
 
 
 
 
 
 
 
898
  function mailchimp_delete_as_jobs() {
899
 
900
  $existing_as_actions = function_exists('as_get_scheduled_actions') ? as_get_scheduled_actions(
@@ -919,31 +978,26 @@ function mailchimp_flush_sync_pointers() {
919
  foreach (array('orders', 'products', 'coupons') as $resource_type) {
920
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.started_at");
921
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.completed_at");
 
922
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.current_page");
923
  }
924
  }
925
 
926
  /**
927
- * To be used when running clean up for uninstalls or re-installs.
928
  */
929
  function mailchimp_clean_database() {
 
 
930
  // delete custom tables data
931
  mailchimp_flush_database_tables();
932
 
933
- // clean up the initial sync pointers
934
- mailchimp_flush_sync_pointers();
935
 
936
- delete_option('mailchimp-woocommerce');
937
- delete_option('mailchimp-woocommerce-store_id');
938
- delete_option('mailchimp-woocommerce-sync.syncing');
939
- delete_option('mailchimp-woocommerce-sync.started_at');
940
- delete_option('mailchimp-woocommerce-sync.completed_at');
941
- delete_option('mailchimp-woocommerce-sync.initial_sync');
942
- delete_option('mailchimp-woocommerce-validation.api.ping');
943
- delete_option('mailchimp-woocommerce-cached-api-lists');
944
- delete_option('mailchimp-woocommerce-cached-api-ping-check');
945
- delete_option('mailchimp-woocommerce-errors.store_info');
946
- delete_option('mailchimp-woocommerce-empty_line_item_placeholder');
947
  }
948
 
949
  /**
@@ -973,13 +1027,8 @@ function run_mailchimp_woocommerce() {
973
  }
974
  }
975
 
976
- function mailchimp_woocommerce_add_meta_tags() {
977
- echo '<meta name="referrer" content="always"/>';
978
- }
979
-
980
  function mailchimp_on_all_plugins_loaded() {
981
  if (mailchimp_check_woocommerce_plugin_status()) {
982
- add_action('wp_head', 'mailchimp_woocommerce_add_meta_tags');
983
  run_mailchimp_woocommerce();
984
  }
985
  }
@@ -1033,7 +1082,7 @@ function mailchimp_update_member_with_double_opt_in(MailChimp_WooCommerce_Order
1033
  } else {
1034
  // if we've set the wordpress user correctly on the customer
1035
  if (($wordpress_user = $order->getCustomer()->getWordpressUser())) {
1036
- $user_submit = new MailChimp_WooCommerce_User_Submit($wordpress_user->ID, true, null, substr( get_locale(), 0, 2 ));
1037
  $user_submit->handle();
1038
  }
1039
  }
@@ -1070,6 +1119,36 @@ function mailchimp_settings_errors() {
1070
  return $notices_html;
1071
  }
1072
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1073
  // Add WP CLI commands
1074
  if (defined( 'WP_CLI' ) && WP_CLI) {
1075
  try {
57
  'MailChimp_WooCommerce_Abstract_Sync' => 'includes/processes/class-mailchimp-woocommerce-abstract-sync.php',
58
  'MailChimp_WooCommerce_Cart_Update' => 'includes/processes/class-mailchimp-woocommerce-cart-update.php',
59
  'MailChimp_WooCommerce_Process_Coupons' => 'includes/processes/class-mailchimp-woocommerce-process-coupons.php',
 
60
  'MailChimp_WooCommerce_Process_Orders' => 'includes/processes/class-mailchimp-woocommerce-process-orders.php',
61
  'MailChimp_WooCommerce_Process_Products' => 'includes/processes/class-mailchimp-woocommerce-process-products.php',
62
  'MailChimp_WooCommerce_SingleCoupon' => 'includes/processes/class-mailchimp-woocommerce-single-coupon.php',
63
  'MailChimp_WooCommerce_Single_Order' => 'includes/processes/class-mailchimp-woocommerce-single-order.php',
64
  'MailChimp_WooCommerce_Single_Product' => 'includes/processes/class-mailchimp-woocommerce-single-product.php',
65
  'MailChimp_WooCommerce_User_Submit' => 'includes/processes/class-mailchimp-woocommerce-user-submit.php',
66
+ 'MailChimp_WooCommerce_Process_Full_Sync_Manager' => 'includes/processes/class-mailchimp-woocommerce-full-sync-manager.php',
67
 
68
  'MailChimp_WooCommerce_Public' => 'public/class-mailchimp-woocommerce-public.php',
69
  'MailChimp_WooCommerce_Admin' => 'admin/class-mailchimp-woocommerce-admin.php',
87
  return (object) array(
88
  'repo' => 'master',
89
  'environment' => 'production', // staging or production
90
+ 'version' => '2.4.0',
91
  'php_version' => phpversion(),
92
  'wp_version' => (empty($wp_version) ? 'Unknown' : $wp_version),
93
  'wc_version' => function_exists('WC') ? WC()->version : null,
105
  */
106
  function mailchimp_as_push( Mailchimp_Woocommerce_Job $job, $delay = 0 ) {
107
  global $wpdb;
108
+ $current_page = isset($job->current_page) && $job->current_page >= 0 ? $job->current_page : false;
109
+ $job_id = isset($job->id) ? $job->id : ($current_page ? $job->current_page : get_class($job));
110
+
111
+
112
+ $message = ($job_id != get_class($job)) ? ' :: '. (isset($job->current_page) ? 'page ' : 'obj_id ') . $job_id : '';
 
 
 
 
 
 
 
 
 
 
 
113
 
114
+ $attempts = $job->get_attempts() > 0 ? ' attempt:' . $job->get_attempts() : '';
115
+
116
+ if ($job->get_attempts() <= 5) {
117
+
118
+ $args = array(
119
+ 'job' => maybe_serialize($job),
120
+ 'obj_id' => $job_id,
121
+ 'created_at' => gmdate( 'Y-m-d H:i:s', time() )
122
+ );
123
+
124
+ $existing_actions = function_exists('as_get_scheduled_actions') ? as_get_scheduled_actions(array(
125
+ 'hook' => get_class($job),
126
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
127
+ 'args' => array(
128
+ 'obj_id' => isset($job->id) ? $job->id : null),
129
+ 'group' => 'mc-woocommerce'
130
+ )
131
+ ) : null;
132
+
133
+ if (!empty($existing_actions)) {
134
+ as_unschedule_action(get_class($job), array('obj_id' => $job->id), 'mc-woocommerce');
135
+ }
136
+ else {
137
+ $inserted = $wpdb->insert($wpdb->prefix."mailchimp_jobs", $args);
138
+ if (!$inserted) {
139
+ try {
140
+ if (mailchimp_string_contains($wpdb->last_error, 'Table')) {
141
+ mailchimp_debug('DB Issue: `mailchimp_job` table was not found!', 'Creating Tables');
142
+ install_mailchimp_queue();
143
+ $inserted = $wpdb->insert($wpdb->prefix."mailchimp_jobs", $args);
144
+ if (!$inserted) {
145
+ mailchimp_debug('Queue Job '.get_class($job), $wpdb->last_error);
146
+ }
147
  }
148
+ } catch (\Exception $e) {
149
+ mailchimp_error_trace($e, 'trying to create queue tables');
150
  }
 
 
151
  }
152
  }
153
+
154
+ $action_args = array(
155
+ 'obj_id' => $job_id,
156
+ );
157
 
158
+ if ($current_page !== false) {
159
+ $action_args['page'] = $current_page;
160
+ }
161
+
162
+ $action = as_schedule_single_action( strtotime( '+'.$delay.' seconds' ), get_class($job), $action_args, "mc-woocommerce");
163
+
164
+ if (!empty($existing_actions)) {
165
+ mailchimp_debug('action_scheduler.reschedule_job', get_class($job) . ($delay > 0 ? ' restarts in '.$delay. ' seconds' : ' re-queued' ) . $message . $attempts);
166
+ }
167
+ else {
168
+ mailchimp_log('action_scheduler.queue_job', get_class($job) . ($delay > 0 ? ' starts in '.$delay. ' seconds' : ' queued' ) . $message . $attempts);
169
+ }
170
 
171
+ return $action;
172
+ }
 
 
 
173
  else {
174
+ $job->set_attempts(0);
175
+ mailchimp_log('action_scheduler.fail_job', get_class($job) . ' cancelled. Too many attempts' . $message . $attempts);
176
+ return false;
177
  }
 
 
178
  }
179
 
180
 
201
  }
202
  }
203
 
204
+ function mailchimp_get_remaining_jobs_count($job_hook) {
205
+ $existing_actions = function_exists('as_get_scheduled_actions') ? as_get_scheduled_actions(
206
+ array(
207
+ 'hook' => $job_hook,
208
+ 'status' => ActionScheduler_Store::STATUS_PENDING,
209
+ 'group' => 'mc-woocommerce',
210
+ 'per_page' => -1,
211
+ ), 'ids'
212
+ ) : null;
213
+ // mailchimp_log('sync.full_sync_manager.queue', "counting {$job_hook} actions:", array($existing_actions));
214
+ return count($existing_actions);
215
+ }
216
+
217
  /**
218
  * @param bool $force
219
  * @return bool
588
  * @param string $wrap
589
  * @return string
590
  */
591
+ function mailchimp_error_trace($e, $wrap = "") {
592
  $error = "Error Code {$e->getCode()} :: {$e->getMessage()} on {$e->getLine()} in {$e->getFile()}";
593
  if (empty($wrap)) return $error;
594
  return "{$wrap} :: {$error}";
614
  return false;
615
  }
616
 
617
+ /**
618
+ * @return int
619
+ */
620
+ function mailchimp_get_coupons_count() {
621
+ $posts = mailchimp_count_posts('shop_coupon');
622
+ unset($posts['auto-draft'], $posts['trash']);
623
+ $total = 0;
624
+ foreach ($posts as $status => $count) {
625
+ $total += $count;
626
+ }
627
+ return $total;
628
+ }
629
 
630
  /**
631
  * @return int
662
  if ($type === 'shop_order') {
663
  $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s";
664
  $posts = $wpdb->get_results( $wpdb->prepare($query, $type, 'wc-completed'));
665
+ } else if ($type === 'product') {
666
+ $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND post_status IN (%s, %s, %s) group BY post_status";
667
+ $posts = $wpdb->get_results( $wpdb->prepare($query, $type, 'private', 'publish', 'draft'));
668
  } else {
669
  $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s";
670
  $posts = $wpdb->get_results( $wpdb->prepare($query, $type, 'publish'));
943
  } catch (\Exception $e) {}
944
  }
945
 
946
+ function mailchimp_flush_sync_job_tables() {
947
+ try {
948
+ /** @var \ */
949
+ global $wpdb;
950
+
951
+ mailchimp_delete_as_jobs();
952
+
953
+ $wpdb->query("TRUNCATE `{$wpdb->prefix}mailchimp_jobs`");
954
+ } catch (\Exception $e) {}
955
+ }
956
+
957
  function mailchimp_delete_as_jobs() {
958
 
959
  $existing_as_actions = function_exists('as_get_scheduled_actions') ? as_get_scheduled_actions(
978
  foreach (array('orders', 'products', 'coupons') as $resource_type) {
979
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.started_at");
980
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.completed_at");
981
+ delete_option("mailchimp-woocommerce-sync.{$resource_type}.started_at");
982
  delete_option("mailchimp-woocommerce-sync.{$resource_type}.current_page");
983
  }
984
  }
985
 
986
  /**
987
+ * To be used when running clean up for uninstalls or store disconnection.
988
  */
989
  function mailchimp_clean_database() {
990
+ global $wpdb;
991
+
992
  // delete custom tables data
993
  mailchimp_flush_database_tables();
994
 
995
+ // delete plugin options
996
+ $plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'mailchimp%woocommerce%'" );
997
 
998
+ foreach( $plugin_options as $option ) {
999
+ delete_option( $option->option_name );
1000
+ }
 
 
 
 
 
 
 
 
1001
  }
1002
 
1003
  /**
1027
  }
1028
  }
1029
 
 
 
 
 
1030
  function mailchimp_on_all_plugins_loaded() {
1031
  if (mailchimp_check_woocommerce_plugin_status()) {
 
1032
  run_mailchimp_woocommerce();
1033
  }
1034
  }
1082
  } else {
1083
  // if we've set the wordpress user correctly on the customer
1084
  if (($wordpress_user = $order->getCustomer()->getWordpressUser())) {
1085
+ $user_submit = new MailChimp_WooCommerce_User_Submit($wordpress_user->ID, true, null);
1086
  $user_submit->handle();
1087
  }
1088
  }
1119
  return $notices_html;
1120
  }
1121
 
1122
+ function mailchimp_member_language_update($user_email = null, $language = null, $caller = '') {
1123
+ if (!$user_email || !$language) return;
1124
+
1125
+ $hash = md5(strtolower(trim($user_email)));
1126
+ if (!mailchimp_get_transient($caller . ".member.{$hash}")) {
1127
+ $list_id = mailchimp_get_list_id();
1128
+ try {
1129
+ // try to get the member to update if already synced
1130
+ $member = mailchimp_get_api()->member($list_id, $user_email);
1131
+ // update member with new language
1132
+ mailchimp_get_api()->update($list_id, $user_email, $member['status'], null, null, $language);
1133
+ // set transient to prevent too many calls to update language
1134
+ mailchimp_set_transient($caller . ".member.{$hash}", true, 3600);
1135
+ mailchimp_log($caller . '.member.updated', "Updated {$user_email} language to {$language}");
1136
+ } catch (\Exception $e) {
1137
+ if ($e->getCode() == 404) {
1138
+ // member doesn't exist yet, create
1139
+ mailchimp_get_api()->subscribe($list_id, $user_email, false, array(), array(), $language);
1140
+ // set transient to prevent too many calls to update language
1141
+ mailchimp_set_transient($caller . ".member.{$hash}", true, 3600);
1142
+ mailchimp_log($caller . '.member.created', "Subscribed {$user_email}, setting language to [{$language}]");
1143
+ } else {
1144
+ mailchimp_error($caller . '.member.sync.error', $e->getMessage(), $user_email);
1145
+
1146
+ }
1147
+ }
1148
+ }
1149
+ }
1150
+
1151
+
1152
  // Add WP CLI commands
1153
  if (defined( 'WP_CLI' ) && WP_CLI) {
1154
  try {
includes/api/class-mailchimp-woocommerce-transform-coupons.php CHANGED
@@ -27,8 +27,8 @@ class MailChimp_WooCommerce_Transform_Coupons
27
  );
28
 
29
  if ((($coupons = $this->getCouponPosts($page, $limit)) && !empty($coupons))) {
30
- foreach ($coupons as $post) {
31
- $response->items[] = $this->transform($post->ID);
32
  $response->count++;
33
  }
34
  }
@@ -110,29 +110,25 @@ class MailChimp_WooCommerce_Transform_Coupons
110
  {
111
  $offset = 0;
112
  if ($page > 1) {
113
- $offset = ($page * $posts);
114
  }
115
 
116
- $coupons = get_posts(array(
117
  'post_type' => array_merge(array_keys(wc_get_product_types()), array('shop_coupon')),
118
  'posts_per_page' => $posts,
119
  'offset' => $offset,
120
  'orderby' => 'ID',
121
  'order' => 'ASC',
122
- ));
 
 
 
123
 
124
  if (empty($coupons)) {
125
 
126
  sleep(2);
127
 
128
- $coupons = get_posts(array(
129
- 'post_type' => array_merge(array_keys(wc_get_product_types()), array('shop_coupon')),
130
- 'posts_per_page' => $posts,
131
- 'offset' => $offset,
132
- 'orderby' => 'ID',
133
- 'order' => 'ASC',
134
- ));
135
-
136
  if (empty($coupons)) {
137
  return false;
138
  }
27
  );
28
 
29
  if ((($coupons = $this->getCouponPosts($page, $limit)) && !empty($coupons))) {
30
+ foreach ($coupons as $post_id) {
31
+ $response->items[] = $post_id;
32
  $response->count++;
33
  }
34
  }
110
  {
111
  $offset = 0;
112
  if ($page > 1) {
113
+ $offset = (($page - 1) * $posts);
114
  }
115
 
116
+ $args = array(
117
  'post_type' => array_merge(array_keys(wc_get_product_types()), array('shop_coupon')),
118
  'posts_per_page' => $posts,
119
  'offset' => $offset,
120
  'orderby' => 'ID',
121
  'order' => 'ASC',
122
+ 'fields' => 'ids'
123
+ );
124
+
125
+ $coupons = get_posts($args);
126
 
127
  if (empty($coupons)) {
128
 
129
  sleep(2);
130
 
131
+ $coupons = get_posts($args);
 
 
 
 
 
 
 
132
  if (empty($coupons)) {
133
  return false;
134
  }
includes/api/class-mailchimp-woocommerce-transform-orders-wc3.php CHANGED
@@ -30,23 +30,9 @@ class MailChimp_WooCommerce_Transform_Orders
30
  );
31
 
32
  if ((($orders = $this->getOrderPosts($page, $limit)) && !empty($orders))) {
33
- foreach ($orders as $post) {
 
34
  $response->count++;
35
-
36
- if ($post->post_status === 'auto-draft') {
37
- $response->drafts++;
38
- continue;
39
- }
40
-
41
- try {
42
- $order = $this->transform($post);
43
- if (!$order->isFlaggedAsAmazonOrder()) {
44
- $response->valid++;
45
- $response->items[] = $order;
46
- }
47
- } catch (\Exception $e) {
48
- mailchimp_error('initial_sync', $e->getMessage(), array('post' => $post));
49
- }
50
  }
51
  }
52
 
@@ -75,6 +61,7 @@ class MailChimp_WooCommerce_Transform_Orders
75
 
76
  // if the woo object does not have a "get_billing_email" method, then we need to skip this until
77
  // we know how to resolve these types of things.
 
78
  if (!method_exists($woo, 'get_billing_email')) {
79
  $message = "Post ID {$post->ID} was an order refund. Skipping this.";
80
  if ($this->is_syncing) {
@@ -396,17 +383,18 @@ class MailChimp_WooCommerce_Transform_Orders
396
  {
397
  $offset = 0;
398
  if ($page > 1) {
399
- $offset = (($page-1) * $posts);
400
  }
401
 
402
  $params = array(
403
- 'post_type' => wc_get_order_types(),
404
  //'post_status' => array_keys(wc_get_order_statuses()),
405
  'post_status' => 'wc-completed',
406
  'posts_per_page' => $posts,
407
  'offset' => $offset,
408
  'orderby' => 'id',
409
  'order' => 'ASC',
 
410
  );
411
 
412
  $orders = get_posts($params);
30
  );
31
 
32
  if ((($orders = $this->getOrderPosts($page, $limit)) && !empty($orders))) {
33
+ foreach ($orders as $post_id) {
34
+ $response->items[] = $post_id;
35
  $response->count++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
  }
38
 
61
 
62
  // if the woo object does not have a "get_billing_email" method, then we need to skip this until
63
  // we know how to resolve these types of things.
64
+ //mailchimp_log('get_billing_mail', method_exists($woo, 'get_billing_email'), array($order->toArray(), $woo));
65
  if (!method_exists($woo, 'get_billing_email')) {
66
  $message = "Post ID {$post->ID} was an order refund. Skipping this.";
67
  if ($this->is_syncing) {
383
  {
384
  $offset = 0;
385
  if ($page > 1) {
386
+ $offset = ($page - 1) * $posts;
387
  }
388
 
389
  $params = array(
390
+ 'post_type' => 'shop_order',
391
  //'post_status' => array_keys(wc_get_order_statuses()),
392
  'post_status' => 'wc-completed',
393
  'posts_per_page' => $posts,
394
  'offset' => $offset,
395
  'orderby' => 'id',
396
  'order' => 'ASC',
397
+ 'fields' => 'ids'
398
  );
399
 
400
  $orders = get_posts($params);
includes/api/class-mailchimp-woocommerce-transform-products.php CHANGED
@@ -26,9 +26,9 @@ class MailChimp_WooCommerce_Transform_Products
26
  'items' => array(),
27
  );
28
 
29
- if ((($products = $this->getProductPosts($page, $limit)) && !empty($products))) {
30
- foreach ($products as $post) {
31
- $response->items[] = $this->transform($post);
32
  $response->count++;
33
  }
34
  }
@@ -206,7 +206,7 @@ class MailChimp_WooCommerce_Transform_Products
206
  * @param int $posts
207
  * @return array|bool
208
  */
209
- public function getProductPosts($page = 1, $posts = 5)
210
  {
211
  $offset = 0;
212
 
@@ -221,6 +221,7 @@ class MailChimp_WooCommerce_Transform_Products
221
  'offset' => $offset,
222
  'orderby' => 'ID',
223
  'order' => 'ASC',
 
224
  );
225
 
226
  $products = get_posts($params);
26
  'items' => array(),
27
  );
28
 
29
+ if ((($products = $this->getProductPostsIds($page, $limit)) && !empty($products))) {
30
+ foreach ($products as $post_id) {
31
+ $response->items[] = $post_id;
32
  $response->count++;
33
  }
34
  }
206
  * @param int $posts
207
  * @return array|bool
208
  */
209
+ public function getProductPostsIds($page = 1, $posts = 5)
210
  {
211
  $offset = 0;
212
 
221
  'offset' => $offset,
222
  'orderby' => 'ID',
223
  'order' => 'ASC',
224
+ 'fields' => 'ids'
225
  );
226
 
227
  $products = get_posts($params);
includes/class-mailchimp-woocommerce-queue.php DELETED
@@ -1,226 +0,0 @@
1
- <?php
2
-
3
- class MailChimp_WooCommerce_Queue
4
- {
5
- /**
6
- * @var string
7
- */
8
- public $table;
9
-
10
- /**
11
- * @var string
12
- */
13
- public $failed_table;
14
-
15
- /**
16
- * @var int
17
- */
18
- public $release_time = 60;
19
-
20
- public $max_tries = 3;
21
-
22
- protected static $_instance = null;
23
-
24
- /**
25
- * @return MailChimp_WooCommerce_Queue
26
- */
27
- public static function instance()
28
- {
29
- if (!empty(static::$_instance)) return static::$_instance;
30
- return static::$_instance = new MailChimp_WooCommerce_Queue();
31
- }
32
-
33
- /**
34
- * WP_Queue constructor
35
- */
36
- public function __construct() {
37
- global $wpdb;
38
- $this->table = $wpdb->prefix . 'queue';
39
- $this->failed_table = $wpdb->prefix . 'failed_jobs';
40
- }
41
-
42
- /**
43
- * Push a job onto the queue.
44
- *
45
- * @param WP_Job $job
46
- * @param int $delay
47
- *
48
- * @return $this
49
- */
50
- public function push(WP_Job $job, $delay = 0)
51
- {
52
- global $wpdb;
53
-
54
- $data = array(
55
- 'job' => maybe_serialize($job),
56
- 'available_at' => $this->datetime($delay),
57
- 'created_at' => $this->datetime(),
58
- );
59
-
60
- if (!$wpdb->insert($this->table, $data) && $this->create_tables_if_required()) {
61
- if (!$wpdb->insert($this->table, $data)) {
62
- mailchimp_debug('Queue Job '.get_class($job), $wpdb->last_error);
63
- }
64
- }
65
-
66
- return $this;
67
- }
68
-
69
- /**
70
- * Release.
71
- *
72
- * @param object $job
73
- * @param int $delay
74
- */
75
- public function release( $job, $delay = 0 )
76
- {
77
- if ($job->attempts >= $this->max_tries) {
78
- return $this->failed($job);
79
- }
80
-
81
- global $wpdb;
82
-
83
- $wpdb->update($this->table, array(
84
- 'attempts' => $job->attempts + 1,
85
- 'locked' => 0,
86
- 'locked_at' => null,
87
- 'available_at' => $this->datetime( $delay ),
88
- ), array('id' => $job->id));
89
- }
90
-
91
- /**
92
- * Failed
93
- *
94
- * @param stdClass $job
95
- */
96
- protected function failed($job)
97
- {
98
- global $wpdb;
99
-
100
- $wpdb->insert($this->failed_table, array(
101
- 'job' => $job->job,
102
- 'failed_at' => $this->datetime(),
103
- ));
104
-
105
- $payload = unserialize($job->job);
106
-
107
- if (method_exists($payload, 'failed')) {
108
- $payload->failed();
109
- }
110
-
111
- $this->delete($job);
112
- }
113
-
114
- /**
115
- * Delete.
116
- *
117
- * @param object $job
118
- */
119
- public function delete( $job )
120
- {
121
- global $wpdb;
122
- $wpdb->delete($this->table, array('id' => $job->id));
123
- }
124
-
125
- /**
126
- * Get MySQL datetime.
127
- *
128
- * @param int $offset Seconds, can pass negative int.
129
- *
130
- * @return string
131
- */
132
- protected function datetime($offset = 0)
133
- {
134
- return gmdate( 'Y-m-d H:i:s', time() + $offset);
135
- }
136
-
137
- /**
138
- * Available jobs.
139
- */
140
- public function available_jobs()
141
- {
142
- global $wpdb;
143
- $now = $this->datetime();
144
- $sql = $wpdb->prepare("SELECT COUNT(*) FROM {$this->table} WHERE available_at <= %s", $now);
145
- return $wpdb->get_var($sql);
146
- }
147
-
148
- /**
149
- * Available jobs.
150
- */
151
- public function failed_jobs()
152
- {
153
- global $wpdb;
154
- return $wpdb->get_var("SELECT COUNT(*) FROM {$this->failed_table}");
155
- }
156
-
157
- /**
158
- * Restart failed jobs.
159
- */
160
- public function restart_failed_jobs()
161
- {
162
- global $wpdb;
163
- $count = 0;
164
- $jobs = $wpdb->get_results("SELECT * FROM {$this->failed_table}");
165
-
166
- foreach ($jobs as $job) {
167
- $this->push(maybe_unserialize($job->job));
168
- $wpdb->delete($this->failed_table, array('id' => $job->id));
169
- $count++;
170
- }
171
-
172
- return $count;
173
- }
174
-
175
- /**
176
- * Get next job.
177
- */
178
- public function get_next_job()
179
- {
180
- global $wpdb;
181
- $this->maybe_release_locked_jobs();
182
- $now = $this->datetime();
183
- $sql = $wpdb->prepare("SELECT * FROM {$this->table} WHERE locked = 0 AND available_at <= %s", $now);
184
- return $wpdb->get_row($sql);
185
- }
186
-
187
- /**
188
- * Maybe release locked jobs.
189
- */
190
- protected function maybe_release_locked_jobs()
191
- {
192
- global $wpdb;
193
- $expired = $this->datetime(-$this->release_time);
194
- $sql = $wpdb->prepare("UPDATE {$this->table} SET attempts = attempts + 1, locked = 0, locked_at = NULL WHERE locked = 1 AND locked_at <= %s", $expired);
195
- $wpdb->query($sql);
196
- }
197
-
198
- /**
199
- * Lock job.
200
- *
201
- * @param object $job
202
- */
203
- public function lock_job( $job )
204
- {
205
- global $wpdb;
206
- $wpdb->update( $this->table, array('locked' => 1, 'locked_at' => $this->datetime()), array('id' => $job->id));
207
- }
208
-
209
- /**
210
- * @return bool
211
- */
212
- public function create_tables_if_required()
213
- {
214
- global $wpdb;
215
- try {
216
- if (mailchimp_string_contains($wpdb->last_error, 'Table')) {
217
- mailchimp_debug('Queue Table Was Not Found!', 'Creating Tables');
218
- MailChimp_WooCommerce_Activator::create_queue_tables();
219
- return true;
220
- }
221
- } catch (\Exception $e) {
222
- mailchimp_error_trace($e, 'trying to create queue tables');
223
- }
224
- return false;
225
- }
226
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-mailchimp-woocommerce-rest-api.php CHANGED
@@ -89,43 +89,57 @@ class MailChimp_WooCommerce_Rest_Api
89
  }
90
 
91
  $store_id = mailchimp_get_store_id();
92
- $promo_rules_count = mailchimp_count_posts('shop_coupon');
 
 
 
 
 
 
 
93
  $product_count = mailchimp_get_product_count();
94
  $order_count = mailchimp_get_order_count();
95
 
96
- try {
97
- $promo_rules = $api->getPromoRules($store_id, 1, 1, 1);
98
- $mailchimp_total_promo_rules = $promo_rules['total_items'];
99
- if (isset($promo_rules_count['publish']) && $mailchimp_total_promo_rules > $promo_rules_count['publish']) $mailchimp_total_promo_rules = $promo_rules_count['publish'];
100
- } catch (\Exception $e) { $mailchimp_total_promo_rules = 0; }
101
- try {
102
- $products = $api->products($store_id, 1, 1);
103
- $mailchimp_total_products = $products['total_items'];
104
- if ($mailchimp_total_products > $product_count) $mailchimp_total_products = $product_count;
105
- } catch (\Exception $e) { $mailchimp_total_products = 0; }
106
- try {
107
- $orders = $api->orders($store_id, 1, 1);
108
- $mailchimp_total_orders = $orders['total_items'];
109
- if ($mailchimp_total_orders > $order_count) $mailchimp_total_orders = $order_count;
110
- } catch (\Exception $e) { $mailchimp_total_orders = 0; }
 
 
 
111
 
112
  $date = mailchimp_date_local('now');
113
 
114
  // but we need to do it just in case.
115
  return $this->mailchimp_rest_response(array(
116
  'success' => true,
117
- 'promo_rules_in_store' => isset($promo_rules_count['publish']) ? (int) $promo_rules_count['publish'] : 0,
118
  'promo_rules_in_mailchimp' => $mailchimp_total_promo_rules,
 
119
  'products_in_store' => $product_count,
120
  'products_in_mailchimp' => $mailchimp_total_products,
 
121
  'orders_in_store' => $order_count,
122
  'orders_in_mailchimp' => $mailchimp_total_orders,
123
- 'promo_rules_page' => get_option('mailchimp-woocommerce-sync.coupons.current_page'),
124
- 'products_page' => get_option('mailchimp-woocommerce-sync.products.current_page'),
125
- 'orders_page' => get_option('mailchimp-woocommerce-sync.orders.current_page'),
 
 
126
  'date' => $date->format( __('D, M j, Y g:i A', 'mailchimp-for-woocommerce')),
127
- 'has_started' => mailchimp_has_started_syncing(),
128
- 'has_finished' => mailchimp_is_done_syncing(),
129
  ));
130
  }
131
 
89
  }
90
 
91
  $store_id = mailchimp_get_store_id();
92
+
93
+ $complete = array(
94
+ 'coupons' => get_option('mailchimp-woocommerce-sync.coupons.completed_at'),
95
+ 'products' => get_option('mailchimp-woocommerce-sync.products.completed_at'),
96
+ 'orders' => get_option('mailchimp-woocommerce-sync.orders.completed_at')
97
+ );
98
+
99
+ $promo_rules_count = mailchimp_get_coupons_count();
100
  $product_count = mailchimp_get_product_count();
101
  $order_count = mailchimp_get_order_count();
102
 
103
+ $mailchimp_total_promo_rules = $complete['coupons'] ? $promo_rules_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_SingleCoupon') : 0;
104
+ $mailchimp_total_products = $complete['products'] ? $product_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Product') : 0;
105
+ $mailchimp_total_orders = $complete['orders'] ? $order_count - mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Order') : 0;
106
+ // try {
107
+ // $promo_rules = $api->getPromoRules($store_id, 1, 1, 1);
108
+ // $mailchimp_total_promo_rules = $promo_rules['total_items'];
109
+ // if (isset($promo_rules_count['publish']) && $mailchimp_total_promo_rules > $promo_rules_count['publish']) $mailchimp_total_promo_rules = $promo_rules_count['publish'];
110
+ // } catch (\Exception $e) { $mailchimp_total_promo_rules = 0; }
111
+ // try {
112
+ // $products = $api->products($store_id, 1, 1);
113
+ // $mailchimp_total_products = $products['total_items'];
114
+ // if ($mailchimp_total_products > $product_count) $mailchimp_total_products = $product_count;
115
+ // } catch (\Exception $e) { $mailchimp_total_products = 0; }
116
+ // try {
117
+ // $orders = $api->orders($store_id, 1, 1);
118
+ // $mailchimp_total_orders = $orders['total_items'];
119
+ // if ($mailchimp_total_orders > $order_count) $mailchimp_total_orders = $order_count;
120
+ // } catch (\Exception $e) { $mailchimp_total_orders = 0; }
121
 
122
  $date = mailchimp_date_local('now');
123
 
124
  // but we need to do it just in case.
125
  return $this->mailchimp_rest_response(array(
126
  'success' => true,
127
+ 'promo_rules_in_store' => $promo_rules_count,
128
  'promo_rules_in_mailchimp' => $mailchimp_total_promo_rules,
129
+
130
  'products_in_store' => $product_count,
131
  'products_in_mailchimp' => $mailchimp_total_products,
132
+
133
  'orders_in_store' => $order_count,
134
  'orders_in_mailchimp' => $mailchimp_total_orders,
135
+
136
+ // 'promo_rules_page' => get_option('mailchimp-woocommerce-sync.coupons.current_page'),
137
+ // 'products_page' => get_option('mailchimp-woocommerce-sync.products.current_page'),
138
+ // 'orders_page' => get_option('mailchimp-woocommerce-sync.orders.current_page'),
139
+
140
  'date' => $date->format( __('D, M j, Y g:i A', 'mailchimp-for-woocommerce')),
141
+ 'has_started' => mailchimp_has_started_syncing() || ($order_count != $mailchimp_total_orders),
142
+ 'has_finished' => mailchimp_is_done_syncing() && ($order_count == $mailchimp_total_orders),
143
  ));
144
  }
145
 
includes/class-mailchimp-woocommerce-service.php CHANGED
@@ -12,6 +12,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
12
  {
13
  protected $user_email = null;
14
  protected $previous_email = null;
 
15
  protected $force_cart_post = false;
16
  protected $cart_was_submitted = false;
17
  protected $cart = array();
@@ -89,7 +90,10 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
89
  $campaign_id = $this->getCampaignTrackingID();
90
  if (empty($campaign_id)) {
91
  $campaign_id = get_post_meta($order_id, 'mailchimp_woocommerce_campaign_id', true);
92
- if (!$campaign_id) $campaign = null;
 
 
 
93
  }
94
 
95
  // grab the landing site cookie if we have one here.
@@ -143,6 +147,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
143
  // queue up the single order to be processed.
144
  $campaign_id = isset($tracking) && isset($tracking['campaign_id']) ? $tracking['campaign_id'] : null;
145
  $landing_site = isset($tracking) && isset($tracking['landing_site']) ? $tracking['landing_site'] : null;
 
146
 
147
  if (isset($tracking)) {
148
  // update the post meta with campaing tracking details for future sync
@@ -150,7 +155,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
150
  update_post_meta($order_id, 'mailchimp_woocommerce_landing_site', $landing_site);
151
  }
152
 
153
- $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, $campaign_id, $landing_site);
154
  $handler->is_update = $newOrder ? !$newOrder : null;
155
  $handler->is_admin_save = is_admin();
156
 
@@ -229,9 +234,12 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
229
 
230
  // grab the cookie data that could play important roles in the submission
231
  $campaign = $this->getCampaignTrackingID();
232
-
 
 
 
233
  // fire up the job handler
234
- $handler = new MailChimp_WooCommerce_Cart_Update($uid, $user_email, $campaign, $this->cart);
235
  mailchimp_handle_or_queue($handler);
236
  }
237
 
@@ -358,7 +366,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
358
  update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
359
 
360
  if ($subscribed) {
361
- mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, $subscribed, null, substr( get_locale(), 0, 2 )));
362
  }
363
  }
364
 
@@ -377,7 +385,7 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
377
  if ($is_subscribed === '' || $is_subscribed === null) return;
378
 
379
  // only send this update if the user actually has a boolean value.
380
- mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, (bool) $is_subscribed, $old_user_data, substr( get_locale(), 0, 2 )));
381
  }
382
 
383
  /**
@@ -488,10 +496,16 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
488
  public function getCampaignTrackingID()
489
  {
490
  $cookie = $this->cookie('mailchimp_campaign_id', false);
 
491
  if (empty($cookie)) {
492
  $cookie = $this->getWooSession('mailchimp_campaign_id', false);
493
  }
494
 
 
 
 
 
 
495
  return $cookie;
496
  }
497
 
@@ -508,6 +522,11 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
508
 
509
  $cid = trim($id);
510
 
 
 
 
 
 
511
  // don't throw the error if it's not found.
512
  if (!$this->api()->getCampaign($cid, false)) {
513
  $cid = null;
@@ -519,6 +538,16 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
519
  return $this;
520
  }
521
 
 
 
 
 
 
 
 
 
 
 
522
  /**
523
  * @return mixed|null
524
  */
@@ -695,6 +724,10 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
695
 
696
  $this->getCartItems();
697
 
 
 
 
 
698
  $this->handleCartUpdated();
699
 
700
  $this->respondJSON(array(
@@ -845,17 +878,22 @@ class MailChimp_Service extends MailChimp_WooCommerce_Options
845
  $job_id =$job_row->id;
846
 
847
  // process job
848
- //mailchimp_debug('action_scheduler.process_job', get_class($job) . ' :: obj_id '.$job->id);
849
  $job->handle();
850
 
851
  // delete processed job
852
  $sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}mailchimp_jobs WHERE id = %s AND obj_id = %s", array($job_id, $obj_id));
853
  $wpdb->query($sql);
854
 
 
855
  } catch (\Exception $e) {
856
  $message = !empty($e->getMessage()) ? ' - ' . $e->getMessage() :'';
857
  mailchimp_debug('action_scheduler.process_job.fail', get_class($job) . ' :: obj_id '.$obj_id . ' :: ' .get_class($e) . $message);
858
  }
859
- return true;
 
 
 
 
 
860
  }
861
  }
12
  {
13
  protected $user_email = null;
14
  protected $previous_email = null;
15
+ protected $user_language = null;
16
  protected $force_cart_post = false;
17
  protected $cart_was_submitted = false;
18
  protected $cart = array();
90
  $campaign_id = $this->getCampaignTrackingID();
91
  if (empty($campaign_id)) {
92
  $campaign_id = get_post_meta($order_id, 'mailchimp_woocommerce_campaign_id', true);
93
+ // make sure this campaign ID has a valid format before we submit something
94
+ if (!$this->campaignIdMatchesFormat($campaign_id)) {
95
+ $campaign = null;
96
+ }
97
  }
98
 
99
  // grab the landing site cookie if we have one here.
147
  // queue up the single order to be processed.
148
  $campaign_id = isset($tracking) && isset($tracking['campaign_id']) ? $tracking['campaign_id'] : null;
149
  $landing_site = isset($tracking) && isset($tracking['landing_site']) ? $tracking['landing_site'] : null;
150
+ $language = $newOrder ? substr( get_locale(), 0, 2 ) : null;
151
 
152
  if (isset($tracking)) {
153
  // update the post meta with campaing tracking details for future sync
155
  update_post_meta($order_id, 'mailchimp_woocommerce_landing_site', $landing_site);
156
  }
157
 
158
+ $handler = new MailChimp_WooCommerce_Single_Order($order_id, null, $campaign_id, $landing_site, $language);
159
  $handler->is_update = $newOrder ? !$newOrder : null;
160
  $handler->is_admin_save = is_admin();
161
 
234
 
235
  // grab the cookie data that could play important roles in the submission
236
  $campaign = $this->getCampaignTrackingID();
237
+
238
+ // get user language or default to admin main language
239
+ $language = $this->user_language ?: substr( get_locale(), 0, 2 );
240
+
241
  // fire up the job handler
242
+ $handler = new MailChimp_WooCommerce_Cart_Update($uid, $user_email, $campaign, $this->cart, $language);
243
  mailchimp_handle_or_queue($handler);
244
  }
245
 
366
  update_user_meta($user_id, 'mailchimp_woocommerce_is_subscribed', $subscribed);
367
 
368
  if ($subscribed) {
369
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, $subscribed, null));
370
  }
371
  }
372
 
385
  if ($is_subscribed === '' || $is_subscribed === null) return;
386
 
387
  // only send this update if the user actually has a boolean value.
388
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_User_Submit($user_id, (bool) $is_subscribed, $old_user_data));
389
  }
390
 
391
  /**
496
  public function getCampaignTrackingID()
497
  {
498
  $cookie = $this->cookie('mailchimp_campaign_id', false);
499
+
500
  if (empty($cookie)) {
501
  $cookie = $this->getWooSession('mailchimp_campaign_id', false);
502
  }
503
 
504
+ // we must follow a pattern at minimum in order to think this is possibly a valid campaign ID.
505
+ if (!$this->campaignIdMatchesFormat($cookie)) {
506
+ return false;
507
+ }
508
+
509
  return $cookie;
510
  }
511
 
522
 
523
  $cid = trim($id);
524
 
525
+ // we must follow a pattern at minimum in order to think this is possibly a valid campaign ID.
526
+ if (!$this->campaignIdMatchesFormat($cid)) {
527
+ return $this;
528
+ }
529
+
530
  // don't throw the error if it's not found.
531
  if (!$this->api()->getCampaign($cid, false)) {
532
  $cid = null;
538
  return $this;
539
  }
540
 
541
+ /**
542
+ * @param $cid
543
+ * @return bool
544
+ */
545
+ public function campaignIdMatchesFormat($cid)
546
+ {
547
+ if (!is_string($cid) || empty($cid)) return false;
548
+ return (bool) preg_match("/^[a-zA-Z0-9]{10,12}$/", $cid, $matches);
549
+ }
550
+
551
  /**
552
  * @return mixed|null
553
  */
724
 
725
  $this->getCartItems();
726
 
727
+ if (isset($_GET['language'])) {
728
+ $this->user_language = $_GET['language'];
729
+ }
730
+
731
  $this->handleCartUpdated();
732
 
733
  $this->respondJSON(array(
878
  $job_id =$job_row->id;
879
 
880
  // process job
 
881
  $job->handle();
882
 
883
  // delete processed job
884
  $sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}mailchimp_jobs WHERE id = %s AND obj_id = %s", array($job_id, $obj_id));
885
  $wpdb->query($sql);
886
 
887
+ return true;
888
  } catch (\Exception $e) {
889
  $message = !empty($e->getMessage()) ? ' - ' . $e->getMessage() :'';
890
  mailchimp_debug('action_scheduler.process_job.fail', get_class($job) . ' :: obj_id '.$obj_id . ' :: ' .get_class($e) . $message);
891
  }
892
+ return false;
893
+ }
894
+
895
+ public function mailchimp_process_sync_manager () {
896
+ $sync_stats_manager = new MailChimp_WooCommerce_Process_Full_Sync_Manager();
897
+ $sync_stats_manager->handle();
898
  }
899
  }
includes/class-mailchimp-woocommerce.php CHANGED
@@ -225,6 +225,7 @@ class MailChimp_WooCommerce
225
 
226
  // Add menu item
227
  $this->loader->add_action('admin_menu', $plugin_admin, 'add_plugin_admin_menu');
 
228
 
229
  // Add WooCommerce Navigation Bar
230
  $this->loader->add_action('admin_menu', $plugin_admin, 'add_woocommerce_navigation_bar');
@@ -277,7 +278,9 @@ class MailChimp_WooCommerce
277
 
278
  $plugin_public = new MailChimp_WooCommerce_Public( $this->get_plugin_name(), $this->get_version() );
279
  $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts');
280
- $this->loader->add_action('wp_footer', $plugin_public, 'add_inline_footer_script');
 
 
281
  }
282
 
283
  /**
@@ -335,7 +338,6 @@ class MailChimp_WooCommerce
335
  $this->loader->add_action('woocommerce_order_partially_refunded', $service, 'onPartiallyRefunded', 20, 1);
336
 
337
  // cart hooks
338
- //$this->loader->add_action('woocommerce_cart_updated', $service, 'handleCartUpdated');
339
  $this->loader->add_filter('woocommerce_update_cart_action_cart_updated', $service, 'handleCartUpdated');
340
  $this->loader->add_action('woocommerce_add_to_cart', $service, 'handleCartUpdated');
341
  $this->loader->add_action('woocommerce_cart_item_removed', $service, 'handleCartUpdated');
@@ -374,13 +376,14 @@ class MailChimp_WooCommerce
374
  "MailChimp_WooCommerce_Cart_Update",
375
  "MailChimp_WooCommerce_User_Submit",
376
  "MailChimp_WooCommerce_Process_Coupons",
377
- "MailChimp_WooCommerce_Process_Coupons_Initial_Sync",
378
  "MailChimp_WooCommerce_Process_Orders",
379
  "MailChimp_WooCommerce_Process_Products"
380
  );
381
  foreach ($jobs_classes as $job_class) {
382
  $this->loader->add_action($job_class, $service, 'mailchimp_process_single_job', 10, 1);
383
  }
 
 
384
  }
385
  }
386
 
225
 
226
  // Add menu item
227
  $this->loader->add_action('admin_menu', $plugin_admin, 'add_plugin_admin_menu');
228
+ $this->loader->add_filter('parent_file', $plugin_admin, 'highlight_admin_menu');
229
 
230
  // Add WooCommerce Navigation Bar
231
  $this->loader->add_action('admin_menu', $plugin_admin, 'add_woocommerce_navigation_bar');
278
 
279
  $plugin_public = new MailChimp_WooCommerce_Public( $this->get_plugin_name(), $this->get_version() );
280
  $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts');
281
+ if ( apply_filters( 'mailchimp_add_inline_footer_script', true ) ) {
282
+ $this->loader->add_action('wp_footer', $plugin_public, 'add_inline_footer_script');
283
+ }
284
  }
285
 
286
  /**
338
  $this->loader->add_action('woocommerce_order_partially_refunded', $service, 'onPartiallyRefunded', 20, 1);
339
 
340
  // cart hooks
 
341
  $this->loader->add_filter('woocommerce_update_cart_action_cart_updated', $service, 'handleCartUpdated');
342
  $this->loader->add_action('woocommerce_add_to_cart', $service, 'handleCartUpdated');
343
  $this->loader->add_action('woocommerce_cart_item_removed', $service, 'handleCartUpdated');
376
  "MailChimp_WooCommerce_Cart_Update",
377
  "MailChimp_WooCommerce_User_Submit",
378
  "MailChimp_WooCommerce_Process_Coupons",
 
379
  "MailChimp_WooCommerce_Process_Orders",
380
  "MailChimp_WooCommerce_Process_Products"
381
  );
382
  foreach ($jobs_classes as $job_class) {
383
  $this->loader->add_action($job_class, $service, 'mailchimp_process_single_job', 10, 1);
384
  }
385
+ // sync stats manager
386
+ $this->loader->add_action('MailChimp_WooCommerce_Process_Full_Sync_Manager', $service, 'mailchimp_process_sync_manager', 10, 1);
387
  }
388
  }
389
 
includes/processes/class-mailchimp-woocommerce-abstract-sync.php CHANGED
@@ -30,21 +30,29 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
30
  */
31
  protected $store_id = '';
32
 
 
 
 
 
 
33
  /**
34
- * @var bool
35
  */
36
- protected $has_applied_pagination = false;
37
 
38
  /**
39
- * @return mixed
 
40
  */
41
- abstract public function getResourceType();
 
 
 
42
 
43
  /**
44
- * @param $item
45
  * @return mixed
46
  */
47
- abstract protected function iterate($item);
48
 
49
  /**
50
  * @return mixed
@@ -52,11 +60,51 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
52
  abstract protected function complete();
53
 
54
  /**
55
- * @return mixed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  */
57
- public function go()
58
  {
59
- return $this->handle();
60
  }
61
 
62
  /**
@@ -99,19 +147,13 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
99
  if ($this->isBeingRateLimited()) {
100
  // ok - hold off for a few - let's re-queue the job.
101
  mailchimp_debug(get_called_class().'@handle', 'being rate limited - pausing for a few seconds...');
102
- $this->next();
103
  return false;
104
  }
105
  }
106
 
107
- // don't let recursion happen.
108
- if ($this->getResourceType() === 'orders' && $this->getResourceCompleteTime()) {
109
- mailchimp_log('sync.stop', "halting the sync for :: {$this->getResourceType()}");
110
- return false;
111
- }
112
-
113
  $page = $this->getResources();
114
-
115
  if (empty($page)) {
116
  mailchimp_debug(get_called_class().'@handle', 'could not find any more '.$this->getResourceType().' records ending on page '.$this->getResourcePagePointer());
117
  // call the completed event to process further
@@ -121,7 +163,6 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
121
  return false;
122
  }
123
 
124
- $this->setResourcePagePointer(($page->page + 1), $this->getResourceType());
125
 
126
  // if we've got a 0 count, that means we're done.
127
  if ($page->count <= 0) {
@@ -134,112 +175,38 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
134
  // call the completed event to process further
135
  $this->complete();
136
 
137
-
138
  return false;
139
  }
140
 
141
  // iterate through the items and send each one through the pipeline based on this class.
142
  foreach ($page->items as $resource) {
143
- try {
144
- $this->iterateCurrentResource($resource);
145
- } catch (MailChimp_WooCommerce_RateLimitError $e) {
146
- $this->applyRateLimitedScenario();
147
- return false;
148
- }
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
- $this->next();
152
-
153
  return false;
154
  }
155
 
156
- /**
157
- * @param $resource
158
- * @return bool
159
- * @throws MailChimp_WooCommerce_RateLimitError
160
- */
161
- protected function iterateCurrentResource($resource)
162
- {
163
- $attempts = 1;
164
- while ($attempts <= 4) {
165
- $attempts++;
166
- try {
167
- return $this->iterate($resource);
168
- } catch (MailChimp_WooCommerce_RateLimitError $e) {
169
- if ($attempts === 4) {
170
- throw $e;
171
- }
172
- sleep(3);
173
- }
174
- }
175
- }
176
-
177
- /**
178
- * @return $this
179
- */
180
- public function flagStartSync()
181
- {
182
- $job = new MailChimp_Service();
183
-
184
- $job->removeSyncPointers();
185
-
186
- $this->setData('sync.config.resync', false);
187
- $this->setData('sync.orders.current_page', 1);
188
- $this->setData('sync.products.current_page', 1);
189
- $this->setData('sync.coupons.current_page', 1);
190
- $this->setData('sync.syncing', true);
191
- $this->setData('sync.started_at', time());
192
-
193
- if (! $this->getData('sync.completed_at')) {
194
- $this->setData('sync.initial_sync', 1);
195
- } else $this->removeData('sync.initial_sync');
196
-
197
- global $wpdb;
198
- try {
199
- $wpdb->show_errors(false);
200
- mailchimp_delete_as_jobs();
201
- $wpdb->show_errors(true);
202
- } catch (\Exception $e) {}
203
-
204
- mailchimp_log('sync.started', "Starting Sync :: ".date('D, M j, Y g:i A'));
205
-
206
- // flag the store as syncing
207
- mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), true);
208
-
209
- return $this;
210
- }
211
-
212
- /**
213
- * @return $this
214
- */
215
- public function flagStopSync()
216
- {
217
- // this is the last thing we're doing so it's complete as of now.
218
- $this->setData('sync.syncing', false);
219
- $this->setData('sync.completed_at', time());
220
-
221
- // set the current sync pages back to 1 if the user hits resync.
222
- $this->setData('sync.orders.current_page', 1);
223
- $this->setData('sync.products.current_page', 1);
224
- $this->setData('sync.coupons.current_page', 1);
225
-
226
- mailchimp_log('sync.completed', "Finished Sync :: ".date('D, M j, Y g:i A'));
227
-
228
- // flag the store as sync_finished
229
- mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), false);
230
-
231
- mailchimp_update_communication_status();
232
-
233
- return $this;
234
- }
235
-
236
  /**
237
  * @return bool|object|stdClass
238
  */
239
  public function getResources()
240
  {
241
- $current_page = $this->getResourcePagePointer($this->getResourceType());
242
-
243
  if ($current_page === 'complete') {
244
  if (!$this->getData('sync.config.resync', false)) {
245
  return false;
@@ -250,20 +217,7 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
250
  $this->setData('sync.config.resync', false);
251
  }
252
 
253
- return $this->api()->paginate($this->getResourceType(), $current_page, 5);
254
- }
255
-
256
- /**
257
- * @param null|string $resource
258
- * @return $this
259
- */
260
- public function resetResourcePagePointer($resource = null)
261
- {
262
- if (empty($resource)) $resource = $this->getResourceType();
263
-
264
- $this->setData('sync.'.$resource.'.current_page', 1);
265
-
266
- return $this;
267
  }
268
 
269
  /**
@@ -286,9 +240,6 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
286
  {
287
  if (empty($resource)) $resource = $this->getResourceType();
288
 
289
- // tell the file that if we catch a rate limit error that we need to revert to the current page.
290
- $this->has_applied_pagination = $page;
291
-
292
  return $this->setData('sync.'.$resource.'.current_page', $page);
293
  }
294
 
@@ -444,31 +395,4 @@ abstract class MailChimp_WooCommerce_Abstract_Sync extends Mailchimp_Woocommerce
444
  {
445
  return (bool) mailchimp_get_transient('api-rate-limited', false);
446
  }
447
-
448
- /**
449
- * @return $this
450
- */
451
- protected function applyRateLimitedScenario()
452
- {
453
- mailchimp_set_transient('api-rate-limited', true, 60);
454
-
455
- if ($this->has_applied_pagination) {
456
- $this->setResourcePagePointer(($this->has_applied_pagination-1));
457
- $this->has_applied_pagination = false;
458
- }
459
-
460
- $this->next();
461
-
462
- return $this;
463
- }
464
-
465
- /**
466
- *
467
- */
468
- protected function next()
469
- {
470
- // this will paginate through all records for the resource type until they return no records.
471
- mailchimp_handle_or_queue(new static(), 0);
472
- mailchimp_debug(get_called_class().'@handle', 'queuing up the next job');
473
- }
474
  }
30
  */
31
  protected $store_id = '';
32
 
33
+ /**
34
+ * @var int
35
+ */
36
+ public $current_page = null;
37
+
38
  /**
39
+ * @var int
40
  */
41
+ public $items_per_page = 100;
42
 
43
  /**
44
+ * MailChimp_WooCommerce_Abstract_Sync constructor.
45
+ * @param int $current_page
46
  */
47
+ public function __construct($current_page = 1)
48
+ {
49
+ $this->setCurrentPage($current_page);
50
+ }
51
 
52
  /**
 
53
  * @return mixed
54
  */
55
+ abstract public function getResourceType();
56
 
57
  /**
58
  * @return mixed
60
  abstract protected function complete();
61
 
62
  /**
63
+ * @return bool
64
+ */
65
+ public function createSyncManagers()
66
+ {
67
+ switch ($this->getResourceType()) {
68
+ case 'coupons':
69
+ $post_count = mailchimp_get_coupons_count();
70
+ break;
71
+ case 'products':
72
+ $post_count = mailchimp_get_product_count();
73
+ break;
74
+ case 'orders':
75
+ $post_count = mailchimp_get_order_count();
76
+ break;
77
+ default:
78
+ mailchimp_log('sync.error', $this->getResourceType().' is not a valid resource.');
79
+ break;
80
+ }
81
+
82
+ $this->setData('sync.'.$this->getResourceType().'.started_at', time());
83
+
84
+ $page = $this->getCurrentPage();
85
+
86
+ while ($page - 1 <= ceil((int)$post_count / $this->items_per_page)) {
87
+ $next = new static($page);
88
+ mailchimp_handle_or_queue($next);
89
+ $this->setResourcePagePointer(($page), $this->getResourceType());
90
+ $page++;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @return string
96
+ */
97
+ public function setCurrentPage($current_page)
98
+ {
99
+ $this->current_page = $current_page;
100
+ }
101
+
102
+ /**
103
+ * @return string
104
  */
105
+ public function getCurrentPage()
106
  {
107
+ return $this->current_page;
108
  }
109
 
110
  /**
147
  if ($this->isBeingRateLimited()) {
148
  // ok - hold off for a few - let's re-queue the job.
149
  mailchimp_debug(get_called_class().'@handle', 'being rate limited - pausing for a few seconds...');
150
+ $this->retry();
151
  return false;
152
  }
153
  }
154
 
 
 
 
 
 
 
155
  $page = $this->getResources();
156
+
157
  if (empty($page)) {
158
  mailchimp_debug(get_called_class().'@handle', 'could not find any more '.$this->getResourceType().' records ending on page '.$this->getResourcePagePointer());
159
  // call the completed event to process further
163
  return false;
164
  }
165
 
 
166
 
167
  // if we've got a 0 count, that means we're done.
168
  if ($page->count <= 0) {
175
  // call the completed event to process further
176
  $this->complete();
177
 
 
178
  return false;
179
  }
180
 
181
  // iterate through the items and send each one through the pipeline based on this class.
182
  foreach ($page->items as $resource) {
183
+ switch ($this->getResourceType()) {
184
+ case 'coupons':
185
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_SingleCoupon($resource));
186
+ break;
187
+ case 'products':
188
+ mailchimp_handle_or_queue(new MailChimp_WooCommerce_Single_Product($resource));
189
+ break;
190
+ case 'orders':
191
+ $order = new MailChimp_WooCommerce_Single_Order($resource);
192
+ $order->set_full_sync(true);
193
+ mailchimp_handle_or_queue($order);
194
+ break;
195
+ default:
196
+ mailchimp_log('sync.error', $this->getResourceType().' is not a valid resource.');
197
+ break;
198
+ }
199
  }
200
 
 
 
201
  return false;
202
  }
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  /**
205
  * @return bool|object|stdClass
206
  */
207
  public function getResources()
208
  {
209
+ $current_page = $this->getCurrentPage();
 
210
  if ($current_page === 'complete') {
211
  if (!$this->getData('sync.config.resync', false)) {
212
  return false;
217
  $this->setData('sync.config.resync', false);
218
  }
219
 
220
+ return $this->api()->paginate($this->getResourceType(), $current_page, $this->items_per_page);
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  }
222
 
223
  /**
240
  {
241
  if (empty($resource)) $resource = $this->getResourceType();
242
 
 
 
 
243
  return $this->setData('sync.'.$resource.'.current_page', $page);
244
  }
245
 
395
  {
396
  return (bool) mailchimp_get_transient('api-rate-limited', false);
397
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  }
includes/processes/class-mailchimp-woocommerce-cart-update.php CHANGED
@@ -16,6 +16,7 @@ class MailChimp_WooCommerce_Cart_Update extends Mailchimp_Woocommerce_Job
16
  public $campaign_id;
17
  public $cart_data;
18
  public $ip_address;
 
19
 
20
 
21
  /**
@@ -25,7 +26,7 @@ class MailChimp_WooCommerce_Cart_Update extends Mailchimp_Woocommerce_Job
25
  * @param null $campaign_id
26
  * @param array $cart_data
27
  */
28
- public function __construct($uid = null, $email = null, $campaign_id = null, array $cart_data = array())
29
  {
30
  if ($uid) {
31
  $this->id = $uid;
@@ -40,6 +41,10 @@ class MailChimp_WooCommerce_Cart_Update extends Mailchimp_Woocommerce_Job
40
  if ($campaign_id) {
41
  $this->campaign_id = $campaign_id;
42
  }
 
 
 
 
43
 
44
  $this->assignIP();
45
  }
@@ -171,6 +176,9 @@ class MailChimp_WooCommerce_Cart_Update extends Mailchimp_Woocommerce_Job
171
  mailchimp_log('abandoned_cart.success', "email: {$customer->getEmailAddress()}");
172
  }
173
 
 
 
 
174
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
175
  sleep(3);
176
  mailchimp_error('cart.error', mailchimp_error_trace($e, "RateLimited :: email {$this->email}"));
16
  public $campaign_id;
17
  public $cart_data;
18
  public $ip_address;
19
+ public $user_language;
20
 
21
 
22
  /**
26
  * @param null $campaign_id
27
  * @param array $cart_data
28
  */
29
+ public function __construct($uid = null, $email = null, $campaign_id = null, array $cart_data = array(), $user_language = null)
30
  {
31
  if ($uid) {
32
  $this->id = $uid;
41
  if ($campaign_id) {
42
  $this->campaign_id = $campaign_id;
43
  }
44
+
45
+ if ($user_language) {
46
+ $this->user_language = $user_language;
47
+ }
48
 
49
  $this->assignIP();
50
  }
176
  mailchimp_log('abandoned_cart.success', "email: {$customer->getEmailAddress()}");
177
  }
178
 
179
+ // Maybe sync subscriber to set correct member.language
180
+ mailchimp_member_language_update($this->email, $this->user_language, 'cart');
181
+
182
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
183
  sleep(3);
184
  mailchimp_error('cart.error', mailchimp_error_trace($e, "RateLimited :: email {$this->email}"));
includes/processes/class-mailchimp-woocommerce-full-sync-manager.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by Vextras.
4
+ *
5
+ * Name: Pedro Germani
6
+ * Email: pedro.germani@gmail.com
7
+ * Date: 04/07/2020
8
+ */
9
+
10
+ if ( ! class_exists( 'MailChimp_WooCommerce_Process_Full_Sync_Manager' ) ) {
11
+ class MailChimp_WooCommerce_Process_Full_Sync_Manager {
12
+ /**
13
+ * @var string
14
+ */
15
+ private $plugin_name = 'mailchimp-woocommerce';
16
+
17
+ /**
18
+ * Start the full sync process
19
+ */
20
+ public function start_sync() {
21
+
22
+ $this->flag_start_sync();
23
+
24
+ $coupons_sync = new MailChimp_WooCommerce_Process_Coupons();
25
+
26
+ // start sync processes creation
27
+ $coupons_sync->createSyncManagers();
28
+
29
+ }
30
+
31
+ /**
32
+ * @return $this
33
+ */
34
+ public function flag_start_sync() {
35
+ $job = new MailChimp_Service();
36
+
37
+ $job->removeSyncPointers();
38
+
39
+ update_option("{$this->plugin_name}-sync.config.resync", false);
40
+ update_option("{$this->plugin_name}-sync.orders.current_page", 1);
41
+ update_option("{$this->plugin_name}-sync.products.current_page", 1);
42
+ update_option("{$this->plugin_name}-sync.coupons.current_page", 1);
43
+
44
+ update_option("{$this->plugin_name}-sync.syncing", true);
45
+ update_option("{$this->plugin_name}-sync.started_at", time());
46
+
47
+ if (! get_option("{$this->plugin_name}-sync.completed_at")) {
48
+ update_option("{$this->plugin_name}-sync.initial_sync", 1);
49
+ } else delete_option("{$this->plugin_name}-sync.initial_sync");
50
+
51
+ global $wpdb;
52
+ try {
53
+ $wpdb->show_errors(false);
54
+ mailchimp_delete_as_jobs();
55
+ mailchimp_flush_sync_job_tables();
56
+ $wpdb->show_errors(true);
57
+ } catch (\Exception $e) {}
58
+
59
+ mailchimp_log("{$this->plugin_name}-sync.started", "Starting Sync :: ".date('D, M j, Y g:i A'));
60
+
61
+ // flag the store as syncing
62
+ mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), true);
63
+
64
+ return $this;
65
+ }
66
+
67
+ /**
68
+ *
69
+ */
70
+ function flag_stop_sync()
71
+ {
72
+ // this is the last thing we're doing so it's complete as of now.
73
+ mailchimp_set_data('sync.syncing', false);
74
+ mailchimp_set_data('sync.completed_at', time());
75
+
76
+ // set the current sync pages back to 1 if the user hits resync.
77
+ mailchimp_set_data('sync.orders.current_page', 1);
78
+ mailchimp_set_data('sync.products.current_page', 1);
79
+ mailchimp_set_data('sync.coupons.current_page', 1);
80
+
81
+ $sync_started_at = get_option('mailchimp-woocommerce-sync.started_at');
82
+ $sync_completed_at = get_option('mailchimp-woocommerce-sync.completed_at');
83
+
84
+ $sync_total_time = $sync_completed_at - $sync_started_at;
85
+ $time = gmdate("H:i:s",$sync_total_time);
86
+
87
+ mailchimp_log('sync.completed', "Finished Sync :: ".date('D, M j, Y g:i A'). " (total time: ".$time.")");
88
+
89
+ // flag the store as sync_finished
90
+ mailchimp_get_api()->flagStoreSync(mailchimp_get_store_id(), false);
91
+
92
+ mailchimp_update_communication_status();
93
+
94
+ }
95
+
96
+ public function handle(){
97
+ // Trigger respawn
98
+ $this->recreate();
99
+
100
+ // get started queueing processes
101
+ $started = array(
102
+ 'coupons' => get_option('mailchimp-woocommerce-sync.coupons.started_at'),
103
+ 'products' => get_option('mailchimp-woocommerce-sync.products.started_at'),
104
+ 'orders' => get_option('mailchimp-woocommerce-sync.orders.started_at')
105
+ );
106
+
107
+ // get completed queueing processes
108
+ $completed = array(
109
+ 'coupons' => get_option('mailchimp-woocommerce-sync.coupons.completed_at'),
110
+ 'products' => get_option('mailchimp-woocommerce-sync.products.completed_at'),
111
+ 'orders' => get_option('mailchimp-woocommerce-sync.orders.completed_at')
112
+ );
113
+
114
+ // allow products and coupons to be synced simultaneously
115
+ if ($started['coupons'] && !$started['products']) {
116
+ mailchimp_log('sync.full_sync_manager.queue', 'Starting PRODUCTS queueing.');
117
+ //create Product Sync object
118
+ $product_sync = new MailChimp_WooCommerce_Process_Products();
119
+
120
+ // queue first job
121
+ //mailchimp_handle_or_queue($product_sync);
122
+
123
+ //trigger subsequent jobs creation
124
+ $product_sync->createSyncManagers();
125
+ }
126
+
127
+ // Only start orders when product jobs are all finished
128
+ if ($completed['products'] && !$started['orders'] ) {
129
+ // check if we have products still to be synced
130
+ if (mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Product') == 0 && mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Process_Products') <= 0) {
131
+
132
+ $prevent_order_sync = get_option('mailchimp-woocommerce-sync.orders.prevent', false);
133
+
134
+ // only do this if we're not strictly syncing products ( which is the default ).
135
+ if (!$prevent_order_sync) {
136
+ // since the products are all good, let's sync up the orders now.
137
+ $order_sync = new MailChimp_WooCommerce_Process_Orders();
138
+ // // queue first job
139
+ //mailchimp_handle_or_queue($order_sync);
140
+ // //trigger subsequent jobs creation
141
+ $order_sync->createSyncManagers();
142
+ }
143
+
144
+ // since we skipped the orders feed we can delete this option.
145
+ delete_option('mailchimp-woocommerce-sync.orders.prevent');
146
+ }
147
+
148
+ }
149
+
150
+ if ($completed['orders']) {
151
+ if (mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Single_Order') <= 0 && mailchimp_get_remaining_jobs_count('MailChimp_WooCommerce_Process_Orders') <= 0) {
152
+ $this->flag_stop_sync();
153
+ as_unschedule_action('MailChimp_WooCommerce_Process_Full_Sync_Manager', array(), 'mc-woocommerce' );
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ *
160
+ */
161
+ protected function recreate()
162
+ {
163
+ as_schedule_single_action(strtotime( '+10 seconds' ), 'MailChimp_WooCommerce_Process_Full_Sync_Manager', array(), 'mc-woocommerce' );
164
+ }
165
+ }
166
+ }
includes/processes/class-mailchimp-woocommerce-job.php CHANGED
@@ -3,23 +3,8 @@
3
  if ( ! class_exists( 'Mailchimp_Woocommerce_Job' ) ) {
4
  abstract class Mailchimp_Woocommerce_Job {
5
 
6
- public $should_kill_queue_listener = false;
7
  private $attempts = 0;
8
 
9
- /**
10
- * @var stdClass
11
- */
12
- private $job;
13
-
14
- /**
15
- * Set job
16
- *
17
- * @param $job
18
- */
19
- public function set_job( $job ) {
20
- $this->job = $job;
21
- }
22
-
23
  /**
24
  * Set attempts
25
  */
@@ -44,6 +29,18 @@ if ( ! class_exists( 'Mailchimp_Woocommerce_Job' ) ) {
44
  mailchimp_as_push($job, $delay);
45
  }
46
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * Handle the job.
49
  */
3
  if ( ! class_exists( 'Mailchimp_Woocommerce_Job' ) ) {
4
  abstract class Mailchimp_Woocommerce_Job {
5
 
 
6
  private $attempts = 0;
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  /**
9
  * Set attempts
10
  */
29
  mailchimp_as_push($job, $delay);
30
  }
31
 
32
+ /**
33
+ * @return $this
34
+ */
35
+ protected function applyRateLimitedScenario()
36
+ {
37
+ mailchimp_set_transient('api-rate-limited', true, 60);
38
+
39
+ $this->retry();
40
+
41
+ return $this;
42
+ }
43
+
44
  /**
45
  * Handle the job.
46
  */
includes/processes/class-mailchimp-woocommerce-process-coupons-initial-sync.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class MailChimp_WooCommerce_Process_Coupons_Then_Products
5
- */
6
- class MailChimp_WooCommerce_Process_Coupons_Initial_Sync extends MailChimp_WooCommerce_Process_Coupons
7
- {
8
- /**
9
- * After the resources have been loaded and pushed
10
- */
11
- protected function complete()
12
- {
13
- mailchimp_log('coupon_sync.completed', 'Done with the coupon sync, queuing up products.');
14
-
15
- // add a timestamp for the orders sync completion
16
- $this->setResourceCompleteTime();
17
-
18
- $product_sync = new MailChimp_WooCommerce_Process_Products();
19
- mailchimp_handle_or_queue($product_sync, 0);
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/processes/class-mailchimp-woocommerce-process-coupons.php CHANGED
@@ -23,48 +23,12 @@ class MailChimp_WooCommerce_Process_Coupons extends MailChimp_WooCommerce_Abstra
23
  return 'coupons';
24
  }
25
 
26
- /**
27
- * @param WC_Coupon $item
28
- *
29
- * @return mixed
30
- */
31
- protected function iterate($item)
32
- {
33
- if ($item instanceof MailChimp_WooCommerce_PromoCode) {
34
-
35
- mailchimp_debug('promo_code_sync', "#{$item->getId()}", $item->toArray());
36
-
37
- try {
38
- $this->mailchimp()->addPromoRule($this->store_id, $item->getAttachedPromoRule(), true);
39
- $response = $this->mailchimp()->addPromoCodeForRule($this->store_id, $item->getAttachedPromoRule(), $item, true);
40
- mailchimp_log('coupon_sync.success', "update promo rule :: #{$item->getCode()}");
41
- return $response;
42
- } catch (MailChimp_WooCommerce_RateLimitError $e) {
43
- mailchimp_error('coupons.error', mailchimp_error_trace($e, "update promo rule :: {$item->getCode()}"));
44
- throw $e;
45
- } catch (MailChimp_WooCommerce_ServerError $e) {
46
- mailchimp_error('coupons.error', mailchimp_error_trace($e, "update promo rule :: {$item->getCode()}"));
47
- return false;
48
- } catch (MailChimp_WooCommerce_Error $e) {
49
- mailchimp_error('coupons.error', mailchimp_error_trace($e, "update promo rule :: {$item->getCode()}"));
50
- return false;
51
- } catch (Exception $e) {
52
- mailchimp_error('coupons.error', mailchimp_error_trace($e, "update promo rule :: {$item->getCode()}"));
53
- return false;
54
- }
55
- }
56
-
57
- mailchimp_debug('coupon_sync', 'no coupon found', $item);
58
-
59
- return false;
60
- }
61
-
62
  /**
63
  * After the resources have been loaded and pushed
64
  */
65
  protected function complete()
66
  {
67
- mailchimp_log('coupon_sync.completed', 'Done with the coupon sync.');
68
 
69
  // add a timestamp for the orders sync completion
70
  $this->setResourceCompleteTime();
23
  return 'coupons';
24
  }
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * After the resources have been loaded and pushed
28
  */
29
  protected function complete()
30
  {
31
+ mailchimp_log('coupon_sync.completed', 'Done with the coupon queueing.');
32
 
33
  // add a timestamp for the orders sync completion
34
  $this->setResourceCompleteTime();
includes/processes/class-mailchimp-woocommerce-process-orders.php CHANGED
@@ -24,178 +24,15 @@ class MailChimp_WooCommerce_Process_Orders extends MailChimp_WooCommerce_Abstrac
24
  return 'orders';
25
  }
26
 
27
- /**
28
- * @param $item
29
- * @return bool|mixed
30
- * @throws Exception
31
- */
32
- protected function iterate($item)
33
- {
34
- if ($item instanceof MailChimp_WooCommerce_Order) {
35
-
36
- // see if we need to prevent this order from being submitted.
37
- $email = $item->getCustomer()->getEmailAddress();
38
-
39
- // see if we have a bad email
40
- if ($this->shouldSkipOrder($email, $item->getId())) {
41
- return false;
42
- }
43
-
44
- // see if this store has the auto subscribe setting enabled on initial sync
45
- $should_auto_subscribe = (bool) $this->getOption('mailchimp_auto_subscribe', false);
46
-
47
- // since we're syncing the customer for the first time, this is where we need to add the override
48
- // for subscriber status. We don't get the checkbox until this plugin is actually installed and working!
49
- if (!($status = $item->getCustomer()->getOptInStatus())) {
50
- try {
51
- $subscriber = $this->mailchimp()->member(mailchimp_get_list_id(), $item->getCustomer()->getEmailAddress());
52
- if ($subscriber['status'] != 'archived') {
53
- $status = !in_array($subscriber['status'], array('unsubscribed', 'transactional'));
54
- $item->getCustomer()->setOptInStatus($status);
55
- }
56
- } catch (\Exception $e) {
57
- if ($e instanceof MailChimp_WooCommerce_RateLimitError) {
58
- mailchimp_error('order_sync.error', mailchimp_error_trace($e, "GET subscriber :: {$item->getId()}"));
59
- throw $e;
60
- }
61
- // if they are using double opt in, we need to pass this in as false here so it doesn't auto subscribe.
62
- $status = mailchimp_list_has_double_optin() ? false : $should_auto_subscribe;
63
- $item->getCustomer()->setOptInStatus($status);
64
- }
65
- }
66
-
67
- try {
68
- $type = $this->mailchimp()->getStoreOrder($this->store_id, $item->getId(), true) ? 'update' : 'create';
69
- } catch (MailChimp_WooCommerce_Error $e) {
70
- if ($e instanceof MailChimp_WooCommerce_RateLimitError) {
71
- mailchimp_error('order_sync.error', mailchimp_error_trace($e, "GET order :: {$item->getId()}"));
72
- throw $e;
73
- }
74
- $type = 'create';
75
- }
76
-
77
- $call = $type === 'create' ? 'addStoreOrder' : 'updateStoreOrder';
78
-
79
- try {
80
-
81
- // if the order is in failed or cancelled status - and it's brand new, we shouldn't submit it.
82
- if ($call === 'addStoreOrder' && !in_array(strtolower($item->getFinancialStatus()), array('processing', 'completed', 'paid'))) {
83
- mailchimp_log('order_sync', "#{$item->getId()} has a financial status of {$item->getFinancialStatus()} and was skipped.");
84
- return false;
85
- }
86
-
87
- $line_items = $item->items();
88
-
89
- // if we don't have any line items, we need to create the mailchimp product
90
- // with a price of 1.00 and we'll use the inventory quantity to adjust correctly.
91
- if (empty($line_items) || !count($line_items)) {
92
-
93
- // this will create an empty product placeholder, or return the pre populated version if already
94
- // sent to Mailchimp.
95
- $product = $this->mailchimp()->createEmptyLineItemProductPlaceholder();
96
-
97
- $line_item = new MailChimp_WooCommerce_LineItem();
98
- $line_item->setId($product->getId());
99
- $line_item->setPrice(1);
100
- $line_item->setProductId($product->getId());
101
- $line_item->setProductVariantId($product->getId());
102
- $line_item->setQuantity((int) $item->getOrderTotal());
103
-
104
- $item->addItem($line_item);
105
-
106
- mailchimp_log('order_sync.error', "order {$item->getId()} does not have any line items, so we are using 'empty_line_item_placeholder' instead.");
107
- }
108
-
109
- mailchimp_debug('order_sync', "#{$item->getId()}", $item->toArray());
110
-
111
- try {
112
- // make the call
113
- $response = $this->mailchimp()->$call($this->store_id, $item, false);
114
- } catch (\Exception $e) {
115
- // if for whatever reason we get a product not found error, we need to iterate
116
- // through the order items, and use a "create mode only" on each product
117
- // then re-submit the order once they're in the database again.
118
- if (mailchimp_string_contains($e->getMessage(), 'product with the provided ID')) {
119
- $this->mailchimp()->handleProductsMissingFromAPI($item);
120
- // make the call again after the product updates
121
- $response = $this->mailchimp()->$call($this->store_id, $item, false);
122
- } else {
123
- throw $e;
124
- }
125
- }
126
-
127
- if (empty($response)) {
128
- mailchimp_error('order_submit.failure', "$call :: #{$item->getId()} :: email: {$item->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
129
- return $response;
130
- }
131
-
132
- mailchimp_log('order_submit.success', "$call :: #{$item->getId()} :: email: {$item->getCustomer()->getEmailAddress()}");
133
-
134
- $this->items[] = array('response' => $response, 'item' => $item);
135
-
136
- // update the list member if they've got double opt in enabled, and this is a new order.
137
- if ($type === 'create') {
138
- mailchimp_update_member_with_double_opt_in($item, ($should_auto_subscribe || $status));
139
- }
140
-
141
- return $response;
142
- } catch (MailChimp_WooCommerce_RateLimitError $e) {
143
- mailchimp_error('order_submit.error', mailchimp_error_trace($e, "$call :: {$item->getId()}"));
144
- throw $e;
145
- } catch (MailChimp_WooCommerce_ServerError $e) {
146
- mailchimp_error('order_submit.error', mailchimp_error_trace($e, "$call :: {$item->getId()}"));
147
- return false;
148
- } catch (MailChimp_WooCommerce_Error $e) {
149
- mailchimp_error('order_submit.error', mailchimp_error_trace($e, "$call :: {$item->getId()}"));
150
- return false;
151
- } catch (Exception $e) {
152
- mailchimp_error('order_submit.error', mailchimp_error_trace($e, "$call :: {$item->getId()}"));
153
- return false;
154
- }
155
- }
156
-
157
- mailchimp_debug('order_submit', 'no order found', $item);
158
-
159
- return false;
160
- }
161
-
162
  /**
163
  * After the resources have been loaded and pushed
164
  */
165
  protected function complete()
166
  {
167
- mailchimp_log('order_submit.completed', 'Done with the order sync.');
168
 
169
  // add a timestamp for the orders sync completion
170
  $this->setResourceCompleteTime();
171
-
172
- // this is the last thing we're doing so it's complete as of now.
173
- $this->flagStopSync();
174
  }
175
 
176
- /**
177
- * @param $email
178
- * @param $order_id
179
- * @return bool
180
- */
181
- protected function shouldSkipOrder($email, $order_id)
182
- {
183
- if (!is_email($email)) {
184
- mailchimp_log('validation.bad_email', "Order #{$order_id} has an invalid email address. Skipping!");
185
- return true;
186
- }
187
-
188
- // make sure we can submit this order to MailChimp or skip it.
189
- if (mailchimp_email_is_amazon($email)) {
190
- mailchimp_log('validation.amazon', "Order #{$order_id} was placed through Amazon. Skipping!");
191
- return true;
192
- }
193
-
194
- if (mailchimp_email_is_privacy_protected($email)) {
195
- mailchimp_log('validation.gdpr', "Order #{$order_id} is GDPR restricted. Skipping!");
196
- return true;
197
- }
198
-
199
- return false;
200
- }
201
  }
24
  return 'orders';
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  /**
28
  * After the resources have been loaded and pushed
29
  */
30
  protected function complete()
31
  {
32
+ mailchimp_log('order_sync.completed', 'Done with the order queueing.');
33
 
34
  // add a timestamp for the orders sync completion
35
  $this->setResourceCompleteTime();
 
 
 
36
  }
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
includes/processes/class-mailchimp-woocommerce-process-products.php CHANGED
@@ -31,72 +31,14 @@ class MailChimp_WooCommerce_Process_Products extends MailChimp_WooCommerce_Abstr
31
  return 'products';
32
  }
33
 
34
- /**
35
- * @param MailChimp_WooCommerce_Product $item
36
- * @return bool|mixed
37
- * @throws MailChimp_WooCommerce_RateLimitError
38
- */
39
- protected function iterate($item) {
40
-
41
- if ($item instanceof MailChimp_WooCommerce_Product) {
42
-
43
- mailchimp_debug('product_sync', "#{$item->getId()}", $item->toArray());
44
-
45
- try {
46
- // pull the product from Mailchimp first to see what method we need to call next.
47
- $mailchimp_product = $this->mailchimp()->getStoreProduct($this->store_id, $item->getId(), true);
48
- } catch (\Exception $e) {
49
- // if we're getting rate limited, we need to throw this error to re-queue things.
50
- if ($e instanceof MailChimp_WooCommerce_RateLimitError) {
51
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "GET product :: {$item->getId()}"));
52
- throw $e;
53
- }
54
- $mailchimp_product = false;
55
- }
56
-
57
- // depending on if it's existing or not - we change the method call
58
- $method = $mailchimp_product ? 'updateStoreProduct' : 'addStoreProduct';
59
-
60
- // need to run the delete option on this before submitting because the API does not support PATCH yet.
61
- try {
62
- // make the call
63
- $response = $this->mailchimp()->{$method}($this->store_id, $item, false);
64
- mailchimp_log('product_sync.success', "{$method} :: #{$response->getId()}");
65
- return $response;
66
- } catch (MailChimp_WooCommerce_RateLimitError $e) {
67
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
68
- throw $e;
69
- } catch (MailChimp_WooCommerce_ServerError $e) {
70
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
71
- } catch (MailChimp_WooCommerce_Error $e) {
72
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
73
- } catch (Exception $e) {
74
- mailchimp_error('product_sync.error', mailchimp_error_trace($e, "{$method} :: {$item->getId()}"));
75
- }
76
- }
77
-
78
- return false;
79
- }
80
-
81
  /**
82
  * Called after all the products have been iterated and processed into MailChimp
83
  */
84
  protected function complete()
85
  {
86
- mailchimp_log('product_sync.completed', 'Done with the product sync :: queuing up the orders next!');
87
 
88
  // add a timestamp for the product sync completion
89
  $this->setResourceCompleteTime();
90
-
91
- $prevent_order_sync = get_option('mailchimp-woocommerce-sync.orders.prevent', false);
92
-
93
- // only do this if we're not strictly syncing products ( which is the default ).
94
- if (!$prevent_order_sync) {
95
- // since the products are all good, let's sync up the orders now.
96
- mailchimp_handle_or_queue(new MailChimp_WooCommerce_Process_Orders());
97
- }
98
-
99
- // since we skipped the orders feed we can delete this option.
100
- delete_option('mailchimp-woocommerce-sync.orders.prevent');
101
  }
102
  }
31
  return 'products';
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  /**
35
  * Called after all the products have been iterated and processed into MailChimp
36
  */
37
  protected function complete()
38
  {
39
+ mailchimp_log('product_sync.completed', 'Done with the product queuing');
40
 
41
  // add a timestamp for the product sync completion
42
  $this->setResourceCompleteTime();
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
  }
includes/processes/class-mailchimp-woocommerce-single-coupon.php CHANGED
@@ -46,7 +46,7 @@ class MailChimp_WooCommerce_SingleCoupon extends Mailchimp_Woocommerce_Job
46
  }
47
 
48
  if (empty($this->id)) {
49
- mailchimp_error('promo_code.failure', "could not process coupon {$this->id}");
50
  return;
51
  }
52
 
@@ -59,15 +59,27 @@ class MailChimp_WooCommerce_SingleCoupon extends Mailchimp_Woocommerce_Job
59
  $api->addPromoRule($store_id, $code->getAttachedPromoRule(), true);
60
  $api->addPromoCodeForRule($store_id, $code->getAttachedPromoRule(), $code, true);
61
 
62
- mailchimp_log('promo_code.update', "updated promo code {$code->getCode()}");
63
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
64
  sleep(3);
65
  $promo_code = isset($code) ? "code {$code->getCode()}" : "id {$this->id}";
66
- mailchimp_error('promo_code.error', mailchimp_error_trace($e, "RateLimited :: #{$promo_code}"));
67
- $this->retry();
 
 
 
 
 
 
 
68
  } catch (\Exception $e) {
69
  $promo_code = isset($code) ? "code {$code->getCode()}" : "id {$this->id}";
70
- mailchimp_error('promo_code.error', mailchimp_error_trace($e, "error updating promo {$promo_code}"));
 
 
 
 
 
71
  }
72
  }
73
  }
46
  }
47
 
48
  if (empty($this->id)) {
49
+ mailchimp_error('promo_code_submit.failure', "could not process coupon {$this->id}");
50
  return;
51
  }
52
 
59
  $api->addPromoRule($store_id, $code->getAttachedPromoRule(), true);
60
  $api->addPromoCodeForRule($store_id, $code->getAttachedPromoRule(), $code, true);
61
 
62
+ mailchimp_log('promo_code_submit.success', "#{$this->id} :: code: {$code->getCode()}");
63
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
64
  sleep(3);
65
  $promo_code = isset($code) ? "code {$code->getCode()}" : "id {$this->id}";
66
+ mailchimp_error('promo_code_submit.error', mailchimp_error_trace($e, "RateLimited :: #{$promo_code}"));
67
+ $this->applyRateLimitedScenario();
68
+ throw $e;
69
+ } catch (MailChimp_WooCommerce_ServerError $e) {
70
+ mailchimp_error('promo_code_submit.error', mailchimp_error_trace($e, "error updating promo rule #{$this->id} :: {$code->getCode()}"));
71
+ throw $e;
72
+ } catch (MailChimp_WooCommerce_Error $e) {
73
+ mailchimp_error('promo_code_submit.error', mailchimp_error_trace($e, "error updating promo rule #{$this->id} :: {$code->getCode()}"));
74
+ throw $e;
75
  } catch (\Exception $e) {
76
  $promo_code = isset($code) ? "code {$code->getCode()}" : "id {$this->id}";
77
+ mailchimp_error('promo_code_submit.exception', mailchimp_error_trace($e, "error updating promo rule :: {$promo_code}"));
78
+ throw $e;
79
+ } catch (\Error $e) {
80
+ $promo_code = isset($code) ? "code {$code->getCode()}" : "id {$this->id}";
81
+ mailchimp_error('promo_code_submit.error', mailchimp_error_trace($e, "Error :: #{$promo_code}"));
82
+ throw $e;
83
  }
84
  }
85
  }
includes/processes/class-mailchimp-woocommerce-single-order.php CHANGED
@@ -14,8 +14,10 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
14
  public $cart_session_id;
15
  public $campaign_id;
16
  public $landing_site;
 
17
  public $is_update = false;
18
  public $is_admin_save = false;
 
19
  public $partially_refunded = false;
20
  protected $woo_order_number = false;
21
  protected $is_amazon_order = false;
@@ -28,12 +30,13 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
28
  * @param null $campaign_id
29
  * @param null $landing_site
30
  */
31
- public function __construct($id = null, $cart_session_id = null, $campaign_id = null, $landing_site = null)
32
  {
33
  if (!empty($id)) $this->id = $id;
34
  if (!empty($cart_session_id)) $this->cart_session_id = $cart_session_id;
35
  if (!empty($campaign_id)) $this->campaign_id = $campaign_id;
36
  if (!empty($landing_site)) $this->landing_site = $landing_site;
 
37
  }
38
 
39
  /**
@@ -47,6 +50,17 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
47
  return $this;
48
  }
49
 
 
 
 
 
 
 
 
 
 
 
 
50
  /**
51
  * @return bool
52
  */
@@ -70,16 +84,6 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
70
  return false;
71
  }
72
 
73
- // see if we need to prevent this order from being submitted.
74
- if ($this->shouldPreventSubmission()) {
75
- if ($this->is_amazon_order) {
76
- mailchimp_log('validation.amazon', "Order #{$woo_order_number} was placed through Amazon. Skipping!");
77
- } elseif ($this->is_privacy_restricted) {
78
- mailchimp_log('validation.gdpr', "Order #{$woo_order_number} is GDPR restricted. Skipping!");
79
- }
80
- return false;
81
- }
82
-
83
  $job = new MailChimp_WooCommerce_Transform_Orders();
84
 
85
  // set the campaign ID
@@ -126,7 +130,41 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
126
  mailchimp_log('system.debug', "order {$order->getId()} is in {$order->getOriginalWooStatus()} status, and is being skipped for now.");
127
  return false;
128
  }
 
 
 
 
 
 
 
 
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  // will be the same as the customer id. an md5'd hash of a lowercased email.
131
  $this->cart_session_id = $order->getCustomer()->getId();
132
 
@@ -155,13 +193,23 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
155
  mailchimp_log('validation.gdpr', "Order #{$woo_order_number} is GDPR restricted. Skipping!");
156
  return false;
157
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- // if the order is in failed or cancelled status - and it's brand new, we shouldn't submit it.
160
- // if the original woocommerce status is actually pending, we need to skip these on new orders because
161
- // it is probably happening due to 3rd party payment processing and it's still pending. These orders
162
- // don't always make it over because someone could be cancelling out of the payment there.
163
- if ($new_order && (in_array($order->getFinancialStatus(), array('failed', 'cancelled')) || $order->getOriginalWooStatus() === 'pending')) {
164
- return false;
165
  }
166
 
167
  // if the order is brand new, and we already have a paid status,
@@ -171,14 +219,12 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
171
  $order->confirmAndPay(true);
172
  }
173
 
174
- mailchimp_debug('order_submit', "#{$woo_order_number}", $order->toArray());
175
-
176
  // if we're overriding this we need to set it here.
177
  if ($this->partially_refunded) {
178
  $order->setFinancialStatus('partially_refunded');
179
  }
180
 
181
- $log = "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
182
 
183
  // only do this stuff on new orders
184
  if ($new_order) {
@@ -200,6 +246,32 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
200
  }
201
  }
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  try {
204
  // update or create
205
  $api_response = $api->$call($store_id, $order, false);
@@ -222,7 +294,7 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
222
  }
223
 
224
  if (empty($api_response)) {
225
- mailchimp_error('order_submit.failure', "$call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()} produced a blank response from MailChimp");
226
  return $api_response;
227
  }
228
 
@@ -230,16 +302,30 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
230
  $log .= " :: abandoned cart deleted [{$this->cart_session_id}]";
231
  }
232
 
 
 
 
233
  mailchimp_log('order_submit.success', $log);
234
 
235
- // if the customer has a flag to double opt in - we need to push this data over to MailChimp as pending
236
- mailchimp_update_member_with_double_opt_in($order, $order->getCustomer()->getOriginalSubscriberStatus());
 
 
 
 
237
 
238
  return $api_response;
239
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
240
  sleep(3);
241
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, "RateLimited :: #{$this->id}"));
242
- $this->retry();
 
 
 
 
 
 
 
243
  } catch (\Exception $e) {
244
  $message = strtolower($e->getMessage());
245
  mailchimp_error('order_submit.tracing_error', $e);
@@ -251,12 +337,12 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
251
  // this can happen when a customer changes their email.
252
  if (isset($order) && strpos($message, 'not be changed')) {
253
  try {
254
- mailchimp_log('order_submit.deleting_customer', "#{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}");
255
  // delete the customer before adding it again.
256
  $api->deleteCustomer($store_id, $order->getCustomer()->getId());
257
  // update or create
258
  $api_response = $api->$call($store_id, $order, false);
259
- $log = "Deleted Customer :: $call :: #{$order->getId()} :: email: {$order->getCustomer()->getEmailAddress()}";
260
  if (!empty($job->campaign_id)) {
261
  $log .= ' :: campaign id '.$job->campaign_id;
262
  }
@@ -270,8 +356,12 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
270
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, 'deleting-customer-re-add :: #'.$this->id));
271
  }
272
  }
 
 
 
 
273
  }
274
-
275
  return false;
276
  }
277
 
@@ -294,27 +384,29 @@ class MailChimp_WooCommerce_Single_Order extends Mailchimp_Woocommerce_Job
294
  }
295
 
296
  /**
 
 
297
  * @return bool
298
  */
299
- public function shouldPreventSubmission()
300
  {
301
- try {
302
- if (empty($this->id) || !($order_post = get_post($this->id))) {
303
- return false;
304
- }
305
- $woo = wc_get_order($order_post);
306
- $email = $woo->get_billing_email();
307
-
308
- // just skip these altogether because we can't submit any amazon orders anyway.
309
- $this->is_amazon_order = mailchimp_email_is_amazon($email);
310
 
311
- // see if this is a privacy restricted email address.
312
- $this->is_privacy_restricted = mailchimp_email_is_privacy_protected($email);
 
 
 
313
 
314
- return $this->is_amazon_order || $this->is_privacy_restricted;
315
- } catch (\Exception $e) {
316
- return false;
317
  }
 
 
318
  }
319
  }
320
 
14
  public $cart_session_id;
15
  public $campaign_id;
16
  public $landing_site;
17
+ public $user_language;
18
  public $is_update = false;
19
  public $is_admin_save = false;
20
+ public $is_full_sync = false;
21
  public $partially_refunded = false;
22
  protected $woo_order_number = false;
23
  protected $is_amazon_order = false;
30
  * @param null $campaign_id
31
  * @param null $landing_site
32
  */
33
+ public function __construct($id = null, $cart_session_id = null, $campaign_id = null, $landing_site = null, $user_language = null)
34
  {
35
  if (!empty($id)) $this->id = $id;
36
  if (!empty($cart_session_id)) $this->cart_session_id = $cart_session_id;
37
  if (!empty($campaign_id)) $this->campaign_id = $campaign_id;
38
  if (!empty($landing_site)) $this->landing_site = $landing_site;
39
+ if (!empty($user_language)) $this->user_language = $user_language;
40
  }
41
 
42
  /**
50
  return $this;
51
  }
52
 
53
+ /**
54
+ * @param null $id
55
+ * @return MailChimp_WooCommerce_Single_Order
56
+ */
57
+ public function set_full_sync($is_full_sync)
58
+ {
59
+ $this->is_full_sync = $is_full_sync;
60
+
61
+ return $this;
62
+ }
63
+
64
  /**
65
  * @return bool
66
  */
84
  return false;
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
87
  $job = new MailChimp_WooCommerce_Transform_Orders();
88
 
89
  // set the campaign ID
130
  mailchimp_log('system.debug', "order {$order->getId()} is in {$order->getOriginalWooStatus()} status, and is being skipped for now.");
131
  return false;
132
  }
133
+
134
+ // see if we need to prevent this order from being submitted.
135
+ $email = $order->getCustomer()->getEmailAddress();
136
+ // see if we have a bad email
137
+
138
+ if ($this->shouldSkipOrder($email, $order->getId())) {
139
+ return false;
140
+ }
141
 
142
+ if ($this->is_full_sync) {
143
+ // see if this store has the auto subscribe setting enabled on initial sync
144
+ $plugin_options = get_option('mailchimp-woocommerce');
145
+ $should_auto_subscribe = (bool) $plugin_options['mailchimp_auto_subscribe'];
146
+
147
+ // since we're syncing the customer for the first time, this is where we need to add the override
148
+ // for subscriber status. We don't get the checkbox until this plugin is actually installed and working!
149
+ if (!($status = $order->getCustomer()->getOptInStatus())) {
150
+ try {
151
+ $subscriber = $api->member(mailchimp_get_list_id(), $order->getCustomer()->getEmailAddress());
152
+ if ($subscriber['status'] != 'archived') {
153
+ $status = !in_array($subscriber['status'], array('unsubscribed', 'transactional'));
154
+ $order->getCustomer()->setOptInStatus($status);
155
+ }
156
+ } catch (\Exception $e) {
157
+ if ($e instanceof MailChimp_WooCommerce_RateLimitError) {
158
+ mailchimp_error('order_sync.error', mailchimp_error_trace($e, "GET subscriber :: {$order->getId()}"));
159
+ throw $e;
160
+ }
161
+ // if they are using double opt in, we need to pass this in as false here so it doesn't auto subscribe.
162
+ $status = mailchimp_list_has_double_optin() ? false : $should_auto_subscribe;
163
+ $order->getCustomer()->setOptInStatus($status);
164
+ }
165
+ }
166
+ }
167
+
168
  // will be the same as the customer id. an md5'd hash of a lowercased email.
169
  $this->cart_session_id = $order->getCustomer()->getId();
170
 
193
  mailchimp_log('validation.gdpr', "Order #{$woo_order_number} is GDPR restricted. Skipping!");
194
  return false;
195
  }
196
+
197
+ if ( $new_order) {
198
+ // if single sync and
199
+ // if the order is in failed or cancelled status - and it's brand new, we shouldn't submit it.
200
+ if (!$this->is_full_sync && in_array($order->getFinancialStatus(), array('failed', 'cancelled')) || $order->getOriginalWooStatus() === 'pending') {
201
+ mailchimp_log('order_sumbit', "#{$order->getId()} has a financial status of {$order->getFinancialStatus()} and was skipped.");
202
+ return false;
203
+ }
204
+ // if full sync and
205
+ // if the original woocommerce status is actually pending, we need to skip these on new orders because
206
+ // it is probably happening due to 3rd party payment processing and it's still pending. These orders
207
+ // don't always make it over because someone could be cancelling out of the payment there.
208
+ if ($this->is_full_sync && !in_array(strtolower($order->getFinancialStatus()), array('processing', 'completed', 'paid'))) {
209
+ mailchimp_log('order_sumbit', "#{$order->getId()} has a financial status of {$order->getFinancialStatus()} and was skipped.");
210
+ return false;
211
+ }
212
 
 
 
 
 
 
 
213
  }
214
 
215
  // if the order is brand new, and we already have a paid status,
219
  $order->confirmAndPay(true);
220
  }
221
 
 
 
222
  // if we're overriding this we need to set it here.
223
  if ($this->partially_refunded) {
224
  $order->setFinancialStatus('partially_refunded');
225
  }
226
 
227
+ $log = "$call :: #{$order->getId()} :: email: {$email}";
228
 
229
  // only do this stuff on new orders
230
  if ($new_order) {
246
  }
247
  }
248
 
249
+ if ($this->is_full_sync) {
250
+ $line_items = $order->items();
251
+
252
+ // if we don't have any line items, we need to create the mailchimp product
253
+ // with a price of 1.00 and we'll use the inventory quantity to adjust correctly.
254
+ if (empty($line_items) || !count($line_items)) {
255
+
256
+ // this will create an empty product placeholder, or return the pre populated version if already
257
+ // sent to Mailchimp.
258
+ $product = $api->createEmptyLineItemProductPlaceholder();
259
+
260
+ $line_item = new MailChimp_WooCommerce_LineItem();
261
+ $line_item->setId($product->getId());
262
+ $line_item->setPrice(1);
263
+ $line_item->setProductId($product->getId());
264
+ $line_item->setProductVariantId($product->getId());
265
+ $line_item->setQuantity((int) $order->getOrderTotal());
266
+
267
+ $order->addItem($line_item);
268
+
269
+ mailchimp_log('order_sumbit.error', "Order {$order->getId()} does not have any line items, so we are using 'empty_line_item_placeholder' instead.");
270
+ }
271
+ }
272
+
273
+ mailchimp_debug('order_submit', "#{$woo_order_number}", $order->toArray());
274
+
275
  try {
276
  // update or create
277
  $api_response = $api->$call($store_id, $order, false);
294
  }
295
 
296
  if (empty($api_response)) {
297
+ mailchimp_error('order_submit.failure', "$call :: #{$order->getId()} :: email: {$email} produced a blank response from MailChimp");
298
  return $api_response;
299
  }
300
 
302
  $log .= " :: abandoned cart deleted [{$this->cart_session_id}]";
303
  }
304
 
305
+ // Maybe sync subscriber to set correct member.language
306
+ mailchimp_member_language_update($email, $this->user_language, 'order');
307
+
308
  mailchimp_log('order_submit.success', $log);
309
 
310
+ if ($this->is_full_sync && $new_order) {
311
+ // if the customer has a flag to double opt in - we need to push this data over to MailChimp as pending
312
+ //TODO: RYAN: this is the only place getOriginalSubscriberStatus() is called, but the iterate method uses another way.
313
+ // mailchimp_update_member_with_double_opt_in($order, ($should_auto_subscribe || $status));
314
+ mailchimp_update_member_with_double_opt_in($order, ($should_auto_subscribe || $order->getCustomer()->getOriginalSubscriberStatus()));
315
+ }
316
 
317
  return $api_response;
318
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
319
  sleep(3);
320
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, "RateLimited :: #{$this->id}"));
321
+ $this->applyRateLimitedScenario();
322
+ throw $e;
323
+ } catch (MailChimp_WooCommerce_ServerError $e) {
324
+ mailchimp_error('order_submit.error', mailchimp_error_trace($e, "{$call} :: #{$this->id}"));
325
+ throw $e;
326
+ } catch (MailChimp_WooCommerce_Error $e) {
327
+ mailchimp_error('order_submit.error', mailchimp_error_trace($e, "{$call} :: #{$this->id}"));
328
+ throw $e;
329
  } catch (\Exception $e) {
330
  $message = strtolower($e->getMessage());
331
  mailchimp_error('order_submit.tracing_error', $e);
337
  // this can happen when a customer changes their email.
338
  if (isset($order) && strpos($message, 'not be changed')) {
339
  try {
340
+ mailchimp_log('order_submit.deleting_customer', "#{$order->getId()} :: email: {$email}");
341
  // delete the customer before adding it again.
342
  $api->deleteCustomer($store_id, $order->getCustomer()->getId());
343
  // update or create
344
  $api_response = $api->$call($store_id, $order, false);
345
+ $log = "Deleted Customer :: $call :: #{$order->getId()} :: email: {$email}";
346
  if (!empty($job->campaign_id)) {
347
  $log .= ' :: campaign id '.$job->campaign_id;
348
  }
356
  mailchimp_error('order_submit.error', mailchimp_error_trace($e, 'deleting-customer-re-add :: #'.$this->id));
357
  }
358
  }
359
+ throw $e;
360
+ } catch (MailChimp_WooCommerce_Error $e) {
361
+ mailchimp_error('order_submit.error', mailchimp_error_trace($e, "{$call} :: #{$this->id}"));
362
+ throw $e;
363
  }
364
+ mailchimp_debug('order_submit', 'no order found', $order);
365
  return false;
366
  }
367
 
384
  }
385
 
386
  /**
387
+ * @param $email
388
+ * @param $order_id
389
  * @return bool
390
  */
391
+ protected function shouldSkipOrder($email, $order_id)
392
  {
393
+ if (!is_email($email)) {
394
+ mailchimp_log('validation.bad_email', "Order #{$order_id} has an invalid email address. Skipping!");
395
+ return true;
396
+ }
 
 
 
 
 
397
 
398
+ // make sure we can submit this order to MailChimp or skip it.
399
+ if (mailchimp_email_is_amazon($email)) {
400
+ mailchimp_log('validation.amazon', "Order #{$order_id} was placed through Amazon. Skipping!");
401
+ return true;
402
+ }
403
 
404
+ if (mailchimp_email_is_privacy_protected($email)) {
405
+ mailchimp_log('validation.gdpr', "Order #{$order_id} is GDPR restricted. Skipping!");
406
+ return true;
407
  }
408
+
409
+ return false;
410
  }
411
  }
412
 
includes/processes/class-mailchimp-woocommerce-single-product.php CHANGED
@@ -175,13 +175,21 @@ class MailChimp_WooCommerce_Single_Product extends Mailchimp_Woocommerce_Job
175
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
176
  sleep(3);
177
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
178
- $this->retry();
 
179
  } catch (MailChimp_WooCommerce_ServerError $e) {
180
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
 
181
  } catch (MailChimp_WooCommerce_Error $e) {
182
  mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
 
183
  } catch (Exception $e) {
184
  mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
 
 
 
 
 
185
  }
186
 
187
  return false;
175
  } catch (MailChimp_WooCommerce_RateLimitError $e) {
176
  sleep(3);
177
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
178
+ $this->applyRateLimitedScenario();
179
+ throw $e;
180
  } catch (MailChimp_WooCommerce_ServerError $e) {
181
  mailchimp_error('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
182
+ throw $e;
183
  } catch (MailChimp_WooCommerce_Error $e) {
184
  mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
185
+ throw $e;
186
  } catch (Exception $e) {
187
  mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
188
+ throw $e;
189
+ }
190
+ catch (\Error $e) {
191
+ mailchimp_log('product_submit.error', mailchimp_error_trace($e, "{$method} :: #{$this->id}"));
192
+ throw $e;
193
  }
194
 
195
  return false;
includes/vendor/action-scheduler/.editorconfig DELETED
@@ -1,24 +0,0 @@
1
- # This file is for unifying the coding style for different editors and IDEs
2
- # editorconfig.org
3
-
4
- # WordPress Coding Standards
5
- # https://make.wordpress.org/core/handbook/coding-standards/
6
-
7
- root = true
8
-
9
- [*]
10
- charset = utf-8
11
- end_of_line = lf
12
- indent_size = 4
13
- tab_width = 4
14
- indent_style = tab
15
- insert_final_newline = true
16
- trim_trailing_whitespace = true
17
-
18
- [*.txt]
19
- trim_trailing_whitespace = false
20
-
21
- [*.{md,json,yml}]
22
- trim_trailing_whitespace = false
23
- indent_style = space
24
- indent_size = 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/.gitattributes DELETED
@@ -1,13 +0,0 @@
1
- docs export-ignore
2
- tests export-ignore
3
- codecov.yml export-ignore
4
- .github export-ignore
5
- .travis.yml export-ignore
6
- .gitattributes export-ignore
7
- .gitignore export-ignore
8
- composer.* export-ignore
9
- Gruntfile.js export-ignore
10
- package.json export-ignore
11
- package-lock.json export-ignore
12
- phpcs.xml export-ignore
13
- phpunit.* export-ignore
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- phpunit.xml
2
- vendor
3
- .idea
4
- node_modules
 
 
 
 
includes/vendor/action-scheduler/.travis.yml DELETED
@@ -1,45 +0,0 @@
1
- # Travis CI Configuration File
2
-
3
- # Tell Travis CI we're using PHP
4
- language: php
5
-
6
- # We nee to use Precise, not Trusty, to test against PHP 5.3, see https://github.com/travis-ci/travis-ci/issues/8219
7
- dist: precise
8
-
9
- # Versions of PHP to test against
10
- php:
11
- - "5.3"
12
- - "5.6"
13
- - "7.0"
14
- - "7.1"
15
- - "7.2"
16
- - "7.3"
17
-
18
- # Specify versions of WordPress to test against
19
- # WP_VERSION = WordPress version number (use "master" for SVN trunk)
20
- # WP_MULTISITE = whether to test multisite (use either "0" or "1")
21
- env:
22
- - WP_VERSION=5.3 WP_MULTISITE=0
23
- - WP_VERSION=5.2 WP_MULTISITE=0
24
- - WP_VERSION=5.1 WP_MULTISITE=0
25
- - WP_VERSION=5.3 WP_MULTISITE=1
26
- - WP_VERSION=5.2 WP_MULTISITE=1
27
- - WP_VERSION=5.1 WP_MULTISITE=1
28
-
29
- # WordPress 5.3 requires PHP 5.6. Exclude WP 5.3 + PHP 5.3
30
- jobs:
31
- exclude:
32
- - php: "5.3"
33
- env: WP_VERSION=5.3 WP_MULTISITE=0
34
- - php: "5.3"
35
- env: WP_VERSION=5.3 WP_MULTISITE=1
36
-
37
- # Grab the setup script and execute
38
- before_script:
39
- - source tests/travis/setup.sh $TRAVIS_PHP_VERSION
40
-
41
- script:
42
- - if [[ "$TRAVIS_PHP_VERSION" == "7.3" ]] && [[ "$WP_VERSION" == "5.3" ]] && [[ "$WP_MULTISITE" == "0" ]] && [[ "$TRAVIS_BRANCH" == "master" ]]; then phpunit --configuration tests/phpunit.xml.dist --coverage-clover clover.xml; else phpunit --configuration tests/phpunit.xml.dist; fi
43
-
44
- after_script:
45
- - bash <(curl -s https://codecov.io/bash)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/Gruntfile.js DELETED
@@ -1,57 +0,0 @@
1
- module.exports = function( grunt ) {
2
- 'use strict';
3
-
4
- grunt.initConfig({
5
- // Check textdomain errors.
6
- checktextdomain: {
7
- options:{
8
- text_domain: 'action-scheduler',
9
- keywords: [
10
- '__:1,2d',
11
- '_e:1,2d',
12
- '_x:1,2c,3d',
13
- 'esc_html__:1,2d',
14
- 'esc_html_e:1,2d',
15
- 'esc_html_x:1,2c,3d',
16
- 'esc_attr__:1,2d',
17
- 'esc_attr_e:1,2d',
18
- 'esc_attr_x:1,2c,3d',
19
- '_ex:1,2c,3d',
20
- '_n:1,2,4d',
21
- '_nx:1,2,4c,5d',
22
- '_n_noop:1,2,3d',
23
- '_nx_noop:1,2,3c,4d'
24
- ]
25
- },
26
- files: {
27
- src: [
28
- '**/*.php',
29
- '!node_modules/**',
30
- '!tests/**',
31
- '!vendor/**',
32
- '!tmp/**'
33
- ],
34
- expand: true
35
- }
36
- },
37
-
38
- // PHP Code Sniffer.
39
- phpcs: {
40
- options: {
41
- bin: 'vendor/bin/phpcs'
42
- },
43
- dist: {
44
- src: [
45
- '**/*.php', // Include all php files.
46
- '!deprecated/**',
47
- '!node_modules/**',
48
- '!vendor/**'
49
- ]
50
- }
51
- }
52
- });
53
-
54
- // Load NPM tasks to be used here.
55
- grunt.loadNpmTasks( 'grunt-phpcs' );
56
- grunt.loadNpmTasks( 'grunt-checktextdomain' );
57
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/action-scheduler.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: A robust scheduling library for use in WordPress plugins.
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/
8
- * Version: 3.1.1
9
  * License: GPLv3
10
  *
11
  * Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
@@ -25,28 +25,28 @@
25
  *
26
  */
27
 
28
- if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_1' ) ) {
29
 
30
  if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
31
  require_once( 'classes/ActionScheduler_Versions.php' );
32
  add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
33
  }
34
 
35
- add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_1', 0, 0 );
36
 
37
- function action_scheduler_register_3_dot_1_dot_1() {
38
  $versions = ActionScheduler_Versions::instance();
39
- $versions->register( '3.1.1', 'action_scheduler_initialize_3_dot_1_dot_1' );
40
  }
41
 
42
- function action_scheduler_initialize_3_dot_1_dot_1() {
43
  require_once( 'classes/abstracts/ActionScheduler.php' );
44
  ActionScheduler::init( __FILE__ );
45
  }
46
 
47
  // Support usage in themes - load this version if no plugin has loaded a version yet.
48
  if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) {
49
- action_scheduler_initialize_3_dot_1_dot_1();
50
  do_action( 'action_scheduler_pre_theme_init' );
51
  ActionScheduler_Versions::initialize_latest_version();
52
  }
5
  * Description: A robust scheduling library for use in WordPress plugins.
6
  * Author: Automattic
7
  * Author URI: https://automattic.com/
8
+ * Version: 3.1.4
9
  * License: GPLv3
10
  *
11
  * Copyright 2019 Automattic, Inc. (https://automattic.com/contact/)
25
  *
26
  */
27
 
28
+ if ( ! function_exists( 'action_scheduler_register_3_dot_1_dot_4' ) ) {
29
 
30
  if ( ! class_exists( 'ActionScheduler_Versions' ) ) {
31
  require_once( 'classes/ActionScheduler_Versions.php' );
32
  add_action( 'plugins_loaded', array( 'ActionScheduler_Versions', 'initialize_latest_version' ), 1, 0 );
33
  }
34
 
35
+ add_action( 'plugins_loaded', 'action_scheduler_register_3_dot_1_dot_4', 0, 0 );
36
 
37
+ function action_scheduler_register_3_dot_1_dot_4() {
38
  $versions = ActionScheduler_Versions::instance();
39
+ $versions->register( '3.1.4', 'action_scheduler_initialize_3_dot_1_dot_4' );
40
  }
41
 
42
+ function action_scheduler_initialize_3_dot_1_dot_4() {
43
  require_once( 'classes/abstracts/ActionScheduler.php' );
44
  ActionScheduler::init( __FILE__ );
45
  }
46
 
47
  // Support usage in themes - load this version if no plugin has loaded a version yet.
48
  if ( did_action( 'plugins_loaded' ) && ! class_exists( 'ActionScheduler' ) ) {
49
+ action_scheduler_initialize_3_dot_1_dot_4();
50
  do_action( 'action_scheduler_pre_theme_init' );
51
  ActionScheduler_Versions::initialize_latest_version();
52
  }
includes/vendor/action-scheduler/classes/ActionScheduler_AdminView.php CHANGED
@@ -10,6 +10,9 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
10
 
11
  private static $screen_id = 'tools_page_action-scheduler';
12
 
 
 
 
13
  /**
14
  * @return ActionScheduler_AdminView
15
  * @codeCoverageIgnore
@@ -82,18 +85,31 @@ class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated {
82
  * Triggers processing of any pending actions.
83
  */
84
  public function process_admin_ui() {
85
- $table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() );
86
- $table->process_actions();
87
  }
88
 
89
  /**
90
  * Renders the Admin UI
91
  */
92
  public function render_admin_ui() {
93
- $table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() );
94
  $table->display_page();
95
  }
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  /**
98
  * Provide more information about the screen and its data in the help tab.
99
  */
10
 
11
  private static $screen_id = 'tools_page_action-scheduler';
12
 
13
+ /** @var ActionScheduler_ListTable */
14
+ protected $list_table;
15
+
16
  /**
17
  * @return ActionScheduler_AdminView
18
  * @codeCoverageIgnore
85
  * Triggers processing of any pending actions.
86
  */
87
  public function process_admin_ui() {
88
+ $this->get_list_table();
 
89
  }
90
 
91
  /**
92
  * Renders the Admin UI
93
  */
94
  public function render_admin_ui() {
95
+ $table = $this->get_list_table();
96
  $table->display_page();
97
  }
98
 
99
+ /**
100
+ * Get the admin UI object and process any requested actions.
101
+ *
102
+ * @return ActionScheduler_ListTable
103
+ */
104
+ protected function get_list_table() {
105
+ if ( null === $this->list_table ) {
106
+ $this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() );
107
+ $this->list_table->process_actions();
108
+ }
109
+
110
+ return $this->list_table;
111
+ }
112
+
113
  /**
114
  * Provide more information about the screen and its data in the help tab.
115
  */
includes/vendor/action-scheduler/classes/ActionScheduler_ListTable.php CHANGED
@@ -318,10 +318,36 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
318
  * Renders admin notifications
319
  *
320
  * Notifications:
321
- * 1. When the maximum number of tasks are being executed simultaneously
322
- * 2. Notifications when a task is manually executed
 
323
  */
324
  public function display_admin_notices() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  if ( $this->runner->has_maximum_concurrent_batches() ) {
326
  $claim_count = $this->store->get_claim_count();
327
  $this->admin_notices[] = array(
@@ -473,6 +499,24 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
473
  $this->process_row_action( $action_id, 'run' );
474
  }
475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
476
  /**
477
  * Implements the logic behind processing an action once an action link is clicked on the list table.
478
  *
@@ -527,6 +571,9 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
527
  } catch ( Exception $e ) {
528
  continue;
529
  }
 
 
 
530
  $this->items[ $action_id ] = array(
531
  'ID' => $action_id,
532
  'hook' => $action->get_hook(),
318
  * Renders admin notifications
319
  *
320
  * Notifications:
321
+ * 1. When the maximum number of tasks are being executed simultaneously.
322
+ * 2. Notifications when a task is manually executed.
323
+ * 3. Tables are missing.
324
  */
325
  public function display_admin_notices() {
326
+ global $wpdb;
327
+
328
+ if ( ( is_a( $this->store, 'ActionScheduler_HybridStore' ) || is_a( $this->store, 'ActionScheduler_DBStore' ) ) && apply_filters( 'action_scheduler_enable_recreate_data_store', true ) ) {
329
+ $table_list = array(
330
+ 'actionscheduler_actions',
331
+ 'actionscheduler_logs',
332
+ 'actionscheduler_groups',
333
+ 'actionscheduler_claims',
334
+ );
335
+
336
+ $found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
337
+ foreach ( $table_list as $table_name ) {
338
+ if ( ! in_array( $wpdb->prefix . $table_name, $found_tables ) ) {
339
+ $this->admin_notices[] = array(
340
+ 'class' => 'error',
341
+ 'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).' , 'action-scheduler' ),
342
+ );
343
+ $this->recreate_tables();
344
+ parent::display_admin_notices();
345
+
346
+ return;
347
+ }
348
+ }
349
+ }
350
+
351
  if ( $this->runner->has_maximum_concurrent_batches() ) {
352
  $claim_count = $this->store->get_claim_count();
353
  $this->admin_notices[] = array(
499
  $this->process_row_action( $action_id, 'run' );
500
  }
501
 
502
+ /**
503
+ * Force the data store schema updates.
504
+ */
505
+ protected function recreate_tables() {
506
+ if ( is_a( $this->store, 'ActionScheduler_HybridStore' ) ) {
507
+ $store = $this->store;
508
+ } else {
509
+ $store = new ActionScheduler_HybridStore();
510
+ }
511
+ add_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10, 2 );
512
+
513
+ $store_schema = new ActionScheduler_StoreSchema();
514
+ $logger_schema = new ActionScheduler_LoggerSchema();
515
+ $store_schema->register_tables( true );
516
+ $logger_schema->register_tables( true );
517
+
518
+ remove_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10 );
519
+ }
520
  /**
521
  * Implements the logic behind processing an action once an action link is clicked on the list table.
522
  *
571
  } catch ( Exception $e ) {
572
  continue;
573
  }
574
+ if ( is_a( $action, 'ActionScheduler_NullAction' ) ) {
575
+ continue;
576
+ }
577
  $this->items[ $action_id ] = array(
578
  'ID' => $action_id,
579
  'hook' => $action->get_hook(),
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler.php CHANGED
@@ -137,31 +137,29 @@ abstract class ActionScheduler {
137
  */
138
  do_action( 'action_scheduler_pre_init' );
139
 
140
- require_once( self::plugin_path('functions.php') );
141
  ActionScheduler_DataController::init();
142
 
143
- $store = self::store();
144
- add_action( 'init', array( $store, 'init' ), 1, 0 );
145
-
146
- $logger = self::logger();
147
- add_action( 'init', array( $logger, 'init' ), 1, 0 );
148
-
149
- $runner = self::runner();
150
- add_action( 'init', array( $runner, 'init' ), 1, 0 );
151
-
152
  $admin_view = self::admin_view();
153
- add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init()
154
 
155
  // Ensure initialization on plugin activation.
156
- if ( did_action( 'init' ) ) {
 
 
 
 
 
 
157
  $store->init();
158
  $logger->init();
159
  $runner->init();
160
- $admin_view->init();
161
  }
162
 
163
  if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) {
164
- require_once( self::plugin_path('deprecated/functions.php') );
165
  }
166
 
167
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
137
  */
138
  do_action( 'action_scheduler_pre_init' );
139
 
140
+ require_once( self::plugin_path( 'functions.php' ) );
141
  ActionScheduler_DataController::init();
142
 
143
+ $store = self::store();
144
+ $logger = self::logger();
145
+ $runner = self::runner();
 
 
 
 
 
 
146
  $admin_view = self::admin_view();
 
147
 
148
  // Ensure initialization on plugin activation.
149
+ if ( ! did_action( 'init' ) ) {
150
+ add_action( 'init', array( $admin_view, 'init' ), 0, 0 ); // run before $store::init()
151
+ add_action( 'init', array( $store, 'init' ), 1, 0 );
152
+ add_action( 'init', array( $logger, 'init' ), 1, 0 );
153
+ add_action( 'init', array( $runner, 'init' ), 1, 0 );
154
+ } else {
155
+ $admin_view->init();
156
  $store->init();
157
  $logger->init();
158
  $runner->init();
 
159
  }
160
 
161
  if ( apply_filters( 'action_scheduler_load_deprecated_functions', true ) ) {
162
+ require_once( self::plugin_path( 'deprecated/functions.php' ) );
163
  }
164
 
165
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_ListTable.php CHANGED
@@ -140,7 +140,6 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
140
  global $wpdb;
141
  // Detect when a bulk action is being triggered.
142
  $action = $this->current_action();
143
-
144
  if ( ! $action ) {
145
  return;
146
  }
@@ -161,13 +160,14 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
161
  }
162
 
163
  /**
164
- * Default code for deleting entries. We trust ids_sql because it is
165
  * validated already by process_bulk_action()
166
  */
167
  protected function bulk_delete( array $ids, $ids_sql ) {
168
- global $wpdb;
169
-
170
- $wpdb->query( "DELETE FROM {$this->table_name} WHERE {$this->ID} IN $ids_sql" );
 
171
  }
172
 
173
  /**
@@ -642,7 +642,6 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
642
  */
643
  public function process_actions() {
644
  $this->process_bulk_action();
645
-
646
  $this->process_row_actions();
647
 
648
  if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
140
  global $wpdb;
141
  // Detect when a bulk action is being triggered.
142
  $action = $this->current_action();
 
143
  if ( ! $action ) {
144
  return;
145
  }
160
  }
161
 
162
  /**
163
+ * Default code for deleting entries.
164
  * validated already by process_bulk_action()
165
  */
166
  protected function bulk_delete( array $ids, $ids_sql ) {
167
+ $store = ActionScheduler::store();
168
+ foreach ( $ids as $action_id ) {
169
+ $store->delete( $action_id );
170
+ }
171
  }
172
 
173
  /**
642
  */
643
  public function process_actions() {
644
  $this->process_bulk_action();
 
645
  $this->process_row_actions();
646
 
647
  if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) {
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Abstract_Schema.php CHANGED
@@ -25,9 +25,11 @@ abstract class ActionScheduler_Abstract_Schema {
25
  /**
26
  * Register tables with WordPress, and create them if needed.
27
  *
 
 
28
  * @return void
29
  */
30
- public function register_tables() {
31
  global $wpdb;
32
 
33
  // make WP aware of our tables
@@ -38,7 +40,7 @@ abstract class ActionScheduler_Abstract_Schema {
38
  }
39
 
40
  // create the tables
41
- if ( $this->schema_update_required() ) {
42
  foreach ( $this->tables as $table ) {
43
  $this->update_table( $table );
44
  }
25
  /**
26
  * Register tables with WordPress, and create them if needed.
27
  *
28
+ * @param bool $force_update Optional. Default false. Use true to always run the schema update.
29
+ *
30
  * @return void
31
  */
32
+ public function register_tables( $force_update = false ) {
33
  global $wpdb;
34
 
35
  // make WP aware of our tables
40
  }
41
 
42
  // create the tables
43
+ if ( $this->schema_update_required() || $force_update ) {
44
  foreach ( $this->tables as $table ) {
45
  $this->update_table( $table );
46
  }
includes/vendor/action-scheduler/classes/abstracts/ActionScheduler_Logger.php CHANGED
@@ -130,7 +130,7 @@ abstract class ActionScheduler_Logger {
130
  } else {
131
  $message = __( 'action ignored', 'action-scheduler' );
132
  }
133
- $this->log( $action_id, __( 'action ignored', 'action-scheduler' ) );
134
  }
135
 
136
  /**
130
  } else {
131
  $message = __( 'action ignored', 'action-scheduler' );
132
  }
133
+ $this->log( $action_id, $message );
134
  }
135
 
136
  /**
includes/vendor/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php CHANGED
@@ -56,7 +56,8 @@ class ActionScheduler_DBStore extends ActionScheduler_Store {
56
  $data['extended_args'] = $args;
57
  }
58
 
59
- $wpdb->insert( $wpdb->actionscheduler_actions, $data );
 
60
  $action_id = $wpdb->insert_id;
61
 
62
  if ( is_wp_error( $action_id ) ) {
56
  $data['extended_args'] = $args;
57
  }
58
 
59
+ $table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
60
+ $wpdb->insert( $table_name, $data );
61
  $action_id = $wpdb->insert_id;
62
 
63
  if ( is_wp_error( $action_id ) ) {
includes/vendor/action-scheduler/codecov.yml DELETED
@@ -1,13 +0,0 @@
1
- codecov:
2
- branch: master
3
-
4
- coverage:
5
- ignore:
6
- - tests/.*
7
- - lib/.*
8
- status:
9
- project: false
10
- patch: false
11
- changes: false
12
-
13
- comment: false
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/composer.json DELETED
@@ -1,36 +0,0 @@
1
- {
2
- "name": "woocommerce/action-scheduler",
3
- "description": "Action Scheduler for WordPress and WooCommerce",
4
- "homepage": "https://actionscheduler.org/",
5
- "type": "wordpress-plugin",
6
- "license": "GPL-3.0-or-later",
7
- "prefer-stable": true,
8
- "minimum-stability": "dev",
9
- "require": {},
10
- "require-dev": {
11
- "phpunit/phpunit": "^5.6",
12
- "wp-cli/wp-cli": "~1.5.1",
13
- "woocommerce/woocommerce-sniffs": "0.0.8"
14
- },
15
- "scripts": {
16
- "test": [
17
- "phpunit"
18
- ],
19
- "phpcs": [
20
- "phpcs -s -p"
21
- ],
22
- "phpcs-pre-commit": [
23
- "phpcs -s -p -n"
24
- ],
25
- "phpcbf": [
26
- "phpcbf -p"
27
- ]
28
- },
29
- "extra": {
30
- "scripts-description": {
31
- "test": "Run unit tests",
32
- "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
33
- "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
34
- }
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/composer.lock DELETED
@@ -1,4878 +0,0 @@
1
- {
2
- "_readme": [
3
- "This file locks the dependencies of your project to a known state",
4
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
- "This file is @generated automatically"
6
- ],
7
- "content-hash": "fe700435a00b5cdde47170ab9811f5ae",
8
- "packages": [],
9
- "packages-dev": [
10
- {
11
- "name": "composer/ca-bundle",
12
- "version": "1.2.6",
13
- "source": {
14
- "type": "git",
15
- "url": "https://github.com/composer/ca-bundle.git",
16
- "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e"
17
- },
18
- "dist": {
19
- "type": "zip",
20
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/47fe531de31fca4a1b997f87308e7d7804348f7e",
21
- "reference": "47fe531de31fca4a1b997f87308e7d7804348f7e",
22
- "shasum": ""
23
- },
24
- "require": {
25
- "ext-openssl": "*",
26
- "ext-pcre": "*",
27
- "php": "^5.3.2 || ^7.0 || ^8.0"
28
- },
29
- "require-dev": {
30
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
31
- "psr/log": "^1.0",
32
- "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
33
- },
34
- "type": "library",
35
- "extra": {
36
- "branch-alias": {
37
- "dev-master": "1.x-dev"
38
- }
39
- },
40
- "autoload": {
41
- "psr-4": {
42
- "Composer\\CaBundle\\": "src"
43
- }
44
- },
45
- "notification-url": "https://packagist.org/downloads/",
46
- "license": [
47
- "MIT"
48
- ],
49
- "authors": [
50
- {
51
- "name": "Jordi Boggiano",
52
- "email": "j.boggiano@seld.be",
53
- "homepage": "http://seld.be"
54
- }
55
- ],
56
- "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
57
- "keywords": [
58
- "cabundle",
59
- "cacert",
60
- "certificate",
61
- "ssl",
62
- "tls"
63
- ],
64
- "time": "2020-01-13T10:02:55+00:00"
65
- },
66
- {
67
- "name": "composer/composer",
68
- "version": "1.9.3",
69
- "source": {
70
- "type": "git",
71
- "url": "https://github.com/composer/composer.git",
72
- "reference": "1291a16ce3f48bfdeca39d64fca4875098af4d7b"
73
- },
74
- "dist": {
75
- "type": "zip",
76
- "url": "https://api.github.com/repos/composer/composer/zipball/1291a16ce3f48bfdeca39d64fca4875098af4d7b",
77
- "reference": "1291a16ce3f48bfdeca39d64fca4875098af4d7b",
78
- "shasum": ""
79
- },
80
- "require": {
81
- "composer/ca-bundle": "^1.0",
82
- "composer/semver": "^1.0",
83
- "composer/spdx-licenses": "^1.2",
84
- "composer/xdebug-handler": "^1.1",
85
- "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0",
86
- "php": "^5.3.2 || ^7.0",
87
- "psr/log": "^1.0",
88
- "seld/jsonlint": "^1.4",
89
- "seld/phar-utils": "^1.0",
90
- "symfony/console": "^2.7 || ^3.0 || ^4.0",
91
- "symfony/filesystem": "^2.7 || ^3.0 || ^4.0",
92
- "symfony/finder": "^2.7 || ^3.0 || ^4.0",
93
- "symfony/process": "^2.7 || ^3.0 || ^4.0"
94
- },
95
- "conflict": {
96
- "symfony/console": "2.8.38"
97
- },
98
- "require-dev": {
99
- "phpunit/phpunit": "^4.8.35 || ^5.7",
100
- "phpunit/phpunit-mock-objects": "^2.3 || ^3.0"
101
- },
102
- "suggest": {
103
- "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
104
- "ext-zip": "Enabling the zip extension allows you to unzip archives",
105
- "ext-zlib": "Allow gzip compression of HTTP requests"
106
- },
107
- "bin": [
108
- "bin/composer"
109
- ],
110
- "type": "library",
111
- "extra": {
112
- "branch-alias": {
113
- "dev-master": "1.9-dev"
114
- }
115
- },
116
- "autoload": {
117
- "psr-4": {
118
- "Composer\\": "src/Composer"
119
- }
120
- },
121
- "notification-url": "https://packagist.org/downloads/",
122
- "license": [
123
- "MIT"
124
- ],
125
- "authors": [
126
- {
127
- "name": "Nils Adermann",
128
- "email": "naderman@naderman.de",
129
- "homepage": "http://www.naderman.de"
130
- },
131
- {
132
- "name": "Jordi Boggiano",
133
- "email": "j.boggiano@seld.be",
134
- "homepage": "http://seld.be"
135
- }
136
- ],
137
- "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
138
- "homepage": "https://getcomposer.org/",
139
- "keywords": [
140
- "autoload",
141
- "dependency",
142
- "package"
143
- ],
144
- "time": "2020-02-04T11:58:49+00:00"
145
- },
146
- {
147
- "name": "composer/semver",
148
- "version": "1.5.1",
149
- "source": {
150
- "type": "git",
151
- "url": "https://github.com/composer/semver.git",
152
- "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de"
153
- },
154
- "dist": {
155
- "type": "zip",
156
- "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
157
- "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
158
- "shasum": ""
159
- },
160
- "require": {
161
- "php": "^5.3.2 || ^7.0"
162
- },
163
- "require-dev": {
164
- "phpunit/phpunit": "^4.5 || ^5.0.5"
165
- },
166
- "type": "library",
167
- "extra": {
168
- "branch-alias": {
169
- "dev-master": "1.x-dev"
170
- }
171
- },
172
- "autoload": {
173
- "psr-4": {
174
- "Composer\\Semver\\": "src"
175
- }
176
- },
177
- "notification-url": "https://packagist.org/downloads/",
178
- "license": [
179
- "MIT"
180
- ],
181
- "authors": [
182
- {
183
- "name": "Nils Adermann",
184
- "email": "naderman@naderman.de",
185
- "homepage": "http://www.naderman.de"
186
- },
187
- {
188
- "name": "Jordi Boggiano",
189
- "email": "j.boggiano@seld.be",
190
- "homepage": "http://seld.be"
191
- },
192
- {
193
- "name": "Rob Bast",
194
- "email": "rob.bast@gmail.com",
195
- "homepage": "http://robbast.nl"
196
- }
197
- ],
198
- "description": "Semver library that offers utilities, version constraint parsing and validation.",
199
- "keywords": [
200
- "semantic",
201
- "semver",
202
- "validation",
203
- "versioning"
204
- ],
205
- "time": "2020-01-13T12:06:48+00:00"
206
- },
207
- {
208
- "name": "composer/spdx-licenses",
209
- "version": "1.5.3",
210
- "source": {
211
- "type": "git",
212
- "url": "https://github.com/composer/spdx-licenses.git",
213
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae"
214
- },
215
- "dist": {
216
- "type": "zip",
217
- "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/0c3e51e1880ca149682332770e25977c70cf9dae",
218
- "reference": "0c3e51e1880ca149682332770e25977c70cf9dae",
219
- "shasum": ""
220
- },
221
- "require": {
222
- "php": "^5.3.2 || ^7.0 || ^8.0"
223
- },
224
- "require-dev": {
225
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
226
- },
227
- "type": "library",
228
- "extra": {
229
- "branch-alias": {
230
- "dev-master": "1.x-dev"
231
- }
232
- },
233
- "autoload": {
234
- "psr-4": {
235
- "Composer\\Spdx\\": "src"
236
- }
237
- },
238
- "notification-url": "https://packagist.org/downloads/",
239
- "license": [
240
- "MIT"
241
- ],
242
- "authors": [
243
- {
244
- "name": "Nils Adermann",
245
- "email": "naderman@naderman.de",
246
- "homepage": "http://www.naderman.de"
247
- },
248
- {
249
- "name": "Jordi Boggiano",
250
- "email": "j.boggiano@seld.be",
251
- "homepage": "http://seld.be"
252
- },
253
- {
254
- "name": "Rob Bast",
255
- "email": "rob.bast@gmail.com",
256
- "homepage": "http://robbast.nl"
257
- }
258
- ],
259
- "description": "SPDX licenses list and validation library.",
260
- "keywords": [
261
- "license",
262
- "spdx",
263
- "validator"
264
- ],
265
- "time": "2020-02-14T07:44:31+00:00"
266
- },
267
- {
268
- "name": "composer/xdebug-handler",
269
- "version": "1.4.0",
270
- "source": {
271
- "type": "git",
272
- "url": "https://github.com/composer/xdebug-handler.git",
273
- "reference": "cbe23383749496fe0f373345208b79568e4bc248"
274
- },
275
- "dist": {
276
- "type": "zip",
277
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248",
278
- "reference": "cbe23383749496fe0f373345208b79568e4bc248",
279
- "shasum": ""
280
- },
281
- "require": {
282
- "php": "^5.3.2 || ^7.0 || ^8.0",
283
- "psr/log": "^1.0"
284
- },
285
- "require-dev": {
286
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
287
- },
288
- "type": "library",
289
- "autoload": {
290
- "psr-4": {
291
- "Composer\\XdebugHandler\\": "src"
292
- }
293
- },
294
- "notification-url": "https://packagist.org/downloads/",
295
- "license": [
296
- "MIT"
297
- ],
298
- "authors": [
299
- {
300
- "name": "John Stevenson",
301
- "email": "john-stevenson@blueyonder.co.uk"
302
- }
303
- ],
304
- "description": "Restarts a process without Xdebug.",
305
- "keywords": [
306
- "Xdebug",
307
- "performance"
308
- ],
309
- "time": "2019-11-06T16:40:04+00:00"
310
- },
311
- {
312
- "name": "dealerdirect/phpcodesniffer-composer-installer",
313
- "version": "v0.5.0",
314
- "source": {
315
- "type": "git",
316
- "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
317
- "reference": "e749410375ff6fb7a040a68878c656c2e610b132"
318
- },
319
- "dist": {
320
- "type": "zip",
321
- "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132",
322
- "reference": "e749410375ff6fb7a040a68878c656c2e610b132",
323
- "shasum": ""
324
- },
325
- "require": {
326
- "composer-plugin-api": "^1.0",
327
- "php": "^5.3|^7",
328
- "squizlabs/php_codesniffer": "^2|^3"
329
- },
330
- "require-dev": {
331
- "composer/composer": "*",
332
- "phpcompatibility/php-compatibility": "^9.0",
333
- "sensiolabs/security-checker": "^4.1.0"
334
- },
335
- "type": "composer-plugin",
336
- "extra": {
337
- "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
338
- },
339
- "autoload": {
340
- "psr-4": {
341
- "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
342
- }
343
- },
344
- "notification-url": "https://packagist.org/downloads/",
345
- "license": [
346
- "MIT"
347
- ],
348
- "authors": [
349
- {
350
- "name": "Franck Nijhof",
351
- "email": "franck.nijhof@dealerdirect.com",
352
- "homepage": "http://www.frenck.nl",
353
- "role": "Developer / IT Manager"
354
- }
355
- ],
356
- "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
357
- "homepage": "http://www.dealerdirect.com",
358
- "keywords": [
359
- "PHPCodeSniffer",
360
- "PHP_CodeSniffer",
361
- "code quality",
362
- "codesniffer",
363
- "composer",
364
- "installer",
365
- "phpcs",
366
- "plugin",
367
- "qa",
368
- "quality",
369
- "standard",
370
- "standards",
371
- "style guide",
372
- "stylecheck",
373
- "tests"
374
- ],
375
- "time": "2018-10-26T13:21:45+00:00"
376
- },
377
- {
378
- "name": "doctrine/instantiator",
379
- "version": "1.3.0",
380
- "source": {
381
- "type": "git",
382
- "url": "https://github.com/doctrine/instantiator.git",
383
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
384
- },
385
- "dist": {
386
- "type": "zip",
387
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
388
- "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
389
- "shasum": ""
390
- },
391
- "require": {
392
- "php": "^7.1"
393
- },
394
- "require-dev": {
395
- "doctrine/coding-standard": "^6.0",
396
- "ext-pdo": "*",
397
- "ext-phar": "*",
398
- "phpbench/phpbench": "^0.13",
399
- "phpstan/phpstan-phpunit": "^0.11",
400
- "phpstan/phpstan-shim": "^0.11",
401
- "phpunit/phpunit": "^7.0"
402
- },
403
- "type": "library",
404
- "extra": {
405
- "branch-alias": {
406
- "dev-master": "1.2.x-dev"
407
- }
408
- },
409
- "autoload": {
410
- "psr-4": {
411
- "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
412
- }
413
- },
414
- "notification-url": "https://packagist.org/downloads/",
415
- "license": [
416
- "MIT"
417
- ],
418
- "authors": [
419
- {
420
- "name": "Marco Pivetta",
421
- "email": "ocramius@gmail.com",
422
- "homepage": "http://ocramius.github.com/"
423
- }
424
- ],
425
- "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
426
- "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
427
- "keywords": [
428
- "constructor",
429
- "instantiate"
430
- ],
431
- "time": "2019-10-21T16:45:58+00:00"
432
- },
433
- {
434
- "name": "justinrainbow/json-schema",
435
- "version": "5.2.9",
436
- "source": {
437
- "type": "git",
438
- "url": "https://github.com/justinrainbow/json-schema.git",
439
- "reference": "44c6787311242a979fa15c704327c20e7221a0e4"
440
- },
441
- "dist": {
442
- "type": "zip",
443
- "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
444
- "reference": "44c6787311242a979fa15c704327c20e7221a0e4",
445
- "shasum": ""
446
- },
447
- "require": {
448
- "php": ">=5.3.3"
449
- },
450
- "require-dev": {
451
- "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
452
- "json-schema/json-schema-test-suite": "1.2.0",
453
- "phpunit/phpunit": "^4.8.35"
454
- },
455
- "bin": [
456
- "bin/validate-json"
457
- ],
458
- "type": "library",
459
- "extra": {
460
- "branch-alias": {
461
- "dev-master": "5.0.x-dev"
462
- }
463
- },
464
- "autoload": {
465
- "psr-4": {
466
- "JsonSchema\\": "src/JsonSchema/"
467
- }
468
- },
469
- "notification-url": "https://packagist.org/downloads/",
470
- "license": [
471
- "MIT"
472
- ],
473
- "authors": [
474
- {
475
- "name": "Bruno Prieto Reis",
476
- "email": "bruno.p.reis@gmail.com"
477
- },
478
- {
479
- "name": "Justin Rainbow",
480
- "email": "justin.rainbow@gmail.com"
481
- },
482
- {
483
- "name": "Igor Wiedler",
484
- "email": "igor@wiedler.ch"
485
- },
486
- {
487
- "name": "Robert Schönthal",
488
- "email": "seroscho@googlemail.com"
489
- }
490
- ],
491
- "description": "A library to validate a json schema.",
492
- "homepage": "https://github.com/justinrainbow/json-schema",
493
- "keywords": [
494
- "json",
495
- "schema"
496
- ],
497
- "time": "2019-09-25T14:49:45+00:00"
498
- },
499
- {
500
- "name": "mustache/mustache",
501
- "version": "v2.13.0",
502
- "source": {
503
- "type": "git",
504
- "url": "https://github.com/bobthecow/mustache.php.git",
505
- "reference": "e95c5a008c23d3151d59ea72484d4f72049ab7f4"
506
- },
507
- "dist": {
508
- "type": "zip",
509
- "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e95c5a008c23d3151d59ea72484d4f72049ab7f4",
510
- "reference": "e95c5a008c23d3151d59ea72484d4f72049ab7f4",
511
- "shasum": ""
512
- },
513
- "require": {
514
- "php": ">=5.2.4"
515
- },
516
- "require-dev": {
517
- "friendsofphp/php-cs-fixer": "~1.11",
518
- "phpunit/phpunit": "~3.7|~4.0|~5.0"
519
- },
520
- "type": "library",
521
- "autoload": {
522
- "psr-0": {
523
- "Mustache": "src/"
524
- }
525
- },
526
- "notification-url": "https://packagist.org/downloads/",
527
- "license": [
528
- "MIT"
529
- ],
530
- "authors": [
531
- {
532
- "name": "Justin Hileman",
533
- "email": "justin@justinhileman.info",
534
- "homepage": "http://justinhileman.com"
535
- }
536
- ],
537
- "description": "A Mustache implementation in PHP.",
538
- "homepage": "https://github.com/bobthecow/mustache.php",
539
- "keywords": [
540
- "mustache",
541
- "templating"
542
- ],
543
- "time": "2019-11-23T21:40:31+00:00"
544
- },
545
- {
546
- "name": "myclabs/deep-copy",
547
- "version": "1.9.5",
548
- "source": {
549
- "type": "git",
550
- "url": "https://github.com/myclabs/DeepCopy.git",
551
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef"
552
- },
553
- "dist": {
554
- "type": "zip",
555
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef",
556
- "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef",
557
- "shasum": ""
558
- },
559
- "require": {
560
- "php": "^7.1"
561
- },
562
- "replace": {
563
- "myclabs/deep-copy": "self.version"
564
- },
565
- "require-dev": {
566
- "doctrine/collections": "^1.0",
567
- "doctrine/common": "^2.6",
568
- "phpunit/phpunit": "^7.1"
569
- },
570
- "type": "library",
571
- "autoload": {
572
- "psr-4": {
573
- "DeepCopy\\": "src/DeepCopy/"
574
- },
575
- "files": [
576
- "src/DeepCopy/deep_copy.php"
577
- ]
578
- },
579
- "notification-url": "https://packagist.org/downloads/",
580
- "license": [
581
- "MIT"
582
- ],
583
- "description": "Create deep copies (clones) of your objects",
584
- "keywords": [
585
- "clone",
586
- "copy",
587
- "duplicate",
588
- "object",
589
- "object graph"
590
- ],
591
- "time": "2020-01-17T21:11:47+00:00"
592
- },
593
- {
594
- "name": "nb/oxymel",
595
- "version": "v0.1.0",
596
- "source": {
597
- "type": "git",
598
- "url": "https://github.com/nb/oxymel.git",
599
- "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c"
600
- },
601
- "dist": {
602
- "type": "zip",
603
- "url": "https://api.github.com/repos/nb/oxymel/zipball/cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c",
604
- "reference": "cbe626ef55d5c4cc9b5e6e3904b395861ea76e3c",
605
- "shasum": ""
606
- },
607
- "require": {
608
- "php": ">=5.2.4"
609
- },
610
- "type": "library",
611
- "autoload": {
612
- "psr-0": {
613
- "Oxymel": ""
614
- }
615
- },
616
- "notification-url": "https://packagist.org/downloads/",
617
- "license": [
618
- "MIT"
619
- ],
620
- "authors": [
621
- {
622
- "name": "Nikolay Bachiyski",
623
- "email": "nb@nikolay.bg",
624
- "homepage": "http://extrapolate.me/"
625
- }
626
- ],
627
- "description": "A sweet XML builder",
628
- "homepage": "https://github.com/nb/oxymel",
629
- "keywords": [
630
- "xml"
631
- ],
632
- "time": "2013-02-24T15:01:54+00:00"
633
- },
634
- {
635
- "name": "phpcompatibility/php-compatibility",
636
- "version": "9.3.5",
637
- "source": {
638
- "type": "git",
639
- "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
640
- "reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
641
- },
642
- "dist": {
643
- "type": "zip",
644
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
645
- "reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
646
- "shasum": ""
647
- },
648
- "require": {
649
- "php": ">=5.3",
650
- "squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
651
- },
652
- "conflict": {
653
- "squizlabs/php_codesniffer": "2.6.2"
654
- },
655
- "require-dev": {
656
- "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
657
- },
658
- "suggest": {
659
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
660
- "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
661
- },
662
- "type": "phpcodesniffer-standard",
663
- "notification-url": "https://packagist.org/downloads/",
664
- "license": [
665
- "LGPL-3.0-or-later"
666
- ],
667
- "authors": [
668
- {
669
- "name": "Wim Godden",
670
- "homepage": "https://github.com/wimg",
671
- "role": "lead"
672
- },
673
- {
674
- "name": "Juliette Reinders Folmer",
675
- "homepage": "https://github.com/jrfnl",
676
- "role": "lead"
677
- },
678
- {
679
- "name": "Contributors",
680
- "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
681
- }
682
- ],
683
- "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
684
- "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
685
- "keywords": [
686
- "compatibility",
687
- "phpcs",
688
- "standards"
689
- ],
690
- "time": "2019-12-27T09:44:58+00:00"
691
- },
692
- {
693
- "name": "phpcompatibility/phpcompatibility-paragonie",
694
- "version": "1.3.0",
695
- "source": {
696
- "type": "git",
697
- "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
698
- "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c"
699
- },
700
- "dist": {
701
- "type": "zip",
702
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c",
703
- "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c",
704
- "shasum": ""
705
- },
706
- "require": {
707
- "phpcompatibility/php-compatibility": "^9.0"
708
- },
709
- "require-dev": {
710
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5",
711
- "paragonie/random_compat": "dev-master",
712
- "paragonie/sodium_compat": "dev-master"
713
- },
714
- "suggest": {
715
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
716
- "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
717
- },
718
- "type": "phpcodesniffer-standard",
719
- "notification-url": "https://packagist.org/downloads/",
720
- "license": [
721
- "LGPL-3.0-or-later"
722
- ],
723
- "authors": [
724
- {
725
- "name": "Wim Godden",
726
- "role": "lead"
727
- },
728
- {
729
- "name": "Juliette Reinders Folmer",
730
- "role": "lead"
731
- }
732
- ],
733
- "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
734
- "homepage": "http://phpcompatibility.com/",
735
- "keywords": [
736
- "compatibility",
737
- "paragonie",
738
- "phpcs",
739
- "polyfill",
740
- "standards"
741
- ],
742
- "time": "2019-11-04T15:17:54+00:00"
743
- },
744
- {
745
- "name": "phpcompatibility/phpcompatibility-wp",
746
- "version": "2.1.0",
747
- "source": {
748
- "type": "git",
749
- "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
750
- "reference": "41bef18ba688af638b7310666db28e1ea9158b2f"
751
- },
752
- "dist": {
753
- "type": "zip",
754
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f",
755
- "reference": "41bef18ba688af638b7310666db28e1ea9158b2f",
756
- "shasum": ""
757
- },
758
- "require": {
759
- "phpcompatibility/php-compatibility": "^9.0",
760
- "phpcompatibility/phpcompatibility-paragonie": "^1.0"
761
- },
762
- "require-dev": {
763
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5"
764
- },
765
- "suggest": {
766
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
767
- "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
768
- },
769
- "type": "phpcodesniffer-standard",
770
- "notification-url": "https://packagist.org/downloads/",
771
- "license": [
772
- "LGPL-3.0-or-later"
773
- ],
774
- "authors": [
775
- {
776
- "name": "Wim Godden",
777
- "role": "lead"
778
- },
779
- {
780
- "name": "Juliette Reinders Folmer",
781
- "role": "lead"
782
- }
783
- ],
784
- "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
785
- "homepage": "http://phpcompatibility.com/",
786
- "keywords": [
787
- "compatibility",
788
- "phpcs",
789
- "standards",
790
- "wordpress"
791
- ],
792
- "time": "2019-08-28T14:22:28+00:00"
793
- },
794
- {
795
- "name": "phpdocumentor/reflection-common",
796
- "version": "2.0.0",
797
- "source": {
798
- "type": "git",
799
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
800
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
801
- },
802
- "dist": {
803
- "type": "zip",
804
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
805
- "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
806
- "shasum": ""
807
- },
808
- "require": {
809
- "php": ">=7.1"
810
- },
811
- "require-dev": {
812
- "phpunit/phpunit": "~6"
813
- },
814
- "type": "library",
815
- "extra": {
816
- "branch-alias": {
817
- "dev-master": "2.x-dev"
818
- }
819
- },
820
- "autoload": {
821
- "psr-4": {
822
- "phpDocumentor\\Reflection\\": "src/"
823
- }
824
- },
825
- "notification-url": "https://packagist.org/downloads/",
826
- "license": [
827
- "MIT"
828
- ],
829
- "authors": [
830
- {
831
- "name": "Jaap van Otterdijk",
832
- "email": "opensource@ijaap.nl"
833
- }
834
- ],
835
- "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
836
- "homepage": "http://www.phpdoc.org",
837
- "keywords": [
838
- "FQSEN",
839
- "phpDocumentor",
840
- "phpdoc",
841
- "reflection",
842
- "static analysis"
843
- ],
844
- "time": "2018-08-07T13:53:10+00:00"
845
- },
846
- {
847
- "name": "phpdocumentor/reflection-docblock",
848
- "version": "4.3.4",
849
- "source": {
850
- "type": "git",
851
- "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
852
- "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c"
853
- },
854
- "dist": {
855
- "type": "zip",
856
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c",
857
- "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c",
858
- "shasum": ""
859
- },
860
- "require": {
861
- "php": "^7.0",
862
- "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
863
- "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
864
- "webmozart/assert": "^1.0"
865
- },
866
- "require-dev": {
867
- "doctrine/instantiator": "^1.0.5",
868
- "mockery/mockery": "^1.0",
869
- "phpdocumentor/type-resolver": "0.4.*",
870
- "phpunit/phpunit": "^6.4"
871
- },
872
- "type": "library",
873
- "extra": {
874
- "branch-alias": {
875
- "dev-master": "4.x-dev"
876
- }
877
- },
878
- "autoload": {
879
- "psr-4": {
880
- "phpDocumentor\\Reflection\\": [
881
- "src/"
882
- ]
883
- }
884
- },
885
- "notification-url": "https://packagist.org/downloads/",
886
- "license": [
887
- "MIT"
888
- ],
889
- "authors": [
890
- {
891
- "name": "Mike van Riel",
892
- "email": "me@mikevanriel.com"
893
- }
894
- ],
895
- "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
896
- "time": "2019-12-28T18:55:12+00:00"
897
- },
898
- {
899
- "name": "phpdocumentor/type-resolver",
900
- "version": "1.0.1",
901
- "source": {
902
- "type": "git",
903
- "url": "https://github.com/phpDocumentor/TypeResolver.git",
904
- "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
905
- },
906
- "dist": {
907
- "type": "zip",
908
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
909
- "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
910
- "shasum": ""
911
- },
912
- "require": {
913
- "php": "^7.1",
914
- "phpdocumentor/reflection-common": "^2.0"
915
- },
916
- "require-dev": {
917
- "ext-tokenizer": "^7.1",
918
- "mockery/mockery": "~1",
919
- "phpunit/phpunit": "^7.0"
920
- },
921
- "type": "library",
922
- "extra": {
923
- "branch-alias": {
924
- "dev-master": "1.x-dev"
925
- }
926
- },
927
- "autoload": {
928
- "psr-4": {
929
- "phpDocumentor\\Reflection\\": "src"
930
- }
931
- },
932
- "notification-url": "https://packagist.org/downloads/",
933
- "license": [
934
- "MIT"
935
- ],
936
- "authors": [
937
- {
938
- "name": "Mike van Riel",
939
- "email": "me@mikevanriel.com"
940
- }
941
- ],
942
- "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
943
- "time": "2019-08-22T18:11:29+00:00"
944
- },
945
- {
946
- "name": "phpspec/prophecy",
947
- "version": "v1.10.2",
948
- "source": {
949
- "type": "git",
950
- "url": "https://github.com/phpspec/prophecy.git",
951
- "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9"
952
- },
953
- "dist": {
954
- "type": "zip",
955
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b4400efc9d206e83138e2bb97ed7f5b14b831cd9",
956
- "reference": "b4400efc9d206e83138e2bb97ed7f5b14b831cd9",
957
- "shasum": ""
958
- },
959
- "require": {
960
- "doctrine/instantiator": "^1.0.2",
961
- "php": "^5.3|^7.0",
962
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
963
- "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
964
- "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
965
- },
966
- "require-dev": {
967
- "phpspec/phpspec": "^2.5 || ^3.2",
968
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
969
- },
970
- "type": "library",
971
- "extra": {
972
- "branch-alias": {
973
- "dev-master": "1.10.x-dev"
974
- }
975
- },
976
- "autoload": {
977
- "psr-4": {
978
- "Prophecy\\": "src/Prophecy"
979
- }
980
- },
981
- "notification-url": "https://packagist.org/downloads/",
982
- "license": [
983
- "MIT"
984
- ],
985
- "authors": [
986
- {
987
- "name": "Konstantin Kudryashov",
988
- "email": "ever.zet@gmail.com",
989
- "homepage": "http://everzet.com"
990
- },
991
- {
992
- "name": "Marcello Duarte",
993
- "email": "marcello.duarte@gmail.com"
994
- }
995
- ],
996
- "description": "Highly opinionated mocking framework for PHP 5.3+",
997
- "homepage": "https://github.com/phpspec/prophecy",
998
- "keywords": [
999
- "Double",
1000
- "Dummy",
1001
- "fake",
1002
- "mock",
1003
- "spy",
1004
- "stub"
1005
- ],
1006
- "time": "2020-01-20T15:57:02+00:00"
1007
- },
1008
- {
1009
- "name": "phpunit/php-code-coverage",
1010
- "version": "4.0.8",
1011
- "source": {
1012
- "type": "git",
1013
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
1014
- "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
1015
- },
1016
- "dist": {
1017
- "type": "zip",
1018
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
1019
- "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
1020
- "shasum": ""
1021
- },
1022
- "require": {
1023
- "ext-dom": "*",
1024
- "ext-xmlwriter": "*",
1025
- "php": "^5.6 || ^7.0",
1026
- "phpunit/php-file-iterator": "^1.3",
1027
- "phpunit/php-text-template": "^1.2",
1028
- "phpunit/php-token-stream": "^1.4.2 || ^2.0",
1029
- "sebastian/code-unit-reverse-lookup": "^1.0",
1030
- "sebastian/environment": "^1.3.2 || ^2.0",
1031
- "sebastian/version": "^1.0 || ^2.0"
1032
- },
1033
- "require-dev": {
1034
- "ext-xdebug": "^2.1.4",
1035
- "phpunit/phpunit": "^5.7"
1036
- },
1037
- "suggest": {
1038
- "ext-xdebug": "^2.5.1"
1039
- },
1040
- "type": "library",
1041
- "extra": {
1042
- "branch-alias": {
1043
- "dev-master": "4.0.x-dev"
1044
- }
1045
- },
1046
- "autoload": {
1047
- "classmap": [
1048
- "src/"
1049
- ]
1050
- },
1051
- "notification-url": "https://packagist.org/downloads/",
1052
- "license": [
1053
- "BSD-3-Clause"
1054
- ],
1055
- "authors": [
1056
- {
1057
- "name": "Sebastian Bergmann",
1058
- "email": "sb@sebastian-bergmann.de",
1059
- "role": "lead"
1060
- }
1061
- ],
1062
- "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
1063
- "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
1064
- "keywords": [
1065
- "coverage",
1066
- "testing",
1067
- "xunit"
1068
- ],
1069
- "time": "2017-04-02T07:44:40+00:00"
1070
- },
1071
- {
1072
- "name": "phpunit/php-file-iterator",
1073
- "version": "1.4.5",
1074
- "source": {
1075
- "type": "git",
1076
- "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
1077
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
1078
- },
1079
- "dist": {
1080
- "type": "zip",
1081
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
1082
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
1083
- "shasum": ""
1084
- },
1085
- "require": {
1086
- "php": ">=5.3.3"
1087
- },
1088
- "type": "library",
1089
- "extra": {
1090
- "branch-alias": {
1091
- "dev-master": "1.4.x-dev"
1092
- }
1093
- },
1094
- "autoload": {
1095
- "classmap": [
1096
- "src/"
1097
- ]
1098
- },
1099
- "notification-url": "https://packagist.org/downloads/",
1100
- "license": [
1101
- "BSD-3-Clause"
1102
- ],
1103
- "authors": [
1104
- {
1105
- "name": "Sebastian Bergmann",
1106
- "email": "sb@sebastian-bergmann.de",
1107
- "role": "lead"
1108
- }
1109
- ],
1110
- "description": "FilterIterator implementation that filters files based on a list of suffixes.",
1111
- "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
1112
- "keywords": [
1113
- "filesystem",
1114
- "iterator"
1115
- ],
1116
- "time": "2017-11-27T13:52:08+00:00"
1117
- },
1118
- {
1119
- "name": "phpunit/php-text-template",
1120
- "version": "1.2.1",
1121
- "source": {
1122
- "type": "git",
1123
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
1124
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
1125
- },
1126
- "dist": {
1127
- "type": "zip",
1128
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1129
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
1130
- "shasum": ""
1131
- },
1132
- "require": {
1133
- "php": ">=5.3.3"
1134
- },
1135
- "type": "library",
1136
- "autoload": {
1137
- "classmap": [
1138
- "src/"
1139
- ]
1140
- },
1141
- "notification-url": "https://packagist.org/downloads/",
1142
- "license": [
1143
- "BSD-3-Clause"
1144
- ],
1145
- "authors": [
1146
- {
1147
- "name": "Sebastian Bergmann",
1148
- "email": "sebastian@phpunit.de",
1149
- "role": "lead"
1150
- }
1151
- ],
1152
- "description": "Simple template engine.",
1153
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
1154
- "keywords": [
1155
- "template"
1156
- ],
1157
- "time": "2015-06-21T13:50:34+00:00"
1158
- },
1159
- {
1160
- "name": "phpunit/php-timer",
1161
- "version": "1.0.9",
1162
- "source": {
1163
- "type": "git",
1164
- "url": "https://github.com/sebastianbergmann/php-timer.git",
1165
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
1166
- },
1167
- "dist": {
1168
- "type": "zip",
1169
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1170
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
1171
- "shasum": ""
1172
- },
1173
- "require": {
1174
- "php": "^5.3.3 || ^7.0"
1175
- },
1176
- "require-dev": {
1177
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1178
- },
1179
- "type": "library",
1180
- "extra": {
1181
- "branch-alias": {
1182
- "dev-master": "1.0-dev"
1183
- }
1184
- },
1185
- "autoload": {
1186
- "classmap": [
1187
- "src/"
1188
- ]
1189
- },
1190
- "notification-url": "https://packagist.org/downloads/",
1191
- "license": [
1192
- "BSD-3-Clause"
1193
- ],
1194
- "authors": [
1195
- {
1196
- "name": "Sebastian Bergmann",
1197
- "email": "sb@sebastian-bergmann.de",
1198
- "role": "lead"
1199
- }
1200
- ],
1201
- "description": "Utility class for timing",
1202
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
1203
- "keywords": [
1204
- "timer"
1205
- ],
1206
- "time": "2017-02-26T11:10:40+00:00"
1207
- },
1208
- {
1209
- "name": "phpunit/php-token-stream",
1210
- "version": "2.0.2",
1211
- "source": {
1212
- "type": "git",
1213
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
1214
- "reference": "791198a2c6254db10131eecfe8c06670700904db"
1215
- },
1216
- "dist": {
1217
- "type": "zip",
1218
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
1219
- "reference": "791198a2c6254db10131eecfe8c06670700904db",
1220
- "shasum": ""
1221
- },
1222
- "require": {
1223
- "ext-tokenizer": "*",
1224
- "php": "^7.0"
1225
- },
1226
- "require-dev": {
1227
- "phpunit/phpunit": "^6.2.4"
1228
- },
1229
- "type": "library",
1230
- "extra": {
1231
- "branch-alias": {
1232
- "dev-master": "2.0-dev"
1233
- }
1234
- },
1235
- "autoload": {
1236
- "classmap": [
1237
- "src/"
1238
- ]
1239
- },
1240
- "notification-url": "https://packagist.org/downloads/",
1241
- "license": [
1242
- "BSD-3-Clause"
1243
- ],
1244
- "authors": [
1245
- {
1246
- "name": "Sebastian Bergmann",
1247
- "email": "sebastian@phpunit.de"
1248
- }
1249
- ],
1250
- "description": "Wrapper around PHP's tokenizer extension.",
1251
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
1252
- "keywords": [
1253
- "tokenizer"
1254
- ],
1255
- "time": "2017-11-27T05:48:46+00:00"
1256
- },
1257
- {
1258
- "name": "phpunit/phpunit",
1259
- "version": "5.7.27",
1260
- "source": {
1261
- "type": "git",
1262
- "url": "https://github.com/sebastianbergmann/phpunit.git",
1263
- "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c"
1264
- },
1265
- "dist": {
1266
- "type": "zip",
1267
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
1268
- "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c",
1269
- "shasum": ""
1270
- },
1271
- "require": {
1272
- "ext-dom": "*",
1273
- "ext-json": "*",
1274
- "ext-libxml": "*",
1275
- "ext-mbstring": "*",
1276
- "ext-xml": "*",
1277
- "myclabs/deep-copy": "~1.3",
1278
- "php": "^5.6 || ^7.0",
1279
- "phpspec/prophecy": "^1.6.2",
1280
- "phpunit/php-code-coverage": "^4.0.4",
1281
- "phpunit/php-file-iterator": "~1.4",
1282
- "phpunit/php-text-template": "~1.2",
1283
- "phpunit/php-timer": "^1.0.6",
1284
- "phpunit/phpunit-mock-objects": "^3.2",
1285
- "sebastian/comparator": "^1.2.4",
1286
- "sebastian/diff": "^1.4.3",
1287
- "sebastian/environment": "^1.3.4 || ^2.0",
1288
- "sebastian/exporter": "~2.0",
1289
- "sebastian/global-state": "^1.1",
1290
- "sebastian/object-enumerator": "~2.0",
1291
- "sebastian/resource-operations": "~1.0",
1292
- "sebastian/version": "^1.0.6|^2.0.1",
1293
- "symfony/yaml": "~2.1|~3.0|~4.0"
1294
- },
1295
- "conflict": {
1296
- "phpdocumentor/reflection-docblock": "3.0.2"
1297
- },
1298
- "require-dev": {
1299
- "ext-pdo": "*"
1300
- },
1301
- "suggest": {
1302
- "ext-xdebug": "*",
1303
- "phpunit/php-invoker": "~1.1"
1304
- },
1305
- "bin": [
1306
- "phpunit"
1307
- ],
1308
- "type": "library",
1309
- "extra": {
1310
- "branch-alias": {
1311
- "dev-master": "5.7.x-dev"
1312
- }
1313
- },
1314
- "autoload": {
1315
- "classmap": [
1316
- "src/"
1317
- ]
1318
- },
1319
- "notification-url": "https://packagist.org/downloads/",
1320
- "license": [
1321
- "BSD-3-Clause"
1322
- ],
1323
- "authors": [
1324
- {
1325
- "name": "Sebastian Bergmann",
1326
- "email": "sebastian@phpunit.de",
1327
- "role": "lead"
1328
- }
1329
- ],
1330
- "description": "The PHP Unit Testing framework.",
1331
- "homepage": "https://phpunit.de/",
1332
- "keywords": [
1333
- "phpunit",
1334
- "testing",
1335
- "xunit"
1336
- ],
1337
- "time": "2018-02-01T05:50:59+00:00"
1338
- },
1339
- {
1340
- "name": "phpunit/phpunit-mock-objects",
1341
- "version": "3.4.4",
1342
- "source": {
1343
- "type": "git",
1344
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
1345
- "reference": "a23b761686d50a560cc56233b9ecf49597cc9118"
1346
- },
1347
- "dist": {
1348
- "type": "zip",
1349
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118",
1350
- "reference": "a23b761686d50a560cc56233b9ecf49597cc9118",
1351
- "shasum": ""
1352
- },
1353
- "require": {
1354
- "doctrine/instantiator": "^1.0.2",
1355
- "php": "^5.6 || ^7.0",
1356
- "phpunit/php-text-template": "^1.2",
1357
- "sebastian/exporter": "^1.2 || ^2.0"
1358
- },
1359
- "conflict": {
1360
- "phpunit/phpunit": "<5.4.0"
1361
- },
1362
- "require-dev": {
1363
- "phpunit/phpunit": "^5.4"
1364
- },
1365
- "suggest": {
1366
- "ext-soap": "*"
1367
- },
1368
- "type": "library",
1369
- "extra": {
1370
- "branch-alias": {
1371
- "dev-master": "3.2.x-dev"
1372
- }
1373
- },
1374
- "autoload": {
1375
- "classmap": [
1376
- "src/"
1377
- ]
1378
- },
1379
- "notification-url": "https://packagist.org/downloads/",
1380
- "license": [
1381
- "BSD-3-Clause"
1382
- ],
1383
- "authors": [
1384
- {
1385
- "name": "Sebastian Bergmann",
1386
- "email": "sb@sebastian-bergmann.de",
1387
- "role": "lead"
1388
- }
1389
- ],
1390
- "description": "Mock Object library for PHPUnit",
1391
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
1392
- "keywords": [
1393
- "mock",
1394
- "xunit"
1395
- ],
1396
- "abandoned": true,
1397
- "time": "2017-06-30T09:13:00+00:00"
1398
- },
1399
- {
1400
- "name": "psr/container",
1401
- "version": "1.0.0",
1402
- "source": {
1403
- "type": "git",
1404
- "url": "https://github.com/php-fig/container.git",
1405
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
1406
- },
1407
- "dist": {
1408
- "type": "zip",
1409
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
1410
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
1411
- "shasum": ""
1412
- },
1413
- "require": {
1414
- "php": ">=5.3.0"
1415
- },
1416
- "type": "library",
1417
- "extra": {
1418
- "branch-alias": {
1419
- "dev-master": "1.0.x-dev"
1420
- }
1421
- },
1422
- "autoload": {
1423
- "psr-4": {
1424
- "Psr\\Container\\": "src/"
1425
- }
1426
- },
1427
- "notification-url": "https://packagist.org/downloads/",
1428
- "license": [
1429
- "MIT"
1430
- ],
1431
- "authors": [
1432
- {
1433
- "name": "PHP-FIG",
1434
- "homepage": "http://www.php-fig.org/"
1435
- }
1436
- ],
1437
- "description": "Common Container Interface (PHP FIG PSR-11)",
1438
- "homepage": "https://github.com/php-fig/container",
1439
- "keywords": [
1440
- "PSR-11",
1441
- "container",
1442
- "container-interface",
1443
- "container-interop",
1444
- "psr"
1445
- ],
1446
- "time": "2017-02-14T16:28:37+00:00"
1447
- },
1448
- {
1449
- "name": "psr/log",
1450
- "version": "1.1.2",
1451
- "source": {
1452
- "type": "git",
1453
- "url": "https://github.com/php-fig/log.git",
1454
- "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
1455
- },
1456
- "dist": {
1457
- "type": "zip",
1458
- "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
1459
- "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
1460
- "shasum": ""
1461
- },
1462
- "require": {
1463
- "php": ">=5.3.0"
1464
- },
1465
- "type": "library",
1466
- "extra": {
1467
- "branch-alias": {
1468
- "dev-master": "1.1.x-dev"
1469
- }
1470
- },
1471
- "autoload": {
1472
- "psr-4": {
1473
- "Psr\\Log\\": "Psr/Log/"
1474
- }
1475
- },
1476
- "notification-url": "https://packagist.org/downloads/",
1477
- "license": [
1478
- "MIT"
1479
- ],
1480
- "authors": [
1481
- {
1482
- "name": "PHP-FIG",
1483
- "homepage": "http://www.php-fig.org/"
1484
- }
1485
- ],
1486
- "description": "Common interface for logging libraries",
1487
- "homepage": "https://github.com/php-fig/log",
1488
- "keywords": [
1489
- "log",
1490
- "psr",
1491
- "psr-3"
1492
- ],
1493
- "time": "2019-11-01T11:05:21+00:00"
1494
- },
1495
- {
1496
- "name": "ramsey/array_column",
1497
- "version": "1.1.3",
1498
- "source": {
1499
- "type": "git",
1500
- "url": "https://github.com/ramsey/array_column.git",
1501
- "reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db"
1502
- },
1503
- "dist": {
1504
- "type": "zip",
1505
- "url": "https://api.github.com/repos/ramsey/array_column/zipball/f8e52eb28e67eb50e613b451dd916abcf783c1db",
1506
- "reference": "f8e52eb28e67eb50e613b451dd916abcf783c1db",
1507
- "shasum": ""
1508
- },
1509
- "require-dev": {
1510
- "jakub-onderka/php-parallel-lint": "0.8.*",
1511
- "phpunit/phpunit": "~4.5",
1512
- "satooshi/php-coveralls": "0.6.*",
1513
- "squizlabs/php_codesniffer": "~2.2"
1514
- },
1515
- "type": "library",
1516
- "autoload": {
1517
- "files": [
1518
- "src/array_column.php"
1519
- ]
1520
- },
1521
- "notification-url": "https://packagist.org/downloads/",
1522
- "license": [
1523
- "MIT"
1524
- ],
1525
- "authors": [
1526
- {
1527
- "name": "Ben Ramsey",
1528
- "homepage": "http://benramsey.com"
1529
- }
1530
- ],
1531
- "description": "Provides functionality for array_column() to projects using PHP earlier than version 5.5.",
1532
- "homepage": "https://github.com/ramsey/array_column",
1533
- "keywords": [
1534
- "array",
1535
- "array_column",
1536
- "column"
1537
- ],
1538
- "abandoned": true,
1539
- "time": "2015-03-20T22:07:39+00:00"
1540
- },
1541
- {
1542
- "name": "rmccue/requests",
1543
- "version": "v1.7.0",
1544
- "source": {
1545
- "type": "git",
1546
- "url": "https://github.com/rmccue/Requests.git",
1547
- "reference": "87932f52ffad70504d93f04f15690cf16a089546"
1548
- },
1549
- "dist": {
1550
- "type": "zip",
1551
- "url": "https://api.github.com/repos/rmccue/Requests/zipball/87932f52ffad70504d93f04f15690cf16a089546",
1552
- "reference": "87932f52ffad70504d93f04f15690cf16a089546",
1553
- "shasum": ""
1554
- },
1555
- "require": {
1556
- "php": ">=5.2"
1557
- },
1558
- "require-dev": {
1559
- "requests/test-server": "dev-master"
1560
- },
1561
- "type": "library",
1562
- "autoload": {
1563
- "psr-0": {
1564
- "Requests": "library/"
1565
- }
1566
- },
1567
- "notification-url": "https://packagist.org/downloads/",
1568
- "license": [
1569
- "ISC"
1570
- ],
1571
- "authors": [
1572
- {
1573
- "name": "Ryan McCue",
1574
- "homepage": "http://ryanmccue.info"
1575
- }
1576
- ],
1577
- "description": "A HTTP library written in PHP, for human beings.",
1578
- "homepage": "http://github.com/rmccue/Requests",
1579
- "keywords": [
1580
- "curl",
1581
- "fsockopen",
1582
- "http",
1583
- "idna",
1584
- "ipv6",
1585
- "iri",
1586
- "sockets"
1587
- ],
1588
- "time": "2016-10-13T00:11:37+00:00"
1589
- },
1590
- {
1591
- "name": "sebastian/code-unit-reverse-lookup",
1592
- "version": "1.0.1",
1593
- "source": {
1594
- "type": "git",
1595
- "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
1596
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
1597
- },
1598
- "dist": {
1599
- "type": "zip",
1600
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1601
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
1602
- "shasum": ""
1603
- },
1604
- "require": {
1605
- "php": "^5.6 || ^7.0"
1606
- },
1607
- "require-dev": {
1608
- "phpunit/phpunit": "^5.7 || ^6.0"
1609
- },
1610
- "type": "library",
1611
- "extra": {
1612
- "branch-alias": {
1613
- "dev-master": "1.0.x-dev"
1614
- }
1615
- },
1616
- "autoload": {
1617
- "classmap": [
1618
- "src/"
1619
- ]
1620
- },
1621
- "notification-url": "https://packagist.org/downloads/",
1622
- "license": [
1623
- "BSD-3-Clause"
1624
- ],
1625
- "authors": [
1626
- {
1627
- "name": "Sebastian Bergmann",
1628
- "email": "sebastian@phpunit.de"
1629
- }
1630
- ],
1631
- "description": "Looks up which function or method a line of code belongs to",
1632
- "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
1633
- "time": "2017-03-04T06:30:41+00:00"
1634
- },
1635
- {
1636
- "name": "sebastian/comparator",
1637
- "version": "1.2.4",
1638
- "source": {
1639
- "type": "git",
1640
- "url": "https://github.com/sebastianbergmann/comparator.git",
1641
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
1642
- },
1643
- "dist": {
1644
- "type": "zip",
1645
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1646
- "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1647
- "shasum": ""
1648
- },
1649
- "require": {
1650
- "php": ">=5.3.3",
1651
- "sebastian/diff": "~1.2",
1652
- "sebastian/exporter": "~1.2 || ~2.0"
1653
- },
1654
- "require-dev": {
1655
- "phpunit/phpunit": "~4.4"
1656
- },
1657
- "type": "library",
1658
- "extra": {
1659
- "branch-alias": {
1660
- "dev-master": "1.2.x-dev"
1661
- }
1662
- },
1663
- "autoload": {
1664
- "classmap": [
1665
- "src/"
1666
- ]
1667
- },
1668
- "notification-url": "https://packagist.org/downloads/",
1669
- "license": [
1670
- "BSD-3-Clause"
1671
- ],
1672
- "authors": [
1673
- {
1674
- "name": "Jeff Welch",
1675
- "email": "whatthejeff@gmail.com"
1676
- },
1677
- {
1678
- "name": "Volker Dusch",
1679
- "email": "github@wallbash.com"
1680
- },
1681
- {
1682
- "name": "Bernhard Schussek",
1683
- "email": "bschussek@2bepublished.at"
1684
- },
1685
- {
1686
- "name": "Sebastian Bergmann",
1687
- "email": "sebastian@phpunit.de"
1688
- }
1689
- ],
1690
- "description": "Provides the functionality to compare PHP values for equality",
1691
- "homepage": "http://www.github.com/sebastianbergmann/comparator",
1692
- "keywords": [
1693
- "comparator",
1694
- "compare",
1695
- "equality"
1696
- ],
1697
- "time": "2017-01-29T09:50:25+00:00"
1698
- },
1699
- {
1700
- "name": "sebastian/diff",
1701
- "version": "1.4.3",
1702
- "source": {
1703
- "type": "git",
1704
- "url": "https://github.com/sebastianbergmann/diff.git",
1705
- "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
1706
- },
1707
- "dist": {
1708
- "type": "zip",
1709
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1710
- "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
1711
- "shasum": ""
1712
- },
1713
- "require": {
1714
- "php": "^5.3.3 || ^7.0"
1715
- },
1716
- "require-dev": {
1717
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
1718
- },
1719
- "type": "library",
1720
- "extra": {
1721
- "branch-alias": {
1722
- "dev-master": "1.4-dev"
1723
- }
1724
- },
1725
- "autoload": {
1726
- "classmap": [
1727
- "src/"
1728
- ]
1729
- },
1730
- "notification-url": "https://packagist.org/downloads/",
1731
- "license": [
1732
- "BSD-3-Clause"
1733
- ],
1734
- "authors": [
1735
- {
1736
- "name": "Kore Nordmann",
1737
- "email": "mail@kore-nordmann.de"
1738
- },
1739
- {
1740
- "name": "Sebastian Bergmann",
1741
- "email": "sebastian@phpunit.de"
1742
- }
1743
- ],
1744
- "description": "Diff implementation",
1745
- "homepage": "https://github.com/sebastianbergmann/diff",
1746
- "keywords": [
1747
- "diff"
1748
- ],
1749
- "time": "2017-05-22T07:24:03+00:00"
1750
- },
1751
- {
1752
- "name": "sebastian/environment",
1753
- "version": "2.0.0",
1754
- "source": {
1755
- "type": "git",
1756
- "url": "https://github.com/sebastianbergmann/environment.git",
1757
- "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac"
1758
- },
1759
- "dist": {
1760
- "type": "zip",
1761
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
1762
- "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac",
1763
- "shasum": ""
1764
- },
1765
- "require": {
1766
- "php": "^5.6 || ^7.0"
1767
- },
1768
- "require-dev": {
1769
- "phpunit/phpunit": "^5.0"
1770
- },
1771
- "type": "library",
1772
- "extra": {
1773
- "branch-alias": {
1774
- "dev-master": "2.0.x-dev"
1775
- }
1776
- },
1777
- "autoload": {
1778
- "classmap": [
1779
- "src/"
1780
- ]
1781
- },
1782
- "notification-url": "https://packagist.org/downloads/",
1783
- "license": [
1784
- "BSD-3-Clause"
1785
- ],
1786
- "authors": [
1787
- {
1788
- "name": "Sebastian Bergmann",
1789
- "email": "sebastian@phpunit.de"
1790
- }
1791
- ],
1792
- "description": "Provides functionality to handle HHVM/PHP environments",
1793
- "homepage": "http://www.github.com/sebastianbergmann/environment",
1794
- "keywords": [
1795
- "Xdebug",
1796
- "environment",
1797
- "hhvm"
1798
- ],
1799
- "time": "2016-11-26T07:53:53+00:00"
1800
- },
1801
- {
1802
- "name": "sebastian/exporter",
1803
- "version": "2.0.0",
1804
- "source": {
1805
- "type": "git",
1806
- "url": "https://github.com/sebastianbergmann/exporter.git",
1807
- "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4"
1808
- },
1809
- "dist": {
1810
- "type": "zip",
1811
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
1812
- "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4",
1813
- "shasum": ""
1814
- },
1815
- "require": {
1816
- "php": ">=5.3.3",
1817
- "sebastian/recursion-context": "~2.0"
1818
- },
1819
- "require-dev": {
1820
- "ext-mbstring": "*",
1821
- "phpunit/phpunit": "~4.4"
1822
- },
1823
- "type": "library",
1824
- "extra": {
1825
- "branch-alias": {
1826
- "dev-master": "2.0.x-dev"
1827
- }
1828
- },
1829
- "autoload": {
1830
- "classmap": [
1831
- "src/"
1832
- ]
1833
- },
1834
- "notification-url": "https://packagist.org/downloads/",
1835
- "license": [
1836
- "BSD-3-Clause"
1837
- ],
1838
- "authors": [
1839
- {
1840
- "name": "Jeff Welch",
1841
- "email": "whatthejeff@gmail.com"
1842
- },
1843
- {
1844
- "name": "Volker Dusch",
1845
- "email": "github@wallbash.com"
1846
- },
1847
- {
1848
- "name": "Bernhard Schussek",
1849
- "email": "bschussek@2bepublished.at"
1850
- },
1851
- {
1852
- "name": "Sebastian Bergmann",
1853
- "email": "sebastian@phpunit.de"
1854
- },
1855
- {
1856
- "name": "Adam Harvey",
1857
- "email": "aharvey@php.net"
1858
- }
1859
- ],
1860
- "description": "Provides the functionality to export PHP variables for visualization",
1861
- "homepage": "http://www.github.com/sebastianbergmann/exporter",
1862
- "keywords": [
1863
- "export",
1864
- "exporter"
1865
- ],
1866
- "time": "2016-11-19T08:54:04+00:00"
1867
- },
1868
- {
1869
- "name": "sebastian/global-state",
1870
- "version": "1.1.1",
1871
- "source": {
1872
- "type": "git",
1873
- "url": "https://github.com/sebastianbergmann/global-state.git",
1874
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1875
- },
1876
- "dist": {
1877
- "type": "zip",
1878
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1879
- "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1880
- "shasum": ""
1881
- },
1882
- "require": {
1883
- "php": ">=5.3.3"
1884
- },
1885
- "require-dev": {
1886
- "phpunit/phpunit": "~4.2"
1887
- },
1888
- "suggest": {
1889
- "ext-uopz": "*"
1890
- },
1891
- "type": "library",
1892
- "extra": {
1893
- "branch-alias": {
1894
- "dev-master": "1.0-dev"
1895
- }
1896
- },
1897
- "autoload": {
1898
- "classmap": [
1899
- "src/"
1900
- ]
1901
- },
1902
- "notification-url": "https://packagist.org/downloads/",
1903
- "license": [
1904
- "BSD-3-Clause"
1905
- ],
1906
- "authors": [
1907
- {
1908
- "name": "Sebastian Bergmann",
1909
- "email": "sebastian@phpunit.de"
1910
- }
1911
- ],
1912
- "description": "Snapshotting of global state",
1913
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
1914
- "keywords": [
1915
- "global state"
1916
- ],
1917
- "time": "2015-10-12T03:26:01+00:00"
1918
- },
1919
- {
1920
- "name": "sebastian/object-enumerator",
1921
- "version": "2.0.1",
1922
- "source": {
1923
- "type": "git",
1924
- "url": "https://github.com/sebastianbergmann/object-enumerator.git",
1925
- "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
1926
- },
1927
- "dist": {
1928
- "type": "zip",
1929
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
1930
- "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
1931
- "shasum": ""
1932
- },
1933
- "require": {
1934
- "php": ">=5.6",
1935
- "sebastian/recursion-context": "~2.0"
1936
- },
1937
- "require-dev": {
1938
- "phpunit/phpunit": "~5"
1939
- },
1940
- "type": "library",
1941
- "extra": {
1942
- "branch-alias": {
1943
- "dev-master": "2.0.x-dev"
1944
- }
1945
- },
1946
- "autoload": {
1947
- "classmap": [
1948
- "src/"
1949
- ]
1950
- },
1951
- "notification-url": "https://packagist.org/downloads/",
1952
- "license": [
1953
- "BSD-3-Clause"
1954
- ],
1955
- "authors": [
1956
- {
1957
- "name": "Sebastian Bergmann",
1958
- "email": "sebastian@phpunit.de"
1959
- }
1960
- ],
1961
- "description": "Traverses array structures and object graphs to enumerate all referenced objects",
1962
- "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
1963
- "time": "2017-02-18T15:18:39+00:00"
1964
- },
1965
- {
1966
- "name": "sebastian/recursion-context",
1967
- "version": "2.0.0",
1968
- "source": {
1969
- "type": "git",
1970
- "url": "https://github.com/sebastianbergmann/recursion-context.git",
1971
- "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a"
1972
- },
1973
- "dist": {
1974
- "type": "zip",
1975
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a",
1976
- "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a",
1977
- "shasum": ""
1978
- },
1979
- "require": {
1980
- "php": ">=5.3.3"
1981
- },
1982
- "require-dev": {
1983
- "phpunit/phpunit": "~4.4"
1984
- },
1985
- "type": "library",
1986
- "extra": {
1987
- "branch-alias": {
1988
- "dev-master": "2.0.x-dev"
1989
- }
1990
- },
1991
- "autoload": {
1992
- "classmap": [
1993
- "src/"
1994
- ]
1995
- },
1996
- "notification-url": "https://packagist.org/downloads/",
1997
- "license": [
1998
- "BSD-3-Clause"
1999
- ],
2000
- "authors": [
2001
- {
2002
- "name": "Jeff Welch",
2003
- "email": "whatthejeff@gmail.com"
2004
- },
2005
- {
2006
- "name": "Sebastian Bergmann",
2007
- "email": "sebastian@phpunit.de"
2008
- },
2009
- {
2010
- "name": "Adam Harvey",
2011
- "email": "aharvey@php.net"
2012
- }
2013
- ],
2014
- "description": "Provides functionality to recursively process PHP variables",
2015
- "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
2016
- "time": "2016-11-19T07:33:16+00:00"
2017
- },
2018
- {
2019
- "name": "sebastian/resource-operations",
2020
- "version": "1.0.0",
2021
- "source": {
2022
- "type": "git",
2023
- "url": "https://github.com/sebastianbergmann/resource-operations.git",
2024
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
2025
- },
2026
- "dist": {
2027
- "type": "zip",
2028
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
2029
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
2030
- "shasum": ""
2031
- },
2032
- "require": {
2033
- "php": ">=5.6.0"
2034
- },
2035
- "type": "library",
2036
- "extra": {
2037
- "branch-alias": {
2038
- "dev-master": "1.0.x-dev"
2039
- }
2040
- },
2041
- "autoload": {
2042
- "classmap": [
2043
- "src/"
2044
- ]
2045
- },
2046
- "notification-url": "https://packagist.org/downloads/",
2047
- "license": [
2048
- "BSD-3-Clause"
2049
- ],
2050
- "authors": [
2051
- {
2052
- "name": "Sebastian Bergmann",
2053
- "email": "sebastian@phpunit.de"
2054
- }
2055
- ],
2056
- "description": "Provides a list of PHP built-in functions that operate on resources",
2057
- "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
2058
- "time": "2015-07-28T20:34:47+00:00"
2059
- },
2060
- {
2061
- "name": "sebastian/version",
2062
- "version": "2.0.1",
2063
- "source": {
2064
- "type": "git",
2065
- "url": "https://github.com/sebastianbergmann/version.git",
2066
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
2067
- },
2068
- "dist": {
2069
- "type": "zip",
2070
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
2071
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
2072
- "shasum": ""
2073
- },
2074
- "require": {
2075
- "php": ">=5.6"
2076
- },
2077
- "type": "library",
2078
- "extra": {
2079
- "branch-alias": {
2080
- "dev-master": "2.0.x-dev"
2081
- }
2082
- },
2083
- "autoload": {
2084
- "classmap": [
2085
- "src/"
2086
- ]
2087
- },
2088
- "notification-url": "https://packagist.org/downloads/",
2089
- "license": [
2090
- "BSD-3-Clause"
2091
- ],
2092
- "authors": [
2093
- {
2094
- "name": "Sebastian Bergmann",
2095
- "email": "sebastian@phpunit.de",
2096
- "role": "lead"
2097
- }
2098
- ],
2099
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
2100
- "homepage": "https://github.com/sebastianbergmann/version",
2101
- "time": "2016-10-03T07:35:21+00:00"
2102
- },
2103
- {
2104
- "name": "seld/jsonlint",
2105
- "version": "1.7.2",
2106
- "source": {
2107
- "type": "git",
2108
- "url": "https://github.com/Seldaek/jsonlint.git",
2109
- "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19"
2110
- },
2111
- "dist": {
2112
- "type": "zip",
2113
- "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e2e5d290e4d2a4f0eb449f510071392e00e10d19",
2114
- "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19",
2115
- "shasum": ""
2116
- },
2117
- "require": {
2118
- "php": "^5.3 || ^7.0"
2119
- },
2120
- "require-dev": {
2121
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
2122
- },
2123
- "bin": [
2124
- "bin/jsonlint"
2125
- ],
2126
- "type": "library",
2127
- "autoload": {
2128
- "psr-4": {
2129
- "Seld\\JsonLint\\": "src/Seld/JsonLint/"
2130
- }
2131
- },
2132
- "notification-url": "https://packagist.org/downloads/",
2133
- "license": [
2134
- "MIT"
2135
- ],
2136
- "authors": [
2137
- {
2138
- "name": "Jordi Boggiano",
2139
- "email": "j.boggiano@seld.be",
2140
- "homepage": "http://seld.be"
2141
- }
2142
- ],
2143
- "description": "JSON Linter",
2144
- "keywords": [
2145
- "json",
2146
- "linter",
2147
- "parser",
2148
- "validator"
2149
- ],
2150
- "time": "2019-10-24T14:27:39+00:00"
2151
- },
2152
- {
2153
- "name": "seld/phar-utils",
2154
- "version": "1.1.0",
2155
- "source": {
2156
- "type": "git",
2157
- "url": "https://github.com/Seldaek/phar-utils.git",
2158
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0"
2159
- },
2160
- "dist": {
2161
- "type": "zip",
2162
- "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0",
2163
- "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0",
2164
- "shasum": ""
2165
- },
2166
- "require": {
2167
- "php": ">=5.3"
2168
- },
2169
- "type": "library",
2170
- "extra": {
2171
- "branch-alias": {
2172
- "dev-master": "1.x-dev"
2173
- }
2174
- },
2175
- "autoload": {
2176
- "psr-4": {
2177
- "Seld\\PharUtils\\": "src/"
2178
- }
2179
- },
2180
- "notification-url": "https://packagist.org/downloads/",
2181
- "license": [
2182
- "MIT"
2183
- ],
2184
- "authors": [
2185
- {
2186
- "name": "Jordi Boggiano",
2187
- "email": "j.boggiano@seld.be"
2188
- }
2189
- ],
2190
- "description": "PHAR file format utilities, for when PHP phars you up",
2191
- "keywords": [
2192
- "phar"
2193
- ],
2194
- "time": "2020-02-14T15:25:33+00:00"
2195
- },
2196
- {
2197
- "name": "squizlabs/php_codesniffer",
2198
- "version": "3.5.4",
2199
- "source": {
2200
- "type": "git",
2201
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
2202
- "reference": "dceec07328401de6211037abbb18bda423677e26"
2203
- },
2204
- "dist": {
2205
- "type": "zip",
2206
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/dceec07328401de6211037abbb18bda423677e26",
2207
- "reference": "dceec07328401de6211037abbb18bda423677e26",
2208
- "shasum": ""
2209
- },
2210
- "require": {
2211
- "ext-simplexml": "*",
2212
- "ext-tokenizer": "*",
2213
- "ext-xmlwriter": "*",
2214
- "php": ">=5.4.0"
2215
- },
2216
- "require-dev": {
2217
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
2218
- },
2219
- "bin": [
2220
- "bin/phpcs",
2221
- "bin/phpcbf"
2222
- ],
2223
- "type": "library",
2224
- "extra": {
2225
- "branch-alias": {
2226
- "dev-master": "3.x-dev"
2227
- }
2228
- },
2229
- "notification-url": "https://packagist.org/downloads/",
2230
- "license": [
2231
- "BSD-3-Clause"
2232
- ],
2233
- "authors": [
2234
- {
2235
- "name": "Greg Sherwood",
2236
- "role": "lead"
2237
- }
2238
- ],
2239
- "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
2240
- "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
2241
- "keywords": [
2242
- "phpcs",
2243
- "standards"
2244
- ],
2245
- "time": "2020-01-30T22:20:29+00:00"
2246
- },
2247
- {
2248
- "name": "symfony/config",
2249
- "version": "v3.4.37",
2250
- "source": {
2251
- "type": "git",
2252
- "url": "https://github.com/symfony/config.git",
2253
- "reference": "6abc18b2a97f63508d23929bbb2ae65aaa07bace"
2254
- },
2255
- "dist": {
2256
- "type": "zip",
2257
- "url": "https://api.github.com/repos/symfony/config/zipball/6abc18b2a97f63508d23929bbb2ae65aaa07bace",
2258
- "reference": "6abc18b2a97f63508d23929bbb2ae65aaa07bace",
2259
- "shasum": ""
2260
- },
2261
- "require": {
2262
- "php": "^5.5.9|>=7.0.8",
2263
- "symfony/filesystem": "~2.8|~3.0|~4.0",
2264
- "symfony/polyfill-ctype": "~1.8"
2265
- },
2266
- "conflict": {
2267
- "symfony/dependency-injection": "<3.3",
2268
- "symfony/finder": "<3.3"
2269
- },
2270
- "require-dev": {
2271
- "symfony/dependency-injection": "~3.3|~4.0",
2272
- "symfony/event-dispatcher": "~3.3|~4.0",
2273
- "symfony/finder": "~3.3|~4.0",
2274
- "symfony/yaml": "~3.0|~4.0"
2275
- },
2276
- "suggest": {
2277
- "symfony/yaml": "To use the yaml reference dumper"
2278
- },
2279
- "type": "library",
2280
- "extra": {
2281
- "branch-alias": {
2282
- "dev-master": "3.4-dev"
2283
- }
2284
- },
2285
- "autoload": {
2286
- "psr-4": {
2287
- "Symfony\\Component\\Config\\": ""
2288
- },
2289
- "exclude-from-classmap": [
2290
- "/Tests/"
2291
- ]
2292
- },
2293
- "notification-url": "https://packagist.org/downloads/",
2294
- "license": [
2295
- "MIT"
2296
- ],
2297
- "authors": [
2298
- {
2299
- "name": "Fabien Potencier",
2300
- "email": "fabien@symfony.com"
2301
- },
2302
- {
2303
- "name": "Symfony Community",
2304
- "homepage": "https://symfony.com/contributors"
2305
- }
2306
- ],
2307
- "description": "Symfony Config Component",
2308
- "homepage": "https://symfony.com",
2309
- "time": "2020-01-04T12:05:51+00:00"
2310
- },
2311
- {
2312
- "name": "symfony/console",
2313
- "version": "v3.4.37",
2314
- "source": {
2315
- "type": "git",
2316
- "url": "https://github.com/symfony/console.git",
2317
- "reference": "7c5bdd346f9d90a2d22d4e1fe61e02dc19b98f12"
2318
- },
2319
- "dist": {
2320
- "type": "zip",
2321
- "url": "https://api.github.com/repos/symfony/console/zipball/7c5bdd346f9d90a2d22d4e1fe61e02dc19b98f12",
2322
- "reference": "7c5bdd346f9d90a2d22d4e1fe61e02dc19b98f12",
2323
- "shasum": ""
2324
- },
2325
- "require": {
2326
- "php": "^5.5.9|>=7.0.8",
2327
- "symfony/debug": "~2.8|~3.0|~4.0",
2328
- "symfony/polyfill-mbstring": "~1.0"
2329
- },
2330
- "conflict": {
2331
- "symfony/dependency-injection": "<3.4",
2332
- "symfony/process": "<3.3"
2333
- },
2334
- "provide": {
2335
- "psr/log-implementation": "1.0"
2336
- },
2337
- "require-dev": {
2338
- "psr/log": "~1.0",
2339
- "symfony/config": "~3.3|~4.0",
2340
- "symfony/dependency-injection": "~3.4|~4.0",
2341
- "symfony/event-dispatcher": "~2.8|~3.0|~4.0",
2342
- "symfony/lock": "~3.4|~4.0",
2343
- "symfony/process": "~3.3|~4.0"
2344
- },
2345
- "suggest": {
2346
- "psr/log": "For using the console logger",
2347
- "symfony/event-dispatcher": "",
2348
- "symfony/lock": "",
2349
- "symfony/process": ""
2350
- },
2351
- "type": "library",
2352
- "extra": {
2353
- "branch-alias": {
2354
- "dev-master": "3.4-dev"
2355
- }
2356
- },
2357
- "autoload": {
2358
- "psr-4": {
2359
- "Symfony\\Component\\Console\\": ""
2360
- },
2361
- "exclude-from-classmap": [
2362
- "/Tests/"
2363
- ]
2364
- },
2365
- "notification-url": "https://packagist.org/downloads/",
2366
- "license": [
2367
- "MIT"
2368
- ],
2369
- "authors": [
2370
- {
2371
- "name": "Fabien Potencier",
2372
- "email": "fabien@symfony.com"
2373
- },
2374
- {
2375
- "name": "Symfony Community",
2376
- "homepage": "https://symfony.com/contributors"
2377
- }
2378
- ],
2379
- "description": "Symfony Console Component",
2380
- "homepage": "https://symfony.com",
2381
- "time": "2020-01-10T07:52:48+00:00"
2382
- },
2383
- {
2384
- "name": "symfony/debug",
2385
- "version": "v3.4.37",
2386
- "source": {
2387
- "type": "git",
2388
- "url": "https://github.com/symfony/debug.git",
2389
- "reference": "70dd18e93bb8bdf3c4db7fde832619fef9828cf8"
2390
- },
2391
- "dist": {
2392
- "type": "zip",
2393
- "url": "https://api.github.com/repos/symfony/debug/zipball/70dd18e93bb8bdf3c4db7fde832619fef9828cf8",
2394
- "reference": "70dd18e93bb8bdf3c4db7fde832619fef9828cf8",
2395
- "shasum": ""
2396
- },
2397
- "require": {
2398
- "php": "^5.5.9|>=7.0.8",
2399
- "psr/log": "~1.0"
2400
- },
2401
- "conflict": {
2402
- "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
2403
- },
2404
- "require-dev": {
2405
- "symfony/http-kernel": "~2.8|~3.0|~4.0"
2406
- },
2407
- "type": "library",
2408
- "extra": {
2409
- "branch-alias": {
2410
- "dev-master": "3.4-dev"
2411
- }
2412
- },
2413
- "autoload": {
2414
- "psr-4": {
2415
- "Symfony\\Component\\Debug\\": ""
2416
- },
2417
- "exclude-from-classmap": [
2418
- "/Tests/"
2419
- ]
2420
- },
2421
- "notification-url": "https://packagist.org/downloads/",
2422
- "license": [
2423
- "MIT"
2424
- ],
2425
- "authors": [
2426
- {
2427
- "name": "Fabien Potencier",
2428
- "email": "fabien@symfony.com"
2429
- },
2430
- {
2431
- "name": "Symfony Community",
2432
- "homepage": "https://symfony.com/contributors"
2433
- }
2434
- ],
2435
- "description": "Symfony Debug Component",
2436
- "homepage": "https://symfony.com",
2437
- "time": "2020-01-08T16:36:15+00:00"
2438
- },
2439
- {
2440
- "name": "symfony/dependency-injection",
2441
- "version": "v3.4.37",
2442
- "source": {
2443
- "type": "git",
2444
- "url": "https://github.com/symfony/dependency-injection.git",
2445
- "reference": "22000f10c9e1cfef051e8b4de46815b41a0223fc"
2446
- },
2447
- "dist": {
2448
- "type": "zip",
2449
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/22000f10c9e1cfef051e8b4de46815b41a0223fc",
2450
- "reference": "22000f10c9e1cfef051e8b4de46815b41a0223fc",
2451
- "shasum": ""
2452
- },
2453
- "require": {
2454
- "php": "^5.5.9|>=7.0.8",
2455
- "psr/container": "^1.0"
2456
- },
2457
- "conflict": {
2458
- "symfony/config": "<3.3.7",
2459
- "symfony/finder": "<3.3",
2460
- "symfony/proxy-manager-bridge": "<3.4",
2461
- "symfony/yaml": "<3.4"
2462
- },
2463
- "provide": {
2464
- "psr/container-implementation": "1.0"
2465
- },
2466
- "require-dev": {
2467
- "symfony/config": "~3.3|~4.0",
2468
- "symfony/expression-language": "~2.8|~3.0|~4.0",
2469
- "symfony/yaml": "~3.4|~4.0"
2470
- },
2471
- "suggest": {
2472
- "symfony/config": "",
2473
- "symfony/expression-language": "For using expressions in service container configuration",
2474
- "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
2475
- "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
2476
- "symfony/yaml": ""
2477
- },
2478
- "type": "library",
2479
- "extra": {
2480
- "branch-alias": {
2481
- "dev-master": "3.4-dev"
2482
- }
2483
- },
2484
- "autoload": {
2485
- "psr-4": {
2486
- "Symfony\\Component\\DependencyInjection\\": ""
2487
- },
2488
- "exclude-from-classmap": [
2489
- "/Tests/"
2490
- ]
2491
- },
2492
- "notification-url": "https://packagist.org/downloads/",
2493
- "license": [
2494
- "MIT"
2495
- ],
2496
- "authors": [
2497
- {
2498
- "name": "Fabien Potencier",
2499
- "email": "fabien@symfony.com"
2500
- },
2501
- {
2502
- "name": "Symfony Community",
2503
- "homepage": "https://symfony.com/contributors"
2504
- }
2505
- ],
2506
- "description": "Symfony DependencyInjection Component",
2507
- "homepage": "https://symfony.com",
2508
- "time": "2020-01-08T11:20:51+00:00"
2509
- },
2510
- {
2511
- "name": "symfony/event-dispatcher",
2512
- "version": "v3.4.37",
2513
- "source": {
2514
- "type": "git",
2515
- "url": "https://github.com/symfony/event-dispatcher.git",
2516
- "reference": "79ede8f2836e5ec910ebb325bde40f987244baa8"
2517
- },
2518
- "dist": {
2519
- "type": "zip",
2520
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/79ede8f2836e5ec910ebb325bde40f987244baa8",
2521
- "reference": "79ede8f2836e5ec910ebb325bde40f987244baa8",
2522
- "shasum": ""
2523
- },
2524
- "require": {
2525
- "php": "^5.5.9|>=7.0.8"
2526
- },
2527
- "conflict": {
2528
- "symfony/dependency-injection": "<3.3"
2529
- },
2530
- "require-dev": {
2531
- "psr/log": "~1.0",
2532
- "symfony/config": "~2.8|~3.0|~4.0",
2533
- "symfony/dependency-injection": "~3.3|~4.0",
2534
- "symfony/expression-language": "~2.8|~3.0|~4.0",
2535
- "symfony/stopwatch": "~2.8|~3.0|~4.0"
2536
- },
2537
- "suggest": {
2538
- "symfony/dependency-injection": "",
2539
- "symfony/http-kernel": ""
2540
- },
2541
- "type": "library",
2542
- "extra": {
2543
- "branch-alias": {
2544
- "dev-master": "3.4-dev"
2545
- }
2546
- },
2547
- "autoload": {
2548
- "psr-4": {
2549
- "Symfony\\Component\\EventDispatcher\\": ""
2550
- },
2551
- "exclude-from-classmap": [
2552
- "/Tests/"
2553
- ]
2554
- },
2555
- "notification-url": "https://packagist.org/downloads/",
2556
- "license": [
2557
- "MIT"
2558
- ],
2559
- "authors": [
2560
- {
2561
- "name": "Fabien Potencier",
2562
- "email": "fabien@symfony.com"
2563
- },
2564
- {
2565
- "name": "Symfony Community",
2566
- "homepage": "https://symfony.com/contributors"
2567
- }
2568
- ],
2569
- "description": "Symfony EventDispatcher Component",
2570
- "homepage": "https://symfony.com",
2571
- "time": "2020-01-04T12:05:51+00:00"
2572
- },
2573
- {
2574
- "name": "symfony/filesystem",
2575
- "version": "v3.4.37",
2576
- "source": {
2577
- "type": "git",
2578
- "url": "https://github.com/symfony/filesystem.git",
2579
- "reference": "0a0d3b4bda11aa3a0464531c40e681e184e75628"
2580
- },
2581
- "dist": {
2582
- "type": "zip",
2583
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/0a0d3b4bda11aa3a0464531c40e681e184e75628",
2584
- "reference": "0a0d3b4bda11aa3a0464531c40e681e184e75628",
2585
- "shasum": ""
2586
- },
2587
- "require": {
2588
- "php": "^5.5.9|>=7.0.8",
2589
- "symfony/polyfill-ctype": "~1.8"
2590
- },
2591
- "type": "library",
2592
- "extra": {
2593
- "branch-alias": {
2594
- "dev-master": "3.4-dev"
2595
- }
2596
- },
2597
- "autoload": {
2598
- "psr-4": {
2599
- "Symfony\\Component\\Filesystem\\": ""
2600
- },
2601
- "exclude-from-classmap": [
2602
- "/Tests/"
2603
- ]
2604
- },
2605
- "notification-url": "https://packagist.org/downloads/",
2606
- "license": [
2607
- "MIT"
2608
- ],
2609
- "authors": [
2610
- {
2611
- "name": "Fabien Potencier",
2612
- "email": "fabien@symfony.com"
2613
- },
2614
- {
2615
- "name": "Symfony Community",
2616
- "homepage": "https://symfony.com/contributors"
2617
- }
2618
- ],
2619
- "description": "Symfony Filesystem Component",
2620
- "homepage": "https://symfony.com",
2621
- "time": "2020-01-17T08:50:08+00:00"
2622
- },
2623
- {
2624
- "name": "symfony/finder",
2625
- "version": "v3.4.37",
2626
- "source": {
2627
- "type": "git",
2628
- "url": "https://github.com/symfony/finder.git",
2629
- "reference": "a90a9d3b9f458a5cdeabfa4090b20c000ca3962f"
2630
- },
2631
- "dist": {
2632
- "type": "zip",
2633
- "url": "https://api.github.com/repos/symfony/finder/zipball/a90a9d3b9f458a5cdeabfa4090b20c000ca3962f",
2634
- "reference": "a90a9d3b9f458a5cdeabfa4090b20c000ca3962f",
2635
- "shasum": ""
2636
- },
2637
- "require": {
2638
- "php": "^5.5.9|>=7.0.8"
2639
- },
2640
- "type": "library",
2641
- "extra": {
2642
- "branch-alias": {
2643
- "dev-master": "3.4-dev"
2644
- }
2645
- },
2646
- "autoload": {
2647
- "psr-4": {
2648
- "Symfony\\Component\\Finder\\": ""
2649
- },
2650
- "exclude-from-classmap": [
2651
- "/Tests/"
2652
- ]
2653
- },
2654
- "notification-url": "https://packagist.org/downloads/",
2655
- "license": [
2656
- "MIT"
2657
- ],
2658
- "authors": [
2659
- {
2660
- "name": "Fabien Potencier",
2661
- "email": "fabien@symfony.com"
2662
- },
2663
- {
2664
- "name": "Symfony Community",
2665
- "homepage": "https://symfony.com/contributors"
2666
- }
2667
- ],
2668
- "description": "Symfony Finder Component",
2669
- "homepage": "https://symfony.com",
2670
- "time": "2020-01-01T11:03:25+00:00"
2671
- },
2672
- {
2673
- "name": "symfony/polyfill-ctype",
2674
- "version": "v1.14.0",
2675
- "source": {
2676
- "type": "git",
2677
- "url": "https://github.com/symfony/polyfill-ctype.git",
2678
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38"
2679
- },
2680
- "dist": {
2681
- "type": "zip",
2682
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
2683
- "reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
2684
- "shasum": ""
2685
- },
2686
- "require": {
2687
- "php": ">=5.3.3"
2688
- },
2689
- "suggest": {
2690
- "ext-ctype": "For best performance"
2691
- },
2692
- "type": "library",
2693
- "extra": {
2694
- "branch-alias": {
2695
- "dev-master": "1.14-dev"
2696
- }
2697
- },
2698
- "autoload": {
2699
- "psr-4": {
2700
- "Symfony\\Polyfill\\Ctype\\": ""
2701
- },
2702
- "files": [
2703
- "bootstrap.php"
2704
- ]
2705
- },
2706
- "notification-url": "https://packagist.org/downloads/",
2707
- "license": [
2708
- "MIT"
2709
- ],
2710
- "authors": [
2711
- {
2712
- "name": "Gert de Pagter",
2713
- "email": "BackEndTea@gmail.com"
2714
- },
2715
- {
2716
- "name": "Symfony Community",
2717
- "homepage": "https://symfony.com/contributors"
2718
- }
2719
- ],
2720
- "description": "Symfony polyfill for ctype functions",
2721
- "homepage": "https://symfony.com",
2722
- "keywords": [
2723
- "compatibility",
2724
- "ctype",
2725
- "polyfill",
2726
- "portable"
2727
- ],
2728
- "time": "2020-01-13T11:15:53+00:00"
2729
- },
2730
- {
2731
- "name": "symfony/polyfill-mbstring",
2732
- "version": "v1.14.0",
2733
- "source": {
2734
- "type": "git",
2735
- "url": "https://github.com/symfony/polyfill-mbstring.git",
2736
- "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2"
2737
- },
2738
- "dist": {
2739
- "type": "zip",
2740
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2",
2741
- "reference": "34094cfa9abe1f0f14f48f490772db7a775559f2",
2742
- "shasum": ""
2743
- },
2744
- "require": {
2745
- "php": ">=5.3.3"
2746
- },
2747
- "suggest": {
2748
- "ext-mbstring": "For best performance"
2749
- },
2750
- "type": "library",
2751
- "extra": {
2752
- "branch-alias": {
2753
- "dev-master": "1.14-dev"
2754
- }
2755
- },
2756
- "autoload": {
2757
- "psr-4": {
2758
- "Symfony\\Polyfill\\Mbstring\\": ""
2759
- },
2760
- "files": [
2761
- "bootstrap.php"
2762
- ]
2763
- },
2764
- "notification-url": "https://packagist.org/downloads/",
2765
- "license": [
2766
- "MIT"
2767
- ],
2768
- "authors": [
2769
- {
2770
- "name": "Nicolas Grekas",
2771
- "email": "p@tchwork.com"
2772
- },
2773
- {
2774
- "name": "Symfony Community",
2775
- "homepage": "https://symfony.com/contributors"
2776
- }
2777
- ],
2778
- "description": "Symfony polyfill for the Mbstring extension",
2779
- "homepage": "https://symfony.com",
2780
- "keywords": [
2781
- "compatibility",
2782
- "mbstring",
2783
- "polyfill",
2784
- "portable",
2785
- "shim"
2786
- ],
2787
- "time": "2020-01-13T11:15:53+00:00"
2788
- },
2789
- {
2790
- "name": "symfony/process",
2791
- "version": "v3.4.37",
2792
- "source": {
2793
- "type": "git",
2794
- "url": "https://github.com/symfony/process.git",
2795
- "reference": "5b9d2bcffe4678911a4c941c00b7c161252cf09a"
2796
- },
2797
- "dist": {
2798
- "type": "zip",
2799
- "url": "https://api.github.com/repos/symfony/process/zipball/5b9d2bcffe4678911a4c941c00b7c161252cf09a",
2800
- "reference": "5b9d2bcffe4678911a4c941c00b7c161252cf09a",
2801
- "shasum": ""
2802
- },
2803
- "require": {
2804
- "php": "^5.5.9|>=7.0.8"
2805
- },
2806
- "type": "library",
2807
- "extra": {
2808
- "branch-alias": {
2809
- "dev-master": "3.4-dev"
2810
- }
2811
- },
2812
- "autoload": {
2813
- "psr-4": {
2814
- "Symfony\\Component\\Process\\": ""
2815
- },
2816
- "exclude-from-classmap": [
2817
- "/Tests/"
2818
- ]
2819
- },
2820
- "notification-url": "https://packagist.org/downloads/",
2821
- "license": [
2822
- "MIT"
2823
- ],
2824
- "authors": [
2825
- {
2826
- "name": "Fabien Potencier",
2827
- "email": "fabien@symfony.com"
2828
- },
2829
- {
2830
- "name": "Symfony Community",
2831
- "homepage": "https://symfony.com/contributors"
2832
- }
2833
- ],
2834
- "description": "Symfony Process Component",
2835
- "homepage": "https://symfony.com",
2836
- "time": "2020-01-01T11:03:25+00:00"
2837
- },
2838
- {
2839
- "name": "symfony/translation",
2840
- "version": "v3.4.37",
2841
- "source": {
2842
- "type": "git",
2843
- "url": "https://github.com/symfony/translation.git",
2844
- "reference": "577ec9ba1d6443947c48058acc3de298ad25e2bf"
2845
- },
2846
- "dist": {
2847
- "type": "zip",
2848
- "url": "https://api.github.com/repos/symfony/translation/zipball/577ec9ba1d6443947c48058acc3de298ad25e2bf",
2849
- "reference": "577ec9ba1d6443947c48058acc3de298ad25e2bf",
2850
- "shasum": ""
2851
- },
2852
- "require": {
2853
- "php": "^5.5.9|>=7.0.8",
2854
- "symfony/polyfill-mbstring": "~1.0"
2855
- },
2856
- "conflict": {
2857
- "symfony/config": "<2.8",
2858
- "symfony/dependency-injection": "<3.4",
2859
- "symfony/yaml": "<3.4"
2860
- },
2861
- "require-dev": {
2862
- "psr/log": "~1.0",
2863
- "symfony/config": "~2.8|~3.0|~4.0",
2864
- "symfony/dependency-injection": "~3.4|~4.0",
2865
- "symfony/finder": "~2.8|~3.0|~4.0",
2866
- "symfony/http-kernel": "~3.4|~4.0",
2867
- "symfony/intl": "^2.8.18|^3.2.5|~4.0",
2868
- "symfony/var-dumper": "~3.4|~4.0",
2869
- "symfony/yaml": "~3.4|~4.0"
2870
- },
2871
- "suggest": {
2872
- "psr/log-implementation": "To use logging capability in translator",
2873
- "symfony/config": "",
2874
- "symfony/yaml": ""
2875
- },
2876
- "type": "library",
2877
- "extra": {
2878
- "branch-alias": {
2879
- "dev-master": "3.4-dev"
2880
- }
2881
- },
2882
- "autoload": {
2883
- "psr-4": {
2884
- "Symfony\\Component\\Translation\\": ""
2885
- },
2886
- "exclude-from-classmap": [
2887
- "/Tests/"
2888
- ]
2889
- },
2890
- "notification-url": "https://packagist.org/downloads/",
2891
- "license": [
2892
- "MIT"
2893
- ],
2894
- "authors": [
2895
- {
2896
- "name": "Fabien Potencier",
2897
- "email": "fabien@symfony.com"
2898
- },
2899
- {
2900
- "name": "Symfony Community",
2901
- "homepage": "https://symfony.com/contributors"
2902
- }
2903
- ],
2904
- "description": "Symfony Translation Component",
2905
- "homepage": "https://symfony.com",
2906
- "time": "2020-01-04T12:05:51+00:00"
2907
- },
2908
- {
2909
- "name": "symfony/yaml",
2910
- "version": "v3.4.37",
2911
- "source": {
2912
- "type": "git",
2913
- "url": "https://github.com/symfony/yaml.git",
2914
- "reference": "aa46bc2233097d5212332c907f9911533acfbf80"
2915
- },
2916
- "dist": {
2917
- "type": "zip",
2918
- "url": "https://api.github.com/repos/symfony/yaml/zipball/aa46bc2233097d5212332c907f9911533acfbf80",
2919
- "reference": "aa46bc2233097d5212332c907f9911533acfbf80",
2920
- "shasum": ""
2921
- },
2922
- "require": {
2923
- "php": "^5.5.9|>=7.0.8",
2924
- "symfony/polyfill-ctype": "~1.8"
2925
- },
2926
- "conflict": {
2927
- "symfony/console": "<3.4"
2928
- },
2929
- "require-dev": {
2930
- "symfony/console": "~3.4|~4.0"
2931
- },
2932
- "suggest": {
2933
- "symfony/console": "For validating YAML files using the lint command"
2934
- },
2935
- "type": "library",
2936
- "extra": {
2937
- "branch-alias": {
2938
- "dev-master": "3.4-dev"
2939
- }
2940
- },
2941
- "autoload": {
2942
- "psr-4": {
2943
- "Symfony\\Component\\Yaml\\": ""
2944
- },
2945
- "exclude-from-classmap": [
2946
- "/Tests/"
2947
- ]
2948
- },
2949
- "notification-url": "https://packagist.org/downloads/",
2950
- "license": [
2951
- "MIT"
2952
- ],
2953
- "authors": [
2954
- {
2955
- "name": "Fabien Potencier",
2956
- "email": "fabien@symfony.com"
2957
- },
2958
- {
2959
- "name": "Symfony Community",
2960
- "homepage": "https://symfony.com/contributors"
2961
- }
2962
- ],
2963
- "description": "Symfony Yaml Component",
2964
- "homepage": "https://symfony.com",
2965
- "time": "2020-01-13T08:00:59+00:00"
2966
- },
2967
- {
2968
- "name": "webmozart/assert",
2969
- "version": "1.7.0",
2970
- "source": {
2971
- "type": "git",
2972
- "url": "https://github.com/webmozart/assert.git",
2973
- "reference": "aed98a490f9a8f78468232db345ab9cf606cf598"
2974
- },
2975
- "dist": {
2976
- "type": "zip",
2977
- "url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598",
2978
- "reference": "aed98a490f9a8f78468232db345ab9cf606cf598",
2979
- "shasum": ""
2980
- },
2981
- "require": {
2982
- "php": "^5.3.3 || ^7.0",
2983
- "symfony/polyfill-ctype": "^1.8"
2984
- },
2985
- "conflict": {
2986
- "vimeo/psalm": "<3.6.0"
2987
- },
2988
- "require-dev": {
2989
- "phpunit/phpunit": "^4.8.36 || ^7.5.13"
2990
- },
2991
- "type": "library",
2992
- "autoload": {
2993
- "psr-4": {
2994
- "Webmozart\\Assert\\": "src/"
2995
- }
2996
- },
2997
- "notification-url": "https://packagist.org/downloads/",
2998
- "license": [
2999
- "MIT"
3000
- ],
3001
- "authors": [
3002
- {
3003
- "name": "Bernhard Schussek",
3004
- "email": "bschussek@gmail.com"
3005
- }
3006
- ],
3007
- "description": "Assertions to validate method input/output with nice error messages.",
3008
- "keywords": [
3009
- "assert",
3010
- "check",
3011
- "validate"
3012
- ],
3013
- "time": "2020-02-14T12:15:55+00:00"
3014
- },
3015
- {
3016
- "name": "woocommerce/woocommerce-sniffs",
3017
- "version": "0.0.8",
3018
- "source": {
3019
- "type": "git",
3020
- "url": "https://github.com/woocommerce/woocommerce-sniffs.git",
3021
- "reference": "ccdae93ba678d59cd9741bec077d0c63c0a82958"
3022
- },
3023
- "dist": {
3024
- "type": "zip",
3025
- "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/ccdae93ba678d59cd9741bec077d0c63c0a82958",
3026
- "reference": "ccdae93ba678d59cd9741bec077d0c63c0a82958",
3027
- "shasum": ""
3028
- },
3029
- "require": {
3030
- "dealerdirect/phpcodesniffer-composer-installer": "0.5.0",
3031
- "php": ">=7.0",
3032
- "phpcompatibility/phpcompatibility-wp": "2.1.0",
3033
- "wp-coding-standards/wpcs": "2.1.1"
3034
- },
3035
- "type": "phpcodesniffer-standard",
3036
- "notification-url": "https://packagist.org/downloads/",
3037
- "license": [
3038
- "MIT"
3039
- ],
3040
- "authors": [
3041
- {
3042
- "name": "Claudio Sanches",
3043
- "email": "claudio@automattic.com"
3044
- }
3045
- ],
3046
- "description": "WooCommerce sniffs",
3047
- "keywords": [
3048
- "phpcs",
3049
- "standards",
3050
- "woocommerce",
3051
- "wordpress"
3052
- ],
3053
- "time": "2019-10-16T18:25:21+00:00"
3054
- },
3055
- {
3056
- "name": "wp-cli/autoload-splitter",
3057
- "version": "v0.1.5",
3058
- "source": {
3059
- "type": "git",
3060
- "url": "https://github.com/wp-cli/autoload-splitter.git",
3061
- "reference": "fb4302da26390811d2631c62b42b75976d224bb8"
3062
- },
3063
- "dist": {
3064
- "type": "zip",
3065
- "url": "https://api.github.com/repos/wp-cli/autoload-splitter/zipball/fb4302da26390811d2631c62b42b75976d224bb8",
3066
- "reference": "fb4302da26390811d2631c62b42b75976d224bb8",
3067
- "shasum": ""
3068
- },
3069
- "require": {
3070
- "composer-plugin-api": "^1.1"
3071
- },
3072
- "type": "composer-plugin",
3073
- "extra": {
3074
- "class": "WP_CLI\\AutoloadSplitter\\ComposerPlugin"
3075
- },
3076
- "autoload": {
3077
- "psr-4": {
3078
- "WP_CLI\\AutoloadSplitter\\": "src"
3079
- }
3080
- },
3081
- "notification-url": "https://packagist.org/downloads/",
3082
- "license": [
3083
- "MIT"
3084
- ],
3085
- "authors": [
3086
- {
3087
- "name": "Alain Schlesser",
3088
- "email": "alain.schlesser@gmail.com",
3089
- "homepage": "https://www.alainschlesser.com"
3090
- }
3091
- ],
3092
- "description": "Composer plugin for splitting a generated autoloader into two distinct parts.",
3093
- "homepage": "https://wp-cli.org",
3094
- "time": "2017-08-03T08:40:16+00:00"
3095
- },
3096
- {
3097
- "name": "wp-cli/cache-command",
3098
- "version": "v1.0.6",
3099
- "source": {
3100
- "type": "git",
3101
- "url": "https://github.com/wp-cli/cache-command.git",
3102
- "reference": "d82cba9effa198f17847dce5771c8fb20c443ffa"
3103
- },
3104
- "dist": {
3105
- "type": "zip",
3106
- "url": "https://api.github.com/repos/wp-cli/cache-command/zipball/d82cba9effa198f17847dce5771c8fb20c443ffa",
3107
- "reference": "d82cba9effa198f17847dce5771c8fb20c443ffa",
3108
- "shasum": ""
3109
- },
3110
- "require-dev": {
3111
- "behat/behat": "~2.5",
3112
- "wp-cli/wp-cli": "*"
3113
- },
3114
- "type": "wp-cli-package",
3115
- "extra": {
3116
- "branch-alias": {
3117
- "dev-master": "1.x-dev"
3118
- },
3119
- "bundled": true,
3120
- "commands": [
3121
- "cache",
3122
- "cache add",
3123
- "cache decr",
3124
- "cache delete",
3125
- "cache flush",
3126
- "cache get",
3127
- "cache incr",
3128
- "cache replace",
3129
- "cache set",
3130
- "cache type",
3131
- "transient",
3132
- "transient delete",
3133
- "transient get",
3134
- "transient set",
3135
- "transient type"
3136
- ]
3137
- },
3138
- "autoload": {
3139
- "psr-4": {
3140
- "": "src/"
3141
- },
3142
- "files": [
3143
- "cache-command.php"
3144
- ]
3145
- },
3146
- "notification-url": "https://packagist.org/downloads/",
3147
- "license": [
3148
- "MIT"
3149
- ],
3150
- "authors": [
3151
- {
3152
- "name": "Daniel Bachhuber",
3153
- "email": "daniel@runcommand.io",
3154
- "homepage": "https://runcommand.io"
3155
- }
3156
- ],
3157
- "description": "Manages object and transient caches.",
3158
- "homepage": "https://github.com/wp-cli/cache-command",
3159
- "time": "2017-12-14T19:21:19+00:00"
3160
- },
3161
- {
3162
- "name": "wp-cli/checksum-command",
3163
- "version": "v1.0.9",
3164
- "source": {
3165
- "type": "git",
3166
- "url": "https://github.com/wp-cli/checksum-command.git",
3167
- "reference": "89a319440651f2867f282339c2223cfe5e9cc3fb"
3168
- },
3169
- "dist": {
3170
- "type": "zip",
3171
- "url": "https://api.github.com/repos/wp-cli/checksum-command/zipball/89a319440651f2867f282339c2223cfe5e9cc3fb",
3172
- "reference": "89a319440651f2867f282339c2223cfe5e9cc3fb",
3173
- "shasum": ""
3174
- },
3175
- "require-dev": {
3176
- "behat/behat": "~2.5",
3177
- "wp-cli/wp-cli": "^1.5"
3178
- },
3179
- "type": "wp-cli-package",
3180
- "extra": {
3181
- "branch-alias": {
3182
- "dev-master": "1.x-dev"
3183
- },
3184
- "bundled": true,
3185
- "commands": [
3186
- "core verify-checksums",
3187
- "plugin verify-checksums"
3188
- ]
3189
- },
3190
- "autoload": {
3191
- "psr-4": {
3192
- "": "src/"
3193
- },
3194
- "files": [
3195
- "checksum-command.php"
3196
- ]
3197
- },
3198
- "notification-url": "https://packagist.org/downloads/",
3199
- "license": [
3200
- "MIT"
3201
- ],
3202
- "authors": [
3203
- {
3204
- "name": "Daniel Bachhuber",
3205
- "email": "daniel@runcommand.io",
3206
- "homepage": "https://runcommand.io"
3207
- }
3208
- ],
3209
- "description": "Verifies file integrity by comparing to published checksums.",
3210
- "homepage": "https://github.com/wp-cli/checksum-command",
3211
- "time": "2018-04-20T07:47:27+00:00"
3212
- },
3213
- {
3214
- "name": "wp-cli/config-command",
3215
- "version": "v1.2.0",
3216
- "source": {
3217
- "type": "git",
3218
- "url": "https://github.com/wp-cli/config-command.git",
3219
- "reference": "7bec9b4685b4022ab511630422dd6acccadfca9b"
3220
- },
3221
- "dist": {
3222
- "type": "zip",
3223
- "url": "https://api.github.com/repos/wp-cli/config-command/zipball/7bec9b4685b4022ab511630422dd6acccadfca9b",
3224
- "reference": "7bec9b4685b4022ab511630422dd6acccadfca9b",
3225
- "shasum": ""
3226
- },
3227
- "require": {
3228
- "wp-cli/wp-config-transformer": "^1.2.1"
3229
- },
3230
- "require-dev": {
3231
- "behat/behat": "~2.5",
3232
- "wp-cli/wp-cli": "*"
3233
- },
3234
- "type": "wp-cli-package",
3235
- "extra": {
3236
- "branch-alias": {
3237
- "dev-master": "1.x-dev"
3238
- },
3239
- "bundled": true,
3240
- "commands": [
3241
- "config",
3242
- "config edit",
3243
- "config delete",
3244
- "config create",
3245
- "config get",
3246
- "config has",
3247
- "config list",
3248
- "config path",
3249
- "config set"
3250
- ]
3251
- },
3252
- "autoload": {
3253
- "psr-4": {
3254
- "": "src/"
3255
- },
3256
- "files": [
3257
- "config-command.php"
3258
- ]
3259
- },
3260
- "notification-url": "https://packagist.org/downloads/",
3261
- "license": [
3262
- "MIT"
3263
- ],
3264
- "authors": [
3265
- {
3266
- "name": "Daniel Bachhuber",
3267
- "email": "daniel@runcommand.io",
3268
- "homepage": "https://runcommand.io"
3269
- },
3270
- {
3271
- "name": "Alain Schlesser",
3272
- "email": "alain.schlesser@gmail.com",
3273
- "homepage": "https://www.alainschlesser.com"
3274
- }
3275
- ],
3276
- "description": "Generates and reads the wp-config.php file.",
3277
- "homepage": "https://github.com/wp-cli/config-command",
3278
- "time": "2018-04-20T08:03:51+00:00"
3279
- },
3280
- {
3281
- "name": "wp-cli/core-command",
3282
- "version": "v1.0.12",
3283
- "source": {
3284
- "type": "git",
3285
- "url": "https://github.com/wp-cli/core-command.git",
3286
- "reference": "b41913707029c5147b38810700e424ed5f5fe8e0"
3287
- },
3288
- "dist": {
3289
- "type": "zip",
3290
- "url": "https://api.github.com/repos/wp-cli/core-command/zipball/b41913707029c5147b38810700e424ed5f5fe8e0",
3291
- "reference": "b41913707029c5147b38810700e424ed5f5fe8e0",
3292
- "shasum": ""
3293
- },
3294
- "require-dev": {
3295
- "behat/behat": "~2.5",
3296
- "wp-cli/wp-cli": "*"
3297
- },
3298
- "type": "wp-cli-package",
3299
- "extra": {
3300
- "branch-alias": {
3301
- "dev-master": "1.x-dev"
3302
- },
3303
- "bundled": true,
3304
- "commands": [
3305
- "core",
3306
- "core check-update",
3307
- "core download",
3308
- "core install",
3309
- "core is-installed",
3310
- "core multisite-convert",
3311
- "core multisite-install",
3312
- "core update",
3313
- "core update-db",
3314
- "core version"
3315
- ]
3316
- },
3317
- "autoload": {
3318
- "psr-4": {
3319
- "": "src/"
3320
- },
3321
- "files": [
3322
- "core-command.php"
3323
- ]
3324
- },
3325
- "notification-url": "https://packagist.org/downloads/",
3326
- "license": [
3327
- "MIT"
3328
- ],
3329
- "authors": [
3330
- {
3331
- "name": "Daniel Bachhuber",
3332
- "email": "daniel@runcommand.io",
3333
- "homepage": "https://runcommand.io"
3334
- }
3335
- ],
3336
- "description": "Downloads, installs, updates, and manages a WordPress installation.",
3337
- "homepage": "https://github.com/wp-cli/core-command",
3338
- "time": "2018-07-25T15:55:02+00:00"
3339
- },
3340
- {
3341
- "name": "wp-cli/cron-command",
3342
- "version": "v1.0.5",
3343
- "source": {
3344
- "type": "git",
3345
- "url": "https://github.com/wp-cli/cron-command.git",
3346
- "reference": "9da7e36e8f9c14cb171a3c5204cba2865e0ed7ef"
3347
- },
3348
- "dist": {
3349
- "type": "zip",
3350
- "url": "https://api.github.com/repos/wp-cli/cron-command/zipball/9da7e36e8f9c14cb171a3c5204cba2865e0ed7ef",
3351
- "reference": "9da7e36e8f9c14cb171a3c5204cba2865e0ed7ef",
3352
- "shasum": ""
3353
- },
3354
- "require-dev": {
3355
- "behat/behat": "~2.5",
3356
- "wp-cli/wp-cli": "*"
3357
- },
3358
- "type": "wp-cli-package",
3359
- "extra": {
3360
- "branch-alias": {
3361
- "dev-master": "1.x-dev"
3362
- },
3363
- "bundled": true,
3364
- "commands": [
3365
- "cron",
3366
- "cron test",
3367
- "cron event",
3368
- "cron event delete",
3369
- "cron event list",
3370
- "cron event run",
3371
- "cron event schedule",
3372
- "cron schedule",
3373
- "cron schedule list"
3374
- ]
3375
- },
3376
- "autoload": {
3377
- "psr-4": {
3378
- "": "src/"
3379
- },
3380
- "files": [
3381
- "cron-command.php"
3382
- ]
3383
- },
3384
- "notification-url": "https://packagist.org/downloads/",
3385
- "license": [
3386
- "MIT"
3387
- ],
3388
- "authors": [
3389
- {
3390
- "name": "Daniel Bachhuber",
3391
- "email": "daniel@runcommand.io",
3392
- "homepage": "https://runcommand.io"
3393
- }
3394
- ],
3395
- "description": "Tests, runs, and deletes WP-Cron events; manages WP-Cron schedules.",
3396
- "homepage": "https://github.com/wp-cli/cron-command",
3397
- "time": "2017-12-08T15:09:54+00:00"
3398
- },
3399
- {
3400
- "name": "wp-cli/db-command",
3401
- "version": "v1.3.5",
3402
- "source": {
3403
- "type": "git",
3404
- "url": "https://github.com/wp-cli/db-command.git",
3405
- "reference": "c260be59d9ac4c0012b016405e17d0251137fb89"
3406
- },
3407
- "dist": {
3408
- "type": "zip",
3409
- "url": "https://api.github.com/repos/wp-cli/db-command/zipball/c260be59d9ac4c0012b016405e17d0251137fb89",
3410
- "reference": "c260be59d9ac4c0012b016405e17d0251137fb89",
3411
- "shasum": ""
3412
- },
3413
- "require-dev": {
3414
- "behat/behat": "~2.5",
3415
- "wp-cli/wp-cli": "^1.5"
3416
- },
3417
- "type": "wp-cli-package",
3418
- "extra": {
3419
- "branch-alias": {
3420
- "dev-master": "1.x-dev"
3421
- },
3422
- "bundled": true,
3423
- "commands": [
3424
- "db",
3425
- "db create",
3426
- "db drop",
3427
- "db reset",
3428
- "db check",
3429
- "db optimize",
3430
- "db prefix",
3431
- "db repair",
3432
- "db cli",
3433
- "db query",
3434
- "db export",
3435
- "db import",
3436
- "db search",
3437
- "db tables",
3438
- "db size",
3439
- "db columns"
3440
- ]
3441
- },
3442
- "autoload": {
3443
- "psr-4": {
3444
- "": "src/"
3445
- },
3446
- "files": [
3447
- "db-command.php"
3448
- ]
3449
- },
3450
- "notification-url": "https://packagist.org/downloads/",
3451
- "license": [
3452
- "MIT"
3453
- ],
3454
- "authors": [
3455
- {
3456
- "name": "Daniel Bachhuber",
3457
- "email": "daniel@runcommand.io",
3458
- "homepage": "https://runcommand.io"
3459
- }
3460
- ],
3461
- "description": "Performs basic database operations using credentials stored in wp-config.php.",
3462
- "homepage": "https://github.com/wp-cli/db-command",
3463
- "time": "2018-07-31T02:06:59+00:00"
3464
- },
3465
- {
3466
- "name": "wp-cli/embed-command",
3467
- "version": "v1.0.0",
3468
- "source": {
3469
- "type": "git",
3470
- "url": "https://github.com/wp-cli/embed-command.git",
3471
- "reference": "81319d4243a8dfe096389bf54cdc4fc3dec53497"
3472
- },
3473
- "dist": {
3474
- "type": "zip",
3475
- "url": "https://api.github.com/repos/wp-cli/embed-command/zipball/81319d4243a8dfe096389bf54cdc4fc3dec53497",
3476
- "reference": "81319d4243a8dfe096389bf54cdc4fc3dec53497",
3477
- "shasum": ""
3478
- },
3479
- "require-dev": {
3480
- "behat/behat": "~2.5",
3481
- "wp-cli/wp-cli": "^1.5"
3482
- },
3483
- "type": "wp-cli-package",
3484
- "extra": {
3485
- "branch-alias": {
3486
- "dev-master": "1.x-dev"
3487
- },
3488
- "bundled": true,
3489
- "commands": [
3490
- "embed",
3491
- "embed fetch",
3492
- "embed provider list",
3493
- "embed provider match",
3494
- "embed handler list",
3495
- "embed cache clear",
3496
- "embed cache find",
3497
- "embed cache trigger"
3498
- ]
3499
- },
3500
- "autoload": {
3501
- "psr-4": {
3502
- "WP_CLI\\Embeds\\": "src/"
3503
- },
3504
- "files": [
3505
- "embed-command.php"
3506
- ]
3507
- },
3508
- "notification-url": "https://packagist.org/downloads/",
3509
- "license": [
3510
- "MIT"
3511
- ],
3512
- "authors": [
3513
- {
3514
- "name": "Pascal Birchler",
3515
- "homepage": "https://pascalbirchler.com/"
3516
- }
3517
- ],
3518
- "description": "Inspects oEmbed providers, clears embed cache, and more.",
3519
- "homepage": "https://github.com/wp-cli/embed-command",
3520
- "time": "2018-01-22T21:26:48+00:00"
3521
- },
3522
- {
3523
- "name": "wp-cli/entity-command",
3524
- "version": "v1.3.1",
3525
- "source": {
3526
- "type": "git",
3527
- "url": "https://github.com/wp-cli/entity-command.git",
3528
- "reference": "7b000645684b6acbb1d55ab47b77eb08f35cd229"
3529
- },
3530
- "dist": {
3531
- "type": "zip",
3532
- "url": "https://api.github.com/repos/wp-cli/entity-command/zipball/7b000645684b6acbb1d55ab47b77eb08f35cd229",
3533
- "reference": "7b000645684b6acbb1d55ab47b77eb08f35cd229",
3534
- "shasum": ""
3535
- },
3536
- "require-dev": {
3537
- "behat/behat": "~2.5",
3538
- "phpunit/phpunit": "^4.8",
3539
- "wp-cli/wp-cli": "^1.5"
3540
- },
3541
- "type": "wp-cli-package",
3542
- "extra": {
3543
- "branch-alias": {
3544
- "dev-master": "1.x-dev"
3545
- },
3546
- "bundled": true,
3547
- "commands": [
3548
- "comment",
3549
- "comment approve",
3550
- "comment count",
3551
- "comment create",
3552
- "comment delete",
3553
- "comment exists",
3554
- "comment generate",
3555
- "comment get",
3556
- "comment list",
3557
- "comment meta",
3558
- "comment meta add",
3559
- "comment meta delete",
3560
- "comment meta get",
3561
- "comment meta list",
3562
- "comment meta patch",
3563
- "comment meta pluck",
3564
- "comment meta update",
3565
- "comment recount",
3566
- "comment spam",
3567
- "comment status",
3568
- "comment trash",
3569
- "comment unapprove",
3570
- "comment unspam",
3571
- "comment untrash",
3572
- "comment update",
3573
- "menu",
3574
- "menu create",
3575
- "menu delete",
3576
- "menu item",
3577
- "menu item add-custom",
3578
- "menu item add-post",
3579
- "menu item add-term",
3580
- "menu item delete",
3581
- "menu item list",
3582
- "menu item update",
3583
- "menu list",
3584
- "menu location",
3585
- "menu location assign",
3586
- "menu location list",
3587
- "menu location remove",
3588
- "network meta",
3589
- "network meta add",
3590
- "network meta delete",
3591
- "network meta get",
3592
- "network meta list",
3593
- "network meta patch",
3594
- "network meta pluck",
3595
- "network meta update",
3596
- "option",
3597
- "option add",
3598
- "option delete",
3599
- "option get",
3600
- "option list",
3601
- "option patch",
3602
- "option pluck",
3603
- "option update",
3604
- "post",
3605
- "post create",
3606
- "post delete",
3607
- "post edit",
3608
- "post generate",
3609
- "post get",
3610
- "post list",
3611
- "post meta",
3612
- "post meta add",
3613
- "post meta delete",
3614
- "post meta get",
3615
- "post meta list",
3616
- "post meta patch",
3617
- "post meta pluck",
3618
- "post meta update",
3619
- "post term",
3620
- "post term add",
3621
- "post term list",
3622
- "post term remove",
3623
- "post term set",
3624
- "post update",
3625
- "post-type",
3626
- "post-type get",
3627
- "post-type list",
3628
- "site",
3629
- "site activate",
3630
- "site archive",
3631
- "site create",
3632
- "site deactivate",
3633
- "site delete",
3634
- "site empty",
3635
- "site list",
3636
- "site mature",
3637
- "site option",
3638
- "site private",
3639
- "site public",
3640
- "site spam",
3641
- "site unarchive",
3642
- "site unmature",
3643
- "site unspam",
3644
- "taxonomy",
3645
- "taxonomy get",
3646
- "taxonomy list",
3647
- "term",
3648
- "term create",
3649
- "term delete",
3650
- "term generate",
3651
- "term get",
3652
- "term list",
3653
- "term meta",
3654
- "term meta add",
3655
- "term meta delete",
3656
- "term meta get",
3657
- "term meta list",
3658
- "term meta patch",
3659
- "term meta pluck",
3660
- "term meta update",
3661
- "term recount",
3662
- "term update",
3663
- "user",
3664
- "user add-cap",
3665
- "user add-role",
3666
- "user create",
3667
- "user delete",
3668
- "user generate",
3669
- "user get",
3670
- "user import-csv",
3671
- "user list",
3672
- "user list-caps",
3673
- "user meta",
3674
- "user meta add",
3675
- "user meta delete",
3676
- "user meta get",
3677
- "user meta list",
3678
- "user meta patch",
3679
- "user meta pluck",
3680
- "user meta update",
3681
- "user remove-cap",
3682
- "user remove-role",
3683
- "user reset-password",
3684
- "user session",
3685
- "user session destroy",
3686
- "user session list",
3687
- "user set-role",
3688
- "user spam",
3689
- "user term",
3690
- "user term add",
3691
- "user term list",
3692
- "user term remove",
3693
- "user term set",
3694
- "user unspam",
3695
- "user update"
3696
- ]
3697
- },
3698
- "autoload": {
3699
- "psr-4": {
3700
- "": "src/",
3701
- "WP_CLI\\": "src/WP_CLI"
3702
- },
3703
- "files": [
3704
- "entity-command.php"
3705
- ]
3706
- },
3707
- "notification-url": "https://packagist.org/downloads/",
3708
- "license": [
3709
- "MIT"
3710
- ],
3711
- "authors": [
3712
- {
3713
- "name": "Daniel Bachhuber",
3714
- "email": "daniel@runcommand.io",
3715
- "homepage": "https://runcommand.io"
3716
- }
3717
- ],
3718
- "description": "Manage WordPress core entities.",
3719
- "homepage": "https://github.com/wp-cli/entity-command",
3720
- "time": "2018-07-13T12:21:06+00:00"
3721
- },
3722
- {
3723
- "name": "wp-cli/eval-command",
3724
- "version": "v1.0.5",
3725
- "source": {
3726
- "type": "git",
3727
- "url": "https://github.com/wp-cli/eval-command.git",
3728
- "reference": "9640d40ab28cd86590396f08f8c382e659f57321"
3729
- },
3730
- "dist": {
3731
- "type": "zip",
3732
- "url": "https://api.github.com/repos/wp-cli/eval-command/zipball/9640d40ab28cd86590396f08f8c382e659f57321",
3733
- "reference": "9640d40ab28cd86590396f08f8c382e659f57321",
3734
- "shasum": ""
3735
- },
3736
- "require": {
3737
- "wp-cli/wp-cli": "*"
3738
- },
3739
- "require-dev": {
3740
- "behat/behat": "~2.5"
3741
- },
3742
- "type": "wp-cli-package",
3743
- "extra": {
3744
- "branch-alias": {
3745
- "dev-master": "1.x-dev"
3746
- },
3747
- "bundled": true,
3748
- "commands": [
3749
- "eval",
3750
- "eval-file"
3751
- ]
3752
- },
3753
- "autoload": {
3754
- "psr-4": {
3755
- "": "src/"
3756
- },
3757
- "files": [
3758
- "eval-command.php"
3759
- ]
3760
- },
3761
- "notification-url": "https://packagist.org/downloads/",
3762
- "license": [
3763
- "MIT"
3764
- ],
3765
- "authors": [
3766
- {
3767
- "name": "Daniel Bachhuber",
3768
- "email": "daniel@runcommand.io",
3769
- "homepage": "https://runcommand.io"
3770
- }
3771
- ],
3772
- "description": "Executes arbitrary PHP code or files.",
3773
- "homepage": "https://github.com/wp-cli/eval-command",
3774
- "time": "2017-12-08T14:33:34+00:00"
3775
- },
3776
- {
3777
- "name": "wp-cli/export-command",
3778
- "version": "v1.0.7",
3779
- "source": {
3780
- "type": "git",
3781
- "url": "https://github.com/wp-cli/export-command.git",
3782
- "reference": "776d33ad6b2ac93c00fded27402ca8e188e7bff0"
3783
- },
3784
- "dist": {
3785
- "type": "zip",
3786
- "url": "https://api.github.com/repos/wp-cli/export-command/zipball/776d33ad6b2ac93c00fded27402ca8e188e7bff0",
3787
- "reference": "776d33ad6b2ac93c00fded27402ca8e188e7bff0",
3788
- "shasum": ""
3789
- },
3790
- "require": {
3791
- "nb/oxymel": "~0.1.0"
3792
- },
3793
- "require-dev": {
3794
- "behat/behat": "~2.5",
3795
- "wp-cli/wp-cli": "^1.5"
3796
- },
3797
- "type": "wp-cli-package",
3798
- "extra": {
3799
- "branch-alias": {
3800
- "dev-master": "1.x-dev"
3801
- },
3802
- "bundled": true,
3803
- "commands": [
3804
- "export"
3805
- ]
3806
- },
3807
- "autoload": {
3808
- "psr-4": {
3809
- "": "src/"
3810
- },
3811
- "files": [
3812
- "export-command.php"
3813
- ]
3814
- },
3815
- "notification-url": "https://packagist.org/downloads/",
3816
- "license": [
3817
- "MIT"
3818
- ],
3819
- "authors": [
3820
- {
3821
- "name": "Daniel Bachhuber",
3822
- "email": "daniel@runcommand.io",
3823
- "homepage": "https://runcommand.io"
3824
- }
3825
- ],
3826
- "description": "Exports WordPress content to a WXR file.",
3827
- "homepage": "https://github.com/wp-cli/export-command",
3828
- "time": "2018-04-20T08:10:47+00:00"
3829
- },
3830
- {
3831
- "name": "wp-cli/extension-command",
3832
- "version": "v1.2.2",
3833
- "source": {
3834
- "type": "git",
3835
- "url": "https://github.com/wp-cli/extension-command.git",
3836
- "reference": "18f1036bad42f481f178c2f4139039e9424b6e14"
3837
- },
3838
- "dist": {
3839
- "type": "zip",
3840
- "url": "https://api.github.com/repos/wp-cli/extension-command/zipball/18f1036bad42f481f178c2f4139039e9424b6e14",
3841
- "reference": "18f1036bad42f481f178c2f4139039e9424b6e14",
3842
- "shasum": ""
3843
- },
3844
- "require-dev": {
3845
- "behat/behat": "~2.5",
3846
- "wp-cli/wp-cli": "*"
3847
- },
3848
- "type": "wp-cli-package",
3849
- "extra": {
3850
- "branch-alias": {
3851
- "dev-master": "1.x-dev"
3852
- },
3853
- "bundled": true,
3854
- "commands": [
3855
- "plugin",
3856
- "plugin activate",
3857
- "plugin deactivate",
3858
- "plugin delete",
3859
- "plugin get",
3860
- "plugin install",
3861
- "plugin is-installed",
3862
- "plugin list",
3863
- "plugin path",
3864
- "plugin search",
3865
- "plugin status",
3866
- "plugin toggle",
3867
- "plugin uninstall",
3868
- "plugin update",
3869
- "theme",
3870
- "theme activate",
3871
- "theme delete",
3872
- "theme disable",
3873
- "theme enable",
3874
- "theme get",
3875
- "theme install",
3876
- "theme is-installed",
3877
- "theme list",
3878
- "theme mod",
3879
- "theme mod get",
3880
- "theme mod set",
3881
- "theme mod remove",
3882
- "theme path",
3883
- "theme search",
3884
- "theme status",
3885
- "theme update",
3886
- "theme mod list"
3887
- ]
3888
- },
3889
- "autoload": {
3890
- "psr-4": {
3891
- "": "src/"
3892
- },
3893
- "files": [
3894
- "extension-command.php"
3895
- ]
3896
- },
3897
- "notification-url": "https://packagist.org/downloads/",
3898
- "license": [
3899
- "MIT"
3900
- ],
3901
- "authors": [
3902
- {
3903
- "name": "Daniel Bachhuber",
3904
- "email": "daniel@runcommand.io",
3905
- "homepage": "https://runcommand.io"
3906
- }
3907
- ],
3908
- "description": "Manages plugins and themes, including installs, activations, and updates.",
3909
- "homepage": "https://github.com/wp-cli/extension-command",
3910
- "time": "2018-07-31T17:46:49+00:00"
3911
- },
3912
- {
3913
- "name": "wp-cli/import-command",
3914
- "version": "v1.0.7",
3915
- "source": {
3916
- "type": "git",
3917
- "url": "https://github.com/wp-cli/import-command.git",
3918
- "reference": "421fec5bd96671931f2119a89d28bae2f9edeb6b"
3919
- },
3920
- "dist": {
3921
- "type": "zip",
3922
- "url": "https://api.github.com/repos/wp-cli/import-command/zipball/421fec5bd96671931f2119a89d28bae2f9edeb6b",
3923
- "reference": "421fec5bd96671931f2119a89d28bae2f9edeb6b",
3924
- "shasum": ""
3925
- },
3926
- "require": {
3927
- "wp-cli/wp-cli": "*"
3928
- },
3929
- "require-dev": {
3930
- "behat/behat": "~2.5"
3931
- },
3932
- "type": "wp-cli-package",
3933
- "extra": {
3934
- "branch-alias": {
3935
- "dev-master": "1.x-dev"
3936
- },
3937
- "bundled": true,
3938
- "commands": [
3939
- "import"
3940
- ]
3941
- },
3942
- "autoload": {
3943
- "psr-4": {
3944
- "": "src/"
3945
- },
3946
- "files": [
3947
- "import-command.php"
3948
- ]
3949
- },
3950
- "notification-url": "https://packagist.org/downloads/",
3951
- "license": [
3952
- "MIT"
3953
- ],
3954
- "authors": [
3955
- {
3956
- "name": "Daniel Bachhuber",
3957
- "email": "daniel@runcommand.io",
3958
- "homepage": "https://runcommand.io"
3959
- }
3960
- ],
3961
- "description": "Imports content from a given WXR file.",
3962
- "homepage": "https://github.com/wp-cli/import-command",
3963
- "time": "2018-04-20T08:07:05+00:00"
3964
- },
3965
- {
3966
- "name": "wp-cli/language-command",
3967
- "version": "v1.0.6",
3968
- "source": {
3969
- "type": "git",
3970
- "url": "https://github.com/wp-cli/language-command.git",
3971
- "reference": "2a3d1ce5a722a4d70809619a065087aa933f6209"
3972
- },
3973
- "dist": {
3974
- "type": "zip",
3975
- "url": "https://api.github.com/repos/wp-cli/language-command/zipball/2a3d1ce5a722a4d70809619a065087aa933f6209",
3976
- "reference": "2a3d1ce5a722a4d70809619a065087aa933f6209",
3977
- "shasum": ""
3978
- },
3979
- "require-dev": {
3980
- "behat/behat": "~2.5",
3981
- "wp-cli/wp-cli": "*"
3982
- },
3983
- "type": "wp-cli-package",
3984
- "extra": {
3985
- "branch-alias": {
3986
- "dev-master": "1.x-dev"
3987
- },
3988
- "commands": [
3989
- "language",
3990
- "language core",
3991
- "language core activate",
3992
- "language core install",
3993
- "language core list",
3994
- "language core uninstall",
3995
- "language core update"
3996
- ],
3997
- "bundled": true
3998
- },
3999
- "autoload": {
4000
- "psr-4": {
4001
- "": "src/"
4002
- },
4003
- "files": [
4004
- "language-command.php"
4005
- ]
4006
- },
4007
- "notification-url": "https://packagist.org/downloads/",
4008
- "license": [
4009
- "MIT"
4010
- ],
4011
- "authors": [
4012
- {
4013
- "name": "Daniel Bachhuber",
4014
- "email": "daniel@runcommand.io",
4015
- "homepage": "https://runcommand.io"
4016
- }
4017
- ],
4018
- "description": "Installs, activates, and manages language packs.",
4019
- "homepage": "https://github.com/wp-cli/language-command",
4020
- "time": "2017-12-08T17:50:26+00:00"
4021
- },
4022
- {
4023
- "name": "wp-cli/media-command",
4024
- "version": "v1.1.4",
4025
- "source": {
4026
- "type": "git",
4027
- "url": "https://github.com/wp-cli/media-command.git",
4028
- "reference": "7f8664ba722505446b3ef3dbc6717e8e7f20265c"
4029
- },
4030
- "dist": {
4031
- "type": "zip",
4032
- "url": "https://api.github.com/repos/wp-cli/media-command/zipball/7f8664ba722505446b3ef3dbc6717e8e7f20265c",
4033
- "reference": "7f8664ba722505446b3ef3dbc6717e8e7f20265c",
4034
- "shasum": ""
4035
- },
4036
- "require-dev": {
4037
- "behat/behat": "~2.5",
4038
- "wp-cli/wp-cli": "^1.5"
4039
- },
4040
- "type": "wp-cli-package",
4041
- "extra": {
4042
- "branch-alias": {
4043
- "dev-master": "1.x-dev"
4044
- },
4045
- "bundled": true,
4046
- "commands": [
4047
- "media",
4048
- "media import",
4049
- "media regenerate",
4050
- "media image-size"
4051
- ]
4052
- },
4053
- "autoload": {
4054
- "psr-4": {
4055
- "": "src/"
4056
- },
4057
- "files": [
4058
- "media-command.php"
4059
- ]
4060
- },
4061
- "notification-url": "https://packagist.org/downloads/",
4062
- "license": [
4063
- "MIT"
4064
- ],
4065
- "authors": [
4066
- {
4067
- "name": "Daniel Bachhuber",
4068
- "email": "daniel@runcommand.io",
4069
- "homepage": "https://runcommand.io"
4070
- }
4071
- ],
4072
- "description": "Imports files as attachments, regenerates thumbnails, or lists registered image sizes.",
4073
- "homepage": "https://github.com/wp-cli/media-command",
4074
- "time": "2018-01-29T02:17:56+00:00"
4075
- },
4076
- {
4077
- "name": "wp-cli/mustangostang-spyc",
4078
- "version": "0.6.3",
4079
- "source": {
4080
- "type": "git",
4081
- "url": "https://github.com/wp-cli/spyc.git",
4082
- "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7"
4083
- },
4084
- "dist": {
4085
- "type": "zip",
4086
- "url": "https://api.github.com/repos/wp-cli/spyc/zipball/6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7",
4087
- "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7",
4088
- "shasum": ""
4089
- },
4090
- "require": {
4091
- "php": ">=5.3.1"
4092
- },
4093
- "require-dev": {
4094
- "phpunit/phpunit": "4.3.*@dev"
4095
- },
4096
- "type": "library",
4097
- "extra": {
4098
- "branch-alias": {
4099
- "dev-master": "0.5.x-dev"
4100
- }
4101
- },
4102
- "autoload": {
4103
- "psr-4": {
4104
- "Mustangostang\\": "src/"
4105
- },
4106
- "files": [
4107
- "includes/functions.php"
4108
- ]
4109
- },
4110
- "notification-url": "https://packagist.org/downloads/",
4111
- "license": [
4112
- "MIT"
4113
- ],
4114
- "authors": [
4115
- {
4116
- "name": "mustangostang",
4117
- "email": "vlad.andersen@gmail.com"
4118
- }
4119
- ],
4120
- "description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)",
4121
- "homepage": "https://github.com/mustangostang/spyc/",
4122
- "time": "2017-04-25T11:26:20+00:00"
4123
- },
4124
- {
4125
- "name": "wp-cli/package-command",
4126
- "version": "v1.0.14",
4127
- "source": {
4128
- "type": "git",
4129
- "url": "https://github.com/wp-cli/package-command.git",
4130
- "reference": "a7ce916de5e1d0c3d910d4fc8ca31928ee3775d3"
4131
- },
4132
- "dist": {
4133
- "type": "zip",
4134
- "url": "https://api.github.com/repos/wp-cli/package-command/zipball/a7ce916de5e1d0c3d910d4fc8ca31928ee3775d3",
4135
- "reference": "a7ce916de5e1d0c3d910d4fc8ca31928ee3775d3",
4136
- "shasum": ""
4137
- },
4138
- "require": {
4139
- "composer/composer": "^1.2.0"
4140
- },
4141
- "require-dev": {
4142
- "behat/behat": "~2.5",
4143
- "wp-cli/wp-cli": "^1.5"
4144
- },
4145
- "type": "wp-cli-package",
4146
- "extra": {
4147
- "branch-alias": {
4148
- "dev-master": "1.x-dev"
4149
- },
4150
- "bundled": true,
4151
- "commands": [
4152
- "package",
4153
- "package browse",
4154
- "package install",
4155
- "package list",
4156
- "package update",
4157
- "package uninstall"
4158
- ]
4159
- },
4160
- "autoload": {
4161
- "psr-4": {
4162
- "": "src/"
4163
- },
4164
- "files": [
4165
- "package-command.php"
4166
- ]
4167
- },
4168
- "notification-url": "https://packagist.org/downloads/",
4169
- "license": [
4170
- "MIT"
4171
- ],
4172
- "authors": [
4173
- {
4174
- "name": "Daniel Bachhuber",
4175
- "email": "daniel@runcommand.io",
4176
- "homepage": "https://runcommand.io"
4177
- }
4178
- ],
4179
- "description": "Lists, installs, and removes WP-CLI packages.",
4180
- "homepage": "https://github.com/wp-cli/package-command",
4181
- "time": "2018-05-28T11:40:24+00:00"
4182
- },
4183
- {
4184
- "name": "wp-cli/php-cli-tools",
4185
- "version": "v0.11.11",
4186
- "source": {
4187
- "type": "git",
4188
- "url": "https://github.com/wp-cli/php-cli-tools.git",
4189
- "reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f"
4190
- },
4191
- "dist": {
4192
- "type": "zip",
4193
- "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
4194
- "reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
4195
- "shasum": ""
4196
- },
4197
- "require": {
4198
- "php": ">= 5.3.0"
4199
- },
4200
- "type": "library",
4201
- "autoload": {
4202
- "psr-0": {
4203
- "cli": "lib/"
4204
- },
4205
- "files": [
4206
- "lib/cli/cli.php"
4207
- ]
4208
- },
4209
- "notification-url": "https://packagist.org/downloads/",
4210
- "license": [
4211
- "MIT"
4212
- ],
4213
- "authors": [
4214
- {
4215
- "name": "James Logsdon",
4216
- "email": "jlogsdon@php.net",
4217
- "role": "Developer"
4218
- },
4219
- {
4220
- "name": "Daniel Bachhuber",
4221
- "email": "daniel@handbuilt.co",
4222
- "role": "Maintainer"
4223
- }
4224
- ],
4225
- "description": "Console utilities for PHP",
4226
- "homepage": "http://github.com/wp-cli/php-cli-tools",
4227
- "keywords": [
4228
- "cli",
4229
- "console"
4230
- ],
4231
- "time": "2018-09-04T13:28:00+00:00"
4232
- },
4233
- {
4234
- "name": "wp-cli/rewrite-command",
4235
- "version": "v1.0.5",
4236
- "source": {
4237
- "type": "git",
4238
- "url": "https://github.com/wp-cli/rewrite-command.git",
4239
- "reference": "6b1695887e289ffad14c8f4ea86b5f1d92757408"
4240
- },
4241
- "dist": {
4242
- "type": "zip",
4243
- "url": "https://api.github.com/repos/wp-cli/rewrite-command/zipball/6b1695887e289ffad14c8f4ea86b5f1d92757408",
4244
- "reference": "6b1695887e289ffad14c8f4ea86b5f1d92757408",
4245
- "shasum": ""
4246
- },
4247
- "require-dev": {
4248
- "behat/behat": "~2.5",
4249
- "wp-cli/wp-cli": "*"
4250
- },
4251
- "type": "wp-cli-package",
4252
- "extra": {
4253
- "branch-alias": {
4254
- "dev-master": "1.x-dev"
4255
- },
4256
- "commands": [
4257
- "rewrite",
4258
- "rewrite flush",
4259
- "rewrite list",
4260
- "rewrite structure"
4261
- ],
4262
- "bundled": true
4263
- },
4264
- "autoload": {
4265
- "psr-4": {
4266
- "": "src/"
4267
- },
4268
- "files": [
4269
- "rewrite-command.php"
4270
- ]
4271
- },
4272
- "notification-url": "https://packagist.org/downloads/",
4273
- "license": [
4274
- "MIT"
4275
- ],
4276
- "authors": [
4277
- {
4278
- "name": "Daniel Bachhuber",
4279
- "email": "daniel@runcommand.io",
4280
- "homepage": "https://runcommand.io"
4281
- }
4282
- ],
4283
- "description": "Lists or flushes the site's rewrite rules, updates the permalink structure.",
4284
- "homepage": "https://github.com/wp-cli/rewrite-command",
4285
- "time": "2017-12-08T17:51:04+00:00"
4286
- },
4287
- {
4288
- "name": "wp-cli/role-command",
4289
- "version": "v1.1.0",
4290
- "source": {
4291
- "type": "git",
4292
- "url": "https://github.com/wp-cli/role-command.git",
4293
- "reference": "f50134ea9c27c108b1069cf044f7395c8f9bf716"
4294
- },
4295
- "dist": {
4296
- "type": "zip",
4297
- "url": "https://api.github.com/repos/wp-cli/role-command/zipball/f50134ea9c27c108b1069cf044f7395c8f9bf716",
4298
- "reference": "f50134ea9c27c108b1069cf044f7395c8f9bf716",
4299
- "shasum": ""
4300
- },
4301
- "require-dev": {
4302
- "behat/behat": "~2.5",
4303
- "wp-cli/wp-cli": "*"
4304
- },
4305
- "type": "wp-cli-package",
4306
- "extra": {
4307
- "branch-alias": {
4308
- "dev-master": "1.x-dev"
4309
- },
4310
- "commands": [
4311
- "role",
4312
- "role create",
4313
- "role delete",
4314
- "role exists",
4315
- "role list",
4316
- "role reset",
4317
- "cap",
4318
- "cap add",
4319
- "cap list",
4320
- "cap remove"
4321
- ],
4322
- "bundled": true
4323
- },
4324
- "autoload": {
4325
- "psr-4": {
4326
- "": "src/"
4327
- },
4328
- "files": [
4329
- "role-command.php"
4330
- ]
4331
- },
4332
- "notification-url": "https://packagist.org/downloads/",
4333
- "license": [
4334
- "MIT"
4335
- ],
4336
- "authors": [
4337
- {
4338
- "name": "Daniel Bachhuber",
4339
- "email": "daniel@runcommand.io",
4340
- "homepage": "https://runcommand.io"
4341
- }
4342
- ],
4343
- "description": "Adds, removes, lists, and resets roles and capabilities.",
4344
- "homepage": "https://github.com/wp-cli/role-command",
4345
- "time": "2018-04-20T08:05:51+00:00"
4346
- },
4347
- {
4348
- "name": "wp-cli/scaffold-command",
4349
- "version": "v1.2.0",
4350
- "source": {
4351
- "type": "git",
4352
- "url": "https://github.com/wp-cli/scaffold-command.git",
4353
- "reference": "a897a54ba0a8199743d90204ff773b302fc77572"
4354
- },
4355
- "dist": {
4356
- "type": "zip",
4357
- "url": "https://api.github.com/repos/wp-cli/scaffold-command/zipball/a897a54ba0a8199743d90204ff773b302fc77572",
4358
- "reference": "a897a54ba0a8199743d90204ff773b302fc77572",
4359
- "shasum": ""
4360
- },
4361
- "require-dev": {
4362
- "behat/behat": "~2.5",
4363
- "wp-cli/wp-cli": "^1.5"
4364
- },
4365
- "type": "wp-cli-package",
4366
- "extra": {
4367
- "branch-alias": {
4368
- "dev-master": "1.x-dev"
4369
- },
4370
- "bundled": true,
4371
- "commands": [
4372
- "scaffold",
4373
- "scaffold _s",
4374
- "scaffold block",
4375
- "scaffold child-theme",
4376
- "scaffold plugin",
4377
- "scaffold plugin-tests",
4378
- "scaffold post-type",
4379
- "scaffold taxonomy",
4380
- "scaffold theme-tests"
4381
- ]
4382
- },
4383
- "autoload": {
4384
- "psr-4": {
4385
- "": "src/"
4386
- },
4387
- "files": [
4388
- "scaffold-command.php"
4389
- ]
4390
- },
4391
- "notification-url": "https://packagist.org/downloads/",
4392
- "license": [
4393
- "MIT"
4394
- ],
4395
- "authors": [
4396
- {
4397
- "name": "Daniel Bachhuber",
4398
- "email": "daniel@runcommand.io",
4399
- "homepage": "https://runcommand.io"
4400
- }
4401
- ],
4402
- "description": "Generates code for post types, taxonomies, blocks, plugins, child themes, etc.",
4403
- "homepage": "https://github.com/wp-cli/scaffold-command",
4404
- "time": "2018-07-29T15:02:24+00:00"
4405
- },
4406
- {
4407
- "name": "wp-cli/search-replace-command",
4408
- "version": "v1.3.1",
4409
- "source": {
4410
- "type": "git",
4411
- "url": "https://github.com/wp-cli/search-replace-command.git",
4412
- "reference": "be21639dc530ad6506664baa813862d39b6d78ba"
4413
- },
4414
- "dist": {
4415
- "type": "zip",
4416
- "url": "https://api.github.com/repos/wp-cli/search-replace-command/zipball/be21639dc530ad6506664baa813862d39b6d78ba",
4417
- "reference": "be21639dc530ad6506664baa813862d39b6d78ba",
4418
- "shasum": ""
4419
- },
4420
- "require-dev": {
4421
- "behat/behat": "~2.5",
4422
- "wp-cli/wp-cli": "^1.5"
4423
- },
4424
- "type": "wp-cli-package",
4425
- "extra": {
4426
- "branch-alias": {
4427
- "dev-master": "1.x-dev"
4428
- },
4429
- "bundled": true,
4430
- "commands": [
4431
- "search-replace"
4432
- ]
4433
- },
4434
- "autoload": {
4435
- "psr-4": {
4436
- "": "src/"
4437
- },
4438
- "files": [
4439
- "search-replace-command.php"
4440
- ]
4441
- },
4442
- "notification-url": "https://packagist.org/downloads/",
4443
- "license": [
4444
- "MIT"
4445
- ],
4446
- "authors": [
4447
- {
4448
- "name": "Daniel Bachhuber",
4449
- "email": "daniel@runcommand.io",
4450
- "homepage": "https://runcommand.io"
4451
- }
4452
- ],
4453
- "description": "Searches/replaces strings in the database.",
4454
- "homepage": "https://github.com/wp-cli/search-replace-command",
4455
- "time": "2018-05-29T10:21:19+00:00"
4456
- },
4457
- {
4458
- "name": "wp-cli/server-command",
4459
- "version": "v1.0.9",
4460
- "source": {
4461
- "type": "git",
4462
- "url": "https://github.com/wp-cli/server-command.git",
4463
- "reference": "6192e6d7becd07e4c11a8f1560655c73a3b3526a"
4464
- },
4465
- "dist": {
4466
- "type": "zip",
4467
- "url": "https://api.github.com/repos/wp-cli/server-command/zipball/6192e6d7becd07e4c11a8f1560655c73a3b3526a",
4468
- "reference": "6192e6d7becd07e4c11a8f1560655c73a3b3526a",
4469
- "shasum": ""
4470
- },
4471
- "require": {
4472
- "wp-cli/wp-cli": "*"
4473
- },
4474
- "require-dev": {
4475
- "behat/behat": "~2.5"
4476
- },
4477
- "type": "wp-cli-package",
4478
- "extra": {
4479
- "branch-alias": {
4480
- "dev-master": "1.x-dev"
4481
- },
4482
- "commands": [
4483
- "server"
4484
- ],
4485
- "bundled": true
4486
- },
4487
- "autoload": {
4488
- "psr-4": {
4489
- "": "src/"
4490
- },
4491
- "files": [
4492
- "server-command.php"
4493
- ]
4494
- },
4495
- "notification-url": "https://packagist.org/downloads/",
4496
- "license": [
4497
- "MIT"
4498
- ],
4499
- "authors": [
4500
- {
4501
- "name": "Daniel Bachhuber",
4502
- "email": "daniel@runcommand.io",
4503
- "homepage": "https://runcommand.io"
4504
- }
4505
- ],
4506
- "description": "Launches PHP's built-in web server for a specific WordPress installation.",
4507
- "homepage": "https://github.com/wp-cli/server-command",
4508
- "time": "2017-12-14T20:06:24+00:00"
4509
- },
4510
- {
4511
- "name": "wp-cli/shell-command",
4512
- "version": "v1.0.5",
4513
- "source": {
4514
- "type": "git",
4515
- "url": "https://github.com/wp-cli/shell-command.git",
4516
- "reference": "507603a8994d984b6c4d5bd26e31ede6d9cce37e"
4517
- },
4518
- "dist": {
4519
- "type": "zip",
4520
- "url": "https://api.github.com/repos/wp-cli/shell-command/zipball/507603a8994d984b6c4d5bd26e31ede6d9cce37e",
4521
- "reference": "507603a8994d984b6c4d5bd26e31ede6d9cce37e",
4522
- "shasum": ""
4523
- },
4524
- "require": {
4525
- "wp-cli/wp-cli": "*"
4526
- },
4527
- "require-dev": {
4528
- "behat/behat": "~2.5"
4529
- },
4530
- "type": "wp-cli-package",
4531
- "extra": {
4532
- "branch-alias": {
4533
- "dev-master": "1.x-dev"
4534
- },
4535
- "commands": [
4536
- "shell"
4537
- ],
4538
- "bundled": true
4539
- },
4540
- "autoload": {
4541
- "psr-4": {
4542
- "": "src/",
4543
- "WP_CLI\\": "src/WP_CLI"
4544
- },
4545
- "files": [
4546
- "shell-command.php"
4547
- ]
4548
- },
4549
- "notification-url": "https://packagist.org/downloads/",
4550
- "license": [
4551
- "MIT"
4552
- ],
4553
- "authors": [
4554
- {
4555
- "name": "Daniel Bachhuber",
4556
- "email": "daniel@runcommand.io",
4557
- "homepage": "https://runcommand.io"
4558
- }
4559
- ],
4560
- "description": "Opens an interactive PHP console for running and testing PHP code.",
4561
- "homepage": "https://github.com/wp-cli/shell-command",
4562
- "time": "2017-12-08T16:03:53+00:00"
4563
- },
4564
- {
4565
- "name": "wp-cli/super-admin-command",
4566
- "version": "v1.0.6",
4567
- "source": {
4568
- "type": "git",
4569
- "url": "https://github.com/wp-cli/super-admin-command.git",
4570
- "reference": "2982d2e6514dbb318561d72d0577746a3a37181e"
4571
- },
4572
- "dist": {
4573
- "type": "zip",
4574
- "url": "https://api.github.com/repos/wp-cli/super-admin-command/zipball/2982d2e6514dbb318561d72d0577746a3a37181e",
4575
- "reference": "2982d2e6514dbb318561d72d0577746a3a37181e",
4576
- "shasum": ""
4577
- },
4578
- "require-dev": {
4579
- "behat/behat": "~2.5",
4580
- "wp-cli/wp-cli": "*"
4581
- },
4582
- "type": "wp-cli-package",
4583
- "extra": {
4584
- "branch-alias": {
4585
- "dev-master": "1.x-dev"
4586
- },
4587
- "commands": [
4588
- "super-admin",
4589
- "super-admin add",
4590
- "super-admin list",
4591
- "super-admin remove"
4592
- ],
4593
- "bundled": true
4594
- },
4595
- "autoload": {
4596
- "psr-4": {
4597
- "": "src/"
4598
- },
4599
- "files": [
4600
- "super-admin-command.php"
4601
- ]
4602
- },
4603
- "notification-url": "https://packagist.org/downloads/",
4604
- "license": [
4605
- "MIT"
4606
- ],
4607
- "authors": [
4608
- {
4609
- "name": "Daniel Bachhuber",
4610
- "email": "daniel@runcommand.io",
4611
- "homepage": "https://runcommand.io"
4612
- }
4613
- ],
4614
- "description": "Lists, adds, or removes super admin users on a multisite installation.",
4615
- "homepage": "https://github.com/wp-cli/super-admin-command",
4616
- "time": "2017-12-08T17:43:53+00:00"
4617
- },
4618
- {
4619
- "name": "wp-cli/widget-command",
4620
- "version": "v1.0.5",
4621
- "source": {
4622
- "type": "git",
4623
- "url": "https://github.com/wp-cli/widget-command.git",
4624
- "reference": "657e0f77d80c892f8f72f90a3a25112c254386df"
4625
- },
4626
- "dist": {
4627
- "type": "zip",
4628
- "url": "https://api.github.com/repos/wp-cli/widget-command/zipball/657e0f77d80c892f8f72f90a3a25112c254386df",
4629
- "reference": "657e0f77d80c892f8f72f90a3a25112c254386df",
4630
- "shasum": ""
4631
- },
4632
- "require-dev": {
4633
- "behat/behat": "~2.5",
4634
- "wp-cli/wp-cli": "*"
4635
- },
4636
- "type": "wp-cli-package",
4637
- "extra": {
4638
- "branch-alias": {
4639
- "dev-master": "1.x-dev"
4640
- },
4641
- "commands": [
4642
- "widget",
4643
- "widget add",
4644
- "widget deactivate",
4645
- "widget delete",
4646
- "widget list",
4647
- "widget move",
4648
- "widget reset",
4649
- "widget update",
4650
- "sidebar",
4651
- "sidebar list"
4652
- ],
4653
- "bundled": true
4654
- },
4655
- "autoload": {
4656
- "psr-4": {
4657
- "": "src/"
4658
- },
4659
- "files": [
4660
- "widget-command.php"
4661
- ]
4662
- },
4663
- "notification-url": "https://packagist.org/downloads/",
4664
- "license": [
4665
- "MIT"
4666
- ],
4667
- "authors": [
4668
- {
4669
- "name": "Daniel Bachhuber",
4670
- "email": "daniel@runcommand.io",
4671
- "homepage": "https://runcommand.io"
4672
- }
4673
- ],
4674
- "description": "Adds, moves, and removes widgets; lists sidebars.",
4675
- "homepage": "https://github.com/wp-cli/widget-command",
4676
- "time": "2017-12-08T17:45:57+00:00"
4677
- },
4678
- {
4679
- "name": "wp-cli/wp-cli",
4680
- "version": "v1.5.1",
4681
- "source": {
4682
- "type": "git",
4683
- "url": "https://github.com/wp-cli/wp-cli.git",
4684
- "reference": "3aac73bc4d629372531f3e15bbb67945d19b5d5a"
4685
- },
4686
- "dist": {
4687
- "type": "zip",
4688
- "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/3aac73bc4d629372531f3e15bbb67945d19b5d5a",
4689
- "reference": "3aac73bc4d629372531f3e15bbb67945d19b5d5a",
4690
- "shasum": ""
4691
- },
4692
- "require": {
4693
- "composer/composer": "^1.2.0",
4694
- "composer/semver": "~1.0",
4695
- "justinrainbow/json-schema": "~5.2.5",
4696
- "mustache/mustache": "~2.4",
4697
- "php": ">=5.3.29",
4698
- "ramsey/array_column": "~1.1",
4699
- "rmccue/requests": "~1.6",
4700
- "symfony/config": "^2.7|^3.0",
4701
- "symfony/console": "^2.7|^3.0",
4702
- "symfony/debug": "^2.7|^3.0",
4703
- "symfony/dependency-injection": "^2.7|^3.0",
4704
- "symfony/event-dispatcher": "^2.7|^3.0",
4705
- "symfony/filesystem": "^2.7|^3.0",
4706
- "symfony/finder": "^2.7|^3.0",
4707
- "symfony/process": "^2.1|^3.0",
4708
- "symfony/translation": "^2.7|^3.0",
4709
- "symfony/yaml": "^2.7|^3.0",
4710
- "wp-cli/autoload-splitter": "^0.1.5",
4711
- "wp-cli/cache-command": "^1.0",
4712
- "wp-cli/checksum-command": "^1.0",
4713
- "wp-cli/config-command": "^1.0",
4714
- "wp-cli/core-command": "^1.0",
4715
- "wp-cli/cron-command": "^1.0",
4716
- "wp-cli/db-command": "^1.0",
4717
- "wp-cli/embed-command": "^1.0",
4718
- "wp-cli/entity-command": "^1.0",
4719
- "wp-cli/eval-command": "^1.0",
4720
- "wp-cli/export-command": "^1.0",
4721
- "wp-cli/extension-command": "^1.0",
4722
- "wp-cli/import-command": "^1.0",
4723
- "wp-cli/language-command": "^1.0",
4724
- "wp-cli/media-command": "^1.0",
4725
- "wp-cli/mustangostang-spyc": "^0.6.3",
4726
- "wp-cli/package-command": "^1.0",
4727
- "wp-cli/php-cli-tools": "~0.11.2",
4728
- "wp-cli/rewrite-command": "^1.0",
4729
- "wp-cli/role-command": "^1.0",
4730
- "wp-cli/scaffold-command": "^1.0",
4731
- "wp-cli/search-replace-command": "^1.0",
4732
- "wp-cli/server-command": "^1.0",
4733
- "wp-cli/shell-command": "^1.0",
4734
- "wp-cli/super-admin-command": "^1.0",
4735
- "wp-cli/widget-command": "^1.0"
4736
- },
4737
- "require-dev": {
4738
- "behat/behat": "2.5.*",
4739
- "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3",
4740
- "phpunit/phpunit": "3.7.*",
4741
- "roave/security-advisories": "dev-master",
4742
- "wimg/php-compatibility": "^8.0",
4743
- "wp-coding-standards/wpcs": "^0.13.1"
4744
- },
4745
- "suggest": {
4746
- "psy/psysh": "Enhanced `wp shell` functionality"
4747
- },
4748
- "bin": [
4749
- "bin/wp.bat",
4750
- "bin/wp"
4751
- ],
4752
- "type": "library",
4753
- "extra": {
4754
- "branch-alias": {
4755
- "dev-master": "1.5.x-dev"
4756
- },
4757
- "autoload-splitter": {
4758
- "splitter-logic": "WP_CLI\\AutoloadSplitter",
4759
- "splitter-location": "php/WP_CLI/AutoloadSplitter.php",
4760
- "split-target-prefix-true": "autoload_commands",
4761
- "split-target-prefix-false": "autoload_framework"
4762
- }
4763
- },
4764
- "autoload": {
4765
- "psr-0": {
4766
- "WP_CLI": "php"
4767
- },
4768
- "psr-4": {
4769
- "": "php/commands/src"
4770
- }
4771
- },
4772
- "notification-url": "https://packagist.org/downloads/",
4773
- "license": [
4774
- "MIT"
4775
- ],
4776
- "description": "The command line interface for WordPress",
4777
- "homepage": "https://wp-cli.org",
4778
- "keywords": [
4779
- "cli",
4780
- "wordpress"
4781
- ],
4782
- "time": "2018-05-31T11:04:05+00:00"
4783
- },
4784
- {
4785
- "name": "wp-cli/wp-config-transformer",
4786
- "version": "v1.2.6",
4787
- "source": {
4788
- "type": "git",
4789
- "url": "https://github.com/wp-cli/wp-config-transformer.git",
4790
- "reference": "1ca98343443a8e4585865db5f50e8e6121fee70b"
4791
- },
4792
- "dist": {
4793
- "type": "zip",
4794
- "url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/1ca98343443a8e4585865db5f50e8e6121fee70b",
4795
- "reference": "1ca98343443a8e4585865db5f50e8e6121fee70b",
4796
- "shasum": ""
4797
- },
4798
- "require": {
4799
- "php": ">=5.3.29"
4800
- },
4801
- "require-dev": {
4802
- "composer/composer": "^1.5.6",
4803
- "phpunit/phpunit": "^6.5.5",
4804
- "wp-coding-standards/wpcs": "^0.14.0 || ^1.0.0 || ^2.0.0"
4805
- },
4806
- "type": "library",
4807
- "autoload": {
4808
- "files": [
4809
- "src/WPConfigTransformer.php"
4810
- ]
4811
- },
4812
- "notification-url": "https://packagist.org/downloads/",
4813
- "license": [
4814
- "MIT"
4815
- ],
4816
- "authors": [
4817
- {
4818
- "name": "Frankie Jarrett",
4819
- "email": "fjarrett@gmail.com"
4820
- }
4821
- ],
4822
- "description": "Programmatically edit a wp-config.php file.",
4823
- "time": "2019-07-23T17:24:43+00:00"
4824
- },
4825
- {
4826
- "name": "wp-coding-standards/wpcs",
4827
- "version": "2.1.1",
4828
- "source": {
4829
- "type": "git",
4830
- "url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
4831
- "reference": "bd9c33152115e6741e3510ff7189605b35167908"
4832
- },
4833
- "dist": {
4834
- "type": "zip",
4835
- "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/bd9c33152115e6741e3510ff7189605b35167908",
4836
- "reference": "bd9c33152115e6741e3510ff7189605b35167908",
4837
- "shasum": ""
4838
- },
4839
- "require": {
4840
- "php": ">=5.4",
4841
- "squizlabs/php_codesniffer": "^3.3.1"
4842
- },
4843
- "require-dev": {
4844
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
4845
- "phpcompatibility/php-compatibility": "^9.0",
4846
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
4847
- },
4848
- "suggest": {
4849
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
4850
- },
4851
- "type": "phpcodesniffer-standard",
4852
- "notification-url": "https://packagist.org/downloads/",
4853
- "license": [
4854
- "MIT"
4855
- ],
4856
- "authors": [
4857
- {
4858
- "name": "Contributors",
4859
- "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
4860
- }
4861
- ],
4862
- "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
4863
- "keywords": [
4864
- "phpcs",
4865
- "standards",
4866
- "wordpress"
4867
- ],
4868
- "time": "2019-05-21T02:50:00+00:00"
4869
- }
4870
- ],
4871
- "aliases": [],
4872
- "minimum-stability": "dev",
4873
- "stability-flags": [],
4874
- "prefer-stable": true,
4875
- "prefer-lowest": false,
4876
- "platform": [],
4877
- "platform-dev": []
4878
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/docs/_layouts/default.html CHANGED
@@ -21,13 +21,13 @@
21
  <body>
22
 
23
  <header>
24
- <a class="github-corner" href="https://github.com/woocommerce/action-scheduler/" aria-label="View on GitHub">
25
  <svg width="80" height="80" viewBox="0 0 250 250" style="fill:#b5e853; color:#151513; position: fixed; top: 0; border: 0; right: 0;" aria-hidden="true">
26
  <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
27
  </svg>
28
  </a>
29
  <div class="container">
30
- <p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a> | <a href="/version3-0/">Version 3.0</a>
31
  <h1><a href="/">action-scheduler</a></h1>
32
  <h2>A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.</h2>
33
  </div>
@@ -42,6 +42,9 @@
42
  <footer>
43
  <div class="container">
44
  <p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a>
 
 
 
45
  </div>
46
  </footer>
47
 
21
  <body>
22
 
23
  <header>
24
+ <a class="github-corner" href="https://github.com/Prospress/action-scheduler/" aria-label="View on GitHub">
25
  <svg width="80" height="80" viewBox="0 0 250 250" style="fill:#b5e853; color:#151513; position: fixed; top: 0; border: 0; right: 0;" aria-hidden="true">
26
  <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
27
  </svg>
28
  </a>
29
  <div class="container">
30
+ <p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a>
31
  <h1><a href="/">action-scheduler</a></h1>
32
  <h2>A scalable, traceable job queue for background processing large queues of tasks in WordPress. Designed for distribution in WordPress plugins - no server access required.</h2>
33
  </div>
42
  <footer>
43
  <div class="container">
44
  <p><a href="/usage/">Usage</a> | <a href="/admin/">Admin</a> | <a href="/wp-cli/">WP-CLI</a> | <a href="/perf/">Background Processing at Scale</a> | <a href="/api/">API</a> | <a href="/faq/">FAQ</a>
45
+ <p class="footer-image">
46
+ <a href="https://prospress.com"><img src="http://pic.pros.pr/eb8dcec9bd54/prospress-hacker-green-logo.png" width="120"></a>
47
+ </p>
48
  </div>
49
  </footer>
50
 
includes/vendor/action-scheduler/docs/android-chrome-192x192.png CHANGED
Binary file
includes/vendor/action-scheduler/docs/android-chrome-256x256.png CHANGED
Binary file
includes/vendor/action-scheduler/docs/api.md CHANGED
@@ -5,7 +5,7 @@ description: Reference guide for background processing functions provided by the
5
 
6
  Action Scheduler provides a range of functions for scheduling hooks to run at some time in the future on one or more occassions.
7
 
8
- To understand the scheduling functions, it can help to think of them as extensions to WordPress' `do_action()` function that add the ability to delay and repeat when the hook will be triggered.
9
 
10
  ## WP-Cron APIs vs. Action Scheduler APIs
11
 
@@ -13,45 +13,22 @@ The Action Scheduler API functions are designed to mirror the WordPress [WP-Cron
13
 
14
  Functions return similar values and accept similar arguments to their WP-Cron counterparts. The notable differences are:
15
 
16
- * `as_schedule_single_action()` & `as_schedule_recurring_action()` will return the ID of the scheduled action rather than boolean indicating whether the event was scheduled
17
  * `as_schedule_recurring_action()` takes an interval in seconds as the recurring interval rather than an arbitrary string
18
  * `as_schedule_single_action()` & `as_schedule_recurring_action()` can accept a `$group` parameter to group different actions for the one plugin together.
19
  * the `wp_` prefix is substituted with `as_` and the term `event` is replaced with `action`
20
 
21
  ## API Function Availability
22
 
23
- As mentioned in the [Usage - Load Order](/usage/#load-order) section, Action Scheduler will initialize itself on the `'init'` hook with priority `1`. While API functions are loaded prior to this and can be called, they should not be called until after `'init'` with priority `1`, because each component, like the data store, has not yet been initialized.
24
 
25
  Do not use Action Scheduler API functions prior to `'init'` hook with priority `1`. Doing so could lead to unexpected results, like data being stored in the incorrect location.
26
 
27
- ## Function Reference / `as_enqueue_async_action()`
28
-
29
- ### Description
30
-
31
- Enqueue an action to run one time, as soon as possible.
32
-
33
- ### Usage
34
-
35
- ```php
36
- as_enqueue_async_action( $hook, $args, $group )
37
- ````
38
-
39
- ### Parameters
40
-
41
- - **$hook** (string)(required) Name of the action hook. Default: _none_.
42
- - **$args** (array) Arguments to pass to callbacks when the hook triggers. Default: _`array()`_.
43
- - **$group** (array) The group to assign this job to. Default: _''_.
44
-
45
- ### Return value
46
-
47
- (integer) the action's ID.
48
-
49
-
50
  ## Function Reference / `as_schedule_single_action()`
51
 
52
  ### Description
53
 
54
- Schedule an action to run one time at some defined point in the future.
55
 
56
  ### Usage
57
 
@@ -68,7 +45,7 @@ as_schedule_single_action( $timestamp, $hook, $args, $group )
68
 
69
  ### Return value
70
 
71
- (integer) the action's ID.
72
 
73
 
74
  ## Function Reference / `as_schedule_recurring_action()`
@@ -93,7 +70,7 @@ as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args, $g
93
 
94
  ### Return value
95
 
96
- (integer) the action's ID.
97
 
98
 
99
  ## Function Reference / `as_schedule_cron_action()`
@@ -118,14 +95,14 @@ as_schedule_cron_action( $timestamp, $schedule, $hook, $args, $group )
118
 
119
  ### Return value
120
 
121
- (integer) the action's ID.
122
 
123
 
124
  ## Function Reference / `as_unschedule_action()`
125
 
126
  ### Description
127
 
128
- Cancel the next occurrence of a scheduled action.
129
 
130
  ### Usage
131
 
@@ -136,28 +113,6 @@ as_unschedule_action( $hook, $args, $group )
136
  ### Parameters
137
 
138
  - **$hook** (string)(required) Name of the action hook. Default: _none_.
139
- - **$args** (array) Arguments passed to callbacks when the hook triggers. Default: _`array()`_.
140
- - **$group** (array) The group job was assigned to. Default: _''_.
141
-
142
- ### Return value
143
-
144
- (null)
145
-
146
- ## Function Reference / `as_unschedule_all_actions()`
147
-
148
- ### Description
149
-
150
- Cancel all occurrences of a scheduled action.
151
-
152
- ### Usage
153
-
154
- ```php
155
- as_unschedule_action( $hook, $args, $group )
156
- ````
157
-
158
- ### Parameters
159
-
160
- - **$hook** (string)(required) Name of the action hook.
161
  - **$args** (array) Arguments to pass to callbacks when the hook triggers. Default: _`array()`_.
162
  - **$group** (array) The group to assign this job to. Default: _''_.
163
 
5
 
6
  Action Scheduler provides a range of functions for scheduling hooks to run at some time in the future on one or more occassions.
7
 
8
+ To understand the scheduling functoins, it can help to think of them as extensions to WordPress' `do_action()` function that add the ability to delay and repeat when the hook will be triggered.
9
 
10
  ## WP-Cron APIs vs. Action Scheduler APIs
11
 
13
 
14
  Functions return similar values and accept similar arguments to their WP-Cron counterparts. The notable differences are:
15
 
16
+ * `as_schedule_single_action()` & `as_schedule_recurring_action()` will return the post ID of the scheduled action rather than boolean indicating whether the event was scheduled
17
  * `as_schedule_recurring_action()` takes an interval in seconds as the recurring interval rather than an arbitrary string
18
  * `as_schedule_single_action()` & `as_schedule_recurring_action()` can accept a `$group` parameter to group different actions for the one plugin together.
19
  * the `wp_` prefix is substituted with `as_` and the term `event` is replaced with `action`
20
 
21
  ## API Function Availability
22
 
23
+ As mentioned in the [Usage - Load Order](/usage/#load-order) section, Action Scheduler will initialize itself on the `'init'` hook with priority `1`. While API functions are loaded prior to this and call be called, they should not be called until after `'init'` with priority `1`, because each component, like the data store, has not yet been initialized.
24
 
25
  Do not use Action Scheduler API functions prior to `'init'` hook with priority `1`. Doing so could lead to unexpected results, like data being stored in the incorrect location.
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  ## Function Reference / `as_schedule_single_action()`
28
 
29
  ### Description
30
 
31
+ Schedule an action to run one time.
32
 
33
  ### Usage
34
 
45
 
46
  ### Return value
47
 
48
+ (integer) the action's ID in the [posts](http://codex.wordpress.org/Database_Description#Table_Overview) table.
49
 
50
 
51
  ## Function Reference / `as_schedule_recurring_action()`
70
 
71
  ### Return value
72
 
73
+ (integer) the action's ID in the [posts](http://codex.wordpress.org/Database_Description#Table_Overview) table.
74
 
75
 
76
  ## Function Reference / `as_schedule_cron_action()`
95
 
96
  ### Return value
97
 
98
+ (integer) the action's ID in the [posts](http://codex.wordpress.org/Database_Description#Table_Overview) table.
99
 
100
 
101
  ## Function Reference / `as_unschedule_action()`
102
 
103
  ### Description
104
 
105
+ Cancel the next occurrence of a job.
106
 
107
  ### Usage
108
 
113
  ### Parameters
114
 
115
  - **$hook** (string)(required) Name of the action hook. Default: _none_.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  - **$args** (array) Arguments to pass to callbacks when the hook triggers. Default: _`array()`_.
117
  - **$group** (array) The group to assign this job to. Default: _''_.
118
 
includes/vendor/action-scheduler/docs/apple-touch-icon.png CHANGED
Binary file
includes/vendor/action-scheduler/docs/assets/css/style.scss CHANGED
@@ -35,7 +35,7 @@ footer {
35
  animation:octocat-wave 560ms ease-in-out
36
  }
37
 
38
- @keyframes octocat-wave {
39
  0%,100%{
40
  transform:rotate(0)
41
  }
@@ -51,7 +51,7 @@ footer {
51
  .github-corner:hover .octo-arm {
52
  animation:none
53
  }
54
- .github-corner .octo-arm {
55
  animation:octocat-wave 560ms ease-in-out
56
  }
57
  }
35
  animation:octocat-wave 560ms ease-in-out
36
  }
37
 
38
+ @keyframes octocat-wave{
39
  0%,100%{
40
  transform:rotate(0)
41
  }
51
  .github-corner:hover .octo-arm {
52
  animation:none
53
  }
54
+ .github-corner .octo-arm{
55
  animation:octocat-wave 560ms ease-in-out
56
  }
57
  }
includes/vendor/action-scheduler/docs/faq.md CHANGED
@@ -4,11 +4,11 @@
4
 
5
  Action Scheduler is designed to be used and released in plugins. It avoids redeclaring public API functions when more than one copy of the library is being loaded by different plugins. It will also load only the most recent version of itself (by checking registered versions after all plugins are loaded on the `'plugins_loaded'` hook).
6
 
7
- To use it in your plugin (or theme), simply require the `action-scheduler/action-scheduler.php` file. Action Scheduler will take care of the rest. __Note:__ Action Scheduler is only loaded from a theme if it is not included in any active plugins.
8
 
9
  ### I don't want to use WP-Cron. Does Action Scheduler depend on WP-Cron?
10
 
11
- By default, Action Scheduler is initiated by WP-Cron (and the `'shutdown'` hook on admin requests). However, it has no dependency on the WP-Cron system. You can initiate the Action Scheduler queue in other ways with just one or two lines of code.
12
 
13
  For example, you can start a queue directly by calling:
14
 
@@ -19,38 +19,30 @@ ActionScheduler::runner()->run();
19
  Or trigger the `'action_scheduler_run_queue'` hook and let Action Scheduler do it for you:
20
 
21
  ```php
22
- do_action( 'action_scheduler_run_queue', $context_identifier );
23
  ```
24
 
25
- Further customization can be done by extending the `ActionScheduler_Abstract_QueueRunner` class to create a custom Queue Runner. For an example of a customized queue runner, see the [`ActionScheduler_WPCLI_QueueRunner`](https://github.com/woocommerce/action-scheduler/blob/master/classes/ActionScheduler_WPCLI_QueueRunner.php), which is used when running WP CLI.
26
 
27
- Want to create some other method for initiating Action Scheduler? [Open a new issue](https://github.com/woocommerce/action-scheduler/issues/new), we'd love to help you with it.
28
 
29
  ### I don't want to use WP-Cron, ever. Does Action Scheduler replace WP-Cron?
30
 
31
  By default, Action Scheduler is designed to work alongside WP-Cron and not change any of its behaviour. This helps avoid unexpectedly overriding WP-Cron on sites installing your plugin, which may have nothing to do with WP-Cron.
32
 
33
- However, we can understand why you might want to replace WP-Cron completely in environments within your control, especially as it gets you the advantages of Action Scheduler. This should be possible without too much code.
34
 
35
  You could use the `'schedule_event'` hook in WordPress to use Action Scheduler for only newly scheduled WP-Cron jobs and map the `$event` param to Action Scheduler API functions.
36
 
37
  Alternatively, you can use a combination of the `'pre_update_option_cron'` and `'pre_option_cron'` hooks to override all new and previously scheduled WP-Cron jobs (similar to the way [Cavalcade](https://github.com/humanmade/Cavalcade) does it).
38
 
39
- If you'd like to create a plugin to do this automatically and want to share your work with others, [open a new issue to let us know](https://github.com/woocommerce/action-scheduler/issues/new), we'd love to help you with it.
40
 
41
- ### How does Action Scheduler store its data?
42
-
43
- Action Scheduler 3.0 and newer stores data in custom tables prefixed with `actionscheduler_`. For the list of all tables and their schemas, refer to the `ActionScheduler_StoreSchema` class.
44
-
45
- Prior to Action 3.0, actions were a custom post type, and data was stored in `wp_posts`, `wp_postmeta` and related tables.
46
-
47
- Action Scheduler 3+ migrates data from the custom post type to custom tables.
48
-
49
- ### Can I use a different storage scheme?
50
 
51
  Of course! Action Scheduler data storage is completely swappable, and always has been.
52
 
53
- If you choose to, you can actually store them anywhere, like in a remote storage service from Amazon Web Services.
54
 
55
  To implement a custom store:
56
 
@@ -64,9 +56,11 @@ function eg_define_custom_store( $existing_storage_class ) {
64
  add_filter( 'action_scheduler_store_class', 'eg_define_custom_store', 10, 1 );
65
  ```
66
 
67
- Take a look at the `classes/data-stores/ActionScheduler_DBStore.php` class for an example implementation of `ActionScheduler_Store`.
 
 
68
 
69
- If you'd like to create a plugin to do this automatically and release it publicly to help others, [open a new issue to let us know](https://github.com/woocommerce/action-scheduler/issues/new), we'd love to help you with it.
70
 
71
  ### Can I use a different storage scheme just for logging?
72
 
@@ -84,7 +78,7 @@ function eg_define_custom_logger( $existing_storage_class ) {
84
  add_filter( 'action_scheduler_logger_class', 'eg_define_custom_logger', 10, 1 );
85
  ```
86
 
87
- Take a look at the `classes/data-stores/ActionScheduler_DBLogger.php` class for an example implementation of `ActionScheduler_Logger`.
88
 
89
  ### I want to run Action Scheduler only on a dedicated application server in my cluster. Can I do that?
90
 
@@ -102,6 +96,6 @@ It requires no setup, and won't override any WordPress APIs (unless you want it
102
 
103
  ### How does Action Scheduler work on WordPress Multisite?
104
 
105
- Action Scheduler is designed to manage the scheduled actions on a single site. It has no special handling for running queues across multiple sites in a multisite network. That said, because its storage and Queue Runner are completely swappable, it would be possible to write multisite handling classes to use with it.
106
 
107
- If you'd like to create a multisite plugin to do this and release it publicly to help others, [open a new issue to let us know](https://github.com/woocommerce/action-scheduler/issues/new), we'd love to help you with it.
4
 
5
  Action Scheduler is designed to be used and released in plugins. It avoids redeclaring public API functions when more than one copy of the library is being loaded by different plugins. It will also load only the most recent version of itself (by checking registered versions after all plugins are loaded on the `'plugins_loaded'` hook).
6
 
7
+ To use it in your plugin, simply require the `action-scheduler/action-scheduler.php` file. Action Scheduler will take care of the rest.
8
 
9
  ### I don't want to use WP-Cron. Does Action Scheduler depend on WP-Cron?
10
 
11
+ By default, Action Scheduler is initiated by WP-Cron. However, it has no dependency on the WP-Cron system. You can initiate the Action Scheduler queue in other ways with just one or two lines of code.
12
 
13
  For example, you can start a queue directly by calling:
14
 
19
  Or trigger the `'action_scheduler_run_queue'` hook and let Action Scheduler do it for you:
20
 
21
  ```php
22
+ do_action( 'action_scheduler_run_queue' );
23
  ```
24
 
25
+ Further customization can be done by extending the `ActionScheduler_Abstract_QueueRunner` class to create a custom Queue Runner. For an example of a customized queue runner, see the [`ActionScheduler_WPCLI_QueueRunner`](https://github.com/Prospress/action-scheduler/blob/master/classes/ActionScheduler_WPCLI_QueueRunner.php), which is used when running WP CLI.
26
 
27
+ Want to create some other method for initiating Action Scheduler? [Open a new issue](https://github.com/Prospress/action-scheduler/issues/new), we'd love to help you with it.
28
 
29
  ### I don't want to use WP-Cron, ever. Does Action Scheduler replace WP-Cron?
30
 
31
  By default, Action Scheduler is designed to work alongside WP-Cron and not change any of its behaviour. This helps avoid unexpectedly overriding WP-Cron on sites installing your plugin, which may have nothing to do with WP-Cron.
32
 
33
+ However, we can understand why you might want to replace WP-Cron completely in environments within you control, especially as it gets you the advantages of Action Scheduler. This should be possible without too much code.
34
 
35
  You could use the `'schedule_event'` hook in WordPress to use Action Scheduler for only newly scheduled WP-Cron jobs and map the `$event` param to Action Scheduler API functions.
36
 
37
  Alternatively, you can use a combination of the `'pre_update_option_cron'` and `'pre_option_cron'` hooks to override all new and previously scheduled WP-Cron jobs (similar to the way [Cavalcade](https://github.com/humanmade/Cavalcade) does it).
38
 
39
+ If you'd like to create a plugin to do this automatically and want to share your work with others, [open a new issue to let us know](https://github.com/Prospress/action-scheduler/issues/new), we'd love to help you with it.
40
 
41
+ ### Eww gross, Custom Post Types! That's _so_ 2010. Can I use a different storage scheme?
 
 
 
 
 
 
 
 
42
 
43
  Of course! Action Scheduler data storage is completely swappable, and always has been.
44
 
45
+ You can store scheduled actions in custom tables in the WordPress site's database. Some sites using it already are. You can actually store them anywhere for that matter, like in a remote storage service from Amazon Web Services.
46
 
47
  To implement a custom store:
48
 
56
  add_filter( 'action_scheduler_store_class', 'eg_define_custom_store', 10, 1 );
57
  ```
58
 
59
+ Take a look at the `ActionScheduler_wpPostStore` class for an example implementation of `ActionScheduler_Store`.
60
+
61
+ If you'd like to create a plugin to do this automatically and release it publicly to help others, [open a new issue to let us know](https://github.com/Prospress/action-scheduler/issues/new), we'd love to help you with it.
62
 
63
+ > Note: we're also moving Action Scheduler itself to use [custom tables for better scalability](https://github.com/Prospress/action-scheduler/issues/77).
64
 
65
  ### Can I use a different storage scheme just for logging?
66
 
78
  add_filter( 'action_scheduler_logger_class', 'eg_define_custom_logger', 10, 1 );
79
  ```
80
 
81
+ Take a look at the `ActionScheduler_wpCommentLogger` class for an example implementation of `ActionScheduler_Logger`.
82
 
83
  ### I want to run Action Scheduler only on a dedicated application server in my cluster. Can I do that?
84
 
96
 
97
  ### How does Action Scheduler work on WordPress Multisite?
98
 
99
+ Action Scheduler is designed to manage the scheduled actions on a single site. It has no special handling for running queues across multiple sites in a multisite network. That said, because it's storage and Queue Runner are completely swappable, it would be possible to write multisite handling classes to use with it.
100
 
101
+ If you'd like to create a multisite plugin to do this and release it publicly to help others, [open a new issue to let us know](https://github.com/Prospress/action-scheduler/issues/new), we'd love to help you with it.
includes/vendor/action-scheduler/docs/favicon-16x16.png CHANGED
Binary file
includes/vendor/action-scheduler/docs/favicon-32x32.png CHANGED
Binary file
includes/vendor/action-scheduler/docs/favicon.ico CHANGED
Binary file
includes/vendor/action-scheduler/docs/index.md CHANGED
@@ -3,7 +3,7 @@ title: Action Scheduler - Background Processing Job Queue for WordPress
3
  ---
4
  ## WordPress Job Queue with Background Processing
5
 
6
- Action Scheduler is a library for triggering a WordPress hook to run at some time in the future (or as soon as possible, in the case of an async action). Each hook can be scheduled with unique data, to allow callbacks to perform operations on that data. The hook can also be scheduled to run on one or more occassions.
7
 
8
  Think of it like an extension to `do_action()` which adds the ability to delay and repeat a hook.
9
 
@@ -21,25 +21,25 @@ Action Scheduler is specifically designed for distribution in WordPress plugins
21
 
22
  ### How it Works
23
 
24
- Action Scheduler stores the hook name, arguments and scheduled date for an action that should be triggered at some time in the future.
25
 
26
- The scheduler will attempt to run every minute by attaching itself as a callback to the `'action_scheduler_run_schedule'` hook, which is scheduled using WordPress's built-in [WP-Cron](http://codex.wordpress.org/Function_Reference/wp_cron) system. Once per minute on, it will also check on the `'shutdown'` hook of WP Admin requests whether there are pending actions, and if there are, it will initiate a queue via an async loopback request.
27
 
28
- When triggered, Action Scheduler will check for scheduled actions that have a due date at or before this point in time i.e. actions scheduled to run now or at sometime in the past. Action scheduled to run asynchronously, i.e. not scheduled, have a zero date, meaning they will always be due no matter when the check occurs.
29
 
30
  ### Batch Processing Background Jobs
31
 
32
- If there are actions to be processed, Action Scheduler will stake a unique claim for a batch of 25 actions and begin processing that batch. The PHP process spawned to run the batch will then continue processing batches of 25 actions until it uses 90% of available memory or has been processing for 30 seconds.
33
 
34
- At that point, if there are additional actions to process, an asynchronous loopback request will be made to the site to continue processing actions in a new request.
35
 
36
- This process and the loopback requests will continue until all actions are processed.
37
 
38
  ### Housekeeping
39
 
40
- Before processing a batch, the scheduler will remove any existing claims on actions which have been sitting in a queue for more than five minutes (or more specifically, 10 times the allowed time limit, which defaults to 30 seconds).
41
 
42
- Action Scheduler will also trash any actions which were completed or canceled more than a month ago.
43
 
44
  If an action runs for more than 5 minutes, Action Scheduler will assume the action has timed out and will mark it as failed. However, if all callbacks attached to the action were to successfully complete sometime after that 5 minute timeout, its status would later be updated to completed.
45
 
@@ -49,11 +49,11 @@ Did your background job run?
49
 
50
  Never be left wondering with Action Scheduler's built-in record keeping.
51
 
52
- All events for each action are logged in the `actionscheduler_logs` table and displayed in the [administration interface](/admin/).
53
 
54
  The events logged by default include when an action:
55
  * is created
56
- * starts (including details of how it was run, e.g. via [WP CLI](/wp-cli/) or WP Cron)
57
  * completes
58
  * fails
59
 
@@ -63,6 +63,6 @@ Actions can also be grouped together using a custom taxonomy named `action-group
63
 
64
  ## Credits
65
 
66
- Action Scheduler is developed and maintained by folks at [Automattic](http://automattic.com/) with significant early development completed by [Flightless](https://flightless.us/).
67
 
68
- Collaboration is cool. We'd love to work with you to improve Action Scheduler. [Pull Requests](https://github.com/woocommerce/action-scheduler/pulls) welcome.
3
  ---
4
  ## WordPress Job Queue with Background Processing
5
 
6
+ Action Scheduler is a library for triggering a WordPress hook to run at some time in the future. Each hook can be scheduled with unique data, to allow callbacks to perform operations on that data. The hook can also be scheduled to run on one or more occassions.
7
 
8
  Think of it like an extension to `do_action()` which adds the ability to delay and repeat a hook.
9
 
21
 
22
  ### How it Works
23
 
24
+ Action Scheduler uses a WordPress [custom post type](http://codex.wordpress.org/Post_Types), creatively named `scheduled-action`, to store the hook name, arguments and scheduled date for an action that should be triggered at some time in the future.
25
 
26
+ The scheduler will attempt to run every minute by attaching itself as a callback to the `'action_scheduler_run_schedule'` hook, which is scheduled using WordPress's built-in [WP-Cron](http://codex.wordpress.org/Function_Reference/wp_cron) system.
27
 
28
+ When triggered, Action Scheduler will check for posts of the `scheduled-action` type that have a `post_date` at or before this point in time i.e. actions scheduled to run now or at sometime in the past.
29
 
30
  ### Batch Processing Background Jobs
31
 
32
+ If there are actions to be processed, Action Scheduler will stake a unique claim for a batch of 20 actions and begin processing that batch. The PHP process spawned to run the batch will then continue processing batches of 20 actions until it times out or exhausts available memory.
33
 
34
+ If your site has a large number of actions scheduled to run at the same time, Action Scheduler will process more than one batch at a time. Specifically, when the `'action_scheduler_run_schedule'` hook is triggered approximately one minute after the first batch began processing, a new PHP process will stake a new claim to a batch of actions which were not claimed by the previous process. It will then begin to process that batch.
35
 
36
+ This will continue until all actions are processed using a maximum of 5 concurrent queues.
37
 
38
  ### Housekeeping
39
 
40
+ Before processing a batch, the scheduler will remove any existing claims on actions which have been sitting in a queue for more than five minutes.
41
 
42
+ Action Scheduler will also trash any actions which were completed more than a month ago.
43
 
44
  If an action runs for more than 5 minutes, Action Scheduler will assume the action has timed out and will mark it as failed. However, if all callbacks attached to the action were to successfully complete sometime after that 5 minute timeout, its status would later be updated to completed.
45
 
49
 
50
  Never be left wondering with Action Scheduler's built-in record keeping.
51
 
52
+ All events for each action are logged in the [comments table](http://codex.wordpress.org/Database_Description#Table_Overview) and displayed in the [administration interface](/admin/).
53
 
54
  The events logged by default include when an action:
55
  * is created
56
+ * starts
57
  * completes
58
  * fails
59
 
63
 
64
  ## Credits
65
 
66
+ Developed and maintained by [Prospress](http://prospress.com/) in collaboration with [Flightless](https://flightless.us/).
67
 
68
+ Collaboration is cool. We'd love to work with you to improve Action Scheduler. [Pull Requests](https://github.com/prospress/action-scheduler/pulls) welcome.
includes/vendor/action-scheduler/docs/perf.md CHANGED
@@ -4,25 +4,24 @@ description: Learn how to do WordPress background processing at scale by tuning
4
  ---
5
  # Background Processing at Scale
6
 
7
- Action Scheduler's default processing is designed to work reliably across all different hosting environments. In order to achieve that, the default processing thresholds are more conservative than many servers could support.
8
 
9
- Specifically, Action Scheduler will only process actions in a request until:
10
 
11
  * 90% of available memory is used
12
  * processing another 3 actions would exceed 30 seconds of total request time, based on the average processing time for the current batch
13
- * in a single concurrent queue
14
 
15
- While Action Scheduler will initiate an asychronous loopback request to process additional actions, on sites with very large queues, this can result in slow processing times.
16
 
17
- While using [WP CLI to process queues](/wp-cli/) is the best approach to increasing processing speed, on occasion, that is not a viable option. In these cases, it's also possible to increase the processing thresholds in Action Scheduler to increase the rate at which actions are processed by the default queue runner.
18
 
19
  ## Increasing Time Limit
20
 
21
- By default, Action Scheduler will only process actions for a maximum of 30 seconds in each request. This time limit minimises the risk of a script timeout on unknown hosting environments, some of which enforce 30 second timeouts.
22
 
23
- If you know your host supports longer than this time limit for web requests, you can increase this time limit. This allows more actions to be processed in each request and reduces the lag between processing each queue, greatly speeding up the processing rate of scheduled actions.
24
 
25
- For example, the following snippet will increase the time limit to 2 minutes (120 seconds):
26
 
27
  ```php
28
  function eg_increase_time_limit( $time_limit ) {
@@ -39,7 +38,7 @@ Some of the known host time limits are:
39
 
40
  ## Increasing Batch Size
41
 
42
- By default, Action Scheduler will claim a batch of 25 actions. This small batch size is because the default time limit is only 30 seconds; however, if you know your actions are processing very quickly, e.g. taking microseconds not seconds, or that you have more than 30 second available to process each batch, increasing the batch size can slightly improve performance.
43
 
44
  This is because claiming a batch has some overhead, so the less often a batch needs to be claimed, the faster actions can be processed.
45
 
@@ -54,11 +53,11 @@ add_filter( 'action_scheduler_queue_runner_batch_size', 'eg_increase_action_sche
54
 
55
  ## Increasing Concurrent Batches
56
 
57
- By default, Action Scheduler will run only one concurrent batches of actions. This is to prevent consuming a lot of available connections or processes on your webserver.
58
 
59
- However, your server may allow a large number of connections, for example, because it has a high value for Apache's `MaxClients` setting or PHP-FPM's `pm.max_children` setting.
60
 
61
- If this is the case, you can use the `'action_scheduler_queue_runner_concurrent_batches'` filter to increase the number of concurrent batches allowed, and therefore speed up processing large numbers of actions scheduled to be processed simultaneously.
62
 
63
  For example, to increase the allowed number of concurrent queues to 10, we can use the following code:
64
 
@@ -69,19 +68,17 @@ function eg_increase_action_scheduler_concurrent_batches( $concurrent_batches )
69
  add_filter( 'action_scheduler_queue_runner_concurrent_batches', 'eg_increase_action_scheduler_concurrent_batches' );
70
  ```
71
 
72
- > WARNING: because of the async queue runner introduced in Action Scheduler 3.0 will continue asynchronous loopback requests to process actions, increasing the number of concurrent batches can substantially increase server load and take down a site. [WP CLI](/wp-cli/) is a better method to achieve higher throughput.
73
-
74
  ## Increasing Initialisation Rate of Runners
75
 
76
- By default, Action scheduler initiates at most one queue runner every time the `'action_scheduler_run_queue'` action is triggered by WP Cron.
77
 
78
- Because this action is only triggered at most once every minute, then there will rarely be more than one queue processing actions even if the concurrent runners is increased.
79
 
80
- To handle larger queues on more powerful servers, it's possible to initiate additional queue runners whenever the `'action_scheduler_run_queue'` action is run.
81
 
82
  That can be done by initiated additional secure requests to our server via loopback requests.
83
 
84
- The code below demonstrates how to create 5 loopback requests each time a queue begins:
85
 
86
  ```php
87
  /**
@@ -125,8 +122,6 @@ function eg_create_additional_runners() {
125
  add_action( 'wp_ajax_nopriv_eg_create_additional_runners', 'eg_create_additional_runners', 0 );
126
  ```
127
 
128
- > WARNING: because of the processing rate of scheduled actions, this kind of increase can very easily take down a site. Use only on high powered servers and be sure to test before attempting to use it in production.
129
-
130
  ## High Volume Plugin
131
 
132
- It's not necessary to add all of this code yourself, there is a handy plugin to get access to each of these increases - the [Action Scheduler - High Volume](https://github.com/woocommerce/action-scheduler-high-volume) plugin.
4
  ---
5
  # Background Processing at Scale
6
 
7
+ Action Scheduler's default processing is designed to work reliably across all different hosting environments. In order to achieve that, the default processing thresholds are very conservative.
8
 
9
+ Specifically, Action Scheduler will only process actions until:
10
 
11
  * 90% of available memory is used
12
  * processing another 3 actions would exceed 30 seconds of total request time, based on the average processing time for the current batch
 
13
 
14
+ On sites with large queues, this can result in very slow processing time.
15
 
16
+ While using [WP CLI to process queues](/wp-cli/) is the best approach to increasing processing speed, on occasion, that is not a viable option. In these cases, it's also possible to increase the processing thresholds in Action Scheduler to increase the rate at which actions are processed by the default WP Cron queue runner.
17
 
18
  ## Increasing Time Limit
19
 
20
+ By default, Action Scheduler will only process actions for a maximum of 30 seconds. This time limit minimises the risk of a script timeout on unknown hosting environments, some of which enforce 30 second timeouts.
21
 
22
+ If you know your host supports longer than this time limit for web requests, you can increase this time limit. This allows more actions to be processed in each request and reduces the lag between processing each queue, greating speeding up the processing rate of scheduled actions.
23
 
24
+ For example, the following snippet will increase the timelimit to 2 minutes (120 seconds):
25
 
26
  ```php
27
  function eg_increase_time_limit( $time_limit ) {
38
 
39
  ## Increasing Batch Size
40
 
41
+ By default, Action Scheduler will claim a batch of 25 actions. This small batch size is because the default time limit is only 30 seconds; however, if you know your actions are processing very quickly, e.g. taking microseconds not seconds, or that you have more than 30 second available to process each batch, increasing the batch size can improve performance.
42
 
43
  This is because claiming a batch has some overhead, so the less often a batch needs to be claimed, the faster actions can be processed.
44
 
53
 
54
  ## Increasing Concurrent Batches
55
 
56
+ By default, Action Scheduler will run up to 5 concurrent batches of actions. This is to prevent consuming all the available connections or processes on your webserver.
57
 
58
+ However, your server may allow a large number of connection, for example, because it has a high value for Apache's `MaxClients` setting or PHP-FPM's `pm.max_children` setting.
59
 
60
+ If this is the case, you can use the `'action_scheduler_queue_runner_concurrent_batches'` filter to increase the number of conncurrent batches allowed, and therefore speed up processing large numbers of actions scheduled to be processed simultaneously.
61
 
62
  For example, to increase the allowed number of concurrent queues to 10, we can use the following code:
63
 
68
  add_filter( 'action_scheduler_queue_runner_concurrent_batches', 'eg_increase_action_scheduler_concurrent_batches' );
69
  ```
70
 
 
 
71
  ## Increasing Initialisation Rate of Runners
72
 
73
+ By default, Action scheduler initiates at most, one queue runner every time the `'action_scheduler_run_queue'` action is triggered by WP Cron.
74
 
75
+ Because this action is only triggered at most once every minute, if a queue is only allowed to process for one minute, then there will never be more than one queue processing actions, greatly reducing the processing rate.
76
 
77
+ To handle larger queues on more powerful servers, it's a good idea to initiate additional queue runners whenever the `'action_scheduler_run_queue'` action is run.
78
 
79
  That can be done by initiated additional secure requests to our server via loopback requests.
80
 
81
+ The code below demonstrates how to create 5 loopback requests each time a queue begins
82
 
83
  ```php
84
  /**
122
  add_action( 'wp_ajax_nopriv_eg_create_additional_runners', 'eg_create_additional_runners', 0 );
123
  ```
124
 
 
 
125
  ## High Volume Plugin
126
 
127
+ It's not necessary to add all of this code yourself, the folks at [Prospress](https://prospress.com) have created a handy plugin to get access to each of these increases - the [Action Scheduler - High Volume](https://github.com/prospress/action-scheduler-high-volume) plugin.
includes/vendor/action-scheduler/docs/usage.md CHANGED
@@ -6,7 +6,7 @@ description: Learn how to use the Action Scheduler background processing job que
6
  Using Action Scheduler requires:
7
 
8
  1. installing the library
9
- 1. scheduling an action
10
  1. attaching a callback to that action
11
 
12
  ## Scheduling an Action
@@ -53,7 +53,7 @@ Action Scheduler includes the necessary file headers to be used as a standard Wo
53
 
54
  To install it as a plugin:
55
 
56
- 1. Download the .zip archive of the latest [stable release](https://github.com/woocommerce/action-scheduler/releases)
57
  1. Go to the **Plugins > Add New > Upload** administration screen on your WordPress site
58
  1. Select the archive file you just downloaded
59
  1. Click **Install Now**
@@ -77,7 +77,7 @@ To include Action Scheduler as a git subtree:
77
  #### Step 1. Add the Repository as a Remote
78
 
79
  ```
80
- git remote add -f subtree-action-scheduler https://github.com/woocommerce/action-scheduler.git
81
  ```
82
 
83
  Adding the subtree as a remote allows us to refer to it in short from via the name `subtree-action-scheduler`, instead of the full GitHub URL.
@@ -112,7 +112,7 @@ require_once( plugin_dir_path( __FILE__ ) . '/libraries/action-scheduler/action-
112
 
113
  There is no need to call any functions or do else to initialize Action Scheduler.
114
 
115
- When the `action-scheduler.php` file is included, Action Scheduler will register the version in that file and then load the most recent version of itself on the site. It will also load the most recent version of [all API functions](https://actionscheduler.org/api/).
116
 
117
  ### Load Order
118
 
@@ -121,7 +121,3 @@ Action Scheduler will register its version on `'plugins_loaded'` with priority `
121
  It is recommended to load it _when the file including it is included_. However, if you need to load it on a hook, then the hook must occur before `'plugins_loaded'`, or you can use `'plugins_loaded'` with negative priority, like `-10`.
122
 
123
  Action Scheduler will later initialize itself on `'init'` with priority `1`. Action Scheduler APIs should not be used until after `'init'` with priority `1`.
124
-
125
- ### Usage in Themes
126
-
127
- When using Action Scheduler in themes, it's important to note that if Action Scheduler has been registered by a plugin, then the latest version registered by a plugin will be used, rather than the version included in the theme. This is because of the version dependency handling code using `'plugins_loaded'` since version 1.0.
6
  Using Action Scheduler requires:
7
 
8
  1. installing the library
9
+ 1. scheduling and action
10
  1. attaching a callback to that action
11
 
12
  ## Scheduling an Action
53
 
54
  To install it as a plugin:
55
 
56
+ 1. Download the .zip archive of the latest [stable release](https://github.com/Prospress/action-scheduler/releases)
57
  1. Go to the **Plugins > Add New > Upload** administration screen on your WordPress site
58
  1. Select the archive file you just downloaded
59
  1. Click **Install Now**
77
  #### Step 1. Add the Repository as a Remote
78
 
79
  ```
80
+ git remote add -f subtree-action-scheduler https://github.com/Prospress/action-scheduler.git
81
  ```
82
 
83
  Adding the subtree as a remote allows us to refer to it in short from via the name `subtree-action-scheduler`, instead of the full GitHub URL.
112
 
113
  There is no need to call any functions or do else to initialize Action Scheduler.
114
 
115
+ When the `action-scheduler.php` file is included, Action Scheduler will register the version in that file and then load the most recent version of itself on the site. It will also load the most recent version of [all API functions](https://github.com/prospress/action-scheduler#api-functions).
116
 
117
  ### Load Order
118
 
121
  It is recommended to load it _when the file including it is included_. However, if you need to load it on a hook, then the hook must occur before `'plugins_loaded'`, or you can use `'plugins_loaded'` with negative priority, like `-10`.
122
 
123
  Action Scheduler will later initialize itself on `'init'` with priority `1`. Action Scheduler APIs should not be used until after `'init'` with priority `1`.
 
 
 
 
includes/vendor/action-scheduler/docs/version3-0.md DELETED
@@ -1,48 +0,0 @@
1
- ## Version 3.0 FAQ
2
-
3
- ### Do we need to wait for this to be bundled with WooCommerce?
4
-
5
- No. Action Scheduler can be run as a standalone plugin. Action Scheduler 3.0 is also part of WooCommerce Subscriptions 3.0, so when updating WooCommerce Subscriptions, Action Scheduler will also be updated.
6
-
7
- ### Can we safely switch to action scheduler version 3.0 and ditch the custom tables plugin?
8
-
9
- Yes! The Action Scheduler Custom Tables plugin code is now part of Action Scheduler itself (with a few improvements). We recommend disabling the Custom Tables plugin immediately after activating Action Scheduler 3.0, or a plugin containing Action Scheduler 3.0, like WooCommerce Subscriptions 3.0 and newer.
10
-
11
- ### How do we migrate from our own custom data store?
12
-
13
- By default, Action Scheduler will only initiate a migration from the internal `WPPostStore` data store. To enable migration from any custom datastore add the following filter `add_filter( 'action_scheduler_migrate_data_store', '__return_true' );`.
14
-
15
- ### I'm currently on PHP <5.5. When I update PHP will the migration start automatically?
16
-
17
- Yes! The migration is initiated as soon as all dependencies are met.
18
-
19
- ### I would like to update a plugin for testing that includes Action Scheduler 3.0 but would like to postpone the migration until that testing is complete. Is that possible?
20
-
21
- Yes, while we recommend migrating to custom tables as soon as possible for performance reasons, you can use `add_filter( 'action_scheduler_migration_dependencies_met', '__return_false' );` to prevent the migration from initiating.
22
-
23
- ### Is there a strong likelihood of migration issues with any of the above?
24
-
25
- There is always the possibilities of issues, but it is not a strong likelihood. We tested migrating from Action Scheduler 2.n with the custom data stores (including Action Scheduler Custom Tables plugin) active to Action Scheduler 3.0 on a number of test sites.
26
-
27
- As with all major, and minor, upgrades, we still testing the update on a staging site before updating the live site. We also recommending taking a backup before updating the live site.
28
-
29
- If you wish to undertake more comprehensive testing on a development or staging site before updating, or want to closely monitor the update on a live site, follow these steps:
30
-
31
- #### Stage 1: Prepare your site:
32
-
33
- 1. Take a backup of your database (AS 3.0 migrates data to custom tables, this can not be undone, you’ll need to restore a backup to downgrade).
34
- 1. Go to Tools > Action Scheduler
35
- 1. Take a screenshot of the action status counts at the top of the page. Example screenshot: https://cld.wthms.co/kwIqv7
36
-
37
-
38
- #### Stage 2: Install & Activate Action Scheduler 3.0 as a plugin
39
-
40
- 1. The migration will start almost immediately
41
- 1. Keep an eye on your error log
42
- 1. Report any notices, errors or other issues on GitHub
43
-
44
- #### Stage 3: Verify Migration
45
-
46
- 1. Go to Tools > Action Scheduler
47
- 1. Take a screenshot of the action status counts at the top of the page.
48
- 1. Verify the counts match the status counts taken in Stage 1 (the Completed counts could be higher because actions will have been completed to run the migration).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/docs/wp-cli.md CHANGED
@@ -13,7 +13,7 @@ For large sites, WP CLI is a much better choice for running queues of actions th
13
 
14
  With a regular web request, you may have to deal with script timeouts enforced by hosts, or other restraints that make it more challenging to run Action Scheduler tasks. Utilizing WP CLI to run commands directly on the server give you more freedom. This means that you typically don't have the same constraints of a normal web request.
15
 
16
- If you choose to utilize WP CLI exclusively, you can disable the normal WP CLI queue runner by installing the [Action Scheduler - Disable Default Queue Runner](https://github.com/woocommerce/action-scheduler-disable-default-runner) plugin. Note that if you do this, you **must** run Action Scheduler via WP CLI or another method, otherwise no scheduled actions will be processed.
17
 
18
  ## Commands
19
 
13
 
14
  With a regular web request, you may have to deal with script timeouts enforced by hosts, or other restraints that make it more challenging to run Action Scheduler tasks. Utilizing WP CLI to run commands directly on the server give you more freedom. This means that you typically don't have the same constraints of a normal web request.
15
 
16
+ If you choose to utilize WP CLI exclusively, you can disable the normal WP CLI queue runner by installing the [Action Scheduler - Disable Default Queue Runner](https://github.com/Prospress/action-scheduler-disable-default-runner) plugin. Note that if you do this, you **must** run Action Scheduler via WP CLI or another method, otherwise no scheduled actions will be processed.
17
 
18
  ## Commands
19
 
includes/vendor/action-scheduler/package-lock.json DELETED
@@ -1,2138 +0,0 @@
1
- {
2
- "name": "action-scheduler",
3
- "version": "3.0.0",
4
- "lockfileVersion": 1,
5
- "requires": true,
6
- "dependencies": {
7
- "@babel/code-frame": {
8
- "version": "7.5.5",
9
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
10
- "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
11
- "dev": true,
12
- "requires": {
13
- "@babel/highlight": "^7.0.0"
14
- }
15
- },
16
- "@babel/highlight": {
17
- "version": "7.5.0",
18
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
19
- "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
20
- "dev": true,
21
- "requires": {
22
- "chalk": "^2.0.0",
23
- "esutils": "^2.0.2",
24
- "js-tokens": "^4.0.0"
25
- }
26
- },
27
- "@nodelib/fs.scandir": {
28
- "version": "2.1.3",
29
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
30
- "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
31
- "dev": true,
32
- "requires": {
33
- "@nodelib/fs.stat": "2.0.3",
34
- "run-parallel": "^1.1.9"
35
- }
36
- },
37
- "@nodelib/fs.stat": {
38
- "version": "2.0.3",
39
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
40
- "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
41
- "dev": true
42
- },
43
- "@nodelib/fs.walk": {
44
- "version": "1.2.4",
45
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
46
- "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
47
- "dev": true,
48
- "requires": {
49
- "@nodelib/fs.scandir": "2.1.3",
50
- "fastq": "^1.6.0"
51
- }
52
- },
53
- "@samverschueren/stream-to-observable": {
54
- "version": "0.3.0",
55
- "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
56
- "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==",
57
- "dev": true,
58
- "requires": {
59
- "any-observable": "^0.3.0"
60
- }
61
- },
62
- "@types/events": {
63
- "version": "3.0.0",
64
- "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
65
- "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
66
- "dev": true
67
- },
68
- "@types/glob": {
69
- "version": "7.1.1",
70
- "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
71
- "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
72
- "dev": true,
73
- "requires": {
74
- "@types/events": "*",
75
- "@types/minimatch": "*",
76
- "@types/node": "*"
77
- }
78
- },
79
- "@types/minimatch": {
80
- "version": "3.0.3",
81
- "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
82
- "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
83
- "dev": true
84
- },
85
- "@types/node": {
86
- "version": "12.11.7",
87
- "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz",
88
- "integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==",
89
- "dev": true
90
- },
91
- "@types/normalize-package-data": {
92
- "version": "2.4.0",
93
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
94
- "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
95
- "dev": true
96
- },
97
- "abbrev": {
98
- "version": "1.1.1",
99
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
100
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
101
- "dev": true
102
- },
103
- "aggregate-error": {
104
- "version": "3.0.1",
105
- "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
106
- "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
107
- "dev": true,
108
- "requires": {
109
- "clean-stack": "^2.0.0",
110
- "indent-string": "^4.0.0"
111
- },
112
- "dependencies": {
113
- "indent-string": {
114
- "version": "4.0.0",
115
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
116
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
117
- "dev": true
118
- }
119
- }
120
- },
121
- "ansi-escapes": {
122
- "version": "3.2.0",
123
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
124
- "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
125
- "dev": true
126
- },
127
- "ansi-regex": {
128
- "version": "2.1.1",
129
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
130
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
131
- "dev": true
132
- },
133
- "ansi-styles": {
134
- "version": "3.2.1",
135
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
136
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
137
- "dev": true,
138
- "requires": {
139
- "color-convert": "^1.9.0"
140
- }
141
- },
142
- "any-observable": {
143
- "version": "0.3.0",
144
- "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
145
- "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
146
- "dev": true
147
- },
148
- "argparse": {
149
- "version": "1.0.10",
150
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
151
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
152
- "dev": true,
153
- "requires": {
154
- "sprintf-js": "~1.0.2"
155
- },
156
- "dependencies": {
157
- "sprintf-js": {
158
- "version": "1.0.3",
159
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
160
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
161
- "dev": true
162
- }
163
- }
164
- },
165
- "array-find-index": {
166
- "version": "1.0.2",
167
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
168
- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
169
- "dev": true
170
- },
171
- "array-union": {
172
- "version": "2.1.0",
173
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
174
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
175
- "dev": true
176
- },
177
- "async": {
178
- "version": "1.5.2",
179
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
180
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
181
- "dev": true
182
- },
183
- "balanced-match": {
184
- "version": "1.0.0",
185
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
186
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
187
- "dev": true
188
- },
189
- "brace-expansion": {
190
- "version": "1.1.11",
191
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
192
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
193
- "dev": true,
194
- "requires": {
195
- "balanced-match": "^1.0.0",
196
- "concat-map": "0.0.1"
197
- }
198
- },
199
- "braces": {
200
- "version": "3.0.2",
201
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
202
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
203
- "dev": true,
204
- "requires": {
205
- "fill-range": "^7.0.1"
206
- }
207
- },
208
- "caller-callsite": {
209
- "version": "2.0.0",
210
- "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
211
- "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
212
- "dev": true,
213
- "requires": {
214
- "callsites": "^2.0.0"
215
- }
216
- },
217
- "caller-path": {
218
- "version": "2.0.0",
219
- "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
220
- "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
221
- "dev": true,
222
- "requires": {
223
- "caller-callsite": "^2.0.0"
224
- }
225
- },
226
- "callsites": {
227
- "version": "2.0.0",
228
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
229
- "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
230
- "dev": true
231
- },
232
- "camelcase": {
233
- "version": "2.1.1",
234
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
235
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
236
- "dev": true
237
- },
238
- "camelcase-keys": {
239
- "version": "2.1.0",
240
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
241
- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
242
- "dev": true,
243
- "requires": {
244
- "camelcase": "^2.0.0",
245
- "map-obj": "^1.0.0"
246
- }
247
- },
248
- "chalk": {
249
- "version": "2.4.2",
250
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
251
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
252
- "dev": true,
253
- "requires": {
254
- "ansi-styles": "^3.2.1",
255
- "escape-string-regexp": "^1.0.5",
256
- "supports-color": "^5.3.0"
257
- }
258
- },
259
- "ci-info": {
260
- "version": "2.0.0",
261
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
262
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
263
- "dev": true
264
- },
265
- "clean-stack": {
266
- "version": "2.2.0",
267
- "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
268
- "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
269
- "dev": true
270
- },
271
- "cli-cursor": {
272
- "version": "2.1.0",
273
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
274
- "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
275
- "dev": true,
276
- "requires": {
277
- "restore-cursor": "^2.0.0"
278
- }
279
- },
280
- "cli-truncate": {
281
- "version": "0.2.1",
282
- "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
283
- "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
284
- "dev": true,
285
- "requires": {
286
- "slice-ansi": "0.0.4",
287
- "string-width": "^1.0.1"
288
- }
289
- },
290
- "code-point-at": {
291
- "version": "1.1.0",
292
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
293
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
294
- "dev": true
295
- },
296
- "coffeescript": {
297
- "version": "1.10.0",
298
- "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
299
- "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
300
- "dev": true
301
- },
302
- "color-convert": {
303
- "version": "1.9.3",
304
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
305
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
306
- "dev": true,
307
- "requires": {
308
- "color-name": "1.1.3"
309
- }
310
- },
311
- "color-name": {
312
- "version": "1.1.3",
313
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
314
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
315
- "dev": true
316
- },
317
- "colors": {
318
- "version": "1.1.2",
319
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
320
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
321
- "dev": true
322
- },
323
- "commander": {
324
- "version": "2.20.3",
325
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
326
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
327
- "dev": true
328
- },
329
- "concat-map": {
330
- "version": "0.0.1",
331
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
332
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
333
- "dev": true
334
- },
335
- "cosmiconfig": {
336
- "version": "5.2.1",
337
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
338
- "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
339
- "dev": true,
340
- "requires": {
341
- "import-fresh": "^2.0.0",
342
- "is-directory": "^0.3.1",
343
- "js-yaml": "^3.13.1",
344
- "parse-json": "^4.0.0"
345
- },
346
- "dependencies": {
347
- "parse-json": {
348
- "version": "4.0.0",
349
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
350
- "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
351
- "dev": true,
352
- "requires": {
353
- "error-ex": "^1.3.1",
354
- "json-parse-better-errors": "^1.0.1"
355
- }
356
- }
357
- }
358
- },
359
- "cross-spawn": {
360
- "version": "6.0.5",
361
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
362
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
363
- "dev": true,
364
- "requires": {
365
- "nice-try": "^1.0.4",
366
- "path-key": "^2.0.1",
367
- "semver": "^5.5.0",
368
- "shebang-command": "^1.2.0",
369
- "which": "^1.2.9"
370
- }
371
- },
372
- "currently-unhandled": {
373
- "version": "0.4.1",
374
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
375
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
376
- "dev": true,
377
- "requires": {
378
- "array-find-index": "^1.0.1"
379
- }
380
- },
381
- "date-fns": {
382
- "version": "1.30.1",
383
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
384
- "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
385
- "dev": true
386
- },
387
- "dateformat": {
388
- "version": "1.0.12",
389
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
390
- "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
391
- "dev": true,
392
- "requires": {
393
- "get-stdin": "^4.0.1",
394
- "meow": "^3.3.0"
395
- }
396
- },
397
- "debug": {
398
- "version": "4.1.1",
399
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
400
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
401
- "dev": true,
402
- "requires": {
403
- "ms": "^2.1.1"
404
- }
405
- },
406
- "decamelize": {
407
- "version": "1.2.0",
408
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
409
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
410
- "dev": true
411
- },
412
- "dedent": {
413
- "version": "0.7.0",
414
- "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
415
- "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
416
- "dev": true
417
- },
418
- "del": {
419
- "version": "5.1.0",
420
- "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
421
- "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
422
- "dev": true,
423
- "requires": {
424
- "globby": "^10.0.1",
425
- "graceful-fs": "^4.2.2",
426
- "is-glob": "^4.0.1",
427
- "is-path-cwd": "^2.2.0",
428
- "is-path-inside": "^3.0.1",
429
- "p-map": "^3.0.0",
430
- "rimraf": "^3.0.0",
431
- "slash": "^3.0.0"
432
- },
433
- "dependencies": {
434
- "glob": {
435
- "version": "7.1.5",
436
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
437
- "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
438
- "dev": true,
439
- "requires": {
440
- "fs.realpath": "^1.0.0",
441
- "inflight": "^1.0.4",
442
- "inherits": "2",
443
- "minimatch": "^3.0.4",
444
- "once": "^1.3.0",
445
- "path-is-absolute": "^1.0.0"
446
- }
447
- },
448
- "rimraf": {
449
- "version": "3.0.0",
450
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
451
- "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
452
- "dev": true,
453
- "requires": {
454
- "glob": "^7.1.3"
455
- }
456
- }
457
- }
458
- },
459
- "dir-glob": {
460
- "version": "3.0.1",
461
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
462
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
463
- "dev": true,
464
- "requires": {
465
- "path-type": "^4.0.0"
466
- },
467
- "dependencies": {
468
- "path-type": {
469
- "version": "4.0.0",
470
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
471
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
472
- "dev": true
473
- }
474
- }
475
- },
476
- "elegant-spinner": {
477
- "version": "1.0.1",
478
- "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
479
- "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
480
- "dev": true
481
- },
482
- "end-of-stream": {
483
- "version": "1.4.4",
484
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
485
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
486
- "dev": true,
487
- "requires": {
488
- "once": "^1.4.0"
489
- }
490
- },
491
- "error-ex": {
492
- "version": "1.3.2",
493
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
494
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
495
- "dev": true,
496
- "requires": {
497
- "is-arrayish": "^0.2.1"
498
- }
499
- },
500
- "escape-string-regexp": {
501
- "version": "1.0.5",
502
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
503
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
504
- "dev": true
505
- },
506
- "esprima": {
507
- "version": "4.0.1",
508
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
509
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
510
- "dev": true
511
- },
512
- "esutils": {
513
- "version": "2.0.3",
514
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
515
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
516
- "dev": true
517
- },
518
- "eventemitter2": {
519
- "version": "0.4.14",
520
- "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
521
- "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
522
- "dev": true
523
- },
524
- "execa": {
525
- "version": "1.0.0",
526
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
527
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
528
- "dev": true,
529
- "requires": {
530
- "cross-spawn": "^6.0.0",
531
- "get-stream": "^4.0.0",
532
- "is-stream": "^1.1.0",
533
- "npm-run-path": "^2.0.0",
534
- "p-finally": "^1.0.0",
535
- "signal-exit": "^3.0.0",
536
- "strip-eof": "^1.0.0"
537
- }
538
- },
539
- "exit": {
540
- "version": "0.1.2",
541
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
542
- "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
543
- "dev": true
544
- },
545
- "fast-glob": {
546
- "version": "3.1.0",
547
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz",
548
- "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==",
549
- "dev": true,
550
- "requires": {
551
- "@nodelib/fs.stat": "^2.0.2",
552
- "@nodelib/fs.walk": "^1.2.3",
553
- "glob-parent": "^5.1.0",
554
- "merge2": "^1.3.0",
555
- "micromatch": "^4.0.2"
556
- }
557
- },
558
- "fastq": {
559
- "version": "1.6.0",
560
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
561
- "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
562
- "dev": true,
563
- "requires": {
564
- "reusify": "^1.0.0"
565
- }
566
- },
567
- "figures": {
568
- "version": "1.7.0",
569
- "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
570
- "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
571
- "dev": true,
572
- "requires": {
573
- "escape-string-regexp": "^1.0.5",
574
- "object-assign": "^4.1.0"
575
- }
576
- },
577
- "fill-range": {
578
- "version": "7.0.1",
579
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
580
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
581
- "dev": true,
582
- "requires": {
583
- "to-regex-range": "^5.0.1"
584
- }
585
- },
586
- "find-up": {
587
- "version": "1.1.2",
588
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
589
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
590
- "dev": true,
591
- "requires": {
592
- "path-exists": "^2.0.0",
593
- "pinkie-promise": "^2.0.0"
594
- }
595
- },
596
- "findup-sync": {
597
- "version": "0.3.0",
598
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
599
- "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
600
- "dev": true,
601
- "requires": {
602
- "glob": "~5.0.0"
603
- },
604
- "dependencies": {
605
- "glob": {
606
- "version": "5.0.15",
607
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
608
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
609
- "dev": true,
610
- "requires": {
611
- "inflight": "^1.0.4",
612
- "inherits": "2",
613
- "minimatch": "2 || 3",
614
- "once": "^1.3.0",
615
- "path-is-absolute": "^1.0.0"
616
- }
617
- }
618
- }
619
- },
620
- "fs.realpath": {
621
- "version": "1.0.0",
622
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
623
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
624
- "dev": true
625
- },
626
- "get-own-enumerable-property-symbols": {
627
- "version": "3.0.1",
628
- "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz",
629
- "integrity": "sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA==",
630
- "dev": true
631
- },
632
- "get-stdin": {
633
- "version": "4.0.1",
634
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
635
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
636
- "dev": true
637
- },
638
- "get-stream": {
639
- "version": "4.1.0",
640
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
641
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
642
- "dev": true,
643
- "requires": {
644
- "pump": "^3.0.0"
645
- }
646
- },
647
- "getobject": {
648
- "version": "0.1.0",
649
- "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
650
- "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
651
- "dev": true
652
- },
653
- "glob": {
654
- "version": "7.0.6",
655
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
656
- "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
657
- "dev": true,
658
- "requires": {
659
- "fs.realpath": "^1.0.0",
660
- "inflight": "^1.0.4",
661
- "inherits": "2",
662
- "minimatch": "^3.0.2",
663
- "once": "^1.3.0",
664
- "path-is-absolute": "^1.0.0"
665
- }
666
- },
667
- "glob-parent": {
668
- "version": "5.1.0",
669
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
670
- "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
671
- "dev": true,
672
- "requires": {
673
- "is-glob": "^4.0.1"
674
- }
675
- },
676
- "globby": {
677
- "version": "10.0.1",
678
- "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
679
- "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
680
- "dev": true,
681
- "requires": {
682
- "@types/glob": "^7.1.1",
683
- "array-union": "^2.1.0",
684
- "dir-glob": "^3.0.1",
685
- "fast-glob": "^3.0.3",
686
- "glob": "^7.1.3",
687
- "ignore": "^5.1.1",
688
- "merge2": "^1.2.3",
689
- "slash": "^3.0.0"
690
- },
691
- "dependencies": {
692
- "glob": {
693
- "version": "7.1.5",
694
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
695
- "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
696
- "dev": true,
697
- "requires": {
698
- "fs.realpath": "^1.0.0",
699
- "inflight": "^1.0.4",
700
- "inherits": "2",
701
- "minimatch": "^3.0.4",
702
- "once": "^1.3.0",
703
- "path-is-absolute": "^1.0.0"
704
- }
705
- }
706
- }
707
- },
708
- "graceful-fs": {
709
- "version": "4.2.3",
710
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
711
- "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
712
- "dev": true
713
- },
714
- "grunt": {
715
- "version": "1.0.4",
716
- "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz",
717
- "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==",
718
- "dev": true,
719
- "requires": {
720
- "coffeescript": "~1.10.0",
721
- "dateformat": "~1.0.12",
722
- "eventemitter2": "~0.4.13",
723
- "exit": "~0.1.1",
724
- "findup-sync": "~0.3.0",
725
- "glob": "~7.0.0",
726
- "grunt-cli": "~1.2.0",
727
- "grunt-known-options": "~1.1.0",
728
- "grunt-legacy-log": "~2.0.0",
729
- "grunt-legacy-util": "~1.1.1",
730
- "iconv-lite": "~0.4.13",
731
- "js-yaml": "~3.13.0",
732
- "minimatch": "~3.0.2",
733
- "mkdirp": "~0.5.1",
734
- "nopt": "~3.0.6",
735
- "path-is-absolute": "~1.0.0",
736
- "rimraf": "~2.6.2"
737
- },
738
- "dependencies": {
739
- "grunt-cli": {
740
- "version": "1.2.0",
741
- "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
742
- "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
743
- "dev": true,
744
- "requires": {
745
- "findup-sync": "~0.3.0",
746
- "grunt-known-options": "~1.1.0",
747
- "nopt": "~3.0.6",
748
- "resolve": "~1.1.0"
749
- }
750
- },
751
- "resolve": {
752
- "version": "1.1.7",
753
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
754
- "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
755
- "dev": true
756
- }
757
- }
758
- },
759
- "grunt-checktextdomain": {
760
- "version": "1.0.1",
761
- "resolved": "https://registry.npmjs.org/grunt-checktextdomain/-/grunt-checktextdomain-1.0.1.tgz",
762
- "integrity": "sha1-slTQHh3pEwBdTbHFMD2QI7mD4Zs=",
763
- "dev": true,
764
- "requires": {
765
- "chalk": "~0.2.1",
766
- "text-table": "~0.2.0"
767
- },
768
- "dependencies": {
769
- "ansi-styles": {
770
- "version": "0.2.0",
771
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-0.2.0.tgz",
772
- "integrity": "sha1-NZq0sV3NZLptdHNLcsNjYKmvLBk=",
773
- "dev": true
774
- },
775
- "chalk": {
776
- "version": "0.2.1",
777
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.2.1.tgz",
778
- "integrity": "sha1-dhPhV1FFshOGSD9/SFql/6jL0Qw=",
779
- "dev": true,
780
- "requires": {
781
- "ansi-styles": "~0.2.0",
782
- "has-color": "~0.1.0"
783
- }
784
- }
785
- }
786
- },
787
- "grunt-known-options": {
788
- "version": "1.1.1",
789
- "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
790
- "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==",
791
- "dev": true
792
- },
793
- "grunt-legacy-log": {
794
- "version": "2.0.0",
795
- "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
796
- "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
797
- "dev": true,
798
- "requires": {
799
- "colors": "~1.1.2",
800
- "grunt-legacy-log-utils": "~2.0.0",
801
- "hooker": "~0.2.3",
802
- "lodash": "~4.17.5"
803
- }
804
- },
805
- "grunt-legacy-log-utils": {
806
- "version": "2.0.1",
807
- "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
808
- "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
809
- "dev": true,
810
- "requires": {
811
- "chalk": "~2.4.1",
812
- "lodash": "~4.17.10"
813
- }
814
- },
815
- "grunt-legacy-util": {
816
- "version": "1.1.1",
817
- "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
818
- "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
819
- "dev": true,
820
- "requires": {
821
- "async": "~1.5.2",
822
- "exit": "~0.1.1",
823
- "getobject": "~0.1.0",
824
- "hooker": "~0.2.3",
825
- "lodash": "~4.17.10",
826
- "underscore.string": "~3.3.4",
827
- "which": "~1.3.0"
828
- }
829
- },
830
- "grunt-phpcs": {
831
- "version": "0.4.0",
832
- "resolved": "https://registry.npmjs.org/grunt-phpcs/-/grunt-phpcs-0.4.0.tgz",
833
- "integrity": "sha1-oI1iX8ZEZeRTsr2T+BCyqB6Uvao=",
834
- "dev": true
835
- },
836
- "has-ansi": {
837
- "version": "2.0.0",
838
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
839
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
840
- "dev": true,
841
- "requires": {
842
- "ansi-regex": "^2.0.0"
843
- }
844
- },
845
- "has-color": {
846
- "version": "0.1.7",
847
- "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
848
- "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
849
- "dev": true
850
- },
851
- "has-flag": {
852
- "version": "3.0.0",
853
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
854
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
855
- "dev": true
856
- },
857
- "hooker": {
858
- "version": "0.2.3",
859
- "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
860
- "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
861
- "dev": true
862
- },
863
- "hosted-git-info": {
864
- "version": "2.8.5",
865
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
866
- "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==",
867
- "dev": true
868
- },
869
- "husky": {
870
- "version": "3.0.9",
871
- "resolved": "https://registry.npmjs.org/husky/-/husky-3.0.9.tgz",
872
- "integrity": "sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg==",
873
- "dev": true,
874
- "requires": {
875
- "chalk": "^2.4.2",
876
- "ci-info": "^2.0.0",
877
- "cosmiconfig": "^5.2.1",
878
- "execa": "^1.0.0",
879
- "get-stdin": "^7.0.0",
880
- "opencollective-postinstall": "^2.0.2",
881
- "pkg-dir": "^4.2.0",
882
- "please-upgrade-node": "^3.2.0",
883
- "read-pkg": "^5.2.0",
884
- "run-node": "^1.0.0",
885
- "slash": "^3.0.0"
886
- },
887
- "dependencies": {
888
- "get-stdin": {
889
- "version": "7.0.0",
890
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
891
- "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
892
- "dev": true
893
- },
894
- "parse-json": {
895
- "version": "5.0.0",
896
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
897
- "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
898
- "dev": true,
899
- "requires": {
900
- "@babel/code-frame": "^7.0.0",
901
- "error-ex": "^1.3.1",
902
- "json-parse-better-errors": "^1.0.1",
903
- "lines-and-columns": "^1.1.6"
904
- }
905
- },
906
- "read-pkg": {
907
- "version": "5.2.0",
908
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
909
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
910
- "dev": true,
911
- "requires": {
912
- "@types/normalize-package-data": "^2.4.0",
913
- "normalize-package-data": "^2.5.0",
914
- "parse-json": "^5.0.0",
915
- "type-fest": "^0.6.0"
916
- }
917
- }
918
- }
919
- },
920
- "iconv-lite": {
921
- "version": "0.4.24",
922
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
923
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
924
- "dev": true,
925
- "requires": {
926
- "safer-buffer": ">= 2.1.2 < 3"
927
- }
928
- },
929
- "ignore": {
930
- "version": "5.1.4",
931
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
932
- "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
933
- "dev": true
934
- },
935
- "import-fresh": {
936
- "version": "2.0.0",
937
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
938
- "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
939
- "dev": true,
940
- "requires": {
941
- "caller-path": "^2.0.0",
942
- "resolve-from": "^3.0.0"
943
- }
944
- },
945
- "indent-string": {
946
- "version": "2.1.0",
947
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
948
- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
949
- "dev": true,
950
- "requires": {
951
- "repeating": "^2.0.0"
952
- }
953
- },
954
- "inflight": {
955
- "version": "1.0.6",
956
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
957
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
958
- "dev": true,
959
- "requires": {
960
- "once": "^1.3.0",
961
- "wrappy": "1"
962
- }
963
- },
964
- "inherits": {
965
- "version": "2.0.4",
966
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
967
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
968
- "dev": true
969
- },
970
- "is-arrayish": {
971
- "version": "0.2.1",
972
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
973
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
974
- "dev": true
975
- },
976
- "is-directory": {
977
- "version": "0.3.1",
978
- "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
979
- "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
980
- "dev": true
981
- },
982
- "is-extglob": {
983
- "version": "2.1.1",
984
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
985
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
986
- "dev": true
987
- },
988
- "is-finite": {
989
- "version": "1.0.2",
990
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
991
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
992
- "dev": true,
993
- "requires": {
994
- "number-is-nan": "^1.0.0"
995
- }
996
- },
997
- "is-fullwidth-code-point": {
998
- "version": "1.0.0",
999
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
1000
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
1001
- "dev": true,
1002
- "requires": {
1003
- "number-is-nan": "^1.0.0"
1004
- }
1005
- },
1006
- "is-glob": {
1007
- "version": "4.0.1",
1008
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
1009
- "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
1010
- "dev": true,
1011
- "requires": {
1012
- "is-extglob": "^2.1.1"
1013
- }
1014
- },
1015
- "is-number": {
1016
- "version": "7.0.0",
1017
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1018
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1019
- "dev": true
1020
- },
1021
- "is-obj": {
1022
- "version": "1.0.1",
1023
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
1024
- "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
1025
- "dev": true
1026
- },
1027
- "is-observable": {
1028
- "version": "1.1.0",
1029
- "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
1030
- "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
1031
- "dev": true,
1032
- "requires": {
1033
- "symbol-observable": "^1.1.0"
1034
- }
1035
- },
1036
- "is-path-cwd": {
1037
- "version": "2.2.0",
1038
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
1039
- "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
1040
- "dev": true
1041
- },
1042
- "is-path-inside": {
1043
- "version": "3.0.2",
1044
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
1045
- "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
1046
- "dev": true
1047
- },
1048
- "is-promise": {
1049
- "version": "2.1.0",
1050
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
1051
- "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
1052
- "dev": true
1053
- },
1054
- "is-regexp": {
1055
- "version": "1.0.0",
1056
- "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
1057
- "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
1058
- "dev": true
1059
- },
1060
- "is-stream": {
1061
- "version": "1.1.0",
1062
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
1063
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
1064
- "dev": true
1065
- },
1066
- "is-utf8": {
1067
- "version": "0.2.1",
1068
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
1069
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
1070
- "dev": true
1071
- },
1072
- "isexe": {
1073
- "version": "2.0.0",
1074
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1075
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1076
- "dev": true
1077
- },
1078
- "js-tokens": {
1079
- "version": "4.0.0",
1080
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1081
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1082
- "dev": true
1083
- },
1084
- "js-yaml": {
1085
- "version": "3.13.1",
1086
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1087
- "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1088
- "dev": true,
1089
- "requires": {
1090
- "argparse": "^1.0.7",
1091
- "esprima": "^4.0.0"
1092
- }
1093
- },
1094
- "json-parse-better-errors": {
1095
- "version": "1.0.2",
1096
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
1097
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
1098
- "dev": true
1099
- },
1100
- "lines-and-columns": {
1101
- "version": "1.1.6",
1102
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
1103
- "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
1104
- "dev": true
1105
- },
1106
- "lint-staged": {
1107
- "version": "9.4.2",
1108
- "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.4.2.tgz",
1109
- "integrity": "sha512-OFyGokJSWTn2M6vngnlLXjaHhi8n83VIZZ5/1Z26SULRUWgR3ITWpAEQC9Pnm3MC/EpCxlwts/mQWDHNji2+zA==",
1110
- "dev": true,
1111
- "requires": {
1112
- "chalk": "^2.4.2",
1113
- "commander": "^2.20.0",
1114
- "cosmiconfig": "^5.2.1",
1115
- "debug": "^4.1.1",
1116
- "dedent": "^0.7.0",
1117
- "del": "^5.0.0",
1118
- "execa": "^2.0.3",
1119
- "listr": "^0.14.3",
1120
- "log-symbols": "^3.0.0",
1121
- "micromatch": "^4.0.2",
1122
- "normalize-path": "^3.0.0",
1123
- "please-upgrade-node": "^3.1.1",
1124
- "string-argv": "^0.3.0",
1125
- "stringify-object": "^3.3.0"
1126
- },
1127
- "dependencies": {
1128
- "cross-spawn": {
1129
- "version": "7.0.1",
1130
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
1131
- "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
1132
- "dev": true,
1133
- "requires": {
1134
- "path-key": "^3.1.0",
1135
- "shebang-command": "^2.0.0",
1136
- "which": "^2.0.1"
1137
- }
1138
- },
1139
- "execa": {
1140
- "version": "2.1.0",
1141
- "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
1142
- "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
1143
- "dev": true,
1144
- "requires": {
1145
- "cross-spawn": "^7.0.0",
1146
- "get-stream": "^5.0.0",
1147
- "is-stream": "^2.0.0",
1148
- "merge-stream": "^2.0.0",
1149
- "npm-run-path": "^3.0.0",
1150
- "onetime": "^5.1.0",
1151
- "p-finally": "^2.0.0",
1152
- "signal-exit": "^3.0.2",
1153
- "strip-final-newline": "^2.0.0"
1154
- }
1155
- },
1156
- "get-stream": {
1157
- "version": "5.1.0",
1158
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
1159
- "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
1160
- "dev": true,
1161
- "requires": {
1162
- "pump": "^3.0.0"
1163
- }
1164
- },
1165
- "is-stream": {
1166
- "version": "2.0.0",
1167
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
1168
- "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
1169
- "dev": true
1170
- },
1171
- "npm-run-path": {
1172
- "version": "3.1.0",
1173
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
1174
- "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
1175
- "dev": true,
1176
- "requires": {
1177
- "path-key": "^3.0.0"
1178
- }
1179
- },
1180
- "p-finally": {
1181
- "version": "2.0.1",
1182
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
1183
- "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
1184
- "dev": true
1185
- },
1186
- "path-key": {
1187
- "version": "3.1.0",
1188
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz",
1189
- "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==",
1190
- "dev": true
1191
- },
1192
- "shebang-command": {
1193
- "version": "2.0.0",
1194
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1195
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1196
- "dev": true,
1197
- "requires": {
1198
- "shebang-regex": "^3.0.0"
1199
- }
1200
- },
1201
- "shebang-regex": {
1202
- "version": "3.0.0",
1203
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1204
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1205
- "dev": true
1206
- },
1207
- "which": {
1208
- "version": "2.0.1",
1209
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz",
1210
- "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==",
1211
- "dev": true,
1212
- "requires": {
1213
- "isexe": "^2.0.0"
1214
- }
1215
- }
1216
- }
1217
- },
1218
- "listr": {
1219
- "version": "0.14.3",
1220
- "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
1221
- "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
1222
- "dev": true,
1223
- "requires": {
1224
- "@samverschueren/stream-to-observable": "^0.3.0",
1225
- "is-observable": "^1.1.0",
1226
- "is-promise": "^2.1.0",
1227
- "is-stream": "^1.1.0",
1228
- "listr-silent-renderer": "^1.1.1",
1229
- "listr-update-renderer": "^0.5.0",
1230
- "listr-verbose-renderer": "^0.5.0",
1231
- "p-map": "^2.0.0",
1232
- "rxjs": "^6.3.3"
1233
- },
1234
- "dependencies": {
1235
- "p-map": {
1236
- "version": "2.1.0",
1237
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
1238
- "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
1239
- "dev": true
1240
- }
1241
- }
1242
- },
1243
- "listr-silent-renderer": {
1244
- "version": "1.1.1",
1245
- "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
1246
- "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
1247
- "dev": true
1248
- },
1249
- "listr-update-renderer": {
1250
- "version": "0.5.0",
1251
- "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
1252
- "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
1253
- "dev": true,
1254
- "requires": {
1255
- "chalk": "^1.1.3",
1256
- "cli-truncate": "^0.2.1",
1257
- "elegant-spinner": "^1.0.1",
1258
- "figures": "^1.7.0",
1259
- "indent-string": "^3.0.0",
1260
- "log-symbols": "^1.0.2",
1261
- "log-update": "^2.3.0",
1262
- "strip-ansi": "^3.0.1"
1263
- },
1264
- "dependencies": {
1265
- "ansi-styles": {
1266
- "version": "2.2.1",
1267
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
1268
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
1269
- "dev": true
1270
- },
1271
- "chalk": {
1272
- "version": "1.1.3",
1273
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
1274
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
1275
- "dev": true,
1276
- "requires": {
1277
- "ansi-styles": "^2.2.1",
1278
- "escape-string-regexp": "^1.0.2",
1279
- "has-ansi": "^2.0.0",
1280
- "strip-ansi": "^3.0.0",
1281
- "supports-color": "^2.0.0"
1282
- }
1283
- },
1284
- "indent-string": {
1285
- "version": "3.2.0",
1286
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
1287
- "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
1288
- "dev": true
1289
- },
1290
- "log-symbols": {
1291
- "version": "1.0.2",
1292
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
1293
- "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
1294
- "dev": true,
1295
- "requires": {
1296
- "chalk": "^1.0.0"
1297
- }
1298
- },
1299
- "supports-color": {
1300
- "version": "2.0.0",
1301
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
1302
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
1303
- "dev": true
1304
- }
1305
- }
1306
- },
1307
- "listr-verbose-renderer": {
1308
- "version": "0.5.0",
1309
- "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
1310
- "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
1311
- "dev": true,
1312
- "requires": {
1313
- "chalk": "^2.4.1",
1314
- "cli-cursor": "^2.1.0",
1315
- "date-fns": "^1.27.2",
1316
- "figures": "^2.0.0"
1317
- },
1318
- "dependencies": {
1319
- "figures": {
1320
- "version": "2.0.0",
1321
- "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
1322
- "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
1323
- "dev": true,
1324
- "requires": {
1325
- "escape-string-regexp": "^1.0.5"
1326
- }
1327
- }
1328
- }
1329
- },
1330
- "load-json-file": {
1331
- "version": "1.1.0",
1332
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
1333
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
1334
- "dev": true,
1335
- "requires": {
1336
- "graceful-fs": "^4.1.2",
1337
- "parse-json": "^2.2.0",
1338
- "pify": "^2.0.0",
1339
- "pinkie-promise": "^2.0.0",
1340
- "strip-bom": "^2.0.0"
1341
- }
1342
- },
1343
- "locate-path": {
1344
- "version": "5.0.0",
1345
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1346
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1347
- "dev": true,
1348
- "requires": {
1349
- "p-locate": "^4.1.0"
1350
- }
1351
- },
1352
- "lodash": {
1353
- "version": "4.17.15",
1354
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
1355
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
1356
- "dev": true
1357
- },
1358
- "log-symbols": {
1359
- "version": "3.0.0",
1360
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
1361
- "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
1362
- "dev": true,
1363
- "requires": {
1364
- "chalk": "^2.4.2"
1365
- }
1366
- },
1367
- "log-update": {
1368
- "version": "2.3.0",
1369
- "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
1370
- "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
1371
- "dev": true,
1372
- "requires": {
1373
- "ansi-escapes": "^3.0.0",
1374
- "cli-cursor": "^2.0.0",
1375
- "wrap-ansi": "^3.0.1"
1376
- }
1377
- },
1378
- "loud-rejection": {
1379
- "version": "1.6.0",
1380
- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
1381
- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
1382
- "dev": true,
1383
- "requires": {
1384
- "currently-unhandled": "^0.4.1",
1385
- "signal-exit": "^3.0.0"
1386
- }
1387
- },
1388
- "map-obj": {
1389
- "version": "1.0.1",
1390
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
1391
- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
1392
- "dev": true
1393
- },
1394
- "meow": {
1395
- "version": "3.7.0",
1396
- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
1397
- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
1398
- "dev": true,
1399
- "requires": {
1400
- "camelcase-keys": "^2.0.0",
1401
- "decamelize": "^1.1.2",
1402
- "loud-rejection": "^1.0.0",
1403
- "map-obj": "^1.0.1",
1404
- "minimist": "^1.1.3",
1405
- "normalize-package-data": "^2.3.4",
1406
- "object-assign": "^4.0.1",
1407
- "read-pkg-up": "^1.0.1",
1408
- "redent": "^1.0.0",
1409
- "trim-newlines": "^1.0.0"
1410
- }
1411
- },
1412
- "merge-stream": {
1413
- "version": "2.0.0",
1414
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
1415
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
1416
- "dev": true
1417
- },
1418
- "merge2": {
1419
- "version": "1.3.0",
1420
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
1421
- "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
1422
- "dev": true
1423
- },
1424
- "micromatch": {
1425
- "version": "4.0.2",
1426
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
1427
- "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
1428
- "dev": true,
1429
- "requires": {
1430
- "braces": "^3.0.1",
1431
- "picomatch": "^2.0.5"
1432
- }
1433
- },
1434
- "mimic-fn": {
1435
- "version": "2.1.0",
1436
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
1437
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
1438
- "dev": true
1439
- },
1440
- "minimatch": {
1441
- "version": "3.0.4",
1442
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1443
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1444
- "dev": true,
1445
- "requires": {
1446
- "brace-expansion": "^1.1.7"
1447
- }
1448
- },
1449
- "minimist": {
1450
- "version": "1.2.0",
1451
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
1452
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
1453
- "dev": true
1454
- },
1455
- "mkdirp": {
1456
- "version": "0.5.1",
1457
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
1458
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
1459
- "dev": true,
1460
- "requires": {
1461
- "minimist": "0.0.8"
1462
- },
1463
- "dependencies": {
1464
- "minimist": {
1465
- "version": "0.0.8",
1466
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
1467
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
1468
- "dev": true
1469
- }
1470
- }
1471
- },
1472
- "ms": {
1473
- "version": "2.1.2",
1474
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1475
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1476
- "dev": true
1477
- },
1478
- "nice-try": {
1479
- "version": "1.0.5",
1480
- "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
1481
- "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
1482
- "dev": true
1483
- },
1484
- "nopt": {
1485
- "version": "3.0.6",
1486
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
1487
- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
1488
- "dev": true,
1489
- "requires": {
1490
- "abbrev": "1"
1491
- }
1492
- },
1493
- "normalize-package-data": {
1494
- "version": "2.5.0",
1495
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
1496
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
1497
- "dev": true,
1498
- "requires": {
1499
- "hosted-git-info": "^2.1.4",
1500
- "resolve": "^1.10.0",
1501
- "semver": "2 || 3 || 4 || 5",
1502
- "validate-npm-package-license": "^3.0.1"
1503
- }
1504
- },
1505
- "normalize-path": {
1506
- "version": "3.0.0",
1507
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1508
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1509
- "dev": true
1510
- },
1511
- "npm-run-path": {
1512
- "version": "2.0.2",
1513
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
1514
- "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
1515
- "dev": true,
1516
- "requires": {
1517
- "path-key": "^2.0.0"
1518
- }
1519
- },
1520
- "number-is-nan": {
1521
- "version": "1.0.1",
1522
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
1523
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
1524
- "dev": true
1525
- },
1526
- "object-assign": {
1527
- "version": "4.1.1",
1528
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1529
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
1530
- "dev": true
1531
- },
1532
- "once": {
1533
- "version": "1.4.0",
1534
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1535
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1536
- "dev": true,
1537
- "requires": {
1538
- "wrappy": "1"
1539
- }
1540
- },
1541
- "onetime": {
1542
- "version": "5.1.0",
1543
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
1544
- "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
1545
- "dev": true,
1546
- "requires": {
1547
- "mimic-fn": "^2.1.0"
1548
- }
1549
- },
1550
- "opencollective-postinstall": {
1551
- "version": "2.0.2",
1552
- "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
1553
- "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==",
1554
- "dev": true
1555
- },
1556
- "p-finally": {
1557
- "version": "1.0.0",
1558
- "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
1559
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
1560
- "dev": true
1561
- },
1562
- "p-limit": {
1563
- "version": "2.2.1",
1564
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
1565
- "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
1566
- "dev": true,
1567
- "requires": {
1568
- "p-try": "^2.0.0"
1569
- }
1570
- },
1571
- "p-locate": {
1572
- "version": "4.1.0",
1573
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
1574
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
1575
- "dev": true,
1576
- "requires": {
1577
- "p-limit": "^2.2.0"
1578
- }
1579
- },
1580
- "p-map": {
1581
- "version": "3.0.0",
1582
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
1583
- "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
1584
- "dev": true,
1585
- "requires": {
1586
- "aggregate-error": "^3.0.0"
1587
- }
1588
- },
1589
- "p-try": {
1590
- "version": "2.2.0",
1591
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
1592
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
1593
- "dev": true
1594
- },
1595
- "parse-json": {
1596
- "version": "2.2.0",
1597
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
1598
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
1599
- "dev": true,
1600
- "requires": {
1601
- "error-ex": "^1.2.0"
1602
- }
1603
- },
1604
- "path-exists": {
1605
- "version": "2.1.0",
1606
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
1607
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
1608
- "dev": true,
1609
- "requires": {
1610
- "pinkie-promise": "^2.0.0"
1611
- }
1612
- },
1613
- "path-is-absolute": {
1614
- "version": "1.0.1",
1615
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1616
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1617
- "dev": true
1618
- },
1619
- "path-key": {
1620
- "version": "2.0.1",
1621
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
1622
- "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1623
- "dev": true
1624
- },
1625
- "path-parse": {
1626
- "version": "1.0.6",
1627
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
1628
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
1629
- "dev": true
1630
- },
1631
- "path-type": {
1632
- "version": "1.1.0",
1633
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
1634
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
1635
- "dev": true,
1636
- "requires": {
1637
- "graceful-fs": "^4.1.2",
1638
- "pify": "^2.0.0",
1639
- "pinkie-promise": "^2.0.0"
1640
- }
1641
- },
1642
- "picomatch": {
1643
- "version": "2.0.7",
1644
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz",
1645
- "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==",
1646
- "dev": true
1647
- },
1648
- "pify": {
1649
- "version": "2.3.0",
1650
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1651
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
1652
- "dev": true
1653
- },
1654
- "pinkie": {
1655
- "version": "2.0.4",
1656
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
1657
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
1658
- "dev": true
1659
- },
1660
- "pinkie-promise": {
1661
- "version": "2.0.1",
1662
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
1663
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
1664
- "dev": true,
1665
- "requires": {
1666
- "pinkie": "^2.0.0"
1667
- }
1668
- },
1669
- "pkg-dir": {
1670
- "version": "4.2.0",
1671
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
1672
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
1673
- "dev": true,
1674
- "requires": {
1675
- "find-up": "^4.0.0"
1676
- },
1677
- "dependencies": {
1678
- "find-up": {
1679
- "version": "4.1.0",
1680
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
1681
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
1682
- "dev": true,
1683
- "requires": {
1684
- "locate-path": "^5.0.0",
1685
- "path-exists": "^4.0.0"
1686
- }
1687
- },
1688
- "path-exists": {
1689
- "version": "4.0.0",
1690
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1691
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1692
- "dev": true
1693
- }
1694
- }
1695
- },
1696
- "please-upgrade-node": {
1697
- "version": "3.2.0",
1698
- "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
1699
- "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
1700
- "dev": true,
1701
- "requires": {
1702
- "semver-compare": "^1.0.0"
1703
- }
1704
- },
1705
- "pump": {
1706
- "version": "3.0.0",
1707
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
1708
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
1709
- "dev": true,
1710
- "requires": {
1711
- "end-of-stream": "^1.1.0",
1712
- "once": "^1.3.1"
1713
- }
1714
- },
1715
- "read-pkg": {
1716
- "version": "1.1.0",
1717
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
1718
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
1719
- "dev": true,
1720
- "requires": {
1721
- "load-json-file": "^1.0.0",
1722
- "normalize-package-data": "^2.3.2",
1723
- "path-type": "^1.0.0"
1724
- }
1725
- },
1726
- "read-pkg-up": {
1727
- "version": "1.0.1",
1728
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
1729
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
1730
- "dev": true,
1731
- "requires": {
1732
- "find-up": "^1.0.0",
1733
- "read-pkg": "^1.0.0"
1734
- }
1735
- },
1736
- "redent": {
1737
- "version": "1.0.0",
1738
- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
1739
- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
1740
- "dev": true,
1741
- "requires": {
1742
- "indent-string": "^2.1.0",
1743
- "strip-indent": "^1.0.1"
1744
- }
1745
- },
1746
- "repeating": {
1747
- "version": "2.0.1",
1748
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
1749
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
1750
- "dev": true,
1751
- "requires": {
1752
- "is-finite": "^1.0.0"
1753
- }
1754
- },
1755
- "resolve": {
1756
- "version": "1.12.0",
1757
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
1758
- "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
1759
- "dev": true,
1760
- "requires": {
1761
- "path-parse": "^1.0.6"
1762
- }
1763
- },
1764
- "resolve-from": {
1765
- "version": "3.0.0",
1766
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
1767
- "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
1768
- "dev": true
1769
- },
1770
- "restore-cursor": {
1771
- "version": "2.0.0",
1772
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
1773
- "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
1774
- "dev": true,
1775
- "requires": {
1776
- "onetime": "^2.0.0",
1777
- "signal-exit": "^3.0.2"
1778
- },
1779
- "dependencies": {
1780
- "mimic-fn": {
1781
- "version": "1.2.0",
1782
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
1783
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
1784
- "dev": true
1785
- },
1786
- "onetime": {
1787
- "version": "2.0.1",
1788
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
1789
- "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
1790
- "dev": true,
1791
- "requires": {
1792
- "mimic-fn": "^1.0.0"
1793
- }
1794
- }
1795
- }
1796
- },
1797
- "reusify": {
1798
- "version": "1.0.4",
1799
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1800
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1801
- "dev": true
1802
- },
1803
- "rimraf": {
1804
- "version": "2.6.3",
1805
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
1806
- "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
1807
- "dev": true,
1808
- "requires": {
1809
- "glob": "^7.1.3"
1810
- },
1811
- "dependencies": {
1812
- "glob": {
1813
- "version": "7.1.5",
1814
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
1815
- "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
1816
- "dev": true,
1817
- "requires": {
1818
- "fs.realpath": "^1.0.0",
1819
- "inflight": "^1.0.4",
1820
- "inherits": "2",
1821
- "minimatch": "^3.0.4",
1822
- "once": "^1.3.0",
1823
- "path-is-absolute": "^1.0.0"
1824
- }
1825
- }
1826
- }
1827
- },
1828
- "run-node": {
1829
- "version": "1.0.0",
1830
- "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz",
1831
- "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==",
1832
- "dev": true
1833
- },
1834
- "run-parallel": {
1835
- "version": "1.1.9",
1836
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
1837
- "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
1838
- "dev": true
1839
- },
1840
- "rxjs": {
1841
- "version": "6.5.3",
1842
- "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
1843
- "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
1844
- "dev": true,
1845
- "requires": {
1846
- "tslib": "^1.9.0"
1847
- }
1848
- },
1849
- "safer-buffer": {
1850
- "version": "2.1.2",
1851
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1852
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1853
- "dev": true
1854
- },
1855
- "semver": {
1856
- "version": "5.7.1",
1857
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1858
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1859
- "dev": true
1860
- },
1861
- "semver-compare": {
1862
- "version": "1.0.0",
1863
- "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
1864
- "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
1865
- "dev": true
1866
- },
1867
- "shebang-command": {
1868
- "version": "1.2.0",
1869
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1870
- "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1871
- "dev": true,
1872
- "requires": {
1873
- "shebang-regex": "^1.0.0"
1874
- }
1875
- },
1876
- "shebang-regex": {
1877
- "version": "1.0.0",
1878
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1879
- "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1880
- "dev": true
1881
- },
1882
- "signal-exit": {
1883
- "version": "3.0.2",
1884
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1885
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
1886
- "dev": true
1887
- },
1888
- "slash": {
1889
- "version": "3.0.0",
1890
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
1891
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
1892
- "dev": true
1893
- },
1894
- "slice-ansi": {
1895
- "version": "0.0.4",
1896
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
1897
- "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
1898
- "dev": true
1899
- },
1900
- "spdx-correct": {
1901
- "version": "3.1.0",
1902
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
1903
- "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
1904
- "dev": true,
1905
- "requires": {
1906
- "spdx-expression-parse": "^3.0.0",
1907
- "spdx-license-ids": "^3.0.0"
1908
- }
1909
- },
1910
- "spdx-exceptions": {
1911
- "version": "2.2.0",
1912
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
1913
- "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
1914
- "dev": true
1915
- },
1916
- "spdx-expression-parse": {
1917
- "version": "3.0.0",
1918
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
1919
- "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
1920
- "dev": true,
1921
- "requires": {
1922
- "spdx-exceptions": "^2.1.0",
1923
- "spdx-license-ids": "^3.0.0"
1924
- }
1925
- },
1926
- "spdx-license-ids": {
1927
- "version": "3.0.5",
1928
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
1929
- "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
1930
- "dev": true
1931
- },
1932
- "sprintf-js": {
1933
- "version": "1.1.2",
1934
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
1935
- "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
1936
- "dev": true
1937
- },
1938
- "string-argv": {
1939
- "version": "0.3.1",
1940
- "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
1941
- "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
1942
- "dev": true
1943
- },
1944
- "string-width": {
1945
- "version": "1.0.2",
1946
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
1947
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
1948
- "dev": true,
1949
- "requires": {
1950
- "code-point-at": "^1.0.0",
1951
- "is-fullwidth-code-point": "^1.0.0",
1952
- "strip-ansi": "^3.0.0"
1953
- }
1954
- },
1955
- "stringify-object": {
1956
- "version": "3.3.0",
1957
- "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
1958
- "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
1959
- "dev": true,
1960
- "requires": {
1961
- "get-own-enumerable-property-symbols": "^3.0.0",
1962
- "is-obj": "^1.0.1",
1963
- "is-regexp": "^1.0.0"
1964
- }
1965
- },
1966
- "strip-ansi": {
1967
- "version": "3.0.1",
1968
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
1969
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
1970
- "dev": true,
1971
- "requires": {
1972
- "ansi-regex": "^2.0.0"
1973
- }
1974
- },
1975
- "strip-bom": {
1976
- "version": "2.0.0",
1977
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
1978
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
1979
- "dev": true,
1980
- "requires": {
1981
- "is-utf8": "^0.2.0"
1982
- }
1983
- },
1984
- "strip-eof": {
1985
- "version": "1.0.0",
1986
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
1987
- "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
1988
- "dev": true
1989
- },
1990
- "strip-final-newline": {
1991
- "version": "2.0.0",
1992
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
1993
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
1994
- "dev": true
1995
- },
1996
- "strip-indent": {
1997
- "version": "1.0.1",
1998
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
1999
- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
2000
- "dev": true,
2001
- "requires": {
2002
- "get-stdin": "^4.0.1"
2003
- }
2004
- },
2005
- "supports-color": {
2006
- "version": "5.5.0",
2007
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2008
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2009
- "dev": true,
2010
- "requires": {
2011
- "has-flag": "^3.0.0"
2012
- }
2013
- },
2014
- "symbol-observable": {
2015
- "version": "1.2.0",
2016
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
2017
- "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
2018
- "dev": true
2019
- },
2020
- "text-table": {
2021
- "version": "0.2.0",
2022
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
2023
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
2024
- "dev": true
2025
- },
2026
- "to-regex-range": {
2027
- "version": "5.0.1",
2028
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2029
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2030
- "dev": true,
2031
- "requires": {
2032
- "is-number": "^7.0.0"
2033
- }
2034
- },
2035
- "trim-newlines": {
2036
- "version": "1.0.0",
2037
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
2038
- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
2039
- "dev": true
2040
- },
2041
- "tslib": {
2042
- "version": "1.10.0",
2043
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
2044
- "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
2045
- "dev": true
2046
- },
2047
- "type-fest": {
2048
- "version": "0.6.0",
2049
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
2050
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
2051
- "dev": true
2052
- },
2053
- "underscore.string": {
2054
- "version": "3.3.5",
2055
- "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
2056
- "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
2057
- "dev": true,
2058
- "requires": {
2059
- "sprintf-js": "^1.0.3",
2060
- "util-deprecate": "^1.0.2"
2061
- }
2062
- },
2063
- "util-deprecate": {
2064
- "version": "1.0.2",
2065
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2066
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
2067
- "dev": true
2068
- },
2069
- "validate-npm-package-license": {
2070
- "version": "3.0.4",
2071
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
2072
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
2073
- "dev": true,
2074
- "requires": {
2075
- "spdx-correct": "^3.0.0",
2076
- "spdx-expression-parse": "^3.0.0"
2077
- }
2078
- },
2079
- "which": {
2080
- "version": "1.3.1",
2081
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2082
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2083
- "dev": true,
2084
- "requires": {
2085
- "isexe": "^2.0.0"
2086
- }
2087
- },
2088
- "wrap-ansi": {
2089
- "version": "3.0.1",
2090
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
2091
- "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
2092
- "dev": true,
2093
- "requires": {
2094
- "string-width": "^2.1.1",
2095
- "strip-ansi": "^4.0.0"
2096
- },
2097
- "dependencies": {
2098
- "ansi-regex": {
2099
- "version": "3.0.0",
2100
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
2101
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
2102
- "dev": true
2103
- },
2104
- "is-fullwidth-code-point": {
2105
- "version": "2.0.0",
2106
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2107
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2108
- "dev": true
2109
- },
2110
- "string-width": {
2111
- "version": "2.1.1",
2112
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
2113
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
2114
- "dev": true,
2115
- "requires": {
2116
- "is-fullwidth-code-point": "^2.0.0",
2117
- "strip-ansi": "^4.0.0"
2118
- }
2119
- },
2120
- "strip-ansi": {
2121
- "version": "4.0.0",
2122
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
2123
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
2124
- "dev": true,
2125
- "requires": {
2126
- "ansi-regex": "^3.0.0"
2127
- }
2128
- }
2129
- }
2130
- },
2131
- "wrappy": {
2132
- "version": "1.0.2",
2133
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2134
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
2135
- "dev": true
2136
- }
2137
- }
2138
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/package.json DELETED
@@ -1,39 +0,0 @@
1
- {
2
- "name": "action-scheduler",
3
- "title": "Action Scheduler",
4
- "version": "3.1.1",
5
- "homepage": "https://actionscheduler.org/",
6
- "repository": {
7
- "type": "git",
8
- "url": "https://github.com/woocommerce/action-scheduler.git"
9
- },
10
- "license": "GPL-3.0+",
11
- "main": "Gruntfile.js",
12
- "scripts": {
13
- "build": "grunt",
14
- "check-textdomain": "grunt checktextdomain",
15
- "phpcs": "grunt phpcs"
16
- },
17
- "devDependencies": {
18
- "grunt": "1.0.4",
19
- "grunt-checktextdomain": "1.0.1",
20
- "grunt-phpcs": "0.4.0",
21
- "husky": "3.0.9",
22
- "lint-staged": "9.4.2"
23
- },
24
- "engines": {
25
- "node": ">=10.15.0",
26
- "npm": ">=6.4.1"
27
- },
28
- "husky": {
29
- "hooks": {
30
- "pre-commit": "lint-staged"
31
- }
32
- },
33
- "lint-staged": {
34
- "*.php": [
35
- "php -d display_errors=1 -l",
36
- "composer run-script phpcs-pre-commit"
37
- ]
38
- }
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/phpcs.xml DELETED
@@ -1,39 +0,0 @@
1
- <?xml version="1.0"?>
2
- <ruleset name="WordPress Coding Standards">
3
- <description>WooCommerce dev PHP_CodeSniffer ruleset.</description>
4
-
5
- <!-- Exclude paths -->
6
- <exclude-pattern>docs/</exclude-pattern>
7
- <exclude-pattern>*/node_modules/*</exclude-pattern>
8
- <exclude-pattern>*/vendor/*</exclude-pattern>
9
-
10
- <!-- Configs -->
11
- <config name="minimum_supported_wp_version" value="4.7" />
12
- <config name="testVersion" value="5.6-" />
13
-
14
- <!-- Rules -->
15
- <rule ref="WooCommerce-Core" />
16
-
17
- <rule ref="WordPress.WP.I18n">
18
- <properties>
19
- <property name="text_domain" type="array" value="action-scheduler" />
20
- </properties>
21
- </rule>
22
-
23
- <rule ref="WordPress.Files.FileName.InvalidClassFileName">
24
- <exclude-pattern>classes/*</exclude-pattern>
25
- <exclude-pattern>deprecated/*</exclude-pattern>
26
- <exclude-pattern>lib/*</exclude-pattern>
27
- <exclude-pattern>tests/*</exclude-pattern>
28
- </rule>
29
- <rule ref="WordPress.Files.FileName.NotHyphenatedLowercase">
30
- <exclude-pattern>classes/*</exclude-pattern>
31
- <exclude-pattern>deprecated/*</exclude-pattern>
32
- <exclude-pattern>lib/*</exclude-pattern>
33
- <exclude-pattern>tests/*</exclude-pattern>
34
- </rule>
35
-
36
- <rule ref="Generic.Commenting">
37
- <exclude-pattern>tests/</exclude-pattern>
38
- </rule>
39
- </ruleset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/bootstrap.php CHANGED
@@ -29,6 +29,3 @@ if ( class_exists( 'PHPUnit\Framework\TestResult' ) ) { // PHPUnit 6.0 or newer
29
  } else {
30
  include_once('phpunit/deprecated/ActionScheduler_UnitTestCase.php');
31
  }
32
-
33
- include_once('phpunit/ActionScheduler_Mocker.php');
34
- include_once('phpunit/ActionScheduler_Mock_Async_Request_QueueRunner.php');
29
  } else {
30
  include_once('phpunit/deprecated/ActionScheduler_UnitTestCase.php');
31
  }
 
 
 
includes/vendor/action-scheduler/tests/phpunit.xml.dist CHANGED
@@ -12,24 +12,8 @@
12
  bootstrap="bootstrap.php"
13
  >
14
  <testsuites>
15
- <testsuite name="Migration">
16
- <directory phpVersion="5.6">./phpunit/migration</directory>
17
- </testsuite>
18
- <testsuite name="Tables">
19
- <file phpVersion="5.6">./phpunit/jobstore/ActionScheduler_DBStoreMigrator_Test.php</file>
20
- <file phpVersion="5.6">./phpunit/jobstore/ActionScheduler_DBStore_Test.php</file>
21
- <file phpVersion="5.6">./phpunit/jobstore/ActionScheduler_HybridStore_Test.php</file>
22
- <file phpVersion="5.6">./phpunit/logging/ActionScheduler_DBLogger_Test.php</file>
23
- </testsuite>
24
  <testsuite name="Action Scheduler">
25
- <directory>./phpunit/helpers</directory>
26
- <directory>./phpunit/jobs</directory>
27
- <directory>./phpunit/procedural_api</directory>
28
- <directory>./phpunit/runner</directory>
29
- <directory>./phpunit/schedules</directory>
30
- <directory>./phpunit/versioning</directory>
31
- <file>./phpunit/logging/ActionScheduler_wpCommentLogger_Test.php</file>
32
- <file>./phpunit/jobstore/ActionScheduler_wpPostStore_Test.php</file>
33
  </testsuite>
34
  </testsuites>
35
  <groups>
12
  bootstrap="bootstrap.php"
13
  >
14
  <testsuites>
 
 
 
 
 
 
 
 
 
15
  <testsuite name="Action Scheduler">
16
+ <directory>./phpunit</directory>
 
 
 
 
 
 
 
17
  </testsuite>
18
  </testsuites>
19
  <groups>
includes/vendor/action-scheduler/tests/phpunit/ActionScheduler_Mock_Async_Request_QueueRunner.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- /**
3
- * ActionScheduler_Mock_AsyncRequest_QueueRunner
4
- */
5
-
6
- defined( 'ABSPATH' ) || exit;
7
-
8
- /**
9
- * ActionScheduler_Mock_AsyncRequest_QueueRunner class.
10
- */
11
- class ActionScheduler_Mock_AsyncRequest_QueueRunner extends ActionScheduler_AsyncRequest_QueueRunner {
12
-
13
- /**
14
- * Do not run queues via async requests.
15
- */
16
- protected function allow() {
17
- return false;
18
- }
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/ActionScheduler_Mocker.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
- /**
3
- * ActionScheduler_Mocker
4
- */
5
-
6
- defined( 'ABSPATH' ) || exit;
7
-
8
- /**
9
- * ActionScheduler_Mocker class.
10
- */
11
- class ActionScheduler_Mocker {
12
-
13
- /**
14
- * Do not run queues via async requests.
15
- *
16
- * @param ActionScheduler_Store $store
17
- */
18
- public static function get_queue_runner( ActionScheduler_Store $store = null ) {
19
-
20
- if ( ! $store ) {
21
- $store = ActionScheduler_Store::instance();
22
- }
23
-
24
- return new ActionScheduler_QueueRunner( $store, null, null, self::get_async_request_queue_runner( $store ) );
25
- }
26
-
27
- /**
28
- * Get an instance of the mock queue runner
29
- *
30
- * @param ActionScheduler_Store $store
31
- */
32
- protected static function get_async_request_queue_runner( ActionScheduler_Store $store ) {
33
- return new ActionScheduler_Mock_AsyncRequest_QueueRunner( $store );
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/jobs/ActionScheduler_NullAction_Test.php CHANGED
@@ -10,7 +10,7 @@ class ActionScheduler_NullAction_Test extends ActionScheduler_UnitTestCase {
10
 
11
  $this->assertEmpty($action->get_hook());
12
  $this->assertEmpty($action->get_args());
13
- $this->assertNull( $action->get_schedule()->get_date() );
14
  }
15
  }
16
 
10
 
11
  $this->assertEmpty($action->get_hook());
12
  $this->assertEmpty($action->get_args());
13
+ $this->assertNull($action->get_schedule()->next());
14
  }
15
  }
16
 
includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_DBStoreMigrator_Test.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class ActionScheduler_DBStoreMigrator_Test
5
- * @group tables
6
- */
7
- class ActionScheduler_DBStoreMigrator_Test extends ActionScheduler_UnitTestCase {
8
-
9
- public function test_create_action_with_last_attempt_date() {
10
- $scheduled_date = as_get_datetime_object( strtotime( '-24 hours' ) );
11
- $last_attempt_date = as_get_datetime_object( strtotime( '-23 hours' ) );
12
-
13
- $action = new ActionScheduler_FinishedAction( 'my_hook', [], new ActionScheduler_SimpleSchedule( $scheduled_date ) );
14
- $store = new ActionScheduler_DBStoreMigrator();
15
-
16
- $action_id = $store->save_action( $action, null, $last_attempt_date );
17
- $action_date = $store->get_date( $action_id );
18
-
19
- $this->assertEquals( $last_attempt_date->format( 'U' ), $action_date->format( 'U' ) );
20
-
21
- $action_id = $store->save_action( $action, $scheduled_date, $last_attempt_date );
22
- $action_date = $store->get_date( $action_id );
23
-
24
- $this->assertEquals( $last_attempt_date->format( 'U' ), $action_date->format( 'U' ) );
25
- }
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_DBStore_Test.php DELETED
@@ -1,396 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class ActionScheduler_DBStore_Test
5
- * @group tables
6
- */
7
- class ActionScheduler_DBStore_Test extends ActionScheduler_UnitTestCase {
8
-
9
- public function test_create_action() {
10
- $time = as_get_datetime_object();
11
- $schedule = new ActionScheduler_SimpleSchedule( $time );
12
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
13
- $store = new ActionScheduler_DBStore();
14
- $action_id = $store->save_action( $action );
15
-
16
- $this->assertNotEmpty( $action_id );
17
- }
18
-
19
- public function test_create_action_with_scheduled_date() {
20
- $time = as_get_datetime_object( strtotime( '-1 week' ) );
21
- $action = new ActionScheduler_Action( 'my_hook', [], new ActionScheduler_SimpleSchedule( $time ) );
22
- $store = new ActionScheduler_DBStore();
23
- $action_id = $store->save_action( $action, $time );
24
- $action_date = $store->get_date( $action_id );
25
-
26
- $this->assertEquals( $time->format( 'U' ), $action_date->format( 'U' ) );
27
- }
28
-
29
- public function test_retrieve_action() {
30
- $time = as_get_datetime_object();
31
- $schedule = new ActionScheduler_SimpleSchedule( $time );
32
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
33
- $store = new ActionScheduler_DBStore();
34
- $action_id = $store->save_action( $action );
35
-
36
- $retrieved = $store->fetch_action( $action_id );
37
- $this->assertEquals( $action->get_hook(), $retrieved->get_hook() );
38
- $this->assertEqualSets( $action->get_args(), $retrieved->get_args() );
39
- $this->assertEquals( $action->get_schedule()->get_date()->format( 'U' ), $retrieved->get_schedule()->get_date()->format( 'U' ) );
40
- $this->assertEquals( $action->get_group(), $retrieved->get_group() );
41
- }
42
-
43
- public function test_cancel_action() {
44
- $time = as_get_datetime_object();
45
- $schedule = new ActionScheduler_SimpleSchedule( $time );
46
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
47
- $store = new ActionScheduler_DBStore();
48
- $action_id = $store->save_action( $action );
49
- $store->cancel_action( $action_id );
50
-
51
- $fetched = $store->fetch_action( $action_id );
52
- $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
53
- }
54
-
55
- public function test_cancel_actions_by_hook() {
56
- $store = new ActionScheduler_DBStore();
57
- $actions = [];
58
- $hook = 'by_hook_test';
59
- for ( $day = 1; $day <= 3; $day++ ) {
60
- $delta = sprintf( '+%d day', $day );
61
- $time = as_get_datetime_object( $delta );
62
- $schedule = new ActionScheduler_SimpleSchedule( $time );
63
- $action = new ActionScheduler_Action( $hook, [], $schedule, 'my_group' );
64
- $actions[] = $store->save_action( $action );
65
- }
66
- $store->cancel_actions_by_hook( $hook );
67
-
68
- foreach ( $actions as $action_id ) {
69
- $fetched = $store->fetch_action( $action_id );
70
- $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
71
- }
72
- }
73
-
74
- public function test_cancel_actions_by_group() {
75
- $store = new ActionScheduler_DBStore();
76
- $actions = [];
77
- $group = 'by_group_test';
78
- for ( $day = 1; $day <= 3; $day++ ) {
79
- $delta = sprintf( '+%d day', $day );
80
- $time = as_get_datetime_object( $delta );
81
- $schedule = new ActionScheduler_SimpleSchedule( $time );
82
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, $group );
83
- $actions[] = $store->save_action( $action );
84
- }
85
- $store->cancel_actions_by_group( $group );
86
-
87
- foreach ( $actions as $action_id ) {
88
- $fetched = $store->fetch_action( $action_id );
89
- $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
90
- }
91
- }
92
-
93
- public function test_claim_actions() {
94
- $created_actions = [];
95
- $store = new ActionScheduler_DBStore();
96
- for ( $i = 3; $i > - 3; $i -- ) {
97
- $time = as_get_datetime_object( $i . ' hours' );
98
- $schedule = new ActionScheduler_SimpleSchedule( $time );
99
- $action = new ActionScheduler_Action( 'my_hook', [ $i ], $schedule, 'my_group' );
100
-
101
- $created_actions[] = $store->save_action( $action );
102
- }
103
-
104
- $claim = $store->stake_claim();
105
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
106
-
107
- $this->assertCount( 3, $claim->get_actions() );
108
- $this->assertEqualSets( array_slice( $created_actions, 3, 3 ), $claim->get_actions() );
109
- }
110
-
111
- public function test_claim_actions_order() {
112
-
113
- $store = new ActionScheduler_DBStore();
114
- $schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( '-1 hour' ) );
115
- $created_actions = array(
116
- $store->save_action( new ActionScheduler_Action( 'my_hook', array( 1 ), $schedule, 'my_group' ) ),
117
- $store->save_action( new ActionScheduler_Action( 'my_hook', array( 1 ), $schedule, 'my_group' ) ),
118
- );
119
-
120
- $claim = $store->stake_claim();
121
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
122
-
123
- // Verify uniqueness of action IDs.
124
- $this->assertEquals( 2, count( array_unique( $created_actions ) ) );
125
-
126
- // Verify the count and order of the actions.
127
- $claimed_actions = $claim->get_actions();
128
- $this->assertCount( 2, $claimed_actions );
129
- $this->assertEquals( $created_actions, $claimed_actions );
130
-
131
- // Verify the reversed order doesn't pass.
132
- $reversed_actions = array_reverse( $created_actions );
133
- $this->assertNotEquals( $reversed_actions, $claimed_actions );
134
- }
135
-
136
- public function test_claim_actions_by_hooks() {
137
- $created_actions = $created_actions_by_hook = [];
138
- $store = new ActionScheduler_DBStore();
139
- $unique_hook_one = 'my_unique_hook_one';
140
- $unique_hook_two = 'my_unique_hook_two';
141
- $unique_hooks = array(
142
- $unique_hook_one,
143
- $unique_hook_two,
144
- );
145
-
146
- for ( $i = 3; $i > - 3; $i -- ) {
147
- foreach ( $unique_hooks as $unique_hook ) {
148
- $time = as_get_datetime_object( $i . ' hours' );
149
- $schedule = new ActionScheduler_SimpleSchedule( $time );
150
- $action = new ActionScheduler_Action( $unique_hook, [ $i ], $schedule, 'my_group' );
151
-
152
- $action_id = $store->save_action( $action );
153
- $created_actions[] = $created_actions_by_hook[ $unique_hook ][] = $action_id;
154
- }
155
- }
156
-
157
- $claim = $store->stake_claim( 10, null, $unique_hooks );
158
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
159
- $this->assertCount( 6, $claim->get_actions() );
160
- $this->assertEqualSets( array_slice( $created_actions, 6, 6 ), $claim->get_actions() );
161
-
162
- $store->release_claim( $claim );
163
-
164
- $claim = $store->stake_claim( 10, null, array( $unique_hook_one ) );
165
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
166
- $this->assertCount( 3, $claim->get_actions() );
167
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_one ], 3, 3 ), $claim->get_actions() );
168
-
169
- $store->release_claim( $claim );
170
-
171
- $claim = $store->stake_claim( 10, null, array( $unique_hook_two ) );
172
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
173
- $this->assertCount( 3, $claim->get_actions() );
174
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_two ], 3, 3 ), $claim->get_actions() );
175
- }
176
-
177
- public function test_claim_actions_by_group() {
178
- $created_actions = [];
179
- $store = new ActionScheduler_DBStore();
180
- $unique_group_one = 'my_unique_group_one';
181
- $unique_group_two = 'my_unique_group_two';
182
- $unique_groups = array(
183
- $unique_group_one,
184
- $unique_group_two,
185
- );
186
-
187
- for ( $i = 3; $i > - 3; $i -- ) {
188
- foreach ( $unique_groups as $unique_group ) {
189
- $time = as_get_datetime_object( $i . ' hours' );
190
- $schedule = new ActionScheduler_SimpleSchedule( $time );
191
- $action = new ActionScheduler_Action( 'my_hook', [ $i ], $schedule, $unique_group );
192
-
193
- $created_actions[ $unique_group ][] = $store->save_action( $action );
194
- }
195
- }
196
-
197
- $claim = $store->stake_claim( 10, null, array(), $unique_group_one );
198
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
199
- $this->assertCount( 3, $claim->get_actions() );
200
- $this->assertEqualSets( array_slice( $created_actions[ $unique_group_one ], 3, 3 ), $claim->get_actions() );
201
-
202
- $store->release_claim( $claim );
203
-
204
- $claim = $store->stake_claim( 10, null, array(), $unique_group_two );
205
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
206
- $this->assertCount( 3, $claim->get_actions() );
207
- $this->assertEqualSets( array_slice( $created_actions[ $unique_group_two ], 3, 3 ), $claim->get_actions() );
208
- }
209
-
210
- public function test_claim_actions_by_hook_and_group() {
211
- $created_actions = $created_actions_by_hook = [];
212
- $store = new ActionScheduler_DBStore();
213
-
214
- $unique_hook_one = 'my_other_unique_hook_one';
215
- $unique_hook_two = 'my_other_unique_hook_two';
216
- $unique_hooks = array(
217
- $unique_hook_one,
218
- $unique_hook_two,
219
- );
220
-
221
- $unique_group_one = 'my_other_other_unique_group_one';
222
- $unique_group_two = 'my_other_unique_group_two';
223
- $unique_groups = array(
224
- $unique_group_one,
225
- $unique_group_two,
226
- );
227
-
228
- for ( $i = 3; $i > - 3; $i -- ) {
229
- foreach ( $unique_hooks as $unique_hook ) {
230
- foreach ( $unique_groups as $unique_group ) {
231
- $time = as_get_datetime_object( $i . ' hours' );
232
- $schedule = new ActionScheduler_SimpleSchedule( $time );
233
- $action = new ActionScheduler_Action( $unique_hook, [ $i ], $schedule, $unique_group );
234
-
235
- $action_id = $store->save_action( $action );
236
- $created_actions[ $unique_group ][] = $action_id;
237
- $created_actions_by_hook[ $unique_hook ][ $unique_group ][] = $action_id;
238
- }
239
- }
240
- }
241
-
242
- /** Test Both Hooks with Each Group */
243
-
244
- $claim = $store->stake_claim( 10, null, $unique_hooks, $unique_group_one );
245
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
246
- $this->assertCount( 6, $claim->get_actions() );
247
- $this->assertEqualSets( array_slice( $created_actions[ $unique_group_one ], 6, 6 ), $claim->get_actions() );
248
-
249
- $store->release_claim( $claim );
250
-
251
- $claim = $store->stake_claim( 10, null, $unique_hooks, $unique_group_two );
252
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
253
- $this->assertCount( 6, $claim->get_actions() );
254
- $this->assertEqualSets( array_slice( $created_actions[ $unique_group_two ], 6, 6 ), $claim->get_actions() );
255
-
256
- $store->release_claim( $claim );
257
-
258
- /** Test Just One Hook with Group One */
259
-
260
- $claim = $store->stake_claim( 10, null, array( $unique_hook_one ), $unique_group_one );
261
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
262
- $this->assertCount( 3, $claim->get_actions() );
263
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_one ][ $unique_group_one ], 3, 3 ), $claim->get_actions() );
264
-
265
- $store->release_claim( $claim );
266
-
267
- $claim = $store->stake_claim( 24, null, array( $unique_hook_two ), $unique_group_one );
268
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
269
- $this->assertCount( 3, $claim->get_actions() );
270
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_two ][ $unique_group_one ], 3, 3 ), $claim->get_actions() );
271
-
272
- $store->release_claim( $claim );
273
-
274
- /** Test Just One Hook with Group Two */
275
-
276
- $claim = $store->stake_claim( 10, null, array( $unique_hook_one ), $unique_group_two );
277
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
278
- $this->assertCount( 3, $claim->get_actions() );
279
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_one ][ $unique_group_two ], 3, 3 ), $claim->get_actions() );
280
-
281
- $store->release_claim( $claim );
282
-
283
- $claim = $store->stake_claim( 24, null, array( $unique_hook_two ), $unique_group_two );
284
- $this->assertInstanceof( 'ActionScheduler_ActionClaim', $claim );
285
- $this->assertCount( 3, $claim->get_actions() );
286
- $this->assertEqualSets( array_slice( $created_actions_by_hook[ $unique_hook_two ][ $unique_group_two ], 3, 3 ), $claim->get_actions() );
287
- }
288
-
289
- public function test_duplicate_claim() {
290
- $created_actions = [];
291
- $store = new ActionScheduler_DBStore();
292
- for ( $i = 0; $i > - 3; $i -- ) {
293
- $time = as_get_datetime_object( $i . ' hours' );
294
- $schedule = new ActionScheduler_SimpleSchedule( $time );
295
- $action = new ActionScheduler_Action( 'my_hook', [ $i ], $schedule, 'my_group' );
296
-
297
- $created_actions[] = $store->save_action( $action );
298
- }
299
-
300
- $claim1 = $store->stake_claim();
301
- $claim2 = $store->stake_claim();
302
- $this->assertCount( 3, $claim1->get_actions() );
303
- $this->assertCount( 0, $claim2->get_actions() );
304
- }
305
-
306
- public function test_release_claim() {
307
- $created_actions = [];
308
- $store = new ActionScheduler_DBStore();
309
- for ( $i = 0; $i > - 3; $i -- ) {
310
- $time = as_get_datetime_object( $i . ' hours' );
311
- $schedule = new ActionScheduler_SimpleSchedule( $time );
312
- $action = new ActionScheduler_Action( 'my_hook', [ $i ], $schedule, 'my_group' );
313
-
314
- $created_actions[] = $store->save_action( $action );
315
- }
316
-
317
- $claim1 = $store->stake_claim();
318
-
319
- $store->release_claim( $claim1 );
320
-
321
- $claim2 = $store->stake_claim();
322
- $this->assertCount( 3, $claim2->get_actions() );
323
- }
324
-
325
- public function test_search() {
326
- $created_actions = [];
327
- $store = new ActionScheduler_DBStore();
328
- for ( $i = - 3; $i <= 3; $i ++ ) {
329
- $time = as_get_datetime_object( $i . ' hours' );
330
- $schedule = new ActionScheduler_SimpleSchedule( $time );
331
- $action = new ActionScheduler_Action( 'my_hook', [ $i ], $schedule, 'my_group' );
332
-
333
- $created_actions[] = $store->save_action( $action );
334
- }
335
-
336
- $next_no_args = $store->find_action( 'my_hook' );
337
- $this->assertEquals( $created_actions[ 0 ], $next_no_args );
338
-
339
- $next_with_args = $store->find_action( 'my_hook', [ 'args' => [ 1 ] ] );
340
- $this->assertEquals( $created_actions[ 4 ], $next_with_args );
341
-
342
- $non_existent = $store->find_action( 'my_hook', [ 'args' => [ 17 ] ] );
343
- $this->assertNull( $non_existent );
344
- }
345
-
346
- public function test_search_by_group() {
347
- $store = new ActionScheduler_DBStore();
348
- $schedule = new ActionScheduler_SimpleSchedule( as_get_datetime_object( 'tomorrow' ) );
349
-
350
- $abc = $store->save_action( new ActionScheduler_Action( 'my_hook', [ 1 ], $schedule, 'abc' ) );
351
- $def = $store->save_action( new ActionScheduler_Action( 'my_hook', [ 1 ], $schedule, 'def' ) );
352
- $ghi = $store->save_action( new ActionScheduler_Action( 'my_hook', [ 1 ], $schedule, 'ghi' ) );
353
-
354
- $this->assertEquals( $abc, $store->find_action( 'my_hook', [ 'group' => 'abc' ] ) );
355
- $this->assertEquals( $def, $store->find_action( 'my_hook', [ 'group' => 'def' ] ) );
356
- $this->assertEquals( $ghi, $store->find_action( 'my_hook', [ 'group' => 'ghi' ] ) );
357
- }
358
-
359
- public function test_get_run_date() {
360
- $time = as_get_datetime_object( '-10 minutes' );
361
- $schedule = new ActionScheduler_IntervalSchedule( $time, HOUR_IN_SECONDS );
362
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
363
- $store = new ActionScheduler_DBStore();
364
- $action_id = $store->save_action( $action );
365
-
366
- $this->assertEquals( $time->format( 'U' ), $store->get_date( $action_id )->format( 'U' ) );
367
-
368
- $action = $store->fetch_action( $action_id );
369
- $action->execute();
370
- $now = as_get_datetime_object();
371
- $store->mark_complete( $action_id );
372
-
373
- $this->assertEquals( $now->format( 'U' ), $store->get_date( $action_id )->format( 'U' ) );
374
-
375
- $next = $action->get_schedule()->get_next( $now );
376
- $new_action_id = $store->save_action( $action, $next );
377
-
378
- $this->assertEquals( (int) ( $now->format( 'U' ) ) + HOUR_IN_SECONDS, $store->get_date( $new_action_id )->format( 'U' ) );
379
- }
380
-
381
- public function test_get_status() {
382
- $time = as_get_datetime_object('-10 minutes');
383
- $schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
384
- $action = new ActionScheduler_Action('my_hook', array(), $schedule);
385
- $store = new ActionScheduler_DBStore();
386
- $action_id = $store->save_action($action);
387
-
388
- $this->assertEquals( ActionScheduler_Store::STATUS_PENDING, $store->get_status( $action_id ) );
389
-
390
- $store->mark_complete( $action_id );
391
- $this->assertEquals( ActionScheduler_Store::STATUS_COMPLETE, $store->get_status( $action_id ) );
392
-
393
- $store->mark_failure( $action_id );
394
- $this->assertEquals( ActionScheduler_Store::STATUS_FAILED, $store->get_status( $action_id ) );
395
- }
396
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_HybridStore_Test.php DELETED
@@ -1,272 +0,0 @@
1
- <?php
2
-
3
-
4
- use Action_Scheduler\Migration\Config;
5
- use ActionScheduler_NullAction as NullAction;
6
- use ActionScheduler_wpCommentLogger as CommentLogger;
7
- use ActionScheduler_wpPostStore as PostStore;
8
-
9
- /**
10
- * Class ActionScheduler_HybridStore_Test
11
- * @group tables
12
- */
13
-
14
- class ActionScheduler_HybridStore_Test extends ActionScheduler_UnitTestCase {
15
- private $demarkation_id = 1000;
16
-
17
- public function setUp() {
18
- parent::setUp();
19
- if ( ! taxonomy_exists( PostStore::GROUP_TAXONOMY ) ) {
20
- // register the post type and taxonomy necessary for the store to work
21
- $store = new PostStore();
22
- $store->init();
23
- }
24
- update_option( ActionScheduler_HybridStore::DEMARKATION_OPTION, $this->demarkation_id );
25
- $hybrid = new ActionScheduler_HybridStore();
26
- $hybrid->set_autoincrement( '', ActionScheduler_StoreSchema::ACTIONS_TABLE );
27
- }
28
-
29
- public function tearDown() {
30
- parent::tearDown();
31
-
32
- // reset the autoincrement index
33
- /** @var \wpdb $wpdb */
34
- global $wpdb;
35
- $wpdb->query( "TRUNCATE TABLE {$wpdb->actionscheduler_actions}" );
36
- delete_option( ActionScheduler_HybridStore::DEMARKATION_OPTION );
37
- }
38
-
39
- public function test_actions_are_migrated_on_find() {
40
- $source_store = new PostStore();
41
- $destination_store = new ActionScheduler_DBStore();
42
- $source_logger = new CommentLogger();
43
- $destination_logger = new ActionScheduler_DBLogger();
44
-
45
- $config = new Config();
46
- $config->set_source_store( $source_store );
47
- $config->set_source_logger( $source_logger );
48
- $config->set_destination_store( $destination_store );
49
- $config->set_destination_logger( $destination_logger );
50
-
51
- $hybrid_store = new ActionScheduler_HybridStore( $config );
52
-
53
- $time = as_get_datetime_object( '10 minutes ago' );
54
- $schedule = new ActionScheduler_SimpleSchedule( $time );
55
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
56
- $source_id = $source_store->save_action( $action );
57
-
58
- $found = $hybrid_store->find_action( __FUNCTION__, [] );
59
-
60
- $this->assertNotEquals( $source_id, $found );
61
- $this->assertGreaterThanOrEqual( $this->demarkation_id, $found );
62
-
63
- $found_in_source = $source_store->fetch_action( $source_id );
64
- $this->assertInstanceOf( NullAction::class, $found_in_source );
65
- }
66
-
67
-
68
- public function test_actions_are_migrated_on_query() {
69
- $source_store = new PostStore();
70
- $destination_store = new ActionScheduler_DBStore();
71
- $source_logger = new CommentLogger();
72
- $destination_logger = new ActionScheduler_DBLogger();
73
-
74
- $config = new Config();
75
- $config->set_source_store( $source_store );
76
- $config->set_source_logger( $source_logger );
77
- $config->set_destination_store( $destination_store );
78
- $config->set_destination_logger( $destination_logger );
79
-
80
- $hybrid_store = new ActionScheduler_HybridStore( $config );
81
-
82
- $source_actions = [];
83
- $destination_actions = [];
84
-
85
- for ( $i = 0; $i < 10; $i++ ) {
86
- // create in instance in the source store
87
- $time = as_get_datetime_object( ( $i * 10 + 1 ) . ' minutes' );
88
- $schedule = new ActionScheduler_SimpleSchedule( $time );
89
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
90
-
91
- $source_actions[] = $source_store->save_action( $action );
92
-
93
- // create an instance in the destination store
94
- $time = as_get_datetime_object( ( $i * 10 + 5 ) . ' minutes' );
95
- $schedule = new ActionScheduler_SimpleSchedule( $time );
96
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
97
-
98
- $destination_actions[] = $destination_store->save_action( $action );
99
- }
100
-
101
- $found = $hybrid_store->query_actions([
102
- 'hook' => __FUNCTION__,
103
- 'per_page' => 6,
104
- ] );
105
-
106
- $this->assertCount( 6, $found );
107
- foreach ( $found as $key => $action_id ) {
108
- $this->assertNotContains( $action_id, $source_actions );
109
- $this->assertGreaterThanOrEqual( $this->demarkation_id, $action_id );
110
- if ( $key % 2 == 0 ) { // it should have been in the source store
111
- $this->assertNotContains( $action_id, $destination_actions );
112
- } else { // it should have already been in the destination store
113
- $this->assertContains( $action_id, $destination_actions );
114
- }
115
- }
116
-
117
- // six of the original 10 should have migrated to the new store
118
- // even though only three were retrieve in the final query
119
- $found_in_source = $source_store->query_actions( [
120
- 'hook' => __FUNCTION__,
121
- 'per_page' => 10,
122
- ] );
123
- $this->assertCount( 4, $found_in_source );
124
- }
125
-
126
-
127
- public function test_actions_are_migrated_on_claim() {
128
- $source_store = new PostStore();
129
- $destination_store = new ActionScheduler_DBStore();
130
- $source_logger = new CommentLogger();
131
- $destination_logger = new ActionScheduler_DBLogger();
132
-
133
- $config = new Config();
134
- $config->set_source_store( $source_store );
135
- $config->set_source_logger( $source_logger );
136
- $config->set_destination_store( $destination_store );
137
- $config->set_destination_logger( $destination_logger );
138
-
139
- $hybrid_store = new ActionScheduler_HybridStore( $config );
140
-
141
- $source_actions = [];
142
- $destination_actions = [];
143
-
144
- for ( $i = 0; $i < 10; $i++ ) {
145
- // create in instance in the source store
146
- $time = as_get_datetime_object( ( $i * 10 + 1 ) . ' minutes ago' );
147
- $schedule = new ActionScheduler_SimpleSchedule( $time );
148
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
149
-
150
- $source_actions[] = $source_store->save_action( $action );
151
-
152
- // create an instance in the destination store
153
- $time = as_get_datetime_object( ( $i * 10 + 5 ) . ' minutes ago' );
154
- $schedule = new ActionScheduler_SimpleSchedule( $time );
155
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
156
-
157
- $destination_actions[] = $destination_store->save_action( $action );
158
- }
159
-
160
- $claim = $hybrid_store->stake_claim( 6 );
161
-
162
- $claimed_actions = $claim->get_actions();
163
- $this->assertCount( 6, $claimed_actions );
164
- $this->assertCount( 3, array_intersect( $destination_actions, $claimed_actions ) );
165
-
166
-
167
- // six of the original 10 should have migrated to the new store
168
- // even though only three were retrieve in the final claim
169
- $found_in_source = $source_store->query_actions( [
170
- 'hook' => __FUNCTION__,
171
- 'per_page' => 10,
172
- ] );
173
- $this->assertCount( 4, $found_in_source );
174
-
175
- $this->assertEquals( 0, $source_store->get_claim_count() );
176
- $this->assertEquals( 1, $destination_store->get_claim_count() );
177
- $this->assertEquals( 1, $hybrid_store->get_claim_count() );
178
-
179
- }
180
-
181
- public function test_fetch_respects_demarkation() {
182
- $source_store = new PostStore();
183
- $destination_store = new ActionScheduler_DBStore();
184
- $source_logger = new CommentLogger();
185
- $destination_logger = new ActionScheduler_DBLogger();
186
-
187
- $config = new Config();
188
- $config->set_source_store( $source_store );
189
- $config->set_source_logger( $source_logger );
190
- $config->set_destination_store( $destination_store );
191
- $config->set_destination_logger( $destination_logger );
192
-
193
- $hybrid_store = new ActionScheduler_HybridStore( $config );
194
-
195
- $source_actions = [];
196
- $destination_actions = [];
197
-
198
- for ( $i = 0; $i < 2; $i++ ) {
199
- // create in instance in the source store
200
- $time = as_get_datetime_object( ( $i * 10 + 1 ) . ' minutes ago' );
201
- $schedule = new ActionScheduler_SimpleSchedule( $time );
202
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
203
-
204
- $source_actions[] = $source_store->save_action( $action );
205
-
206
- // create an instance in the destination store
207
- $time = as_get_datetime_object( ( $i * 10 + 5 ) . ' minutes ago' );
208
- $schedule = new ActionScheduler_SimpleSchedule( $time );
209
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
210
-
211
- $destination_actions[] = $destination_store->save_action( $action );
212
- }
213
-
214
- foreach ( $source_actions as $action_id ) {
215
- $action = $hybrid_store->fetch_action( $action_id );
216
- $this->assertInstanceOf( ActionScheduler_Action::class, $action );
217
- $this->assertNotInstanceOf( NullAction::class, $action );
218
- }
219
-
220
- foreach ( $destination_actions as $action_id ) {
221
- $action = $hybrid_store->fetch_action( $action_id );
222
- $this->assertInstanceOf( ActionScheduler_Action::class, $action );
223
- $this->assertNotInstanceOf( NullAction::class, $action );
224
- }
225
- }
226
-
227
- public function test_mark_complete_respects_demarkation() {
228
- $source_store = new PostStore();
229
- $destination_store = new ActionScheduler_DBStore();
230
- $source_logger = new CommentLogger();
231
- $destination_logger = new ActionScheduler_DBLogger();
232
-
233
- $config = new Config();
234
- $config->set_source_store( $source_store );
235
- $config->set_source_logger( $source_logger );
236
- $config->set_destination_store( $destination_store );
237
- $config->set_destination_logger( $destination_logger );
238
-
239
- $hybrid_store = new ActionScheduler_HybridStore( $config );
240
-
241
- $source_actions = [];
242
- $destination_actions = [];
243
-
244
- for ( $i = 0; $i < 2; $i++ ) {
245
- // create in instance in the source store
246
- $time = as_get_datetime_object( ( $i * 10 + 1 ) . ' minutes ago' );
247
- $schedule = new ActionScheduler_SimpleSchedule( $time );
248
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
249
-
250
- $source_actions[] = $source_store->save_action( $action );
251
-
252
- // create an instance in the destination store
253
- $time = as_get_datetime_object( ( $i * 10 + 5 ) . ' minutes ago' );
254
- $schedule = new ActionScheduler_SimpleSchedule( $time );
255
- $action = new ActionScheduler_Action( __FUNCTION__, [], $schedule );
256
-
257
- $destination_actions[] = $destination_store->save_action( $action );
258
- }
259
-
260
- foreach ( $source_actions as $action_id ) {
261
- $hybrid_store->mark_complete( $action_id );
262
- $action = $hybrid_store->fetch_action( $action_id );
263
- $this->assertInstanceOf( ActionScheduler_FinishedAction::class, $action );
264
- }
265
-
266
- foreach ( $destination_actions as $action_id ) {
267
- $hybrid_store->mark_complete( $action_id );
268
- $action = $hybrid_store->fetch_action( $action_id );
269
- $this->assertInstanceOf( ActionScheduler_FinishedAction::class, $action );
270
- }
271
- }
272
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/jobstore/ActionScheduler_wpPostStore_Test.php CHANGED
@@ -37,7 +37,7 @@ class ActionScheduler_wpPostStore_Test extends ActionScheduler_UnitTestCase {
37
  $retrieved = $store->fetch_action($action_id);
38
  $this->assertEquals($action->get_hook(), $retrieved->get_hook());
39
  $this->assertEqualSets($action->get_args(), $retrieved->get_args());
40
- $this->assertEquals( $action->get_schedule()->get_date()->getTimestamp(), $retrieved->get_schedule()->get_date()->getTimestamp() );
41
  $this->assertEquals($action->get_group(), $retrieved->get_group());
42
  }
43
 
@@ -76,45 +76,6 @@ class ActionScheduler_wpPostStore_Test extends ActionScheduler_UnitTestCase {
76
  $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
77
  }
78
 
79
- public function test_cancel_actions_by_hook() {
80
- $store = new ActionScheduler_wpPostStore();
81
- $actions = array();
82
- $hook = 'by_hook_test';
83
- for ( $day = 1; $day <= 3; $day++ ) {
84
- $delta = sprintf( '+%d day', $day );
85
- $time = as_get_datetime_object( $delta );
86
- $schedule = new ActionScheduler_SimpleSchedule( $time );
87
- $action = new ActionScheduler_Action( $hook, array(), $schedule, 'my_group' );
88
- $actions[] = $store->save_action( $action );
89
- }
90
- $store->cancel_actions_by_hook( $hook );
91
-
92
- foreach ( $actions as $action_id ) {
93
- $fetched = $store->fetch_action( $action_id );
94
- $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
95
- }
96
- }
97
-
98
- public function test_cancel_actions_by_group() {
99
- $store = new ActionScheduler_wpPostStore();
100
- $actions = array();
101
- $group = 'by_group_test';
102
-
103
- for ( $day = 1; $day <= 3; $day++ ) {
104
- $delta = sprintf( '+%d day', $day );
105
- $time = as_get_datetime_object( $delta );
106
- $schedule = new ActionScheduler_SimpleSchedule( $time );
107
- $action = new ActionScheduler_Action( 'my_hook', array(), $schedule, $group );
108
- $actions[] = $store->save_action( $action );
109
- }
110
- $store->cancel_actions_by_group( $group );
111
-
112
- foreach ( $actions as $action_id ) {
113
- $fetched = $store->fetch_action( $action_id );
114
- $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
115
- }
116
- }
117
-
118
  public function test_claim_actions() {
119
  $created_actions = array();
120
  $store = new ActionScheduler_wpPostStore();
@@ -264,7 +225,7 @@ class ActionScheduler_wpPostStore_Test extends ActionScheduler_UnitTestCase {
264
  $action->execute();
265
  $store->mark_complete( $action_id );
266
 
267
- $next = $action->get_schedule()->get_next( as_get_datetime_object() );
268
  $new_action_id = $store->save_action( $action, $next );
269
 
270
  $this->assertEquals('publish', get_post_status($action_id));
@@ -285,9 +246,9 @@ class ActionScheduler_wpPostStore_Test extends ActionScheduler_UnitTestCase {
285
  $now = as_get_datetime_object();
286
  $store->mark_complete( $action_id );
287
 
288
- $this->assertEquals( $store->get_date( $action_id )->getTimestamp(), $now->getTimestamp(), '', 1 ); // allow timestamp to be 1 second off for older versions of PHP
289
 
290
- $next = $action->get_schedule()->get_next( $now );
291
  $new_action_id = $store->save_action( $action, $next );
292
 
293
  $this->assertEquals( (int)($now->getTimestamp()) + HOUR_IN_SECONDS, $store->get_date($new_action_id)->getTimestamp() );
37
  $retrieved = $store->fetch_action($action_id);
38
  $this->assertEquals($action->get_hook(), $retrieved->get_hook());
39
  $this->assertEqualSets($action->get_args(), $retrieved->get_args());
40
+ $this->assertEquals($action->get_schedule()->next()->getTimestamp(), $retrieved->get_schedule()->next()->getTimestamp());
41
  $this->assertEquals($action->get_group(), $retrieved->get_group());
42
  }
43
 
76
  $this->assertInstanceOf( 'ActionScheduler_CanceledAction', $fetched );
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  public function test_claim_actions() {
80
  $created_actions = array();
81
  $store = new ActionScheduler_wpPostStore();
225
  $action->execute();
226
  $store->mark_complete( $action_id );
227
 
228
+ $next = $action->get_schedule()->next( as_get_datetime_object() );
229
  $new_action_id = $store->save_action( $action, $next );
230
 
231
  $this->assertEquals('publish', get_post_status($action_id));
246
  $now = as_get_datetime_object();
247
  $store->mark_complete( $action_id );
248
 
249
+ $this->assertEquals( $store->get_date($action_id)->getTimestamp(), $now->getTimestamp() );
250
 
251
+ $next = $action->get_schedule()->next( $now );
252
  $new_action_id = $store->save_action( $action, $next );
253
 
254
  $this->assertEquals( (int)($now->getTimestamp()) + HOUR_IN_SECONDS, $store->get_date($new_action_id)->getTimestamp() );
includes/vendor/action-scheduler/tests/phpunit/lock/ActionScheduler_OptionLock_Test.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class ActionScheduler_Lock_Test
5
- * @package test_cases\lock
6
- */
7
- class ActionScheduler_OptionLock_Test extends ActionScheduler_UnitTestCase {
8
- public function test_instance() {
9
- $lock = ActionScheduler::lock();
10
- $this->assertInstanceOf( 'ActionScheduler_Lock', $lock );
11
- $this->assertInstanceOf( 'ActionScheduler_OptionLock', $lock );
12
- }
13
-
14
- public function test_is_locked() {
15
- $lock = ActionScheduler::lock();
16
- $lock_type = md5( rand() );
17
-
18
- $this->assertFalse( $lock->is_locked( $lock_type ) );
19
-
20
- $lock->set( $lock_type );
21
- $this->assertTrue( $lock->is_locked( $lock_type ) );
22
- }
23
-
24
- public function test_set() {
25
- $lock = ActionScheduler::lock();
26
- $lock_type = md5( rand() );
27
-
28
- $lock->set( $lock_type );
29
- $this->assertTrue( $lock->is_locked( $lock_type ) );
30
- }
31
-
32
- public function test_get_expiration() {
33
- $lock = ActionScheduler::lock();
34
- $lock_type = md5( rand() );
35
-
36
- $lock->set( $lock_type );
37
-
38
- $expiration = $lock->get_expiration( $lock_type );
39
- $current_time = time();
40
-
41
- $this->assertGreaterThanOrEqual( 0, $expiration );
42
- $this->assertGreaterThan( $current_time, $expiration );
43
- $this->assertLessThan( $current_time + MINUTE_IN_SECONDS + 1, $expiration );
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/logging/ActionScheduler_DBLogger_Test.php DELETED
@@ -1,139 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class ActionScheduler_DBLogger_Test
5
- * @package test_cases\logging
6
- * @group tables
7
- */
8
- class ActionScheduler_DBLogger_Test extends ActionScheduler_UnitTestCase {
9
- public function test_default_logger() {
10
- $logger = ActionScheduler::logger();
11
- $this->assertInstanceOf( 'ActionScheduler_Logger', $logger );
12
- $this->assertInstanceOf( ActionScheduler_DBLogger::class, $logger );
13
- }
14
-
15
- public function test_add_log_entry() {
16
- $action_id = as_schedule_single_action( time(), __METHOD__ );
17
- $logger = ActionScheduler::logger();
18
- $message = 'Logging that something happened';
19
- $log_id = $logger->log( $action_id, $message );
20
- $entry = $logger->get_entry( $log_id );
21
-
22
- $this->assertEquals( $action_id, $entry->get_action_id() );
23
- $this->assertEquals( $message, $entry->get_message() );
24
- }
25
-
26
- public function test_null_log_entry() {
27
- $logger = ActionScheduler::logger();
28
- $entry = $logger->get_entry( 1 );
29
- $this->assertEquals( '', $entry->get_action_id() );
30
- $this->assertEquals( '', $entry->get_message() );
31
- }
32
-
33
- public function test_storage_logs() {
34
- $action_id = as_schedule_single_action( time(), __METHOD__ );
35
- $logger = ActionScheduler::logger();
36
- $logs = $logger->get_logs( $action_id );
37
- $expected = new ActionScheduler_LogEntry( $action_id, 'action created' );
38
- $this->assertCount( 1, $logs );
39
- $this->assertEquals( $expected->get_action_id(), $logs[0]->get_action_id() );
40
- $this->assertEquals( $expected->get_message(), $logs[0]->get_message() );
41
- }
42
-
43
- public function test_execution_logs() {
44
- $action_id = as_schedule_single_action( time(), __METHOD__ );
45
- $logger = ActionScheduler::logger();
46
- $started = new ActionScheduler_LogEntry( $action_id, 'action started via Unit Tests' );
47
- $finished = new ActionScheduler_LogEntry( $action_id, 'action complete via Unit Tests' );
48
-
49
- $runner = ActionScheduler_Mocker::get_queue_runner();
50
- $runner->run( 'Unit Tests' );
51
-
52
- // Expect 3 logs with the correct action ID.
53
- $logs = $logger->get_logs( $action_id );
54
- $this->assertCount( 3, $logs );
55
- foreach ( $logs as $log ) {
56
- $this->assertEquals( $action_id, $log->get_action_id() );
57
- }
58
-
59
- // Expect created, then started, then completed.
60
- $this->assertEquals( 'action created', $logs[0]->get_message() );
61
- $this->assertEquals( $started->get_message(), $logs[1]->get_message() );
62
- $this->assertEquals( $finished->get_message(), $logs[2]->get_message() );
63
- }
64
-
65
- public function test_failed_execution_logs() {
66
- $hook = __METHOD__;
67
- add_action( $hook, array( $this, '_a_hook_callback_that_throws_an_exception' ) );
68
- $action_id = as_schedule_single_action( time(), $hook );
69
- $logger = ActionScheduler::logger();
70
- $started = new ActionScheduler_LogEntry( $action_id, 'action started via Unit Tests' );
71
- $finished = new ActionScheduler_LogEntry( $action_id, 'action complete via Unit Tests' );
72
- $failed = new ActionScheduler_LogEntry( $action_id, 'action failed via Unit Tests: Execution failed' );
73
-
74
- $runner = ActionScheduler_Mocker::get_queue_runner();
75
- $runner->run( 'Unit Tests' );
76
-
77
- // Expect 3 logs with the correct action ID.
78
- $logs = $logger->get_logs( $action_id );
79
- $this->assertCount( 3, $logs );
80
- foreach ( $logs as $log ) {
81
- $this->assertEquals( $action_id, $log->get_action_id() );
82
- $this->assertNotEquals( $finished->get_message(), $log->get_message() );
83
- }
84
-
85
- // Expect created, then started, then failed.
86
- $this->assertEquals( 'action created', $logs[0]->get_message() );
87
- $this->assertEquals( $started->get_message(), $logs[1]->get_message() );
88
- $this->assertEquals( $failed->get_message(), $logs[2]->get_message() );
89
- }
90
-
91
- public function test_fatal_error_log() {
92
- $action_id = as_schedule_single_action( time(), __METHOD__ );
93
- $logger = ActionScheduler::logger();
94
- do_action( 'action_scheduler_unexpected_shutdown', $action_id, array(
95
- 'type' => E_ERROR,
96
- 'message' => 'Test error',
97
- 'file' => __FILE__,
98
- 'line' => __LINE__,
99
- ));
100
-
101
- $logs = $logger->get_logs( $action_id );
102
- $found_log = FALSE;
103
- foreach ( $logs as $l ) {
104
- if ( strpos( $l->get_message(), 'unexpected shutdown' ) === 0 ) {
105
- $found_log = TRUE;
106
- }
107
- }
108
- $this->assertTrue( $found_log, 'Unexpected shutdown log not found' );
109
- }
110
-
111
- public function test_canceled_action_log() {
112
- $action_id = as_schedule_single_action( time(), __METHOD__ );
113
- as_unschedule_action( __METHOD__ );
114
- $logger = ActionScheduler::logger();
115
- $logs = $logger->get_logs( $action_id );
116
- $expected = new ActionScheduler_LogEntry( $action_id, 'action canceled' );
117
- $this->assertEquals( $expected->get_message(), end( $logs )->get_message() );
118
- }
119
-
120
- public function test_deleted_action_cleanup() {
121
- $time = as_get_datetime_object('-10 minutes');
122
- $schedule = new \ActionScheduler_SimpleSchedule($time);
123
- $action = new \ActionScheduler_Action('my_hook', array(), $schedule);
124
- $store = new ActionScheduler_DBStore();
125
- $action_id = $store->save_action($action);
126
-
127
- $logger = new ActionScheduler_DBLogger();
128
- $logs = $logger->get_logs( $action_id );
129
- $this->assertNotEmpty( $logs );
130
-
131
- $store->delete_action( $action_id );
132
- $logs = $logger->get_logs( $action_id );
133
- $this->assertEmpty( $logs );
134
- }
135
-
136
- public function _a_hook_callback_that_throws_an_exception() {
137
- throw new \RuntimeException('Execution failed');
138
- }
139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/logging/ActionScheduler_wpCommentLogger_Test.php CHANGED
@@ -5,16 +5,10 @@
5
  * @package test_cases\logging
6
  */
7
  class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase {
8
- private $use_comment_logger;
9
-
10
  public function test_default_logger() {
11
  $logger = ActionScheduler::logger();
12
  $this->assertInstanceOf( 'ActionScheduler_Logger', $logger );
13
- if ( $this->using_comment_logger() ) {
14
- $this->assertInstanceOf( 'ActionScheduler_wpCommentLogger', $logger );
15
- } else {
16
- $this->assertNotInstanceOf( 'ActionScheduler_wpCommentLogger', $logger );
17
- }
18
  }
19
 
20
  public function test_add_log_entry() {
@@ -89,11 +83,11 @@ class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase
89
  public function test_execution_comments() {
90
  $action_id = as_schedule_single_action( time(), 'a hook' );
91
  $logger = ActionScheduler::logger();
92
- $started = new ActionScheduler_LogEntry( $action_id, 'action started via Unit Tests' );
93
- $finished = new ActionScheduler_LogEntry( $action_id, 'action complete via Unit Tests' );
94
 
95
- $runner = ActionScheduler_Mocker::get_queue_runner();
96
- $runner->run( 'Unit Tests' );
97
 
98
  $logs = $logger->get_logs( $action_id );
99
  $this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
@@ -105,12 +99,12 @@ class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase
105
  add_action( $hook, array( $this, '_a_hook_callback_that_throws_an_exception' ) );
106
  $action_id = as_schedule_single_action( time(), $hook );
107
  $logger = ActionScheduler::logger();
108
- $started = new ActionScheduler_LogEntry( $action_id, 'action started via Unit Tests' );
109
- $finished = new ActionScheduler_LogEntry( $action_id, 'action complete via Unit Tests' );
110
- $failed = new ActionScheduler_LogEntry( $action_id, 'action failed via Unit Tests: Execution failed' );
111
 
112
- $runner = ActionScheduler_Mocker::get_queue_runner();
113
- $runner->run( 'Unit Tests' );
114
 
115
  $logs = $logger->get_logs( $action_id );
116
  $this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
@@ -118,21 +112,6 @@ class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase
118
  $this->assertTrue( in_array( $this->log_entry_to_array( $failed ), $this->log_entry_to_array( $logs ) ) );
119
  }
120
 
121
- public function test_failed_schedule_next_instance_comments() {
122
- $action_id = rand();
123
- $logger = ActionScheduler::logger();
124
- $log_entry = new ActionScheduler_LogEntry( $action_id, 'There was a failure scheduling the next instance of this action: Execution failed' );
125
-
126
- try {
127
- $this->_a_hook_callback_that_throws_an_exception();
128
- } catch ( Exception $e ) {
129
- do_action( 'action_scheduler_failed_to_schedule_next_instance', $action_id, $e, new ActionScheduler_Action('my_hook') );
130
- }
131
-
132
- $logs = $logger->get_logs( $action_id );
133
- $this->assertTrue( in_array( $this->log_entry_to_array( $log_entry ), $this->log_entry_to_array( $logs ) ) );
134
- }
135
-
136
  public function test_fatal_error_comments() {
137
  $hook = md5(rand());
138
  $action_id = as_schedule_single_action( time(), $hook );
@@ -168,10 +147,6 @@ class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase
168
  }
169
 
170
  public function test_filtering_of_get_comments() {
171
- if ( ! $this->using_comment_logger() ) {
172
- return;
173
- }
174
-
175
  $post_id = $this->factory->post->create_object(array(
176
  'post_title' => __FUNCTION__,
177
  ));
@@ -206,13 +181,5 @@ class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase
206
  $this->assertCount( 2, $comments );
207
  $this->assertContains( $log_id, wp_list_pluck($comments, 'comment_ID'));
208
  }
209
-
210
- private function using_comment_logger() {
211
- if ( null === $this->use_comment_logger ) {
212
- $this->use_comment_logger = ! ActionScheduler_DataController::dependencies_met();
213
- }
214
-
215
- return $this->use_comment_logger;
216
- }
217
  }
218
 
5
  * @package test_cases\logging
6
  */
7
  class ActionScheduler_wpCommentLogger_Test extends ActionScheduler_UnitTestCase {
 
 
8
  public function test_default_logger() {
9
  $logger = ActionScheduler::logger();
10
  $this->assertInstanceOf( 'ActionScheduler_Logger', $logger );
11
+ $this->assertInstanceOf( 'ActionScheduler_wpCommentLogger', $logger );
 
 
 
 
12
  }
13
 
14
  public function test_add_log_entry() {
83
  public function test_execution_comments() {
84
  $action_id = as_schedule_single_action( time(), 'a hook' );
85
  $logger = ActionScheduler::logger();
86
+ $started = new ActionScheduler_LogEntry( $action_id, 'action started' );
87
+ $finished = new ActionScheduler_LogEntry( $action_id, 'action complete' );
88
 
89
+ $runner = new ActionScheduler_QueueRunner();
90
+ $runner->run();
91
 
92
  $logs = $logger->get_logs( $action_id );
93
  $this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
99
  add_action( $hook, array( $this, '_a_hook_callback_that_throws_an_exception' ) );
100
  $action_id = as_schedule_single_action( time(), $hook );
101
  $logger = ActionScheduler::logger();
102
+ $started = new ActionScheduler_LogEntry( $action_id, 'action started' );
103
+ $finished = new ActionScheduler_LogEntry( $action_id, 'action complete' );
104
+ $failed = new ActionScheduler_LogEntry( $action_id, 'action failed: Execution failed' );
105
 
106
+ $runner = new ActionScheduler_QueueRunner();
107
+ $runner->run();
108
 
109
  $logs = $logger->get_logs( $action_id );
110
  $this->assertTrue( in_array( $this->log_entry_to_array( $started ), $this->log_entry_to_array( $logs ) ) );
112
  $this->assertTrue( in_array( $this->log_entry_to_array( $failed ), $this->log_entry_to_array( $logs ) ) );
113
  }
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  public function test_fatal_error_comments() {
116
  $hook = md5(rand());
117
  $action_id = as_schedule_single_action( time(), $hook );
147
  }
148
 
149
  public function test_filtering_of_get_comments() {
 
 
 
 
150
  $post_id = $this->factory->post->create_object(array(
151
  'post_title' => __FUNCTION__,
152
  ));
181
  $this->assertCount( 2, $comments );
182
  $this->assertContains( $log_id, wp_list_pluck($comments, 'comment_ID'));
183
  }
 
 
 
 
 
 
 
 
184
  }
185
 
includes/vendor/action-scheduler/tests/phpunit/migration/ActionMigrator_Test.php DELETED
@@ -1,145 +0,0 @@
1
- <?php
2
-
3
- use Action_Scheduler\Migration\ActionMigrator;
4
- use Action_Scheduler\Migration\LogMigrator;
5
-
6
- /**
7
- * Class ActionMigrator_Test
8
- * @group migration
9
- */
10
- class ActionMigrator_Test extends ActionScheduler_UnitTestCase {
11
- public function setUp() {
12
- parent::setUp();
13
- if ( ! taxonomy_exists( ActionScheduler_wpPostStore::GROUP_TAXONOMY ) ) {
14
- // register the post type and taxonomy necessary for the store to work
15
- $store = new ActionScheduler_wpPostStore();
16
- $store->init();
17
- }
18
- }
19
-
20
- public function test_migrate_from_wpPost_to_db() {
21
- $source = new ActionScheduler_wpPostStore();
22
- $destination = new ActionScheduler_DBStore();
23
- $migrator = new ActionMigrator( $source, $destination, $this->get_log_migrator() );
24
-
25
- $time = as_get_datetime_object();
26
- $schedule = new ActionScheduler_SimpleSchedule( $time );
27
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
28
- $action_id = $source->save_action( $action );
29
-
30
- $new_id = $migrator->migrate( $action_id );
31
-
32
- // ensure we get the same record out of the new store as we stored in the old
33
- $retrieved = $destination->fetch_action( $new_id );
34
- $this->assertEquals( $action->get_hook(), $retrieved->get_hook() );
35
- $this->assertEqualSets( $action->get_args(), $retrieved->get_args() );
36
- $this->assertEquals( $action->get_schedule()->get_date()->format( 'U' ), $retrieved->get_schedule()->get_date()->format( 'U' ) );
37
- $this->assertEquals( $action->get_group(), $retrieved->get_group() );
38
- $this->assertEquals( \ActionScheduler_Store::STATUS_PENDING, $destination->get_status( $new_id ) );
39
-
40
-
41
- // ensure that the record in the old store does not exist
42
- $old_action = $source->fetch_action( $action_id );
43
- $this->assertInstanceOf( 'ActionScheduler_NullAction', $old_action );
44
- }
45
-
46
- public function test_does_not_migrate_missing_action_from_wpPost_to_db() {
47
- $source = new ActionScheduler_wpPostStore();
48
- $destination = new ActionScheduler_DBStore();
49
- $migrator = new ActionMigrator( $source, $destination, $this->get_log_migrator() );
50
-
51
- $action_id = rand( 100, 100000 );
52
-
53
- $new_id = $migrator->migrate( $action_id );
54
- $this->assertEquals( 0, $new_id );
55
-
56
- // ensure we get the same record out of the new store as we stored in the old
57
- $retrieved = $destination->fetch_action( $new_id );
58
- $this->assertInstanceOf( 'ActionScheduler_NullAction', $retrieved );
59
- }
60
-
61
- public function test_migrate_completed_action_from_wpPost_to_db() {
62
- $source = new ActionScheduler_wpPostStore();
63
- $destination = new ActionScheduler_DBStore();
64
- $migrator = new ActionMigrator( $source, $destination, $this->get_log_migrator() );
65
-
66
- $time = as_get_datetime_object();
67
- $schedule = new ActionScheduler_SimpleSchedule( $time );
68
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
69
- $action_id = $source->save_action( $action );
70
- $source->mark_complete( $action_id );
71
-
72
- $new_id = $migrator->migrate( $action_id );
73
-
74
- // ensure we get the same record out of the new store as we stored in the old
75
- $retrieved = $destination->fetch_action( $new_id );
76
- $this->assertEquals( $action->get_hook(), $retrieved->get_hook() );
77
- $this->assertEqualSets( $action->get_args(), $retrieved->get_args() );
78
- $this->assertEquals( $action->get_schedule()->get_date()->format( 'U' ), $retrieved->get_schedule()->get_date()->format( 'U' ) );
79
- $this->assertEquals( $action->get_group(), $retrieved->get_group() );
80
- $this->assertTrue( $retrieved->is_finished() );
81
- $this->assertEquals( \ActionScheduler_Store::STATUS_COMPLETE, $destination->get_status( $new_id ) );
82
-
83
- // ensure that the record in the old store does not exist
84
- $old_action = $source->fetch_action( $action_id );
85
- $this->assertInstanceOf( 'ActionScheduler_NullAction', $old_action );
86
- }
87
-
88
- public function test_migrate_failed_action_from_wpPost_to_db() {
89
- $source = new ActionScheduler_wpPostStore();
90
- $destination = new ActionScheduler_DBStore();
91
- $migrator = new ActionMigrator( $source, $destination, $this->get_log_migrator() );
92
-
93
- $time = as_get_datetime_object();
94
- $schedule = new ActionScheduler_SimpleSchedule( $time );
95
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
96
- $action_id = $source->save_action( $action );
97
- $source->mark_failure( $action_id );
98
-
99
- $new_id = $migrator->migrate( $action_id );
100
-
101
- // ensure we get the same record out of the new store as we stored in the old
102
- $retrieved = $destination->fetch_action( $new_id );
103
- $this->assertEquals( $action->get_hook(), $retrieved->get_hook() );
104
- $this->assertEqualSets( $action->get_args(), $retrieved->get_args() );
105
- $this->assertEquals( $action->get_schedule()->get_date()->format( 'U' ), $retrieved->get_schedule()->get_date()->format( 'U' ) );
106
- $this->assertEquals( $action->get_group(), $retrieved->get_group() );
107
- $this->assertTrue( $retrieved->is_finished() );
108
- $this->assertEquals( \ActionScheduler_Store::STATUS_FAILED, $destination->get_status( $new_id ) );
109
-
110
- // ensure that the record in the old store does not exist
111
- $old_action = $source->fetch_action( $action_id );
112
- $this->assertInstanceOf( 'ActionScheduler_NullAction', $old_action );
113
- }
114
-
115
- public function test_migrate_canceled_action_from_wpPost_to_db() {
116
- $source = new ActionScheduler_wpPostStore();
117
- $destination = new ActionScheduler_DBStore();
118
- $migrator = new ActionMigrator( $source, $destination, $this->get_log_migrator() );
119
-
120
- $time = as_get_datetime_object();
121
- $schedule = new ActionScheduler_SimpleSchedule( $time );
122
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule, 'my_group' );
123
- $action_id = $source->save_action( $action );
124
- $source->cancel_action( $action_id );
125
-
126
- $new_id = $migrator->migrate( $action_id );
127
-
128
- // ensure we get the same record out of the new store as we stored in the old
129
- $retrieved = $destination->fetch_action( $new_id );
130
- $this->assertEquals( $action->get_hook(), $retrieved->get_hook() );
131
- $this->assertEqualSets( $action->get_args(), $retrieved->get_args() );
132
- $this->assertEquals( $action->get_schedule()->get_date()->format( 'U' ), $retrieved->get_schedule()->get_date()->format( 'U' ) );
133
- $this->assertEquals( $action->get_group(), $retrieved->get_group() );
134
- $this->assertTrue( $retrieved->is_finished() );
135
- $this->assertEquals( \ActionScheduler_Store::STATUS_CANCELED, $destination->get_status( $new_id ) );
136
-
137
- // ensure that the record in the old store does not exist
138
- $old_action = $source->fetch_action( $action_id );
139
- $this->assertInstanceOf( 'ActionScheduler_NullAction', $old_action );
140
- }
141
-
142
- private function get_log_migrator() {
143
- return new LogMigrator( \ActionScheduler::logger(), new ActionScheduler_DBLogger() );
144
- }
145
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/migration/BatchFetcher_Test.php DELETED
@@ -1,76 +0,0 @@
1
- <?php
2
-
3
- use Action_Scheduler\Migration\BatchFetcher;
4
- use ActionScheduler_wpPostStore as PostStore;
5
-
6
- /**
7
- * Class BatchFetcher_Test
8
- * @group migration
9
- */
10
- class BatchFetcher_Test extends ActionScheduler_UnitTestCase {
11
- public function setUp() {
12
- parent::setUp();
13
- if ( ! taxonomy_exists( PostStore::GROUP_TAXONOMY ) ) {
14
- // register the post type and taxonomy necessary for the store to work
15
- $store = new PostStore();
16
- $store->init();
17
- }
18
- }
19
-
20
- public function test_nothing_to_migrate() {
21
- $store = new PostStore();
22
- $batch_fetcher = new BatchFetcher( $store );
23
-
24
- $actions = $batch_fetcher->fetch();
25
- $this->assertEmpty( $actions );
26
- }
27
-
28
- public function test_get_due_before_future() {
29
- $store = new PostStore();
30
- $due = [];
31
- $future = [];
32
-
33
- for ( $i = 0; $i < 5; $i ++ ) {
34
- $time = as_get_datetime_object( $i + 1 . ' minutes' );
35
- $schedule = new ActionScheduler_SimpleSchedule( $time );
36
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
37
- $future[] = $store->save_action( $action );
38
-
39
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
40
- $schedule = new ActionScheduler_SimpleSchedule( $time );
41
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
42
- $due[] = $store->save_action( $action );
43
- }
44
-
45
- $batch_fetcher = new BatchFetcher( $store );
46
-
47
- $actions = $batch_fetcher->fetch();
48
-
49
- $this->assertEqualSets( $due, $actions );
50
- }
51
-
52
-
53
- public function test_get_future_before_complete() {
54
- $store = new PostStore();
55
- $future = [];
56
- $complete = [];
57
-
58
- for ( $i = 0; $i < 5; $i ++ ) {
59
- $time = as_get_datetime_object( $i + 1 . ' minutes' );
60
- $schedule = new ActionScheduler_SimpleSchedule( $time );
61
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
62
- $future[] = $store->save_action( $action );
63
-
64
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
65
- $schedule = new ActionScheduler_SimpleSchedule( $time );
66
- $action = new ActionScheduler_FinishedAction( 'my_hook', [], $schedule );
67
- $complete[] = $store->save_action( $action );
68
- }
69
-
70
- $batch_fetcher = new BatchFetcher( $store );
71
-
72
- $actions = $batch_fetcher->fetch();
73
-
74
- $this->assertEqualSets( $future, $actions );
75
- }
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/migration/Config_Test.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- use Action_Scheduler\Migration\Config;
4
-
5
- /**
6
- * Class Config_Test
7
- * @group migration
8
- */
9
- class Config_Test extends ActionScheduler_UnitTestCase {
10
- public function test_source_store_required() {
11
- $config = new Config();
12
- $this->expectException( \RuntimeException::class );
13
- $config->get_source_store();
14
- }
15
-
16
- public function test_source_logger_required() {
17
- $config = new Config();
18
- $this->expectException( \RuntimeException::class );
19
- $config->get_source_logger();
20
- }
21
-
22
- public function test_destination_store_required() {
23
- $config = new Config();
24
- $this->expectException( \RuntimeException::class );
25
- $config->get_destination_store();
26
- }
27
-
28
- public function test_destination_logger_required() {
29
- $config = new Config();
30
- $this->expectException( \RuntimeException::class );
31
- $config->get_destination_logger();
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/migration/LogMigrator_Test.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- use Action_Scheduler\Migration\LogMigrator;
4
-
5
- /**
6
- * Class LogMigrator_Test
7
- * @group migration
8
- */
9
- class LogMigrator_Test extends ActionScheduler_UnitTestCase {
10
- function setUp() {
11
- parent::setUp();
12
- if ( ! taxonomy_exists( ActionScheduler_wpPostStore::GROUP_TAXONOMY ) ) {
13
- // register the post type and taxonomy necessary for the store to work
14
- $store = new ActionScheduler_wpPostStore();
15
- $store->init();
16
- }
17
- }
18
-
19
- public function test_migrate_from_wpComment_to_db() {
20
- $source = new ActionScheduler_wpCommentLogger();
21
- $destination = new ActionScheduler_DBLogger();
22
- $migrator = new LogMigrator( $source, $destination );
23
- $source_action_id = rand( 10, 10000 );
24
- $destination_action_id = rand( 10, 10000 );
25
-
26
- $logs = [];
27
- for ( $i = 0 ; $i < 3 ; $i++ ) {
28
- for ( $j = 0 ; $j < 5 ; $j++ ) {
29
- $logs[ $i ][ $j ] = md5(rand());
30
- if ( $i == 1 ) {
31
- $source->log( $source_action_id, $logs[ $i ][ $j ] );
32
- }
33
- }
34
- }
35
-
36
- $migrator->migrate( $source_action_id, $destination_action_id );
37
-
38
- $migrated = $destination->get_logs( $destination_action_id );
39
- $this->assertEqualSets( $logs[ 1 ], array_map( function( $log ) { return $log->get_message(); }, $migrated ) );
40
-
41
- // no API for deleting logs, so we leave them for manual cleanup later
42
- $this->assertCount( 5, $source->get_logs( $source_action_id ) );
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/migration/Runner_Test.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
-
3
-
4
- use Action_Scheduler\Migration\Config;
5
- use Action_Scheduler\Migration\Runner;
6
- use ActionScheduler_wpCommentLogger as CommentLogger;
7
- use ActionScheduler_wpPostStore as PostStore;
8
-
9
- /**
10
- * Class Runner_Test
11
- * @group migration
12
- */
13
- class Runner_Test extends ActionScheduler_UnitTestCase {
14
- public function setUp() {
15
- parent::setUp();
16
- if ( ! taxonomy_exists( PostStore::GROUP_TAXONOMY ) ) {
17
- // register the post type and taxonomy necessary for the store to work
18
- $store = new PostStore();
19
- $store->init();
20
- }
21
- }
22
-
23
- public function test_migrate_batches() {
24
- $source_store = new PostStore();
25
- $destination_store = new ActionScheduler_DBStore();
26
- $source_logger = new CommentLogger();
27
- $destination_logger = new ActionScheduler_DBLogger();
28
-
29
- $config = new Config();
30
- $config->set_source_store( $source_store );
31
- $config->set_source_logger( $source_logger );
32
- $config->set_destination_store( $destination_store );
33
- $config->set_destination_logger( $destination_logger );
34
-
35
- $runner = new Runner( $config );
36
-
37
- $due = [];
38
- $future = [];
39
- $complete = [];
40
-
41
- for ( $i = 0; $i < 5; $i ++ ) {
42
- $time = as_get_datetime_object( $i + 1 . ' minutes' );
43
- $schedule = new ActionScheduler_SimpleSchedule( $time );
44
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
45
- $future[] = $source_store->save_action( $action );
46
-
47
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
48
- $schedule = new ActionScheduler_SimpleSchedule( $time );
49
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
50
- $due[] = $source_store->save_action( $action );
51
-
52
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
53
- $schedule = new ActionScheduler_SimpleSchedule( $time );
54
- $action = new ActionScheduler_FinishedAction( 'my_hook', [], $schedule );
55
- $complete[] = $source_store->save_action( $action );
56
- }
57
-
58
- $created = $source_store->query_actions( [ 'per_page' => 0 ] );
59
- $this->assertCount( 15, $created );
60
-
61
- $runner->run( 10 );
62
-
63
- // due actions should migrate in the first batch
64
- $migrated = $destination_store->query_actions( [ 'per_page' => 0 ] );
65
- $this->assertCount( 5, $migrated );
66
-
67
- $remaining = $source_store->query_actions( [ 'per_page' => 0 ] );
68
- $this->assertCount( 10, $remaining );
69
-
70
-
71
- $runner->run( 10 );
72
-
73
- // pending actions should migrate in the second batch
74
- $migrated = $destination_store->query_actions( [ 'per_page' => 0 ] );
75
- $this->assertCount( 10, $migrated );
76
-
77
- $remaining = $source_store->query_actions( [ 'per_page' => 0 ] );
78
- $this->assertCount( 5, $remaining );
79
-
80
-
81
- $runner->run( 10 );
82
-
83
- // completed actions should migrate in the third batch
84
- $migrated = $destination_store->query_actions( [ 'per_page' => 0 ] );
85
- $this->assertCount( 15, $migrated );
86
-
87
- $remaining = $source_store->query_actions( [ 'per_page' => 0 ] );
88
- $this->assertCount( 0, $remaining );
89
-
90
- }
91
-
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/migration/Scheduler_Test.php DELETED
@@ -1,122 +0,0 @@
1
- <?php
2
-
3
- use Action_Scheduler\Migration\Scheduler;
4
- use ActionScheduler_wpPostStore as PostStore;
5
-
6
- /**
7
- * Class Scheduler_Test
8
- * @group migration
9
- */
10
- class Scheduler_Test extends ActionScheduler_UnitTestCase {
11
- public function setUp() {
12
- parent::setUp();
13
- if ( ! taxonomy_exists( PostStore::GROUP_TAXONOMY ) ) {
14
- // register the post type and taxonomy necessary for the store to work
15
- $store = new PostStore();
16
- $store->init();
17
- }
18
- }
19
-
20
- public function test_migration_is_complete() {
21
- ActionScheduler_DataController::mark_migration_complete();
22
- $this->assertTrue( ActionScheduler_DataController::is_migration_complete() );
23
- }
24
-
25
- public function test_migration_is_not_complete() {
26
- $this->assertFalse( ActionScheduler_DataController::is_migration_complete() );
27
- update_option( ActionScheduler_DataController::STATUS_FLAG, 'something_random' );
28
- $this->assertFalse( ActionScheduler_DataController::is_migration_complete() );
29
- }
30
-
31
- public function test_migration_is_scheduled() {
32
- $scheduler = new Scheduler();
33
- $scheduler->schedule_migration();
34
- $this->assertTrue( $scheduler->is_migration_scheduled() );
35
- }
36
-
37
- public function test_migration_is_not_scheduled() {
38
- $scheduler = new Scheduler();
39
- $this->assertFalse( $scheduler->is_migration_scheduled() );
40
- }
41
-
42
- public function test_scheduler_runs_migration() {
43
- $source_store = new PostStore();
44
- $destination_store = new ActionScheduler_DBStore();
45
-
46
- $return_5 = function () {
47
- return 5;
48
- };
49
- add_filter( 'action_scheduler/migration_batch_size', $return_5 );
50
-
51
- // Make sure successive migration actions are delayed so all actions aren't migrated at once on separate hooks
52
- $return_60 = function () {
53
- return 60;
54
- };
55
- add_filter( 'action_scheduler/migration_interval', $return_60 );
56
-
57
- for ( $i = 0; $i < 10; $i ++ ) {
58
- $time = as_get_datetime_object( $i + 1 . ' minutes' );
59
- $schedule = new ActionScheduler_SimpleSchedule( $time );
60
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
61
- $future[] = $source_store->save_action( $action );
62
-
63
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
64
- $schedule = new ActionScheduler_SimpleSchedule( $time );
65
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
66
- $due[] = $source_store->save_action( $action );
67
- }
68
-
69
- $this->assertCount( 20, $source_store->query_actions( [ 'per_page' => 0 ] ) );
70
-
71
- $scheduler = new Scheduler();
72
- $scheduler->schedule_migration();
73
-
74
- $queue_runner = ActionScheduler_Mocker::get_queue_runner( $destination_store );
75
- $queue_runner->run();
76
-
77
- // 5 actions should have moved from the source store when the queue runner triggered the migration action
78
- $this->assertCount( 15, $source_store->query_actions( [ 'per_page' => 0 ] ) );
79
-
80
- remove_filter( 'action_scheduler/migration_batch_size', $return_5 );
81
- remove_filter( 'action_scheduler/migration_interval', $return_60 );
82
- }
83
-
84
- public function test_scheduler_marks_itself_complete() {
85
- $source_store = new PostStore();
86
- $destination_store = new ActionScheduler_DBStore();
87
-
88
- for ( $i = 0; $i < 5; $i ++ ) {
89
- $time = as_get_datetime_object( $i + 1 . ' minutes ago' );
90
- $schedule = new ActionScheduler_SimpleSchedule( $time );
91
- $action = new ActionScheduler_Action( 'my_hook', [], $schedule );
92
- $due[] = $source_store->save_action( $action );
93
- }
94
-
95
- $this->assertCount( 5, $source_store->query_actions( [ 'per_page' => 0 ] ) );
96
-
97
- $scheduler = new Scheduler();
98
- $scheduler->schedule_migration();
99
-
100
- $queue_runner = ActionScheduler_Mocker::get_queue_runner( $destination_store );
101
- $queue_runner->run();
102
-
103
- // All actions should have moved from the source store when the queue runner triggered the migration action
104
- $this->assertCount( 0, $source_store->query_actions( [ 'per_page' => 0 ] ) );
105
-
106
- // schedule another so we can get it to run immediately
107
- $scheduler->unschedule_migration();
108
- $scheduler->schedule_migration();
109
-
110
- // run again so it knows that there's nothing left to process
111
- $queue_runner->run();
112
-
113
- $scheduler->unhook();
114
-
115
- // ensure the flag is set marking migration as complete
116
- $this->assertTrue( ActionScheduler_DataController::is_migration_complete() );
117
-
118
- // ensure that another instance has not been scheduled
119
- $this->assertFalse( $scheduler->is_migration_scheduled() );
120
-
121
- }
122
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/vendor/action-scheduler/tests/phpunit/procedural_api/procedural_api_Test.php CHANGED
@@ -12,7 +12,7 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
12
 
13
  $store = ActionScheduler::store();
14
  $action = $store->fetch_action($action_id);
15
- $this->assertEquals( $time, $action->get_schedule()->get_date()->getTimestamp() );
16
  $this->assertEquals( $hook, $action->get_hook() );
17
  }
18
 
@@ -23,8 +23,8 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
23
 
24
  $store = ActionScheduler::store();
25
  $action = $store->fetch_action($action_id);
26
- $this->assertEquals( $time, $action->get_schedule()->get_date()->getTimestamp() );
27
- $this->assertEquals( $time + HOUR_IN_SECONDS + 2, $action->get_schedule()->get_next(as_get_datetime_object($time + 2))->getTimestamp());
28
  $this->assertEquals( $hook, $action->get_hook() );
29
  }
30
 
@@ -36,11 +36,8 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
36
  $store = ActionScheduler::store();
37
  $action = $store->fetch_action($action_id);
38
  $expected_date = as_get_datetime_object('2014-10-10');
39
- $this->assertEquals( $expected_date->getTimestamp(), $action->get_schedule()->get_date()->getTimestamp() );
40
  $this->assertEquals( $hook, $action->get_hook() );
41
-
42
- $expected_date = as_get_datetime_object( '2015-10-10' );
43
- $this->assertEquals( $expected_date->getTimestamp(), $action->get_schedule()->get_next( as_get_datetime_object( '2015-01-02' ) )->getTimestamp() );
44
  }
45
 
46
  public function test_get_next() {
@@ -53,32 +50,6 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
53
  $this->assertEquals( $time->getTimestamp(), $next );
54
  }
55
 
56
- public function test_get_next_async() {
57
- $hook = md5(rand());
58
- $action_id = as_enqueue_async_action( $hook );
59
-
60
- $next = as_next_scheduled_action( $hook );
61
-
62
- $this->assertTrue( $next );
63
-
64
- $store = ActionScheduler::store();
65
-
66
- // Completed async actions should still return false
67
- $store->mark_complete( $action_id );
68
- $next = as_next_scheduled_action( $hook );
69
- $this->assertFalse( $next );
70
-
71
- // Failed async actions should still return false
72
- $store->mark_failure( $action_id );
73
- $next = as_next_scheduled_action( $hook );
74
- $this->assertFalse( $next );
75
-
76
- // Cancelled async actions should still return false
77
- $store->cancel_action( $action_id );
78
- $next = as_next_scheduled_action( $hook );
79
- $this->assertFalse( $next );
80
- }
81
-
82
  public function provider_time_hook_args_group() {
83
  $time = time() + 60 * 2;
84
  $hook = md5( rand() );
@@ -140,16 +111,13 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
140
 
141
  // Make sure the next scheduled action is unscheduled
142
  $this->assertEquals( $hook, $unscheduled_action->get_hook() );
143
- $this->assertEquals( as_get_datetime_object($time), $unscheduled_action->get_schedule()->get_date() );
144
- $this->assertEquals( ActionScheduler_Store::STATUS_CANCELED, $store->get_status( $action_id_unscheduled ) );
145
- $this->assertNull( $unscheduled_action->get_schedule()->get_next( as_get_datetime_object() ) );
146
 
147
  // Make sure other scheduled actions are not unscheduled
148
- $this->assertEquals( ActionScheduler_Store::STATUS_PENDING, $store->get_status( $action_id_scheduled ) );
149
  $scheduled_action = $store->fetch_action( $action_id_scheduled );
150
 
151
  $this->assertEquals( $hook, $scheduled_action->get_hook() );
152
- $this->assertEquals( $action_scheduled_time, $scheduled_action->get_schedule()->get_date()->getTimestamp() );
153
  }
154
 
155
  /**
@@ -169,18 +137,13 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
169
  $next = as_next_scheduled_action( $hook );
170
  $this->assertFalse($next);
171
 
172
- $after = as_get_datetime_object( $time );
173
- $after->modify( '+1 minute' );
174
-
175
  $store = ActionScheduler::store();
176
 
177
  foreach ( $action_ids as $action_id ) {
178
  $action = $store->fetch_action($action_id);
179
 
180
- $this->assertEquals( $hook, $action->get_hook() );
181
- $this->assertEquals( as_get_datetime_object( $time ), $action->get_schedule()->get_date() );
182
- $this->assertEquals( ActionScheduler_Store::STATUS_CANCELED, $store->get_status( $action_id ) );
183
- $this->assertNull( $action->get_schedule()->get_next( $after ) );
184
  }
185
  }
186
 
@@ -238,7 +201,7 @@ class procedural_api_Test extends ActionScheduler_UnitTestCase {
238
  $au_now = new ActionScheduler_DateTime(null);
239
  $as_au_now = as_get_datetime_object();
240
 
241
- $this->assertEquals( $au_now->getTimestamp(), $as_now->getTimestamp(), '', 2 );
242
 
243
  // But not in the same timezone, as $as_now should be using UTC
244
  $this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s'));
12
 
13
  $store = ActionScheduler::store();
14
  $action = $store->fetch_action($action_id);
15
+ $this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() );
16
  $this->assertEquals( $hook, $action->get_hook() );
17
  }
18
 
23
 
24
  $store = ActionScheduler::store();
25
  $action = $store->fetch_action($action_id);
26
+ $this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() );
27
+ $this->assertEquals( $time + HOUR_IN_SECONDS + 2, $action->get_schedule()->next(as_get_datetime_object($time + 2))->getTimestamp());
28
  $this->assertEquals( $hook, $action->get_hook() );
29
  }
30
 
36
  $store = ActionScheduler::store();
37
  $action = $store->fetch_action($action_id);
38
  $expected_date = as_get_datetime_object('2014-10-10');
39
+ $this->assertEquals( $expected_date->getTimestamp(), $action->get_schedule()->next()->getTimestamp() );
40
  $this->assertEquals( $hook, $action->get_hook() );
 
 
 
41
  }
42
 
43
  public function test_get_next() {
50
  $this->assertEquals( $time->getTimestamp(), $next );
51
  }
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  public function provider_time_hook_args_group() {
54
  $time = time() + 60 * 2;
55
  $hook = md5( rand() );
111
 
112
  // Make sure the next scheduled action is unscheduled
113
  $this->assertEquals( $hook, $unscheduled_action->get_hook() );
114
+ $this->assertNull( $unscheduled_action->get_schedule()->next() );
 
 
115
 
116
  // Make sure other scheduled actions are not unscheduled
 
117
  $scheduled_action = $store->fetch_action( $action_id_scheduled );
118
 
119
  $this->assertEquals( $hook, $scheduled_action->get_hook() );
120
+ $this->assertEquals( $action_scheduled_time, $scheduled_action->get_schedule()->next()->getTimestamp() );
121
  }
122
 
123
  /**
137
  $next = as_next_scheduled_action( $hook );
138
  $this->assertFalse($next);
139
 
 
 
 
140
  $store = ActionScheduler::store();
141
 
142
  foreach ( $action_ids as $action_id ) {
143
  $action = $store->fetch_action($action_id);
144
 
145
+ $this->assertNull($action->get_schedule()->next());
146
+ $this->assertEquals($hook, $action->get_hook() );
 
 
147
  }
148
  }
149
 
201
  $au_now = new ActionScheduler_DateTime(null);
202
  $as_au_now = as_get_datetime_object();
203
 
204
+ $this->assertEquals($au_now->getTimestamp(),$as_now->getTimestamp());
205
 
206
  // But not in the same timezone, as $as_now should be using UTC
207
  $this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s'));
includes/vendor/action-scheduler/tests/phpunit/runner/ActionScheduler_QueueCleaner_Test.php CHANGED
@@ -7,7 +7,7 @@ class ActionScheduler_QueueCleaner_Test extends ActionScheduler_UnitTestCase {
7
 
8
  public function test_delete_old_actions() {
9
  $store = ActionScheduler::store();
10
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
11
 
12
  $random = md5(rand());
13
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
@@ -62,7 +62,7 @@ class ActionScheduler_QueueCleaner_Test extends ActionScheduler_UnitTestCase {
62
 
63
  public function test_do_not_delete_recent_actions() {
64
  $store = ActionScheduler::store();
65
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
66
 
67
  $random = md5(rand());
68
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
7
 
8
  public function test_delete_old_actions() {
9
  $store = ActionScheduler::store();
10
+ $runner = new ActionScheduler_QueueRunner( $store );
11
 
12
  $random = md5(rand());
13
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
62
 
63
  public function test_do_not_delete_recent_actions() {
64
  $store = ActionScheduler::store();
65
+ $runner = new ActionScheduler_QueueRunner( $store );
66
 
67
  $random = md5(rand());
68
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('1 day ago'));
includes/vendor/action-scheduler/tests/phpunit/runner/ActionScheduler_QueueRunner_Test.php CHANGED
@@ -7,7 +7,7 @@
7
  class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
8
  public function test_create_runner() {
9
  $store = ActionScheduler::store();
10
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
11
  $actions_run = $runner->run();
12
 
13
  $this->assertEquals( 0, $actions_run );
@@ -15,7 +15,7 @@ class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
15
 
16
  public function test_run() {
17
  $store = ActionScheduler::store();
18
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
19
 
20
  $mock = new MockAction();
21
  $random = md5(rand());
@@ -37,7 +37,7 @@ class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
37
 
38
  public function test_run_with_future_actions() {
39
  $store = ActionScheduler::store();
40
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
41
 
42
  $mock = new MockAction();
43
  $random = md5(rand());
@@ -65,7 +65,7 @@ class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
65
 
66
  public function test_completed_action_status() {
67
  $store = ActionScheduler::store();
68
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
69
 
70
  $random = md5(rand());
71
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('12 hours ago'));
@@ -80,145 +80,77 @@ class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
80
  $this->assertTrue( $finished_action->is_finished() );
81
  }
82
 
83
- public function test_next_instance_of_cron_action() {
84
- // Create an action with daily Cron expression (i.e. midnight each day)
85
- $random = md5( rand() );
86
- $action_id = ActionScheduler::factory()->cron( $random, array(), null, '0 0 * * *' );
87
- $store = ActionScheduler::store();
88
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
89
-
90
- // Make sure the 1st instance of the action is scheduled to occur tomorrow
91
- $date = as_get_datetime_object( 'tomorrow' );
92
- $date->modify( '-1 minute' );
93
- $claim = $store->stake_claim( 10, $date );
94
- $this->assertCount( 0, $claim->get_actions() );
95
-
96
- $store->release_claim( $claim );
97
-
98
- $date->modify( '+1 minute' );
99
-
100
- $claim = $store->stake_claim( 10, $date );
101
- $actions = $claim->get_actions();
102
- $this->assertCount( 1, $actions );
103
-
104
- $fetched_action_id = reset( $actions );
105
- $fetched_action = $store->fetch_action( $fetched_action_id );
106
-
107
- $this->assertEquals( $fetched_action_id, $action_id );
108
- $this->assertEquals( $random, $fetched_action->get_hook() );
109
- $this->assertEquals( $date->getTimestamp(), $fetched_action->get_schedule()->get_date()->getTimestamp(), '', 1 );
110
-
111
- $store->release_claim( $claim );
112
-
113
- // Make sure the 2nd instance of the cron action is scheduled to occur tomorrow still
114
- $runner->process_action( $action_id );
115
-
116
- $claim = $store->stake_claim( 10, $date );
117
- $actions = $claim->get_actions();
118
- $this->assertCount( 1, $actions );
119
-
120
- $fetched_action_id = reset( $actions );
121
- $fetched_action = $store->fetch_action( $fetched_action_id );
122
-
123
- $this->assertNotEquals( $fetched_action_id, $action_id );
124
- $this->assertEquals( $random, $fetched_action->get_hook() );
125
- $this->assertEquals( $date->getTimestamp(), $fetched_action->get_schedule()->get_date()->getTimestamp(), '', 1 );
126
- }
127
-
128
- public function test_next_instance_of_interval_action() {
129
- // Create an action to recur every 24 hours, with the first instance scheduled to run 12 hours ago
130
- $random = md5( rand() );
131
- $date = as_get_datetime_object( '12 hours ago' );
132
- $action_id = ActionScheduler::factory()->recurring( $random, array(), $date->getTimestamp(), DAY_IN_SECONDS );
133
- $store = ActionScheduler::store();
134
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
135
-
136
- // Make sure the 1st instance of the action is scheduled to occur 12 hours ago
137
- $claim = $store->stake_claim( 10, $date );
138
- $actions = $claim->get_actions();
139
- $this->assertCount( 1, $actions );
140
-
141
- $fetched_action_id = reset( $actions );
142
- $fetched_action = $store->fetch_action( $fetched_action_id );
143
 
144
- $this->assertEquals( $fetched_action_id, $action_id );
145
- $this->assertEquals( $random, $fetched_action->get_hook() );
146
- $this->assertEquals( $date->getTimestamp(), $fetched_action->get_schedule()->get_date()->getTimestamp(), '', 1 );
147
 
148
- $store->release_claim( $claim );
 
149
 
150
- // Make sure after the queue is run, the 2nd instance of the action is scheduled to occur in 24 hours
151
  $runner->run();
152
 
153
- $date = as_get_datetime_object( '+1 day' );
154
- $claim = $store->stake_claim( 10, $date );
155
- $actions = $claim->get_actions();
156
- $this->assertCount( 1, $actions );
157
-
158
- $fetched_action_id = reset( $actions );
159
- $fetched_action = $store->fetch_action( $fetched_action_id );
160
-
161
- $this->assertNotEquals( $fetched_action_id, $action_id );
162
- $this->assertEquals( $random, $fetched_action->get_hook() );
163
- $this->assertEquals( $date->getTimestamp(), $fetched_action->get_schedule()->get_date()->getTimestamp(), '', 1 );
164
-
165
- $store->release_claim( $claim );
166
-
167
- // Make sure the 3rd instance of the cron action is scheduled for 24 hours from now, as the action was run early, ahead of schedule
168
- $runner->process_action( $action_id );
169
- $date = as_get_datetime_object( '+1 day' );
170
 
171
- $claim = $store->stake_claim( 10, $date );
172
  $actions = $claim->get_actions();
173
- $this->assertCount( 1, $actions );
174
 
175
- $fetched_action_id = reset( $actions );
176
- $fetched_action = $store->fetch_action( $fetched_action_id );
177
 
178
- $this->assertNotEquals( $fetched_action_id, $action_id );
179
- $this->assertEquals( $random, $fetched_action->get_hook() );
180
- $this->assertEquals( $date->getTimestamp(), $fetched_action->get_schedule()->get_date()->getTimestamp(), '', 1 );
181
  }
182
 
183
  public function test_hooked_into_wp_cron() {
184
- $next = wp_next_scheduled( ActionScheduler_QueueRunner::WP_CRON_HOOK, array( 'WP Cron' ) );
185
  $this->assertNotEmpty($next);
186
  }
187
 
188
  public function test_batch_count_limit() {
189
  $store = ActionScheduler::store();
190
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
191
 
192
  $mock = new MockAction();
193
  $random = md5(rand());
194
  add_action( $random, array( $mock, 'action' ) );
195
  $schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
196
 
197
- for ( $i = 0 ; $i < 2 ; $i++ ) {
198
  $action = new ActionScheduler_Action( $random, array($random), $schedule );
199
  $store->save_action( $action );
200
  }
201
 
202
- $claim = $store->stake_claim();
 
 
 
 
203
 
204
  $actions_run = $runner->run();
205
 
 
206
  $this->assertEquals( 0, $mock->get_call_count() );
207
  $this->assertEquals( 0, $actions_run );
208
 
209
- $store->release_claim( $claim );
 
210
 
211
  $actions_run = $runner->run();
212
-
213
- $this->assertEquals( 2, $mock->get_call_count() );
214
- $this->assertEquals( 2, $actions_run );
215
 
216
  remove_action( $random, array( $mock, 'action' ) );
217
  }
218
 
219
  public function test_changing_batch_count_limit() {
220
  $store = ActionScheduler::store();
221
- $runner = ActionScheduler_Mocker::get_queue_runner( $store );
222
 
223
  $random = md5(rand());
224
  $schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
7
  class ActionScheduler_QueueRunner_Test extends ActionScheduler_UnitTestCase {
8
  public function test_create_runner() {
9
  $store = ActionScheduler::store();
10
+ $runner = new ActionScheduler_QueueRunner( $store );
11
  $actions_run = $runner->run();
12
 
13
  $this->assertEquals( 0, $actions_run );
15
 
16
  public function test_run() {
17
  $store = ActionScheduler::store();
18
+ $runner = new ActionScheduler_QueueRunner( $store );
19
 
20
  $mock = new MockAction();
21
  $random = md5(rand());
37
 
38
  public function test_run_with_future_actions() {
39
  $store = ActionScheduler::store();
40
+ $runner = new ActionScheduler_QueueRunner( $store );
41
 
42
  $mock = new MockAction();
43
  $random = md5(rand());
65
 
66
  public function test_completed_action_status() {
67
  $store = ActionScheduler::store();
68
+ $runner = new ActionScheduler_QueueRunner( $store );
69
 
70
  $random = md5(rand());
71
  $schedule = new ActionScheduler_SimpleSchedule(as_get_datetime_object('12 hours ago'));
80
  $this->assertTrue( $finished_action->is_finished() );
81
  }
82
 
83
+ public function test_next_instance_of_action() {
84
+ $store = ActionScheduler::store();
85
+ $runner = new ActionScheduler_QueueRunner( $store );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ $random = md5(rand());
88
+ $schedule = new ActionScheduler_IntervalSchedule(as_get_datetime_object('12 hours ago'), DAY_IN_SECONDS);
 
89
 
90
+ $action = new ActionScheduler_Action( $random, array(), $schedule );
91
+ $store->save_action( $action );
92
 
 
93
  $runner->run();
94
 
95
+ $claim = $store->stake_claim(10, as_get_datetime_object((DAY_IN_SECONDS - 60).' seconds'));
96
+ $this->assertCount(0, $claim->get_actions());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
+ $claim = $store->stake_claim(10, as_get_datetime_object(DAY_IN_SECONDS.' seconds'));
99
  $actions = $claim->get_actions();
100
+ $this->assertCount(1, $actions);
101
 
102
+ $action_id = reset($actions);
103
+ $new_action = $store->fetch_action($action_id);
104
 
105
+
106
+ $this->assertEquals( $random, $new_action->get_hook() );
107
+ $this->assertEquals( $schedule->next(as_get_datetime_object())->getTimestamp(), $new_action->get_schedule()->next(as_get_datetime_object())->getTimestamp() );
108
  }
109
 
110
  public function test_hooked_into_wp_cron() {
111
+ $next = wp_next_scheduled( ActionScheduler_QueueRunner::WP_CRON_HOOK );
112
  $this->assertNotEmpty($next);
113
  }
114
 
115
  public function test_batch_count_limit() {
116
  $store = ActionScheduler::store();
117
+ $runner = new ActionScheduler_QueueRunner( $store );
118
 
119
  $mock = new MockAction();
120
  $random = md5(rand());
121
  add_action( $random, array( $mock, 'action' ) );
122
  $schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
123
 
124
+ for ( $i = 0 ; $i < 30 ; $i++ ) {
125
  $action = new ActionScheduler_Action( $random, array($random), $schedule );
126
  $store->save_action( $action );
127
  }
128
 
129
+ $claims = array();
130
+
131
+ for ( $i = 0 ; $i < 5 ; $i++ ) {
132
+ $claims[] = $store->stake_claim( 5 );
133
+ }
134
 
135
  $actions_run = $runner->run();
136
 
137
+
138
  $this->assertEquals( 0, $mock->get_call_count() );
139
  $this->assertEquals( 0, $actions_run );
140
 
141
+ $first = reset($claims);
142
+ $store->release_claim( $first );
143
 
144
  $actions_run = $runner->run();
145
+ $this->assertEquals( 10, $mock->get_call_count() );
146
+ $this->assertEquals( 10, $actions_run );
 
147
 
148
  remove_action( $random, array( $mock, 'action' ) );
149
  }
150
 
151
  public function test_changing_batch_count_limit() {
152
  $store = ActionScheduler::store();
153
+ $runner = new ActionScheduler_QueueRunner( $store );
154
 
155
  $random = md5(rand());
156
  $schedule = new ActionScheduler_SimpleSchedule(new ActionScheduler_DateTime('1 day ago'));
includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_CronSchedule_Test.php CHANGED
@@ -8,46 +8,15 @@ class ActionScheduler_CronSchedule_Test extends ActionScheduler_UnitTestCase {
8
  public function test_creation() {
9
  $time = as_get_datetime_object('tomorrow');
10
  $cron = CronExpression::factory('@daily');
11
- $start = clone $time;
12
- $start->modify( '-1 hour' );
13
- $schedule = new ActionScheduler_CronSchedule( $start, $cron );
14
- $this->assertEquals( $time, $schedule->get_date() );
15
- $this->assertEquals( $start, $schedule->get_first_date() );
16
-
17
- // Test delaying for a future start date
18
- $start->modify( '+1 week' );
19
- $time->modify( '+1 week' );
20
-
21
- $schedule = new ActionScheduler_CronSchedule( $start, $cron );
22
- $this->assertEquals( $time, $schedule->get_date() );
23
- $this->assertEquals( $start, $schedule->get_first_date() );
24
- }
25
-
26
- public function test_creation_with_first_date() {
27
- $time = as_get_datetime_object( 'tomorrow' );
28
- $cron = CronExpression::factory( '@daily' );
29
- $start = clone $time;
30
- $start->modify( '-1 hour' );
31
- $schedule = new ActionScheduler_CronSchedule( $start, $cron );
32
- $this->assertEquals( $time, $schedule->get_date() );
33
- $this->assertEquals( $start, $schedule->get_first_date() );
34
-
35
- // Test delaying for a future start date
36
- $first = clone $time;
37
- $first->modify( '-1 day' );
38
- $start->modify( '+1 week' );
39
- $time->modify( '+1 week' );
40
-
41
- $schedule = new ActionScheduler_CronSchedule( $start, $cron, $first );
42
- $this->assertEquals( $time, $schedule->get_date() );
43
- $this->assertEquals( $first, $schedule->get_first_date() );
44
  }
45
 
46
  public function test_next() {
47
  $time = as_get_datetime_object('2013-06-14');
48
  $cron = CronExpression::factory('@daily');
49
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
50
- $this->assertEquals( as_get_datetime_object('tomorrow'), $schedule->get_next( as_get_datetime_object() ) );
51
  }
52
 
53
  public function test_is_recurring() {
@@ -59,18 +28,18 @@ class ActionScheduler_CronSchedule_Test extends ActionScheduler_UnitTestCase {
59
  $time = as_get_datetime_object('2014-01-01');
60
  $cron = CronExpression::factory('0 0 10 10 *');
61
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
62
- $this->assertEquals( as_get_datetime_object('2014-10-10'), $schedule->get_date() );
63
 
64
  $cron = CronExpression::factory('0 0 L 1/2 *');
65
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
66
- $this->assertEquals( as_get_datetime_object('2014-01-31'), $schedule->get_date() );
67
- $this->assertEquals( as_get_datetime_object('2014-07-31'), $schedule->get_next( as_get_datetime_object('2014-06-01') ) );
68
- $this->assertEquals( as_get_datetime_object('2028-11-30'), $schedule->get_next( as_get_datetime_object('2028-11-01') ) );
69
 
70
  $cron = CronExpression::factory('30 14 * * MON#3 *');
71
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
72
- $this->assertEquals( as_get_datetime_object('2014-01-20 14:30:00'), $schedule->get_date() );
73
- $this->assertEquals( as_get_datetime_object('2014-05-19 14:30:00'), $schedule->get_next( as_get_datetime_object('2014-05-01') ) );
74
  }
75
  }
76
 
8
  public function test_creation() {
9
  $time = as_get_datetime_object('tomorrow');
10
  $cron = CronExpression::factory('@daily');
11
+ $schedule = new ActionScheduler_CronSchedule(as_get_datetime_object(), $cron);
12
+ $this->assertEquals( $time, $schedule->next() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  }
14
 
15
  public function test_next() {
16
  $time = as_get_datetime_object('2013-06-14');
17
  $cron = CronExpression::factory('@daily');
18
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
19
+ $this->assertEquals( as_get_datetime_object('tomorrow'), $schedule->next( as_get_datetime_object() ) );
20
  }
21
 
22
  public function test_is_recurring() {
28
  $time = as_get_datetime_object('2014-01-01');
29
  $cron = CronExpression::factory('0 0 10 10 *');
30
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
31
+ $this->assertEquals( as_get_datetime_object('2014-10-10'), $schedule->next() );
32
 
33
  $cron = CronExpression::factory('0 0 L 1/2 *');
34
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
35
+ $this->assertEquals( as_get_datetime_object('2014-01-31'), $schedule->next() );
36
+ $this->assertEquals( as_get_datetime_object('2014-07-31'), $schedule->next( as_get_datetime_object('2014-06-01') ) );
37
+ $this->assertEquals( as_get_datetime_object('2028-11-30'), $schedule->next( as_get_datetime_object('2028-11-01') ) );
38
 
39
  $cron = CronExpression::factory('30 14 * * MON#3 *');
40
  $schedule = new ActionScheduler_CronSchedule($time, $cron);
41
+ $this->assertEquals( as_get_datetime_object('2014-01-20 14:30:00'), $schedule->next() );
42
+ $this->assertEquals( as_get_datetime_object('2014-05-19 14:30:00'), $schedule->next( as_get_datetime_object('2014-05-01') ) );
43
  }
44
  }
45
 
includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_IntervalSchedule_Test.php CHANGED
@@ -8,25 +8,16 @@ class ActionScheduler_IntervalSchedule_Test extends ActionScheduler_UnitTestCase
8
  public function test_creation() {
9
  $time = as_get_datetime_object();
10
  $schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
11
- $this->assertEquals( $time, $schedule->get_date() );
12
- $this->assertEquals( $time, $schedule->get_first_date() );
13
- }
14
-
15
- public function test_creation_with_first_date() {
16
- $first = as_get_datetime_object();
17
- $time = as_get_datetime_object( '+12 hours' );
18
- $schedule = new ActionScheduler_IntervalSchedule( $time, HOUR_IN_SECONDS, $first );
19
- $this->assertEquals( $time, $schedule->get_date() );
20
- $this->assertEquals( $first, $schedule->get_first_date() );
21
  }
22
 
23
  public function test_next() {
24
  $now = time();
25
  $start = $now - 30;
26
  $schedule = new ActionScheduler_IntervalSchedule( as_get_datetime_object("@$start"), MINUTE_IN_SECONDS );
27
- $this->assertEquals( $start, $schedule->get_date()->getTimestamp() );
28
- $this->assertEquals( $now + MINUTE_IN_SECONDS, $schedule->get_next(as_get_datetime_object())->getTimestamp() );
29
- $this->assertEquals( $start, $schedule->get_next( as_get_datetime_object( "@$start" ) )->getTimestamp() );
30
  }
31
 
32
  public function test_is_recurring() {
8
  public function test_creation() {
9
  $time = as_get_datetime_object();
10
  $schedule = new ActionScheduler_IntervalSchedule($time, HOUR_IN_SECONDS);
11
+ $this->assertEquals( $time, $schedule->next() );
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
  public function test_next() {
15
  $now = time();
16
  $start = $now - 30;
17
  $schedule = new ActionScheduler_IntervalSchedule( as_get_datetime_object("@$start"), MINUTE_IN_SECONDS );
18
+ $this->assertEquals( $start, $schedule->next()->getTimestamp() );
19
+ $this->assertEquals( $now + MINUTE_IN_SECONDS, $schedule->next(as_get_datetime_object())->getTimestamp() );
20
+ $this->assertEquals( $start, $schedule->next(as_get_datetime_object("@$start"))->getTimestamp() );
21
  }
22
 
23
  public function test_is_recurring() {
includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_NullSchedule_Test.php CHANGED
@@ -7,7 +7,7 @@
7
  class ActionScheduler_NullSchedule_Test extends ActionScheduler_UnitTestCase {
8
  public function test_null_schedule() {
9
  $schedule = new ActionScheduler_NullSchedule();
10
- $this->assertNull( $schedule->get_date() );
11
  }
12
 
13
  public function test_is_recurring() {
7
  class ActionScheduler_NullSchedule_Test extends ActionScheduler_UnitTestCase {
8
  public function test_null_schedule() {
9
  $schedule = new ActionScheduler_NullSchedule();
10
+ $this->assertNull( $schedule->next() );
11
  }
12
 
13
  public function test_is_recurring() {
includes/vendor/action-scheduler/tests/phpunit/schedules/ActionScheduler_SimpleSchedule_Test.php CHANGED
@@ -8,25 +8,25 @@ class ActionScheduler_SimpleSchedule_Test extends ActionScheduler_UnitTestCase {
8
  public function test_creation() {
9
  $time = as_get_datetime_object();
10
  $schedule = new ActionScheduler_SimpleSchedule($time);
11
- $this->assertEquals( $time, $schedule->get_date() );
12
  }
13
 
14
  public function test_past_date() {
15
  $time = as_get_datetime_object('-1 day');
16
  $schedule = new ActionScheduler_SimpleSchedule($time);
17
- $this->assertEquals( $time, $schedule->get_date() );
18
  }
19
 
20
  public function test_future_date() {
21
  $time = as_get_datetime_object('+1 day');
22
  $schedule = new ActionScheduler_SimpleSchedule($time);
23
- $this->assertEquals( $time, $schedule->get_date() );
24
  }
25
 
26
  public function test_grace_period_for_next() {
27
  $time = as_get_datetime_object('3 seconds ago');
28
  $schedule = new ActionScheduler_SimpleSchedule($time);
29
- $this->assertEquals( $time, $schedule->get_date() );
30
  }
31
 
32
  public function test_is_recurring() {
8
  public function test_creation() {
9
  $time = as_get_datetime_object();
10
  $schedule = new ActionScheduler_SimpleSchedule($time);
11
+ $this->assertEquals( $time, $schedule->next() );
12
  }
13
 
14
  public function test_past_date() {
15
  $time = as_get_datetime_object('-1 day');
16
  $schedule = new ActionScheduler_SimpleSchedule($time);
17
+ $this->assertEquals( $time, $schedule->next() );
18
  }
19
 
20
  public function test_future_date() {
21
  $time = as_get_datetime_object('+1 day');
22
  $schedule = new ActionScheduler_SimpleSchedule($time);
23
+ $this->assertEquals( $time, $schedule->next() );
24
  }
25
 
26
  public function test_grace_period_for_next() {
27
  $time = as_get_datetime_object('3 seconds ago');
28
  $schedule = new ActionScheduler_SimpleSchedule($time);
29
+ $this->assertEquals( $time, $schedule->next() );
30
  }
31
 
32
  public function test_is_recurring() {
mailchimp-woocommerce.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: Mailchimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
  * Description: Connects WooCommerce to Mailchimp to sync your store data, send targeted campaigns to your customers, and sell more stuff.
19
- * Version: 2.3.6
20
  * Author: Mailchimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
16
  * Plugin Name: Mailchimp for WooCommerce
17
  * Plugin URI: https://mailchimp.com/connect-your-store/
18
  * Description: Connects WooCommerce to Mailchimp to sync your store data, send targeted campaigns to your customers, and sell more stuff.
19
+ * Version: 2.4.0
20
  * Author: Mailchimp
21
  * Author URI: https://mailchimp.com
22
  * License: GPL-2.0+
public/class-mailchimp-woocommerce-public.php CHANGED
@@ -63,6 +63,7 @@ class MailChimp_WooCommerce_Public {
63
  wp_localize_script($this->plugin_name, 'mailchimp_public_data', array(
64
  'site_url' => site_url(),
65
  'ajax_url' => admin_url('admin-ajax.php'),
 
66
  ));
67
 
68
  // Enqueued script with localized data.
63
  wp_localize_script($this->plugin_name, 'mailchimp_public_data', array(
64
  'site_url' => site_url(),
65
  'ajax_url' => admin_url('admin-ajax.php'),
66
+ 'language' => substr( get_locale(), 0, 2 )
67
  ));
68
 
69
  // Enqueued script with localized data.
public/js/mailchimp-woocommerce-public.js CHANGED
@@ -33,7 +33,7 @@ function mailchimpHandleBillingEmail(selector) {
33
  var b = void 0 !== a ? a.value : "";
34
  if (!mailchimp_cart.valueEmail(b) || mailchimp_submitted_email === b) { return false; }
35
  mailchimp_cart.setEmail(b);
36
- var c = mailchimp_public_data.ajax_url + "?action=mailchimp_set_user_by_email&email=" + b;
37
  var d = new XMLHttpRequest;
38
  d.open("POST", c, !0);
39
  d.onload = function () {
33
  var b = void 0 !== a ? a.value : "";
34
  if (!mailchimp_cart.valueEmail(b) || mailchimp_submitted_email === b) { return false; }
35
  mailchimp_cart.setEmail(b);
36
+ var c = mailchimp_public_data.ajax_url + "?action=mailchimp_set_user_by_email&email=" + b + "&language=" + mailchimp_public_data.language;
37
  var d = new XMLHttpRequest;
38
  d.open("POST", c, !0);
39
  d.onload = function () {
public/js/mailchimp-woocommerce-public.min.js CHANGED
@@ -1 +1 @@
1
- var mailchimp,mailchimp_cart,mailchimp_billing_email,mailchimp_username_email,mailchimp_registration_email,mailchimp_submitted_email=!1,mailchimpReady=function(e){/in/.test(document.readyState)?setTimeout("mailchimpReady("+e+")",9):e()};function mailchimpGetCurrentUserByHash(e){try{var i=mailchimp_public_data.ajax_url+"?action=mailchimp_get_user_by_hash&hash="+e,a=new XMLHttpRequest;a.open("POST",i,!0),a.onload=function(){if(a.status>=200&&a.status<400){var e=JSON.parse(a.responseText);if(!e)return;mailchimp_cart.valueEmail(e.email)&&mailchimp_cart.setEmail(e.email)}},a.onerror=function(){console.log("mailchimp.get_email_by_hash.request.error",a.responseText)},a.setRequestHeader("Content-Type","application/json"),a.setRequestHeader("Accept","application/json"),a.send()}catch(e){console.log("mailchimp.get_email_by_hash.error",e)}}function mailchimpHandleBillingEmail(e){try{e||(e="#billing_email");var i=document.querySelector(e),a=void 0!==i?i.value:"";if(!mailchimp_cart.valueEmail(a)||mailchimp_submitted_email===a)return!1;mailchimp_cart.setEmail(a);var t=mailchimp_public_data.ajax_url+"?action=mailchimp_set_user_by_email&email="+a,n=new XMLHttpRequest;return n.open("POST",t,!0),n.onload=function(){var e=n.status>=200&&n.status<400,i=e?"mailchimp.handle_billing_email.request.success":"mailchimp.handle_billing_email.request.error";e&&(mailchimp_submitted_email=a),console.log(i,n.responseText)},n.onerror=function(){console.log("mailchimp.handle_billing_email.request.error",n.responseText)},n.setRequestHeader("Content-Type","application/json"),n.setRequestHeader("Accept","application/json"),n.send(),!0}catch(i){console.log("mailchimp.handle_billing_email.error",i),mailchimp_submitted_email=!1}}!function(){"use strict";var e,i,a,t={extend:function(e,i){for(var a in i||{})i.hasOwnProperty(a)&&(e[a]=i[a]);return e},getQueryStringVars:function(){var e=window.location.search||"",i=[],a={};if((e=e.substr(1)).length)for(var t in i=e.split("&")){var n=i[t];if("string"==typeof n){var l=n.split("="),r=l[0],m=l[1];r.length&&(void 0===a[r]&&(a[r]=[]),a[r].push(m))}}return a},unEscape:function(e){return decodeURIComponent(e)},escape:function(e){return encodeURIComponent(e)},createDate:function(e,i){e||(e=0);var a=new Date,t=i?a.getDate()-e:a.getDate()+e;return a.setDate(t),a},arrayUnique:function(e){for(var i=e.concat(),a=0;a<i.length;++a)for(var t=a+1;t<i.length;++t)i[a]===i[t]&&i.splice(t,1);return i},objectCombineUnique:function(e){for(var i=e[0],a=1;a<e.length;a++){var t=e[a];for(var n in t)i[n]=t[n]}return i}},n=(e=document,(a=function(e,i,t){return 1===arguments.length?a.get(e):a.set(e,i,t)}).get=function(i,t){return e.cookie!==a._cacheString&&a._populateCache(),null==a._cache[i]?t:a._cache[i]},a.defaults={path:"/"},a.set=function(t,n,l){switch(l={path:l&&l.path||a.defaults.path,domain:l&&l.domain||a.defaults.domain,expires:l&&l.expires||a.defaults.expires,secure:l&&l.secure!==i?l.secure:a.defaults.secure},n===i&&(l.expires=-1),typeof l.expires){case"number":l.expires=new Date((new Date).getTime()+1e3*l.expires);break;case"string":l.expires=new Date(l.expires)}return t=encodeURIComponent(t)+"="+(n+"").replace(/[^!#-+\--:<-\[\]-~]/g,encodeURIComponent),t+=l.path?";path="+l.path:"",t+=l.domain?";domain="+l.domain:"",t+=l.expires?";expires="+l.expires.toGMTString():"",t+=l.secure?";secure":"",e.cookie=t,a},a.expire=function(e,t){return a.set(e,i,t)},a._populateCache=function(){a._cache={};try{a._cacheString=e.cookie;for(var t=a._cacheString.split("; "),n=0;n<t.length;n++){var l=t[n].indexOf("="),r=decodeURIComponent(t[n].substr(0,l));l=decodeURIComponent(t[n].substr(l+1)),a._cache[r]===i&&(a._cache[r]=l)}}catch(e){console.log(e)}},a.enabled=function(){var e="1"===a.set("cookies.js","1").get("cookies.js");return a.expire("cookies.js"),e}(),a);mailchimp={storage:n,utils:t},mailchimp_cart=new function(){return this.email_types="input[type=email]",this.regex_email=/^([A-Za-z0-9_+\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,this.current_email=null,this.previous_email=null,this.expireUser=function(){this.current_email=null,mailchimp.storage.expire("mailchimp.cart.current_email")},this.expireSaved=function(){mailchimp.storage.expire("mailchimp.cart.items")},this.setEmail=function(e){if(!this.valueEmail(e))return!1;this.setPreviousEmail(this.getEmail()),mailchimp.storage.set("mailchimp.cart.current_email",this.current_email=e)},this.getEmail=function(){if(this.current_email)return this.current_email;var e=mailchimp.storage.get("mailchimp.cart.current_email",!1);return!(!e||!this.valueEmail(e))&&(this.current_email=e)},this.setPreviousEmail=function(e){if(!this.valueEmail(e))return!1;mailchimp.storage.set("mailchimp.cart.previous_email",this.previous_email=e)},this.valueEmail=function(e){return this.regex_email.test(e)},this}}(),mailchimpReady(function(){if(void 0===e)var e={site_url:document.location.origin,defaulted:!0,ajax_url:document.location.origin+"/wp-admin?admin-ajax.php"};try{var i=mailchimp.utils.getQueryStringVars();void 0!==i.mc_cart_id&&mailchimpGetCurrentUserByHash(i.mc_cart_id),mailchimp_username_email=document.querySelector("#username"),mailchimp_billing_email=document.querySelector("#billing_email"),mailchimp_registration_email=document.querySelector("#reg_email"),mailchimp_billing_email&&(mailchimp_billing_email.onblur=function(){mailchimpHandleBillingEmail("#billing_email")},mailchimp_billing_email.onfocus=function(){mailchimpHandleBillingEmail("#billing_email")}),mailchimp_username_email&&(mailchimp_username_email.onblur=function(){mailchimpHandleBillingEmail("#username")},mailchimp_username_email.onfocus=function(){mailchimpHandleBillingEmail("#username")}),mailchimp_registration_email&&(mailchimp_registration_email.onblur=function(){mailchimpHandleBillingEmail("#reg_email")},mailchimp_registration_email.onfocus=function(){mailchimpHandleBillingEmail("#reg_email")})}catch(e){console.log("mailchimp ready error",e)}});
1
+ var mailchimp,mailchimp_cart,mailchimp_billing_email,mailchimp_username_email,mailchimp_registration_email,mailchimp_submitted_email=!1,mailchimpReady=function(e){/in/.test(document.readyState)?setTimeout("mailchimpReady("+e+")",9):e()};function mailchimpGetCurrentUserByHash(e){try{var i=mailchimp_public_data.ajax_url+"?action=mailchimp_get_user_by_hash&hash="+e,a=new XMLHttpRequest;a.open("POST",i,!0),a.onload=function(){if(a.status>=200&&a.status<400){var e=JSON.parse(a.responseText);if(!e)return;mailchimp_cart.valueEmail(e.email)&&mailchimp_cart.setEmail(e.email)}},a.onerror=function(){console.log("mailchimp.get_email_by_hash.request.error",a.responseText)},a.setRequestHeader("Content-Type","application/json"),a.setRequestHeader("Accept","application/json"),a.send()}catch(e){console.log("mailchimp.get_email_by_hash.error",e)}}function mailchimpHandleBillingEmail(e){try{e||(e="#billing_email");var i=document.querySelector(e),a=void 0!==i?i.value:"";if(!mailchimp_cart.valueEmail(a)||mailchimp_submitted_email===a)return!1;mailchimp_cart.setEmail(a);var t=mailchimp_public_data.ajax_url+"?action=mailchimp_set_user_by_email&email="+a+"&language="+mailchimp_public_data.language,n=new XMLHttpRequest;return n.open("POST",t,!0),n.onload=function(){var e=n.status>=200&&n.status<400,i=e?"mailchimp.handle_billing_email.request.success":"mailchimp.handle_billing_email.request.error";e&&(mailchimp_submitted_email=a),console.log(i,n.responseText)},n.onerror=function(){console.log("mailchimp.handle_billing_email.request.error",n.responseText)},n.setRequestHeader("Content-Type","application/json"),n.setRequestHeader("Accept","application/json"),n.send(),!0}catch(i){console.log("mailchimp.handle_billing_email.error",i),mailchimp_submitted_email=!1}}!function(){"use strict";var e,i,a,t={extend:function(e,i){for(var a in i||{})i.hasOwnProperty(a)&&(e[a]=i[a]);return e},getQueryStringVars:function(){var e=window.location.search||"",i=[],a={};if((e=e.substr(1)).length)for(var t in i=e.split("&")){var n=i[t];if("string"==typeof n){var l=n.split("="),r=l[0],m=l[1];r.length&&(void 0===a[r]&&(a[r]=[]),a[r].push(m))}}return a},unEscape:function(e){return decodeURIComponent(e)},escape:function(e){return encodeURIComponent(e)},createDate:function(e,i){e||(e=0);var a=new Date,t=i?a.getDate()-e:a.getDate()+e;return a.setDate(t),a},arrayUnique:function(e){for(var i=e.concat(),a=0;a<i.length;++a)for(var t=a+1;t<i.length;++t)i[a]===i[t]&&i.splice(t,1);return i},objectCombineUnique:function(e){for(var i=e[0],a=1;a<e.length;a++){var t=e[a];for(var n in t)i[n]=t[n]}return i}},n=(e=document,(a=function(e,i,t){return 1===arguments.length?a.get(e):a.set(e,i,t)}).get=function(i,t){return e.cookie!==a._cacheString&&a._populateCache(),null==a._cache[i]?t:a._cache[i]},a.defaults={path:"/"},a.set=function(t,n,l){switch(l={path:l&&l.path||a.defaults.path,domain:l&&l.domain||a.defaults.domain,expires:l&&l.expires||a.defaults.expires,secure:l&&l.secure!==i?l.secure:a.defaults.secure},n===i&&(l.expires=-1),typeof l.expires){case"number":l.expires=new Date((new Date).getTime()+1e3*l.expires);break;case"string":l.expires=new Date(l.expires)}return t=encodeURIComponent(t)+"="+(n+"").replace(/[^!#-+\--:<-\[\]-~]/g,encodeURIComponent),t+=l.path?";path="+l.path:"",t+=l.domain?";domain="+l.domain:"",t+=l.expires?";expires="+l.expires.toGMTString():"",t+=l.secure?";secure":"",e.cookie=t,a},a.expire=function(e,t){return a.set(e,i,t)},a._populateCache=function(){a._cache={};try{a._cacheString=e.cookie;for(var t=a._cacheString.split("; "),n=0;n<t.length;n++){var l=t[n].indexOf("="),r=decodeURIComponent(t[n].substr(0,l));l=decodeURIComponent(t[n].substr(l+1)),a._cache[r]===i&&(a._cache[r]=l)}}catch(e){console.log(e)}},a.enabled=function(){var e="1"===a.set("cookies.js","1").get("cookies.js");return a.expire("cookies.js"),e}(),a);mailchimp={storage:n,utils:t},mailchimp_cart=new function(){return this.email_types="input[type=email]",this.regex_email=/^([A-Za-z0-9_+\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,this.current_email=null,this.previous_email=null,this.expireUser=function(){this.current_email=null,mailchimp.storage.expire("mailchimp.cart.current_email")},this.expireSaved=function(){mailchimp.storage.expire("mailchimp.cart.items")},this.setEmail=function(e){if(!this.valueEmail(e))return!1;this.setPreviousEmail(this.getEmail()),mailchimp.storage.set("mailchimp.cart.current_email",this.current_email=e)},this.getEmail=function(){if(this.current_email)return this.current_email;var e=mailchimp.storage.get("mailchimp.cart.current_email",!1);return!(!e||!this.valueEmail(e))&&(this.current_email=e)},this.setPreviousEmail=function(e){if(!this.valueEmail(e))return!1;mailchimp.storage.set("mailchimp.cart.previous_email",this.previous_email=e)},this.valueEmail=function(e){return this.regex_email.test(e)},this}}(),mailchimpReady(function(){if(void 0===e)var e={site_url:document.location.origin,defaulted:!0,ajax_url:document.location.origin+"/wp-admin?admin-ajax.php"};try{var i=mailchimp.utils.getQueryStringVars();void 0!==i.mc_cart_id&&mailchimpGetCurrentUserByHash(i.mc_cart_id),mailchimp_username_email=document.querySelector("#username"),mailchimp_billing_email=document.querySelector("#billing_email"),mailchimp_registration_email=document.querySelector("#reg_email"),mailchimp_billing_email&&(mailchimp_billing_email.onblur=function(){mailchimpHandleBillingEmail("#billing_email")},mailchimp_billing_email.onfocus=function(){mailchimpHandleBillingEmail("#billing_email")}),mailchimp_username_email&&(mailchimp_username_email.onblur=function(){mailchimpHandleBillingEmail("#username")},mailchimp_username_email.onfocus=function(){mailchimpHandleBillingEmail("#username")}),mailchimp_registration_email&&(mailchimp_registration_email.onblur=function(){mailchimpHandleBillingEmail("#reg_email")},mailchimp_registration_email.onfocus=function(){mailchimpHandleBillingEmail("#reg_email")})}catch(e){console.log("mailchimp ready error",e)}});