PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 3.8.1
WooCommerce Square v3.8.1
5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Lifecycle.php
woocommerce-square / includes Last commit date
API 3 years ago Admin 3 years ago Emails 3 years ago Framework 3 years ago Gateway 3 years ago Handlers 3 years ago Sync 3 years ago Utilities 3 years ago AJAX.php 3 years ago API.php 3 years ago Admin.php 3 years ago Functions.php 3 years ago Gateway.php 3 years ago Lifecycle.php 3 years ago Plugin.php 3 years ago Settings.php 3 years ago
Lifecycle.php
580 lines
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
22 */
23
24 namespace WooCommerce\Square;
25
26 defined( 'ABSPATH' ) || exit;
27
28 use WooCommerce\Square\Handlers\Product;
29
30 /**
31 * The plugin lifecycle handler.
32 *
33 * @since 2.0.0
34 *
35 * @method Plugin get_plugin()
36 */
37 class Lifecycle extends \WooCommerce\Square\Framework\Lifecycle {
38
39 /**
40 * Lifecycle constructor.
41 *
42 * @since 2.0.0
43 *
44 * @param Plugin $plugin main instance.
45 */
46 public function __construct( Plugin $plugin ) {
47
48 parent::__construct( $plugin );
49
50 // plugin upgrade path: maps automatically each semver to upgrade_to_x_y_z() protected method.
51 $this->upgrade_versions = array(
52 '2.0.0',
53 '2.0.4',
54 '2.1.5',
55 '2.2.0',
56 '2.3.0',
57 '3.0.2',
58 '3.2.0',
59 '3.7.1',
60 );
61 }
62
63
64 /**
65 * Performs plugin installation.
66 *
67 * @since 2.0.0
68 */
69 protected function install() {
70
71 // create the db table for the customer index.
72 Gateway\Customer_Helper::create_table();
73
74 /**
75 * Fires upon plugin installed.
76 *
77 * @since 2.0.0
78 *
79 * @param string $version plugin version (available from v2.0.0)
80 */
81 do_action( 'wc_square_installed', Plugin::VERSION );
82 }
83
84
85 /**
86 * Performs upgrade tasks.
87 *
88 * @since 2.0.0
89 *
90 * @param string $installed_version semver.
91 */
92 protected function upgrade( $installed_version ) {
93
94 parent::upgrade( $installed_version );
95
96 /**
97 * Fires upon plugin upgraded (legacy hook).
98 *
99 * @since 1.0.0
100 *
101 * @param string $version version updating to (available from v2.0.0)
102 * @param string $version version updating from (available from v2.0.0)
103 */
104 do_action( 'wc_square_updated', Plugin::VERSION, $installed_version );
105 }
106
107
108 /**
109 * Upgrades to version 2.0.0
110 *
111 * @since 2.0.0
112 */
113 protected function upgrade_to_2_0_0() {
114
115 // create the db table for the customer index.
116 Gateway\Customer_Helper::create_table();
117
118 wc_set_time_limit( 300 );
119
120 // migrate all the things!
121 $syncing_products = $this->migrate_plugin_settings();
122
123 $this->migrate_gateway_settings();
124 $this->migrate_orders();
125
126 // only set the products "sync" status if v2 is now configured to sync products.
127 if ( $syncing_products ) {
128
129 $this->migrate_products();
130
131 // assume a last sync occurred before upgrading.
132 $this->get_plugin()->get_sync_handler()->set_last_synced_at();
133 $this->get_plugin()->get_sync_handler()->set_inventory_last_synced_at();
134 }
135
136 $this->migrate_customers();
137
138 // mark upgrade complete.
139 update_option( 'wc_square_updated_to_2_0_0', true );
140 }
141
142
143 /**
144 * Upgrades to version 2.0.4.
145 *
146 * @since 2.0.4
147 */
148 protected function upgrade_to_2_0_4() {
149
150 $v1_settings = get_option( 'woocommerce_squareconnect_settings', array() );
151 $v2_settings = get_option( 'wc_square_settings', array() );
152
153 $v2_settings = $this->get_migrated_system_of_record( $v1_settings, $v2_settings );
154
155 update_option( 'wc_square_settings', $v2_settings );
156 }
157
158 /**
159 * Upgrades to version 2.1.5
160 *
161 * 2.1.5 updated the woocommerce_square_customers database schema.
162 *
163 * @see https://github.com/woocommerce/woocommerce-square/issues/359
164 * @since 2.1.5
165 */
166 protected function upgrade_to_2_1_5() {
167 Gateway\Customer_Helper::create_table();
168 }
169
170 /**
171 * Adds the missing Square customer table.
172 *
173 * @see https://github.com/woocommerce/woocommerce-square/issues/825
174 * @since 3.2.0
175 */
176 protected function upgrade_to_3_2_0() {
177 Gateway\Customer_Helper::create_table();
178 }
179
180 /**
181 * Upgrades to version 3.7.1
182 *
183 * This upgrade disables gift cards, and shows a notice to inform the merchant.
184 * Gift Cards are in beta status and not recommended for production.
185 *
186 * @see https://github.com/woocommerce/woocommerce-square/issues/1003
187 * @see https://github.com/woocommerce/woocommerce-square/issues/1009
188 * @since 3.7.1.
189 */
190 protected function upgrade_to_3_7_1() {
191 // Early return if Gift Cards are already disabled.
192 $gateway_settings = get_option( 'woocommerce_square_credit_card_settings', array() );
193 if ( ! isset( $gateway_settings['enable_gift_cards'] ) || 'no' === $gateway_settings['enable_gift_cards'] ) {
194 return;
195 }
196
197 // Force-disable Gift Cards (only if store has it enabled).
198 $gateway_settings['enable_gift_cards'] = 'no';
199 update_option( 'woocommerce_square_credit_card_settings', $gateway_settings );
200
201 // Store an option to inform the merchant that Gift Cards has been force-disabled.
202 // Using version number in the option name so it's easy to remove in the future.
203 update_option( 'woocommerce_square_3_7_1_gift_cards_force_disable_notice', 'yes' );
204 }
205
206 /**
207 * Generates a milestone notice message.
208 *
209 * @since 2.1.7
210 *
211 * @param string $custom_message Custom text that notes what milestone was completed.
212 * @return string
213 */
214 protected function generate_milestone_notice_message( $custom_message ) {
215
216 $message = '';
217
218 if ( $this->get_plugin()->get_reviews_url() ) {
219
220 // to be prepended at random to each milestone notice.
221 $exclamations = array(
222 __( 'Awesome', 'woocommerce-square' ),
223 __( 'Congratulations', 'woocommerce-square' ),
224 __( 'Great', 'woocommerce-square' ),
225 __( 'Fantastic', 'woocommerce-square' ),
226 );
227
228 $message = $exclamations[ array_rand( $exclamations ) ] . ', ' . esc_html( $custom_message ) . ' ';
229
230 $message .= sprintf(
231 /* translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a> tag, %4$s - <a> tag, %5$s - </a> tag */
232 __( 'Are you having a great experience with %1$s so far? Please consider %2$sleaving a review%3$s! If things aren\'t going quite as expected, we\'re happy to help -- please %4$sreach out to our support team%5$s.', 'woocommerce-square' ),
233 '<strong>' . esc_html( $this->get_plugin()->get_plugin_name() ) . '</strong>',
234 '<a href="' . esc_url( $this->get_plugin()->get_reviews_url() ) . '">',
235 '</a>',
236 '<a href="' . esc_url( $this->get_plugin()->get_support_url() ) . '">',
237 '</a>'
238 );
239 }
240
241 return $message;
242 }
243
244 /**
245 * Upgrades to version 2.2.0.
246 *
247 * @since 2.2.0
248 */
249 protected function upgrade_to_2_2_0() {
250
251 $v1_settings = get_option( 'wc_square_settings', array() );
252
253 $v2_settings = $this->set_environment_location_id( $v1_settings );
254
255 update_option( 'wc_square_settings', $v2_settings );
256 }
257
258 /**
259 * Upgrades to version 2.3.0.
260 *
261 * @since 2.3.0
262 */
263 protected function upgrade_to_2_3_0() {
264 // Set `enable_digital_wallets` default to no for existing stores
265 $gateway_settings = get_option( 'woocommerce_square_credit_card_settings', array() );
266
267 if ( ! isset( $gateway_settings['enable_digital_wallets'] ) ) {
268 $gateway_settings['enable_digital_wallets'] = 'no';
269 }
270
271 update_option( 'woocommerce_square_credit_card_settings', $gateway_settings );
272 }
273
274 /**
275 * Deletes the transient that holds locations data.
276 *
277 * @see https://github.com/woocommerce/woocommerce-square/issues/786#issuecomment-1121388650
278 *
279 * @since 3.0.2
280 */
281 protected function upgrade_to_3_0_2() {
282 delete_transient( 'wc_square_locations' );
283 }
284
285 /**
286 * Migrates plugin settings from v1 to v2.
287 *
288 * @see Lifecycle::upgrade_to_2_0_0()
289 *
290 * @since 2.0.0
291 *
292 * @return bool whether a Sync setting was enabled from migration
293 */
294 private function migrate_plugin_settings() {
295
296 $this->get_plugin()->log( 'Migrating plugin settings...' );
297
298 // get legacy and new default settings.
299 $new_settings = get_option( 'wc_square_settings', array() );
300 $legacy_settings = get_option( 'woocommerce_squareconnect_settings', array() );
301 $email_settings = get_option( 'woocommerce_wc_square_sync_completed_settings', array() );
302
303 // bail if they already have v2 settings present.
304 if ( ! empty( $new_settings ) ) {
305 return;
306 }
307
308 // handle access token first.
309 $legacy_access_token = get_option( 'woocommerce_square_merchant_access_token' );
310 if ( $legacy_access_token ) {
311
312 // the access token was previously stored unencrypted.
313 if ( ! empty( $legacy_access_token ) && Utilities\Encryption_Utility::is_encryption_supported() ) {
314
315 $encryption = new Utilities\Encryption_Utility();
316
317 try {
318 $legacy_access_token = $encryption->encrypt_data( $legacy_access_token );
319 } catch ( \Exception $exception ) {
320 // log the event, but don't halt the process.
321 $this->get_plugin()->log( 'Could not encrypt access token during upgrade. ' . $exception->getMessage() );
322 }
323 }
324
325 // previously only 'production' environment was assumed.
326 $access_tokens = get_option( 'wc_square_access_tokens', array() );
327 $access_tokens['production'] = is_string( $legacy_access_token ) ? $legacy_access_token : '';
328
329 update_option( 'wc_square_access_tokens', $access_tokens );
330 }
331
332 // migrate store location.
333 if ( ! empty( $legacy_settings['location'] ) ) {
334 $new_settings['location_id'] = $legacy_settings['location'];
335 }
336
337 // toggle debug logging.
338 $new_settings['debug_logging_enabled'] = isset( $legacy_settings['logging'] ) && in_array( $legacy_settings['logging'], array( 'yes', 'no' ), true ) ? $legacy_settings['logging'] : 'no';
339
340 // set the SOR and inventory sync values.
341 $new_settings = $this->get_migrated_system_of_record( $legacy_settings, $new_settings );
342
343 // migrate email notification settings: if there's a recipient, we enable email and pass recipient(s) to email setting.
344 if ( isset( $legacy_settings['sync_email'] ) && is_string( $legacy_settings['sync_email'] ) && '' !== trim( $legacy_settings['sync_email'] ) ) {
345 $email_settings['enabled'] = 'yes';
346 $email_settings['recipient'] = $legacy_settings['sync_email'];
347 } else {
348 $email_settings['enabled'] = 'no';
349 $email_settings['recipient'] = '';
350 }
351
352 // save email settings.
353 update_option( 'woocommerce_wc_square_sync_completed_settings', $email_settings );
354 // save plugin settings.
355 update_option( 'wc_square_settings', $new_settings );
356
357 $this->get_plugin()->log( 'Plugin settings migration complete.' );
358
359 return isset( $new_settings['system_of_record'] ) && Settings::SYSTEM_OF_RECORD_DISABLED !== $new_settings['system_of_record'];
360 }
361
362
363 /**
364 * Migrates gateway settings from v1 to v2.
365 *
366 * @see Lifecycle::upgrade_to_2_0_0()
367 *
368 * @since 2.0.0
369 */
370 private function migrate_gateway_settings() {
371
372 $this->get_plugin()->log( 'Migrating gateway settings...' );
373
374 $legacy_settings = get_option( 'woocommerce_square_settings', array() );
375 $new_settings = get_option( 'woocommerce_square_credit_card_settings', array() );
376
377 // bail if they already have v2 settings present.
378 if ( ! empty( $new_settings ) ) {
379 return;
380 }
381
382 if ( isset( $legacy_settings['enabled'] ) ) {
383 $new_settings['enabled'] = 'yes' === $legacy_settings['enabled'] ? 'yes' : 'no';
384 }
385
386 if ( isset( $legacy_settings['title'] ) && is_string( $legacy_settings['title'] ) ) {
387 $new_settings['title'] = $legacy_settings['title'];
388 }
389
390 if ( isset( $legacy_settings['description'] ) && is_string( $legacy_settings['description'] ) ) {
391 $new_settings['description'] = $legacy_settings['description'];
392 }
393
394 // note: the following is not an error, the setting on v1 intends "delayed" capture, hence authorization only, if set.
395 if ( isset( $legacy_settings['capture'] ) ) {
396 $new_settings['transaction_type'] = 'yes' === $legacy_settings['capture'] ? Gateway::TRANSACTION_TYPE_AUTHORIZATION : Gateway::TRANSACTION_TYPE_CHARGE;
397 }
398
399 // not quite the same, since tokenization is a new thing, but we could presume the intention to let customers save their payment details.
400 if ( isset( $legacy_settings['create_customer'] ) ) {
401 $new_settings['tokenization'] = 'yes' === $legacy_settings['create_customer'] ? 'yes' : 'no';
402 }
403
404 if ( isset( $legacy_settings['logging'] ) ) {
405 $new_settings['debug_mode'] = 'yes' === $legacy_settings['logging'] ? 'log' : 'off';
406 }
407
408 // there was no card types setting in v1.
409 $new_settings['card_types'] = array(
410 'VISA',
411 'MC',
412 'AMEX',
413 'JCB',
414 // purposefully omit dinersclub & discover.
415 );
416
417 // save migrated settings.
418 update_option( 'woocommerce_square_credit_card_settings', $new_settings );
419
420 $this->get_plugin()->log( 'Gateway settings migration complete.' );
421 }
422
423
424 /**
425 * Migrates order data from v1 to v2.
426 *
427 * @see Lifecycle::upgrade_to_2_0_0()
428 *
429 * @since 2.0.0
430 */
431 private function migrate_orders() {
432 global $wpdb;
433
434 $this->get_plugin()->log( 'Migrating orders data...' );
435
436 $wpdb->update( $wpdb->postmeta, array( 'meta_key' => '_wc_square_credit_card_charge_captured' ), array( 'meta_key' => '_square_charge_captured' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
437
438 // move payment ID to new gateway ID meta key value.
439 $wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
440 $wpdb->postmeta,
441 array(
442 'meta_value' => 'square_credit_card', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
443 ),
444 array(
445 'meta_key' => '_payment_method', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
446 'meta_value' => 'square', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
447 )
448 );
449 $this->get_plugin()->log( 'Orders migration complete.' );
450 }
451
452
453 /**
454 * Migrates product data from v1 to v2.
455 *
456 * @see Lifecycle::upgrade_to_2_0_0()
457 *
458 * @since 2.0.0
459 */
460 private function migrate_products() {
461 global $wpdb;
462
463 $this->get_plugin()->log( 'Migrating products data...' );
464
465 // the handling in v1 was reversed, so we want products where sync wasn't disabled.
466 $legacy_product_ids = get_posts(
467 array(
468 'nopaging' => true,
469 'post_type' => 'product',
470 'post_status' => 'all',
471 'fields' => 'ids',
472 'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
473
474 'relation' => 'OR',
475 array(
476 'key' => '_wcsquare_disable_sync',
477 'value' => 'no',
478 ),
479 array(
480 'key' => '_wcsquare_disable_sync',
481 'compare' => 'NOT EXISTS',
482 ),
483 ),
484 )
485 );
486
487 // in v2 we turn those products as flagged to be sync-enabled instead.
488 if ( ! empty( $legacy_product_ids ) ) {
489
490 $failed_products = array();
491
492 // ensure taxonomy is registered at this stage.
493 if ( ! taxonomy_exists( Product::SYNCED_WITH_SQUARE_TAXONOMY ) ) {
494 Product::init_taxonomies();
495 }
496
497 // will not create the term if already exists.
498 wp_create_term( 'yes', Product::SYNCED_WITH_SQUARE_TAXONOMY );
499
500 // set Square sync status via taxonomy term.
501 foreach ( $legacy_product_ids as $i => $product_id ) {
502
503 $set_term = wp_set_object_terms( $product_id, array( 'yes' ), Product::SYNCED_WITH_SQUARE_TAXONOMY );
504
505 if ( ! is_array( $set_term ) ) {
506
507 unset( $legacy_product_ids[ $i ] );
508
509 $failed_products[] = $product_id;
510 }
511 }
512
513 // log any errors.
514 if ( ! empty( $failed_products ) ) {
515 $this->get_plugin()->log( 'Could not update sync with Square status for products with ID: ' . implode( ', ', array_unique( $failed_products ) ) . '.' );
516 }
517 }
518
519 $this->get_plugin()->log( 'Products migration complete.' );
520 }
521
522
523 /**
524 * Migrates customer data.
525 *
526 * @since 2.0.0
527 */
528 private function migrate_customers() {
529 global $wpdb;
530
531 $this->get_plugin()->log( 'Migrating customer data.' );
532
533 $rows = (int) $wpdb->update( $wpdb->usermeta, array( 'meta_key' => 'wc_square_customer_id' ), array( 'meta_key' => '_square_customer_id' ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.DirectQuery
534
535 $this->get_plugin()->log( sprintf( '%d customers migrated', $rows ) );
536 }
537
538
539 /**
540 * Adds the Sync setting setting to the v2 plugin settings depending on v1 setting values.
541 *
542 * @since 2.0.2
543 *
544 * @param array $v1_settings v1 plugin settings.
545 * @param array $v2_settings v2 plugin settings.
546 * @return array
547 */
548 private function get_migrated_system_of_record( $v1_settings, $v2_settings ) {
549
550 $sync_products = isset( $v1_settings['sync_products'] ) && 'yes' === $v1_settings['sync_products'];
551 $sync_inventory = $sync_products && isset( $v1_settings['sync_inventory'] ) && 'yes' === $v1_settings['sync_inventory'];
552 $inventory_polling = isset( $v1_settings['inventory_polling'] ) && 'yes' === $v1_settings['inventory_polling'];
553
554 $v2_settings['system_of_record'] = $sync_products && $inventory_polling ? Settings::SYSTEM_OF_RECORD_SQUARE : Settings::SYSTEM_OF_RECORD_DISABLED;
555 $v2_settings['enable_inventory_sync'] = $inventory_polling || $sync_inventory ? 'yes' : 'no';
556
557 return $v2_settings;
558 }
559
560 /**
561 * Adds environment specific location_id to, and removes general location_id from v1 setting array.
562 *
563 * @since 2.2.0
564 *
565 * @param array $v1_settings v1 plugin settings.
566 * @return array
567 */
568 private function set_environment_location_id( $v1_settings ) {
569
570 $environment = isset( $v1_settings['enable_sandbox'] ) && 'yes' === $v1_settings['enable_sandbox'] ? 'sandbox' : 'production';
571
572 if ( ! isset( $v1_settings[ $environment . '_location_id' ] ) ) {
573 $v1_location_id = isset( $v1_settings['location_id'] ) ? $v1_settings['location_id'] : '';
574 $v1_settings[ $environment . '_location_id' ] = $v1_location_id;
575 }
576
577 return $v1_settings;
578 }
579 }
580