PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.3.2
Jetpack – WP Security, Backup, Speed, & Growth v12.3.2
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / modules / google-analytics / classes / wp-google-analytics-universal.php
jetpack / modules / google-analytics / classes Last commit date
class-jetpack-google-amp-analytics.php 3 years ago wp-google-analytics-legacy.php 3 years ago wp-google-analytics-options.php 4 years ago wp-google-analytics-universal.php 3 years ago wp-google-analytics-utils.php 3 years ago
wp-google-analytics-universal.php
471 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Jetpack_Google_Analytics_Universal hooks and and enqueues support for analytics.js
4 * https://developers.google.com/analytics/devguides/collection/analyticsjs/
5 * https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce
6 *
7 * @author allendav
8 */
9
10 /**
11 * Bail if accessed directly
12 */
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Jetpack_Google_Analytics_Universal main class.
19 */
20 class Jetpack_Google_Analytics_Universal {
21 /**
22 * Jetpack_Google_Analytics_Universal constructor.
23 */
24 public function __construct() {
25 add_filter( 'jetpack_wga_universal_commands', array( $this, 'maybe_anonymize_ip' ) );
26 add_filter( 'jetpack_wga_universal_commands', array( $this, 'maybe_track_purchases' ) );
27
28 add_action( 'wp_head', array( $this, 'wp_head' ), 999999 );
29
30 add_action( 'woocommerce_after_add_to_cart_button', array( $this, 'add_to_cart' ) );
31 add_action( 'wp_footer', array( $this, 'loop_add_to_cart' ) );
32 add_action( 'woocommerce_after_cart', array( $this, 'remove_from_cart' ) );
33 add_action( 'woocommerce_after_mini_cart', array( $this, 'remove_from_cart' ) );
34 add_filter( 'woocommerce_cart_item_remove_link', array( $this, 'remove_from_cart_attributes' ), 10, 2 );
35 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'listing_impression' ) );
36 add_action( 'woocommerce_after_shop_loop_item', array( $this, 'listing_click' ) );
37 add_action( 'woocommerce_after_single_product', array( $this, 'product_detail' ) );
38 add_action( 'woocommerce_after_checkout_form', array( $this, 'checkout_process' ) );
39
40 // we need to send a pageview command last - so we use priority 24 to add
41 // this command's JavaScript just before wc_print_js is called (pri 25)
42 add_action( 'wp_footer', array( $this, 'send_pageview_in_footer' ), 24 );
43 }
44
45 /**
46 * Hook for the `wp_head` action to output the analytics code.
47 */
48 public function wp_head() {
49 $tracking_code = Jetpack_Google_Analytics_Options::get_tracking_code();
50 if ( empty( $tracking_code ) ) {
51 echo "<!-- No tracking ID configured for Jetpack Google Analytics -->\r\n";
52 return;
53 }
54
55 // If we're in the admin_area or DNT is honored and enabled, return without inserting code.
56 if (
57 is_admin()
58 || Jetpack_Google_Analytics_Utils::is_dnt_enabled()
59 ) {
60 return;
61 }
62
63 if ( class_exists( Jetpack_AMP_Support::class ) && Jetpack_AMP_Support::is_amp_request() ) {
64 // For Reader mode — legacy.
65 add_filter( 'amp_post_template_analytics', 'Jetpack_Google_Analytics::amp_analytics_entries', 1000 );
66 // For Standard and Transitional modes.
67 add_filter( 'amp_analytics_entries', 'Jetpack_Google_Analytics::amp_analytics_entries', 1000 );
68 return;
69 }
70
71 /**
72 * Allow for additional elements to be added to the universal Google Analytics queue (ga) array
73 *
74 * @since 5.6.0
75 *
76 * @param array $custom_vars Array of universal Google Analytics queue elements
77 */
78 $universal_commands = apply_filters( 'jetpack_wga_universal_commands', array() );
79
80 // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Script is added to wp_head.
81 $async_code = "
82 <!-- Jetpack Google Analytics -->
83 <script>
84 window.ga = window.ga || function(){ ( ga.q = ga.q || [] ).push( arguments ) }; ga.l=+new Date;
85 ga( 'create', '%tracking_id%', 'auto' );
86 ga( 'require', 'ec' );
87 %universal_commands%
88 </script>
89 <script async src='https://www.google-analytics.com/analytics.js'></script>
90 <!-- End Jetpack Google Analytics -->
91 "; // phpcs:enable WordPress.WP.EnqueuedResources.NonEnqueuedScript
92 $async_code = str_replace( '%tracking_id%', $tracking_code, $async_code );
93
94 $universal_commands_string = implode( "\r\n", $universal_commands );
95 $async_code = str_replace( '%universal_commands%', $universal_commands_string, $async_code );
96
97 echo "$async_code\r\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
98 }
99
100 /**
101 * Check if the 'anonymize_ip' option should be added to the universal Google Analytics queue (ga) commands.
102 *
103 * @param array $command_array Array of commands.
104 * @return array `$command_array` with the additional command conditionally added.
105 */
106 public function maybe_anonymize_ip( $command_array ) {
107 if ( Jetpack_Google_Analytics_Options::anonymize_ip_is_enabled() ) {
108 array_push( $command_array, "ga( 'set', 'anonymizeIp', true );" );
109 }
110
111 return $command_array;
112 }
113
114 /**
115 * Process purchase tracking options for the universal Google Analytics queue (ga) commands.
116 *
117 * May also update post meta to indicate the order has been tracked.
118 *
119 * @param array $command_array Array of commands.
120 * @return array `$command_array` with additional commands conditionally added.
121 */
122 public function maybe_track_purchases( $command_array ) {
123 global $wp;
124
125 if ( ! Jetpack_Google_Analytics_Options::track_purchases_is_enabled() ) {
126 return $command_array;
127 }
128
129 if ( ! class_exists( 'WooCommerce' ) ) {
130 return $command_array;
131 }
132
133 $minimum_woocommerce_active = class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.0', '>=' );
134 if ( ! $minimum_woocommerce_active ) {
135 return $command_array;
136 }
137
138 if ( ! is_order_received_page() ) {
139 return $command_array;
140 }
141
142 $order_id = isset( $wp->query_vars['order-received'] ) ? $wp->query_vars['order-received'] : 0;
143 if ( 0 === (int) $order_id ) {
144 return $command_array;
145 }
146
147 // A 1 indicates we've already tracked this order - don't do it again
148 if ( 1 === (int) get_post_meta( $order_id, '_ga_tracked', true ) ) {
149 return $command_array;
150 }
151
152 $order = new WC_Order( $order_id );
153 $order_currency = $order->get_currency();
154 $command = "ga( 'set', '&cu', '" . esc_js( $order_currency ) . "' );";
155 array_push( $command_array, $command );
156
157 // Order items
158 if ( $order->get_items() ) {
159 foreach ( $order->get_items() as $item ) {
160 $product = $order->get_product_from_item( $item );
161 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
162
163 $item_details = array(
164 'id' => $product_sku_or_id,
165 'name' => $item['name'],
166 'category' => Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
167 'price' => $order->get_item_total( $item ),
168 'quantity' => $item['qty'],
169 );
170 $command = "ga( 'ec:addProduct', " . wp_json_encode( $item_details ) . ' );';
171 array_push( $command_array, $command );
172 }
173 }
174
175 // Order summary
176 $summary = array(
177 'id' => $order->get_order_number(),
178 'affiliation' => get_bloginfo( 'name' ),
179 'revenue' => $order->get_total(),
180 'tax' => $order->get_total_tax(),
181 'shipping' => $order->get_total_shipping(),
182 );
183 $command = "ga( 'ec:setAction', 'purchase', " . wp_json_encode( $summary ) . ' );';
184 array_push( $command_array, $command );
185
186 update_post_meta( $order_id, '_ga_tracked', 1 );
187
188 return $command_array;
189 }
190
191 /**
192 * Enqueue add-to-cart click tracking script, if enabled.
193 */
194 public function add_to_cart() {
195 if ( ! Jetpack_Google_Analytics_Options::track_add_to_cart_is_enabled() ) {
196 return;
197 }
198
199 if ( ! is_single() ) {
200 return;
201 }
202
203 global $product;
204
205 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
206 $selector = '.single_add_to_cart_button';
207
208 wc_enqueue_js(
209 "$( '" . esc_js( $selector ) . "' ).click( function() {
210 var productDetails = {
211 'id': '" . esc_js( $product_sku_or_id ) . "',
212 'name' : '" . esc_js( $product->get_title() ) . "',
213 'quantity': $( 'input.qty' ).val() ? $( 'input.qty' ).val() : '1',
214 };
215 ga( 'ec:addProduct', productDetails );
216 ga( 'ec:setAction', 'add' );
217 ga( 'send', 'event', 'UX', 'click', 'add to cart' );
218 } );"
219 );
220 }
221
222 /**
223 * Enqueue add-to-cart click tracking script for looped product views, if enabled.
224 */
225 public function loop_add_to_cart() {
226 if ( ! Jetpack_Google_Analytics_Options::track_add_to_cart_is_enabled() ) {
227 return;
228 }
229
230 if ( ! class_exists( 'WooCommerce' ) ) {
231 return;
232 }
233
234 $minimum_woocommerce_active = class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.0', '>=' );
235 if ( ! $minimum_woocommerce_active ) {
236 return;
237 }
238
239 $selector = '.add_to_cart_button:not(.product_type_variable, .product_type_grouped)';
240
241 wc_enqueue_js(
242 "$( '" . esc_js( $selector ) . "' ).click( function() {
243 var productSku = $( this ).data( 'product_sku' );
244 var productID = $( this ).data( 'product_id' );
245 var productDetails = {
246 'id': productSku ? productSku : '#' + productID,
247 'quantity': $( this ).data( 'quantity' ),
248 };
249 ga( 'ec:addProduct', productDetails );
250 ga( 'ec:setAction', 'add' );
251 ga( 'send', 'event', 'UX', 'click', 'add to cart' );
252 } );"
253 );
254 }
255
256 /**
257 * Enqueue remove-from-cart click tracking script, if enabled.
258 */
259 public function remove_from_cart() {
260 if ( ! Jetpack_Google_Analytics_Options::enhanced_ecommerce_tracking_is_enabled() ) {
261 return;
262 }
263
264 if ( ! Jetpack_Google_Analytics_Options::track_remove_from_cart_is_enabled() ) {
265 return;
266 }
267
268 // We listen at div.woocommerce because the cart 'form' contents get forcibly
269 // updated and subsequent removals from cart would then not have this click
270 // handler attached
271 wc_enqueue_js(
272 "$( 'div.woocommerce' ).on( 'click', 'a.remove', function() {
273 var productSku = $( this ).data( 'product_sku' );
274 var productID = $( this ).data( 'product_id' );
275 var quantity = $( this ).parent().parent().find( '.qty' ).val()
276 var productDetails = {
277 'id': productSku ? productSku : '#' + productID,
278 'quantity': quantity ? quantity : '1',
279 };
280 ga( 'ec:addProduct', productDetails );
281 ga( 'ec:setAction', 'remove' );
282 ga( 'send', 'event', 'UX', 'click', 'remove from cart' );
283 } );"
284 );
285 }
286
287 /**
288 * Adds the product ID and SKU to the remove product link (for use by remove_from_cart above) if not present
289 *
290 * @param string $url Full HTML a tag of the link to remove an item from the cart.
291 * @param string $key Unique Key ID for a cart item.
292 */
293 public function remove_from_cart_attributes( $url, $key ) {
294 if ( false !== strpos( $url, 'data-product_id' ) ) {
295 return $url;
296 }
297
298 $item = WC()->cart->get_cart_item( $key );
299 $product = $item['data'];
300
301 $new_attributes = sprintf(
302 '" data-product_id="%1$s" data-product_sku="%2$s">',
303 esc_attr( $product->get_id() ),
304 esc_attr( $product->get_sku() )
305 );
306
307 $url = str_replace( '">', $new_attributes, $url );
308 return $url;
309 }
310
311 /**
312 * Enqueue listing impression tracking script, if enabled.
313 */
314 public function listing_impression() {
315 if ( ! Jetpack_Google_Analytics_Options::enhanced_ecommerce_tracking_is_enabled() ) {
316 return;
317 }
318
319 if ( ! Jetpack_Google_Analytics_Options::track_product_impressions_is_enabled() ) {
320 return;
321 }
322
323 if ( isset( $_GET['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No site actions, just GA options being set.
324 $list = 'Search Results';
325 } else {
326 $list = 'Product List';
327 }
328
329 global $product, $woocommerce_loop;
330 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
331
332 $item_details = array(
333 'id' => $product_sku_or_id,
334 'name' => $product->get_title(),
335 'category' => Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
336 'list' => $list,
337 'position' => $woocommerce_loop['loop'],
338 );
339 wc_enqueue_js( "ga( 'ec:addImpression', " . wp_json_encode( $item_details ) . ' );' );
340 }
341
342 /**
343 * Enqueue listing click tracking script, if enabled.
344 */
345 public function listing_click() {
346 if ( ! Jetpack_Google_Analytics_Options::enhanced_ecommerce_tracking_is_enabled() ) {
347 return;
348 }
349
350 if ( ! Jetpack_Google_Analytics_Options::track_product_clicks_is_enabled() ) {
351 return;
352 }
353
354 if ( isset( $_GET['s'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No site actions, just GA options being set.
355 $list = 'Search Results';
356 } else {
357 $list = 'Product List';
358 }
359
360 global $product, $woocommerce_loop;
361 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
362
363 $selector = '.products .post-' . esc_js( $product->get_id() ) . ' a';
364
365 $item_details = array(
366 'id' => $product_sku_or_id,
367 'name' => $product->get_title(),
368 'category' => Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
369 'position' => $woocommerce_loop['loop'],
370 );
371
372 wc_enqueue_js(
373 "$( '" . esc_js( $selector ) . "' ).click( function() {
374 if ( true === $( this ).hasClass( 'add_to_cart_button' ) ) {
375 return;
376 }
377
378 ga( 'ec:addProduct', " . wp_json_encode( $item_details ) . " );
379 ga( 'ec:setAction', 'click', { list: '" . esc_js( $list ) . "' } );
380 ga( 'send', 'event', 'UX', 'click', { list: '" . esc_js( $list ) . "' } );
381 } );"
382 );
383 }
384
385 /**
386 * Enqueue product detail view tracking script, if enabled.
387 */
388 public function product_detail() {
389 if ( ! Jetpack_Google_Analytics_Options::enhanced_ecommerce_tracking_is_enabled() ) {
390 return;
391 }
392
393 if ( ! Jetpack_Google_Analytics_Options::track_product_detail_view_is_enabled() ) {
394 return;
395 }
396
397 global $product;
398 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
399
400 $item_details = array(
401 'id' => $product_sku_or_id,
402 'name' => $product->get_title(),
403 'category' => Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
404 'price' => $product->get_price(),
405 );
406 wc_enqueue_js(
407 "ga( 'ec:addProduct', " . wp_json_encode( $item_details ) . ' );' .
408 "ga( 'ec:setAction', 'detail' );"
409 );
410 }
411
412 /**
413 * Enqueue post-checkout tracking script, if enabled.
414 */
415 public function checkout_process() {
416 if ( ! Jetpack_Google_Analytics_Options::enhanced_ecommerce_tracking_is_enabled() ) {
417 return;
418 }
419
420 if ( ! Jetpack_Google_Analytics_Options::track_checkout_started_is_enabled() ) {
421 return;
422 }
423
424 $universal_commands = array();
425 $cart = WC()->cart->get_cart();
426
427 foreach ( $cart as $cart_item_key => $cart_item ) {
428 /**
429 * This filter is already documented in woocommerce/templates/cart/cart.php
430 */
431 $product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
432 $product_sku_or_id = Jetpack_Google_Analytics_Utils::get_product_sku_or_id( $product );
433
434 $item_details = array(
435 'id' => $product_sku_or_id,
436 'name' => $product->get_title(),
437 'category' => Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
438 'price' => $product->get_price(),
439 'quantity' => $cart_item['quantity'],
440 );
441
442 array_push( $universal_commands, "ga( 'ec:addProduct', " . wp_json_encode( $item_details ) . ' );' );
443 }
444
445 array_push( $universal_commands, "ga( 'ec:setAction','checkout' );" );
446
447 wc_enqueue_js( implode( "\r\n", $universal_commands ) );
448 }
449
450 /**
451 * Enqueue pageview event in footer of all pages.
452 *
453 * Action hook added with later priority to come after all of the above tracking.
454 */
455 public function send_pageview_in_footer() {
456 if ( ! Jetpack_Google_Analytics_Options::has_tracking_code() ) {
457 return;
458 }
459
460 if ( is_admin() ) {
461 return;
462 }
463
464 if ( ! class_exists( 'WooCommerce' ) ) {
465 return;
466 }
467
468 wc_enqueue_js( "ga( 'send', 'pageview' );" );
469 }
470 }
471