From a56d57a0cc393e74fa141059adffc1194cf1a13e Mon Sep 17 00:00:00 2001 From: Alefe Souza Date: Mon, 19 Aug 2024 12:12:52 -0300 Subject: [PATCH] Fix tracks identity cookie cache (#9249) --- changelog/fix-wcpay-tracking-cookie-cache | 4 ++ client/frontend-tracks/index.js | 12 +++++ client/payment-methods-map.tsx | 4 ++ client/tracks/index.ts | 1 + includes/class-woopay-tracker.php | 59 +++++++++++++++++++++-- webpack/shared.js | 1 + 6 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 changelog/fix-wcpay-tracking-cookie-cache create mode 100644 client/frontend-tracks/index.js diff --git a/changelog/fix-wcpay-tracking-cookie-cache b/changelog/fix-wcpay-tracking-cookie-cache new file mode 100644 index 00000000000..e0f40c40a19 --- /dev/null +++ b/changelog/fix-wcpay-tracking-cookie-cache @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Fix caching with tracking cookie. diff --git a/client/frontend-tracks/index.js b/client/frontend-tracks/index.js new file mode 100644 index 00000000000..33d13c3321b --- /dev/null +++ b/client/frontend-tracks/index.js @@ -0,0 +1,12 @@ +/** + * Internal dependencies + */ +import { recordUserEvent } from 'tracks'; + +if ( window.wcPayFrontendTracks && window.wcPayFrontendTracks.length ) { + for ( const track of window.wcPayFrontendTracks ) { + recordUserEvent( track.event, track.properties ); + } + + window.wcPayFrontendTracks = []; +} diff --git a/client/payment-methods-map.tsx b/client/payment-methods-map.tsx index 10b96f5d527..1f5e1a9a9cf 100644 --- a/client/payment-methods-map.tsx +++ b/client/payment-methods-map.tsx @@ -31,6 +31,10 @@ declare global { country: string; }; }; + wcPayFrontendTracks: { + event: string; + properties: Record< string, unknown >; + }; } } diff --git a/client/tracks/index.ts b/client/tracks/index.ts index d3f14dd57b3..5648493c46a 100644 --- a/client/tracks/index.ts +++ b/client/tracks/index.ts @@ -125,6 +125,7 @@ export const getTracksIdentity = async (): Promise< string | undefined > => { body.append( 'tracksNonce', nonce ); body.append( 'action', 'get_identity' ); + try { const response = await fetch( ajaxUrl, { method: 'post', diff --git a/includes/class-woopay-tracker.php b/includes/class-woopay-tracker.php index 75ca5ecf3bc..22c5a82057c 100644 --- a/includes/class-woopay-tracker.php +++ b/includes/class-woopay-tracker.php @@ -73,6 +73,7 @@ public function __construct( $http ) { add_action( 'woocommerce_checkout_order_processed', [ $this, 'checkout_order_processed' ], 10, 2 ); add_action( 'woocommerce_store_api_checkout_order_processed', [ $this, 'checkout_order_processed' ], 10, 2 ); add_action( 'woocommerce_payments_save_user_in_woopay', [ $this, 'must_save_payment_method_to_platform' ] ); + add_action( 'wp_footer', [ $this, 'add_frontend_tracks_scripts' ] ); add_action( 'before_woocommerce_pay_form', [ $this, 'pay_for_order_page_view' ] ); add_action( 'woocommerce_thankyou', [ $this, 'thank_you_page_view' ] ); } @@ -144,8 +145,9 @@ public function maybe_record_event( $event, $data = [] ) { * * @param string $event name of the event. * @param array $data array of event properties. + * @param bool $record_on_frontend whether to record the event on the frontend to prevent cache break. */ - public function maybe_record_wcpay_shopper_event( $event, $data = [] ) { + public function maybe_record_wcpay_shopper_event( $event, $data = [], $record_on_frontend = true ) { // Top level events should not be namespaced. if ( '_aliasUser' !== $event ) { $event = self::$user_prefix . '_' . $event; @@ -154,7 +156,23 @@ public function maybe_record_wcpay_shopper_event( $event, $data = [] ) { $is_admin_event = false; $track_on_all_stores = true; - return $this->tracks_record_event( $event, $data, $is_admin_event, $track_on_all_stores ); + if ( ! $record_on_frontend ) { + return $this->tracks_record_event( $event, $data, $is_admin_event, $track_on_all_stores ); + } + + $data['record_event_data'] = compact( 'is_admin_event', 'track_on_all_stores' ); + + add_filter( + 'wcpay_frontend_tracks', + function ( $tracks ) use ( $event, $data ) { + $tracks[] = [ + 'event' => $event, + 'properties' => $data, + ]; + + return $tracks; + } + ); } /** @@ -275,6 +293,18 @@ public function tracks_record_event( $event_name, $properties = [], $is_admin_ev return false; } + if ( isset( $properties['record_event_data'] ) ) { + if ( isset( $properties['record_event_data']['is_admin_event'] ) ) { + $is_admin_event = $properties['record_event_data']['is_admin_event']; + } + + if ( isset( $properties['record_event_data']['track_on_all_stores'] ) ) { + $track_on_all_stores = $properties['record_event_data']['track_on_all_stores']; + } + + unset( $properties['record_event_data'] ); + } + if ( ! $this->should_enable_tracking( $is_admin_event, $track_on_all_stores ) ) { return false; } @@ -519,7 +549,7 @@ public function checkout_order_processed( $order_id ) { // Don't track WooPay orders. They will be tracked on WooPay side with more details. if ( ! $is_woopay_order ) { - $this->maybe_record_wcpay_shopper_event( 'checkout_order_placed', $properties ); + $this->maybe_record_wcpay_shopper_event( 'checkout_order_placed', $properties, false ); } // If the order was placed using a different payment gateway, just increment a counter. } else { @@ -576,4 +606,27 @@ public function woopay_locations_updated( $all_locations, $platform_checkout_ena $this->maybe_record_admin_event( 'woopay_express_button_locations_updated', $props ); } + + /** + * Add front-end tracks scripts to prevent cache break. + * + * @return void + */ + public function add_frontend_tracks_scripts() { + $frontent_tracks = apply_filters( 'wcpay_frontend_tracks', [] ); + + if ( count( $frontent_tracks ) === 0 ) { + return; + } + + WC_Payments::register_script_with_dependencies( 'wcpay-frontend-tracks', 'dist/frontend-tracks' ); + + wp_enqueue_script( 'wcpay-frontend-tracks' ); + + wp_localize_script( + 'wcpay-frontend-tracks', + 'wcPayFrontendTracks', + $frontent_tracks + ); + } } diff --git a/webpack/shared.js b/webpack/shared.js index 953830ba44f..7ef039967cd 100644 --- a/webpack/shared.js +++ b/webpack/shared.js @@ -41,6 +41,7 @@ module.exports = { 'product-details': './client/product-details/index.js', 'cart-block': './client/cart/blocks/index.js', 'plugins-page': './client/plugins-page/index.js', + 'frontend-tracks': './client/frontend-tracks/index.js', }, // Override webpack public path dynamically on every entry. // Required for chunks loading to work on sites with JS concatenation.