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-legacy.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-legacy.php
338 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 /**
4 * Jetpack_Google_Analytics_Legacy hooks and enqueues support for ga.js
5 * https://developers.google.com/analytics/devguides/collection/gajs/
6 *
7 * @author Aaron D. Campbell (original)
8 * @author allendav
9 */
10
11 /**
12 * Bail if accessed directly
13 */
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 /**
19 * Jetpack_Google_Analytics_Legacy hooks and enqueues support for ga.js
20 */
21 class Jetpack_Google_Analytics_Legacy {
22 /**
23 * Jetpack_Google_Analytics_Legacy constructor.
24 */
25 public function __construct() {
26 add_filter( 'jetpack_wga_classic_custom_vars', array( $this, 'jetpack_wga_classic_anonymize_ip' ) );
27 add_filter( 'jetpack_wga_classic_custom_vars', array( $this, 'jetpack_wga_classic_track_purchases' ) );
28 add_action( 'wp_head', array( $this, 'insert_code' ), 999 );
29 add_action( 'wp_footer', array( $this, 'jetpack_wga_classic_track_add_to_cart' ) );
30 }
31
32 /**
33 * Used to generate a tracking URL
34 * Called exclusively by insert_code
35 *
36 * @param array $track - Must have ['data'] and ['code'].
37 * @return string - Tracking URL
38 */
39 private function get_url( $track ) {
40 $site_url = ( is_ssl() ? 'https://' : 'http://' ) . sanitize_text_field( wp_unslash( isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : '' ) );
41 foreach ( $track as $k => $value ) {
42 if ( strpos( strtolower( $value ), strtolower( $site_url ) ) === 0 ) {
43 $track[ $k ] = substr( $track[ $k ], strlen( $site_url ) );
44 }
45 if ( 'data' === $k ) {
46 $track[ $k ] = preg_replace( '/^https?:\/\/|^\/+/i', '', $track[ $k ] );
47 }
48
49 // This way we don't lose search data.
50 if ( 'data' === $k && 'search' === $track['code'] ) {
51 $track[ $k ] = rawurlencode( $track[ $k ] );
52 } else {
53 $track[ $k ] = preg_replace( '/[^a-z0-9\.\/\+\?=-]+/i', '_', $track[ $k ] );
54 }
55
56 $track[ $k ] = trim( $track[ $k ], '_' );
57 }
58 $char = ( strpos( $track['data'], '?' ) === false ) ? '?' : '&amp;';
59 return str_replace( "'", "\'", "/{$track['code']}/{$track['data']}{$char}referer=" . rawurlencode( isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '' ) );
60 }
61
62 /**
63 * This injects the Google Analytics code into the footer of the page.
64 * Called exclusively by wp_head action
65 */
66 public function insert_code() {
67 $tracking_id = Jetpack_Google_Analytics_Options::get_tracking_code();
68 if ( empty( $tracking_id ) ) {
69 echo "<!-- Your Google Analytics Plugin is missing the tracking ID -->\r\n";
70 return;
71 }
72
73 // If we're in the admin_area or DNT is honored and enabled, return without inserting code.
74 if (
75 is_admin()
76 || Jetpack_Google_Analytics_Utils::is_dnt_enabled()
77 ) {
78 return;
79 }
80
81 if ( class_exists( Jetpack_AMP_Support::class ) && Jetpack_AMP_Support::is_amp_request() ) {
82 // For Reader mode — legacy.
83 add_filter( 'amp_post_template_analytics', 'Jetpack_Google_Analytics::amp_analytics_entries', 1000 );
84 // For Standard and Transitional modes.
85 add_filter( 'amp_analytics_entries', 'Jetpack_Google_Analytics::amp_analytics_entries', 1000 );
86 return;
87 }
88
89 if ( 'G-' === substr( $tracking_id, 0, 2 ) ) {
90 $this->render_gtag_code( $tracking_id );
91 } else {
92 $this->render_ga_code( $tracking_id );
93 }
94 }
95
96 /**
97 * Renders legacy ga.js code.
98 *
99 * @param string $tracking_id Google Analytics measurement ID.
100 */
101 private function render_ga_code( $tracking_id ) {
102 $custom_vars = array(
103 "_gaq.push(['_setAccount', '{$tracking_id}']);",
104 );
105
106 $track = array();
107 if ( is_404() ) {
108 // This is a 404 and we are supposed to track them.
109 $custom_vars[] = "_gaq.push(['_trackEvent', '404', document.location.href, document.referrer]);";
110 } elseif (
111 is_search()
112 && isset( $_REQUEST['s'] ) // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Function renders client-side JS, no site actions.
113 ) {
114 // Set track for searches, if it's a search, and we are supposed to.
115 $track['data'] = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Function renders client-side JS, no site actions.
116 $track['code'] = 'search';
117 }
118
119 if ( ! empty( $track ) ) {
120 $track['url'] = $this->get_url( $track );
121 // adjust the code that we output, account for both types of tracking.
122 $track['url'] = esc_js( str_replace( '&', '&amp;', $track['url'] ) );
123 $custom_vars[] = "_gaq.push(['_trackPageview','{$track['url']}']);";
124 } else {
125 $custom_vars[] = "_gaq.push(['_trackPageview']);";
126 }
127
128 /**
129 * Allow for additional elements to be added to the classic Google Analytics queue (_gaq) array
130 *
131 * @since 5.4.0
132 *
133 * @param array $custom_vars Array of classic Google Analytics queue elements
134 */
135 $custom_vars = apply_filters( 'jetpack_wga_classic_custom_vars', $custom_vars );
136
137 // Ref: https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingEcommerce#Example
138 printf(
139 "<!-- Jetpack Google Analytics -->
140 <script type='text/javascript'>
141 var _gaq = _gaq || [];
142 %s
143 (function() {
144 var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
145 ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
146 var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
147 })();
148 </script>
149 <!-- End Jetpack Google Analytics -->\r\n",
150 implode( "\r\n", $custom_vars ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Additional elements added to the classic Google Analytics script.
151 );
152 }
153
154 /**
155 * Renders new gtag code.
156 *
157 * @param string $tracking_id Google Analytics measurement ID.
158 */
159 private function render_gtag_code( $tracking_id ) {
160 /**
161 * Allow for additional elements to be added to the Global Site Tags array.
162 *
163 * @since 9.2.0
164 *
165 * @param array $universal_commands Array of gtag function calls.
166 */
167 $universal_commands = apply_filters( 'jetpack_gtag_universal_commands', array() );
168 $custom_vars = array();
169 if ( is_404() ) {
170 $custom_vars[] = array(
171 'event',
172 'exception',
173 array(
174 'description' => '404',
175 'fatal' => false,
176 ),
177 );
178 }
179 // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
180 ?>
181 <!-- Jetpack Google Analytics -->
182 <script async src='https://www.googletagmanager.com/gtag/js?id=<?php echo esc_attr( $tracking_id ); ?>'></script>
183 <script>
184 window.dataLayer = window.dataLayer || [];
185 function gtag() { dataLayer.push( arguments ); }
186 gtag( 'js', new Date() );
187 gtag( 'config', <?php echo wp_json_encode( $tracking_id ); ?> );
188 <?php
189 foreach ( $universal_commands as $command ) {
190 echo 'gtag( ' . implode( ', ', array_map( 'wp_json_encode', $command ) ) . " );\n";
191 }
192 foreach ( $custom_vars as $var ) {
193 echo 'gtag( ' . implode( ', ', array_map( 'wp_json_encode', $var ) ) . " );\n";
194 }
195 ?>
196 </script>
197 <!-- End Jetpack Google Analytics -->
198 <?php
199 // phpcs:enable
200 }
201
202 /**
203 * Used to filter in the anonymize IP snippet to the custom vars array for classic analytics
204 * Ref https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApi_gat#_gat._anonymizelp
205 *
206 * @param array $custom_vars Custom vars to be filtered.
207 * @return array Possibly updated custom vars.
208 */
209 public function jetpack_wga_classic_anonymize_ip( $custom_vars ) {
210 if ( Jetpack_Google_Analytics_Options::anonymize_ip_is_enabled() ) {
211 array_push( $custom_vars, "_gaq.push(['_gat._anonymizeIp']);" );
212 }
213
214 return $custom_vars;
215 }
216
217 /**
218 * Used to filter in the order details to the custom vars array for classic analytics
219 *
220 * @param array $custom_vars Custom vars to be filtered.
221 * @return array Possibly updated custom vars.
222 */
223 public function jetpack_wga_classic_track_purchases( $custom_vars ) {
224 global $wp;
225
226 if ( ! class_exists( 'WooCommerce' ) ) {
227 return $custom_vars;
228 }
229
230 if ( ! Jetpack_Google_Analytics_Options::has_tracking_code() ) {
231 return;
232 }
233
234 // Ref: https://developers.google.com/analytics/devguides/collection/gajs/gaTrackingEcommerce#Example
235 if ( ! Jetpack_Google_Analytics_Options::track_purchases_is_enabled() ) {
236 return $custom_vars;
237 }
238
239 $minimum_woocommerce_active = class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.0', '>=' );
240 if ( $minimum_woocommerce_active && is_order_received_page() ) {
241 $order_id = isset( $wp->query_vars['order-received'] ) ? $wp->query_vars['order-received'] : 0;
242 if ( 0 < $order_id && 1 !== (int) get_post_meta( $order_id, '_ga_tracked', true ) ) {
243 $order = new WC_Order( $order_id );
244
245 /**
246 * [ '_add_Trans', '123', 'Site Title', '21.00', '1.00', '5.00', 'Snohomish', 'WA', 'USA' ]
247 */
248 array_push(
249 $custom_vars,
250 sprintf(
251 '_gaq.push( %s );',
252 wp_json_encode(
253 array(
254 '_addTrans',
255 (string) $order->get_order_number(),
256 get_bloginfo( 'name' ),
257 (string) $order->get_total(),
258 (string) $order->get_total_tax(),
259 (string) $order->get_total_shipping(),
260 (string) $order->get_billing_city(),
261 (string) $order->get_billing_state(),
262 (string) $order->get_billing_country(),
263 )
264 )
265 )
266 );
267
268 // Order items
269 if ( $order->get_items() ) {
270 foreach ( $order->get_items() as $item ) {
271 $product = $order->get_product_from_item( $item );
272 $product_sku_or_id = $product->get_sku() ? $product->get_sku() : $product->get_id();
273
274 array_push(
275 $custom_vars,
276 sprintf(
277 '_gaq.push( %s );',
278 wp_json_encode(
279 array(
280 '_addItem',
281 (string) $order->get_order_number(),
282 (string) $product_sku_or_id,
283 $item['name'],
284 Jetpack_Google_Analytics_Utils::get_product_categories_concatenated( $product ),
285 (string) $order->get_item_total( $item ),
286 (string) $item['qty'],
287 )
288 )
289 )
290 );
291 }
292 } // get_items
293
294 // Mark the order as tracked
295 update_post_meta( $order_id, '_ga_tracked', 1 );
296 array_push( $custom_vars, "_gaq.push(['_trackTrans']);" );
297 } // order not yet tracked
298 } // is order received page
299
300 return $custom_vars;
301 }
302
303 /**
304 * Used to add footer javascript to track user clicking on add-to-cart buttons
305 * on single views (.single_add_to_cart_button) and list views (.add_to_cart_button)
306 */
307 public function jetpack_wga_classic_track_add_to_cart() {
308 if ( ! class_exists( 'WooCommerce' ) ) {
309 return;
310 }
311
312 if ( ! Jetpack_Google_Analytics_Options::has_tracking_code() ) {
313 return;
314 }
315
316 if ( ! Jetpack_Google_Analytics_Options::track_add_to_cart_is_enabled() ) {
317 return;
318 }
319
320 if ( is_product() ) { // product page
321 global $product;
322 $product_sku_or_id = $product->get_sku() ? $product->get_sku() : '#' . $product->get_id();
323 wc_enqueue_js(
324 "$( '.single_add_to_cart_button' ).click( function() {
325 _gaq.push(['_trackEvent', 'Products', 'Add to Cart', '#" . esc_js( $product_sku_or_id ) . "']);
326 } );"
327 );
328 } elseif ( is_woocommerce() ) { // any other page that uses templates (like product lists, archives, etc)
329 wc_enqueue_js(
330 "$( '.add_to_cart_button:not(.product_type_variable, .product_type_grouped)' ).click( function() {
331 var label = $( this ).data( 'product_sku' ) ? $( this ).data( 'product_sku' ) : '#' + $( this ).data( 'product_id' );
332 _gaq.push(['_trackEvent', 'Products', 'Add to Cart', label]);
333 } );"
334 );
335 }
336 }
337 }
338