diff --git a/assets/js/editor-components/feedback-prompt/index.tsx b/assets/js/editor-components/feedback-prompt/index.tsx index 44487defd1e..c9400e25a36 100644 --- a/assets/js/editor-components/feedback-prompt/index.tsx +++ b/assets/js/editor-components/feedback-prompt/index.tsx @@ -12,7 +12,7 @@ import './style.scss'; interface FeedbackPromptProps { text: string; title?: string; - url?: string; + url: string; } /** * Component to render a Feedback prompt in the sidebar. @@ -25,7 +25,7 @@ interface FeedbackPromptProps { const FeedbackPrompt = ( { text, title = __( 'Feedback?', 'woo-gutenberg-products-block' ), - url = 'https://ideas.woocommerce.com/forums/133476-woocommerce?category_id=384565', + url, }: FeedbackPromptProps ) => { // By returning false we ensure that this component is not entered into the InspectorControls // (which is a slot fill), children array on first render, on the second render when the state @@ -71,17 +71,7 @@ export const CartCheckoutFeedbackPrompt = () => ( 'We are currently working on improving our cart and checkout blocks to provide merchants with the tools and customization options they need.', 'woo-gutenberg-products-block' ) } - url="https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/new?template=--cart-checkout-feedback.md" - /> -); - -export const LegacyFeedbackPrompt = () => ( - ); diff --git a/assets/js/extensions/jetpack/woocommerce-analytics/constants.ts b/assets/js/extensions/jetpack/woocommerce-analytics/constants.ts deleted file mode 100644 index 88fa51b8a6a..00000000000 --- a/assets/js/extensions/jetpack/woocommerce-analytics/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const namespace = 'jetpack-woocommerce-analytics'; -export const actionPrefix = 'experimental__woocommerce_blocks'; diff --git a/assets/js/extensions/jetpack/woocommerce-analytics/index.ts b/assets/js/extensions/jetpack/woocommerce-analytics/index.ts deleted file mode 100644 index db84f07861c..00000000000 --- a/assets/js/extensions/jetpack/woocommerce-analytics/index.ts +++ /dev/null @@ -1,185 +0,0 @@ -/** - * External dependencies - */ -import { Cart, isObject, objectHasProp } from '@woocommerce/types'; -import { select } from '@wordpress/data'; -import { getSetting } from '@woocommerce/settings'; - -/** - * Internal dependencies - */ -import { STORE_KEY as CART_STORE_KEY } from '../../../data/cart/constants'; - -declare global { - interface Window { - // eslint-disable-next-line @typescript-eslint/naming-convention - _wca: { - // eslint-disable-next-line @typescript-eslint/ban-types - push: ( properties: Record< string, unknown > ) => void; - }; - } -} - -interface StorePageDetails { - id: number; - title: string; - permalink: string; -} - -interface StorePages { - checkout: StorePageDetails; - cart: StorePageDetails; - myaccount: StorePageDetails; - privacy: StorePageDetails; - shop: StorePageDetails; - terms: StorePageDetails; -} - -/** - * Check if the _wca object is valid and has a push property that is a function. - * - * @param wca {unknown} Object that might be a Jetpack WooCommerce Analytics object. - */ -// eslint-disable-next-line @typescript-eslint/ban-types -const isValidWCA = ( - wca: unknown -): wca is { push: ( properties: Record< string, unknown > ) => void } => { - if ( ! isObject( wca ) || ! objectHasProp( wca, 'push' ) ) { - return false; - } - return typeof wca.push === 'function'; -}; - -const registerActions = (): void => { - if ( ! isValidWCA( window._wca ) ) { - // eslint-disable-next-line no-useless-return - return; - } - - // We will register actions here in a later PR. -}; - -document.addEventListener( 'DOMContentLoaded', () => { - registerActions(); -} ); - -export const cleanUrl = ( link: string ) => { - const url = link.split( '?' )[ 0 ]; - if ( url.charAt( url.length - 1 ) !== '/' ) { - return url + '/'; - } - return url; -}; - -const maybeTrackCheckoutPageView = ( cart: Cart ) => { - const storePages = getSetting< StorePages >( 'storePages', {} ); - if ( ! objectHasProp( storePages, 'checkout' ) ) { - return; - } - - if ( - cleanUrl( storePages?.checkout?.permalink ) !== - cleanUrl( window.location.href ) - ) { - return; - } - - if ( ! isValidWCA( window._wca ) ) { - return; - } - - const checkoutData = getSetting< Record< string, unknown > >( - 'wc-blocks-jetpack-woocommerce-analytics_cart_checkout_info', - {} - ); - - window._wca.push( { - _en: 'woocommerceanalytics_checkout_view', - products_count: cart.items.length, - order_value: cart.totals.total_price, - products: JSON.stringify( - cart.items.map( ( item ) => { - return { - pp: item.totals.line_total, - pq: item.quantity, - pi: item.id, - pn: item.name, - }; - } ) - ), - ...checkoutData, - } ); -}; - -const maybeTrackCartPageView = ( cart: Cart ) => { - const storePages = getSetting< StorePages >( 'storePages', {} ); - if ( ! objectHasProp( storePages, 'cart' ) ) { - return; - } - - if ( - cleanUrl( storePages?.cart?.permalink ) !== - cleanUrl( window.location.href ) - ) { - return; - } - - if ( ! isValidWCA( window._wca ) ) { - return; - } - - const checkoutData = getSetting< Record< string, unknown > >( - 'wc-blocks-jetpack-woocommerce-analytics_cart_checkout_info', - {} - ); - - window._wca.push( { - _en: 'woocommerceanalytics_cart_view', - products_count: cart.items.length, - order_value: cart.totals.total_price, - products: JSON.stringify( - cart.items.map( ( item ) => { - return { - pp: item.totals.line_total, - pq: item.quantity, - pi: item.id, - pn: item.name, - pt: item.type, - }; - } ) - ), - ...checkoutData, - } ); -}; - -const maybeTrackOrderReceivedPageView = () => { - const orderReceivedProps = getSetting( - 'wc-blocks-jetpack-woocommerce-analytics_order_received_properties', - false - ); - - if ( ! orderReceivedProps || ! isValidWCA( window._wca ) ) { - return; - } - - window._wca.push( { - _en: 'woocommerceanalytics_order_confirmation_view', - ...orderReceivedProps, - } ); -}; - -document.addEventListener( 'DOMContentLoaded', () => { - const store = select( CART_STORE_KEY ); - - // If the store doesn't load, we aren't on a cart/checkout block page, so maybe it's order received page. - if ( ! store ) { - maybeTrackOrderReceivedPageView(); - return; - } - - const hasCartLoaded = store.hasFinishedResolution( 'getCartTotals' ); - if ( hasCartLoaded ) { - maybeTrackCartPageView( store.getCartData() ); - maybeTrackCheckoutPageView( store.getCartData() ); - } -} ); diff --git a/assets/js/extensions/jetpack/woocommerce-analytics/test/index.ts b/assets/js/extensions/jetpack/woocommerce-analytics/test/index.ts deleted file mode 100644 index 4f4048c95b6..00000000000 --- a/assets/js/extensions/jetpack/woocommerce-analytics/test/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Internal dependencies - */ -import { cleanUrl } from '../index'; - -describe( 'WooCommerce Analytics', () => { - describe( 'cleanUrl', () => { - it( 'returns a clean URL with a trailing slash', () => { - expect( cleanUrl( 'https://test.com?test=1' ) ).toEqual( - 'https://test.com/' - ); - expect( cleanUrl( '' ) ).toEqual( '/' ); - expect( cleanUrl( 'https://test.com/' ) ).toEqual( - 'https://test.com/' - ); - expect( cleanUrl( 'https://test.com' ) ).toEqual( - 'https://test.com/' - ); - } ); - } ); -} ); diff --git a/bin/webpack-entries.js b/bin/webpack-entries.js index 6e23e4beb52..105cb32e99e 100644 --- a/bin/webpack-entries.js +++ b/bin/webpack-entries.js @@ -238,8 +238,6 @@ const entries = { './assets/js/extensions/google-analytics/index.ts', 'wc-shipping-method-pickup-location': './assets/js/extensions/shipping-methods/pickup-location/index.js', - 'wc-blocks-jetpack-woocommerce-analytics': - './assets/js/extensions/jetpack/woocommerce-analytics/index.ts', }, editor: { 'wc-blocks-classic-template-revert-button': diff --git a/composer.json b/composer.json index a43aa558267..7a88bc5c0ab 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "WooCommerce blocks for the Gutenberg editor.", "homepage": "https://woocommerce.com/", "type": "wordpress-plugin", - "version": "11.6.1", + "version": "11.6.2", "keywords": [ "gutenberg", "woocommerce", diff --git a/composer.lock b/composer.lock index 8ec8edd8763..529b68f6b87 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c0c84c60784dac89f2eb3425d7f423e7", + "content-hash": "38946ab8ac8f160ec94a4d2f32c752a2", "packages": [ { "name": "automattic/jetpack-a8c-mc-stats", diff --git a/docs/internal-developers/testing/releases/1162.md b/docs/internal-developers/testing/releases/1162.md new file mode 100644 index 00000000000..5e9c7d36c4c --- /dev/null +++ b/docs/internal-developers/testing/releases/1162.md @@ -0,0 +1,13 @@ +# Testing notes and ZIP for release 11.6.2 + +Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/13545737/woocommerce-gutenberg-products-block.zip) + +## Testing Notes + +### Update the "Give us your feedback" link to point to the WooCommerce repo discussions. [#11999](https://github.com/woocommerce/woocommerce-blocks/pull/11999) [#12006](https://github.com/woocommerce/woocommerce-blocks/pull/12006) + +1. Create pages and add the Cart Block and Checkout block +2. Select each of those blocks +3. Verify that the Give us your feedback link (see printscreen) now directs to [https://github.com/woocommerce/woocommerce/discussions/new?category=checkout-flow&labels=type%3A+product%20feedback](https://github.com/woocommerce/woocommerce/discussions/new?category=checkout-flow&labels=type%3A+product%20feedback). + +Feedback diff --git a/docs/internal-developers/testing/releases/README.md b/docs/internal-developers/testing/releases/README.md index cfef07759c1..0164d23e0dc 100644 --- a/docs/internal-developers/testing/releases/README.md +++ b/docs/internal-developers/testing/releases/README.md @@ -196,3 +196,4 @@ Every release includes specific testing instructions for new features and bug fi - [11.5.4](./1154.md) - [11.6.0](./1160.md) - [11.6.1](./1161.md) + - [11.6.2](./1162.md) diff --git a/package-lock.json b/package-lock.json index 42a48a66143..41eda5f2588 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@woocommerce/block-library", - "version": "11.6.1", + "version": "11.6.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@woocommerce/block-library", - "version": "11.6.1", + "version": "11.6.2", "hasInstallScript": true, "license": "GPL-3.0+", "dependencies": { diff --git a/package.json b/package.json index 48eeff865a4..ddec2bc6312 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@woocommerce/block-library", "title": "WooCommerce Blocks", "author": "Automattic", - "version": "11.6.1", + "version": "11.6.2", "description": "WooCommerce blocks for the Gutenberg editor.", "homepage": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/", "keywords": [ diff --git a/readme.txt b/readme.txt index 2a120843056..0eee42d4456 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: gutenberg, woocommerce, woo commerce, products, blocks, woocommerce blocks Requires at least: 6.4 Tested up to: 6.4 Requires PHP: 7.4 -Stable tag: 11.6.1 +Stable tag: 11.6.2 License: GPLv3 License URI: https://www.gnu.org/licenses/gpl-3.0.html @@ -81,6 +81,12 @@ Release and roadmap notes available on the [WooCommerce Developers Blog](https:/ == Changelog == += 11.6.2 - 2023-12-01 = + +#### Enhancements + +- Update the "Give us your feedback" link to point to the WooCommerce repo discussions. [#11999](https://github.com/woocommerce/woocommerce-blocks/pull/11999) [#12006](https://github.com/woocommerce/woocommerce-blocks/pull/12006) + = 11.6.1 - 2023-11-23 = #### Bug Fixes diff --git a/src/Domain/Bootstrap.php b/src/Domain/Bootstrap.php index 58b1f13ac0e..4b40fd32ee6 100644 --- a/src/Domain/Bootstrap.php +++ b/src/Domain/Bootstrap.php @@ -8,7 +8,6 @@ use Automattic\WooCommerce\Blocks\BlockTemplatesController; use Automattic\WooCommerce\Blocks\BlockTypesController; use Automattic\WooCommerce\Blocks\Domain\Services\CreateAccount; -use Automattic\WooCommerce\Blocks\Domain\Services\JetpackWooCommerceAnalytics; use Automattic\WooCommerce\Blocks\Domain\Services\Notices; use Automattic\WooCommerce\Blocks\Domain\Services\DraftOrders; use Automattic\WooCommerce\Blocks\Domain\Services\FeatureGating; @@ -132,7 +131,6 @@ function() { $this->container->get( CreateAccount::class )->init(); $this->container->get( ShippingController::class )->init(); $this->container->get( TasksController::class )->init(); - $this->container->get( JetpackWooCommerceAnalytics::class )->init(); // Load assets in admin and on the frontend. if ( ! $is_rest ) { @@ -366,15 +364,6 @@ function( Container $container ) { return new GoogleAnalytics( $asset_api ); } ); - $this->container->register( - JetpackWooCommerceAnalytics::class, - function( Container $container ) { - $asset_api = $container->get( AssetApi::class ); - $asset_data_registry = $container->get( AssetDataRegistry::class ); - $block_templates_controller = $container->get( BlockTemplatesController::class ); - return new JetpackWooCommerceAnalytics( $asset_api, $asset_data_registry, $block_templates_controller ); - } - ); $this->container->register( Notices::class, function( Container $container ) { diff --git a/src/Domain/Services/JetpackWooCommerceAnalytics.php b/src/Domain/Services/JetpackWooCommerceAnalytics.php deleted file mode 100644 index 4b0e320a3db..00000000000 --- a/src/Domain/Services/JetpackWooCommerceAnalytics.php +++ /dev/null @@ -1,400 +0,0 @@ -asset_api = $asset_api; - $this->asset_data_registry = $asset_data_registry; - $this->block_templates_controller = $block_templates_controller; - } - - /** - * Hook into WP. - */ - public function init() { - add_action( 'init', array( $this, 'check_compatibility' ) ); - add_action( 'rest_pre_serve_request', array( $this, 'track_local_pickup' ), 10, 4 ); - - $is_rest = wc()->is_rest_api_request(); - if ( ! $is_rest ) { - add_action( 'init', array( $this, 'init_if_compatible' ), 20 ); - } - } - - /** - * Gets product categories or varation attributes as a formatted concatenated string - * - * @param object $product WC_Product. - * @return string - */ - public function get_product_categories_concatenated( $product ) { - - if ( ! $product instanceof WC_Product ) { - return ''; - } - - $variation_data = $product->is_type( 'variation' ) ? wc_get_product_variation_attributes( $product->get_id() ) : ''; - if ( is_array( $variation_data ) && ! empty( $variation_data ) ) { - $line = wc_get_formatted_variation( $variation_data, true ); - } else { - $out = array(); - $categories = get_the_terms( $product->get_id(), 'product_cat' ); - if ( $categories ) { - foreach ( $categories as $category ) { - $out[] = $category->name; - } - } - $line = implode( '/', $out ); - } - return $line; - } - - /** - * Gather relevant product information. Taken from Jetpack WooCommerce Analytics Module. - * - * @param \WC_Product $product product. - * @return array - */ - public function get_product_details( $product ) { - return array( - 'id' => $product->get_id(), - 'name' => $product->get_title(), - 'category' => $this->get_product_categories_concatenated( $product ), - 'price' => $product->get_price(), - 'type' => $product->get_type(), - ); - } - - /** - * Save the order received page view event properties to the asset data registry. The front end will consume these - * later. - * - * @param int $order_id The order ID. - * - * @return void - */ - public function output_order_received_page_view_properties( $order_id ) { - $order = wc_get_order( $order_id ); - $product_data = wp_json_encode( - array_map( - function( $item ) { - $product = wc_get_product( $item->get_product_id() ); - $product_details = $this->get_product_details( $product ); - return array( - 'pi' => $product_details['id'], - 'pq' => $item->get_quantity(), - 'pt' => $product_details['type'], - 'pn' => $product_details['name'], - 'pc' => $product_details['category'], - 'pp' => $product_details['price'], - ); - }, - $order->get_items() - ) - ); - - $properties = $this->get_cart_checkout_info(); - $properties['products'] = $product_data; - $this->asset_data_registry->add( 'wc-blocks-jetpack-woocommerce-analytics_order_received_properties', $properties ); - } - - /** - * Check compatibility with Jetpack WooCommerce Analytics. - * - * @return void - */ - public function check_compatibility() { - // Require Jetpack WooCommerce Analytics to be available. - $this->is_compatible = class_exists( 'Jetpack_WooCommerce_Analytics_Universal', false ) && - class_exists( 'Jetpack_WooCommerce_Analytics', false ) && - \Jetpack_WooCommerce_Analytics::should_track_store(); - } - - /** - * Initialize if compatible. - */ - public function init_if_compatible() { - if ( ! $this->is_compatible ) { - return; - } - $this->register_assets(); - add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); - add_action( 'wp_enqueue_scripts', array( $this, 'register_script_data' ) ); - add_action( 'woocommerce_thankyou', array( $this, 'output_order_received_page_view_properties' ) ); - } - - /** - * Register scripts. - */ - public function register_assets() { - if ( ! $this->is_compatible ) { - return; - } - $asset_file = include Package::get_path() . 'build/wc-blocks-jetpack-woocommerce-analytics.asset.php'; - if ( is_array( $asset_file['dependencies'] ) ) { - $this->asset_api->register_script( 'wc-blocks-jetpack-woocommerce-analytics', 'build/wc-blocks-jetpack-woocommerce-analytics.js', array_merge( array( 'wc-blocks' ), $asset_file['dependencies'] ) ); - } - } - - /** - * Enqueue the Google Tag Manager script if prerequisites are met. - */ - public function enqueue_scripts() { - // Additional check here before finally enqueueing the scripts. Done late here because checking these earlier fails. - if ( ! is_cart() && ! is_checkout() ) { - return; - } - wp_enqueue_script( 'wc-blocks-jetpack-woocommerce-analytics' ); - } - - /** - * Enqueue the Google Tag Manager script if prerequisites are met. - */ - public function register_script_data() { - $this->asset_data_registry->add( 'wc-blocks-jetpack-woocommerce-analytics_cart_checkout_info', $this->get_cart_checkout_info() ); - } - - /** - * Get the current user id - * - * @return int - */ - private function get_user_id() { - if ( is_user_logged_in() ) { - $blogid = \Jetpack::get_option( 'id' ); - $userid = get_current_user_id(); - return $blogid . ':' . $userid; - } - return 'null'; - } - - /** - * Default event properties which should be included with all events. - * - * @return array Array of standard event props. - */ - public function get_common_properties() { - if ( ! class_exists( 'Jetpack' ) || ! is_callable( array( 'Jetpack', 'get_option' ) ) ) { - return array(); - } - return array( - 'blog_id' => \Jetpack::get_option( 'id' ), - 'ui' => $this->get_user_id(), - 'url' => home_url(), - 'woo_version' => WC()->version, - ); - } - - /** - * Get info about the cart & checkout pages, in particular whether the store is using shortcodes or Gutenberg blocks. - * This info is cached in a transient. - * - * @return array - */ - public function get_cart_checkout_info() { - $transient_name = 'woocommerce_blocks_jetpack_woocommerce_analytics_cart_checkout_info_cache'; - - $info = get_transient( $transient_name ); - - // Return cached data early to prevent additional processing, the transient lasts for 1 day. - if ( false !== $info ) { - return $info; - } - - $cart_template = null; - $checkout_template = null; - $cart_template_id = null; - $checkout_template_id = null; - $templates = $this->block_templates_controller->get_block_templates( array( 'cart', 'checkout', 'page-checkout', 'page-cart' ) ); - $guest_checkout = ucfirst( get_option( 'woocommerce_enable_guest_checkout', 'No' ) ); - $create_account = ucfirst( get_option( 'woocommerce_enable_signup_and_login_from_checkout', 'No' ) ); - - foreach ( $templates as $template ) { - if ( 'cart' === $template->slug || 'page-cart' === $template->slug ) { - $cart_template_id = ( $template->id ); - continue; - } - if ( 'checkout' === $template->slug || 'page-checkout' === $template->slug ) { - $checkout_template_id = ( $template->id ); - } - } - - // Get the template and its contents from the IDs we found above. - if ( function_exists( 'get_block_template' ) ) { - $cart_template = get_block_template( $cart_template_id ); - $checkout_template = get_block_template( $checkout_template_id ); - } - - if ( function_exists( 'gutenberg_get_block_template' ) ) { - $cart_template = get_block_template( $cart_template_id ); - $checkout_template = get_block_template( $checkout_template_id ); - } - - // Something failed with the template retrieval, return early with 0 values rather than let a warning appear. - if ( ! $cart_template || ! $checkout_template ) { - return array( - 'cart_page_contains_cart_block' => 0, - 'cart_page_contains_cart_shortcode' => 0, - 'checkout_page_contains_checkout_block' => 0, - 'checkout_page_contains_checkout_shortcode' => 0, - ); - } - - // Update the info transient with data we got from the templates, if the site isn't using WC Blocks we - // won't be doing this so no concern about overwriting. - // Sites that load this code will be loading it on a page using the relevant block, but we still need to check - // the other page to see if it's using the block or shortcode. - $info = array( - 'cart_page_contains_cart_block' => str_contains( $cart_template->content, '