From 1e11f8e8674139c69463768f93c28dcc8de1e0f0 Mon Sep 17 00:00:00 2001 From: Sicelo Date: Sun, 29 Aug 2021 16:00:09 +0200 Subject: [PATCH 01/53] Fix symbol for SZL currency The symbol for the Swaziland (now Eswatini) Lilangeni is not L (for Lilangeni), but E (for Emalangeni, plural). Even if it is just one Lilangeni, it is written as E1.00. --- plugins/woocommerce/includes/wc-core-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/wc-core-functions.php b/plugins/woocommerce/includes/wc-core-functions.php index 878c34f7fc1..d0d26b734cc 100644 --- a/plugins/woocommerce/includes/wc-core-functions.php +++ b/plugins/woocommerce/includes/wc-core-functions.php @@ -801,7 +801,7 @@ function get_woocommerce_currency_symbols() { 'SSP' => '£', 'STN' => 'Db', 'SYP' => 'ل.س', - 'SZL' => 'L', + 'SZL' => 'E', 'THB' => '฿', 'TJS' => 'ЅМ', 'TMT' => 'm', From d3421126e754b8060ee5cd4377fffe8789e892ee Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 14 Oct 2021 10:37:29 +0100 Subject: [PATCH 02/53] Add 'woocommerce_show_product_variant_metadata_line' hook This can be used to allow extensions to override whether the metadata line is displayed in the order meta box or not. --- .../woocommerce/includes/class-wc-order-item.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-order-item.php b/plugins/woocommerce/includes/class-wc-order-item.php index a65b1baf0cf..2445328a253 100644 --- a/plugins/woocommerce/includes/class-wc-order-item.php +++ b/plugins/woocommerce/includes/class-wc-order-item.php @@ -279,8 +279,19 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { } } + $show_metadata_line = ! $include_all && + $product && $product->is_type( 'variation' ) && + wc_is_attribute_in_product_name( $display_value, $order_item_name ); + $show_metadata_line = apply_filters( + 'woocommerce_show_product_variant_metadata_line', + $attribute_key, + $display_value, + $product, + $show_metadata_line + ); + // Skip items with values already in the product details area of the product name. - if ( ! $include_all && $product && $product->is_type( 'variation' ) && wc_is_attribute_in_product_name( $display_value, $order_item_name ) ) { + if ( ! $show_metadata_line ) { continue; } From bdf673c86d45b393e8fd1cf6bfd959c5e0d3e49f Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 14 Oct 2021 17:47:23 +0100 Subject: [PATCH 03/53] Add woocommerce_order_item_meta_include_all_meta_lines filter This will be used to determine if all meta lines should be shown in the order-item-meta template. --- .../admin/meta-boxes/views/html-order-item-meta.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index 9056a957668..63ad417e6a4 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -21,7 +21,12 @@ $hidden_order_itemmeta = apply_filters( ) ); ?>
- get_formatted_meta_data( '' ) ) : ?> + get_formatted_meta_data( '', $include_all ); + ?> + $meta ) : @@ -40,7 +45,7 @@ $hidden_order_itemmeta = apply_filters(
- get_formatted_meta_data( '' ) ) : ?> + $meta ) : if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) { From 09450393d0d29e0a0d413e2934598461d497c19f Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 14 Oct 2021 17:47:52 +0100 Subject: [PATCH 04/53] Update uses of get_formatted_metadata to pass through filter first --- .../class-wc-admin-list-table-orders.php | 5 ++++- .../woocommerce/includes/class-wc-order-item.php | 13 +------------ .../includes/legacy/api/v2/class-wc-api-orders.php | 10 ++++++++-- .../includes/legacy/api/v3/class-wc-api-orders.php | 10 ++++++++-- .../woocommerce/includes/wc-template-functions.php | 4 +++- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php index 6c604088976..81d7c1850c1 100644 --- a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php +++ b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php @@ -507,7 +507,10 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table { $html .= '
' . esc_html( $product_object->get_sku() ) . '
'; } - $meta_data = $item->get_formatted_meta_data( '' ); + + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + $meta_data = $item->get_formatted_meta_data( '', $include_all ); if ( $meta_data ) { $html .= '
'; diff --git a/plugins/woocommerce/includes/class-wc-order-item.php b/plugins/woocommerce/includes/class-wc-order-item.php index 2445328a253..a65b1baf0cf 100644 --- a/plugins/woocommerce/includes/class-wc-order-item.php +++ b/plugins/woocommerce/includes/class-wc-order-item.php @@ -279,19 +279,8 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { } } - $show_metadata_line = ! $include_all && - $product && $product->is_type( 'variation' ) && - wc_is_attribute_in_product_name( $display_value, $order_item_name ); - $show_metadata_line = apply_filters( - 'woocommerce_show_product_variant_metadata_line', - $attribute_key, - $display_value, - $product, - $show_metadata_line - ); - // Skip items with values already in the product details area of the product name. - if ( ! $show_metadata_line ) { + if ( ! $include_all && $product && $product->is_type( 'variation' ) && wc_is_attribute_in_product_name( $display_value, $order_item_name ) ) { continue; } diff --git a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php index cfc2d13c95b..1e8fbd5ff7c 100644 --- a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php @@ -213,7 +213,10 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1525,7 +1528,10 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php index 2fe2b6cdcf4..18ceabc529f 100644 --- a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php @@ -220,7 +220,10 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1570,7 +1573,10 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php index bbf1a556f42..436abcccfc5 100644 --- a/plugins/woocommerce/includes/wc-template-functions.php +++ b/plugins/woocommerce/includes/wc-template-functions.php @@ -3336,7 +3336,9 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { ) ); - foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { + $include_all = false; + $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); + foreach ( $item->get_formatted_meta_data( '_', $include_all ) as $meta_id => $meta ) { $value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) ); $strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value; } From 91f2295c41b6f5a91c006dc9213feca554656c18 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 14 Oct 2021 17:58:40 +0100 Subject: [PATCH 05/53] Remove accidentally added empty line --- .../admin/list-tables/class-wc-admin-list-table-orders.php | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php index 81d7c1850c1..f176c8031e9 100644 --- a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php +++ b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php @@ -507,7 +507,6 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table { $html .= '
' . esc_html( $product_object->get_sku() ) . '
'; } - $include_all = false; $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); $meta_data = $item->get_formatted_meta_data( '', $include_all ); From 2256b9b337bfa3f32526c3c7ded300a569ba509b Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Thu, 14 Oct 2021 17:59:11 +0100 Subject: [PATCH 06/53] Add file meta to html-order-item-meta.php --- .../admin/meta-boxes/views/html-order-item-meta.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index 63ad417e6a4..283deb50163 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -1,4 +1,12 @@ Date: Fri, 26 Nov 2021 15:37:13 +0000 Subject: [PATCH 07/53] Revert changes made in PR so far --- .../class-wc-admin-list-table-orders.php | 4 +--- .../meta-boxes/views/html-order-item-meta.php | 17 ++--------------- .../legacy/api/v2/class-wc-api-orders.php | 10 ++-------- .../legacy/api/v3/class-wc-api-orders.php | 10 ++-------- .../includes/wc-template-functions.php | 4 +--- 5 files changed, 8 insertions(+), 37 deletions(-) diff --git a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php index f176c8031e9..6c604088976 100644 --- a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php +++ b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php @@ -507,9 +507,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table { $html .= '
' . esc_html( $product_object->get_sku() ) . '
'; } - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - $meta_data = $item->get_formatted_meta_data( '', $include_all ); + $meta_data = $item->get_formatted_meta_data( '' ); if ( $meta_data ) { $html .= '
'; diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index 283deb50163..9056a957668 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -1,12 +1,4 @@
- get_formatted_meta_data( '', $include_all ); - ?> - + get_formatted_meta_data( '' ) ) : ?>
$meta ) : @@ -53,7 +40,7 @@ $hidden_order_itemmeta = apply_filters(
- + get_formatted_meta_data( '' ) ) : ?> $meta ) : if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) { diff --git a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php index 1e8fbd5ff7c..cfc2d13c95b 100644 --- a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php @@ -213,10 +213,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); + $item_meta = $item->get_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1528,10 +1525,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); + $item_meta = $item->get_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php index 18ceabc529f..2fe2b6cdcf4 100644 --- a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php @@ -220,10 +220,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); + $item_meta = $item->get_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1573,10 +1570,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - $item_meta = $item->get_formatted_meta_data( $hideprefix, $include_all ); + $item_meta = $item->get_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php index 436abcccfc5..bbf1a556f42 100644 --- a/plugins/woocommerce/includes/wc-template-functions.php +++ b/plugins/woocommerce/includes/wc-template-functions.php @@ -3336,9 +3336,7 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { ) ); - $include_all = false; - $include_all = apply_filters( 'woocommerce_get_formatted_meta_data_include_all_meta_lines', $include_all, $item ); - foreach ( $item->get_formatted_meta_data( '_', $include_all ) as $meta_id => $meta ) { + foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { $value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) ); $strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value; } From d0a5c6b99898bfefbd32d8cfd74194af84181d3e Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 26 Nov 2021 15:39:43 +0000 Subject: [PATCH 08/53] Add docblock to html-order-item-meta --- .../admin/meta-boxes/views/html-order-item-meta.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index 9056a957668..3f766d3b703 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -1,4 +1,11 @@ Date: Fri, 26 Nov 2021 15:40:52 +0000 Subject: [PATCH 09/53] Fix problem with assignment in conditional --- .../admin/meta-boxes/views/html-order-item-meta.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index 3f766d3b703..d849402211d 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -28,7 +28,10 @@ $hidden_order_itemmeta = apply_filters( ) ); ?>
- get_formatted_meta_data( '' ) ) : ?> + get_formatted_meta_data( '' ); + if ( $meta_data ) : + ?>
$meta ) : @@ -47,7 +50,7 @@ $hidden_order_itemmeta = apply_filters(
- get_formatted_meta_data( '' ) ) : ?> + $meta ) : if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) { From 95a43ea56a23d4fe150ef475bc812672938685e0 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 26 Nov 2021 15:48:06 +0000 Subject: [PATCH 10/53] Add get_all_formatted_meta_data wrapper This sets include_all to true --- plugins/woocommerce/includes/class-wc-order-item.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plugins/woocommerce/includes/class-wc-order-item.php b/plugins/woocommerce/includes/class-wc-order-item.php index a65b1baf0cf..6900685e19e 100644 --- a/plugins/woocommerce/includes/class-wc-order-item.php +++ b/plugins/woocommerce/includes/class-wc-order-item.php @@ -247,6 +247,17 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { |-------------------------------------------------------------------------- */ + /** + * Wrapper for get_formatted_meta_data that includes all metadata by default. See https://github.com/woocommerce/woocommerce/pull/30948 + * + * @param string $hideprefix Meta data prefix, (default: _). + * @param bool $include_all Include all meta data, this stop skip items with values already in the product name. + * @return array + */ + public function get_all_formatted_meta_data( $hideprefix = '_', $include_all = true ) { + return $this->get_formatted_meta_data( $hideprefix, $include_all ); + } + /** * Expands things like term slugs before return. * From eb31bd5275c7d8d15a9bec4392a670dbb6a2b352 Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 26 Nov 2021 16:16:48 +0000 Subject: [PATCH 11/53] Update uses of get_formatted_data to new wrapper --- .../admin/list-tables/class-wc-admin-list-table-orders.php | 2 +- .../includes/admin/meta-boxes/views/html-order-item-meta.php | 2 +- .../includes/legacy/api/v2/class-wc-api-orders.php | 4 ++-- .../includes/legacy/api/v3/class-wc-api-orders.php | 4 ++-- .../Version1/class-wc-rest-order-refunds-v1-controller.php | 2 +- .../Version1/class-wc-rest-orders-v1-controller.php | 2 +- .../Version2/class-wc-rest-orders-v2-controller.php | 4 ++-- plugins/woocommerce/includes/wc-template-functions.php | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php index 6c604088976..4f7a95f5ed0 100644 --- a/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php +++ b/plugins/woocommerce/includes/admin/list-tables/class-wc-admin-list-table-orders.php @@ -507,7 +507,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table { $html .= '
' . esc_html( $product_object->get_sku() ) . '
'; } - $meta_data = $item->get_formatted_meta_data( '' ); + $meta_data = $item->get_all_formatted_meta_data( '' ); if ( $meta_data ) { $html .= '
'; diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php index d849402211d..a1842993293 100644 --- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php +++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php @@ -29,7 +29,7 @@ $hidden_order_itemmeta = apply_filters( ); ?>
get_formatted_meta_data( '' ); + $meta_data = $item->get_all_formatted_meta_data( '' ); if ( $meta_data ) : ?>
diff --git a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php index cfc2d13c95b..937de6e4d35 100644 --- a/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v2/class-wc-api-orders.php @@ -213,7 +213,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + $item_meta = $item->get_all_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1525,7 +1525,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + $item_meta = $item->get_all_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php index 2fe2b6cdcf4..4d602a94edb 100644 --- a/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php +++ b/plugins/woocommerce/includes/legacy/api/v3/class-wc-api-orders.php @@ -220,7 +220,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + $item_meta = $item->get_all_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; @@ -1570,7 +1570,7 @@ class WC_API_Orders extends WC_API_Resource { foreach ( $refund->get_items( 'line_item' ) as $item_id => $item ) { $product = $item->get_product(); $hideprefix = ( isset( $filter['all_item_meta'] ) && 'true' === $filter['all_item_meta'] ) ? null : '_'; - $item_meta = $item->get_formatted_meta_data( $hideprefix ); + $item_meta = $item->get_all_formatted_meta_data( $hideprefix ); foreach ( $item_meta as $key => $values ) { $item_meta[ $key ]->label = $values->display_key; diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php index 550aef9107f..345935333d2 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-refunds-v1-controller.php @@ -161,7 +161,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller { $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + foreach ( $item->get_all_formatted_meta_data( $hideprefix ) as $meta_key => $formatted_meta ) { $item_meta[] = array( 'key' => $formatted_meta->key, 'label' => $formatted_meta->display_key, diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php index 51fffe19e4a..bf2ecaa2652 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-orders-v1-controller.php @@ -189,7 +189,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller { $hideprefix = 'true' === $request['all_item_meta'] ? null : '_'; - foreach ( $item->get_formatted_meta_data( $hideprefix, true ) as $meta_key => $formatted_meta ) { + foreach ( $item->get_all_formatted_meta_data( $hideprefix ) as $meta_key => $formatted_meta ) { $item_meta[] = array( 'key' => $formatted_meta->key, 'label' => $formatted_meta->display_key, diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php index 0d963e0be93..dcda34cf357 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-orders-v2-controller.php @@ -209,7 +209,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { unset( $data['type'] ); // Expand meta_data to include user-friendly values. - $formatted_meta_data = $item->get_formatted_meta_data( null, true ); + $formatted_meta_data = $item->get_all_formatted_meta_data( null ); $data['meta_data'] = array_map( array( $this, 'merge_meta_item_with_formatted_meta_display_attributes' ), $data['meta_data'], @@ -224,7 +224,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller { * {@link WC_Meta_Data}. Returns the merged array. * * @param WC_Meta_Data $meta_item An object from {@link WC_Order_Item::get_meta_data()}. - * @param array $formatted_meta_data An object result from {@link WC_Order_Item::get_formatted_meta_data}. + * @param array $formatted_meta_data An object result from {@link WC_Order_Item::get_all_formatted_meta_data}. * The keys are the IDs of {@link WC_Meta_Data}. * * @return array diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php index bbf1a556f42..87497229236 100644 --- a/plugins/woocommerce/includes/wc-template-functions.php +++ b/plugins/woocommerce/includes/wc-template-functions.php @@ -3336,7 +3336,7 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { ) ); - foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { + foreach ( $item->get_all_formatted_meta_data() as $meta_id => $meta ) { $value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) ); $strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value; } From b87c52f0680c4ed05b6edcbea8ed80f82cd83e7e Mon Sep 17 00:00:00 2001 From: Thomas Roberts Date: Fri, 26 Nov 2021 16:17:44 +0000 Subject: [PATCH 12/53] Add tests for new get_all_formatted_metadata method --- .../class-wc-tests-order-item-product.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/plugins/woocommerce/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php b/plugins/woocommerce/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php index d253bf59332..669231741c0 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/order-items/class-wc-tests-order-item-product.php @@ -212,6 +212,85 @@ class WC_Tests_Order_Item_Product extends WC_Unit_Test_Case { $this->assertEmpty( $formatted ); } + /** + * Test the get_formatted_meta_data method. + * + * @since x.x.x + */ + public function test_get_all_formatted_meta_data() { + $parent_product = new WC_Product_Variable(); + $parent_product->set_name( 'Test Parent' ); + $parent_product->save(); + + $variation_product = new WC_Product_Variation(); + $variation_product->set_name( 'Test Variation' ); + $variation_product->set_parent_id( $parent_product->get_id() ); + $variation_product->set_attributes( + array( + 'color' => 'Green', + 'size' => 'Large', + ) + ); + $variation_product->save(); + + $product_item = new WC_Order_Item_Product(); + $product_item->set_product( $variation_product ); + $product_item->add_meta_data( 'testkey', 'testval', true ); + $product_item->save(); + + // Test with show_all set to default. + $formatted = $product_item->get_all_formatted_meta_data( '_' ); + $formatted_as_array = array(); + foreach ( $formatted as $f ) { + $formatted_as_array[] = (array) $f; + } + $this->assertEquals( + array( + array( + 'key' => 'color', + 'value' => 'Green', + 'display_key' => 'color', + 'display_value' => "

Green

\n", + ), + array( + 'key' => 'size', + 'value' => 'Large', + 'display_key' => 'size', + 'display_value' => "

Large

\n", + ), + array( + 'key' => 'testkey', + 'value' => 'testval', + 'display_key' => 'testkey', + 'display_value' => "

testval

\n", + ), + ), + $formatted_as_array + ); + + // Test with show_all off. + $formatted = $product_item->get_all_formatted_meta_data( '_', false ); + $formatted_as_array = array(); + foreach ( $formatted as $f ) { + $formatted_as_array[] = (array) $f; + } + $this->assertEquals( + array( + array( + 'key' => 'testkey', + 'value' => 'testval', + 'display_key' => 'testkey', + 'display_value' => "

testval

\n", + ), + ), + $formatted_as_array + ); + + // Test with an exclude prefix. Should exclude everything since they're either in the title or in the exclude prefix. + $formatted = $product_item->get_all_formatted_meta_data( 'test', false ); + $this->assertEmpty( $formatted ); + } + /** * Test the Array Access methods. * From 0d207cee4c7b8eaa4d9f0c6b1ee068432d0a15fe Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Mon, 3 Jan 2022 12:53:25 -0800 Subject: [PATCH 13/53] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4ff98b84e02..b65934c26c6 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ If you are not a developer, please use the [WooCommerce plugin page](https://wor * [WooCommerce Developer Documentation](https://github.com/woocommerce/woocommerce/wiki) * [WooCommerce Code Reference](https://docs.woocommerce.com/wc-apidocs/) * [WooCommerce REST API Docs](https://woocommerce.github.io/woocommerce-rest-api-docs/) +* [Setting up a development environment](https://github.com/woocommerce/woocommerce/wiki/How-to-set-up-WooCommerce-development-environment) ## Reporting Security Issues To disclose a security issue to our team, [please submit a report via HackerOne here](https://hackerone.com/automattic/). From 1be5e81860df97ea0d2efb9aed919480de7ac288 Mon Sep 17 00:00:00 2001 From: Dharmesh Patel Date: Thu, 10 Feb 2022 10:14:01 +0530 Subject: [PATCH 14/53] Fixed clear cart after payment for block-based themes(Twenty Twenty-Two). --- plugins/woocommerce/includes/wc-cart-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/wc-cart-functions.php b/plugins/woocommerce/includes/wc-cart-functions.php index 1d159c7d55a..a001455d01e 100644 --- a/plugins/woocommerce/includes/wc-cart-functions.php +++ b/plugins/woocommerce/includes/wc-cart-functions.php @@ -192,7 +192,7 @@ function wc_clear_cart_after_payment() { } } } -add_action( 'get_header', 'wc_clear_cart_after_payment' ); +add_action( 'template_redirect', 'wc_clear_cart_after_payment', 20 ); /** * Get the subtotal. From b072cc1f9eafd8759eb4da7c641481cf2c2d8766 Mon Sep 17 00:00:00 2001 From: Pierre Carrier Date: Sun, 20 Feb 2022 12:42:43 -0500 Subject: [PATCH 15/53] includes/class-wc-geolocation.php: bot.whatismyipaddress.com gone, tnedi.me new --- plugins/woocommerce/includes/class-wc-geolocation.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-geolocation.php b/plugins/woocommerce/includes/class-wc-geolocation.php index d47ac659386..2e02d855890 100644 --- a/plugins/woocommerce/includes/class-wc-geolocation.php +++ b/plugins/woocommerce/includes/class-wc-geolocation.php @@ -45,10 +45,10 @@ class WC_Geolocation { * @var array */ private static $ip_lookup_apis = array( - 'ipify' => 'http://api.ipify.org/', - 'ipecho' => 'http://ipecho.net/plain', - 'ident' => 'http://ident.me', - 'whatismyipaddress' => 'http://bot.whatismyipaddress.com', + 'ipify' => 'http://api.ipify.org/', + 'ipecho' => 'http://ipecho.net/plain', + 'ident' => 'http://ident.me', + 'tnedi' => 'http://tnedi.me', ); /** From 0f5a395cb97db6ad48428fbe098f20ea03ea4200 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 24 Feb 2022 15:26:34 +0100 Subject: [PATCH 16/53] Add code comments about db updates on new WooCommerce installs. The update functions in wc-update-functions.php run when WooCommerce is updated from a previous version, but not when it's newly installed. This commit adds a couple of comments explaining that. --- plugins/woocommerce/includes/class-wc-install.php | 7 +++++++ plugins/woocommerce/includes/wc-update-functions.php | 10 +++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php index 9186ac8d8d1..b95cd9ca3b1 100644 --- a/plugins/woocommerce/includes/class-wc-install.php +++ b/plugins/woocommerce/includes/class-wc-install.php @@ -21,6 +21,13 @@ class WC_Install { /** * DB updates and callbacks that need to be run per version. * + * Please note that these functions are invoked when WooCommerce is updated from a previous version, + * but NOT when WooCommerce is newly installed. + * + * Database schema changes must be incorporated to the SQL returned by get_schema, which is applied + * via dbDelta at both install and update time. If any other kind of database change is required + * at install time (e.g. populating tables), use the 'woocommerce_installed' hook. + * * @var array */ private static $db_updates = array( diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php index 6f19adb89e1..cda7ef3e929 100644 --- a/plugins/woocommerce/includes/wc-update-functions.php +++ b/plugins/woocommerce/includes/wc-update-functions.php @@ -2,7 +2,15 @@ /** * WooCommerce Updates * - * Functions for updating data, used by the background updater. + * Functions for updating data, used by the background updater. These functions must be included + * in the list returned by WC_Install::get_db_update_callbacks. + * + * Please note that these functions are invoked when WooCommerce is updated from a previous version, + * but NOT when WooCommerce is newly installed. + * + * Database schema changes must be incorporated to the SQL returned by WC_Install::get_schema, which is applied + * via dbDelta at both install and update time. If any other kind of database change is required + * at install time (e.g. populating tables), use the 'woocommerce_installed' hook. * * @package WooCommerce\Functions * @version 3.3.0 From 32e01a21f2b7c5a0b9cfa87b9d75488594dd8b91 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Fri, 25 Feb 2022 11:27:58 +0100 Subject: [PATCH 17/53] Fix internal links in README files After the WooCommerce code was moved to 'plugins/woocommerce' many of the internal links in the README files (links to other README files or to code files) were broken. This commit fixes that. --- .github/CONTRIBUTING.md | 2 +- plugins/woocommerce/includes/README.md | 12 ++++++------ plugins/woocommerce/src/Internal/README.md | 2 +- plugins/woocommerce/src/README.md | 8 ++++---- plugins/woocommerce/tests/README.md | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 884d1852ddb..bf0a99c028d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -26,7 +26,7 @@ If you have questions about the process to contribute code or want to discuss de - [Minification of SCSS and JS](https://github.com/woocommerce/woocommerce/wiki/Minification-of-SCSS-and-JS) - [Naming conventions](https://github.com/woocommerce/woocommerce/wiki/Naming-conventions) - [String localisation guidelines](https://github.com/woocommerce/woocommerce/wiki/String-localisation-guidelines) -- [Running unit tests](https://github.com/woocommerce/woocommerce/blob/trunk/tests/README.md) +- [Running unit tests](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/README.md) - [Running e2e tests](https://github.com/woocommerce/woocommerce/wiki/End-to-end-Testing) ## Coding Guidelines and Development 🛠 diff --git a/plugins/woocommerce/includes/README.md b/plugins/woocommerce/includes/README.md index d7c1b794437..923d9b0b41a 100644 --- a/plugins/woocommerce/includes/README.md +++ b/plugins/woocommerce/includes/README.md @@ -1,11 +1,11 @@ # WooCommerce `includes` files -This directory contains WooCommerce legacy code. Ideally, the code in this folder should only get the minimum required changes for bug fixing, and any new code should go in [the `src` directory](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md) instead. +This directory contains WooCommerce legacy code. Ideally, the code in this folder should only get the minimum required changes for bug fixing, and any new code should go in [the `src` directory](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md) instead. ## Interacting with the `src` folder -Whenever you need to get an instance of a class from the `src` directory, please don't instantiate it directly, but instead use [the container](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md#the-container). To get an instance of the container itself you can use the `wc_get_container` function, for example: +Whenever you need to get an instance of a class from the `src` directory, please don't instantiate it directly, but instead use [the container](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md#the-container). To get an instance of the container itself you can use the `wc_get_container` function, for example: ```php $container = wc_get_container(); @@ -17,18 +17,18 @@ The exception to this rule might be data-only classes that could be created the ## Adding new actions and filters -Please take a look at [the considerations for creation new hooks in `src` code](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md#defining-new-actions-and-filters), as they apply for `includes` code as well. The short version is that **new hooks should be introduced only if they provide a valuable extension point for plugins**, and not with the purpose of driving WooCommerce's internal logic. +Please take a look at [the considerations for creation new hooks in `src` code](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md#defining-new-actions-and-filters), as they apply for `includes` code as well. The short version is that **new hooks should be introduced only if they provide a valuable extension point for plugins**, and not with the purpose of driving WooCommerce's internal logic. ## Writing unit tests -[As it's the case for the `src` folder](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md#writing-unit-tests), writing unit tests is generally mandatory if you are a WooCommerce team member or a contributor from another Automattic team, and encouraged if you are an external contributor. Tests should cover any new code (although as mentioned, adding new code in `includes` should be rare) and any modifications to existing code. +[As it's the case for the `src` folder](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md#writing-unit-tests), writing unit tests is generally mandatory if you are a WooCommerce team member or a contributor from another Automattic team, and encouraged if you are an external contributor. Tests should cover any new code (although as mentioned, adding new code in `includes` should be rare) and any modifications to existing code. In order to make it easier to write unit tests, there are a couple of mechanisms in place that you can use: -* [The code hacker](https://github.com/woocommerce/woocommerce/blob/trunk/tests/Tools/CodeHacking/README.md). Pros: you don't need to do any special changes to your code to make it testable. Cons: it's a hack, the tested code is being actually modified while being loaded by the PHP engine, so not an ideal solution. +* [The code hacker](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/Tools/CodeHacking/README.md). Pros: you don't need to do any special changes to your code to make it testable. Cons: it's a hack, the tested code is being actually modified while being loaded by the PHP engine, so not an ideal solution. -* [The legacy proxy and the related helper methods in WC_Unit_Test_case](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md#interacting-with-legacy-code): although these are intended in principle for writing tests for code in the `src` directory, they can be used for `includes` code as well. Pros: a clean approach, no hacks involved. Cons: you need to modify your code to use the proxy whenever you need to call a function or static method that makes the code difficult to test. +* [The legacy proxy and the related helper methods in WC_Unit_Test_case](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md#interacting-with-legacy-code): although these are intended in principle for writing tests for code in the `src` directory, they can be used for `includes` code as well. Pros: a clean approach, no hacks involved. Cons: you need to modify your code to use the proxy whenever you need to call a function or static method that makes the code difficult to test. It's up to you as a contributor to decide which mechanism to use in each case. Choose wisely. diff --git a/plugins/woocommerce/src/Internal/README.md b/plugins/woocommerce/src/Internal/README.md index bbd4bd6855d..f77ec3ff204 100644 --- a/plugins/woocommerce/src/Internal/README.md +++ b/plugins/woocommerce/src/Internal/README.md @@ -2,4 +2,4 @@ All the code in this directory (and hence in the `Automattic\WooCommerce\Internal` namespace) is internal WooCommerce infrastructure code and not intended to be used by plugins. The important thing that this implies is that **backwards compatibility of the public surface for classes in this namespace is not guaranteed in future releases of WooCommerce**. -Therefore **plugin developers should never use classes in this namespace directly in their code**. See [the README file for the src folder](https://github.com/woocommerce/woocommerce/blob/trunk/src/README.md#the-internal-namespace) for more detailed guidance. +Therefore **plugin developers should never use classes in this namespace directly in their code**. See [the README file for the src folder](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/src/README.md#the-internal-namespace) for more detailed guidance. diff --git a/plugins/woocommerce/src/README.md b/plugins/woocommerce/src/README.md index b914586e578..3e0df5c1657 100644 --- a/plugins/woocommerce/src/README.md +++ b/plugins/woocommerce/src/README.md @@ -26,7 +26,7 @@ This directory is home to new WooCommerce class files under the `Automattic\WooCommerce` namespace using [PSR-4](https://www.php-fig.org/psr/psr-4/) file naming. This is to take full advantage of autoloading. -Ideally, all the new code for WooCommerce should consist of classes following the PSR-4 naming and living in this directory, and the code in [the `includes` directory](https://github.com/woocommerce/woocommerce/tree/trunk/includes/README.md) should receive the minimum amount of changes required for bug fixing. This will not always be possible but that should be the rule of thumb. +Ideally, all the new code for WooCommerce should consist of classes following the PSR-4 naming and living in this directory, and the code in [the `includes` directory](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/includes/README.md) should receive the minimum amount of changes required for bug fixing. This will not always be possible but that should be the rule of thumb. A [PSR-11](https://www.php-fig.org/psr/psr-11/) container is in place for registering and resolving the classes in this directory by using the [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) pattern. There are tools in place to interact with legacy code (and code outside the `src` directory in general) in a way that makes it easy to write unit tests. @@ -281,7 +281,7 @@ What this implies for you as developer depends on what type of contribution are Here by "legacy code" we refer mainly to the old WooCommerce code in the `includes` directory, but the mechanisms described in this section are useful for dealing with any code outside the `src` directory. -The code in the `src` directory can for sure interact directly with legacy code. A function needs to be called? Call it. You need an instance of an object? Instantiate it. The problem is that this makes the code difficult to test: it's not easy to mock functions (unless you use [hacks](https://github.com/woocommerce/woocommerce/blob/trunk/tests/Tools/CodeHacking/README.md), or objects that are instantiated directly with `new` or whose instance is retrieved via a `TheClass::instance()` method). +The code in the `src` directory can for sure interact directly with legacy code. A function needs to be called? Call it. You need an instance of an object? Instantiate it. The problem is that this makes the code difficult to test: it's not easy to mock functions (unless you use [hacks](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/Tools/CodeHacking/README.md), or objects that are instantiated directly with `new` or whose instance is retrieved via a `TheClass::instance()` method). But we want the WooCommerce code base (and especially the code in `src`) to be well covered by unit tests, and so there are mechanisms in place to interact with legacy code while keeping the code testable. @@ -355,7 +355,7 @@ $this->register_legacy_proxy_function_mocks( Of course, for the cases where no mocks are defined `MockableLegacyProxy` works the same way as `LegacyProxy`. -Please see [the code of the MockableLegacyProxy class](https://github.com/woocommerce/woocommerce/blob/trunk/tests/Tools/DependencyManagement/MockableLegacyProxy.php) and [its unit tests](https://github.com/woocommerce/woocommerce/blob/trunk/tests/php/src/Proxies/MockableLegacyProxyTest.php) for more detailed usage instructions and examples. +Please see [the code of the MockableLegacyProxy class](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/Tools/DependencyManagement/MockableLegacyProxy.php) and [its unit tests](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/php/src/Proxies/MockableLegacyProxyTest.php) for more detailed usage instructions and examples. ### But how does `get_instance_of` work? @@ -363,7 +363,7 @@ We use a container to resolve instances of classes in the `src` directory, but h This is a mostly ad-hoc process. When a class has a special way to be instantiated or retrieved (e.g. a static `instance` method), then that is used; otherwise the method fallbacks to simply creating a new instance of the class using `new`. -This means that the `get_instance_of` method will most likely need to evolve over time to cover additional special cases. Take a look at the method code in [LegacyProxy](https://github.com/woocommerce/woocommerce/blob/trunk/src/Proxies/LegacyProxy.php) for details on how to properly make changes to the method. +This means that the `get_instance_of` method will most likely need to evolve over time to cover additional special cases. Take a look at the method code in [LegacyProxy](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/src/Proxies/LegacyProxy.php) for details on how to properly make changes to the method. ### Creating specialized proxies diff --git a/plugins/woocommerce/tests/README.md b/plugins/woocommerce/tests/README.md index bcd6e5088c5..d804cc8c739 100644 --- a/plugins/woocommerce/tests/README.md +++ b/plugins/woocommerce/tests/README.md @@ -125,7 +125,7 @@ Each test file should correspond to an associated source file and be named accor * When testing functions: use one test file per functions group file, for example `wc-formatting-functions-test.php` for code in the `wc-formatting-functions.php` file. -See also [the guidelines for writing unit tests for `src` code](https://github.com/woocommerce/woocommerce/tree/trunk/src/README.md#writing-unit-tests) and [the guidelines for `includes` code](https://github.com/woocommerce/woocommerce/tree/trunk/includes/README.md#writing-unit-tests). +See also [the guidelines for writing unit tests for `src` code](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/src/README.md#writing-unit-tests) and [the guidelines for `includes` code](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/includes/README.md#writing-unit-tests). General guidelines for all the unit tests: From d76dac08e6399a34f2a454f21c8cbf950e903a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9stor=20Soriano?= Date: Fri, 25 Feb 2022 11:38:27 +0100 Subject: [PATCH 18/53] Add syntax highlight to README for the code hacker --- plugins/woocommerce/tests/Tools/CodeHacking/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce/tests/Tools/CodeHacking/README.md b/plugins/woocommerce/tests/Tools/CodeHacking/README.md index 5bd143e14dd..f4beef28b68 100644 --- a/plugins/woocommerce/tests/Tools/CodeHacking/README.md +++ b/plugins/woocommerce/tests/Tools/CodeHacking/README.md @@ -14,7 +14,7 @@ Let's go through an example. First, create a file named `class-wc-admin-foobar.php` in `includes/admin` with the following code: -``` +```php function($name, $default = false) { @@ -110,7 +110,7 @@ If you ever need to remove the configured static method mocks from inside a test Note that the code hacker is configured so that only the production code files are modified, the tests code itself is **not** modified. This means that you can use the original static methods within your tests even if you have mocked them, for example the following would work: -``` +```php StaticMockerHack::add_method_mocks([ 'WC_Some_Legacy_Service' => [ //Mock WC_Some_Legacy_Service::do_something but only if the supplied parameter is 'foo' From c90e11ea3dbe52c5586de78c90b8cc91cf0341a7 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Mon, 28 Feb 2022 17:09:19 -0300 Subject: [PATCH 19/53] Refactor merchant logout --- packages/js/e2e-utils/src/flows/merchant.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/js/e2e-utils/src/flows/merchant.js b/packages/js/e2e-utils/src/flows/merchant.js index 858b43edac6..f8da8c396bf 100644 --- a/packages/js/e2e-utils/src/flows/merchant.js +++ b/packages/js/e2e-utils/src/flows/merchant.js @@ -72,17 +72,14 @@ const merchant = { }, logout: async () => { - // Log out link in admin bar is not visible so can't be clicked directly. - const logoutLinks = await page.$$eval( - '#wp-admin-bar-logout a', - ( am ) => am.filter( ( e ) => e.href ).map( ( e ) => e.href ) - ); + await page.goto( WP_ADMIN_LOGIN + '?action=logout', { + waitUntil: 'networkidle0', + } ); - if ( logoutLinks && logoutLinks[0] ) { - await page.goto(logoutLinks[0], { - waitUntil: 'networkidle0', - }); - } + // Confirm logout using XPath, which works on all languages. + await expect( page ).toClick( '//a[contains(@href,\'action=logout\')]' ); + + await page.waitForNavigation( { waitUntil: 'networkidle0' } ); }, openAllOrdersView: async () => { From 31fae36caafd8177820eab3878fd4b93203bcd16 Mon Sep 17 00:00:00 2001 From: Lucas Bustamante Date: Mon, 28 Feb 2022 17:41:00 -0300 Subject: [PATCH 20/53] Update XPath syntax --- packages/js/e2e-utils/src/flows/merchant.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/js/e2e-utils/src/flows/merchant.js b/packages/js/e2e-utils/src/flows/merchant.js index f8da8c396bf..e8a0b60af4b 100644 --- a/packages/js/e2e-utils/src/flows/merchant.js +++ b/packages/js/e2e-utils/src/flows/merchant.js @@ -77,7 +77,8 @@ const merchant = { } ); // Confirm logout using XPath, which works on all languages. - await expect( page ).toClick( '//a[contains(@href,\'action=logout\')]' ); + const elements = await page.$x('//a[contains(@href,\'action=logout\')]') + await elements[0].click() await page.waitForNavigation( { waitUntil: 'networkidle0' } ); }, From 2874a22fe22645695931d781f41a8ba0c20c7ae4 Mon Sep 17 00:00:00 2001 From: barryhughes <3594411+barryhughes@users.noreply.github.com> Date: Mon, 28 Feb 2022 19:34:19 -0800 Subject: [PATCH 21/53] Allow limited HTML when rendering failure messages (CSV import). --- .../includes/admin/importers/views/html-csv-import-done.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php b/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php index 1774001d014..3abb51c3a76 100644 --- a/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php +++ b/plugins/woocommerce/includes/admin/importers/views/html-csv-import-done.php @@ -81,7 +81,7 @@ if ( ! defined( 'ABSPATH' ) ) { ?>
- + Date: Tue, 1 Mar 2022 16:35:15 -0800 Subject: [PATCH 22/53] Correct type in @return tag (to string). --- plugins/woocommerce/includes/class-wc-install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php index 9186ac8d8d1..e83fa30cda9 100644 --- a/plugins/woocommerce/includes/class-wc-install.php +++ b/plugins/woocommerce/includes/class-wc-install.php @@ -1706,7 +1706,7 @@ $product_attributes_lookup_table_creation_sql * Gets the content of the sample refunds and return policy page. * * @since 5.6.0 - * @return HTML The content for the page + * @return string The content for the page */ private static function get_refunds_return_policy_page_content() { return << Date: Wed, 2 Mar 2022 23:45:42 +0000 Subject: [PATCH 23/53] Update the WP version compatibility --- plugins/woocommerce/readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/readme.txt b/plugins/woocommerce/readme.txt index f3361b1ef53..0cb734bd720 100644 --- a/plugins/woocommerce/readme.txt +++ b/plugins/woocommerce/readme.txt @@ -1,8 +1,8 @@ === WooCommerce === Contributors: automattic, mikejolley, jameskoster, claudiosanches, rodrigosprimo, peterfabian1000, vedjain, jamosova, obliviousharmony, konamiman, sadowski, wpmuguru, royho, barryhughes-1 Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, downloads, payments, paypal, storefront, stripe, woo commerce -Requires at least: 5.6 -Tested up to: 5.8 +Requires at least: 5.7 +Tested up to: 5.9 Requires PHP: 7.0 Stable tag: 6.2.0 License: GPLv3 From a8679b041ddf48dc79706923e8701b9eab3f7b69 Mon Sep 17 00:00:00 2001 From: Felipe Santos <40555737+felipelousantos@users.noreply.github.com> Date: Thu, 3 Mar 2022 11:38:27 +0000 Subject: [PATCH 24/53] Update the WP version for tests and WooCommerce --- .github/workflows/ci.yml | 4 ++-- .github/workflows/pr-unit-tests.yml | 4 ++-- plugins/woocommerce/woocommerce.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index df8ad097394..94098f80e9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: include: - wp: nightly php: '7.4' - - wp: '5.7' + - wp: '5.8' php: 7.2 - - wp: '5.6' + - wp: '5.7' php: 7.2 services: database: diff --git a/.github/workflows/pr-unit-tests.yml b/.github/workflows/pr-unit-tests.yml index fc1c4ce5d0c..1c470598e08 100644 --- a/.github/workflows/pr-unit-tests.yml +++ b/.github/workflows/pr-unit-tests.yml @@ -19,9 +19,9 @@ jobs: include: - wp: nightly php: '7.4' - - wp: '5.7' + - wp: '5.8' php: 7.2 - - wp: '5.6' + - wp: '5.7' php: 7.2 services: database: diff --git a/plugins/woocommerce/woocommerce.php b/plugins/woocommerce/woocommerce.php index 2e4331d0952..78cb6934cc8 100644 --- a/plugins/woocommerce/woocommerce.php +++ b/plugins/woocommerce/woocommerce.php @@ -8,7 +8,7 @@ * Author URI: https://woocommerce.com * Text Domain: woocommerce * Domain Path: /i18n/languages/ - * Requires at least: 5.6 + * Requires at least: 5.7 * Requires PHP: 7.0 * * @package WooCommerce From 7ac79aa6d74a19d0ad5ca16426ee09b018be8138 Mon Sep 17 00:00:00 2001 From: helgatheviking <507025+helgatheviking@users.noreply.github.com> Date: Sat, 5 Mar 2022 15:05:13 -0700 Subject: [PATCH 25/53] Add has_options to product REST API response. Closes #30187. --- .../Version3/class-wc-rest-products-controller.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php index 47bb55b7a9e..6a34df6f7fc 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php @@ -1220,6 +1220,12 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), ), + 'has_options' => array( + 'description' => __( 'Shows if the product needs confiruging before it can be bought.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), 'attributes' => array( 'description' => __( 'List of attributes.', 'woocommerce' ), 'type' => 'array', @@ -1381,6 +1387,9 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { if ( in_array( 'stock_status', $fields ) ) { $data['stock_status'] = $product->get_stock_status( $context ); } + if ( in_array( 'has_options', $fields ) ) { + $data['has_options'] = $product->has_options( $context ); + } } return $data; } From 3450112f39ca3dbfe8432a0c80e5df5a5ec87805 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 8 Mar 2022 12:25:54 +0000 Subject: [PATCH 26/53] Add rate_limit_remaining column to wc_rate_limits table --- plugins/woocommerce/includes/class-wc-install.php | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php index 9186ac8d8d1..6bf03fb7b88 100644 --- a/plugins/woocommerce/includes/class-wc-install.php +++ b/plugins/woocommerce/includes/class-wc-install.php @@ -1068,6 +1068,7 @@ CREATE TABLE {$wpdb->prefix}wc_rate_limits ( rate_limit_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, rate_limit_key varchar(200) NOT NULL, rate_limit_expiry BIGINT UNSIGNED NOT NULL, + rate_limit_remaining smallint(10) NOT NULL DEFAULT '0', PRIMARY KEY (rate_limit_id), UNIQUE KEY rate_limit_key (rate_limit_key($max_index_length)) ) $collate; From 52de5683addc2af029132428467ebba0e4b3db13 Mon Sep 17 00:00:00 2001 From: roykho Date: Tue, 8 Mar 2022 12:55:07 -0800 Subject: [PATCH 27/53] Update changelog --- changelog.txt | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/changelog.txt b/changelog.txt index d717b9c09f8..f338280bffe 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,121 @@ == Changelog == += 6.3.0 2022-03-08 = + +**WooCommerce** + +* Add - Add states for Germany. ([#31825](https://github.com/woocommerce/woocommerce/pull/31825)) +* Add - Track WcPay settings in WC Tracker. ([#31663](https://github.com/woocommerce/woocommerce/pull/31663)) +* Add - Add filter woocommerce_set_cookie_enabled to allow disabling specific cookies.([#31317](https://github.com/woocommerce/woocommerce/pull/31317)) +* Tweak - Enhancement - Add indices to the product attributes lookup table. ([#31819](https://github.com/woocommerce/woocommerce/pull/31819)) +* Tweak - Adjust input styles for the Twenty Twenty One theme. ([#31734](https://github.com/woocommerce/woocommerce/pull/31734)) +* Tweak - Adjust input styles for the Twenty Twenty theme. ([#31698](https://github.com/woocommerce/woocommerce/pull/31698)) +* Tweak - 2022 theme store notice styling. ([#31683](https://github.com/woocommerce/woocommerce/pull/31683)) +* Tweak - Guatemalan postcode field is now visible by default but remains unrequired. ([#31303](https://github.com/woocommerce/woocommerce/pull/31303)) +* Tweak - Ensure the WC_CSV_Batch_Exporter::get_percent_complete() method returns an int. ([#31138](https://github.com/woocommerce/woocommerce/pull/31138)) +* Fix - Support custom Product Taxonomies in block template loader. ([#31610](https://github.com/woocommerce/woocommerce/pull/31610)) +* Fix - Support special chars in email subjects using wp_specialchars_decode. ([#31589](https://github.com/woocommerce/woocommerce/pull/31589)) +* Fix - Ensure that WooCommerce panel within the Customizer is showing a back button. ([#31508](https://github.com/woocommerce/woocommerce/pull/31508)) +* Fix - Avoids incorrectly setting the search argument under some conditions, when the Customers endpoint of the REST API is used. ([#31295](https://github.com/woocommerce/woocommerce/pull/31295)) +* Fix - Reverted #31593 that caused the returned line item price to be a string instead of a float. ([#31935](https://github.com/woocommerce/woocommerce/pull/31935)) +* Dev - The cart session is now updated later on during the woocommerce_after_calculate_totals action (priority 1000, instead of priority 10 as previously). ([#31711](https://github.com/woocommerce/woocommerce/pull/31711)) +* Dev - Enable browser-suggested passwords on checkout signup. ([#31701](https://github.com/woocommerce/woocommerce/pull/31701)) +* Dev - Add method can_view_woocommerce_menu_item to check if the user can access the top-level WooCommerce menu item. ([#31689](https://github.com/woocommerce/woocommerce/pull/31689)) +* Dev - Wrap terms and conditions required asterisk symbol with tag. ([#31673](https://github.com/woocommerce/woocommerce/pull/31673)) +* Dev - Allow to use use all get_image function parameters by woocommerce_get_product_thumbnail to customize image. ([#31605](https://github.com/woocommerce/woocommerce/pull/31605)) +* Dev - Format price decimal places correctly in the order API. ([#31593](https://github.com/woocommerce/woocommerce/pull/31593)) +* Dev - Update text for generating an account in admin menu to be more clear. ([#31590](https://github.com/woocommerce/woocommerce/pull/31590)) +* Dev - Adds the option to filter coupons by status when calling the GET /coupons endpoint. ([#31577](https://github.com/woocommerce/woocommerce/pull/31577)) +* Dev - Made the $loop position counter available via the 'woocommerce_variation_header' hook. ([#31565](https://github.com/woocommerce/woocommerce/pull/31565)) +* Dev - Change '__return_true' to true in the apply_filters() call for the woocommerce_product_recount_terms filter. ([#31506](https://github.com/woocommerce/woocommerce/pull/31506)) +* Dev - Add $key field as well to woocommerce_checkout_required_field_notice filter. ([#31435](https://github.com/woocommerce/woocommerce/pull/31435)) +* Dev - Add product meta data to published product tracks. ([#31355](https://github.com/woocommerce/woocommerce/pull/31355)) +* Dev - Allow auto-draft in API orders. ([#31290](https://github.com/woocommerce/woocommerce/pull/31290)) +* Dev - A $file param is now available via the woocommerce_[product_]csv_importer_check_import_file_path filter hooks. ([#31266](https://github.com/woocommerce/woocommerce/pull/31266)) +* Dev - Data migration to create and activate the product attributes lookup table. ([#31256](https://github.com/woocommerce/woocommerce/pull/31256)) +* Dev - A new filter hook woocommerce_cart_item_removed_because_modified_message($message, $product) which allows to update the notice message if a product is modified and page is loaded while product is in cart. ([#31193](https://github.com/woocommerce/woocommerce/pull/31193)) +* Security - Add prefix to identify guest sessions. + +**WooCommerce Admin - 3.2.0 & 3.2.1** + +* Fix - Adjusted task list logic to fix conflict between current and experimental task list. ([#8321](https://github.com/woocommerce/woocommerce-admin/pull/8321)) +* Fix - changed email validation in Store Details onboarding task to more closely match PHP backend validation. ([#8197](https://github.com/woocommerce/woocommerce-admin/pull/8197)) +* Fix - Disallow whitespace as the platform name input. ([#8090](https://github.com/woocommerce/woocommerce-admin/pull/8090)) +* Fix - Ensure setup-wizard redirection on homescreen is stable. ([#8114](https://github.com/woocommerce/woocommerce-admin/pull/8114)) +* Fix - Fix category report query returns invalid net sales. ([#8153](https://github.com/woocommerce/woocommerce-admin/pull/8153)) +* Fix - Fix clicking the error message opens the dropdown. ([#8094](https://github.com/woocommerce/woocommerce-admin/pull/8094)) +* Fix - Fix country/region selection not preserved in store details task. ([#8228](https://github.com/woocommerce/woocommerce-admin/pull/8228)) +* Fix - Fixed email address not being optional in OBW ([#8263](https://github.com/woocommerce/woocommerce-admin/pull/8263)) +* Fix - Fix get_automated_tax_supported_countries doesn't include UK. ([#8180](https://github.com/woocommerce/woocommerce-admin/pull/8180)) +* Fix - Fix incorrect date options when the "Default Date Range" is set from Analytics settings. ([#8189](https://github.com/woocommerce/woocommerce-admin/pull/8189)) +* Fix - Fix incorrectly displayed note created date. ([#8179](https://github.com/woocommerce/woocommerce-admin/pull/8179)) +* Fix - Fix incorrect screen reader text generated for data points on charts table. ([#8181](https://github.com/woocommerce/woocommerce-admin/pull/8181)) +* Fix - Fix incorrect total count of downloads on the analytics download report. ([#8182](https://github.com/woocommerce/woocommerce-admin/pull/8182)) +* Fix - Fix misaligned status column on order report. ([#8121](https://github.com/woocommerce/woocommerce-admin/pull/8121)) +* Fix - Fix shipping rate error message overlaps with the 'Proceed' button. ([#8165](https://github.com/woocommerce/woocommerce-admin/pull/8165)) +* Fix - Fix Shipping task sometimes skipping the set shipping costs step. ([#8260](https://github.com/woocommerce/woocommerce-admin/pull/8260)) +* Fix - Fix Uncaught TypeError count(NULL) for php8+ in Marketing.php. ([#8213](https://github.com/woocommerce/woocommerce-admin/pull/8213)) +* Fix - Fix undefined derived_currency value for the track 'wcadmin_storeprofiler_store_details_continue'. ([#8193](https://github.com/woocommerce/woocommerce-admin/pull/8193)) +* Fix - Fix variations table product filter query. ([#8120](https://github.com/woocommerce/woocommerce-admin/pull/8120)) +* Fix - Make sure free subscriptions does not show when cbd industry is selected. ([#8323](https://github.com/woocommerce/woocommerce-admin/pull/8323)) +* Fix - Make sure WooCommerce Payments tasklist_payment_setup is triggered again. ([#8146](https://github.com/woocommerce/woocommerce-admin/pull/8146)) +* Fix - Preserve HTML markup in server-side error messages received from sample product import request. ([#8173](https://github.com/woocommerce/woocommerce-admin/pull/8173)) +* Fix - Remove border between email input and newsletter checkbox in OBW store details. ([#8148](https://github.com/woocommerce/woocommerce-admin/pull/8148)) +* Fix - Reset "install_timestamp" if it's not numeric to avoid TypeError. ([#8100](https://github.com/woocommerce/woocommerce-admin/pull/8100)) +* Fix - Truncate the long site title with an ellipses on the second line. ([#8112](https://github.com/woocommerce/woocommerce-admin/pull/8112)) +* Fix - Fix backwards compatibility with SkyVerge payment gateway.([#8371](https://github.com/woocommerce/woocommerce-admin/pull/8371)) +* Add - Add additional store profiler track for the business details tab. ([#8265](https://github.com/woocommerce/woocommerce-admin/pull/8265)) +* Add - Add countries data store ([#8119](https://github.com/woocommerce/woocommerce-admin/pull/8119)) +* Add - Add extra tracking for plugin installation performance during onboarding. ([#8042](https://github.com/woocommerce/woocommerce-admin/pull/8042)) +* Add - Adding tooltip to describe the lack of refund deductions from revenue summaries. ([#8187](https://github.com/woocommerce/woocommerce-admin/pull/8187)) +* Add - Add localized validation to store address ([#8123](https://github.com/woocommerce/woocommerce-admin/pull/8123)) +* Add - Add Magento migration note ([#8145](https://github.com/woocommerce/woocommerce-admin/pull/8145)) +* Add - Add REST endpoint to retrieve address locales ([#8116](https://github.com/woocommerce/woocommerce-admin/pull/8116)) +* Add - Add Spain to Square country suggestion list. ([#8210](https://github.com/woocommerce/woocommerce-admin/pull/8210)) +* Add - Add wc_version property to the store profile onboarding tracks for view and complete steps. ([#8290](https://github.com/woocommerce/woocommerce-admin/pull/8290)) +* Add - Change the reviews empty state panels logic ([#8147](https://github.com/woocommerce/woocommerce-admin/pull/8147)) +* Update - Add custom error for store details email and allow continue ([#8110](https://github.com/woocommerce/woocommerce-admin/pull/8110)) +* Update - Adding "allow-plugins" property for composer configuration. ([#8139](https://github.com/woocommerce/woocommerce-admin/pull/8139)) +* Dev - Remove wc-admin-settings package and rename getSetting to getAdminSetting. ([#8057](https://github.com/woocommerce/woocommerce-admin/pull/8057)) +* Tweak - Fix WCPay in core texts and promo slug ([#8296](https://github.com/woocommerce/woocommerce-admin/pull/8296)) +* Tweak - Grow and center buttons in all WooCommerce ellipsis menu popover containers. ([#8168](https://github.com/woocommerce/woocommerce-admin/pull/8168)) +* Tweak - Hide store address fields in regions that specify hidden ([#8172](https://github.com/woocommerce/woocommerce-admin/pull/8172)) +* Tweak - Make activity panel badges margin consistent. ([#8152](https://github.com/woocommerce/woocommerce-admin/pull/8152)) +* Tweak - Padding tweak for marketing tools plugin list headings. ([#8171](https://github.com/woocommerce/woocommerce-admin/pull/8171)) +* Performance - Speed up customer syncing action. ([#8021](https://github.com/woocommerce/woocommerce-admin/pull/8021)) +* Enhancement - Enhance report chart i18n support. ([#8129](https://github.com/woocommerce/woocommerce-admin/pull/8129)) +* Enhancement - Make ExPlat request URL args filterable. Added woocommerce_explat_request_args filter. ([#8231](https://github.com/woocommerce/woocommerce-admin/pull/8231)) +* Enhancement - Show MailPoet in Installed marketing extensions. ([#8091](https://github.com/woocommerce/woocommerce-admin/pull/8091)) +* Enhancement - Update headercard to use filter to add ExPlat parameter ([#8233](https://github.com/woocommerce/woocommerce-admin/pull/8233)) + +**WooCommerce Blocks - 6.8.0 & 6.9.0** + +* Add - Add support for the global style for the Price Filter block. ([#5559](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5559)) +* Add - Hold stock for 60mins if the order is pending payment. ([#5546](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5546)) +* Add - Allow users to reinsert the WooCommerce Legacy Template block in their block template if it is a WooCommerce block template. ([#5545](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5545)) +* Add - Add support for the global style for the Stock Indicator block. ([#5525](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5525)) +* Add - Add support for the global style for the Summary Product block. ([#5524](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5524)) +* Add - Add support for the global style for the Product Title block. ([#5515](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5515)) +* Add - Store API: Throw errors when attempting to pay with a non-available payment method. ([#5440](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5440)) +* Add - Add support for the wide and full alignment for the legacy template block. ([#5433](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5433)) +* Add - Store API and Cart block now support defining a quantity stepper and a minimum quantity. ([#5406](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5406)) +* Add - Added controls to product grid blocks for filtering by stock levels. ([#4943](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4943)) +* Add - Add support for the global style for the Featured Category block. ([#5542](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5542)) +* Fix duplicated checkout error notices. ([#5476](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5476)) +* Fix - Use consistent HTML code for all rating sections, so that screen readers pronounce the rating correctly. ([#5552](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5552)) +* Fix - All Products block displays thumbnails. ([#5551](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5551)) +* Fix - Fixed a styling issue in the Checkout block when an order has multiple shipping packages. ([#5529](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5529)) +* Fix - Fixed a visual bug (#5152) with the points and rewards plugin. ([#5430](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5430)) +* Fix - Filter Products By Price block: Don't allow to insert negative values on inputs. ([#5123](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5123)) +* Fix - Enable Mini Cart template-parts only for experimental builds. ([#5606](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5606)) +* Fix - Show express payment button in full width if only one express payment method is available. ([#5601](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5601)) +* Fix - Wrapped cart item product contents in inner div. ([#5240](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5240)) +* Fix - Fix alignment issue with the "create account" section on the checkout block in the editor ([#5633](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5633)) +* Dev - Remove invalid `$wpdb->prepare()` statement in Featured Category Block. ([#5471](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5471)) +* Dev - Remove Stripe Payment Method Integration (which is now part of the Stripe Payment Method extension itself). ([#5449](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5449)) +* Dev - Update the block theme folders to latest Gutenberg convention (i.e. `templates` and `parts`). ([#5464](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5464)) +* Dev - Revert "Allow LegacyTemplate block to be reinserted, only on WooCommerce block templates.". ([#5643](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5643)) + = 6.2.1 2022-02-22 = **WooCommerce** From 9cd2a2bce1a0d75c63de73becfa18802af1a1d96 Mon Sep 17 00:00:00 2001 From: roykho Date: Tue, 8 Mar 2022 12:56:16 -0800 Subject: [PATCH 28/53] Update readme --- plugins/woocommerce/readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/readme.txt b/plugins/woocommerce/readme.txt index 0cb734bd720..5fe323beb36 100644 --- a/plugins/woocommerce/readme.txt +++ b/plugins/woocommerce/readme.txt @@ -4,7 +4,7 @@ Tags: e-commerce, store, sales, sell, woo, shop, cart, checkout, downloadable, d Requires at least: 5.7 Tested up to: 5.9 Requires PHP: 7.0 -Stable tag: 6.2.0 +Stable tag: 6.3.0 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -160,6 +160,6 @@ WooCommerce comes with some sample data you can use to see how products look; im == Changelog == -= 6.3.0 2021-XX-XX = += 6.4.0 2022-XX-XX = [See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce/trunk/changelog.txt). From e20473161793e3bcfc7e55b9f4fe817443a4b235 Mon Sep 17 00:00:00 2001 From: roykho Date: Thu, 24 Feb 2022 08:52:25 -0800 Subject: [PATCH 29/53] Update changelog with sec changes --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index f338280bffe..b25bbf54af7 100644 --- a/changelog.txt +++ b/changelog.txt @@ -18,6 +18,7 @@ * Fix - Ensure that WooCommerce panel within the Customizer is showing a back button. ([#31508](https://github.com/woocommerce/woocommerce/pull/31508)) * Fix - Avoids incorrectly setting the search argument under some conditions, when the Customers endpoint of the REST API is used. ([#31295](https://github.com/woocommerce/woocommerce/pull/31295)) * Fix - Reverted #31593 that caused the returned line item price to be a string instead of a float. ([#31935](https://github.com/woocommerce/woocommerce/pull/31935)) +* Fix - Add prefix to easy identify guest sessions. * Dev - The cart session is now updated later on during the woocommerce_after_calculate_totals action (priority 1000, instead of priority 10 as previously). ([#31711](https://github.com/woocommerce/woocommerce/pull/31711)) * Dev - Enable browser-suggested passwords on checkout signup. ([#31701](https://github.com/woocommerce/woocommerce/pull/31701)) * Dev - Add method can_view_woocommerce_menu_item to check if the user can access the top-level WooCommerce menu item. ([#31689](https://github.com/woocommerce/woocommerce/pull/31689)) From 8d57884a705917984e4d484a965271abf25c39e4 Mon Sep 17 00:00:00 2001 From: roykho Date: Thu, 24 Feb 2022 08:49:11 -0800 Subject: [PATCH 30/53] Cherry picked sec changes --- .../includes/class-wc-checkout.php | 15 ++- .../includes/class-wc-session-handler.php | 74 ++++++++++++- .../class-wc-tests-session-handler.php | 101 +++++++++++++++++- 3 files changed, 185 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-checkout.php b/plugins/woocommerce/includes/class-wc-checkout.php index 076b8a48e32..9dfa2474b42 100644 --- a/plugins/woocommerce/includes/class-wc-checkout.php +++ b/plugins/woocommerce/includes/class-wc-checkout.php @@ -1134,9 +1134,19 @@ class WC_Checkout { */ public function process_checkout() { try { - $nonce_value = wc_get_var( $_REQUEST['woocommerce-process-checkout-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // phpcs:ignore + $nonce_value = wc_get_var( $_REQUEST['woocommerce-process-checkout-nonce'], wc_get_var( $_REQUEST['_wpnonce'], '' ) ); // phpcs:ignore + $expiry_message = sprintf( + /* translators: %s: shop cart url */ + __( 'Sorry, your session has expired. Return to shop', 'woocommerce' ), + esc_url( wc_get_page_permalink( 'shop' ) ) + ); if ( empty( $nonce_value ) || ! wp_verify_nonce( $nonce_value, 'woocommerce-process_checkout' ) ) { + // If the cart is empty, the nonce check failed because of session expiry. + if ( WC()->cart->is_empty() ) { + throw new Exception( $expiry_message ); + } + WC()->session->set( 'refresh_totals', true ); throw new Exception( __( 'We were unable to process your order, please try again.', 'woocommerce' ) ); } @@ -1147,8 +1157,7 @@ class WC_Checkout { do_action( 'woocommerce_before_checkout_process' ); if ( WC()->cart->is_empty() ) { - /* translators: %s: shop cart url */ - throw new Exception( sprintf( __( 'Sorry, your session has expired. Return to shop', 'woocommerce' ), esc_url( wc_get_page_permalink( 'shop' ) ) ) ); + throw new Exception( $expiry_message ); } do_action( 'woocommerce_checkout_process' ); diff --git a/plugins/woocommerce/includes/class-wc-session-handler.php b/plugins/woocommerce/includes/class-wc-session-handler.php index 0c6dda12484..a98bf04bc78 100644 --- a/plugins/woocommerce/includes/class-wc-session-handler.php +++ b/plugins/woocommerce/includes/class-wc-session-handler.php @@ -88,12 +88,18 @@ class WC_Session_Handler extends WC_Session { $cookie = $this->get_session_cookie(); if ( $cookie ) { + // Customer ID will be an MD5 hash id this is a guest session. $this->_customer_id = $cookie[0]; $this->_session_expiration = $cookie[1]; $this->_session_expiring = $cookie[2]; $this->_has_cookie = true; $this->_data = $this->get_session_data(); + if ( ! $this->is_session_cookie_valid() ) { + $this->destroy_session(); + $this->set_session_expiration(); + } + // If the user logs in, update session. if ( is_user_logged_in() && strval( get_current_user_id() ) !== $this->_customer_id ) { $guest_session_id = $this->_customer_id; @@ -115,6 +121,30 @@ class WC_Session_Handler extends WC_Session { } } + /** + * Checks if session cookie is expired, or belongs to a logged out user. + * + * @return bool Whether session cookie is valid. + */ + private function is_session_cookie_valid() { + // If session is expired, session cookie is invalid. + if ( time() > $this->_session_expiration ) { + return false; + } + + // If user has logged out, session cookie is invalid. + if ( ! is_user_logged_in() && ! $this->is_customer_guest( $this->_customer_id ) ) { + return false; + } + + // Session from a different user is not valid. (Although from a guest user will be valid) + if ( is_user_logged_in() && ! $this->is_customer_guest( $this->_customer_id ) && strval( get_current_user_id() ) !== $this->_customer_id ) { + return false; + } + + return true; + } + /** * Sets the session cookie on-demand (usually after adding an item to the cart). * @@ -181,12 +211,54 @@ class WC_Session_Handler extends WC_Session { if ( empty( $customer_id ) ) { require_once ABSPATH . 'wp-includes/class-phpass.php'; $hasher = new PasswordHash( 8, false ); - $customer_id = md5( $hasher->get_random_bytes( 32 ) ); + $customer_id = 't_' . substr( md5( $hasher->get_random_bytes( 32 ) ), 2 ); } return $customer_id; } + /** + * Checks if this is an auto-generated customer ID. + * + * @param string|int $customer_id Customer ID to check. + * + * @return bool Whether customer ID is randomly generated. + */ + private function is_customer_guest( $customer_id ) { + $customer_id = strval( $customer_id ); + + if ( empty( $customer_id ) ) { + return true; + } + + if ( 't_' === substr( $customer_id, 0, 2 ) ) { + return true; + } + + /** + * Legacy checks. This is to handle sessions that were created from a previous release. + * Maybe we can get rid of them after a few releases. + */ + + // Almost all random $customer_ids will have some letters in it, while all actual ids will be integers. + if ( strval( (int) $customer_id ) !== $customer_id ) { + return true; + } + + // Performance hack to potentially save a DB query, when same user as $customer_id is logged in. + if ( is_user_logged_in() && strval( get_current_user_id() ) === $customer_id ) { + return false; + } else { + $customer = new WC_Customer( $customer_id ); + + if ( 0 === $customer->get_id() ) { + return true; + } + } + + return false; + } + /** * Get session unique ID for requests if session is initialized or user ID if logged in. * Introduced to help with unit tests. diff --git a/plugins/woocommerce/tests/legacy/unit-tests/session/class-wc-tests-session-handler.php b/plugins/woocommerce/tests/legacy/unit-tests/session/class-wc-tests-session-handler.php index 7af97b30165..bb60510722d 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/session/class-wc-tests-session-handler.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/session/class-wc-tests-session-handler.php @@ -130,12 +130,111 @@ class WC_Tests_Session_Handler extends WC_Unit_Test_Case { $this->assertEquals( $this->handler->get_customer_unique_id(), $this->handler->maybe_update_nonce_user_logged_out( 1, 'woocommerce-something' ) ); } + /** + * @testdox Test that session from cookie is destroyed if expired. + */ + public function test_destroy_session_cookie_expired() { + $customer_id = '1'; + $session_expiration = time() - 10000; + $session_expiring = time() - 1000; + $cookie_hash = ''; + $this->session_key = $customer_id; + + $handler = $this + ->getMockBuilder( WC_Session_Handler::class ) + ->setMethods( array( 'get_session_cookie' ) ) + ->getMock(); + + $handler + ->method( 'get_session_cookie' ) + ->willReturn( array( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) ); + + add_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $handler->init_session_cookie(); + + remove_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $this->assertFalse( wp_cache_get( $this->cache_prefix . $this->session_key, WC_SESSION_CACHE_GROUP ) ); + $this->assertNull( $this->get_session_from_db( $this->session_key ) ); + } + + /** + * @testdox Test that session from cookie is destroyed if user is logged out. + */ + public function test_destroy_session_user_logged_out() { + $customer_id = '1'; + $session_expiration = time() + 50000; + $session_expiring = time() + 5000; + $cookie_hash = ''; + $this->session_key = $customer_id; + + // Simulate a log out. + wp_set_current_user( 0 ); + + $handler = $this + ->getMockBuilder( WC_Session_Handler::class ) + ->setMethods( array( 'get_session_cookie' ) ) + ->getMock(); + + $handler + ->method( 'get_session_cookie' ) + ->willReturn( array( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) ); + + add_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $handler->init_session_cookie(); + + remove_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $this->assertFalse( wp_cache_get( $this->cache_prefix . $this->session_key, WC_SESSION_CACHE_GROUP ) ); + $this->assertNull( $this->get_session_from_db( $this->session_key ) ); + } + + /** + * @testdox Test that session from cookie is destroyed if logged in user doesn't match. + */ + public function test_destroy_session_user_mismatch() { + $customer = WC_Helper_Customer::create_customer(); + $customer_id = (string) $customer->get_id(); + $session_expiration = time() + 50000; + $session_expiring = time() + 5000; + $cookie_hash = ''; + + $handler = $this + ->getMockBuilder( WC_Session_Handler::class ) + ->setMethods( array( 'get_session_cookie' ) ) + ->getMock(); + + wp_set_current_user( $customer->get_id() ); + + $handler->init(); + $handler->set( 'cart', 'fake cart' ); + $handler->save_data(); + + $handler + ->method( 'get_session_cookie' ) + ->willReturn( array( $customer_id, $session_expiration, $session_expiring, $cookie_hash ) ); + + wp_set_current_user( 1 ); + + add_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $handler->init_session_cookie(); + + remove_filter( 'woocommerce_set_cookie_enabled', '__return_false' ); + + $this->assertFalse( wp_cache_get( $this->cache_prefix . $customer_id, WC_SESSION_CACHE_GROUP ) ); + $this->assertNull( $this->get_session_from_db( $customer_id ) ); + $this->assertNotNull( $this->get_session_from_db( '1' ) ); + } + /** * Helper function to create a WC session and save it to the DB. */ protected function create_session() { - $this->handler->init(); wp_set_current_user( 1 ); + $this->handler->init(); $this->handler->set( 'cart', 'fake cart' ); $this->handler->save_data(); $this->session_key = $this->handler->get_customer_id(); From 17744d5aa6db57eaef5cbe2c82891e0ae70cb0c0 Mon Sep 17 00:00:00 2001 From: barryhughes <3594411+barryhughes@users.noreply.github.com> Date: Wed, 9 Mar 2022 12:18:29 -0800 Subject: [PATCH 31/53] Update tests to account for the 'has_options' property. --- .../legacy/unit-tests/rest-api/Tests/Version3/products.php | 2 +- .../Version3/class-wc-rest-products-controller-tests.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/products.php b/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/products.php index 1d5e5055ad2..17006c32598 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/products.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/rest-api/Tests/Version3/products.php @@ -646,7 +646,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 66, count( $properties ) ); + $this->assertEquals( 67, count( $properties ) ); } /** diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php index be242cded44..55ac6fc68a0 100644 --- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php +++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php @@ -84,6 +84,7 @@ class WC_REST_Products_Controller_Tests extends WC_REST_Unit_Test_Case { 'categories', 'tags', 'images', + 'has_options', 'attributes', 'default_attributes', 'variations', From 57a7f94fe98cd73463cda07fa17a6bda392b7d88 Mon Sep 17 00:00:00 2001 From: barryhughes <3594411+barryhughes@users.noreply.github.com> Date: Wed, 9 Mar 2022 12:31:46 -0800 Subject: [PATCH 32/53] Tweak field description. --- .../Controllers/Version3/class-wc-rest-products-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php index 6a34df6f7fc..c2c03690b87 100644 --- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php +++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php @@ -1221,7 +1221,7 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller { ), ), 'has_options' => array( - 'description' => __( 'Shows if the product needs confiruging before it can be bought.', 'woocommerce' ), + 'description' => __( 'Shows if the product needs to be configured before it can be bought.', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), 'readonly' => true, From 8bb2b57f6567fe4046892b132eb7ccc816e15ea1 Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Fri, 4 Mar 2022 20:43:28 -0300 Subject: [PATCH 33/53] Make PayPal Standard PDT notification validation more strict --- .../paypal/class-wc-gateway-paypal.php | 2 +- .../class-wc-gateway-paypal-pdt-handler.php | 49 ++++++++++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php index 04549880989..a54d891d125 100644 --- a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -84,7 +84,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { if ( $this->identity_token ) { include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php'; - new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token ); + new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token, $this->receiver_email ); } } diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index c37d4d1462e..f52d5a0c094 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -25,15 +25,24 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { */ protected $identity_token; + /** + * Receiver email address to validate. + * + * @var string Receiver email address. + */ + protected $receiver_email; + /** * Constructor. * * @param bool $sandbox Whether to use sandbox mode or not. * @param string $identity_token Identity token for PDT support. + * @param string $receiver_email Email to receive PDT notification from. */ - public function __construct( $sandbox = false, $identity_token = '' ) { + public function __construct( $sandbox = false, $identity_token = '', $receiver_email = '' ) { add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response' ) ); + $this->receiver_email = $receiver_email; $this->identity_token = $identity_token; $this->sandbox = $sandbox; } @@ -84,24 +93,42 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { /** * Check Response for PDT. */ - public function check_response() { - if ( empty( $_REQUEST['cm'] ) || empty( $_REQUEST['tx'] ) || empty( $_REQUEST['st'] ) ) { // WPCS: Input var ok, CSRF ok, sanitization ok. + public function check_response( $wc_order_id ) { + if ( empty( $_REQUEST['tx'] ) ) { // WPCS: Input var ok, CSRF ok, sanitization ok. return; } - $order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. - $status = wc_clean( strtolower( wp_unslash( $_REQUEST['st'] ) ) ); // WPCS: input var ok, CSRF ok, sanitization ok. - $amount = isset( $_REQUEST['amt'] ) ? wc_clean( wp_unslash( $_REQUEST['amt'] ) ) : 0; // WPCS: input var ok, CSRF ok, sanitization ok. - $transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. - $order = $this->get_paypal_order( $order_id ); - - if ( ! $order || ! $order->needs_payment() ) { - return false; + $wc_order = wc_get_order( $wc_order_id ); + if ( ! $wc_order->needs_payment() ) { + return; } + $transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. $transaction_result = $this->validate_transaction( $transaction ); if ( $transaction_result ) { + $status = strtolower( $transaction_result['payment_status'] ); + $amount = isset( $transaction_result['mc_gross'] ) ? $transaction_result['mc_gross'] : 0; + $order = $this->get_paypal_order( $transaction_result['custom'] ); + + if ( ! $order ) { + // No valid WC order found on tx data. + return; + } + + if ( $wc_order->get_id() !== $order->get_id() ) { + /* translators: 1: order ID, 2: order ID. */ + WC_Gateway_Paypal::log( sprintf( __( 'Received PDT notification for order %1$d on endpoint for order %2$d.', 'woocommerce' ), $order->get_id(), $wc_order_id ), 'error' ); + return; + } + + if ( 0 !== strcasecmp( trim( $transaction_result['receiver_email'] ), trim( $this->receiver_email ) ) ) { + /* translators: 1: email address, 2: order ID . */ + WC_Gateway_Paypal::log( sprintf( __( 'Received PDT notification for another account: %1$s. Order ID: %2$d.', 'woocommerce' ), $transaction_result['receiver_email'], $order->get_id() ), 'error' ); + return; + } + + // We have a valid response from PayPal. WC_Gateway_Paypal::log( 'PDT Transaction Status: ' . wc_print_r( $status, true ) ); $order->add_meta_data( '_paypal_status', $status ); From 3e1acd113bd4c2f1439ba0d767e96b704dd6f684 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 7 Mar 2022 15:39:31 +0100 Subject: [PATCH 34/53] Create a new WC_Gateway_Paypal_Response::check_response_for_order method Adding a new parameter to the existing check_response method could cause backwards incompatibility issues in inherited classes, so we deprecate the old method and create a new one instead. --- .../class-wc-gateway-paypal-pdt-handler.php | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index f52d5a0c094..c0450980ed0 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -40,7 +40,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { * @param string $receiver_email Email to receive PDT notification from. */ public function __construct( $sandbox = false, $identity_token = '', $receiver_email = '' ) { - add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response' ) ); + add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response_for_order' ) ); $this->receiver_email = $receiver_email; $this->identity_token = $identity_token; @@ -91,10 +91,32 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { } /** - * Check Response for PDT. + * Check Response for PDT, taking the order id from the request. + * + * @deprecated 6.4 Use check_response_for_order instead. */ - public function check_response( $wc_order_id ) { - if ( empty( $_REQUEST['tx'] ) ) { // WPCS: Input var ok, CSRF ok, sanitization ok. + public function check_response() { + // phpcs:disable WordPress.Security.NonceVerification.Recommended + if ( empty( $_REQUEST['cm'] ) ) { + return; + } + + $order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); + + // phpcs:enable WordPress.Security.NonceVerification.Recommended + check_response_for_order( $order_id ); + } + + /** + * Check Response for PDT. + * + * @since 6.4 + * + * @param mixed $wc_order_id The order id to check the response against. + */ + public function check_response_for_order( $wc_order_id ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( empty( $_REQUEST['tx'] ) ) { return; } @@ -103,7 +125,8 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { return; } - $transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); // WPCS: input var ok, CSRF ok, sanitization ok. + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $transaction = wc_clean( wp_unslash( $_REQUEST['tx'] ) ); $transaction_result = $this->validate_transaction( $transaction ); if ( $transaction_result ) { From b1b68f52cd84838c5b5964e5557c3c0959b09c93 Mon Sep 17 00:00:00 2001 From: Vedanshu Jain Date: Mon, 7 Mar 2022 23:00:51 +0530 Subject: [PATCH 35/53] Fix object reference Co-authored-by: Barry Hughes <3594411+barryhughes@users.noreply.github.com> --- .../paypal/includes/class-wc-gateway-paypal-pdt-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index c0450980ed0..51c5deeb378 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -104,7 +104,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { $order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); // phpcs:enable WordPress.Security.NonceVerification.Recommended - check_response_for_order( $order_id ); + $this->check_response_for_order( $order_id ); } /** From 95ec1fc56ecabc7324ae91c4d5f65934d74c2185 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Mon, 7 Mar 2022 19:53:14 +0100 Subject: [PATCH 36/53] Receiver email set separately for bw compat --- .../gateways/paypal/class-wc-gateway-paypal.php | 3 ++- .../includes/class-wc-gateway-paypal-pdt-handler.php | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php index a54d891d125..658cec00094 100644 --- a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -84,7 +84,8 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { if ( $this->identity_token ) { include_once dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php'; - new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token, $this->receiver_email ); + $pdt_handler = new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token ); + $pdt_handler->set_receiver_email( $this->receiver_email ); } } diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index 51c5deeb378..dd31b02d303 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -39,14 +39,22 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { * @param string $identity_token Identity token for PDT support. * @param string $receiver_email Email to receive PDT notification from. */ - public function __construct( $sandbox = false, $identity_token = '', $receiver_email = '' ) { + public function __construct( $sandbox = false, $identity_token = '' ) { add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response_for_order' ) ); - $this->receiver_email = $receiver_email; $this->identity_token = $identity_token; $this->sandbox = $sandbox; } + /** + * Set receiver email to enable more strict validation. + * + * @param string $receiver_email PayPal reciever email. + */ + public function set_receiver_email( $receiver_email = '' ) { + $this->receiver_email = $receiver_email; + } + /** * Validate a PDT transaction to ensure its authentic. * From ce3780017874af1872e7eaccda59d97502ec99d7 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Mon, 7 Mar 2022 19:53:37 +0100 Subject: [PATCH 37/53] Fixed the order id fetching --- .../includes/class-wc-gateway-paypal-pdt-handler.php | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index dd31b02d303..91acf80b3ee 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -41,7 +41,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { */ public function __construct( $sandbox = false, $identity_token = '' ) { add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response_for_order' ) ); - + $this->identity_token = $identity_token; $this->sandbox = $sandbox; } @@ -104,14 +104,9 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { * @deprecated 6.4 Use check_response_for_order instead. */ public function check_response() { - // phpcs:disable WordPress.Security.NonceVerification.Recommended - if ( empty( $_REQUEST['cm'] ) ) { - return; - } + global $wp; + $order_id = apply_filters( 'woocommerce_thankyou_order_id', absint( $wp->query_vars['order-received'] ) ); - $order_id = wc_clean( wp_unslash( $_REQUEST['cm'] ) ); - - // phpcs:enable WordPress.Security.NonceVerification.Recommended $this->check_response_for_order( $order_id ); } From 8d8a556e5cb8ff75a26a7d10505fed9428fd63f4 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Mon, 7 Mar 2022 19:55:25 +0100 Subject: [PATCH 38/53] Fixed docs. --- .../paypal/includes/class-wc-gateway-paypal-pdt-handler.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index 91acf80b3ee..b6a400a93fc 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -37,7 +37,6 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { * * @param bool $sandbox Whether to use sandbox mode or not. * @param string $identity_token Identity token for PDT support. - * @param string $receiver_email Email to receive PDT notification from. */ public function __construct( $sandbox = false, $identity_token = '' ) { add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response_for_order' ) ); @@ -49,7 +48,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { /** * Set receiver email to enable more strict validation. * - * @param string $receiver_email PayPal reciever email. + * @param string $receiver_email Email to receive PDT notification from. */ public function set_receiver_email( $receiver_email = '' ) { $this->receiver_email = $receiver_email; From 8be6eb4a630d639ad1aa1da3e634dd9ef4ea3eab Mon Sep 17 00:00:00 2001 From: Barry Hughes <3594411+barryhughes@users.noreply.github.com> Date: Mon, 7 Mar 2022 12:05:32 -0800 Subject: [PATCH 39/53] Update plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php --- .../paypal/includes/class-wc-gateway-paypal-pdt-handler.php | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index b6a400a93fc..b356f66a7de 100644 --- a/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/plugins/woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -40,7 +40,6 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { */ public function __construct( $sandbox = false, $identity_token = '' ) { add_action( 'woocommerce_thankyou_paypal', array( $this, 'check_response_for_order' ) ); - $this->identity_token = $identity_token; $this->sandbox = $sandbox; } From 871ac9074358094037c233ab5f8496f0513d6257 Mon Sep 17 00:00:00 2001 From: Jonathan Sadowski Date: Thu, 10 Mar 2022 11:02:30 -0600 Subject: [PATCH 40/53] Update changelog for PP security fix --- changelog.txt | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/changelog.txt b/changelog.txt index b25bbf54af7..2d055307fe0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,11 @@ == Changelog == += 6.3.1 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 6.3.0 2022-03-08 = **WooCommerce** @@ -117,6 +123,12 @@ * Dev - Update the block theme folders to latest Gutenberg convention (i.e. `templates` and `parts`). ([#5464](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5464)) * Dev - Revert "Allow LegacyTemplate block to be reinserted, only on WooCommerce block templates.". ([#5643](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5643)) += 6.2.2 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 6.2.1 2022-02-22 = **WooCommerce** @@ -196,6 +208,12 @@ * Tweak - Add error handling to `get_routes_from_namespace` method. ([5319](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5319)) * Tweak - Update WooCommerce plugin slug for Block Templates. ([#5519](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5519)) += 6.1.2 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 6.1.1 2022-01-20 = **WooCommerce** @@ -314,6 +332,12 @@ * Fix - Fix error when reverting WooCommerce templates. ( [#5342](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5342) ) * Fix - Fix: WooCommerce block templates loading for WP 5.9 without Gutenberg plugin. ( [#5335](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5335) ) += 6.0.1 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 6.0.0 2021-12-14 = **WooCommerce** @@ -419,6 +443,12 @@ * Fix - Store API – Ensure returned customer address state is valid. ( [#4844](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4844) ) * Fix - fatal error in certain WP 5.9 pre-release versions. ( [#5183](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/5183) ) += 5.9.1 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.9.0 2021-11-09 = **WooCommerce** @@ -476,6 +506,12 @@ * Fix - Remove IntersectionObserver shim in favor of dropping IE11 support. #4808 * Enhancement - Added global styles to All Reviews, Reviews by Category and Reviews by Product blocks. Now it's possible to change the text color and font size of those blocks. #4323 += 5.8.2 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.8.0 2021-10-12 = **WooCommerce** @@ -549,6 +585,12 @@ * Fix - Improves compatibility with environments where NO_ZERO_DATE is enabled. #519 * Fix - Adds safety checks to guard against errors when our database tables cannot be created. #645 += 5.7.2 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.7.1 2021-09-23 = **WooCommerce** @@ -656,6 +698,12 @@ - Fix - Fix memory leak when previewing transform options for the All reviews block. #4428 - Fix - Disable Cart, Checkout, All Products & filters blocks from the widgets screen. #4646 += 5.6.2 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.6.0 2021-08-17 = **WooCommerce** @@ -762,6 +810,12 @@ - Tweak - Allow products to be added by SKU in the Hand-Picked Products block. #4366 - Tweak - Add Slot in the Discounts section of the Checkout sidebar to allow third party extensions to render their own components there. #4310 += 5.5.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.5.2 2021-07-22 = * Fix - Add a new option allowing product downloads to be served using redirects as a last resort. #30288 @@ -965,6 +1019,12 @@ * Fix - Add extra safety/account for different versions of AS and different loading patterns. #714 * Fix - Handle hidden columns (Tools → Scheduled Actions) | #600. += 5.4.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.4.2 2021-07-14 = **WooCommerce** @@ -1064,6 +1124,12 @@ * Fix - Prevent parts of old addresses being displayed in the shipping calculator when changing countries. #4038 * Fix - issue in which email and phone fields are cleared when using a separate billing address. #4162 += 5.3.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.3.1 2021-07-14 = **WooCommerce** @@ -1201,6 +1267,12 @@ * Tweak - Store profiler - Changed MailPoet's title and description #6886 * Tweak - Update PayU logo #6829 += 5.2.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.2.3 2021-07-14 = **WooCommerce** @@ -1370,6 +1442,12 @@ * Fix - Ensure sale badges have a uniform height in the Cart block. ([3897](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3897)) * Note - Internally, this release has modified how `AbstractBlock` (the base class for all of our blocks) functions, and how it loads assets. `AbstractBlock` is internal to this project and does not seem like something that would ever need to be extended by 3rd parties, but note if you are doing so for whatever reason, your implementation would need to be updated to match. ([3829](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3829)) += 5.1.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.1.1 2021-07-14 = **WooCommerce** @@ -1484,6 +1562,12 @@ * Dev - Added formatting classes to the Store API for extensions to consume. * Dev - Refactored and reordered Store API checkout processing to handle various edge cases and better support future extensibility. ([3454](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3454)) += 5.0.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 5.0.1 2021-07-14 = **WooCommerce** @@ -1557,6 +1641,12 @@ * Enhancement - Add an "unread" indicator to inbox messages. #6047 * Add - Manage activity from home screen inbox message. #6072 += 4.9.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.9.3 2021-07-14 = **WooCommerce** @@ -1687,6 +1777,12 @@ * Dev - Expose store/cart via ExtendRestApi to extensions. ([3445](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3445)) * Dev - Added formatting classes to the Store API for extensions to consume. += 4.8.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.8.1 2021-07-14 = **WooCommerce** @@ -1806,6 +1902,12 @@ * Fix - Twenty Twenty One Button and Placeholder Styling. #3443 * Fix - checkbox and textarea styles in Twenty Twenty One when it has dark controls active. #3450 += 4.7.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.7.2 2021-07-14 = **WooCommerce** @@ -1874,6 +1976,12 @@ * Tweak: Add BR and IN to list of stripe countries [#5377](https://github.com/woocommerce/woocommerce-admin/pull/5377) * Fix: Redirect instead of stalling on WCPay Inbox note action [#5413](https://github.com/woocommerce/woocommerce-admin/pull/5413) += 4.6.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.6.3 2021-07-14 = **WooCommerce** @@ -2002,6 +2110,12 @@ - Create DebouncedValidatedTextInput component. ([3108](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3108)) - Merge ProductPrice atomic block and component. ([3065](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3065)) += 4.5.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.5.3 2021-07-14 = **WooCommerce** @@ -2056,6 +2170,12 @@ * Dev - Task list - add a shortcut back to store setup. #4853 * Dev - Update the colors of the illustrations in the welcome modal. #4945 += 4.4.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.4.2 2021-07-14 = **WooCommerce** @@ -2210,6 +2330,12 @@ * Fix - 'Product Summary' in All Products block is not pulling in the short description of the product. #2913 * Dev - Add query filter when searching for a table. #2886 += 4.3.6 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.3.4 2021-07-14 = **WooCommerce** @@ -2397,6 +2523,12 @@ * Dev - Table creation validation for install routine #2287 * Dev - Update the icons used in the blocks. #1644 += 4.2.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.2.3 2021-07-14 = **WooCommerce** @@ -2481,6 +2613,12 @@ * Dev - Dynamic Currency with Context API #4027 * Dev - Remove Duplicate array entry #4049 += 4.1.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.1.2 2021-07-14 = **WooCommerce** @@ -2546,6 +2684,12 @@ * Dev - Adds usage data for the of cart & checkout blocks (currently in development in WooCommmerce Blocks plugin) to the WC Tracker snapshot. #26084 * Dev - Implement some additional tracks for coupons, orders, and products. #26085 += 4.0.4 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 4.0.2 2021-07-14 = **WooCommerce** @@ -2670,6 +2814,12 @@ * Dev - Applies woocommerce_maxmind_geolocation_database_path in MaxMind database migration. #25681 * Dev - Support both .data() and .dataset for formdata in add to cart requests. #25726 += 3.9.5 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 3.9.4 2021-07-14 = **WooCommerce** @@ -2785,6 +2935,12 @@ * Localization - Fixed translatable string comments for translators. #24928 * Localization - Add postcode validation for Slovenia. #25174 += 3.8.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 3.8.2 2021-07-14 = **WooCommerce** @@ -2907,6 +3063,12 @@ * Security - Add an exit after the redirect when checking author archive capabilities for customers. * Security - Ensure 404 pages with single product urls cannot be exploited using Open Redirect. += 3.7.3 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 3.7.2 2021-07-14 = **WooCommerce** @@ -3019,6 +3181,12 @@ * Localization - Add new currency for São Tomé, Príncipe dobra and Mauritanian ouguiya. #23950 * Localization - Change Canada poscode label to `Postal code`. #23740 += 3.6.7 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 3.6.6 2021-07-14 = **WooCommerce** @@ -3348,6 +3516,12 @@ * Localization - Update CA address format. #22692 * Localization - Updated JP field order. #22774 += 3.5.10 2022-03-10 = + +**WooCommerce** + +* Security - Address an issue with the PayPal Standard Payment Gateway. See https://developer.woocommerce.com/2022/03/10/woocommerce-3-5-10-6-3-1-security-releases/. ([#32057](https://github.com/woocommerce/woocommerce/pull/32057)) + = 3.5.9 2021-07-14 = **WooCommerce** From 5963c564cb07bed7dbac36576d64d452b57e172a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Sz=C3=A9pe?= Date: Wed, 22 Sep 2021 00:04:43 +0200 Subject: [PATCH 41/53] Remove stray unset from wc_update_200_line_items Discovered by @phpstan --- plugins/woocommerce/includes/wc-update-functions.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php index 6f19adb89e1..d17a43499df 100644 --- a/plugins/woocommerce/includes/wc-update-functions.php +++ b/plugins/woocommerce/includes/wc-update-functions.php @@ -346,8 +346,6 @@ function wc_update_200_line_items() { $order_tax_row->post_id ) ); - - unset( $tax_amount ); } } } From 98376d4ec4063a0f776997c4d549c2a0a35cf6e6 Mon Sep 17 00:00:00 2001 From: Job Date: Thu, 26 Aug 2021 15:05:00 +0200 Subject: [PATCH 42/53] Update class-wc-settings-emails.php --- .../includes/admin/settings/class-wc-settings-emails.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce/includes/admin/settings/class-wc-settings-emails.php b/plugins/woocommerce/includes/admin/settings/class-wc-settings-emails.php index 4f9db0ec091..9086d7fd8b8 100644 --- a/plugins/woocommerce/includes/admin/settings/class-wc-settings-emails.php +++ b/plugins/woocommerce/includes/admin/settings/class-wc-settings-emails.php @@ -146,11 +146,11 @@ class WC_Settings_Emails extends WC_Settings_Page { array( 'title' => __( 'Base color', 'woocommerce' ), /* translators: %s: default color */ - 'desc' => sprintf( __( 'The base color for WooCommerce email templates. Default %s.', 'woocommerce' ), '#96588a' ), + 'desc' => sprintf( __( 'The base color for WooCommerce email templates. Default %s.', 'woocommerce' ), '#7f54b3' ), 'id' => 'woocommerce_email_base_color', 'type' => 'color', 'css' => 'width:6em;', - 'default' => '#96588a', + 'default' => '#7f54b3', 'autoload' => false, 'desc_tip' => true, ), From 94729ca032b651fa75655ac071115601086697a1 Mon Sep 17 00:00:00 2001 From: Job Date: Thu, 26 Aug 2021 15:06:13 +0200 Subject: [PATCH 43/53] Update wc-setup.scss --- plugins/woocommerce/legacy/css/wc-setup.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/legacy/css/wc-setup.scss b/plugins/woocommerce/legacy/css/wc-setup.scss index f6e2373ed8a..2a83916e96b 100644 --- a/plugins/woocommerce/legacy/css/wc-setup.scss +++ b/plugins/woocommerce/legacy/css/wc-setup.scss @@ -1489,7 +1489,7 @@ p.jetpack-terms { margin-left: 4px; &.recommended-item-icon-wc_admin { - background-color: #96588a; + background-color: #7f54b3; padding: 0.5em; height: 2em; } From 1caf5aa7da83dcf66dd8bafe1cd653583448698f Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Mon, 14 Mar 2022 11:30:54 +0100 Subject: [PATCH 44/53] Add a primary key to the product attributes lookup table. --- .../woocommerce/includes/class-wc-install.php | 4 ++ .../includes/wc-update-functions.php | 19 +++++ .../DataRegenerator.php | 72 ++++++++++++------- 3 files changed, 68 insertions(+), 27 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php index a0fa2282960..774a8b50f4c 100644 --- a/plugins/woocommerce/includes/class-wc-install.php +++ b/plugins/woocommerce/includes/class-wc-install.php @@ -175,6 +175,10 @@ class WC_Install { 'wc_update_630_create_product_attributes_lookup_table', 'wc_update_630_db_version', ), + '6.4.0' => array( + 'wc_update_640_add_primary_key_to_product_attributes_lookup_table', + 'wc_update_640_db_version', + ), ); /** diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php index d17a43499df..468f21f352e 100644 --- a/plugins/woocommerce/includes/wc-update-functions.php +++ b/plugins/woocommerce/includes/wc-update-functions.php @@ -2364,3 +2364,22 @@ function wc_update_630_create_product_attributes_lookup_table() { function wc_update_630_db_version() { WC_Install::update_db_version( '6.3.0' ); } + +/** + * Create the primary key for the product attributes lookup table if it doesn't exist already. + * + * @return bool Always false. + */ +function wc_update_640_add_primary_key_to_product_attributes_lookup_table() { + wc_get_container()->get( DataRegenerator::class )->create_table_primary_index(); + + return false; +} + +/** + * + * Update DB version to 6.4.0. + */ +function wc_update_640_db_version() { + WC_Install::update_db_version( '6.4.0' ); +} diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index b6013be86a5..28d7168acdc 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -440,26 +440,26 @@ class DataRegenerator { } } - /* - * Get the name of the product attributes lookup table. - * - * @return string - */ - public function get_lookup_table_name() { - return $this->lookup_table_name; - } + /** + * Get the name of the product attributes lookup table. + * + * @return string + */ + public function get_lookup_table_name() { + return $this->lookup_table_name; + } - /** - * Get the SQL statement that creates the product attributes lookup table, including the indices. - * - * @return string - */ - public function get_table_creation_sql() { - global $wpdb; + /** + * Get the SQL statement that creates the product attributes lookup table, including the indices. + * + * @return string + */ + public function get_table_creation_sql() { + global $wpdb; - $collate = $wpdb->has_cap( 'collation' ) ? $wpdb->get_charset_collate() : ''; + $collate = $wpdb->has_cap( 'collation' ) ? $wpdb->get_charset_collate() : ''; - return "CREATE TABLE {$this->lookup_table_name} ( + return "CREATE TABLE {$this->lookup_table_name} ( product_id bigint(20) NOT NULL, product_or_parent_id bigint(20) NOT NULL, taxonomy varchar(32) NOT NULL, @@ -467,17 +467,35 @@ class DataRegenerator { is_variation_attribute tinyint(1) NOT NULL, in_stock tinyint(1) NOT NULL, INDEX product_or_parent_id_term_id (product_or_parent_id, term_id), - INDEX is_variation_attribute_term_id (is_variation_attribute, term_id) + INDEX is_variation_attribute_term_id (is_variation_attribute, term_id), + PRIMARY KEY (`product_id`, `product_or_parent_id`, `taxonomy`, `term_id`) ) $collate;"; - } + } - /** - * Run additional setup needed after a clean WooCommerce install finishes. - */ - private function run_woocommerce_installed_callback() { - // The table must exist at this point (created via dbDelta), but we check just in case. - if ( $this->data_store->check_lookup_table_exists() ) { - $this->finalize_regeneration( true ); - } + /** + * Create the primary key for the table if it doesn't exist already. + * + * @return void + */ + public function create_table_primary_index() { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + $wpdb->query( + " +ALTER TABLE {$this->lookup_table_name} +ADD PRIMARY KEY IF NOT EXISTS (`product_id`, `product_or_parent_id`, `taxonomy`, `term_id`)" + ); + // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + } + + /** + * Run additional setup needed after a clean WooCommerce install finishes. + */ + private function run_woocommerce_installed_callback() { + // The table must exist at this point (created via dbDelta), but we check just in case. + if ( $this->data_store->check_lookup_table_exists() ) { + $this->finalize_regeneration( true ); + } } } From 904ec4343c341d82b0d301a5151681a6c9318d89 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 15 Mar 2022 11:59:09 +0100 Subject: [PATCH 45/53] Fix misc links in READMEs and GitHub templates. --- .github/CONTRIBUTING.md | 6 ++--- .github/ISSUE_TEMPLATE/2-enhancement.yml | 2 +- packages/js/e2e-core-tests/CHANGELOG.md | 2 +- packages/js/e2e-environment/builtin.md | 2 +- packages/js/e2e-environment/external.md | 2 +- .../includes/admin/class-wc-admin-help.php | 6 ++--- plugins/woocommerce/src/README.md | 26 +++++++++---------- plugins/woocommerce/tests/e2e/README.md | 4 +-- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index bf0a99c028d..a20fb54f898 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -27,7 +27,7 @@ If you have questions about the process to contribute code or want to discuss de - [Naming conventions](https://github.com/woocommerce/woocommerce/wiki/Naming-conventions) - [String localisation guidelines](https://github.com/woocommerce/woocommerce/wiki/String-localisation-guidelines) - [Running unit tests](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/README.md) -- [Running e2e tests](https://github.com/woocommerce/woocommerce/wiki/End-to-end-Testing) +- [Running e2e tests](https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/tests/e2e/README.md) ## Coding Guidelines and Development 🛠 @@ -48,8 +48,8 @@ If you are contributing code to the (Javascript-driven) WooCommerce Admin projec ## Feature Requests 🚀 -Feature requests can be [submitted to our issue tracker](https://github.com/woocommerce/woocommerce/issues/new?template=6-Feature-request.md). Be sure to include a description of the expected behavior and use case, and before submitting a request, please search for similar ones in the closed issues. +Feature requests can be [submitted to our issue tracker](https://github.com/woocommerce/woocommerce/issues/new?assignees=&labels=type%3A+enhancement%2Cstatus%3A+awaiting+triage&template=2-enhancement.yml&title=%5BEnhancement%5D%3A+). Be sure to include a description of the expected behavior and use case, and before submitting a request, please search for similar ones in the closed issues. Feature request issues will remain closed until we see sufficient interest via comments and [👍 reactions](https://help.github.com/articles/about-discussions-in-issues-and-pull-requests/) from the community. -You can see a [list of current feature requests which require votes here](https://github.com/woocommerce/woocommerce/issues?q=is%3Aclosed+label%3A%22type%3A+enhancement%22+label%3A%22votes+needed%22+sort%3Areactions-%2B1-desc). +You can see a [list of current feature requests which require votes here](https://github.com/woocommerce/woocommerce/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3A%22needs%3A+votes%22+). diff --git a/.github/ISSUE_TEMPLATE/2-enhancement.yml b/.github/ISSUE_TEMPLATE/2-enhancement.yml index 0da172f20d9..3c7637cea8c 100644 --- a/.github/ISSUE_TEMPLATE/2-enhancement.yml +++ b/.github/ISSUE_TEMPLATE/2-enhancement.yml @@ -10,7 +10,7 @@ body: Please provide us with the information requested in this form. - Make sure to look through [existing `type: enhancement` issues](https://github.com/woocommerce/woocommerce/issues?q=is%3Aopen+is%3Aissue+label%3A%22type%3A+enhancement%22) and [existing `votes needed` issues](https://github.com/woocommerce/woocommerce/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3A%22votes+needed%22) to see whether your idea is already being discussed. + Make sure to look through [existing `type: enhancement` issues](https://github.com/woocommerce/woocommerce/issues?q=is%3Aopen+is%3Aissue+label%3A%22type%3A+enhancement%22) and [existing `votes needed` issues](https://github.com/woocommerce/woocommerce/issues?q=is%3Aissue+sort%3Areactions-%2B1-desc+label%3A%22needs%3A+votes%22+) to see whether your idea is already being discussed. Feel free to contribute to any existing issues. Search tip: You can filter our issues using [our enhancement label](https://github.com/woocommerce/woocommerce/issues?q=is%3Aissue+label%3A%22type%3A+enhancement%22+). Search tip: Make use of [GitHub's search syntax to refine your search](https://help.github.com/en/github/searching-for-information-on-github/searching-issues-and-pull-requests). diff --git a/packages/js/e2e-core-tests/CHANGELOG.md b/packages/js/e2e-core-tests/CHANGELOG.md index 65f185480e2..3996c4db256 100644 --- a/packages/js/e2e-core-tests/CHANGELOG.md +++ b/packages/js/e2e-core-tests/CHANGELOG.md @@ -27,7 +27,7 @@ - Support for re-running setup and shopper tests - Shopper Order Email Receiving -- New tests - See [README.md](https://github.com/woocommerce/woocommerce/blob/trunk/tests/e2e/core-tests/README.md) for list of available tests +- New tests - See [README.md](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/e2e-core-tests/README.md) for list of available tests ## Fixed diff --git a/packages/js/e2e-environment/builtin.md b/packages/js/e2e-environment/builtin.md index 2b91b80bd98..683e4269001 100644 --- a/packages/js/e2e-environment/builtin.md +++ b/packages/js/e2e-environment/builtin.md @@ -16,7 +16,7 @@ wp post create --post_type=page --post_status=publish --post_title='Ready' --pos ### Project Initialization -Each project will have its own begin test state and initialization script. For example, a project might start testing expecting that the [sample products](https://github.com/woocommerce/woocommerce/tree/trunk/sample-data) have already been imported. Below is the WP CLI equivalent of the built in initialization script for WooCommerce Core E2E testing: +Each project will have its own begin test state and initialization script. For example, a project might start testing expecting that the [sample products](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/sample-data) have already been imported. Below is the WP CLI equivalent of the built in initialization script for WooCommerce Core E2E testing: ``` diff --git a/packages/js/e2e-environment/external.md b/packages/js/e2e-environment/external.md index a39ff5965bb..b3eea9b1129 100644 --- a/packages/js/e2e-environment/external.md +++ b/packages/js/e2e-environment/external.md @@ -16,7 +16,7 @@ wp post create --post_type=page --post_status=publish --post_title='Ready' --pos ### Project Initialization -Each project will have its own begin test state and initialization script. For example, a project might start testing expecting that the [sample products](https://github.com/woocommerce/woocommerce/tree/trunk/sample-data) have already been imported. Below is the WP CLI equivalent initialization script for WooCommerce Core E2E testing: +Each project will have its own begin test state and initialization script. For example, a project might start testing expecting that the [sample products](https://github.com/woocommerce/woocommerce/tree/trunk/plugins/woocommerce/sample-data) have already been imported. Below is the WP CLI equivalent initialization script for WooCommerce Core E2E testing: ``` diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-help.php b/plugins/woocommerce/includes/admin/class-wc-admin-help.php index c4531915bdf..c5afccda4d3 100644 --- a/plugins/woocommerce/includes/admin/class-wc-admin-help.php +++ b/plugins/woocommerce/includes/admin/class-wc-admin-help.php @@ -65,8 +65,8 @@ class WC_Admin_Help { 'content' => '

' . __( 'Found a bug?', 'woocommerce' ) . '

' . /* translators: 1: GitHub issues URL 2: GitHub contribution guide URL 3: System status report URL */ - '

' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via Github issues. Ensure you read the contribution guide prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your system status report.', 'woocommerce' ), 'https://github.com/woocommerce/woocommerce/issues?state=open', 'https://github.com/woocommerce/woocommerce/blob/trunk/.github/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '

' . - '

' . __( 'Report a bug', 'woocommerce' ) . ' ' . __( 'System status', 'woocommerce' ) . '

', + '

' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via GitHub issues. Ensure you read the contribution guide prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your system status report.', 'woocommerce' ), 'https://github.com/woocommerce/woocommerce/issues?state=open', 'https://github.com/woocommerce/woocommerce/blob/trunk/.github/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '

' . + '

' . __( 'Report a bug', 'woocommerce' ) . ' ' . __( 'System status', 'woocommerce' ) . '

', ) ); @@ -75,7 +75,7 @@ class WC_Admin_Help { '

' . __( 'For more information:', 'woocommerce' ) . '

' . '

' . __( 'About WooCommerce', 'woocommerce' ) . '

' . '

' . __( 'WordPress.org project', 'woocommerce' ) . '

' . - '

' . __( 'Github project', 'woocommerce' ) . '

' . + '

' . __( 'GitHub project', 'woocommerce' ) . '

' . '

' . __( 'Official theme', 'woocommerce' ) . '

' . '

' . __( 'Official extensions', 'woocommerce' ) . '

' ); diff --git a/plugins/woocommerce/src/README.md b/plugins/woocommerce/src/README.md index 3e0df5c1657..a1712fcef45 100644 --- a/plugins/woocommerce/src/README.md +++ b/plugins/woocommerce/src/README.md @@ -177,13 +177,13 @@ use Automattic\WooCommerce\TheDependencyNamespace\TheDependencyClass; class TheClassServiceProvider extends AbstractServiceProvider { - protected $provides = array( - TheClass::class - ); + protected $provides = array( + TheClass::class + ); - public function register() { - $this->add( TheClass::class )->addArgument( TheDependencyClass::class ); - } + public function register() { + $this->add( TheClass::class )->addArgument( TheDependencyClass::class ); + } } ``` @@ -209,15 +209,15 @@ use Automattic\WooCommerce\TheDependencyNamespace\TheDependencyClass; class TheClassServiceProvider extends AbstractServiceProvider { - protected $provides = array( - TheClass::class, + protected $provides = array( + TheClass::class, TheDependencyClass::class - ); + ); - public function register() { + public function register() { $this->share( TheDependencyClass::class ); - $this->share_with_auto_arguments( ActionsProxy::class ); - } + $this->share_with_auto_arguments( ActionsProxy::class ); + } } ``` @@ -405,7 +405,7 @@ Unit tests are a fundamental tool to keep the code reliable and reasonably safe ### Mocking dependencies -Since all the dependencies for classes in this directory are dependency-injected or retrieved lazily by directly accessing the container, it's easy to mock them by either manually creating a mock class with the same public surface or by using [PHPUnit's test doubles](https://phpunit.readthedocs.io/en/9.2/test-doubles.html): +Since all the dependencies for classes in this directory are dependency-injected or retrieved lazily by directly accessing the container, it's easy to mock them by either manually creating a mock class with the same public surface or by using [PHPUnit's test doubles](https://phpunit.readthedocs.io/en/9.5/test-doubles.html): ```php $dependency_mock = somehow_create_mock(); diff --git a/plugins/woocommerce/tests/e2e/README.md b/plugins/woocommerce/tests/e2e/README.md index 0f734809c01..6ca2c9a3b14 100644 --- a/plugins/woocommerce/tests/e2e/README.md +++ b/plugins/woocommerce/tests/e2e/README.md @@ -63,7 +63,7 @@ This section explains how e2e tests are working behind the scenes. These are not ### Test Environment -We recommend using Docker for running tests locally in order for the test environment to match the setup on Github CI (where Docker is also used for running tests). [An official WordPress Docker image](https://github.com/docker-library/docs/blob/master/wordpress/README.md) is used to build the site. Once the site using the WP Docker image is built, the current WooCommerce dev branch is mapped into the `plugins` folder of that newly built test site. +We recommend using Docker for running tests locally in order for the test environment to match the setup on GitHub CI (where Docker is also used for running tests). [An official WordPress Docker image](https://github.com/docker-library/docs/blob/master/wordpress/README.md) is used to build the site. Once the site using the WP Docker image is built, the current WooCommerce dev branch is mapped into the `plugins` folder of that newly built test site. ### Test Variables @@ -289,7 +289,7 @@ In the WooCommerce Core repository the tests are in `tests/e2e/core-tests/specs/ The following packages are used in write tests: - `@automattic/puppeteer-utils` - utilities and configuration for running puppeteer against WordPress. See details in the [package's repository](https://github.com/Automattic/puppeteer-utils). -- `@woocommerce/e2e-utils` - this package contains utilities to simplify writing e2e tests specific to WooCommmerce. See details in the [package's repository](https://github.com/woocommerce/woocommerce/tree/trunk/tests/e2e/utils). +- `@woocommerce/e2e-utils` - this package contains utilities to simplify writing e2e tests specific to WooCommmerce. See details in the [package's repository](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/e2e-utils). ### Creating test structure From eb94672f76a67892144c21c6fb3f84f0a43d7c85 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Tue, 15 Mar 2022 17:03:51 +0100 Subject: [PATCH 46/53] Delete the (now redundant) product_or_parent_id_term_id index in the product attributes lookup table. --- .../DataRegenerator.php | 15 ++++++--- .../src/Utilities/DatabaseUtil.php | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index 28d7168acdc..47dbcc7c9e1 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -6,6 +6,7 @@ namespace Automattic\WooCommerce\Internal\ProductAttributesLookup; use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore; +use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil; use Automattic\WooCommerce\Utilities\ArrayUtil; defined( 'ABSPATH' ) || exit; @@ -466,27 +467,31 @@ class DataRegenerator { term_id bigint(20) NOT NULL, is_variation_attribute tinyint(1) NOT NULL, in_stock tinyint(1) NOT NULL, - INDEX product_or_parent_id_term_id (product_or_parent_id, term_id), INDEX is_variation_attribute_term_id (is_variation_attribute, term_id), - PRIMARY KEY (`product_id`, `product_or_parent_id`, `taxonomy`, `term_id`) + PRIMARY KEY ( `product_or_parent_id`, `term_id`, `product_id`, `taxonomy` ) ) $collate;"; } /** * Create the primary key for the table if it doesn't exist already. + * It also deletes the product_or_parent_id_term_id index if it exists, since it's now redundant. * * @return void */ public function create_table_primary_index() { global $wpdb; - // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + // phpcs:disable WordPress.DB.PreparedSQL $wpdb->query( " ALTER TABLE {$this->lookup_table_name} -ADD PRIMARY KEY IF NOT EXISTS (`product_id`, `product_or_parent_id`, `taxonomy`, `term_id`)" +ADD PRIMARY KEY IF NOT EXISTS ( `product_or_parent_id`, `term_id`, `product_id`, `taxonomy` )" ); - // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared + // phpcs:enable WordPress.DB.PreparedSQL + + wc_get_container() + ->get( DatabaseUtil::class ) + ->drop_table_index( $this->lookup_table_name, 'product_or_parent_id_term_id' ); } /** diff --git a/plugins/woocommerce/src/Utilities/DatabaseUtil.php b/plugins/woocommerce/src/Utilities/DatabaseUtil.php index 644102587af..e12540aec23 100644 --- a/plugins/woocommerce/src/Utilities/DatabaseUtil.php +++ b/plugins/woocommerce/src/Utilities/DatabaseUtil.php @@ -70,4 +70,37 @@ class DatabaseUtil { //phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared return $wpdb->query( "DROP TABLE IF EXISTS `{$table_name}`" ); } + + /** + * Drops a table index, if both the table and the index exist. + * + * @param string $table_name The name of the table that contains the index. + * @param string $index_name The name of the index to be dropped. + * @return bool True if the index has been dropped, false if either the table or the index don't exist. + */ + public function drop_table_index( string $table_name, string $index_name ): bool { + global $wpdb; + + // phpcs:disable WordPress.DB.PreparedSQL + + $index_count = intval( + $wpdb->get_var( + " +SELECT COUNT(1) FROM INFORMATION_SCHEMA.STATISTICS +WHERE table_name='$table_name' +AND table_schema='" . DB_NAME . "' +AND index_name='$index_name'" + ) + ); + + if ( 0 === $index_count ) { + return false; + } + + $wpdb->query( "ALTER TABLE $table_name DROP INDEX $index_name" ); + + // phpcs:enable WordPress.DB.PreparedSQL + + return true; + } } From 72e00f9f996a58f6f391c72db10351f62573d8de Mon Sep 17 00:00:00 2001 From: barryhughes <3594411+barryhughes@users.noreply.github.com> Date: Tue, 15 Mar 2022 11:09:24 -0700 Subject: [PATCH 47/53] Minify updated PayPal admin JS. --- .../includes/gateways/paypal/assets/js/paypal-admin.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js b/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js index 24ad8028587..f91eadf31e4 100644 --- a/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js +++ b/plugins/woocommerce/includes/gateways/paypal/assets/js/paypal-admin.min.js @@ -1 +1 @@ -jQuery(function($){'use strict';var wc_paypal_admin={isTestMode:function(){return $('#woocommerce_paypal_testmode').is(':checked')},init:function(){$(document.body).on('change','#woocommerce_paypal_testmode',function(){var test_api_username=$('#woocommerce_paypal_sandbox_api_username').parents('tr').eq(0),test_api_password=$('#woocommerce_paypal_sandbox_api_password').parents('tr').eq(0),test_api_signature=$('#woocommerce_paypal_sandbox_api_signature').parents('tr').eq(0),live_api_username=$('#woocommerce_paypal_api_username').parents('tr').eq(0),live_api_password=$('#woocommerce_paypal_api_password').parents('tr').eq(0),live_api_signature=$('#woocommerce_paypal_api_signature').parents('tr').eq(0);if($(this).is(':checked')){test_api_username.show();test_api_password.show();test_api_signature.show();live_api_username.hide();live_api_password.hide();live_api_signature.hide()}else{test_api_username.hide();test_api_password.hide();test_api_signature.hide();live_api_username.show();live_api_password.show();live_api_signature.show()}});$('#woocommerce_paypal_testmode').change()}};wc_paypal_admin.init()}) \ No newline at end of file +jQuery(function(t){"use strict";(function(){t(document.body).on("change","#woocommerce_paypal_testmode",function(){var e=t("#woocommerce_paypal_sandbox_api_username").parents("tr").eq(0),o=t("#woocommerce_paypal_sandbox_api_password").parents("tr").eq(0),a=t("#woocommerce_paypal_sandbox_api_signature").parents("tr").eq(0),r=t("#woocommerce_paypal_api_username").parents("tr").eq(0),p=t("#woocommerce_paypal_api_password").parents("tr").eq(0),s=t("#woocommerce_paypal_api_signature").parents("tr").eq(0);t(this).is(":checked")?(e.show(),o.show(),a.show(),r.hide(),p.hide(),s.hide()):(e.hide(),o.hide(),a.hide(),r.show(),p.show(),s.show())}),t("#woocommerce_paypal_testmode").trigger("change")})()}); \ No newline at end of file From 80b1ea2b3499de6035de13030a27882e96cf891f Mon Sep 17 00:00:00 2001 From: "Jorge A. Torres" Date: Tue, 15 Mar 2022 14:50:52 -0500 Subject: [PATCH 48/53] Correct "good first issue" link --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a20fb54f898..677999b111b 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -13,7 +13,7 @@ There are many ways to contribute to the project! If you wish to contribute code, please read the information in the sections below. Then [fork](https://help.github.com/articles/fork-a-repo/) WooCommerce, commit your changes, and [submit a pull request](https://help.github.com/articles/using-pull-requests/) 🎉 -We use the `good first issue` label to mark issues that are suitable for new contributors. You can find all the issues with this label [here](https://github.com/woocommerce/woocommerce/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). +We use the `good first issue` label to mark issues that are suitable for new contributors. You can find all the issues with this label [here](https://github.com/woocommerce/woocommerce/issues?q=is%3Aopen+is%3Aissue+label%3A%22type%3A+good+first+issue%22). WooCommerce is licensed under the GPLv3+, and all contributions to the project will be released under the same license. You maintain copyright over any contribution you make, and by submitting a pull request, you are agreeing to release that contribution under the GPLv3+ license. From 8ba55cd021f05dd2d8a1c72ee25c0f052807eb45 Mon Sep 17 00:00:00 2001 From: Shohei Tanaka Date: Thu, 19 Aug 2021 07:26:48 +0900 Subject: [PATCH 49/53] Escape processing missing It was escaped in other email templates, but not here. --- .../templates/emails/plain/customer-refunded-order.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php b/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php index a6626d37165..69fbf7351a8 100644 --- a/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php +++ b/plugins/woocommerce/templates/emails/plain/customer-refunded-order.php @@ -22,7 +22,7 @@ echo esc_html( wp_strip_all_tags( $email_heading ) ); echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n"; /* translators: %s: Customer first name */ -echo sprintf( esc_html__( 'Hi %s,', 'woocommerce' ), $order->get_billing_first_name() ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped +echo sprintf( esc_html__( 'Hi %s,', 'woocommerce' ), esc_html( $order->get_billing_first_name() ) ) . "\n\n"; if ( $partial_refund ) { /* translators: %s: Site title */ echo sprintf( esc_html__( 'Your order on %s has been partially refunded. There are more details below for your reference:', 'woocommerce' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ) . "\n\n"; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped From fc4a71d9b83b03f22743360127f37230864b3a6d Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Wed, 16 Mar 2022 13:18:22 +0100 Subject: [PATCH 50/53] Don't use ADD PRIMARY KEY IF NOT EXISTS as it's not supported by MySQL Instead, manually check if the key exists and create it if not. --- .../DataRegenerator.php | 16 ++----- .../src/Utilities/DatabaseUtil.php | 46 ++++++++++++++++--- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index 47dbcc7c9e1..f6771452b11 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -479,19 +479,9 @@ class DataRegenerator { * @return void */ public function create_table_primary_index() { - global $wpdb; - - // phpcs:disable WordPress.DB.PreparedSQL - $wpdb->query( - " -ALTER TABLE {$this->lookup_table_name} -ADD PRIMARY KEY IF NOT EXISTS ( `product_or_parent_id`, `term_id`, `product_id`, `taxonomy` )" - ); - // phpcs:enable WordPress.DB.PreparedSQL - - wc_get_container() - ->get( DatabaseUtil::class ) - ->drop_table_index( $this->lookup_table_name, 'product_or_parent_id_term_id' ); + $database_util = wc_get_container()->get( DatabaseUtil::class ); + $database_util->create_primary_key( $this->lookup_table_name, array( 'product_or_parent_id', 'term_id', 'product_id', 'taxonomy' ) ); + $database_util->drop_table_index( $this->lookup_table_name, 'product_or_parent_id_term_id' ); } /** diff --git a/plugins/woocommerce/src/Utilities/DatabaseUtil.php b/plugins/woocommerce/src/Utilities/DatabaseUtil.php index e12540aec23..e1c67595a2a 100644 --- a/plugins/woocommerce/src/Utilities/DatabaseUtil.php +++ b/plugins/woocommerce/src/Utilities/DatabaseUtil.php @@ -81,6 +81,44 @@ class DatabaseUtil { public function drop_table_index( string $table_name, string $index_name ): bool { global $wpdb; + if ( ! $this->index_exists( $table_name, $index_name ) ) { + return false; + } + + // phpcs:ignore WordPress.DB.PreparedSQL + $wpdb->query( "ALTER TABLE $table_name DROP INDEX $index_name" ); + return true; + } + + /** + * Create a primary key for a table, only if the table doesn't have a primary key already. + * + * @param string $table_name Table name. + * @param array $columns An array with the index column names. + * @return bool True if the key has been created, false if the table already had a primary key. + */ + public function create_primary_key( string $table_name, array $columns ) { + global $wpdb; + + if ( $this->index_exists( $table_name, 'PRIMARY' ) ) { + return false; + } + + // phpcs:ignore WordPress.DB.PreparedSQL + $wpdb->query( "ALTER TABLE $table_name ADD PRIMARY KEY(`" . join( '`,`', $columns ) . '`)' ); + return true; + } + + /** + * Does a given index exist for a given table? + * + * @param string $table_name Table name. + * @param string $index_name Index name, or "PRIMARY" for the primary index. + * @return bool + */ + private function index_exists( string $table_name, string $index_name ): bool { + global $wpdb; + // phpcs:disable WordPress.DB.PreparedSQL $index_count = intval( @@ -93,14 +131,8 @@ AND index_name='$index_name'" ) ); - if ( 0 === $index_count ) { - return false; - } - - $wpdb->query( "ALTER TABLE $table_name DROP INDEX $index_name" ); + return 0 !== $index_count; // phpcs:enable WordPress.DB.PreparedSQL - - return true; } } From 76deb8b6a1d46961b8faaeb3904d28a24b7e9336 Mon Sep 17 00:00:00 2001 From: Tam Mullen Date: Wed, 16 Mar 2022 15:43:49 +0000 Subject: [PATCH 51/53] Include link to e2e boilerplate in e2e Readme --- plugins/woocommerce/tests/e2e/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/woocommerce/tests/e2e/README.md b/plugins/woocommerce/tests/e2e/README.md index 6ca2c9a3b14..4ecb3d44d54 100644 --- a/plugins/woocommerce/tests/e2e/README.md +++ b/plugins/woocommerce/tests/e2e/README.md @@ -26,6 +26,7 @@ Automated end-to-end tests for WooCommerce. - [Creating test structure](#creating-test-structure) - [Writing the test](#writing-the-test) - [Best practices](#best-practices) + - [Writing tests for WooCommerce extensions](#Writing-tests-for-WooCommerce-extensions) - [Debugging tests](#debugging-tests) ## Pre-requisites @@ -371,6 +372,12 @@ FAIL ../specs/front-end/front-end-my-account.test.js (9.219s) In the example above, you can see that `allows customer to see downloads` part of the test failed and can start looking at it right away. Without steps the test goes through being detailed, it is more difficult to debug it. +### Writing tests for WooCommerce extensions + +If you want to set up E2E tests for your WooCommerce extension you can make use of the default WooCommerce E2E package. + +The [WooCommerce E2E Tests Boilerplate repo](https://github.com/woocommerce/woocommerce-e2e-boilerplate) aims to provide a stripped down version of the default WooCommerce E2E test suite along with basic set up instructions to get started. + ## Debugging tests The test sequencer (`pnpm nx test-e2e woocommerce`) includes support for saving [screenshots on test errors](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/e2e-environment#test-screenshots) which can be sent to a Slack channel via a [Slackbot](https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/e2e-environment#slackbot-setup). From ad55634ea5706267c1dadbae7b4a09b0bef7a934 Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Thu, 17 Mar 2022 09:31:26 +0100 Subject: [PATCH 52/53] Add error logging to DataRegenerator::create_table_primary_index --- .../DataRegenerator.php | 8 ++++++ .../src/Utilities/DatabaseUtil.php | 28 +++++++++---------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index f6771452b11..6b949c510fc 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -482,6 +482,14 @@ class DataRegenerator { $database_util = wc_get_container()->get( DatabaseUtil::class ); $database_util->create_primary_key( $this->lookup_table_name, array( 'product_or_parent_id', 'term_id', 'product_id', 'taxonomy' ) ); $database_util->drop_table_index( $this->lookup_table_name, 'product_or_parent_id_term_id' ); + + if ( empty( $database_util->get_index_columns( $this->lookup_table_name ) ) ) { + wc_get_logger()->error( "The creation of the primary key for the {$this->lookup_table_name} table failed" ); + } + + if ( ! empty( $database_util->get_index_columns( $this->lookup_table_name, 'product_or_parent_id_term_id' ) ) ) { + wc_get_logger()->error( "Dropping the product_or_parent_id_term_id index from the {$this->lookup_table_name} table failed" ); + } } /** diff --git a/plugins/woocommerce/src/Utilities/DatabaseUtil.php b/plugins/woocommerce/src/Utilities/DatabaseUtil.php index e1c67595a2a..526edd41007 100644 --- a/plugins/woocommerce/src/Utilities/DatabaseUtil.php +++ b/plugins/woocommerce/src/Utilities/DatabaseUtil.php @@ -81,7 +81,7 @@ class DatabaseUtil { public function drop_table_index( string $table_name, string $index_name ): bool { global $wpdb; - if ( ! $this->index_exists( $table_name, $index_name ) ) { + if ( empty( $this->get_index_columns( $table_name, $index_name ) ) ) { return false; } @@ -100,7 +100,7 @@ class DatabaseUtil { public function create_primary_key( string $table_name, array $columns ) { global $wpdb; - if ( $this->index_exists( $table_name, 'PRIMARY' ) ) { + if ( ! empty( $this->get_index_columns( $table_name ) ) ) { return false; } @@ -110,29 +110,27 @@ class DatabaseUtil { } /** - * Does a given index exist for a given table? + * Get the columns of a given table index, or of the primary key. * * @param string $table_name Table name. - * @param string $index_name Index name, or "PRIMARY" for the primary index. - * @return bool + * @param string $index_name Index name, empty string for the primary key. + * @return array The index columns. Empty array if the table or the index don't exist. */ - private function index_exists( string $table_name, string $index_name ): bool { + public function get_index_columns( string $table_name, string $index_name = '' ): array { global $wpdb; - // phpcs:disable WordPress.DB.PreparedSQL + if ( empty( $index_name ) ) { + $index_name = 'PRIMARY'; + } - $index_count = intval( - $wpdb->get_var( - " -SELECT COUNT(1) FROM INFORMATION_SCHEMA.STATISTICS + // phpcs:disable WordPress.DB.PreparedSQL + return $wpdb->get_col( + " +SELECT column_name FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='$table_name' AND table_schema='" . DB_NAME . "' AND index_name='$index_name'" - ) ); - - return 0 !== $index_count; - // phpcs:enable WordPress.DB.PreparedSQL } } From b662d2b450a7d5fdf3c4a8a5038dd297f819f763 Mon Sep 17 00:00:00 2001 From: 9ete Date: Thu, 30 Sep 2021 15:58:08 -0700 Subject: [PATCH 53/53] fix/30156: prevent 'Search' field from overflowing container on the 'Downloadable product permissions' widget when in the sidebar on the admin order detail page --- plugins/woocommerce/legacy/css/admin.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/woocommerce/legacy/css/admin.scss b/plugins/woocommerce/legacy/css/admin.scss index 38b751a93cb..9fc9be88f16 100644 --- a/plugins/woocommerce/legacy/css/admin.scss +++ b/plugins/woocommerce/legacy/css/admin.scss @@ -2426,6 +2426,14 @@ ul.wc_coupon_list_block { } } +#side-sortables #woocommerce-order-downloads { + + .buttons, + .select2-container { + max-width: 100%; + } +} + #poststuff #woocommerce-order-actions .inside { margin: 0; padding: 0;
get_error_message() ); ?>get_error_message() ); ?>