Skip to content

Commit

Permalink
Merge branch 'remove-universal-analytics' into add/consent-mode-v0
Browse files Browse the repository at this point in the history
  • Loading branch information
tomalec committed Feb 29, 2024
2 parents 6d1a82c + c4e9ebc commit 1bdf0b6
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 50 deletions.
14 changes: 2 additions & 12 deletions assets/js/src/config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
/* global wcgaiData */
/* eslint-disable camelcase */
export const {
config,
events,
cart,
products,
product,
added_to_cart: addedToCart,
order,
} = wcgaiData;

/* global wcgai */
export const config = wcgai.config;
export const EEARegions = [
'AT',
'BE',
Expand Down
4 changes: 2 additions & 2 deletions assets/js/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Initialize tracking for classic WooCommerce pages
import { trackClassicIntegration } from './integrations/classic';
trackClassicIntegration();
import { trackClassicPages } from './integrations/classic';
window.wcgai.trackClassicPages = trackClassicPages;

// Initialize tracking for Block based WooCommerce pages
import './integrations/blocks';
56 changes: 36 additions & 20 deletions assets/js/src/integrations/classic.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
import { tracker } from '../tracker';
import { getProductFromID } from '../utils';
import {
events,
cart,
products,
product,
addedToCart,
order,
} from '../config.js';

/**
* The Google Analytics integration for classic WooCommerce pages
* triggers events using three different methods.
*
* 1. Automatically handle events listed in the global `wcgaiData.events` object.
* 1. Instantly handle events listed in the `events` object.
* 2. Listen for custom events from WooCommerce core.
* 3. Listen for various actions (i.e clicks) on specific elements.
*
* To be executed once data set is complete, and `document` is ready.
*
* @param {Object} data - The tracking data from the current page load, containing the following properties:
* @param {Object} data.events - An object containing the events to be instantly tracked.
* @param {Object} data.cart - The cart object.
* @param {Object[]} data.products - An array of all product from the current page.
* @param {Object} data.product - The single product object.
* @param {Object} data.added_to_cart - The product added to cart.
* @param {Object} data.order - The order object.
*/

export const trackClassicIntegration = () => {
export function trackClassicPages( {
events,
cart,
products,
product,
added_to_cart: addedToCart,
order,
} ) {
// Instantly track the events listed in the `events` object.
const eventData = {
storeCart: cart,
products,
product,
order,
};

Object.values( events ?? {} ).forEach( ( eventName ) => {
if ( eventName === 'add_to_cart' ) {
tracker.eventHandler( eventName )( { product: addedToCart } );
Expand All @@ -34,6 +42,7 @@ export const trackClassicIntegration = () => {
}
} );

// Handle runtime cart events.
/**
* Track the custom add to cart event dispatched by WooCommerce Core
*
Expand All @@ -45,7 +54,9 @@ export const trackClassicIntegration = () => {
document.body.onadded_to_cart = ( e, fragments, cartHash, button ) => {
tracker.eventHandler( 'add_to_cart' )( {
product: getProductFromID(
parseInt( button[ 0 ].dataset.product_id )
parseInt( button[ 0 ].dataset.product_id ),
products,
cart
),
} );
};
Expand All @@ -71,7 +82,9 @@ export const trackClassicIntegration = () => {
function removeFromCartHandler( element ) {
tracker.eventHandler( 'remove_from_cart' )( {
product: getProductFromID(
parseInt( element.target.dataset.product_id )
parseInt( element.target.dataset.product_id ),
products,
cart
),
} );
}
Expand All @@ -95,10 +108,9 @@ export const trackClassicIntegration = () => {
removeFromCartHandler( { target: args[ 3 ][ 0 ] } );
};

/**
* Attaches click event listeners to non-block product listings that sends a
* `select_content` event if the target link takes the user to the product page.
*/
// Handle product selection events.
// Attach click event listeners to non-block product listings
// to send a `select_content` event if the target link takes the user to the product page.
document
.querySelectorAll( '.products .product:not(.wp-block-post)' )
?.forEach( ( item ) => {
Expand Down Expand Up @@ -136,8 +148,12 @@ export const trackClassicIntegration = () => {
}

tracker.eventHandler( 'select_content' )( {
product: getProductFromID( parseInt( productId ) ),
product: getProductFromID(
parseInt( productId ),
products,
cart
),
} );
} );
} );
};
}
6 changes: 4 additions & 2 deletions assets/js/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { addAction, removeAction } from '@wordpress/hooks';
import { config, products, cart } from '../config.js';
import { config } from '../config.js';

/**
* Formats data into the productFieldObject shape.
Expand Down Expand Up @@ -158,9 +158,11 @@ const formatCategoryKey = ( index ) => {
* Searches through the global wcgaiData.products object to find a single product by its ID
*
* @param {number} search The ID of the product to search for
* @param {Object[]} products The array of available products
* @param {Object} cart The cart object
* @return {Object|undefined} The product object or undefined if not found
*/
export const getProductFromID = ( search ) => {
export const getProductFromID = ( search, products, cart ) => {
return (
cart?.items?.find( ( { id } ) => id === search ) ??
products?.find( ( { id } ) => id === search )
Expand Down
7 changes: 7 additions & 0 deletions includes/class-wc-google-analytics.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ public function __construct() {

// utm_nooverride parameter for Google AdWords
add_filter( 'woocommerce_get_return_url', array( $this, 'utm_nooverride' ) );

// Dequeue the WooCommerce Blocks Google Analytics integration,
// not to let it register its `gtag` function so that we could provide a more detailed configuration.
add_action( 'wp_enqueue_scripts', function() {
wp_dequeue_script( 'wc-blocks-google-analytics' );
});

}

/**
Expand Down
49 changes: 35 additions & 14 deletions includes/class-wc-google-gtag-js.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class WC_Google_Gtag_JS extends WC_Abstract_Google_Analytics_JS {
/** @var string $script_handle Handle for the front end JavaScript file */
public $script_handle = 'woocommerce-google-analytics-integration';

/** @var string $script_handle Handle for the event data inline script */
public $data_script_handle = 'woocommerce-google-analytics-integration-data';

/** @var string $script_data Data required for frontend event tracking */
private $script_data = array();

Expand All @@ -39,28 +42,29 @@ public function __construct( $options = array() ) {
parent::__construct();
self::$options = $options;

$this->load_analytics_config();
$this->map_actions();

// Setup frontend scripts
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enquque_tracker' ), 5 );
add_action( 'wp_footer', array( $this, 'inline_script_data' ) );
}

/**
* Register front end scripts and inline script data
* Register tracker scripts and its inline config.
* We need to execute tracker.js w/ `gtag` configuration before any trackable action may happen.
*
* @return void
*/
public function register_scripts(): void {
public function enquque_tracker(): void {
wp_enqueue_script(
'google-tag-manager',
'https://www.googletagmanager.com/gtag/js?id=' . self::get( 'ga_id' ),
array(),
null,
false
);

// tracker.js needs to be executed ASAP, the remaining bits for main.js could be deffered,
// but to reduce the traffic, we ship it all together.
wp_enqueue_script(
$this->script_handle,
Plugin::get_instance()->get_js_asset_url( 'main.js' ),
Expand All @@ -71,22 +75,39 @@ public function register_scripts(): void {
Plugin::get_instance()->get_js_asset_version( 'main' ),
true
);
// Provide tracker's configuration.
wp_add_inline_script(
$this->script_handle,
sprintf(
'var wcgai = {config: %s};',
wp_json_encode( $this->get_analytics_config() )
),
'before'
);
}

/**
* Add inline script data to the front end
* Feed classic tracking with event data via inline script.
* Make sure it's added at the bottom of the page, so all the data is collected.
*
* @return void
*/
public function inline_script_data(): void {
wp_register_script(
$this->data_script_handle,
'',
array( $this->script_handle ),
);

wp_add_inline_script(
$this->script_handle,
$this->data_script_handle,
sprintf(
'const wcgaiData = %s;',
'wcgai.trackClassicPages( %s );',
$this->get_script_data()
),
'before'
)
);

wp_enqueue_script( $this->data_script_handle );
}

/**
Expand Down Expand Up @@ -130,7 +151,7 @@ public function set_script_data( string $type, $data ): void {
*
* @return void
*/
public function append_script_data( string $type, $data ): void {
public function append_script_data( string $type, $data ): void {
if ( ! isset( $this->script_data[ $type ] ) ) {
$this->script_data[ $type ] = array();
}
Expand All @@ -156,12 +177,12 @@ public static function tracker_function_name(): string {
}

/**
* Add Google Analytics configuration data to the script data
* Return Google Analytics configuration, for JS to read.
*
* @return void
*/
public function load_analytics_config(): void {
$this->script_data['config'] = array(
public function get_analytics_config(): array {
return array(
'developer_id' => self::DEVELOPER_ID,
'gtag_id' => self::get( 'ga_id' ),
'tracker_function_name' => self::tracker_function_name(),
Expand Down

0 comments on commit 1bdf0b6

Please sign in to comment.