PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 4.4.0-rc.1
WooCommerce v4.4.0-rc.1
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / wc-update-functions.php
woocommerce / includes Last commit date
abstracts 5 years ago admin 5 years ago cli 5 years ago customizer 5 years ago data-stores 5 years ago emails 6 years ago export 5 years ago gateways 5 years ago import 5 years ago integrations 6 years ago interfaces 6 years ago legacy 5 years ago libraries 6 years ago log-handlers 6 years ago payment-tokens 6 years ago queue 7 years ago shipping 5 years ago shortcodes 5 years ago theme-support 6 years ago tracks 5 years ago traits 6 years ago walkers 8 years ago wccom-site 6 years ago widgets 5 years ago class-wc-ajax.php 5 years ago class-wc-api.php 6 years ago class-wc-auth.php 7 years ago class-wc-autoloader.php 6 years ago class-wc-background-emailer.php 6 years ago class-wc-background-updater.php 7 years ago class-wc-breadcrumb.php 7 years ago class-wc-cache-helper.php 5 years ago class-wc-cart-fees.php 6 years ago class-wc-cart-session.php 6 years ago class-wc-cart-totals.php 5 years ago class-wc-cart.php 5 years ago class-wc-checkout.php 5 years ago class-wc-cli.php 8 years ago class-wc-comments.php 5 years ago class-wc-countries.php 5 years ago class-wc-coupon.php 6 years ago class-wc-customer-download-log.php 8 years ago class-wc-customer-download.php 6 years ago class-wc-customer.php 7 years ago class-wc-data-exception.php 8 years ago class-wc-data-store.php 6 years ago class-wc-datetime.php 7 years ago class-wc-deprecated-action-hooks.php 8 years ago class-wc-deprecated-filter-hooks.php 7 years ago class-wc-discounts.php 6 years ago class-wc-download-handler.php 5 years ago class-wc-emails.php 6 years ago class-wc-embed.php 8 years ago class-wc-form-handler.php 5 years ago class-wc-frontend-scripts.php 6 years ago class-wc-geo-ip.php 8 years ago class-wc-geolite-integration.php 6 years ago class-wc-geolocation.php 6 years ago class-wc-https.php 8 years ago class-wc-install.php 5 years ago class-wc-integrations.php 6 years ago class-wc-log-levels.php 7 years ago class-wc-logger.php 6 years ago class-wc-meta-data.php 7 years ago class-wc-order-factory.php 6 years ago class-wc-order-item-coupon.php 5 years ago class-wc-order-item-fee.php 5 years ago class-wc-order-item-meta.php 7 years ago class-wc-order-item-product.php 5 years ago class-wc-order-item-shipping.php 5 years ago class-wc-order-item-tax.php 5 years ago class-wc-order-item.php 6 years ago class-wc-order-query.php 7 years ago class-wc-order-refund.php 8 years ago class-wc-order.php 5 years ago class-wc-payment-gateways.php 6 years ago class-wc-payment-tokens.php 6 years ago class-wc-post-data.php 6 years ago class-wc-post-types.php 5 years ago class-wc-privacy-background-process.php 8 years ago class-wc-privacy-erasers.php 6 years ago class-wc-privacy-exporters.php 6 years ago class-wc-privacy.php 6 years ago class-wc-product-attribute.php 7 years ago class-wc-product-download.php 6 years ago class-wc-product-external.php 8 years ago class-wc-product-factory.php 7 years ago class-wc-product-grouped.php 8 years ago class-wc-product-query.php 7 years ago class-wc-product-simple.php 6 years ago class-wc-product-variable.php 5 years ago class-wc-product-variation.php 5 years ago class-wc-query.php 5 years ago class-wc-rate-limiter.php 6 years ago class-wc-regenerate-images-request.php 7 years ago class-wc-regenerate-images.php 7 years ago class-wc-register-wp-admin-settings.php 8 years ago class-wc-rest-authentication.php 6 years ago class-wc-rest-exception.php 6 years ago class-wc-session-handler.php 6 years ago class-wc-shipping-rate.php 8 years ago class-wc-shipping-zone.php 6 years ago class-wc-shipping-zones.php 6 years ago class-wc-shipping.php 5 years ago class-wc-shortcodes.php 6 years ago class-wc-structured-data.php 5 years ago class-wc-tax.php 6 years ago class-wc-template-loader.php 6 years ago class-wc-tracker.php 6 years ago class-wc-validation.php 5 years ago class-wc-webhook.php 6 years ago class-woocommerce.php 5 years ago wc-account-functions.php 5 years ago wc-attribute-functions.php 5 years ago wc-cart-functions.php 5 years ago wc-conditional-functions.php 6 years ago wc-core-functions.php 5 years ago wc-coupon-functions.php 7 years ago wc-deprecated-functions.php 5 years ago wc-formatting-functions.php 5 years ago wc-notice-functions.php 6 years ago wc-order-functions.php 5 years ago wc-order-item-functions.php 6 years ago wc-page-functions.php 6 years ago wc-product-functions.php 6 years ago wc-rest-functions.php 6 years ago wc-stock-functions.php 5 years ago wc-template-functions.php 5 years ago wc-template-hooks.php 6 years ago wc-term-functions.php 6 years ago wc-update-functions.php 5 years ago wc-user-functions.php 5 years ago wc-webhook-functions.php 5 years ago wc-widget-functions.php 8 years ago
wc-update-functions.php
2178 lines
1 <?php
2 /**
3 * WooCommerce Updates
4 *
5 * Functions for updating data, used by the background updater.
6 *
7 * @package WooCommerce/Functions
8 * @version 3.3.0
9 */
10
11 defined( 'ABSPATH' ) || exit;
12
13 /**
14 * Update file paths for 2.0
15 *
16 * @return void
17 */
18 function wc_update_200_file_paths() {
19 global $wpdb;
20
21 // Upgrade old style files paths to support multiple file paths.
22 $existing_file_paths = $wpdb->get_results( "SELECT meta_value, meta_id, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_file_path' AND meta_value != '';" );
23
24 if ( $existing_file_paths ) {
25
26 foreach ( $existing_file_paths as $existing_file_path ) {
27
28 $old_file_path = trim( $existing_file_path->meta_value );
29
30 if ( ! empty( $old_file_path ) ) {
31 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
32 $file_paths = serialize( array( md5( $old_file_path ) => $old_file_path ) );
33
34 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = '_file_paths', meta_value = %s WHERE meta_id = %d", $file_paths, $existing_file_path->meta_id ) );
35
36 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions SET download_id = %s WHERE product_id = %d", md5( $old_file_path ), $existing_file_path->post_id ) );
37
38 }
39 }
40 }
41 }
42
43 /**
44 * Update permalinks for 2.0
45 *
46 * @return void
47 */
48 function wc_update_200_permalinks() {
49 // Setup default permalinks if shop page is defined.
50 $permalinks = get_option( 'woocommerce_permalinks' );
51 $shop_page_id = wc_get_page_id( 'shop' );
52
53 if ( empty( $permalinks ) && $shop_page_id > 0 ) {
54
55 $base_slug = $shop_page_id > 0 && get_post( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop';
56
57 $category_base = 'yes' === get_option( 'woocommerce_prepend_shop_page_to_urls' ) ? trailingslashit( $base_slug ) : '';
58 $category_slug = get_option( 'woocommerce_product_category_slug' ) ? get_option( 'woocommerce_product_category_slug' ) : _x( 'product-category', 'slug', 'woocommerce' );
59 $tag_slug = get_option( 'woocommerce_product_tag_slug' ) ? get_option( 'woocommerce_product_tag_slug' ) : _x( 'product-tag', 'slug', 'woocommerce' );
60
61 if ( 'yes' === get_option( 'woocommerce_prepend_shop_page_to_products' ) ) {
62 $product_base = trailingslashit( $base_slug );
63 } else {
64 $product_slug = get_option( 'woocommerce_product_slug' );
65 if ( false !== $product_slug && ! empty( $product_slug ) ) {
66 $product_base = trailingslashit( $product_slug );
67 } else {
68 $product_base = trailingslashit( _x( 'product', 'slug', 'woocommerce' ) );
69 }
70 }
71
72 if ( 'yes' === get_option( 'woocommerce_prepend_category_to_products' ) ) {
73 $product_base .= trailingslashit( '%product_cat%' );
74 }
75
76 $permalinks = array(
77 'product_base' => untrailingslashit( $product_base ),
78 'category_base' => untrailingslashit( $category_base . $category_slug ),
79 'attribute_base' => untrailingslashit( $category_base ),
80 'tag_base' => untrailingslashit( $category_base . $tag_slug ),
81 );
82
83 update_option( 'woocommerce_permalinks', $permalinks );
84 }
85 }
86
87 /**
88 * Update sub-category display options for 2.0
89 *
90 * @return void
91 */
92 function wc_update_200_subcat_display() {
93 // Update subcat display settings.
94 if ( 'yes' === get_option( 'woocommerce_shop_show_subcategories' ) ) {
95 if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) {
96 update_option( 'woocommerce_shop_page_display', 'subcategories' );
97 } else {
98 update_option( 'woocommerce_shop_page_display', 'both' );
99 }
100 }
101
102 if ( 'yes' === get_option( 'woocommerce_show_subcategories' ) ) {
103 if ( 'yes' === get_option( 'woocommerce_hide_products_when_showing_subcategories' ) ) {
104 update_option( 'woocommerce_category_archive_display', 'subcategories' );
105 } else {
106 update_option( 'woocommerce_category_archive_display', 'both' );
107 }
108 }
109 }
110
111 /**
112 * Update tax rates for 2.0
113 *
114 * @return void
115 */
116 function wc_update_200_taxrates() {
117 global $wpdb;
118
119 // Update tax rates.
120 $loop = 0;
121 $tax_rates = get_option( 'woocommerce_tax_rates' );
122
123 if ( $tax_rates ) {
124 foreach ( $tax_rates as $tax_rate ) {
125
126 foreach ( $tax_rate['countries'] as $country => $states ) {
127
128 $states = array_reverse( $states );
129
130 foreach ( $states as $state ) {
131
132 if ( '*' === $state ) {
133 $state = '';
134 }
135
136 $wpdb->insert(
137 $wpdb->prefix . 'woocommerce_tax_rates',
138 array(
139 'tax_rate_country' => $country,
140 'tax_rate_state' => $state,
141 'tax_rate' => $tax_rate['rate'],
142 'tax_rate_name' => $tax_rate['label'],
143 'tax_rate_priority' => 1,
144 'tax_rate_compound' => ( 'yes' === $tax_rate['compound'] ) ? 1 : 0,
145 'tax_rate_shipping' => ( 'yes' === $tax_rate['shipping'] ) ? 1 : 0,
146 'tax_rate_order' => $loop,
147 'tax_rate_class' => $tax_rate['class'],
148 )
149 );
150
151 $loop++;
152 }
153 }
154 }
155 }
156
157 $local_tax_rates = get_option( 'woocommerce_local_tax_rates' );
158
159 if ( $local_tax_rates ) {
160 foreach ( $local_tax_rates as $tax_rate ) {
161
162 $location_type = ( 'postcode' === $tax_rate['location_type'] ) ? 'postcode' : 'city';
163
164 if ( '*' === $tax_rate['state'] ) {
165 $tax_rate['state'] = '';
166 }
167
168 $wpdb->insert(
169 $wpdb->prefix . 'woocommerce_tax_rates',
170 array(
171 'tax_rate_country' => $tax_rate['country'],
172 'tax_rate_state' => $tax_rate['state'],
173 'tax_rate' => $tax_rate['rate'],
174 'tax_rate_name' => $tax_rate['label'],
175 'tax_rate_priority' => 2,
176 'tax_rate_compound' => ( 'yes' === $tax_rate['compound'] ) ? 1 : 0,
177 'tax_rate_shipping' => ( 'yes' === $tax_rate['shipping'] ) ? 1 : 0,
178 'tax_rate_order' => $loop,
179 'tax_rate_class' => $tax_rate['class'],
180 )
181 );
182
183 $tax_rate_id = $wpdb->insert_id;
184
185 if ( $tax_rate['locations'] ) {
186 foreach ( $tax_rate['locations'] as $location ) {
187
188 $wpdb->insert(
189 $wpdb->prefix . 'woocommerce_tax_rate_locations',
190 array(
191 'location_code' => $location,
192 'tax_rate_id' => $tax_rate_id,
193 'location_type' => $location_type,
194 )
195 );
196
197 }
198 }
199
200 $loop++;
201 }
202 }
203
204 update_option( 'woocommerce_tax_rates_backup', $tax_rates );
205 update_option( 'woocommerce_local_tax_rates_backup', $local_tax_rates );
206 delete_option( 'woocommerce_tax_rates' );
207 delete_option( 'woocommerce_local_tax_rates' );
208 }
209
210 /**
211 * Update order item line items for 2.0
212 *
213 * @return void
214 */
215 function wc_update_200_line_items() {
216 global $wpdb;
217
218 // Now its time for the massive update to line items - move them to the new DB tables.
219 // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old'.
220 $order_item_rows = $wpdb->get_results(
221 "SELECT meta_value, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_order_items'"
222 );
223
224 foreach ( $order_item_rows as $order_item_row ) {
225
226 $order_items = (array) maybe_unserialize( $order_item_row->meta_value );
227
228 foreach ( $order_items as $order_item ) {
229
230 if ( ! isset( $order_item['line_total'] ) && isset( $order_item['taxrate'] ) && isset( $order_item['cost'] ) ) {
231 $order_item['line_tax'] = number_format( ( $order_item['cost'] * $order_item['qty'] ) * ( $order_item['taxrate'] / 100 ), 2, '.', '' );
232 $order_item['line_total'] = $order_item['cost'] * $order_item['qty'];
233 $order_item['line_subtotal_tax'] = $order_item['line_tax'];
234 $order_item['line_subtotal'] = $order_item['line_total'];
235 }
236
237 $order_item['line_tax'] = isset( $order_item['line_tax'] ) ? $order_item['line_tax'] : 0;
238 $order_item['line_total'] = isset( $order_item['line_total'] ) ? $order_item['line_total'] : 0;
239 $order_item['line_subtotal_tax'] = isset( $order_item['line_subtotal_tax'] ) ? $order_item['line_subtotal_tax'] : 0;
240 $order_item['line_subtotal'] = isset( $order_item['line_subtotal'] ) ? $order_item['line_subtotal'] : 0;
241
242 $item_id = wc_add_order_item(
243 $order_item_row->post_id,
244 array(
245 'order_item_name' => $order_item['name'],
246 'order_item_type' => 'line_item',
247 )
248 );
249
250 // Add line item meta.
251 if ( $item_id ) {
252 wc_add_order_item_meta( $item_id, '_qty', absint( $order_item['qty'] ) );
253 wc_add_order_item_meta( $item_id, '_tax_class', $order_item['tax_class'] );
254 wc_add_order_item_meta( $item_id, '_product_id', $order_item['id'] );
255 wc_add_order_item_meta( $item_id, '_variation_id', $order_item['variation_id'] );
256 wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $order_item['line_subtotal'] ) );
257 wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $order_item['line_subtotal_tax'] ) );
258 wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $order_item['line_total'] ) );
259 wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $order_item['line_tax'] ) );
260
261 $meta_rows = array();
262
263 // Insert meta.
264 if ( ! empty( $order_item['item_meta'] ) ) {
265 foreach ( $order_item['item_meta'] as $key => $meta ) {
266 // Backwards compatibility.
267 if ( is_array( $meta ) && isset( $meta['meta_name'] ) ) {
268 $meta_rows[] = '(' . $item_id . ',"' . esc_sql( $meta['meta_name'] ) . '","' . esc_sql( $meta['meta_value'] ) . '")';
269 } else {
270 $meta_rows[] = '(' . $item_id . ',"' . esc_sql( $key ) . '","' . esc_sql( $meta ) . '")';
271 }
272 }
273 }
274
275 // Insert meta rows at once.
276 if ( count( $meta_rows ) > 0 ) {
277 $wpdb->query(
278 $wpdb->prepare(
279 "INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value )
280 VALUES " . implode( ',', $meta_rows ) . ';', // @codingStandardsIgnoreLine
281 $order_item_row->post_id
282 )
283 );
284 }
285
286 // Delete from DB (rename).
287 $wpdb->query(
288 $wpdb->prepare(
289 "UPDATE {$wpdb->postmeta}
290 SET meta_key = '_order_items_old'
291 WHERE meta_key = '_order_items'
292 AND post_id = %d",
293 $order_item_row->post_id
294 )
295 );
296 }
297
298 unset( $meta_rows, $item_id, $order_item );
299 }
300 }
301
302 // Do the same kind of update for order_taxes - move to lines.
303 // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_taxes' WHERE meta_key = '_order_taxes_old'.
304 $order_tax_rows = $wpdb->get_results(
305 "SELECT meta_value, post_id FROM {$wpdb->postmeta}
306 WHERE meta_key = '_order_taxes'"
307 );
308
309 foreach ( $order_tax_rows as $order_tax_row ) {
310
311 $order_taxes = (array) maybe_unserialize( $order_tax_row->meta_value );
312
313 if ( ! empty( $order_taxes ) ) {
314 foreach ( $order_taxes as $order_tax ) {
315
316 if ( ! isset( $order_tax['label'] ) || ! isset( $order_tax['cart_tax'] ) || ! isset( $order_tax['shipping_tax'] ) ) {
317 continue;
318 }
319
320 $item_id = wc_add_order_item(
321 $order_tax_row->post_id,
322 array(
323 'order_item_name' => $order_tax['label'],
324 'order_item_type' => 'tax',
325 )
326 );
327
328 // Add line item meta.
329 if ( $item_id ) {
330 wc_add_order_item_meta( $item_id, 'compound', absint( isset( $order_tax['compound'] ) ? $order_tax['compound'] : 0 ) );
331 wc_add_order_item_meta( $item_id, 'tax_amount', wc_clean( $order_tax['cart_tax'] ) );
332 wc_add_order_item_meta( $item_id, 'shipping_tax_amount', wc_clean( $order_tax['shipping_tax'] ) );
333 }
334
335 // Delete from DB (rename).
336 $wpdb->query(
337 $wpdb->prepare(
338 "UPDATE {$wpdb->postmeta}
339 SET meta_key = '_order_taxes_old'
340 WHERE meta_key = '_order_taxes'
341 AND post_id = %d",
342 $order_tax_row->post_id
343 )
344 );
345
346 unset( $tax_amount );
347 }
348 }
349 }
350 }
351
352 /**
353 * Update image settings for 2.0
354 *
355 * @return void
356 */
357 function wc_update_200_images() {
358 // Grab the pre 2.0 Image options and use to populate the new image options settings,
359 // cleaning up afterwards like nice people do.
360 foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) {
361
362 $old_settings = array_filter(
363 array(
364 'width' => get_option( 'woocommerce_' . $value . '_image_width' ),
365 'height' => get_option( 'woocommerce_' . $value . '_image_height' ),
366 'crop' => get_option( 'woocommerce_' . $value . '_image_crop' ),
367 )
368 );
369
370 if ( ! empty( $old_settings ) && update_option( 'shop_' . $value . '_image_size', $old_settings ) ) {
371
372 delete_option( 'woocommerce_' . $value . '_image_width' );
373 delete_option( 'woocommerce_' . $value . '_image_height' );
374 delete_option( 'woocommerce_' . $value . '_image_crop' );
375
376 }
377 }
378 }
379
380 /**
381 * Update DB version for 2.0
382 *
383 * @return void
384 */
385 function wc_update_200_db_version() {
386 WC_Install::update_db_version( '2.0.0' );
387 }
388
389 /**
390 * Update Brazilian States for 2.0.9
391 *
392 * @return void
393 */
394 function wc_update_209_brazillian_state() {
395 global $wpdb;
396
397 // phpcs:disable WordPress.DB.SlowDBQuery
398
399 // Update brazillian state codes.
400 $wpdb->update(
401 $wpdb->postmeta,
402 array(
403 'meta_value' => 'BA',
404 ),
405 array(
406 'meta_key' => '_billing_state',
407 'meta_value' => 'BH',
408 )
409 );
410 $wpdb->update(
411 $wpdb->postmeta,
412 array(
413 'meta_value' => 'BA',
414 ),
415 array(
416 'meta_key' => '_shipping_state',
417 'meta_value' => 'BH',
418 )
419 );
420 $wpdb->update(
421 $wpdb->usermeta,
422 array(
423 'meta_value' => 'BA',
424 ),
425 array(
426 'meta_key' => 'billing_state',
427 'meta_value' => 'BH',
428 )
429 );
430 $wpdb->update(
431 $wpdb->usermeta,
432 array(
433 'meta_value' => 'BA',
434 ),
435 array(
436 'meta_key' => 'shipping_state',
437 'meta_value' => 'BH',
438 )
439 );
440
441 // phpcs:enable WordPress.DB.SlowDBQuery
442 }
443
444 /**
445 * Update DB version for 2.0.9
446 *
447 * @return void
448 */
449 function wc_update_209_db_version() {
450 WC_Install::update_db_version( '2.0.9' );
451 }
452
453 /**
454 * Remove pages for 2.1
455 *
456 * @return void
457 */
458 function wc_update_210_remove_pages() {
459 // Pages no longer used.
460 wp_trash_post( get_option( 'woocommerce_pay_page_id' ) );
461 wp_trash_post( get_option( 'woocommerce_thanks_page_id' ) );
462 wp_trash_post( get_option( 'woocommerce_view_order_page_id' ) );
463 wp_trash_post( get_option( 'woocommerce_change_password_page_id' ) );
464 wp_trash_post( get_option( 'woocommerce_edit_address_page_id' ) );
465 wp_trash_post( get_option( 'woocommerce_lost_password_page_id' ) );
466 }
467
468 /**
469 * Update file paths to support multiple files for 2.1
470 *
471 * @return void
472 */
473 function wc_update_210_file_paths() {
474 global $wpdb;
475
476 // Upgrade file paths to support multiple file paths + names etc.
477 $existing_file_paths = $wpdb->get_results( "SELECT meta_value, meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_file_paths' AND meta_value != '';" );
478
479 if ( $existing_file_paths ) {
480
481 foreach ( $existing_file_paths as $existing_file_path ) {
482
483 $needs_update = false;
484 $new_value = array();
485 $value = maybe_unserialize( trim( $existing_file_path->meta_value ) );
486
487 if ( $value ) {
488 foreach ( $value as $key => $file ) {
489 if ( ! is_array( $file ) ) {
490 $needs_update = true;
491 $new_value[ $key ] = array(
492 'file' => $file,
493 'name' => wc_get_filename_from_url( $file ),
494 );
495 } else {
496 $new_value[ $key ] = $file;
497 }
498 }
499 if ( $needs_update ) {
500 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
501 $new_value = serialize( $new_value );
502
503 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = %s, meta_value = %s WHERE meta_id = %d", '_downloadable_files', $new_value, $existing_file_path->meta_id ) );
504 }
505 }
506 }
507 }
508 }
509
510 /**
511 * Update DB version for 2.1
512 *
513 * @return void
514 */
515 function wc_update_210_db_version() {
516 WC_Install::update_db_version( '2.1.0' );
517 }
518
519 /**
520 * Update shipping options for 2.2
521 *
522 * @return void
523 */
524 function wc_update_220_shipping() {
525 $woocommerce_ship_to_destination = 'shipping';
526
527 if ( get_option( 'woocommerce_ship_to_billing_address_only' ) === 'yes' ) {
528 $woocommerce_ship_to_destination = 'billing_only';
529 } elseif ( get_option( 'woocommerce_ship_to_billing' ) === 'yes' ) {
530 $woocommerce_ship_to_destination = 'billing';
531 }
532
533 add_option( 'woocommerce_ship_to_destination', $woocommerce_ship_to_destination, '', 'no' );
534 }
535
536 /**
537 * Update order statuses for 2.2
538 *
539 * @return void
540 */
541 function wc_update_220_order_status() {
542 global $wpdb;
543 $wpdb->query(
544 "UPDATE {$wpdb->posts} as posts
545 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
546 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
547 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
548 SET posts.post_status = 'wc-pending'
549 WHERE posts.post_type = 'shop_order'
550 AND posts.post_status = 'publish'
551 AND tax.taxonomy = 'shop_order_status'
552 AND term.slug LIKE 'pending%';"
553 );
554 $wpdb->query(
555 "UPDATE {$wpdb->posts} as posts
556 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
557 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
558 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
559 SET posts.post_status = 'wc-processing'
560 WHERE posts.post_type = 'shop_order'
561 AND posts.post_status = 'publish'
562 AND tax.taxonomy = 'shop_order_status'
563 AND term.slug LIKE 'processing%';"
564 );
565 $wpdb->query(
566 "UPDATE {$wpdb->posts} as posts
567 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
568 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
569 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
570 SET posts.post_status = 'wc-on-hold'
571 WHERE posts.post_type = 'shop_order'
572 AND posts.post_status = 'publish'
573 AND tax.taxonomy = 'shop_order_status'
574 AND term.slug LIKE 'on-hold%';"
575 );
576 $wpdb->query(
577 "UPDATE {$wpdb->posts} as posts
578 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
579 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
580 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
581 SET posts.post_status = 'wc-completed'
582 WHERE posts.post_type = 'shop_order'
583 AND posts.post_status = 'publish'
584 AND tax.taxonomy = 'shop_order_status'
585 AND term.slug LIKE 'completed%';"
586 );
587 $wpdb->query(
588 "UPDATE {$wpdb->posts} as posts
589 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
590 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
591 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
592 SET posts.post_status = 'wc-cancelled'
593 WHERE posts.post_type = 'shop_order'
594 AND posts.post_status = 'publish'
595 AND tax.taxonomy = 'shop_order_status'
596 AND term.slug LIKE 'cancelled%';"
597 );
598 $wpdb->query(
599 "UPDATE {$wpdb->posts} as posts
600 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
601 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
602 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
603 SET posts.post_status = 'wc-refunded'
604 WHERE posts.post_type = 'shop_order'
605 AND posts.post_status = 'publish'
606 AND tax.taxonomy = 'shop_order_status'
607 AND term.slug LIKE 'refunded%';"
608 );
609 $wpdb->query(
610 "UPDATE {$wpdb->posts} as posts
611 LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
612 LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
613 LEFT JOIN {$wpdb->terms} AS term USING( term_id )
614 SET posts.post_status = 'wc-failed'
615 WHERE posts.post_type = 'shop_order'
616 AND posts.post_status = 'publish'
617 AND tax.taxonomy = 'shop_order_status'
618 AND term.slug LIKE 'failed%';"
619 );
620 }
621
622 /**
623 * Update variations for 2.2
624 *
625 * @return void
626 */
627 function wc_update_220_variations() {
628 global $wpdb;
629 // Update variations which manage stock.
630 $update_variations = $wpdb->get_results(
631 "SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent FROM {$wpdb->posts} as posts
632 LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock'
633 LEFT OUTER JOIN {$wpdb->postmeta} as postmeta2 ON posts.ID = postmeta2.post_id AND postmeta2.meta_key = '_manage_stock'
634 WHERE posts.post_type = 'product_variation'
635 AND postmeta.meta_value IS NOT NULL
636 AND postmeta.meta_value != ''
637 AND postmeta2.meta_value IS NULL"
638 );
639
640 foreach ( $update_variations as $variation ) {
641 $parent_backorders = get_post_meta( $variation->variation_parent, '_backorders', true );
642 add_post_meta( $variation->variation_id, '_manage_stock', 'yes', true );
643 add_post_meta( $variation->variation_id, '_backorders', $parent_backorders ? $parent_backorders : 'no', true );
644 }
645 }
646
647 /**
648 * Update attributes for 2.2
649 *
650 * @return void
651 */
652 function wc_update_220_attributes() {
653 global $wpdb;
654 // Update taxonomy names with correct sanitized names.
655 $attribute_taxonomies = $wpdb->get_results( 'SELECT attribute_name, attribute_id FROM ' . $wpdb->prefix . 'woocommerce_attribute_taxonomies' );
656
657 foreach ( $attribute_taxonomies as $attribute_taxonomy ) {
658 $sanitized_attribute_name = wc_sanitize_taxonomy_name( $attribute_taxonomy->attribute_name );
659 if ( $sanitized_attribute_name !== $attribute_taxonomy->attribute_name ) {
660 if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT 1=1 FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_name = %s;", $sanitized_attribute_name ) ) ) {
661 // Update attribute.
662 $wpdb->update(
663 "{$wpdb->prefix}woocommerce_attribute_taxonomies",
664 array(
665 'attribute_name' => $sanitized_attribute_name,
666 ),
667 array(
668 'attribute_id' => $attribute_taxonomy->attribute_id,
669 )
670 );
671
672 // Update terms.
673 $wpdb->update(
674 $wpdb->term_taxonomy,
675 array( 'taxonomy' => wc_attribute_taxonomy_name( $sanitized_attribute_name ) ),
676 array( 'taxonomy' => 'pa_' . $attribute_taxonomy->attribute_name )
677 );
678 }
679 }
680 }
681
682 delete_transient( 'wc_attribute_taxonomies' );
683 WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
684 }
685
686 /**
687 * Update DB version for 2.2
688 *
689 * @return void
690 */
691 function wc_update_220_db_version() {
692 WC_Install::update_db_version( '2.2.0' );
693 }
694
695 /**
696 * Update options for 2.3
697 *
698 * @return void
699 */
700 function wc_update_230_options() {
701 // _money_spent and _order_count may be out of sync - clear them
702 delete_metadata( 'user', 0, '_money_spent', '', true );
703 delete_metadata( 'user', 0, '_order_count', '', true );
704
705 // To prevent taxes being hidden when using a default 'no address' in a store with tax inc prices, set the woocommerce_default_customer_address to use the store base address by default.
706 if ( '' === get_option( 'woocommerce_default_customer_address', false ) && wc_prices_include_tax() ) {
707 update_option( 'woocommerce_default_customer_address', 'base' );
708 }
709 }
710
711 /**
712 * Update DB version for 2.3
713 *
714 * @return void
715 */
716 function wc_update_230_db_version() {
717 WC_Install::update_db_version( '2.3.0' );
718 }
719
720 /**
721 * Update calc discount options for 2.4
722 *
723 * @return void
724 */
725 function wc_update_240_options() {
726 /**
727 * Coupon discount calculations.
728 * Maintain the old coupon logic for upgrades.
729 */
730 update_option( 'woocommerce_calc_discounts_sequentially', 'yes' );
731 }
732
733 /**
734 * Update shipping methods for 2.4
735 *
736 * @return void
737 */
738 function wc_update_240_shipping_methods() {
739 /**
740 * Flat Rate Shipping.
741 * Update legacy options to new math based options.
742 */
743 $shipping_methods = array(
744 'woocommerce_flat_rates' => new WC_Shipping_Legacy_Flat_Rate(),
745 'woocommerce_international_delivery_flat_rates' => new WC_Shipping_Legacy_International_Delivery(),
746 );
747 foreach ( $shipping_methods as $flat_rate_option_key => $shipping_method ) {
748 // Stop this running more than once if routine is repeated.
749 if ( version_compare( $shipping_method->get_option( 'version', 0 ), '2.4.0', '<' ) ) {
750 $shipping_classes = WC()->shipping()->get_shipping_classes();
751 $has_classes = count( $shipping_classes ) > 0;
752 $cost_key = $has_classes ? 'no_class_cost' : 'cost';
753 $min_fee = $shipping_method->get_option( 'minimum_fee' );
754 $math_cost_strings = array(
755 'cost' => array(),
756 'no_class_cost' => array(),
757 );
758
759 $math_cost_strings[ $cost_key ][] = $shipping_method->get_option( 'cost' );
760 $fee = $shipping_method->get_option( 'fee' );
761
762 if ( $fee ) {
763 $math_cost_strings[ $cost_key ][] = strstr( $fee, '%' ) ? '[fee percent="' . str_replace( '%', '', $fee ) . '" min="' . esc_attr( $min_fee ) . '"]' : $fee;
764 }
765
766 foreach ( $shipping_classes as $shipping_class ) {
767 $rate_key = 'class_cost_' . $shipping_class->slug;
768 $math_cost_strings[ $rate_key ] = $math_cost_strings['no_class_cost'];
769 }
770
771 $flat_rates = array_filter( (array) get_option( $flat_rate_option_key, array() ) );
772
773 if ( $flat_rates ) {
774 foreach ( $flat_rates as $shipping_class => $rate ) {
775 $rate_key = 'class_cost_' . $shipping_class;
776 if ( $rate['cost'] || $rate['fee'] ) {
777 $math_cost_strings[ $rate_key ][] = $rate['cost'];
778 $math_cost_strings[ $rate_key ][] = strstr( $rate['fee'], '%' ) ? '[fee percent="' . str_replace( '%', '', $rate['fee'] ) . '" min="' . esc_attr( $min_fee ) . '"]' : $rate['fee'];
779 }
780 }
781 }
782
783 if ( 'item' === $shipping_method->type ) {
784 foreach ( $math_cost_strings as $key => $math_cost_string ) {
785 $math_cost_strings[ $key ] = array_filter( array_map( 'trim', $math_cost_strings[ $key ] ) );
786 if ( ! empty( $math_cost_strings[ $key ] ) ) {
787 $last_key = max( 0, count( $math_cost_strings[ $key ] ) - 1 );
788 $math_cost_strings[ $key ][0] = '( ' . $math_cost_strings[ $key ][0];
789 $math_cost_strings[ $key ][ $last_key ] .= ' ) * [qty]';
790 }
791 }
792 }
793
794 $math_cost_strings['cost'][] = $shipping_method->get_option( 'cost_per_order' );
795
796 // Save settings.
797 foreach ( $math_cost_strings as $option_id => $math_cost_string ) {
798 $shipping_method->settings[ $option_id ] = implode( ' + ', array_filter( $math_cost_string ) );
799 }
800
801 $shipping_method->settings['version'] = '2.4.0';
802 $shipping_method->settings['type'] = 'item' === $shipping_method->settings['type'] ? 'class' : $shipping_method->settings['type'];
803
804 update_option( $shipping_method->plugin_id . $shipping_method->id . '_settings', $shipping_method->settings );
805 }
806 }
807 }
808
809 /**
810 * Update API keys for 2.4
811 *
812 * @return void
813 */
814 function wc_update_240_api_keys() {
815 global $wpdb;
816 /**
817 * Update the old user API keys to the new Apps keys.
818 */
819 $api_users = $wpdb->get_results( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'woocommerce_api_consumer_key'" );
820 $apps_keys = array();
821
822 // Get user data.
823 foreach ( $api_users as $_user ) {
824 $user = get_userdata( $_user->user_id );
825 $apps_keys[] = array(
826 'user_id' => $user->ID,
827 'permissions' => $user->woocommerce_api_key_permissions,
828 'consumer_key' => wc_api_hash( $user->woocommerce_api_consumer_key ),
829 'consumer_secret' => $user->woocommerce_api_consumer_secret,
830 'truncated_key' => substr( $user->woocommerce_api_consumer_secret, -7 ),
831 );
832 }
833
834 if ( ! empty( $apps_keys ) ) {
835 // Create new apps.
836 foreach ( $apps_keys as $app ) {
837 $wpdb->insert(
838 $wpdb->prefix . 'woocommerce_api_keys',
839 $app,
840 array(
841 '%d',
842 '%s',
843 '%s',
844 '%s',
845 '%s',
846 )
847 );
848 }
849
850 // Delete old user keys from usermeta.
851 foreach ( $api_users as $_user ) {
852 $user_id = intval( $_user->user_id );
853 delete_user_meta( $user_id, 'woocommerce_api_consumer_key' );
854 delete_user_meta( $user_id, 'woocommerce_api_consumer_secret' );
855 delete_user_meta( $user_id, 'woocommerce_api_key_permissions' );
856 }
857 }
858 }
859
860 /**
861 * Update webhooks for 2.4
862 *
863 * @return void
864 */
865 function wc_update_240_webhooks() {
866 // phpcs:disable WordPress.DB.SlowDBQuery
867
868 /**
869 * Webhooks.
870 * Make sure order.update webhooks get the woocommerce_order_edit_status hook.
871 */
872 $order_update_webhooks = get_posts(
873 array(
874 'posts_per_page' => -1,
875 'post_type' => 'shop_webhook',
876 'meta_key' => '_topic',
877 'meta_value' => 'order.updated',
878 )
879 );
880 foreach ( $order_update_webhooks as $order_update_webhook ) {
881 $webhook = new WC_Webhook( $order_update_webhook->ID );
882 $webhook->set_topic( 'order.updated' );
883 }
884
885 // phpcs:enable WordPress.DB.SlowDBQuery
886 }
887
888 /**
889 * Update refunds for 2.4
890 *
891 * @return void
892 */
893 function wc_update_240_refunds() {
894 global $wpdb;
895 /**
896 * Refunds for full refunded orders.
897 * Update fully refunded orders to ensure they have a refund line item so reports add up.
898 */
899 $refunded_orders = get_posts(
900 array(
901 'posts_per_page' => -1,
902 'post_type' => 'shop_order',
903 'post_status' => array( 'wc-refunded' ),
904 )
905 );
906
907 // Ensure emails are disabled during this update routine.
908 remove_all_actions( 'woocommerce_order_status_refunded_notification' );
909 remove_all_actions( 'woocommerce_order_partially_refunded_notification' );
910 remove_action( 'woocommerce_order_status_refunded', array( 'WC_Emails', 'send_transactional_email' ) );
911 remove_action( 'woocommerce_order_partially_refunded', array( 'WC_Emails', 'send_transactional_email' ) );
912
913 foreach ( $refunded_orders as $refunded_order ) {
914 $order_total = get_post_meta( $refunded_order->ID, '_order_total', true );
915 $refunded_total = $wpdb->get_var(
916 $wpdb->prepare(
917 "SELECT SUM( postmeta.meta_value )
918 FROM $wpdb->postmeta AS postmeta
919 INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
920 WHERE postmeta.meta_key = '_refund_amount'
921 AND postmeta.post_id = posts.ID",
922 $refunded_order->ID
923 )
924 );
925
926 if ( $order_total > $refunded_total ) {
927 wc_create_refund(
928 array(
929 'amount' => $order_total - $refunded_total,
930 'reason' => __( 'Order fully refunded', 'woocommerce' ),
931 'order_id' => $refunded_order->ID,
932 'line_items' => array(),
933 'date' => $refunded_order->post_modified,
934 )
935 );
936 }
937 }
938
939 wc_delete_shop_order_transients();
940 }
941
942 /**
943 * Update DB version for 2.4
944 *
945 * @return void
946 */
947 function wc_update_240_db_version() {
948 WC_Install::update_db_version( '2.4.0' );
949 }
950
951 /**
952 * Update variations for 2.4.1
953 *
954 * @return void
955 */
956 function wc_update_241_variations() {
957 global $wpdb;
958
959 // Select variations that don't have any _stock_status implemented on WooCommerce 2.2.
960 $update_variations = $wpdb->get_results(
961 "SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent
962 FROM {$wpdb->posts} as posts
963 LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock_status'
964 WHERE posts.post_type = 'product_variation'
965 AND postmeta.meta_value IS NULL"
966 );
967
968 foreach ( $update_variations as $variation ) {
969 // Get the parent _stock_status.
970 $parent_stock_status = get_post_meta( $variation->variation_parent, '_stock_status', true );
971
972 // Set the _stock_status.
973 add_post_meta( $variation->variation_id, '_stock_status', $parent_stock_status ? $parent_stock_status : 'instock', true );
974
975 // Delete old product children array.
976 delete_transient( 'wc_product_children_' . $variation->variation_parent );
977 }
978
979 // Invalidate old transients such as wc_var_price.
980 WC_Cache_Helper::get_transient_version( 'product', true );
981 }
982
983 /**
984 * Update DB version for 2.4.1
985 *
986 * @return void
987 */
988 function wc_update_241_db_version() {
989 WC_Install::update_db_version( '2.4.1' );
990 }
991
992 /**
993 * Update currency settings for 2.5
994 *
995 * @return void
996 */
997 function wc_update_250_currency() {
998 global $wpdb;
999 // Fix currency settings for LAK currency.
1000 $current_currency = get_option( 'woocommerce_currency' );
1001
1002 if ( 'KIP' === $current_currency ) {
1003 update_option( 'woocommerce_currency', 'LAK' );
1004 }
1005
1006 // phpcs:disable WordPress.DB.SlowDBQuery
1007
1008 // Update LAK currency code.
1009 $wpdb->update(
1010 $wpdb->postmeta,
1011 array(
1012 'meta_value' => 'LAK',
1013 ),
1014 array(
1015 'meta_key' => '_order_currency',
1016 'meta_value' => 'KIP',
1017 )
1018 );
1019
1020 // phpcs:enable WordPress.DB.SlowDBQuery
1021 }
1022
1023 /**
1024 * Update DB version for 2.5
1025 *
1026 * @return void
1027 */
1028 function wc_update_250_db_version() {
1029 WC_Install::update_db_version( '2.5.0' );
1030 }
1031
1032 /**
1033 * Update ship to countries options for 2.6
1034 *
1035 * @return void
1036 */
1037 function wc_update_260_options() {
1038 // woocommerce_calc_shipping option has been removed in 2.6.
1039 if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) {
1040 update_option( 'woocommerce_ship_to_countries', 'disabled' );
1041 }
1042
1043 WC_Admin_Notices::add_notice( 'legacy_shipping' );
1044 }
1045
1046 /**
1047 * Update term meta for 2.6
1048 *
1049 * @return void
1050 */
1051 function wc_update_260_termmeta() {
1052 global $wpdb;
1053 /**
1054 * Migrate term meta to WordPress tables.
1055 */
1056 if ( get_option( 'db_version' ) >= 34370 && $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_termmeta';" ) ) {
1057 if ( $wpdb->query( "INSERT INTO {$wpdb->termmeta} ( term_id, meta_key, meta_value ) SELECT woocommerce_term_id, meta_key, meta_value FROM {$wpdb->prefix}woocommerce_termmeta;" ) ) {
1058 $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_termmeta" );
1059 wp_cache_flush();
1060 }
1061 }
1062 }
1063
1064 /**
1065 * Update zones for 2.6
1066 *
1067 * @return void
1068 */
1069 function wc_update_260_zones() {
1070 global $wpdb;
1071 /**
1072 * Old (table rate) shipping zones to new core shipping zones migration.
1073 * zone_enabled and zone_type are no longer used, but it's safe to leave them be.
1074 */
1075 if ( $wpdb->get_var( "SHOW COLUMNS FROM `{$wpdb->prefix}woocommerce_shipping_zones` LIKE 'zone_enabled';" ) ) {
1076 $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zones CHANGE `zone_type` `zone_type` VARCHAR(40) NOT NULL DEFAULT '';" );
1077 $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zones CHANGE `zone_enabled` `zone_enabled` INT(1) NOT NULL DEFAULT 1;" );
1078 }
1079 }
1080
1081 /**
1082 * Update zone methods for 2.6
1083 *
1084 * @return void
1085 */
1086 function wc_update_260_zone_methods() {
1087 global $wpdb;
1088
1089 /**
1090 * Shipping zones in WC 2.6.0 use a table named woocommerce_shipping_zone_methods.
1091 * Migrate the old data out of woocommerce_shipping_zone_shipping_methods into the new table and port over any known options (used by table rates and flat rate boxes).
1092 */
1093 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_shipping_zone_shipping_methods';" ) ) {
1094 $old_methods = $wpdb->get_results( "SELECT zone_id, shipping_method_type, shipping_method_order, shipping_method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_shipping_methods;" );
1095
1096 if ( $old_methods ) {
1097 $max_new_id = $wpdb->get_var( "SELECT MAX(instance_id) FROM {$wpdb->prefix}woocommerce_shipping_zone_methods" );
1098 $max_old_id = $wpdb->get_var( "SELECT MAX(shipping_method_id) FROM {$wpdb->prefix}woocommerce_shipping_zone_shipping_methods" );
1099
1100 // Avoid ID conflicts.
1101 $wpdb->query( $wpdb->prepare( "ALTER TABLE {$wpdb->prefix}woocommerce_shipping_zone_methods AUTO_INCREMENT = %d;", max( $max_new_id, $max_old_id ) + 1 ) );
1102
1103 // Store changes.
1104 $changes = array();
1105
1106 // Move data.
1107 foreach ( $old_methods as $old_method ) {
1108 $wpdb->insert(
1109 $wpdb->prefix . 'woocommerce_shipping_zone_methods',
1110 array(
1111 'zone_id' => $old_method->zone_id,
1112 'method_id' => $old_method->shipping_method_type,
1113 'method_order' => $old_method->shipping_method_order,
1114 )
1115 );
1116
1117 $new_instance_id = $wpdb->insert_id;
1118
1119 // Move main settings.
1120 $older_settings_key = 'woocommerce_' . $old_method->shipping_method_type . '-' . $old_method->shipping_method_id . '_settings';
1121 $old_settings_key = 'woocommerce_' . $old_method->shipping_method_type . '_' . $old_method->shipping_method_id . '_settings';
1122 add_option( 'woocommerce_' . $old_method->shipping_method_type . '_' . $new_instance_id . '_settings', get_option( $old_settings_key, get_option( $older_settings_key ) ) );
1123
1124 // Handling for table rate and flat rate box shipping.
1125 if ( 'table_rate' === $old_method->shipping_method_type ) {
1126 // Move priority settings.
1127 add_option( 'woocommerce_table_rate_default_priority_' . $new_instance_id, get_option( 'woocommerce_table_rate_default_priority_' . $old_method->shipping_method_id ) );
1128 add_option( 'woocommerce_table_rate_priorities_' . $new_instance_id, get_option( 'woocommerce_table_rate_priorities_' . $old_method->shipping_method_id ) );
1129
1130 // Move rates.
1131 $wpdb->update(
1132 $wpdb->prefix . 'woocommerce_shipping_table_rates',
1133 array(
1134 'shipping_method_id' => $new_instance_id,
1135 ),
1136 array(
1137 'shipping_method_id' => $old_method->shipping_method_id,
1138 )
1139 );
1140 } elseif ( 'flat_rate_boxes' === $old_method->shipping_method_type ) {
1141 $wpdb->update(
1142 $wpdb->prefix . 'woocommerce_shipping_flat_rate_boxes',
1143 array(
1144 'shipping_method_id' => $new_instance_id,
1145 ),
1146 array(
1147 'shipping_method_id' => $old_method->shipping_method_id,
1148 )
1149 );
1150 }
1151
1152 $changes[ $old_method->shipping_method_id ] = $new_instance_id;
1153 }
1154
1155 // $changes contains keys (old method ids) and values (new instance ids) if extra processing is needed in plugins.
1156 // Store this to an option so extensions can pick it up later, then fire an action.
1157 update_option( 'woocommerce_updated_instance_ids', $changes );
1158 do_action( 'woocommerce_updated_instance_ids', $changes );
1159 }
1160 }
1161
1162 // Change ranges used to ...
1163 $wpdb->query( "UPDATE {$wpdb->prefix}woocommerce_shipping_zone_locations SET location_code = REPLACE( location_code, '-', '...' );" );
1164 }
1165
1166 /**
1167 * Update refunds for 2.6
1168 *
1169 * @return void
1170 */
1171 function wc_update_260_refunds() {
1172 global $wpdb;
1173 /**
1174 * Refund item qty should be negative.
1175 */
1176 $wpdb->query(
1177 "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta
1178 LEFT JOIN {$wpdb->prefix}woocommerce_order_items as items ON item_meta.order_item_id = items.order_item_id
1179 LEFT JOIN {$wpdb->posts} as posts ON items.order_id = posts.ID
1180 SET item_meta.meta_value = item_meta.meta_value * -1
1181 WHERE item_meta.meta_value > 0 AND item_meta.meta_key = '_qty' AND posts.post_type = 'shop_order_refund'"
1182 );
1183 }
1184
1185 /**
1186 * Update DB version for 2.6
1187 *
1188 * @return void
1189 */
1190 function wc_update_260_db_version() {
1191 WC_Install::update_db_version( '2.6.0' );
1192 }
1193
1194 /**
1195 * Update webhooks for 3.0
1196 *
1197 * @return void
1198 */
1199 function wc_update_300_webhooks() {
1200 // phpcs:disable WordPress.DB.SlowDBQuery
1201
1202 /**
1203 * Make sure product.update webhooks get the woocommerce_product_quick_edit_save
1204 * and woocommerce_product_bulk_edit_save hooks.
1205 */
1206 $product_update_webhooks = get_posts(
1207 array(
1208 'posts_per_page' => -1,
1209 'post_type' => 'shop_webhook',
1210 'meta_key' => '_topic',
1211 'meta_value' => 'product.updated',
1212 )
1213 );
1214 foreach ( $product_update_webhooks as $product_update_webhook ) {
1215 $webhook = new WC_Webhook( $product_update_webhook->ID );
1216 $webhook->set_topic( 'product.updated' );
1217 }
1218
1219 // phpcs:enable WordPress.DB.SlowDBQuery
1220 }
1221
1222 /**
1223 * Add an index to the field comment_type to improve the response time of the query
1224 * used by WC_Comments::wp_count_comments() to get the number of comments by type.
1225 */
1226 function wc_update_300_comment_type_index() {
1227 global $wpdb;
1228
1229 $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->comments} WHERE column_name = 'comment_type' and key_name = 'woo_idx_comment_type'" );
1230
1231 if ( is_null( $index_exists ) ) {
1232 // Add an index to the field comment_type to improve the response time of the query
1233 // used by WC_Comments::wp_count_comments() to get the number of comments by type.
1234 $wpdb->query( "ALTER TABLE {$wpdb->comments} ADD INDEX woo_idx_comment_type (comment_type)" );
1235 }
1236 }
1237
1238 /**
1239 * Update grouped products for 3.0
1240 *
1241 * @return void
1242 */
1243 function wc_update_300_grouped_products() {
1244 global $wpdb;
1245 $parents = $wpdb->get_col( "SELECT DISTINCT( post_parent ) FROM {$wpdb->posts} WHERE post_parent > 0 AND post_type = 'product';" );
1246 foreach ( $parents as $parent_id ) {
1247 $parent = wc_get_product( $parent_id );
1248 if ( $parent && $parent->is_type( 'grouped' ) ) {
1249 $children_ids = get_posts(
1250 array(
1251 'post_parent' => $parent_id,
1252 'posts_per_page' => -1,
1253 'post_type' => 'product',
1254 'fields' => 'ids',
1255 )
1256 );
1257 update_post_meta( $parent_id, '_children', $children_ids );
1258
1259 // Update children to remove the parent.
1260 $wpdb->update(
1261 $wpdb->posts,
1262 array(
1263 'post_parent' => 0,
1264 ),
1265 array(
1266 'post_parent' => $parent_id,
1267 )
1268 );
1269 }
1270 }
1271 }
1272
1273 /**
1274 * Update shipping tax classes for 3.0
1275 *
1276 * @return void
1277 */
1278 function wc_update_300_settings() {
1279 $woocommerce_shipping_tax_class = get_option( 'woocommerce_shipping_tax_class' );
1280 if ( '' === $woocommerce_shipping_tax_class ) {
1281 update_option( 'woocommerce_shipping_tax_class', 'inherit' );
1282 } elseif ( 'standard' === $woocommerce_shipping_tax_class ) {
1283 update_option( 'woocommerce_shipping_tax_class', '' );
1284 }
1285 }
1286
1287 /**
1288 * Convert meta values into term for product visibility.
1289 */
1290 function wc_update_300_product_visibility() {
1291 global $wpdb;
1292
1293 WC_Install::create_terms();
1294
1295 $featured_term = get_term_by( 'name', 'featured', 'product_visibility' );
1296
1297 if ( $featured_term ) {
1298 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_featured' AND meta_value = 'yes';", $featured_term->term_taxonomy_id ) );
1299 }
1300
1301 $exclude_search_term = get_term_by( 'name', 'exclude-from-search', 'product_visibility' );
1302
1303 if ( $exclude_search_term ) {
1304 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'catalog');", $exclude_search_term->term_taxonomy_id ) );
1305 }
1306
1307 $exclude_catalog_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' );
1308
1309 if ( $exclude_catalog_term ) {
1310 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'search');", $exclude_catalog_term->term_taxonomy_id ) );
1311 }
1312
1313 $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' );
1314
1315 if ( $outofstock_term ) {
1316 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_stock_status' AND meta_value = 'outofstock';", $outofstock_term->term_taxonomy_id ) );
1317 }
1318
1319 $rating_term = get_term_by( 'name', 'rated-1', 'product_visibility' );
1320
1321 if ( $rating_term ) {
1322 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 1;", $rating_term->term_taxonomy_id ) );
1323 }
1324
1325 $rating_term = get_term_by( 'name', 'rated-2', 'product_visibility' );
1326
1327 if ( $rating_term ) {
1328 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 2;", $rating_term->term_taxonomy_id ) );
1329 }
1330
1331 $rating_term = get_term_by( 'name', 'rated-3', 'product_visibility' );
1332
1333 if ( $rating_term ) {
1334 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 3;", $rating_term->term_taxonomy_id ) );
1335 }
1336
1337 $rating_term = get_term_by( 'name', 'rated-4', 'product_visibility' );
1338
1339 if ( $rating_term ) {
1340 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 4;", $rating_term->term_taxonomy_id ) );
1341 }
1342
1343 $rating_term = get_term_by( 'name', 'rated-5', 'product_visibility' );
1344
1345 if ( $rating_term ) {
1346 $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 5;", $rating_term->term_taxonomy_id ) );
1347 }
1348 }
1349
1350 /**
1351 * Update DB Version.
1352 */
1353 function wc_update_300_db_version() {
1354 WC_Install::update_db_version( '3.0.0' );
1355 }
1356
1357 /**
1358 * Add an index to the downloadable product permissions table to improve performance of update_user_by_order_id.
1359 */
1360 function wc_update_310_downloadable_products() {
1361 global $wpdb;
1362
1363 $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE column_name = 'order_id' and key_name = 'order_id'" );
1364
1365 if ( is_null( $index_exists ) ) {
1366 $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD INDEX order_id (order_id)" );
1367 }
1368 }
1369
1370 /**
1371 * Find old order notes and ensure they have the correct type for exclusion.
1372 */
1373 function wc_update_310_old_comments() {
1374 global $wpdb;
1375
1376 $wpdb->query( "UPDATE $wpdb->comments comments LEFT JOIN $wpdb->posts as posts ON comments.comment_post_ID = posts.ID SET comment_type = 'order_note' WHERE posts.post_type = 'shop_order' AND comment_type = '';" );
1377 }
1378
1379 /**
1380 * Update DB Version.
1381 */
1382 function wc_update_310_db_version() {
1383 WC_Install::update_db_version( '3.1.0' );
1384 }
1385
1386 /**
1387 * Update shop_manager capabilities.
1388 */
1389 function wc_update_312_shop_manager_capabilities() {
1390 $role = get_role( 'shop_manager' );
1391 $role->remove_cap( 'unfiltered_html' );
1392 }
1393
1394 /**
1395 * Update DB Version.
1396 */
1397 function wc_update_312_db_version() {
1398 WC_Install::update_db_version( '3.1.2' );
1399 }
1400
1401 /**
1402 * Update state codes for Mexico.
1403 */
1404 function wc_update_320_mexican_states() {
1405 global $wpdb;
1406
1407 $mx_states = array(
1408 'Distrito Federal' => 'CMX',
1409 'Jalisco' => 'JAL',
1410 'Nuevo Leon' => 'NLE',
1411 'Aguascalientes' => 'AGS',
1412 'Baja California' => 'BCN',
1413 'Baja California Sur' => 'BCS',
1414 'Campeche' => 'CAM',
1415 'Chiapas' => 'CHP',
1416 'Chihuahua' => 'CHH',
1417 'Coahuila' => 'COA',
1418 'Colima' => 'COL',
1419 'Durango' => 'DGO',
1420 'Guanajuato' => 'GTO',
1421 'Guerrero' => 'GRO',
1422 'Hidalgo' => 'HGO',
1423 'Estado de Mexico' => 'MEX',
1424 'Michoacan' => 'MIC',
1425 'Morelos' => 'MOR',
1426 'Nayarit' => 'NAY',
1427 'Oaxaca' => 'OAX',
1428 'Puebla' => 'PUE',
1429 'Queretaro' => 'QRO',
1430 'Quintana Roo' => 'ROO',
1431 'San Luis Potosi' => 'SLP',
1432 'Sinaloa' => 'SIN',
1433 'Sonora' => 'SON',
1434 'Tabasco' => 'TAB',
1435 'Tamaulipas' => 'TMP',
1436 'Tlaxcala' => 'TLA',
1437 'Veracruz' => 'VER',
1438 'Yucatan' => 'YUC',
1439 'Zacatecas' => 'ZAC',
1440 );
1441
1442 foreach ( $mx_states as $old => $new ) {
1443 $wpdb->query(
1444 $wpdb->prepare(
1445 "UPDATE $wpdb->postmeta
1446 SET meta_value = %s
1447 WHERE meta_key IN ( '_billing_state', '_shipping_state' )
1448 AND meta_value = %s",
1449 $new,
1450 $old
1451 )
1452 );
1453 $wpdb->update(
1454 "{$wpdb->prefix}woocommerce_shipping_zone_locations",
1455 array(
1456 'location_code' => 'MX:' . $new,
1457 ),
1458 array(
1459 'location_code' => 'MX:' . $old,
1460 )
1461 );
1462 $wpdb->update(
1463 "{$wpdb->prefix}woocommerce_tax_rates",
1464 array(
1465 'tax_rate_state' => strtoupper( $new ),
1466 ),
1467 array(
1468 'tax_rate_state' => strtoupper( $old ),
1469 )
1470 );
1471 }
1472 }
1473
1474 /**
1475 * Update DB Version.
1476 */
1477 function wc_update_320_db_version() {
1478 WC_Install::update_db_version( '3.2.0' );
1479 }
1480
1481 /**
1482 * Update image settings to use new aspect ratios and widths.
1483 */
1484 function wc_update_330_image_options() {
1485 $old_thumbnail_size = get_option( 'shop_catalog_image_size', array() );
1486 $old_single_size = get_option( 'shop_single_image_size', array() );
1487
1488 if ( ! empty( $old_thumbnail_size['width'] ) ) {
1489 $width = absint( $old_thumbnail_size['width'] );
1490 $height = absint( $old_thumbnail_size['height'] );
1491 $hard_crop = ! empty( $old_thumbnail_size['crop'] );
1492
1493 if ( ! $width ) {
1494 $width = 300;
1495 }
1496
1497 if ( ! $height ) {
1498 $height = $width;
1499 }
1500
1501 update_option( 'woocommerce_thumbnail_image_width', $width );
1502
1503 // Calculate cropping mode from old image options.
1504 if ( ! $hard_crop ) {
1505 update_option( 'woocommerce_thumbnail_cropping', 'uncropped' );
1506 } elseif ( $width === $height ) {
1507 update_option( 'woocommerce_thumbnail_cropping', '1:1' );
1508 } else {
1509 $ratio = $width / $height;
1510 $fraction = wc_decimal_to_fraction( $ratio );
1511
1512 if ( $fraction ) {
1513 update_option( 'woocommerce_thumbnail_cropping', 'custom' );
1514 update_option( 'woocommerce_thumbnail_cropping_custom_width', $fraction[0] );
1515 update_option( 'woocommerce_thumbnail_cropping_custom_height', $fraction[1] );
1516 }
1517 }
1518 }
1519
1520 // Single is uncropped.
1521 if ( ! empty( $old_single_size['width'] ) ) {
1522 update_option( 'woocommerce_single_image_width', absint( $old_single_size['width'] ) );
1523 }
1524 }
1525
1526 /**
1527 * Migrate webhooks from post type to CRUD.
1528 */
1529 function wc_update_330_webhooks() {
1530 register_post_type( 'shop_webhook' );
1531
1532 // Map statuses from post_type to Webhooks CRUD.
1533 $statuses = array(
1534 'publish' => 'active',
1535 'draft' => 'paused',
1536 'pending' => 'disabled',
1537 );
1538
1539 $posts = get_posts(
1540 array(
1541 'posts_per_page' => -1,
1542 'post_type' => 'shop_webhook',
1543 'post_status' => 'any',
1544 )
1545 );
1546
1547 foreach ( $posts as $post ) {
1548 $webhook = new WC_Webhook();
1549 $webhook->set_name( $post->post_title );
1550 $webhook->set_status( isset( $statuses[ $post->post_status ] ) ? $statuses[ $post->post_status ] : 'disabled' );
1551 $webhook->set_delivery_url( get_post_meta( $post->ID, '_delivery_url', true ) );
1552 $webhook->set_secret( get_post_meta( $post->ID, '_secret', true ) );
1553 $webhook->set_topic( get_post_meta( $post->ID, '_topic', true ) );
1554 $webhook->set_api_version( get_post_meta( $post->ID, '_api_version', true ) );
1555 $webhook->set_user_id( $post->post_author );
1556 $webhook->set_pending_delivery( false );
1557 $webhook->save();
1558
1559 wp_delete_post( $post->ID, true );
1560 }
1561
1562 unregister_post_type( 'shop_webhook' );
1563 }
1564
1565 /**
1566 * Assign default cat to all products with no cats.
1567 */
1568 function wc_update_330_set_default_product_cat() {
1569 global $wpdb;
1570
1571 $default_category = get_option( 'default_product_cat', 0 );
1572
1573 if ( $default_category ) {
1574 $wpdb->query(
1575 $wpdb->prepare(
1576 "INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id)
1577 SELECT DISTINCT posts.ID, %s FROM {$wpdb->posts} posts
1578 LEFT JOIN
1579 (
1580 SELECT object_id FROM {$wpdb->term_relationships} term_relationships
1581 LEFT JOIN {$wpdb->term_taxonomy} term_taxonomy ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id
1582 WHERE term_taxonomy.taxonomy = 'product_cat'
1583 ) AS tax_query
1584 ON posts.ID = tax_query.object_id
1585 WHERE posts.post_type = 'product'
1586 AND tax_query.object_id IS NULL",
1587 $default_category
1588 )
1589 );
1590 wp_cache_flush();
1591 delete_transient( 'wc_term_counts' );
1592 wp_update_term_count_now( array( $default_category ), 'product_cat' );
1593 }
1594 }
1595
1596 /**
1597 * Update product stock status to use the new onbackorder status.
1598 */
1599 function wc_update_330_product_stock_status() {
1600 global $wpdb;
1601
1602 if ( 'yes' !== get_option( 'woocommerce_manage_stock' ) ) {
1603 return;
1604 }
1605
1606 $min_stock_amount = (int) get_option( 'woocommerce_notify_no_stock_amount', 0 );
1607
1608 // Get all products that have stock management enabled, stock less than or equal to min stock amount, and backorders enabled.
1609 $post_ids = $wpdb->get_col(
1610 $wpdb->prepare(
1611 "SELECT t1.post_id FROM $wpdb->postmeta t1
1612 INNER JOIN $wpdb->postmeta t2
1613 ON t1.post_id = t2.post_id
1614 AND t1.meta_key = '_manage_stock' AND t1.meta_value = 'yes'
1615 AND t2.meta_key = '_stock' AND t2.meta_value <= %d
1616 INNER JOIN $wpdb->postmeta t3
1617 ON t2.post_id = t3.post_id
1618 AND t3.meta_key = '_backorders' AND ( t3.meta_value = 'yes' OR t3.meta_value = 'notify' )",
1619 $min_stock_amount
1620 )
1621 );
1622
1623 if ( empty( $post_ids ) ) {
1624 return;
1625 }
1626
1627 $post_ids = array_map( 'absint', $post_ids );
1628
1629 // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
1630 // Set the status to onbackorder for those products.
1631 $wpdb->query(
1632 "UPDATE $wpdb->postmeta
1633 SET meta_value = 'onbackorder'
1634 WHERE meta_key = '_stock_status' AND post_id IN ( " . implode( ',', $post_ids ) . ' )'
1635 );
1636 // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
1637 }
1638
1639 /**
1640 * Clear addons page transients
1641 */
1642 function wc_update_330_clear_transients() {
1643 delete_transient( 'wc_addons_sections' );
1644 delete_transient( 'wc_addons_featured' );
1645 }
1646
1647 /**
1648 * Set PayPal's sandbox credentials.
1649 */
1650 function wc_update_330_set_paypal_sandbox_credentials() {
1651
1652 $paypal_settings = get_option( 'woocommerce_paypal_settings' );
1653
1654 if ( isset( $paypal_settings['testmode'] ) && 'yes' === $paypal_settings['testmode'] ) {
1655 foreach ( array( 'api_username', 'api_password', 'api_signature' ) as $credential ) {
1656 if ( ! empty( $paypal_settings[ $credential ] ) ) {
1657 $paypal_settings[ 'sandbox_' . $credential ] = $paypal_settings[ $credential ];
1658 }
1659 }
1660
1661 update_option( 'woocommerce_paypal_settings', $paypal_settings );
1662 }
1663 }
1664
1665 /**
1666 * Update DB Version.
1667 */
1668 function wc_update_330_db_version() {
1669 WC_Install::update_db_version( '3.3.0' );
1670 }
1671
1672 /**
1673 * Update state codes for Ireland and BD.
1674 */
1675 function wc_update_340_states() {
1676 $country_states = array(
1677 'IE' => array(
1678 'CK' => 'CO',
1679 'DN' => 'D',
1680 'GY' => 'G',
1681 'TY' => 'TA',
1682 ),
1683 'BD' => array(
1684 'BAG' => 'BD-05',
1685 'BAN' => 'BD-01',
1686 'BAR' => 'BD-02',
1687 'BARI' => 'BD-06',
1688 'BHO' => 'BD-07',
1689 'BOG' => 'BD-03',
1690 'BRA' => 'BD-04',
1691 'CHA' => 'BD-09',
1692 'CHI' => 'BD-10',
1693 'CHU' => 'BD-12',
1694 'COX' => 'BD-11',
1695 'COM' => 'BD-08',
1696 'DHA' => 'BD-13',
1697 'DIN' => 'BD-14',
1698 'FAR' => 'BD-15',
1699 'FEN' => 'BD-16',
1700 'GAI' => 'BD-19',
1701 'GAZI' => 'BD-18',
1702 'GOP' => 'BD-17',
1703 'HAB' => 'BD-20',
1704 'JAM' => 'BD-21',
1705 'JES' => 'BD-22',
1706 'JHA' => 'BD-25',
1707 'JHE' => 'BD-23',
1708 'JOY' => 'BD-24',
1709 'KHA' => 'BD-29',
1710 'KHU' => 'BD-27',
1711 'KIS' => 'BD-26',
1712 'KUR' => 'BD-28',
1713 'KUS' => 'BD-30',
1714 'LAK' => 'BD-31',
1715 'LAL' => 'BD-32',
1716 'MAD' => 'BD-36',
1717 'MAG' => 'BD-37',
1718 'MAN' => 'BD-33',
1719 'MEH' => 'BD-39',
1720 'MOU' => 'BD-38',
1721 'MUN' => 'BD-35',
1722 'MYM' => 'BD-34',
1723 'NAO' => 'BD-48',
1724 'NAR' => 'BD-43',
1725 'NARG' => 'BD-40',
1726 'NARD' => 'BD-42',
1727 'NAT' => 'BD-44',
1728 'NAW' => 'BD-45',
1729 'NET' => 'BD-41',
1730 'NIL' => 'BD-46',
1731 'NOA' => 'BD-47',
1732 'PAB' => 'BD-49',
1733 'PAN' => 'BD-52',
1734 'PAT' => 'BD-51',
1735 'PIR' => 'BD-50',
1736 'RAJB' => 'BD-53',
1737 'RAJ' => 'BD-54',
1738 'RAN' => 'BD-56',
1739 'RANP' => 'BD-55',
1740 'SAT' => 'BD-58',
1741 'SHA' => 'BD-57',
1742 'SIR' => 'BD-59',
1743 'SUN' => 'BD-61',
1744 'SYL' => 'BD-60',
1745 'TAN' => 'BD-63',
1746 'THA' => 'BD-64',
1747 ),
1748 );
1749
1750 update_option( 'woocommerce_update_340_states', $country_states );
1751 }
1752
1753 /**
1754 * Update next state in the queue.
1755 *
1756 * @return bool True to run again, false if completed.
1757 */
1758 function wc_update_340_state() {
1759 global $wpdb;
1760
1761 $country_states = array_filter( (array) get_option( 'woocommerce_update_340_states', array() ) );
1762
1763 if ( empty( $country_states ) ) {
1764 return false;
1765 }
1766
1767 foreach ( $country_states as $country => $states ) {
1768 foreach ( $states as $old => $new ) {
1769 $wpdb->query(
1770 $wpdb->prepare(
1771 "UPDATE $wpdb->postmeta
1772 SET meta_value = %s
1773 WHERE meta_key IN ( '_billing_state', '_shipping_state' )
1774 AND meta_value = %s",
1775 $new,
1776 $old
1777 )
1778 );
1779 $wpdb->update(
1780 "{$wpdb->prefix}woocommerce_shipping_zone_locations",
1781 array(
1782 'location_code' => $country . ':' . $new,
1783 ),
1784 array(
1785 'location_code' => $country . ':' . $old,
1786 )
1787 );
1788 $wpdb->update(
1789 "{$wpdb->prefix}woocommerce_tax_rates",
1790 array(
1791 'tax_rate_state' => strtoupper( $new ),
1792 ),
1793 array(
1794 'tax_rate_state' => strtoupper( $old ),
1795 )
1796 );
1797 unset( $country_states[ $country ][ $old ] );
1798
1799 if ( empty( $country_states[ $country ] ) ) {
1800 unset( $country_states[ $country ] );
1801 }
1802 break 2;
1803 }
1804 }
1805
1806 if ( ! empty( $country_states ) ) {
1807 return update_option( 'woocommerce_update_340_states', $country_states );
1808 }
1809
1810 delete_option( 'woocommerce_update_340_states' );
1811
1812 return false;
1813 }
1814
1815 /**
1816 * Set last active prop for users.
1817 */
1818 function wc_update_340_last_active() {
1819 global $wpdb;
1820 // @codingStandardsIgnoreStart.
1821 $wpdb->query(
1822 $wpdb->prepare( "
1823 INSERT INTO {$wpdb->usermeta} (user_id, meta_key, meta_value)
1824 SELECT DISTINCT users.ID, 'wc_last_active', %s
1825 FROM {$wpdb->users} as users
1826 LEFT OUTER JOIN {$wpdb->usermeta} AS usermeta ON users.ID = usermeta.user_id AND usermeta.meta_key = 'wc_last_active'
1827 WHERE usermeta.meta_value IS NULL
1828 ",
1829 (string) strtotime( date( 'Y-m-d', current_time( 'timestamp', true ) ) )
1830 )
1831 );
1832 // @codingStandardsIgnoreEnd.
1833 }
1834
1835 /**
1836 * Update DB Version.
1837 */
1838 function wc_update_340_db_version() {
1839 WC_Install::update_db_version( '3.4.0' );
1840 }
1841
1842 /**
1843 * Remove duplicate foreign keys
1844 *
1845 * @return void
1846 */
1847 function wc_update_343_cleanup_foreign_keys() {
1848 global $wpdb;
1849
1850 $results = $wpdb->get_results(
1851 "SELECT CONSTRAINT_NAME
1852 FROM information_schema.TABLE_CONSTRAINTS
1853 WHERE CONSTRAINT_SCHEMA = '{$wpdb->dbname}'
1854 AND CONSTRAINT_NAME LIKE '%wc_download_log_ib%'
1855 AND CONSTRAINT_TYPE = 'FOREIGN KEY'
1856 AND TABLE_NAME = '{$wpdb->prefix}wc_download_log'"
1857 );
1858
1859 if ( $results ) {
1860 foreach ( $results as $fk ) {
1861 $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_download_log DROP FOREIGN KEY {$fk->CONSTRAINT_NAME}" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
1862 }
1863 }
1864 }
1865
1866 /**
1867 * Update DB version.
1868 *
1869 * @return void
1870 */
1871 function wc_update_343_db_version() {
1872 WC_Install::update_db_version( '3.4.3' );
1873 }
1874
1875 /**
1876 * Recreate user roles so existing users will get the new capabilities.
1877 *
1878 * @return void
1879 */
1880 function wc_update_344_recreate_roles() {
1881 WC_Install::remove_roles();
1882 WC_Install::create_roles();
1883 }
1884
1885 /**
1886 * Update DB version.
1887 *
1888 * @return void
1889 */
1890 function wc_update_344_db_version() {
1891 WC_Install::update_db_version( '3.4.4' );
1892 }
1893
1894 /**
1895 * Set the comment type to 'review' for product reviews that don't have a comment type.
1896 */
1897 function wc_update_350_reviews_comment_type() {
1898 global $wpdb;
1899
1900 $wpdb->query(
1901 "UPDATE {$wpdb->prefix}comments JOIN {$wpdb->prefix}posts ON {$wpdb->prefix}posts.ID = {$wpdb->prefix}comments.comment_post_ID AND ( {$wpdb->prefix}posts.post_type = 'product' OR {$wpdb->prefix}posts.post_type = 'product_variation' ) SET {$wpdb->prefix}comments.comment_type = 'review' WHERE {$wpdb->prefix}comments.comment_type = ''"
1902 );
1903 }
1904
1905 /**
1906 * Update DB Version.
1907 */
1908 function wc_update_350_db_version() {
1909 WC_Install::update_db_version( '3.5.0' );
1910 }
1911
1912 /**
1913 * Drop the fk_wc_download_log_permission_id FK as we use a new one with the table and blog prefix for MS compatability.
1914 *
1915 * @return void
1916 */
1917 function wc_update_352_drop_download_log_fk() {
1918 global $wpdb;
1919 $results = $wpdb->get_results(
1920 "SELECT CONSTRAINT_NAME
1921 FROM information_schema.TABLE_CONSTRAINTS
1922 WHERE CONSTRAINT_SCHEMA = '{$wpdb->dbname}'
1923 AND CONSTRAINT_NAME = 'fk_wc_download_log_permission_id'
1924 AND CONSTRAINT_TYPE = 'FOREIGN KEY'
1925 AND TABLE_NAME = '{$wpdb->prefix}wc_download_log'"
1926 );
1927
1928 // We only need to drop the old key as WC_Install::create_tables() takes care of creating the new FK.
1929 if ( $results ) {
1930 $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_download_log DROP FOREIGN KEY fk_wc_download_log_permission_id" ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
1931 }
1932 }
1933
1934 /**
1935 * Remove edit_user capabilities from shop managers and use "translated" capabilities instead.
1936 * See wc_shop_manager_has_capability function.
1937 */
1938 function wc_update_354_modify_shop_manager_caps() {
1939 global $wp_roles;
1940
1941 if ( ! class_exists( 'WP_Roles' ) ) {
1942 return;
1943 }
1944
1945 if ( ! isset( $wp_roles ) ) {
1946 $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
1947 }
1948
1949 $wp_roles->remove_cap( 'shop_manager', 'edit_users' );
1950 }
1951
1952 /**
1953 * Update DB Version.
1954 */
1955 function wc_update_354_db_version() {
1956 WC_Install::update_db_version( '3.5.4' );
1957 }
1958
1959 /**
1960 * Update product lookup tables in bulk.
1961 */
1962 function wc_update_360_product_lookup_tables() {
1963 wc_update_product_lookup_tables();
1964 }
1965
1966 /**
1967 * Renames ordering meta to be consistent across taxonomies.
1968 */
1969 function wc_update_360_term_meta() {
1970 global $wpdb;
1971
1972 $wpdb->query( "UPDATE {$wpdb->termmeta} SET meta_key = 'order' WHERE meta_key LIKE 'order_pa_%';" );
1973 }
1974
1975 /**
1976 * Add new user_order_remaining_expires to speed up user download permission fetching.
1977 *
1978 * @return void
1979 */
1980 function wc_update_360_downloadable_product_permissions_index() {
1981 global $wpdb;
1982
1983 $index_exists = $wpdb->get_row( "SHOW INDEX FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE key_name = 'user_order_remaining_expires'" );
1984
1985 if ( is_null( $index_exists ) ) {
1986 $wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD INDEX user_order_remaining_expires (user_id,order_id,downloads_remaining,access_expires)" );
1987 }
1988 }
1989
1990 /**
1991 * Update DB Version.
1992 */
1993 function wc_update_360_db_version() {
1994 WC_Install::update_db_version( '3.6.0' );
1995 }
1996
1997 /**
1998 * Put tax classes into a DB table.
1999 *
2000 * @return void
2001 */
2002 function wc_update_370_tax_rate_classes() {
2003 global $wpdb;
2004
2005 $classes = array_map( 'trim', explode( "\n", get_option( 'woocommerce_tax_classes' ) ) );
2006
2007 if ( $classes ) {
2008 foreach ( $classes as $class ) {
2009 if ( empty( $class ) ) {
2010 continue;
2011 }
2012 WC_Tax::create_tax_class( $class );
2013 }
2014 }
2015 delete_option( 'woocommerce_tax_classes' );
2016 }
2017
2018 /**
2019 * Update currency settings for 3.7.0
2020 *
2021 * @return void
2022 */
2023 function wc_update_370_mro_std_currency() {
2024 global $wpdb;
2025
2026 // Fix currency settings for MRU and STN currency.
2027 $current_currency = get_option( 'woocommerce_currency' );
2028
2029 if ( 'MRO' === $current_currency ) {
2030 update_option( 'woocommerce_currency', 'MRU' );
2031 }
2032
2033 if ( 'STD' === $current_currency ) {
2034 update_option( 'woocommerce_currency', 'STN' );
2035 }
2036
2037 // Update MRU currency code.
2038 $wpdb->update(
2039 $wpdb->postmeta,
2040 array(
2041 'meta_value' => 'MRU', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
2042 ),
2043 array(
2044 'meta_key' => '_order_currency', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
2045 'meta_value' => 'MRO', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
2046 )
2047 );
2048
2049 // Update STN currency code.
2050 $wpdb->update(
2051 $wpdb->postmeta,
2052 array(
2053 'meta_value' => 'STN', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
2054 ),
2055 array(
2056 'meta_key' => '_order_currency', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
2057 'meta_value' => 'STD', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
2058 )
2059 );
2060 }
2061
2062 /**
2063 * Update DB Version.
2064 */
2065 function wc_update_370_db_version() {
2066 WC_Install::update_db_version( '3.7.0' );
2067 }
2068
2069 /**
2070 * We've moved the MaxMind database to a new location, as per the TOS' requirement that the database not
2071 * be publicly accessible.
2072 */
2073 function wc_update_390_move_maxmind_database() {
2074 // Make sure to use all of the correct filters to pull the local database path.
2075 $old_path = apply_filters( 'woocommerce_geolocation_local_database_path', WP_CONTENT_DIR . '/uploads/GeoLite2-Country.mmdb', 2 );
2076
2077 // Generate a prefix for the old file and store it in the integration as it would expect it.
2078 $prefix = wp_generate_password( 32, false );
2079 update_option( 'woocommerce_maxmind_geolocation_settings', array( 'database_prefix' => $prefix ) );
2080
2081 // Generate the new path in the same way that the integration will.
2082 $uploads_dir = wp_upload_dir();
2083 $new_path = trailingslashit( $uploads_dir['basedir'] ) . 'woocommerce_uploads/' . $prefix . '-GeoLite2-Country.mmdb';
2084 $new_path = apply_filters( 'woocommerce_geolocation_local_database_path', $new_path, 2 );
2085 $new_path = apply_filters( 'woocommerce_maxmind_geolocation_database_path', $new_path );
2086
2087 // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
2088 @rename( $old_path, $new_path );
2089 }
2090
2091 /**
2092 * So that we can best meet MaxMind's TOS, the geolocation database update cron should run once per 15 days.
2093 */
2094 function wc_update_390_change_geolocation_database_update_cron() {
2095 wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
2096 wp_schedule_event( time() + ( DAY_IN_SECONDS * 15 ), 'fifteendays', 'woocommerce_geoip_updater' );
2097 }
2098
2099 /**
2100 * Update DB version.
2101 */
2102 function wc_update_390_db_version() {
2103 WC_Install::update_db_version( '3.9.0' );
2104 }
2105
2106 /**
2107 * Increase column size
2108 */
2109 function wc_update_400_increase_size_of_column() {
2110 global $wpdb;
2111 $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_product_meta_lookup MODIFY COLUMN `min_price` decimal(19,4) NULL default NULL" );
2112 $wpdb->query( "ALTER TABLE {$wpdb->prefix}wc_product_meta_lookup MODIFY COLUMN `max_price` decimal(19,4) NULL default NULL" );
2113 }
2114
2115 /**
2116 * Reset ActionScheduler migration status. Needs AS >= 3.0 shipped with WC >= 4.0.
2117 */
2118 function wc_update_400_reset_action_scheduler_migration_status() {
2119 if (
2120 class_exists( 'ActionScheduler_DataController' ) &&
2121 method_exists( 'ActionScheduler_DataController', 'mark_migration_incomplete' )
2122 ) {
2123 \ActionScheduler_DataController::mark_migration_incomplete();
2124 }
2125 }
2126
2127 /**
2128 * Update DB version.
2129 */
2130 function wc_update_400_db_version() {
2131 WC_Install::update_db_version( '4.0.0' );
2132 }
2133
2134 /**
2135 * Register attributes as terms for variable products, in increments of 100 products.
2136 *
2137 * @return bool true if there are more products to process.
2138 */
2139 function wc_update_440_insert_attribute_terms_for_variable_products() {
2140 $state_option_name = 'woocommerce_' . __FUNCTION__ . '_state';
2141
2142 $page = intval( get_option( $state_option_name, 1 ) );
2143 $products = wc_get_products(
2144 array(
2145 'type' => 'variable',
2146 'limit' => 100,
2147 'page' => $page,
2148 )
2149 );
2150 if ( empty( $products ) ) {
2151 delete_option( $state_option_name );
2152 return false;
2153 }
2154
2155 $attribute_taxonomy_names = wc_get_attribute_taxonomy_names();
2156 foreach ( $products as $product ) {
2157 $variation_ids = $product->get_children();
2158 foreach ( $variation_ids as $variation_id ) {
2159 $variation = wc_get_product( $variation_id );
2160 $variation_attributes = $variation->get_attributes();
2161 foreach ( $variation_attributes as $attr_name => $attr_value ) {
2162 wp_set_post_terms( $variation_id, array( $attr_value ), $attr_name );
2163 }
2164 $attributes_to_delete = array_diff( $attribute_taxonomy_names, array_keys( $variation_attributes ) );
2165 wp_delete_object_term_relationships( $variation_id, $attributes_to_delete );
2166 }
2167 }
2168
2169 return update_option( $state_option_name, $page + 1 );
2170 }
2171
2172 /**
2173 * Update DB version.
2174 */
2175 function wc_update_440_db_version() {
2176 WC_Install::update_db_version( '4.4.0' );
2177 }
2178