Google Analytics Dashboard for WP (GADWP) - Version 6.5.0

Version Description

Download this release

Release Info

Developer gripgrip
Plugin Icon 128x128 Google Analytics Dashboard for WP (GADWP)
Version 6.5.0
Comparing to
See all releases

Code changes from version 6.4.0 to 6.5.0

assets/js/frontend-gtag.js ADDED
@@ -0,0 +1,648 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Developer's Notice:
3
+ *
4
+ * Note: JS in this file (and this file itself) is not guaranteed backwards compatibility. JS can be added, changed or removed at any time without notice.
5
+ * For more information see the `Backwards Compatibility Guidelines for Developers` section of the README.md file.
6
+ */
7
+ /**
8
+ * Handles:
9
+ * - JS Events handling
10
+ *
11
+ * @since 7.15.0
12
+ */
13
+ var ExactMetrics = function () {
14
+ /* ExactMetrics JS events tracking works on all major browsers, including IE starting at IE 7, via polyfills for any major JS function used that
15
+ is not supported by at least 95% of the global and/or US browser marketshare. Currently, IE 7 & 8 which as of 2/14/17 have under 0.25% global marketshare, require
16
+ us to polyfill Array.prototype.lastIndexOf, and if they continue to drop, we might remove this polyfill at some point. In that case note that events tracking
17
+ for IE 7/8 will continue to work, with the exception of events tracking of downloads. */
18
+ var lastClicked = [];
19
+ var internalAsOutboundCategory = '';
20
+
21
+ this.setLastClicked = function ( valuesArray, fieldsArray, tracked ) {
22
+ valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
23
+ fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : [];
24
+ tracked = typeof tracked !== 'undefined' ? tracked : false;
25
+
26
+ lastClicked.valuesArray = valuesArray;
27
+ lastClicked.fieldsArray = fieldsArray;
28
+ };
29
+
30
+ this.getLastClicked = function () {
31
+ return lastClicked;
32
+ };
33
+
34
+ this.setInternalAsOutboundCategory = function ( category ) {
35
+ internalAsOutboundCategory = category;
36
+ };
37
+
38
+ this.getInternalAsOutboundCategory = function () {
39
+ return internalAsOutboundCategory;
40
+ };
41
+
42
+ this.sendEvent = function ( type, action, fieldsArray ) {
43
+ __gtagTrackerSend( type, action, fieldsArray, [] );
44
+ };
45
+
46
+ function __gtagTrackerIsDebug() {
47
+ if ( window.exactmetrics_debug_mode ) {
48
+ return true;
49
+ } else {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * This attempts to be compatible with the gtag function.
56
+ *
57
+ * @see https://developers.google.com/analytics/devguides/collection/gtagjs
58
+ * @param type string Type of request, event, timing, config.
59
+ * @param action string Event action or UA for config.
60
+ * @param fieldsArray object The configuration object.
61
+ * @param valuesArray object The values for the log.
62
+ * @private
63
+ */
64
+ function __gtagTrackerSend( type, action, fieldsArray, valuesArray ) {
65
+ type = typeof type !== 'undefined' ? type : 'event';
66
+ action = typeof action !== 'undefined' ? action : '';
67
+ valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
68
+ fieldsArray = typeof fieldsArray !== 'undefined' ? fieldsArray : {};
69
+
70
+ __gtagTracker( type, action, fieldsArray );
71
+
72
+ lastClicked.valuesArray = valuesArray;
73
+ lastClicked.fieldsArray = fieldsArray;
74
+ lastClicked.fieldsArray.event_action = action;
75
+ lastClicked.tracked = true;
76
+ __gtagTrackerLog( 'Tracked: ' + valuesArray.type );
77
+ __gtagTrackerLog( lastClicked );
78
+ }
79
+
80
+ function __gtagTrackerNotSend( valuesArray ) {
81
+ valuesArray = typeof valuesArray !== 'undefined' ? valuesArray : [];
82
+
83
+ lastClicked.valuesArray = valuesArray;
84
+ lastClicked.fieldsArray = [];
85
+ lastClicked.tracked = false;
86
+ __gtagTrackerLog( 'Not Tracked: ' + valuesArray.exit );
87
+ __gtagTrackerLog( lastClicked );
88
+ }
89
+
90
+ function __gtagTrackerLog( message ) {
91
+ if ( __gtagTrackerIsDebug() ) {
92
+ console.dir( message );
93
+ }
94
+ }
95
+
96
+ function __gtagTrackerStringTrim( x ) {
97
+ return x.replace( /^\s+|\s+$/gm, '' );
98
+ }
99
+
100
+ function __gtagTrackerGetDomain() {
101
+ var i = 0, currentdomain = document.domain, p = currentdomain.split( '.' ), s = '_gd' + (
102
+ new Date()
103
+ ).getTime();
104
+ while ( i < ( p.length - 1 ) && document.cookie.indexOf( s + '=' + s ) == - 1 ) {
105
+ currentdomain = p.slice( - 1 - (
106
+ ++ i
107
+ ) ).join( '.' );
108
+ document.cookie = s + "=" + s + ";domain=" + currentdomain + ";";
109
+ }
110
+ document.cookie = s + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain=" + currentdomain + ";";
111
+ return currentdomain;
112
+ }
113
+
114
+ function __gtagTrackerGetExtension( extension ) {
115
+ extension = extension.toString();
116
+ extension = extension.substring( 0, (
117
+ extension.indexOf( "#" ) == - 1
118
+ ) ? extension.length : extension.indexOf( "#" ) ); /* Remove the anchor at the end, if there is one */
119
+ extension = extension.substring( 0, (
120
+ extension.indexOf( "?" ) == - 1
121
+ ) ? extension.length : extension.indexOf( "?" ) ); /* Remove the query after the file name, if there is one */
122
+ extension = extension.substring( extension.lastIndexOf( "/" ) + 1, extension.length ); /* Remove everything before the last slash in the path */
123
+ if ( extension.length > 0 && extension.indexOf( '.' ) !== - 1 ) { /* If there's a period left in the URL, then there's a extension. Else it is not a extension. */
124
+ extension = extension.substring( extension.indexOf( "." ) + 1 ); /* Remove everything but what's after the first period */
125
+ return extension;
126
+ } else {
127
+ return "";
128
+ }
129
+ }
130
+
131
+ function __gtagTrackerTrackedClick( event ) {
132
+ return event.which == 1 || event.which == 2 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
133
+ }
134
+
135
+ function __gtagTrackerGetDownloadExtensions() {
136
+ var download_extensions = [];
137
+ if ( typeof exactmetrics_frontend.download_extensions == 'string' ) {
138
+ download_extensions = exactmetrics_frontend.download_extensions.split( "," );
139
+ }
140
+ return download_extensions;
141
+ }
142
+
143
+ function __gtagTrackerGetInboundPaths() {
144
+ var inbound_paths = [];
145
+ if ( typeof exactmetrics_frontend.inbound_paths == 'string' ) {
146
+ inbound_paths = JSON.parse( exactmetrics_frontend.inbound_paths );
147
+ }
148
+
149
+ return inbound_paths;
150
+ }
151
+
152
+ function __gtagTrackerTrackedClickType( event ) {
153
+ if ( event.which == 1 ) {
154
+ return 'event.which=1';
155
+ } else if ( event.which == 2 ) {
156
+ return 'event.which=2';
157
+ } else if ( event.metaKey ) {
158
+ return 'metaKey';
159
+ } else if ( event.ctrlKey ) {
160
+ return 'ctrlKey';
161
+ } else if ( event.shiftKey ) {
162
+ return 'shiftKey';
163
+ } else if ( event.altKey ) {
164
+ return 'altKey';
165
+ } else {
166
+ return '';
167
+ }
168
+ }
169
+
170
+ function __gtagTrackerLinkType( el ) {
171
+ var download_extensions = __gtagTrackerGetDownloadExtensions();
172
+ var inbound_paths = __gtagTrackerGetInboundPaths();
173
+ var type = 'unknown';
174
+ var link = el.href;
175
+ var extension = __gtagTrackerGetExtension( el.href );
176
+ var currentdomain = __gtagTrackerGetDomain();
177
+ var hostname = el.hostname;
178
+ var protocol = el.protocol;
179
+ var pathname = el.pathname;
180
+ link = link.toString();
181
+ var index, len;
182
+ var category = el.getAttribute( "data-vars-ga-category" );
183
+
184
+ if ( category ) {
185
+ return category;
186
+ }
187
+
188
+ if ( link.match( /^javascript\:/i ) ) {
189
+ type = 'internal'; /* if it's a JS link, it's internal */
190
+ } else if ( protocol && protocol.length > 0 && (
191
+ __gtagTrackerStringTrim( protocol ) == 'tel' || __gtagTrackerStringTrim( protocol ) == 'tel:'
192
+ ) ) { /* If it's a telephone link */
193
+ type = "tel";
194
+ } else if ( protocol && protocol.length > 0 && (
195
+ __gtagTrackerStringTrim( protocol ) == 'mailto' || __gtagTrackerStringTrim( protocol ) == 'mailto:'
196
+ ) ) { /* If it's a email */
197
+ type = "mailto";
198
+ } else if ( hostname && currentdomain && hostname.length > 0 && currentdomain.length > 0 && !hostname.endsWith( '.' + currentdomain ) && hostname !== currentdomain ) { /* If it's a outbound */
199
+ type = "external";
200
+ } else if ( pathname && JSON.stringify( inbound_paths ) != "{}" && pathname.length > 0 ) { /* If it's an internal as outbound */
201
+ var inbound_paths_length = inbound_paths.length;
202
+ for ( var inbound_paths_index = 0; inbound_paths_index < inbound_paths_length; inbound_paths_index ++ ) {
203
+ if ( inbound_paths[inbound_paths_index].path && inbound_paths[inbound_paths_index].label && inbound_paths[inbound_paths_index].path.length > 0 && inbound_paths[inbound_paths_index].label.length > 0 && pathname.startsWith( inbound_paths[inbound_paths_index].path ) ) {
204
+ type = "internal-as-outbound";
205
+ internalAsOutboundCategory = "outbound-link-" + inbound_paths[inbound_paths_index].label;
206
+ break;
207
+ }
208
+ }
209
+ /* Enable window.exactmetrics_experimental_mode at your own risk. We might eventually remove it. Also you may/can/will burn through GA quota for your property quickly. */
210
+ } else if ( hostname && window.exactmetrics_experimental_mode && hostname.length > 0 && document.domain.length > 0 && hostname !== document.domain ) { /* If it's a cross-hostname link */
211
+ type = "cross-hostname";
212
+ }
213
+
214
+ if ( extension && (
215
+ type === 'unknown' || 'external' === type
216
+ ) && download_extensions.length > 0 && extension.length > 0 ) { /* If it's a download */
217
+ for ( index = 0, len = download_extensions.length; index < len; ++ index ) {
218
+ if ( download_extensions[index].length > 0 && (
219
+ link.endsWith( download_extensions[index] ) || download_extensions[index] == extension
220
+ ) ) {
221
+ type = "download";
222
+ break;
223
+ }
224
+ }
225
+ }
226
+
227
+ if ( type === 'unknown' ) {
228
+ type = 'internal';
229
+ }
230
+ return type;
231
+ }
232
+
233
+ function __gtagTrackerLinkTarget( el, event ) {
234
+
235
+ /* Is actual target set and not _(self|parent|top)? */
236
+ var target = (
237
+ el.target && !el.target.match( /^_(self|parent|top)$/i )
238
+ ) ? el.target : false;
239
+
240
+ /* Assume a target if Ctrl|shift|meta-click */
241
+ if ( event.ctrlKey || event.shiftKey || event.metaKey || event.which == 2 ) {
242
+ target = "_blank";
243
+ }
244
+ return target;
245
+ }
246
+
247
+ function __gtagTrackerGetTitle( el ) {
248
+ if ( el.getAttribute( "data-vars-ga-label" ) && el.getAttribute( "data-vars-ga-label" ).replace( /\n/ig, '' ) ) {
249
+ return el.getAttribute( "data-vars-ga-label" ).replace( /\n/ig, '' );
250
+ } else if ( el.title && el.title.replace( /\n/ig, '' ) ) {
251
+ return el.title.replace( /\n/ig, '' );
252
+ } else if ( el.innerText && el.innerText.replace( /\n/ig, '' ) ) {
253
+ return el.innerText.replace( /\n/ig, '' );
254
+ } else if ( el.getAttribute( 'aria-label' ) && el.getAttribute( 'aria-label' ).replace( /\n/ig, '' ) ) {
255
+ return el.getAttribute( 'aria-label' ).replace( /\n/ig, '' );
256
+ } else if ( el.alt && el.alt.replace( /\n/ig, '' ) ) {
257
+ return el.alt.replace( /\n/ig, '' );
258
+ } else if ( el.textContent && el.textContent.replace( /\n/ig, '' ) ) {
259
+ return el.textContent.replace( /\n/ig, '' );
260
+ } else {
261
+ return undefined;
262
+ }
263
+ }
264
+
265
+ function __gtagTrackerGetInnerTitle( el ) {
266
+ var children = el.children;
267
+ var count = 0;
268
+ var child;
269
+ var value;
270
+ for ( var i = 0; i < children.length; i ++ ) {
271
+ child = children[i];
272
+ value = __gtagTrackerGetTitle( child );
273
+ if ( value ) {
274
+ return value;
275
+ }
276
+ /* max search 100 elements to ensure performance */
277
+ if ( count == 99 ) {
278
+ return undefined;
279
+ }
280
+ count ++;
281
+ }
282
+ return undefined;
283
+ }
284
+
285
+ function __gtagTrackerClickEvent( event ) {
286
+ var el = event.srcElement || event.target;
287
+ var valuesArray = [];
288
+ var fieldsArray;
289
+
290
+ /* Start Values Array */
291
+ valuesArray.el = el;
292
+ valuesArray.click_type = __gtagTrackerTrackedClickType( event );
293
+
294
+ /* If GA is blocked or not loaded, or not main|middle|touch click then don't track */
295
+ if ( 'undefined' === typeof __gtagTracker || ! __gtagTrackerTrackedClick( event ) ) {
296
+ valuesArray.exit = 'loaded';
297
+ __gtagTrackerNotSend( valuesArray );
298
+ return;
299
+ }
300
+
301
+ /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
302
+ while ( el && (
303
+ typeof el.tagName == 'undefined' || el.tagName.toLowerCase() != 'a' || !el.href
304
+ ) ) {
305
+ el = el.parentNode;
306
+ }
307
+
308
+ /* if a link with valid href has been clicked */
309
+ if ( el && el.href && !el.hasAttribute( 'xlink:href' ) ) {
310
+ var link = el.href; /* What link are we tracking */
311
+ var extension = __gtagTrackerGetExtension( el.href ); /* What extension is this link */
312
+ var download_extensions = __gtagTrackerGetDownloadExtensions(); /* Let's get the extensions to track */
313
+ var inbound_paths = __gtagTrackerGetInboundPaths(); /* Let's get the internal paths to track */
314
+ var home_url = exactmetrics_frontend.home_url; /* Let's get the url to compare for external/internal use */
315
+ var currentdomain = __gtagTrackerGetDomain(); /* What domain are we on? */
316
+ var type = __gtagTrackerLinkType( el ); /* What type of link is this? */
317
+ var target = __gtagTrackerLinkTarget( el, event ); /* Is a new tab/window being opened? */
318
+ var action = el.getAttribute( "data-vars-ga-action" );
319
+ var label = el.getAttribute( "data-vars-ga-label" );
320
+
321
+ /* Element */
322
+ valuesArray.el = el; /* el is an a element so we can parse it */
323
+ valuesArray.el_href = el.href; /* "http://example.com:3000/pathname/?search=test#hash" */
324
+ valuesArray.el_protocol = el.protocol; /* "http:" */
325
+ valuesArray.el_hostname = el.hostname; /* "example.com" */
326
+ valuesArray.el_port = el.port; /* "3000" */
327
+ valuesArray.el_pathname = el.pathname; /* "/pathname/" */
328
+ valuesArray.el_search = el.search; /* "?search=test" */
329
+ valuesArray.el_hash = el.hash; /* "#hash" */
330
+ valuesArray.el_host = el.host; /* "example.com:3000" */
331
+
332
+ /* Settings */
333
+ valuesArray.debug_mode = __gtagTrackerIsDebug(); /* "example.com:3000" */
334
+ valuesArray.download_extensions = download_extensions; /* Let's get the extensions to track */
335
+ valuesArray.inbound_paths = inbound_paths; /* Let's get the internal paths to track */
336
+ valuesArray.home_url = home_url; /* Let's get the url to compare for external/internal use */
337
+
338
+ /* Parsed/Logic */
339
+ valuesArray.link = link; /* What link are we tracking */
340
+ valuesArray.extension = extension; /* What extension is this link */
341
+ valuesArray.type = type; /* What type of link is this */
342
+ valuesArray.target = target; /* Is a new tab/window being opened? */
343
+ valuesArray.title = __gtagTrackerGetTitle( el ); /* Try link title, then text content */
344
+
345
+ /* only find innerTitle if we need one */
346
+ if ( ! valuesArray.label && !valuesArray.title ) {
347
+ valuesArray.title = __gtagTrackerGetInnerTitle( el );
348
+ }
349
+
350
+ /* Let's track everything but internals (that aren't internal-as-externals) and javascript */
351
+ if ( type !== 'internal' && type !== 'javascript' ) {
352
+
353
+ var __gtagTrackerHitBackRun = false; /* Tracker has not yet run */
354
+
355
+ /* HitCallback to open link in same window after tracker */
356
+ var __gtagTrackerHitBack = function () {
357
+ /* Run the hitback only once */
358
+ if ( __gtagTrackerHitBackRun ) {
359
+ return;
360
+ }
361
+ __gtagTrackerHitBackRun = true;
362
+ window.location.href = link;
363
+ };
364
+
365
+ var __gtagTrackerNoRedirectExternal = function () {
366
+ valuesArray.exit = 'external';
367
+ __gtagTrackerNotSend( valuesArray );
368
+ };
369
+
370
+ var __gtagTrackerNoRedirectInboundAsExternal = function () {
371
+ valuesArray.exit = 'internal-as-outbound';
372
+ __gtagTrackerNotSend( valuesArray );
373
+ };
374
+ var __gtagTrackerNoRedirectCrossHostname = function () {
375
+ valuesArray.exit = 'cross-hostname';
376
+ __gtagTrackerNotSend( valuesArray );
377
+ };
378
+
379
+ if ( target || type == 'mailto' || type == 'tel' ) { /* If target opens a new window then just track */
380
+ if ( type == 'download' ) {
381
+ fieldsArray = {
382
+ event_category: 'download',
383
+ event_label: label || valuesArray.title,
384
+ };
385
+ } else if ( type == 'tel' ) {
386
+ fieldsArray = {
387
+ event_category: 'tel',
388
+ event_label: label || valuesArray.title.replace( 'tel:', '' ),
389
+ };
390
+ } else if ( type == 'mailto' ) {
391
+ console.log( label || valuesArray.title.replace( 'mailto:', '' ) );
392
+ fieldsArray = {
393
+ event_category: 'mailto',
394
+ event_label: label || valuesArray.title.replace( 'mailto:', '' ),
395
+ };
396
+ } else if ( type == 'internal-as-outbound' ) {
397
+ fieldsArray = {
398
+ event_category: internalAsOutboundCategory,
399
+ event_label: label || valuesArray.title,
400
+ };
401
+ } else if ( type == 'external' ) {
402
+ fieldsArray = {
403
+ event_category: 'outbound-link',
404
+ event_label: label || valuesArray.title,
405
+ };
406
+ } else if ( type == 'cross-hostname' ) {
407
+ fieldsArray = {
408
+ event_category: 'cross-hostname',
409
+ event_label: label || valuesArray.title,
410
+ };
411
+ }
412
+
413
+ if ( fieldsArray ) {
414
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
415
+ } else {
416
+ if ( type && type != 'internal' ) {
417
+ fieldsArray = {
418
+ event_category: type,
419
+ event_label: label || valuesArray.title,
420
+ };
421
+
422
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
423
+ } else {
424
+ valuesArray.exit = 'type';
425
+ __gtagTrackerNotSend( valuesArray );
426
+ }
427
+ }
428
+ } else {
429
+ /* Prevent standard click, track then open */
430
+ if ( type != 'cross-hostname' && type != 'external' && type != 'internal-as-outbound' ) {
431
+ if ( !event.defaultPrevented ) {
432
+ if ( event.preventDefault ) {
433
+ event.preventDefault();
434
+ } else {
435
+ event.returnValue = false;
436
+ }
437
+ }
438
+ }
439
+
440
+ if ( type == 'download' ) {
441
+ fieldsArray = {
442
+ event_category: 'download',
443
+ event_label: label || valuesArray.title,
444
+ event_callback: __gtagTrackerHitBack,
445
+ };
446
+
447
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
448
+ } else if ( type == 'internal-as-outbound' ) {
449
+ window.onbeforeunload = function ( e ) {
450
+ if ( !event.defaultPrevented ) {
451
+ if ( event.preventDefault ) {
452
+ event.preventDefault();
453
+ } else {
454
+ event.returnValue = false;
455
+ }
456
+ }
457
+
458
+ fieldsArray = {
459
+ event_category: internalAsOutboundCategory,
460
+ event_label: label || valuesArray.title,
461
+ event_callback: __gtagTrackerHitBack,
462
+ };
463
+
464
+ if ( navigator.sendBeacon ) {
465
+ fieldsArray.transport = 'beacon';
466
+ }
467
+
468
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
469
+ setTimeout( __gtagTrackerHitBack, 1000 );
470
+ };
471
+ } else if ( type == 'external' ) {
472
+ window.onbeforeunload = function ( e ) {
473
+ if ( !event.defaultPrevented ) {
474
+ if ( event.preventDefault ) {
475
+ event.preventDefault();
476
+ } else {
477
+ event.returnValue = false;
478
+ }
479
+ }
480
+
481
+ fieldsArray = {
482
+ event_category: 'outbound-link',
483
+ event_label: label || valuesArray.title,
484
+ event_callback: __gtagTrackerHitBack,
485
+ };
486
+
487
+ if ( navigator.sendBeacon ) {
488
+ fieldsArray.transport = 'beacon';
489
+ }
490
+
491
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
492
+ setTimeout( __gtagTrackerHitBack, 1000 );
493
+ };
494
+ } else if ( type == 'cross-hostname' ) {
495
+ window.onbeforeunload = function ( e ) {
496
+ if ( !event.defaultPrevented ) {
497
+ if ( event.preventDefault ) {
498
+ event.preventDefault();
499
+ } else {
500
+ event.returnValue = false;
501
+ }
502
+ }
503
+
504
+ fieldsArray = {
505
+ event_category: 'cross-hostname',
506
+ event_label: label || valuesArray.title,
507
+ event_callback: __gtagTrackerHitBack,
508
+ };
509
+
510
+ if ( navigator.sendBeacon ) {
511
+ fieldsArray.transport = 'beacon';
512
+ }
513
+
514
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
515
+ setTimeout( __gtagTrackerHitBack, 1000 );
516
+ };
517
+ } else {
518
+ if ( type && type !== 'internal' ) {
519
+ fieldsArray = {
520
+ event_category: type,
521
+ event_label: label || valuesArray.title,
522
+ event_callback: __gtagTrackerHitBack,
523
+ };
524
+
525
+ __gtagTrackerSend( 'event', action || link, fieldsArray, valuesArray );
526
+ } else {
527
+ valuesArray.exit = 'type';
528
+ __gtagTrackerNotSend( valuesArray );
529
+ }
530
+ }
531
+
532
+ if ( type != 'external' && type != 'cross-hostname' && type != 'internal-as-outbound' ) {
533
+ /* Run event_callback again if GA takes longer than 1 second */
534
+ setTimeout( __gtagTrackerHitBack, 1000 );
535
+ } else {
536
+ if ( type == 'external' ) {
537
+ setTimeout( __gtagTrackerNoRedirectExternal, 1100 );
538
+ } else if ( type == 'cross-hostname' ) {
539
+ setTimeout( __gtagTrackerNoRedirectCrossHostname, 1100 );
540
+ } else {
541
+ setTimeout( __gtagTrackerNoRedirectInboundAsExternal, 1100 );
542
+ }
543
+ }
544
+ }
545
+ } else {
546
+ valuesArray.exit = 'internal';
547
+ __gtagTrackerNotSend( valuesArray );
548
+ }
549
+ } else {
550
+ valuesArray.exit = 'notlink';
551
+ __gtagTrackerNotSend( valuesArray );
552
+ }
553
+ }
554
+
555
+ var prevHash = window.location.hash;
556
+
557
+ function __gtagTrackerHashChangeEvent() {
558
+ /* Todo: Ready this section for JS unit testing */
559
+ if ( exactmetrics_frontend.hash_tracking === "true" && prevHash != window.location.hash && exactmetrics_frontend.ua ) {
560
+ prevHash = window.location.hash;
561
+ __gtagTracker( 'config', exactmetrics_frontend.ua, {
562
+ page_path: location.pathname + location.search + location.hash,
563
+ } )
564
+ __gtagTrackerLog( "Hash change to: " + location.pathname + location.search + location.hash );
565
+ } else {
566
+ __gtagTrackerLog( "Hash change to (untracked): " + location.pathname + location.search + location.hash );
567
+ }
568
+ }
569
+
570
+ /* Attach the event to all clicks in the document after page has loaded */
571
+ var __gtagTrackerWindow = window;
572
+ if ( __gtagTrackerWindow.addEventListener ) {
573
+ __gtagTrackerWindow.addEventListener(
574
+ "load",
575
+ function () {
576
+ document.body.addEventListener(
577
+ "click",
578
+ __gtagTrackerClickEvent,
579
+ false
580
+ );
581
+ },
582
+ false
583
+ );
584
+ window.addEventListener( "hashchange", __gtagTrackerHashChangeEvent, false );
585
+ } else {
586
+ if ( __gtagTrackerWindow.attachEvent ) {
587
+ __gtagTrackerWindow.attachEvent(
588
+ "onload",
589
+ function () {
590
+ document.body.attachEvent( "onclick", __gtagTrackerClickEvent );
591
+ }
592
+ );
593
+ window.attachEvent( "onhashchange", __gtagTrackerHashChangeEvent );
594
+ }
595
+ }
596
+
597
+ if ( typeof String.prototype.endsWith !== 'function' ) {
598
+ String.prototype.endsWith = function ( suffix ) {
599
+ return this.indexOf( suffix, this.length - suffix.length ) !== - 1;
600
+ };
601
+ }
602
+ if ( typeof String.prototype.startsWith !== 'function' ) {
603
+ String.prototype.startsWith = function ( prefix ) {
604
+ return this.indexOf( prefix ) === 0;
605
+ };
606
+ }
607
+
608
+ if ( typeof Array.prototype.lastIndexOf !== 'function' ) {
609
+ Array.prototype.lastIndexOf = function ( searchElement /*, fromIndex*/ ) {
610
+ 'use strict';
611
+
612
+ if ( this === void 0 || this === null ) {
613
+ throw new TypeError();
614
+ }
615
+
616
+ var n, k,
617
+ t = Object( this ),
618
+ len = t.length >>> 0; /* jshint ignore:line */
619
+ if ( len === 0 ) {
620
+ return - 1;
621
+ }
622
+
623
+ n = len - 1;
624
+ if ( arguments.length > 1 ) {
625
+ n = Number( arguments[1] );
626
+ if ( n != n ) {
627
+ n = 0;
628
+ } else if ( n != 0 && n != (
629
+ 1 / 0
630
+ ) && n != - (
631
+ 1 / 0
632
+ ) ) { /* jshint ignore:line */
633
+ n = (
634
+ n > 0 || - 1
635
+ ) * Math.floor( Math.abs( n ) );
636
+ }
637
+ }
638
+
639
+ for ( k = n >= 0 ? Math.min( n, len - 1 ) : len - Math.abs( n ); k >= 0; k -- ) {
640
+ if ( k in t && t[k] === searchElement ) {
641
+ return k;
642
+ }
643
+ }
644
+ return - 1;
645
+ };
646
+ }
647
+ };
648
+ var ExactMetricsObject = new ExactMetrics();
assets/js/frontend-gtag.min.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;var ExactMetrics=function(){var e=[],a='';this.setLastClicked=function(t,n,i){t=typeof t!=='undefined'?t:[];n=typeof n!=='undefined'?n:[];i=typeof i!=='undefined'?i:!1;e.valuesArray=t;e.fieldsArray=n};this.getLastClicked=function(){return e};this.setInternalAsOutboundCategory=function(e){a=e};this.getInternalAsOutboundCategory=function(){return a};this.sendEvent=function(e,n,i){t(e,n,i,[])};function s(){if(window.exactmetrics_debug_mode){return!0}
2
+ else{return!1}};function t(t,n,a,r){t=typeof t!=='undefined'?t:'event';n=typeof n!=='undefined'?n:'';r=typeof r!=='undefined'?r:[];a=typeof a!=='undefined'?a:{};__gtagTracker(t,n,a);e.valuesArray=r;e.fieldsArray=a;e.fieldsArray.event_action=n;e.tracked=!0;i('Tracked: '+r.type);i(e)};function n(t){t=typeof t!=='undefined'?t:[];e.valuesArray=t;e.fieldsArray=[];e.tracked=!1;i('Not Tracked: '+t.exit);i(e)};function i(e){if(s()){console.dir(e)}};function o(e){return e.replace(/^\s+|\s+$/gm,'')};function f(){var n=0,e=document.domain,i=e.split('.'),t='_gd'+(new Date()).getTime();while(n<(i.length-1)&&document.cookie.indexOf(t+'='+t)==-1){e=i.slice(-1-(++n)).join('.');document.cookie=t+'='+t+';domain='+e+';'};document.cookie=t+'=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain='+e+';';return e};function u(e){e=e.toString();e=e.substring(0,(e.indexOf('#')==-1)?e.length:e.indexOf('#'));e=e.substring(0,(e.indexOf('?')==-1)?e.length:e.indexOf('?'));e=e.substring(e.lastIndexOf('/')+1,e.length);if(e.length>0&&e.indexOf('.')!==-1){e=e.substring(e.indexOf('.')+1);return e}
3
+ else{return''}};function p(e){return e.which==1||e.which==2||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey};function c(){var e=[];if(typeof exactmetrics_frontend.download_extensions=='string'){e=exactmetrics_frontend.download_extensions.split(',')};return e};function d(){var e=[];if(typeof exactmetrics_frontend.inbound_paths=='string'){e=JSON.parse(exactmetrics_frontend.inbound_paths)};return e};function m(e){if(e.which==1){return'event.which=1'}
4
+ else if(e.which==2){return'event.which=2'}
5
+ else if(e.metaKey){return'metaKey'}
6
+ else if(e.ctrlKey){return'ctrlKey'}
7
+ else if(e.shiftKey){return'shiftKey'}
8
+ else if(e.altKey){return'altKey'}
9
+ else{return''}};function b(e){var h=c(),i=d(),t='unknown',g=e.href,p=u(e.href),v=f(),l=e.hostname,r=e.protocol,m=e.pathname;g=g.toString();var s,b,y=e.getAttribute('data-vars-ga-category');if(y){return y};if(g.match(/^javascript\:/i)){t='internal'}
10
+ else if(r&&r.length>0&&(o(r)=='tel'||o(r)=='tel:')){t='tel'}
11
+ else if(r&&r.length>0&&(o(r)=='mailto'||o(r)=='mailto:')){t='mailto'}
12
+ else if(l&&v&&l.length>0&&v.length>0&&!l.endsWith('.'+v)&&l!==v){t='external'}
13
+ else if(m&&JSON.stringify(i)!='{}'&&m.length>0){var w=i.length;for(var n=0;n<w;n++){if(i[n].path&&i[n].label&&i[n].path.length>0&&i[n].label.length>0&&m.startsWith(i[n].path)){t='internal-as-outbound';a='outbound-link-'+i[n].label;break}}}
14
+ else if(l&&window.exactmetrics_experimental_mode&&l.length>0&&document.domain.length>0&&l!==document.domain){t='cross-hostname'};if(p&&(t==='unknown'||'external'===t)&&h.length>0&&p.length>0){for(s=0,b=h.length;s<b;++s){if(h[s].length>0&&(g.endsWith(h[s])||h[s]==p)){t='download';break}}};if(t==='unknown'){t='internal'};return t};function y(e,t){var n=(e.target&&!e.target.match(/^_(self|parent|top)$/i))?e.target:!1;if(t.ctrlKey||t.shiftKey||t.metaKey||t.which==2){n='_blank'};return n};function h(e){if(e.getAttribute('data-vars-ga-label')&&e.getAttribute('data-vars-ga-label').replace(/\n/ig,'')){return e.getAttribute('data-vars-ga-label').replace(/\n/ig,'')}
15
+ else if(e.title&&e.title.replace(/\n/ig,'')){return e.title.replace(/\n/ig,'')}
16
+ else if(e.innerText&&e.innerText.replace(/\n/ig,'')){return e.innerText.replace(/\n/ig,'')}
17
+ else if(e.getAttribute('aria-label')&&e.getAttribute('aria-label').replace(/\n/ig,'')){return e.getAttribute('aria-label').replace(/\n/ig,'')}
18
+ else if(e.alt&&e.alt.replace(/\n/ig,'')){return e.alt.replace(/\n/ig,'')}
19
+ else if(e.textContent&&e.textContent.replace(/\n/ig,'')){return e.textContent.replace(/\n/ig,'')}
20
+ else{return undefined}};function w(e){var i=e.children,a=0,r,n;for(var t=0;t<i.length;t++){r=i[t];n=h(r);if(n){return n};if(a==99){return undefined};a++};return undefined};function g(i){var o=i.srcElement||i.target,e=[],l;e.el=o;e.click_type=m(i);if('undefined'===typeof __gtagTracker||!p(i)){e.exit='loaded';n(e);return}
21
+ while(o&&(typeof o.tagName=='undefined'||o.tagName.toLowerCase()!='a'||!o.href)){o=o.parentNode};if(o&&o.href&&!o.hasAttribute('xlink:href')){var x=o.href,D=u(o.href),C=c(),I=d(),M=exactmetrics_frontend.home_url,S=f(),r=b(o),T=y(o,i),k=o.getAttribute('data-vars-ga-action'),g=o.getAttribute('data-vars-ga-label');e.el=o;e.el_href=o.href;e.el_protocol=o.protocol;e.el_hostname=o.hostname;e.el_port=o.port;e.el_pathname=o.pathname;e.el_search=o.search;e.el_hash=o.hash;e.el_host=o.host;e.debug_mode=s();e.download_extensions=C;e.inbound_paths=I;e.home_url=M;e.link=x;e.extension=D;e.type=r;e.target=T;e.title=h(o);if(!e.label&&!e.title){e.title=w(o)};if(r!=='internal'&&r!=='javascript'){var A=!1,v=function(){if(A){return};A=!0;window.location.href=x},O=function(){e.exit='external';n(e)},K=function(){e.exit='internal-as-outbound';n(e)},E=function(){e.exit='cross-hostname';n(e)};if(T||r=='mailto'||r=='tel'){if(r=='download'){l={event_category:'download',event_label:g||e.title,}}
22
+ else if(r=='tel'){l={event_category:'tel',event_label:g||e.title.replace('tel:',''),}}
23
+ else if(r=='mailto'){console.log(g||e.title.replace('mailto:',''));l={event_category:'mailto',event_label:g||e.title.replace('mailto:',''),}}
24
+ else if(r=='internal-as-outbound'){l={event_category:a,event_label:g||e.title,}}
25
+ else if(r=='external'){l={event_category:'outbound-link',event_label:g||e.title,}}
26
+ else if(r=='cross-hostname'){l={event_category:'cross-hostname',event_label:g||e.title,}};if(l){t('event',k||x,l,e)}
27
+ else{if(r&&r!='internal'){l={event_category:r,event_label:g||e.title,};t('event',k||x,l,e)}
28
+ else{e.exit='type';n(e)}}}
29
+ else{if(r!='cross-hostname'&&r!='external'&&r!='internal-as-outbound'){if(!i.defaultPrevented){if(i.preventDefault){i.preventDefault()}
30
+ else{i.returnValue=!1}}};if(r=='download'){l={event_category:'download',event_label:g||e.title,event_callback:v,};t('event',k||x,l,e)}
31
+ else if(r=='internal-as-outbound'){window.onbeforeunload=function(n){if(!i.defaultPrevented){if(i.preventDefault){i.preventDefault()}
32
+ else{i.returnValue=!1}};l={event_category:a,event_label:g||e.title,event_callback:v,};if(navigator.sendBeacon){l.transport='beacon'};t('event',k||x,l,e);setTimeout(v,1000)}}
33
+ else if(r=='external'){window.onbeforeunload=function(n){if(!i.defaultPrevented){if(i.preventDefault){i.preventDefault()}
34
+ else{i.returnValue=!1}};l={event_category:'outbound-link',event_label:g||e.title,event_callback:v,};if(navigator.sendBeacon){l.transport='beacon'};t('event',k||x,l,e);setTimeout(v,1000)}}
35
+ else if(r=='cross-hostname'){window.onbeforeunload=function(n){if(!i.defaultPrevented){if(i.preventDefault){i.preventDefault()}
36
+ else{i.returnValue=!1}};l={event_category:'cross-hostname',event_label:g||e.title,event_callback:v,};if(navigator.sendBeacon){l.transport='beacon'};t('event',k||x,l,e);setTimeout(v,1000)}}
37
+ else{if(r&&r!=='internal'){l={event_category:r,event_label:g||e.title,event_callback:v,};t('event',k||x,l,e)}
38
+ else{e.exit='type';n(e)}};if(r!='external'&&r!='cross-hostname'&&r!='internal-as-outbound'){setTimeout(v,1000)}
39
+ else{if(r=='external'){setTimeout(O,1100)}
40
+ else if(r=='cross-hostname'){setTimeout(E,1100)}
41
+ else{setTimeout(K,1100)}}}}
42
+ else{e.exit='internal';n(e)}}
43
+ else{e.exit='notlink';n(e)}};var l=window.location.hash;function v(){if(exactmetrics_frontend.hash_tracking==='true'&&l!=window.location.hash&&exactmetrics_frontend.ua){l=window.location.hash;__gtagTracker('config',exactmetrics_frontend.ua,{page_path:location.pathname+location.search+location.hash,});i('Hash change to: '+location.pathname+location.search+location.hash)}
44
+ else{i('Hash change to (untracked): '+location.pathname+location.search+location.hash)}};var r=window;if(r.addEventListener){r.addEventListener('load',function(){document.body.addEventListener('click',g,!1)},!1);window.addEventListener('hashchange',v,!1)}
45
+ else{if(r.attachEvent){r.attachEvent('onload',function(){document.body.attachEvent('onclick',g)});window.attachEvent('onhashchange',v)}};if(typeof String.prototype.endsWith!=='function'){String.prototype.endsWith=function(e){return this.indexOf(e,this.length-e.length)!==-1}};if(typeof String.prototype.startsWith!=='function'){String.prototype.startsWith=function(e){return this.indexOf(e)===0}};if(typeof Array.prototype.lastIndexOf!=='function'){Array.prototype.lastIndexOf=function(e){'use strict';if(this===void 0||this===null){throw new TypeError()};var t,n,a=Object(this),i=a.length>>>0;if(i===0){return-1};t=i-1;if(arguments.length>1){t=Number(arguments[1]);if(t!=t){t=0}
46
+ else if(t!=0&&t!=(1/0)&&t!=-(1/0)){t=(t>0||-1)*Math.floor(Math.abs(t))}};for(n=t>=0?Math.min(t,i-1):i-Math.abs(t);n>=0;n--){if(n in a&&a[n]===e){return n}};return-1}}},ExactMetricsObject=new ExactMetrics();
gadwp.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin URI: https://exactmetrics.com
5
  * Description: Displays Google Analytics Reports and Real-Time Statistics in your Dashboard. Automatically inserts the tracking code in every page of your website.
6
  * Author: ExactMetrics
7
- * Version: 6.4.0
8
  * Requires at least: 3.8.0
9
  * Requires PHP: 5.2
10
  * Author URI: https://exactmetrics.com
@@ -44,7 +44,7 @@ final class ExactMetrics_Lite {
44
  * @access public
45
  * @var string $version Plugin version.
46
  */
47
- public $version = '6.4.0';
48
 
49
  /**
50
  * Plugin file.
@@ -145,6 +145,15 @@ final class ExactMetrics_Lite {
145
  */
146
  public $routes;
147
 
 
 
 
 
 
 
 
 
 
148
  /**
149
  * Primary class constructor.
150
  *
@@ -200,7 +209,7 @@ final class ExactMetrics_Lite {
200
 
201
  // This does the version to version background upgrade routines and initial install
202
  $em_version = get_option( 'exactmetrics_current_version', '5.5.3' );
203
- if ( version_compare( $em_version, '6.4.0', '<' ) ) {
204
  exactmetrics_lite_call_install_and_upgrade();
205
  }
206
 
@@ -546,6 +555,21 @@ final class ExactMetrics_Lite {
546
  require_once EXACTMETRICS_PLUGIN_DIR . 'includes/frontend/seedprod.php';
547
  require_once EXACTMETRICS_PLUGIN_DIR . 'includes/measurement-protocol.php';
548
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  }
550
 
551
  /**
4
  * Plugin URI: https://exactmetrics.com
5
  * Description: Displays Google Analytics Reports and Real-Time Statistics in your Dashboard. Automatically inserts the tracking code in every page of your website.
6
  * Author: ExactMetrics
7
+ * Version: 6.5.0
8
  * Requires at least: 3.8.0
9
  * Requires PHP: 5.2
10
  * Author URI: https://exactmetrics.com
44
  * @access public
45
  * @var string $version Plugin version.
46
  */
47
+ public $version = '6.5.0';
48
 
49
  /**
50
  * Plugin file.
145
  */
146
  public $routes;
147
 
148
+ /**
149
+ * The tracking mode used in the frontend.
150
+ *
151
+ * @since 6.5.0
152
+ * @accces public
153
+ * @var string
154
+ */
155
+ public $tracking_mode;
156
+
157
  /**
158
  * Primary class constructor.
159
  *
209
 
210
  // This does the version to version background upgrade routines and initial install
211
  $em_version = get_option( 'exactmetrics_current_version', '5.5.3' );
212
+ if ( version_compare( $em_version, '6.5.0', '<' ) ) {
213
  exactmetrics_lite_call_install_and_upgrade();
214
  }
215
 
555
  require_once EXACTMETRICS_PLUGIN_DIR . 'includes/frontend/seedprod.php';
556
  require_once EXACTMETRICS_PLUGIN_DIR . 'includes/measurement-protocol.php';
557
  }
558
+
559
+ /**
560
+ * Get the tracking mode for the frontend scripts.
561
+ *
562
+ * @return string
563
+ */
564
+ public function get_tracking_mode() {
565
+
566
+ if ( ! isset( $this->tracking_mode ) ) {
567
+ // This will already be set to 'analytics' to anybody already using the plugin before 6.5.0.
568
+ $this->tracking_mode = exactmetrics_get_option( 'tracking_mode', 'gtag' );
569
+ }
570
+
571
+ return $this->tracking_mode;
572
+ }
573
  }
574
 
575
  /**
includes/em-install.php CHANGED
@@ -93,6 +93,10 @@ class ExactMetrics_Install {
93
  $this->v640_upgrades();
94
  }
95
 
 
 
 
 
96
  // Do not use. See exactmetrics_after_install_routine comment below.
97
  do_action( 'exactmetrics_after_existing_upgrade_routine', $version );
98
  $version = get_option( 'exactmetrics_current_version', $version );
@@ -456,7 +460,8 @@ class ExactMetrics_Install {
456
  'save_settings' => array( 'administrator' ),
457
  'view_reports' => array( 'administrator', 'editor' ),
458
  'events_mode' => 'js',
459
- 'tracking_mode' => 'analytics',
 
460
  'email_summaries' => 'on',
461
  'summaries_html_template' => 'yes',
462
  'summaries_email_addresses' => $admin_email_array,
@@ -667,4 +672,14 @@ class ExactMetrics_Install {
667
  // Delete existing year in review report option.
668
  delete_option( 'exactmetrics_report_data_yearinreview' );
669
  }
 
 
 
 
 
 
 
 
 
 
670
  }
93
  $this->v640_upgrades();
94
  }
95
 
96
+ if ( version_compare( $version, '6.5.0', '<' ) ) {
97
+ $this->v650_upgrades();
98
+ }
99
+
100
  // Do not use. See exactmetrics_after_install_routine comment below.
101
  do_action( 'exactmetrics_after_existing_upgrade_routine', $version );
102
  $version = get_option( 'exactmetrics_current_version', $version );
460
  'save_settings' => array( 'administrator' ),
461
  'view_reports' => array( 'administrator', 'editor' ),
462
  'events_mode' => 'js',
463
+ 'tracking_mode' => 'gtag', // Default new users to gtag.
464
+ 'gtagtracker_compatibility_mode' => true,
465
  'email_summaries' => 'on',
466
  'summaries_html_template' => 'yes',
467
  'summaries_email_addresses' => $admin_email_array,
672
  // Delete existing year in review report option.
673
  delete_option( 'exactmetrics_report_data_yearinreview' );
674
  }
675
+
676
+ /**
677
+ * Upgrade routine for version 6.5.0
678
+ */
679
+ public function v650_upgrades() {
680
+ // Enable gtag compatibility mode by default.
681
+ if ( empty( $this->new_settings['gtagtracker_compatibility_mode'] ) ) {
682
+ $this->new_settings['gtagtracker_compatibility_mode'] = true;
683
+ }
684
+ }
685
  }
includes/frontend/events/class-gtag-events.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Events JS class.
4
+ *
5
+ * @since 6.0.0
6
+ *
7
+ * @package ExactMetrics
8
+ * @subpackage Events
9
+ * @author Chris Christoff
10
+ */
11
+
12
+ // Exit if accessed directly
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ class ExactMetrics_Gtag_Events {
18
+
19
+ /**
20
+ * Holds the name of the events type.
21
+ *
22
+ * @since 6.0.0
23
+ * @access public
24
+ *
25
+ * @var string $name Name of the events type.
26
+ */
27
+ public $name = 'js';
28
+
29
+ /**
30
+ * Version of the events class.
31
+ *
32
+ * @since 6.0.0
33
+ * @access public
34
+ *
35
+ * @var string $version Version of the events class.
36
+ */
37
+ public $version = '1.0.0';
38
+
39
+ /**
40
+ * Primary class constructor.
41
+ *
42
+ * @since 6.0.0
43
+ * @access public
44
+ */
45
+ public function __construct() {
46
+ add_action( 'wp_enqueue_scripts', array( $this, 'output_javascript' ), 9 );
47
+ }
48
+
49
+ /**
50
+ * Outputs the Javascript for JS tracking on the page.
51
+ *
52
+ * @since 6.0.0
53
+ * @access public
54
+ *
55
+ * @return string
56
+ */
57
+ public function output_javascript() {
58
+ // Affiliate Links
59
+ $inbound_paths = exactmetrics_get_option( 'affiliate_links', array() );
60
+ if ( ! is_array( $inbound_paths ) ) {
61
+ $inbound_paths = array();
62
+ } else {
63
+ foreach( $inbound_paths as $index => $pair ) {
64
+ // if empty pair, unset and continue
65
+ if ( empty( $pair['path'] ) ) {
66
+ unset( $inbound_paths[$index] );
67
+ continue;
68
+ }
69
+
70
+ // if path does not start with a /, start it with that
71
+ $path = ! empty( $pair['path'] ) ? $pair['path'] : 'aff';
72
+ $inbound_paths[$index]['path'] = trim( $path );
73
+
74
+ // js escape the link label
75
+ $label = ! empty( $pair['label'] ) ? $pair['label'] : 'aff';
76
+ $inbound_paths[$index]['label'] = esc_js( trim( $label ) );
77
+ }
78
+ }
79
+
80
+ $inbound_paths = wp_json_encode( $inbound_paths );
81
+
82
+ // Get download extensions to track
83
+ $download_extensions = exactmetrics_get_option( 'extensions_of_files', '' );
84
+ $download_extensions = explode( ',', str_replace( '.', '', $download_extensions ) );
85
+ if ( ! is_array( $download_extensions ) ) {
86
+ $download_extensions = array( $download_extensions );
87
+ }
88
+ $i = 0;
89
+ foreach( $download_extensions as $extension ){
90
+ $download_extensions[ $i ] = esc_js( trim( $extension ) );
91
+ $i++;
92
+ }
93
+
94
+ $download_extensions = implode( ",", $download_extensions );
95
+
96
+ $hash_tracking = exactmetrics_get_option( 'hash_tracking', false ) ? 'true' : 'false';
97
+
98
+ $suffix = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) || ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
99
+ if ( ! file_exists( EXACTMETRICS_PLUGIN_DIR . 'assets/js/frontend-gtag.min.js' ) ) {
100
+ $suffix = '';
101
+ }
102
+ wp_enqueue_script( 'exactmetrics-frontend-script', plugins_url( 'assets/js/frontend-gtag' . $suffix . '.js', EXACTMETRICS_PLUGIN_FILE ), array(), exactmetrics_get_asset_version(), false );
103
+ wp_localize_script(
104
+ 'exactmetrics-frontend-script',
105
+ 'exactmetrics_frontend',
106
+ array(
107
+ 'js_events_tracking' => 'true',
108
+ 'download_extensions' => $download_extensions, /* Let's get the extensions to track */
109
+ 'inbound_paths' => $inbound_paths, /* Let's get the internal paths to track */
110
+ 'home_url' => home_url(), /* Let's get the url to compare for external/internal use */
111
+ 'hash_tracking' => $hash_tracking, /* Should hash track */
112
+ 'ua' => exactmetrics_get_ua(), /* UA code used for tracking */
113
+ )
114
+ );
115
+ }
116
+ }
includes/frontend/frontend.php CHANGED
@@ -10,7 +10,7 @@
10
 
11
  // Exit if accessed directly
12
  if ( ! defined( 'ABSPATH' ) ) {
13
- exit;
14
  }
15
 
16
 
@@ -21,31 +21,36 @@ if ( ! defined( 'ABSPATH' ) ) {
21
  * for the frontend_output() function to output. These are
22
  * generally dimensions and turned on GA features.
23
  *
 
24
  * @since 7.0.0
25
  * @access public
26
  *
27
- * @return array Array of the options to use.
28
  */
29
- function exactmetrics_tracking_script( ) {
30
- require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/class-tracking-abstract.php';
31
-
32
- $mode = is_preview() ? 'preview' : 'analytics';
33
-
34
- do_action( 'exactmetrics_tracking_before_' . $mode );
35
- do_action( 'exactmetrics_tracking_before', $mode );
36
- if ( $mode === 'preview' ) {
37
- require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-preview.php';
38
- $tracking = new ExactMetrics_Tracking_Preview();
39
- echo $tracking->frontend_output();
40
- } else {
41
- require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-analytics.php';
42
- $tracking = new ExactMetrics_Tracking_Analytics();
43
- echo $tracking->frontend_output();
44
- }
45
-
46
- do_action( 'exactmetrics_tracking_after_' . $mode );
47
- do_action( 'exactmetrics_tracking_after', $mode );
 
 
 
 
48
  }
 
49
  add_action( 'wp_head', 'exactmetrics_tracking_script', 6 );
50
  //add_action( 'login_head', 'exactmetrics_tracking_script', 6 );
51
 
@@ -56,51 +61,61 @@ add_action( 'wp_head', 'exactmetrics_tracking_script', 6 );
56
  * for the frontend_output() function to output. These are
57
  * generally dimensions and turned on GA features.
58
  *
 
59
  * @since 6.0.0
60
  * @access public
61
  *
62
- * @return array Array of the options to use.
63
  */
64
- function exactmetrics_events_tracking( ) {
65
- $track_user = exactmetrics_track_user();
66
-
67
- if ( $track_user ) {
68
- require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/events/class-analytics-events.php';
69
- new ExactMetrics_Analytics_Events();
70
- } else {
71
- // User is in the disabled group or events mode is off
72
- }
 
 
 
 
 
 
73
  }
 
74
  add_action( 'template_redirect', 'exactmetrics_events_tracking', 9 );
75
 
76
  /**
77
  * Add the UTM source parameters in the RSS feeds to track traffic.
78
  *
79
- * @since 6.0.0
80
- * @access public
81
- *
82
  * @param string $guid The link for the RSS feed.
83
  *
84
  * @return string The new link for the RSS feed.
 
 
 
85
  */
86
  function exactmetrics_rss_link_tagger( $guid ) {
87
- global $post;
88
-
89
- if ( exactmetrics_get_option( 'tag_links_in_rss', false ) ){
90
- if ( is_feed() ) {
91
- if ( exactmetrics_get_option( 'allow_anchor', false ) ) {
92
- $delimiter = '#';
93
- } else {
94
- $delimiter = '?';
95
- if ( strpos( $guid, $delimiter ) > 0 ) {
96
- $delimiter = '&amp;';
97
- }
98
- }
99
- return $guid . $delimiter . 'utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=' . urlencode( $post->post_name );
100
- }
101
- }
102
- return $guid;
 
 
103
  }
 
104
  add_filter( 'the_permalink_rss', 'exactmetrics_rss_link_tagger', 99 );
105
 
106
 
@@ -114,9 +129,9 @@ function exactmetrics_prevent_loading_frontend_reports() {
114
  /**
115
  * Add an admin bar menu item on the frontend.
116
  *
 
117
  * @since 7.5.0
118
  *
119
- * @return void
120
  */
121
  function exactmetrics_add_admin_bar_menu() {
122
  if ( exactmetrics_prevent_loading_frontend_reports() ) {
@@ -127,7 +142,8 @@ function exactmetrics_add_admin_bar_menu() {
127
 
128
  $args = array(
129
  'id' => 'exactmetrics_frontend_button',
130
- 'title' => '<span class="ab-icon dashicons-before dashicons-chart-bar"></span> ExactMetrics', // Maybe allow translation?
 
131
  'href' => '#',
132
  );
133
 
@@ -141,9 +157,9 @@ add_action( 'admin_bar_menu', 'exactmetrics_add_admin_bar_menu', 999 );
141
  /**
142
  * Load the scripts needed for the admin bar.
143
  *
 
144
  * @since 7.5.0
145
  *
146
- * @return void
147
  */
148
  function exactmetrics_frontend_admin_bar_scripts() {
149
  if ( exactmetrics_prevent_loading_frontend_reports() ) {
@@ -234,7 +250,8 @@ function exactmetrics_administrator_tracking_notice() {
234
  ?>
235
  <div class="exactmetrics-tracking-notice exactmetrics-tracking-notice-hide">
236
  <div class="exactmetrics-tracking-notice-icon">
237
- <img src="<?php echo esc_url( plugins_url( 'assets/images/em-mascot.png', EXACTMETRICS_PLUGIN_FILE ) ); ?>" width="40" alt="ExactMetrics Mascot" />
 
238
  </div>
239
  <div class="exactmetrics-tracking-notice-text">
240
  <h3><?php esc_html_e( 'Tracking is Disabled for Administrators', 'google-analytics-dashboard-for-wp' ); ?></h3>
@@ -254,91 +271,91 @@ function exactmetrics_administrator_tracking_notice() {
254
  <div class="exactmetrics-tracking-notice-close">&times;</div>
255
  </div>
256
  <style type="text/css">
257
- .exactmetrics-tracking-notice {
258
- position: fixed;
259
- bottom: 20px;
260
- right: 15px;
261
- font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
262
- background: #fff;
263
- box-shadow: 0 0 10px 0 #dedede;
264
- padding: 6px 5px;
265
- display: flex;
266
- align-items: center;
267
- justify-content: center;
268
- width: 380px;
269
- max-width: calc( 100% - 30px );
270
- border-radius: 6px;
271
- transition: bottom 700ms ease;
272
- z-index: 10000;
273
- }
274
 
275
- .exactmetrics-tracking-notice h3 {
276
- font-size: 13px;
277
- color: #222;
278
- font-weight: 700;
279
- margin: 0 0 8px;
280
- padding: 0;
281
- line-height: 1;
282
- border: none;
283
- }
284
 
285
- .exactmetrics-tracking-notice p {
286
- font-size: 13px;
287
- color: #7f7f7f;
288
- font-weight: 400;
289
- margin: 0;
290
- padding: 0;
291
- line-height: 1.2;
292
- border: none;
293
- }
294
 
295
- .exactmetrics-tracking-notice p a {
296
- color: #7f7f7f;
297
- font-size: 13px;
298
- line-height: 1.2;
299
- margin: 0;
300
- padding: 0;
301
- text-decoration: underline;
302
- font-weight: 400;
303
- }
304
 
305
- .exactmetrics-tracking-notice p a:hover {
306
- color: #7f7f7f;
307
- text-decoration: none;
308
- }
309
 
310
- .exactmetrics-tracking-notice-icon img {
311
- height: auto;
312
- display: block;
313
- margin: 0;
314
- }
315
 
316
- .exactmetrics-tracking-notice-icon {
317
- padding: 14px;
318
- background-color: #f4f3f7;
319
- border-radius: 6px;
320
- flex-grow: 0;
321
- flex-shrink: 0;
322
- margin-right: 12px;
323
- }
324
 
325
- .exactmetrics-tracking-notice-close {
326
- padding: 0;
327
- margin: 0 3px 0 0;
328
- border: none;
329
- box-shadow: none;
330
- border-radius: 0;
331
- color: #7f7f7f;
332
- background: transparent;
333
- line-height: 1;
334
- align-self: flex-start;
335
- cursor: pointer;
336
- font-weight: 400;
337
- }
338
 
339
- .exactmetrics-tracking-notice.exactmetrics-tracking-notice-hide {
340
- bottom: -200px;
341
- }
342
  </style>
343
  <?php
344
 
10
 
11
  // Exit if accessed directly
12
  if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
  }
15
 
16
 
21
  * for the frontend_output() function to output. These are
22
  * generally dimensions and turned on GA features.
23
  *
24
+ * @return array Array of the options to use.
25
  * @since 7.0.0
26
  * @access public
27
  *
 
28
  */
29
+ function exactmetrics_tracking_script() {
30
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/class-tracking-abstract.php';
31
+
32
+ $mode = is_preview() ? 'preview' : ExactMetrics()->get_tracking_mode();
33
+
34
+ do_action( 'exactmetrics_tracking_before_' . $mode );
35
+ do_action( 'exactmetrics_tracking_before', $mode );
36
+ if ( 'preview' === $mode ) {
37
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-preview.php';
38
+ $tracking = new ExactMetrics_Tracking_Preview();
39
+ echo $tracking->frontend_output();
40
+ } else if ( 'gtag' === $mode ) {
41
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-gtag.php';
42
+ $tracking = new ExactMetrics_Tracking_Gtag();
43
+ echo $tracking->frontend_output();
44
+ } else {
45
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/tracking/class-tracking-analytics.php';
46
+ $tracking = new ExactMetrics_Tracking_Analytics();
47
+ echo $tracking->frontend_output();
48
+ }
49
+
50
+ do_action( 'exactmetrics_tracking_after_' . $mode );
51
+ do_action( 'exactmetrics_tracking_after', $mode );
52
  }
53
+
54
  add_action( 'wp_head', 'exactmetrics_tracking_script', 6 );
55
  //add_action( 'login_head', 'exactmetrics_tracking_script', 6 );
56
 
61
  * for the frontend_output() function to output. These are
62
  * generally dimensions and turned on GA features.
63
  *
64
+ * @return array Array of the options to use.
65
  * @since 6.0.0
66
  * @access public
67
  *
 
68
  */
69
+ function exactmetrics_events_tracking() {
70
+ $track_user = exactmetrics_track_user();
71
+
72
+ if ( $track_user ) {
73
+ $tracking_mode = exactmetrics_get_option( 'tracking_mode', 'gtag' );
74
+ if ( 'analytics' === $tracking_mode ) {
75
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/events/class-analytics-events.php';
76
+ new ExactMetrics_Analytics_Events();
77
+ } else {
78
+ require_once plugin_dir_path( EXACTMETRICS_PLUGIN_FILE ) . 'includes/frontend/events/class-gtag-events.php';
79
+ new ExactMetrics_Gtag_Events();
80
+ }
81
+ } else {
82
+ // User is in the disabled group or events mode is off
83
+ }
84
  }
85
+
86
  add_action( 'template_redirect', 'exactmetrics_events_tracking', 9 );
87
 
88
  /**
89
  * Add the UTM source parameters in the RSS feeds to track traffic.
90
  *
 
 
 
91
  * @param string $guid The link for the RSS feed.
92
  *
93
  * @return string The new link for the RSS feed.
94
+ * @since 6.0.0
95
+ * @access public
96
+ *
97
  */
98
  function exactmetrics_rss_link_tagger( $guid ) {
99
+ global $post;
100
+
101
+ if ( exactmetrics_get_option( 'tag_links_in_rss', false ) ) {
102
+ if ( is_feed() ) {
103
+ if ( exactmetrics_get_option( 'allow_anchor', false ) ) {
104
+ $delimiter = '#';
105
+ } else {
106
+ $delimiter = '?';
107
+ if ( strpos( $guid, $delimiter ) > 0 ) {
108
+ $delimiter = '&amp;';
109
+ }
110
+ }
111
+
112
+ return $guid . $delimiter . 'utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=' . urlencode( $post->post_name );
113
+ }
114
+ }
115
+
116
+ return $guid;
117
  }
118
+
119
  add_filter( 'the_permalink_rss', 'exactmetrics_rss_link_tagger', 99 );
120
 
121
 
129
  /**
130
  * Add an admin bar menu item on the frontend.
131
  *
132
+ * @return void
133
  * @since 7.5.0
134
  *
 
135
  */
136
  function exactmetrics_add_admin_bar_menu() {
137
  if ( exactmetrics_prevent_loading_frontend_reports() ) {
142
 
143
  $args = array(
144
  'id' => 'exactmetrics_frontend_button',
145
+ 'title' => '<span class="ab-icon dashicons-before dashicons-chart-bar"></span> ExactMetrics',
146
+ // Maybe allow translation?
147
  'href' => '#',
148
  );
149
 
157
  /**
158
  * Load the scripts needed for the admin bar.
159
  *
160
+ * @return void
161
  * @since 7.5.0
162
  *
 
163
  */
164
  function exactmetrics_frontend_admin_bar_scripts() {
165
  if ( exactmetrics_prevent_loading_frontend_reports() ) {
250
  ?>
251
  <div class="exactmetrics-tracking-notice exactmetrics-tracking-notice-hide">
252
  <div class="exactmetrics-tracking-notice-icon">
253
+ <img src="<?php echo esc_url( plugins_url( 'assets/images/em-mascot.png', EXACTMETRICS_PLUGIN_FILE ) ); ?>"
254
+ width="40" alt="ExactMetrics Mascot"/>
255
  </div>
256
  <div class="exactmetrics-tracking-notice-text">
257
  <h3><?php esc_html_e( 'Tracking is Disabled for Administrators', 'google-analytics-dashboard-for-wp' ); ?></h3>
271
  <div class="exactmetrics-tracking-notice-close">&times;</div>
272
  </div>
273
  <style type="text/css">
274
+ .exactmetrics-tracking-notice {
275
+ position: fixed;
276
+ bottom: 20px;
277
+ right: 15px;
278
+ font-family: Arial, Helvetica, "Trebuchet MS", sans-serif;
279
+ background: #fff;
280
+ box-shadow: 0 0 10px 0 #dedede;
281
+ padding: 6px 5px;
282
+ display: flex;
283
+ align-items: center;
284
+ justify-content: center;
285
+ width: 380px;
286
+ max-width: calc(100% - 30px);
287
+ border-radius: 6px;
288
+ transition: bottom 700ms ease;
289
+ z-index: 10000;
290
+ }
291
 
292
+ .exactmetrics-tracking-notice h3 {
293
+ font-size: 13px;
294
+ color: #222;
295
+ font-weight: 700;
296
+ margin: 0 0 8px;
297
+ padding: 0;
298
+ line-height: 1;
299
+ border: none;
300
+ }
301
 
302
+ .exactmetrics-tracking-notice p {
303
+ font-size: 13px;
304
+ color: #7f7f7f;
305
+ font-weight: 400;
306
+ margin: 0;
307
+ padding: 0;
308
+ line-height: 1.2;
309
+ border: none;
310
+ }
311
 
312
+ .exactmetrics-tracking-notice p a {
313
+ color: #7f7f7f;
314
+ font-size: 13px;
315
+ line-height: 1.2;
316
+ margin: 0;
317
+ padding: 0;
318
+ text-decoration: underline;
319
+ font-weight: 400;
320
+ }
321
 
322
+ .exactmetrics-tracking-notice p a:hover {
323
+ color: #7f7f7f;
324
+ text-decoration: none;
325
+ }
326
 
327
+ .exactmetrics-tracking-notice-icon img {
328
+ height: auto;
329
+ display: block;
330
+ margin: 0;
331
+ }
332
 
333
+ .exactmetrics-tracking-notice-icon {
334
+ padding: 14px;
335
+ background-color: #f4f3f7;
336
+ border-radius: 6px;
337
+ flex-grow: 0;
338
+ flex-shrink: 0;
339
+ margin-right: 12px;
340
+ }
341
 
342
+ .exactmetrics-tracking-notice-close {
343
+ padding: 0;
344
+ margin: 0 3px 0 0;
345
+ border: none;
346
+ box-shadow: none;
347
+ border-radius: 0;
348
+ color: #7f7f7f;
349
+ background: transparent;
350
+ line-height: 1;
351
+ align-self: flex-start;
352
+ cursor: pointer;
353
+ font-weight: 400;
354
+ }
355
 
356
+ .exactmetrics-tracking-notice.exactmetrics-tracking-notice-hide {
357
+ bottom: -200px;
358
+ }
359
  </style>
360
  <?php
361
 
includes/frontend/tracking/class-tracking-gtag.php ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tracking gtag.js class.
4
+ *
5
+ * @since 7.15.0
6
+ *
7
+ * @package ExactMetrics
8
+ * @author Mircea Sandu
9
+ */
10
+
11
+ // Exit if accessed directly
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ class ExactMetrics_Tracking_Gtag extends ExactMetrics_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( 'exactmetrics_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
+