Passed
Push — master ( ac9aa8...8b4016 )
by
unknown
10:20
created

MonsterInsights_Tracking_Gtag   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 353
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 202
c 1
b 0
f 0
dl 0
loc 353
rs 9.52
wmc 36

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A frontend_tracking_options_persistent() 0 4 1
A should_do_optout() 0 2 2
F frontend_tracking_options() 0 85 18
D frontend_output() 0 192 14
1
<?php
2
/**
3
 * Tracking gtag.js class.
4
 *
5
 * @since 7.15.0
6
 *
7
 * @package MonsterInsights
8
 * @author  Mircea Sandu
9
 */
10
11
// Exit if accessed directly
12
if ( ! defined( 'ABSPATH' ) ) {
13
	exit;
14
}
15
16
class MonsterInsights_Tracking_Gtag extends MonsterInsights_Tracking_Abstract {
17
18
	/**
19
	 * Holds the name of the tracking type.
20
	 *
21
	 * @since 7.15.0
22
	 * @access public
23
	 *
24
	 * @var string $name Name of the tracking type.
25
	 */
26
	public $name = 'gtag';
27
28
	/**
29
	 * Version of the tracking class.
30
	 *
31
	 * @since 7.15.0
32
	 * @access public
33
	 *
34
	 * @var string $version Version of the tracking class.
35
	 */
36
	public $version = '1.0.0';
37
38
	/**
39
	 * Primary class constructor.
40
	 *
41
	 * @since 7.15.0
42
	 * @access public
43
	 */
44
	public function __construct() {
45
46
	}
47
48
	/**
49
	 * Array of options that will be made persistent by setting them before the pageview.
50
	 *
51
	 * @see https://developers.google.com/analytics/devguides/collection/gtagjs/setting-values
52
	 * @return array Options for persistent values, like custom dimensions.
53
	 * @since 7.15.0
54
	 * @access public
55
	 */
56
	public function frontend_tracking_options_persistent() {
57
		$options = apply_filters( 'monsterinsights_frontend_tracking_options_persistent_gtag_before_pageview', array() );
58
59
		return $options;
60
	}
61
62
	/**
63
	 * Get frontend tracking options for the gtag script.
64
	 *
65
	 * This function is used to return an array of parameters
66
	 * for the frontend_output() function to output. These are
67
	 * generally dimensions and turned on GA features.
68
	 *
69
	 * @return array Options for the gtag config.
70
	 * @since 7.15.0
71
	 * @access public
72
	 *
73
	 */
74
	public function frontend_tracking_options() {
75
		global $wp_query;
76
		$options = array();
77
78
		$ua_code = monsterinsights_get_ua_to_output();
79
		if ( empty( $ua_code ) ) {
80
			return $options;
81
		}
82
83
//		$track_user = monsterinsights_track_user();
84
//
85
//		if ( ! $track_user ) {
86
//			$options['create']   = "'create', '" . esc_js( $ua_code ) . "', '" . esc_js( 'auto' ) . "'";
87
//			$options['forceSSL'] = "'set', 'forceSSL', true";
88
//			$options['send']     = "'send','pageview'";
89
//
90
//			return $options;
91
//		}
92
93
		$cross_domains = monsterinsights_get_option( 'cross_domains', array() );
94
		$allow_anchor  = monsterinsights_get_option( 'allow_anchor', false );
95
96
		if ( $allow_anchor ) {
97
			$options['allow_anchor'] = 'true';
98
		}
99
100
		if ( class_exists( 'MonsterInsights_AMP' ) ) {
101
			$options['use_amp_client_id'] = 'true';
102
		}
103
104
105
		$options['forceSSL'] = 'true';
106
107
		// Anonymous data.
108
		if ( monsterinsights_get_option( 'anonymize_ips', false ) ) {
109
			$options['anonymize_ip'] = 'true';
110
		}
111
112
		$options = apply_filters( 'monsterinsights_frontend_tracking_options_gtag_before_scripts', $options );
113
114
		// Add Enhanced link attribution.
115
		if ( monsterinsights_get_option( 'link_attribution', false ) ) {
116
			$options['link_attribution'] = 'true';
117
		}
118
119
		// Add cross-domain tracking.
120
		if ( is_array( $cross_domains ) && ! empty( $cross_domains ) ) {
0 ignored issues
show
introduced by
The condition is_array($cross_domains) is always false.
Loading history...
121
			$linker_domains = array();
122
			foreach ( $cross_domains as $cross_domain ) {
123
				if ( ! empty( $cross_domain['domain'] ) ) {
124
					$linker_domains[] = $cross_domain['domain'];
125
				}
126
			}
127
			$options['linker'] = json_encode( array(
128
				'domains' => $linker_domains,
129
			) );
130
		}
131
132
		$options = apply_filters( 'monsterinsights_frontend_tracking_options_gtag_before_pageview', $options );
133
		$options = apply_filters( 'monsterinsights_frontend_tracking_options_before_pageview', $options, $this->name, $this->version );
134
135
		if ( is_404() ) {
136
			if ( monsterinsights_get_option( 'hash_tracking', false ) ) {
137
				$options['page_path'] = "'/404.html?page=' + document.location.pathname + document.location.search + location.hash + '&from=' + document.referrer";
138
			} else {
139
				$options['page_path'] = "'/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
140
			}
141
		} else if ( $wp_query->is_search ) {
142
			$pushstr = "'/?s=";
143
			if ( 0 === (int) $wp_query->found_posts ) {
144
				$options['page_path'] = $pushstr . 'no-results:' . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=no-results'";
145
			} else if ( (int) $wp_query->found_posts === 1 ) {
146
				$options['page_path'] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=1-result'";
147
			} else if ( $wp_query->found_posts > 1 && $wp_query->found_posts < 6 ) {
148
				$options['page_path'] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=2-5-results'";
149
			} else {
150
				$options['page_path'] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=plus-5-results'";
151
			}
152
		} else if ( monsterinsights_get_option( 'hash_tracking', false ) ) {
153
			$options['page_path'] = 'location.pathname + location.search + location.hash';
154
		}
155
156
		$options = apply_filters( 'monsterinsights_frontend_tracking_options_gtag_end', $options );
157
158
		return $options;
159
	}
160
161
	/**
162
	 * Get frontend output.
163
	 *
164
	 * This function is used to return the Javascript
165
	 * to output in the head of the page for the given
166
	 * tracking method.
167
	 *
168
	 * @return string Javascript to output.
169
	 * @since 7.15.0
170
	 * @access public
171
	 *
172
	 */
173
	public function frontend_output() {
174
		$options     = $this->frontend_tracking_options();
175
		$persistent  = $this->frontend_tracking_options_persistent();
176
		$ua          = monsterinsights_get_ua();
177
		$src         = apply_filters( 'monsterinsights_frontend_output_gtag_src', '//www.googletagmanager.com/gtag/js?id=' . $ua );
178
		$compat_mode = monsterinsights_get_option( 'gtagtracker_compatibility_mode', true );
179
		$compat      = $compat_mode ? 'window.gtag = __gtagTracker;' : '';
180
		$track_user  = monsterinsights_track_user();
181
		$output      = '';
182
		$reason      = '';
183
		$attr_string = monsterinsights_get_frontend_analytics_script_atts();
184
		ob_start();
185
		?>
186
		<!-- This site uses the Google Analytics by MonsterInsights plugin v<?php echo MONSTERINSIGHTS_VERSION; ?> - Using Analytics tracking - https://www.monsterinsights.com/ -->
187
		<?php if ( ! $track_user ) {
188
			if ( empty( $ua ) ) {
189
				$reason = __( 'Note: MonsterInsights is not currently configured on this site. The site owner needs to authenticate with Google Analytics in the MonsterInsights settings panel.', 'google-analytics-for-wordpress' );
190
				$output .= '<!-- ' . esc_html( $reason ) . ' -->' . PHP_EOL;
191
			} else if ( current_user_can( 'monsterinsights_save_settings' ) ) {
192
				$reason = __( 'Note: MonsterInsights does not track you as a logged-in site administrator to prevent site owners from accidentally skewing their own Google Analytics data.' . PHP_EOL . 'If you are testing Google Analytics code, please do so either logged out or in the private browsing/incognito mode of your web browser.', 'google-analytics-for-wordpress' );
193
				$output .= '<!-- ' . esc_html( $reason ) . ' -->' . PHP_EOL;
194
			} else {
195
				$reason = __( 'Note: The site owner has disabled Google Analytics tracking for your user role.', 'google-analytics-for-wordpress' );
196
				$output .= '<!-- ' . esc_html( $reason ) . ' -->' . PHP_EOL;
197
			}
198
			echo $output;
199
		} ?>
200
		<?php if ( $ua ) { ?>
201
			<script src="<?php echo esc_attr( $src ); ?>" <?php echo $attr_string; ?>></script>
202
			<script<?php echo $attr_string; ?>>
203
				var mi_version = '<?php echo MONSTERINSIGHTS_VERSION; ?>';
204
				var mi_track_user = <?php echo( $track_user ? 'true' : 'false' ); ?>;
205
				var mi_no_track_reason = <?php echo( $reason ? "'" . esc_js( $reason ) . "'" : "''" ); ?>;
206
				<?php do_action( 'monsterinsights_tracking_gtag_frontend_output_after_mi_track_user' ); ?>
207
208
				<?php if ( $this->should_do_optout() ) { ?>
209
				var disableStr = 'ga-disable-<?php echo monsterinsights_get_ua(); ?>';
210
211
				/* Function to detect opted out users */
212
				function __gtagTrackerIsOptedOut() {
213
					return document.cookie.indexOf( disableStr + '=true' ) > - 1;
214
				}
215
216
				/* Disable tracking if the opt-out cookie exists. */
217
				if ( __gtagTrackerIsOptedOut() ) {
218
					window[disableStr] = true;
219
				}
220
221
				/* Opt-out function */
222
				function __gtagTrackerOptout() {
223
					document.cookie = disableStr + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
224
					window[disableStr] = true;
225
				}
226
227
				if ( 'undefined' === typeof gaOptout ) {
228
					function gaOptout() {
229
						__gtagTrackerOptout();
230
					}
231
				}
232
				<?php } ?>
233
				window.dataLayer = window.dataLayer || [];
234
				if ( mi_track_user ) {
235
					function __gtagTracker() {
236
						dataLayer.push( arguments );
237
					}
238
					__gtagTracker( 'js', new Date() );
239
					__gtagTracker( 'set', {
240
						'developer_id.dZGIzZG' : true,
241
						<?php
242
						if ( ! empty( $persistent ) ) {
243
							foreach ( $persistent as $key => $value ) {
244
								echo "'" . esc_js( $key ) . "' : '" . stripslashes( $value ) . "',";
245
							}
246
						}
247
						?>
248
                    });
249
					__gtagTracker( 'config', '<?php echo esc_js( $ua ); ?>', {
250
						<?php
251
						foreach ( $options as $key => $value ) {
252
							echo esc_js( $key ) . ':' . stripslashes( $value ) . ',';
253
						}
254
						?>
255
					} );
256
					<?php
257
						/**
258
						 * Extend or enhance the functionality by adding custom code to frontend
259
						 * tracking via this hook.
260
						 *
261
						 * @since 7.15.0
262
						 */
263
						do_action( 'monsterinsights_frontend_tracking_gtag_after_pageview' );
264
					?>
265
					<?php echo esc_js( $compat ); ?>
266
					<?php if ( apply_filters( 'monsterinsights_tracking_gtag_frontend_gatracker_compatibility', true ) ) { ?>
267
					(
268
						function () {
269
							/* https://developers.google.com/analytics/devguides/collection/analyticsjs/ */
270
							/* ga and __gaTracker compatibility shim. */
271
							var noopfn = function () {
272
								return null;
273
							};
274
							var noopnullfn = function () {
275
								return null;
276
							};
277
							var Tracker = function () {
278
								return null;
279
							};
280
							var p = Tracker.prototype;
281
							p.get = noopfn;
282
							p.set = noopfn;
283
							p.send = noopfn;
284
							var __gaTracker = function () {
285
								var len = arguments.length;
286
								if ( len === 0 ) {
287
									return;
288
								}
289
								var f = arguments[len - 1];
290
								if ( typeof f !== 'object' || f === null || typeof f.hitCallback !== 'function' ) {
291
									if ( 'send' === arguments[0] ) {
292
										if ( 'event' === arguments[1] ) {
293
											__gtagTracker( 'event', arguments[3], {
294
												'event_category': arguments[2],
295
												'event_label': arguments[4],
296
												'value': 1
297
											} );
298
											return;
299
										}
300
										if ( 'undefined' !== typeof ( arguments[1].hitType ) ) {
301
											var hitDetails = {};
302
											var gagtag_map = {
303
												'eventCategory': 'event_category',
304
												'eventAction': 'event_action',
305
												'eventLabel': 'event_label',
306
												'eventValue': 'event_value',
307
												'nonInteraction': 'non_interaction',
308
												'timingCategory': 'event_category',
309
												'timingVar': 'name',
310
												'timingValue': 'value',
311
												'timingLabel': 'event_label',
312
											};
313
											var gaKey;
314
											for ( gaKey in gagtag_map ) {
315
												if ( 'undefined' !== typeof arguments[1][gaKey] ) {
316
													hitDetails[gagtag_map[gaKey]] = arguments[1][gaKey];
317
												}
318
											}
319
											var action = 'timing' === arguments[1].hitType ? 'timing_complete' : arguments[1].eventAction;
320
											__gtagTracker( 'event', action, hitDetails );
321
										}
322
									}
323
									return;
324
								}
325
								try {
326
									f.hitCallback();
327
								} catch ( ex ) {
328
								}
329
							};
330
							__gaTracker.create = function () {
331
								return new Tracker();
332
							};
333
							__gaTracker.getByName = noopnullfn;
334
							__gaTracker.getAll = function () {
335
								return [];
336
							};
337
							__gaTracker.remove = noopfn;
338
							__gaTracker.loaded = true;
339
							window['__gaTracker'] = __gaTracker;
340
						}
341
					)();
342
					<?php } ?>
343
				} else {
344
					<?php if ( $this->should_do_optout() ) { ?>
345
					console.log( "<?php echo esc_js( $reason );?>" );
346
					( function () {
347
						function __gtagTracker() {
348
							return null;
349
						}
350
						window['__gtagTracker'] = __gtagTracker;
351
						window['gtag'] = __gtagTracker;
352
					} )();
353
					<?php } ?>
354
				}
355
			</script>
356
		<?php } else { ?>
357
			<!-- No UA code set -->
358
		<?php } ?>
359
		<!-- / Google Analytics by MonsterInsights -->
360
		<?php
361
		$output = ob_get_contents();
362
		ob_end_clean();
363
364
		return $output;
365
	}
366
367
	public function should_do_optout() {
368
		return ! ( defined( 'MI_NO_TRACKING_OPTOUT' ) && MI_NO_TRACKING_OPTOUT );
0 ignored issues
show
Bug introduced by
The constant MI_NO_TRACKING_OPTOUT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
369
	}
370
}
371