tracking-analytics.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. <?php
  2. /**
  3. * Author: ExactMetrics team
  4. * Author URI: https://exactmetrics.com
  5. * Copyright 2018 ExactMetrics team
  6. * License: GPLv2 or later
  7. * License URI: http://www.gnu.org/licenses/gpl-2.0.html
  8. */
  9. // Exit if accessed directly
  10. if ( ! defined( 'ABSPATH' ) )
  11. exit();
  12. if ( ! class_exists( 'GADWP_Tracking_Analytics_Base' ) ) {
  13. class GADWP_Tracking_Analytics_Base {
  14. protected $gadwp;
  15. protected $uaid;
  16. public function __construct() {
  17. $this->gadwp = GADWP();
  18. $profile = GADWP_Tools::get_selected_profile( $this->gadwp->config->options['ga_profiles_list'], $this->gadwp->config->options['tableid_jail'] );
  19. $this->uaid = esc_html( $profile[2] );
  20. }
  21. protected function build_custom_dimensions() {
  22. $custom_dimensions = array();
  23. if ( $this->gadwp->config->options['ga_author_dimindex'] && ( is_single() || is_page() ) ) {
  24. global $post;
  25. $author_id = $post->post_author;
  26. $author_name = get_the_author_meta( 'display_name', $author_id );
  27. $index = (int) $this->gadwp->config->options['ga_author_dimindex'];
  28. $custom_dimensions[$index] = esc_attr( $author_name );
  29. }
  30. if ( $this->gadwp->config->options['ga_pubyear_dimindex'] && is_single() ) {
  31. global $post;
  32. $date = get_the_date( 'Y', $post->ID );
  33. $index = (int) $this->gadwp->config->options['ga_pubyear_dimindex'];
  34. $custom_dimensions[$index] = (int) $date;
  35. }
  36. if ( $this->gadwp->config->options['ga_pubyearmonth_dimindex'] && is_single() ) {
  37. global $post;
  38. $date = get_the_date( 'Y-m', $post->ID );
  39. $index = (int) $this->gadwp->config->options['ga_pubyearmonth_dimindex'];
  40. $custom_dimensions[$index] = esc_attr( $date );
  41. }
  42. if ( $this->gadwp->config->options['ga_category_dimindex'] && is_category() ) {
  43. $fields = array();
  44. $index = (int) $this->gadwp->config->options['ga_category_dimindex'];
  45. $custom_dimensions[$index] = esc_attr( single_tag_title( '', false ) );
  46. }
  47. if ( $this->gadwp->config->options['ga_category_dimindex'] && is_single() ) {
  48. global $post;
  49. $categories = get_the_category( $post->ID );
  50. foreach ( $categories as $category ) {
  51. $index = (int) $this->gadwp->config->options['ga_category_dimindex'];
  52. $custom_dimensions[$index] = esc_attr( $category->name );
  53. break;
  54. }
  55. }
  56. if ( $this->gadwp->config->options['ga_tag_dimindex'] && is_single() ) {
  57. global $post;
  58. $fields = array();
  59. $post_tags_list = '';
  60. $post_tags_array = get_the_tags( $post->ID );
  61. if ( $post_tags_array ) {
  62. foreach ( $post_tags_array as $tag ) {
  63. $post_tags_list .= $tag->name . ', ';
  64. }
  65. }
  66. $post_tags_list = rtrim( $post_tags_list, ', ' );
  67. if ( $post_tags_list ) {
  68. $index = (int) $this->gadwp->config->options['ga_tag_dimindex'];
  69. $custom_dimensions[$index] = esc_attr( $post_tags_list );
  70. }
  71. }
  72. if ( $this->gadwp->config->options['ga_user_dimindex'] ) {
  73. $fields = array();
  74. $index = (int) $this->gadwp->config->options['ga_user_dimindex'];
  75. $custom_dimensions[$index] = is_user_logged_in() ? 'registered' : 'guest';
  76. }
  77. return $custom_dimensions;
  78. }
  79. protected function is_event_tracking( $opt, $with_pagescrolldepth = true ) {
  80. if ( $this->gadwp->config->options['ga_event_tracking'] || $this->gadwp->config->options['ga_aff_tracking'] || $this->gadwp->config->options['ga_hash_tracking'] || $this->gadwp->config->options['ga_formsubmit_tracking'] ) {
  81. return true;
  82. }
  83. if ( $this->gadwp->config->options['ga_pagescrolldepth_tracking'] && $with_pagescrolldepth ) {
  84. return true;
  85. }
  86. return false;
  87. }
  88. }
  89. }
  90. if ( ! class_exists( 'GADWP_Tracking_Analytics_Common' ) ) {
  91. class GADWP_Tracking_Analytics_Common extends GADWP_Tracking_Analytics_Base {
  92. protected $commands;
  93. public function __construct() {
  94. parent::__construct();
  95. $this->load_scripts();
  96. if ( $this->gadwp->config->options['optimize_tracking'] && $this->gadwp->config->options['optimize_pagehiding'] && $this->gadwp->config->options['optimize_containerid'] ) {
  97. add_action( 'wp_head', array( $this, 'optimize_output' ), 99 );
  98. }
  99. }
  100. /**
  101. * Styles & Scripts load
  102. */
  103. private function load_scripts() {
  104. if ( $this->is_event_tracking( true ) ) {
  105. $root_domain = GADWP_Tools::get_root_domain();
  106. wp_enqueue_script( 'gadwp-tracking-analytics-events', GADWP_URL . 'front/js/tracking-analytics-events.js', array( 'jquery' ), GADWP_CURRENT_VERSION, $this->gadwp->config->options['trackingevents_infooter'] );
  107. if ( $this->gadwp->config->options['ga_pagescrolldepth_tracking'] ) {
  108. wp_enqueue_script( 'gadwp-pagescrolldepth-tracking', GADWP_URL . 'front/js/tracking-scrolldepth.js', array( 'jquery' ), GADWP_CURRENT_VERSION, $this->gadwp->config->options['trackingevents_infooter'] );
  109. }
  110. /* @formatter:off */
  111. wp_localize_script( 'gadwp-tracking-analytics-events', 'gadwpUAEventsData', array(
  112. 'options' => array(
  113. 'event_tracking' => $this->gadwp->config->options['ga_event_tracking'],
  114. 'event_downloads' => esc_js($this->gadwp->config->options['ga_event_downloads']),
  115. 'event_bouncerate' => $this->gadwp->config->options['ga_event_bouncerate'],
  116. 'aff_tracking' => $this->gadwp->config->options['ga_aff_tracking'],
  117. 'event_affiliates' => esc_js($this->gadwp->config->options['ga_event_affiliates']),
  118. 'hash_tracking' => $this->gadwp->config->options ['ga_hash_tracking'],
  119. 'root_domain' => $root_domain,
  120. 'event_timeout' => apply_filters( 'gadwp_analyticsevents_timeout', 100 ),
  121. 'event_precision' => $this->gadwp->config->options['ga_event_precision'],
  122. 'event_formsubmit' => $this->gadwp->config->options ['ga_formsubmit_tracking'],
  123. 'ga_pagescrolldepth_tracking' => $this->gadwp->config->options['ga_pagescrolldepth_tracking'],
  124. 'ga_with_gtag' => $this->gadwp->config->options ['ga_with_gtag'],
  125. ),
  126. )
  127. );
  128. /* @formatter:on */
  129. }
  130. }
  131. /**
  132. * Outputs the Google Optimize tracking code
  133. */
  134. public function optimize_output() {
  135. GADWP_Tools::load_view( 'front/views/optimize-code.php', array( 'containerid' => $this->gadwp->config->options['optimize_containerid'] ) );
  136. }
  137. /**
  138. * Sanitizes the output of commands in the tracking code
  139. * @param string $value
  140. * @return string
  141. */
  142. protected function filter( $value, $is_dim = false ) {
  143. if ( 'true' == $value || 'false' == $value || ( is_numeric( $value ) && ! $is_dim ) ) {
  144. return $value;
  145. }
  146. if ( substr( $value, 0, 1 ) == '[' && substr( $value, - 1 ) == ']' || substr( $value, 0, 1 ) == '{' && substr( $value, - 1 ) == '}' ) {
  147. return $value;
  148. }
  149. return "'" . $value . "'";
  150. }
  151. /**
  152. * Retrieves the commands
  153. */
  154. public function get() {
  155. return $this->commands;
  156. }
  157. /**
  158. * Stores the commands
  159. * @param array $commands
  160. */
  161. public function set( $commands ) {
  162. $this->commands = $commands;
  163. }
  164. /**
  165. * Formats the command before being added to the commands
  166. * @param string $command
  167. * @param array $fields
  168. * @param string $fieldsobject
  169. * @return array
  170. */
  171. public function prepare( $command, $fields, $fieldsobject = null ) {
  172. return array( 'command' => $command, 'fields' => $fields, 'fieldsobject' => $fieldsobject );
  173. }
  174. /**
  175. * Adds a formatted command to commands
  176. * @param string $command
  177. * @param array $fields
  178. * @param string $fieldsobject
  179. */
  180. protected function add( $command, $fields, $fieldsobject = null ) {
  181. $this->commands[] = $this->prepare( $command, $fields, $fieldsobject );
  182. }
  183. }
  184. }
  185. if ( ! class_exists( 'GADWP_Tracking_Analytics' ) ) {
  186. class GADWP_Tracking_Analytics extends GADWP_Tracking_Analytics_Common {
  187. public function __construct() {
  188. parent::__construct();
  189. if ( $this->gadwp->config->options['trackingcode_infooter'] ) {
  190. add_action( 'wp_footer', array( $this, 'output' ), 99 );
  191. } else {
  192. add_action( 'wp_head', array( $this, 'output' ), 99 );
  193. }
  194. }
  195. /**
  196. * Builds the commands based on user's options
  197. */
  198. private function build_commands() {
  199. $fields = array();
  200. $fieldsobject = array();
  201. $fields['trackingId'] = $this->uaid;
  202. if ( 1 != $this->gadwp->config->options['ga_speed_samplerate'] ) {
  203. $fieldsobject['siteSpeedSampleRate'] = (int) $this->gadwp->config->options['ga_speed_samplerate'];
  204. }
  205. if ( 100 != $this->gadwp->config->options['ga_user_samplerate'] ) {
  206. $fieldsobject['sampleRate'] = (int) $this->gadwp->config->options['ga_user_samplerate'];
  207. }
  208. if ( $this->gadwp->config->options['ga_crossdomain_tracking'] && '' != $this->gadwp->config->options['ga_crossdomain_list'] ) {
  209. $fieldsobject['allowLinker'] = 'true';
  210. }
  211. if ( ! empty( $this->gadwp->config->options['ga_cookiedomain'] ) ) {
  212. $fieldsobject['cookieDomain'] = $this->gadwp->config->options['ga_cookiedomain'];
  213. } else {
  214. $fields['cookieDomain'] = 'auto';
  215. }
  216. if ( ! empty( $this->gadwp->config->options['ga_cookiename'] ) ) {
  217. $fieldsobject['cookieName'] = $this->gadwp->config->options['ga_cookiename'];
  218. }
  219. if ( ! empty( $this->gadwp->config->options['ga_cookieexpires'] ) ) {
  220. $fieldsobject['cookieExpires'] = (int) $this->gadwp->config->options['ga_cookieexpires'];
  221. }
  222. if ( $this->gadwp->config->options['amp_tracking_clientidapi'] ) {
  223. $fieldsobject['useAmpClientId'] = 'true';
  224. }
  225. $this->add( 'create', $fields, $fieldsobject );
  226. if ( $this->gadwp->config->options['ga_crossdomain_tracking'] && '' != $this->gadwp->config->options['ga_crossdomain_list'] ) {
  227. $fields = array();
  228. $fields['plugin'] = 'linker';
  229. $this->add( 'require', $fields );
  230. $fields = array();
  231. $domains = '';
  232. $domains = explode( ',', $this->gadwp->config->options['ga_crossdomain_list'] );
  233. $domains = array_map( 'trim', $domains );
  234. $domains = strip_tags( implode( "','", $domains ) );
  235. $domains = "['" . $domains . "']";
  236. $fields['domains'] = $domains;
  237. $this->add( 'linker:autoLink', $fields );
  238. }
  239. if ( $this->gadwp->config->options['ga_remarketing'] ) {
  240. $fields = array();
  241. $fields['plugin'] = 'displayfeatures';
  242. $this->add( 'require', $fields );
  243. }
  244. if ( $this->gadwp->config->options['ga_enhanced_links'] ) {
  245. $fields = array();
  246. $fields['plugin'] = 'linkid';
  247. $this->add( 'require', $fields );
  248. }
  249. if ( $this->gadwp->config->options['ga_force_ssl'] ) {
  250. $fields = array();
  251. $fields['option'] = 'forceSSL';
  252. $fields['value'] = 'true';
  253. $this->add( 'set', $fields );
  254. }
  255. $custom_dimensions = $this->build_custom_dimensions();
  256. if ( ! empty( $custom_dimensions ) ) {
  257. foreach ( $custom_dimensions as $index => $value ) {
  258. $fields = array();
  259. $fields['gadwp_dimension'] = 'dimension' . $index;
  260. $fields['gadwp_dim_value'] = $value;
  261. $this->add( 'set', $fields );
  262. }
  263. }
  264. if ( $this->gadwp->config->options['ga_anonymize_ip'] ) {
  265. $fields = array();
  266. $fields['option'] = 'anonymizeIp';
  267. $fields['value'] = 'true';
  268. $this->add( 'set', $fields );
  269. }
  270. if ( 'enhanced' == $this->gadwp->config->options['ecommerce_mode'] ) {
  271. $fields = array();
  272. $fields['plugin'] = 'ec';
  273. $this->add( 'require', $fields );
  274. } else if ( 'standard' == $this->gadwp->config->options['ecommerce_mode'] ) {
  275. $fields = array();
  276. $fields['plugin'] = 'ecommerce';
  277. $this->add( 'require', $fields );
  278. }
  279. if ( $this->gadwp->config->options['optimize_tracking'] && $this->gadwp->config->options['optimize_containerid'] ) {
  280. $fields = array();
  281. $fields['plugin'] = esc_attr( $this->gadwp->config->options['optimize_containerid'] );
  282. $this->add( 'require', $fields );
  283. }
  284. $fields = array();
  285. $fields['hitType'] = 'pageview';
  286. $this->add( 'send', $fields );
  287. do_action( 'gadwp_analytics_commands', $this );
  288. }
  289. /**
  290. * Outputs the Google Analytics tracking code
  291. */
  292. public function output() {
  293. $this->commands = array();
  294. $this->build_commands();
  295. $trackingcode = '';
  296. foreach ( $this->commands as $set ) {
  297. $command = $set['command'];
  298. $fields = '';
  299. foreach ( $set['fields'] as $fieldkey => $fieldvalue ) {
  300. if ( false === strpos( $fieldkey, 'gadwp_dim_value' ) ) {
  301. $fieldvalue = $this->filter( $fieldvalue );
  302. } else {
  303. $fieldvalue = $this->filter( $fieldvalue, true );
  304. }
  305. $fields .= ", " . $fieldvalue;
  306. }
  307. if ( $set['fieldsobject'] ) {
  308. $fieldsobject = ", {";
  309. foreach ( $set['fieldsobject'] as $fieldkey => $fieldvalue ) {
  310. $fieldvalue = $this->filter( $fieldvalue );
  311. $fieldkey = $this->filter( $fieldkey );
  312. $fieldsobject .= $fieldkey . ": " . $fieldvalue . ", ";
  313. }
  314. $fieldsobject = rtrim( $fieldsobject, ", " );
  315. $fieldsobject .= "}";
  316. $trackingcode .= " ga('" . $command . "'" . $fields . $fieldsobject . ");\n";
  317. } else {
  318. $trackingcode .= " ga('" . $command . "'" . $fields . ");\n";
  319. }
  320. }
  321. $tracking_script_path = apply_filters( 'gadwp_analytics_script_path', 'https://www.google-analytics.com/analytics.js' );
  322. if ( $this->gadwp->config->options['ga_optout'] || $this->gadwp->config->options['ga_dnt_optout'] ) {
  323. GADWP_Tools::load_view( 'front/views/analytics-optout-code.php', array( 'uaid' => $this->uaid, 'gaDntOptout' => $this->gadwp->config->options['ga_dnt_optout'], 'gaOptout' => $this->gadwp->config->options['ga_optout'] ) );
  324. }
  325. GADWP_Tools::load_view( 'front/views/analytics-code.php', array( 'trackingcode' => $trackingcode, 'tracking_script_path' => $tracking_script_path, 'ga_with_gtag' => $this->gadwp->config->options['ga_with_gtag'] , 'uaid' => $this->uaid ) );
  326. }
  327. }
  328. }
  329. if ( ! class_exists( 'GADWP_Tracking_GlobalSiteTag' ) ) {
  330. class GADWP_Tracking_GlobalSiteTag extends GADWP_Tracking_Analytics_Common {
  331. public function __construct() {
  332. parent::__construct();
  333. if ( $this->gadwp->config->options['trackingcode_infooter'] ) {
  334. add_action( 'wp_footer', array( $this, 'output' ), 99 );
  335. } else {
  336. add_action( 'wp_head', array( $this, 'output' ), 99 );
  337. }
  338. }
  339. /**
  340. * Builds the commands based on user's options
  341. */
  342. private function build_commands() {
  343. $fields = array();
  344. $fieldsobject = array();
  345. $fields['trackingId'] = $this->uaid;
  346. $custom_dimensions = $this->build_custom_dimensions();
  347. /*
  348. * if ( 1 != $this->gadwp->config->options['ga_speed_samplerate'] ) {
  349. * $fieldsobject['siteSpeedSampleRate'] = (int) $this->gadwp->config->options['ga_speed_samplerate'];
  350. * }
  351. */
  352. if ( ! empty( $this->gadwp->config->options['ga_cookiedomain'] ) ) {
  353. $fieldsobject['cookie_domain'] = $this->gadwp->config->options['ga_cookiedomain'];
  354. }
  355. if ( ! empty( $this->gadwp->config->options['ga_cookiename'] ) ) {
  356. $fieldsobject['cookie_name'] = $this->gadwp->config->options['ga_cookiename'];
  357. }
  358. if ( ! empty( $this->gadwp->config->options['ga_cookieexpires'] ) ) {
  359. $fieldsobject['cookie_expires'] = (int) $this->gadwp->config->options['ga_cookieexpires'];
  360. }
  361. /*
  362. * if ( $this->gadwp->config->options['amp_tracking_clientidapi'] ) {
  363. * $fieldsobject['useAmpClientId'] = 'true';
  364. * }
  365. */
  366. if ( $this->gadwp->config->options['ga_crossdomain_tracking'] && '' != $this->gadwp->config->options['ga_crossdomain_list'] ) {
  367. $domains = '';
  368. $domains = explode( ',', $this->gadwp->config->options['ga_crossdomain_list'] );
  369. $domains = array_map( 'trim', $domains );
  370. $domains = strip_tags( implode( "','", $domains ) );
  371. $domains = "['" . $domains . "']";
  372. $fieldsobject['linker'] = "{ 'domains' : " . $domains . " }";
  373. }
  374. if ( ! $this->gadwp->config->options['ga_remarketing'] ) {
  375. $fieldsobject['allow_display_features'] = 'false';
  376. }
  377. if ( $this->gadwp->config->options['ga_enhanced_links'] ) {
  378. $fieldsobject['link_attribution'] = 'true';
  379. }
  380. if ( $this->gadwp->config->options['ga_anonymize_ip'] ) {
  381. $fieldsobject['anonymize_ip'] = 'true';
  382. }
  383. if ( $this->gadwp->config->options['optimize_tracking'] && $this->gadwp->config->options['optimize_containerid'] ) {
  384. $fieldsobject['optimize_id'] = esc_attr( $this->gadwp->config->options['optimize_containerid'] );
  385. }
  386. if ( 100 != $this->gadwp->config->options['ga_user_samplerate'] ) {
  387. $fieldsobject['sample_rate'] = (int) $this->gadwp->config->options['ga_user_samplerate'];
  388. }
  389. if ( ! empty( $custom_dimensions ) ) {
  390. $fieldsobject['custom_map'] = "{\n\t\t";
  391. foreach ( $custom_dimensions as $index => $value ) {
  392. $fieldsobject['custom_map'] .= "'dimension" . $index . "': '" . "gadwp_dim_" . $index . "', \n\t\t";
  393. }
  394. $fieldsobject['custom_map'] = rtrim( $fieldsobject['custom_map'], ", \n\t\t" );
  395. $fieldsobject['custom_map'] .= "\n\t}";
  396. }
  397. $this->add( 'config', $fields, $fieldsobject );
  398. if ( ! empty( $custom_dimensions ) ) {
  399. $fields = array();
  400. $fieldsobject = array();
  401. $fields['event_name'] = 'gadwp_dimensions';
  402. foreach ( $custom_dimensions as $index => $value ) {
  403. $fieldsobject['gadwp_dim_' . $index] = $value;
  404. }
  405. $this->add( 'event', $fields, $fieldsobject );
  406. }
  407. do_action( 'gadwp_gtag_commands', $this );
  408. }
  409. /**
  410. * Outputs the Google Analytics tracking code
  411. */
  412. public function output() {
  413. $this->commands = array();
  414. $this->build_commands();
  415. $trackingcode = '';
  416. foreach ( $this->commands as $set ) {
  417. $command = $set['command'];
  418. $fields = '';
  419. foreach ( $set['fields'] as $fieldkey => $fieldvalue ) {
  420. $fieldvalue = $this->filter( $fieldvalue );
  421. $fields .= ", " . $fieldvalue;
  422. }
  423. if ( $set['fieldsobject'] ) {
  424. $fieldsobject = ", {\n\t";
  425. foreach ( $set['fieldsobject'] as $fieldkey => $fieldvalue ) {
  426. if ( false === strpos( $fieldkey, 'gadwp_' ) ) {
  427. $fieldvalue = $this->filter( $fieldvalue );
  428. } else {
  429. $fieldvalue = $this->filter( $fieldvalue, true );
  430. }
  431. $fieldkey = $this->filter( $fieldkey );
  432. $fieldsobject .= $fieldkey . ": " . $fieldvalue . ", \n\t";
  433. }
  434. $fieldsobject = rtrim( $fieldsobject, ", \n\t" );
  435. $fieldsobject .= "\n }";
  436. $trackingcode .= " gtag('" . $command . "'" . $fields . $fieldsobject . ");\n";
  437. } else {
  438. $trackingcode .= " gtag('" . $command . "'" . $fields . ");\n";
  439. }
  440. }
  441. $tracking_script_path = apply_filters( 'gadwp_gtag_script_path', 'https://www.googletagmanager.com/gtag/js' );
  442. if ( $this->gadwp->config->options['ga_optout'] || $this->gadwp->config->options['ga_dnt_optout'] ) {
  443. GADWP_Tools::load_view( 'front/views/analytics-optout-code.php', array( 'uaid' => $this->uaid, 'gaDntOptout' => $this->gadwp->config->options['ga_dnt_optout'], 'gaOptout' => $this->gadwp->config->options['ga_optout'] ) );
  444. }
  445. GADWP_Tools::load_view( 'front/views/analytics-code.php', array( 'trackingcode' => $trackingcode, 'tracking_script_path' => $tracking_script_path, 'ga_with_gtag' => $this->gadwp->config->options['ga_with_gtag'] , 'uaid' => $this->uaid ) );
  446. }
  447. }
  448. }
  449. if ( ! class_exists( 'GADWP_Tracking_Analytics_AMP' ) ) {
  450. class GADWP_Tracking_Analytics_AMP extends GADWP_Tracking_Analytics_Base {
  451. private $config;
  452. public function __construct() {
  453. parent::__construct();
  454. add_filter( 'amp_post_template_data', array( $this, 'load_scripts' ) );
  455. add_action( 'amp_post_template_footer', array( $this, 'output' ) );
  456. add_filter( 'the_content', array( $this, 'add_data_attributes' ), 999, 1 );
  457. if ( $this->gadwp->config->options['amp_tracking_clientidapi'] ) {
  458. add_action( 'amp_post_template_head', array( $this, 'add_amp_client_id' ) );
  459. }
  460. }
  461. private function get_link_event_data( $link ) {
  462. if ( empty( $link ) ) {
  463. return false;
  464. }
  465. if ( $this->gadwp->config->options['ga_event_tracking'] ) {
  466. // on changes adjust the substr() length parameter
  467. if ( substr( $link, 0, 7 ) === "mailto:" ) {
  468. return array( 'email', 'send', $link );
  469. }
  470. // on changes adjust the substr() length parameter
  471. if ( substr( $link, 0, 4 ) === "tel:" ) {
  472. return array( 'telephone', 'call', $link );
  473. }
  474. // Add download data-vars
  475. if ( $this->gadwp->config->options['ga_event_downloads'] && preg_match( '/.*\.(' . $this->gadwp->config->options['ga_event_downloads'] . ')(\?.*)?$/i', $link, $matches ) ) {
  476. return array( 'download', 'click', $link );
  477. }
  478. }
  479. if ( $this->gadwp->config->options['ga_hash_tracking'] ) {
  480. // Add hashmark data-vars
  481. $root_domain = GADWP_Tools::get_root_domain();
  482. if ( $root_domain && ( strpos( $link, $root_domain ) > - 1 || strpos( $link, '://' ) === false ) && strpos( $link, '#' ) > - 1 ) {
  483. return array( 'hashmark', 'click', $link );
  484. }
  485. }
  486. if ( $this->gadwp->config->options['ga_aff_tracking'] ) {
  487. // Add affiliate data-vars
  488. if ( strpos( $link, $this->gadwp->config->options['ga_event_affiliates'] ) > - 1 ) {
  489. return array( 'affiliates', 'click', $link );
  490. }
  491. }
  492. if ( $this->gadwp->config->options['ga_event_tracking'] ) {
  493. // Add outbound data-vars
  494. $root_domain = GADWP_Tools::get_root_domain();
  495. if ( $root_domain && strpos( $link, $root_domain ) === false && strpos( $link, '://' ) > - 1 ) {
  496. return array( 'outbound', 'click', $link );
  497. }
  498. }
  499. return false;
  500. }
  501. public function add_data_attributes( $content ) {
  502. if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && $this->is_event_tracking( false ) ) {
  503. $dom = GADWP_Tools::get_dom_from_content( $content );
  504. if ( $dom ) {
  505. $links = $dom->getElementsByTagName( 'a' );
  506. foreach ( $links as $item ) {
  507. $data_attributes = $this->get_link_event_data( $item->getAttribute( 'href' ) );
  508. if ( $data_attributes ) {
  509. if ( ! $item->hasAttribute( 'data-vars-ga-category' ) ) {
  510. $item->setAttribute( 'data-vars-ga-category', $data_attributes[0] );
  511. }
  512. if ( ! $item->hasAttribute( 'data-vars-ga-action' ) ) {
  513. $item->setAttribute( 'data-vars-ga-action', $data_attributes[1] );
  514. }
  515. if ( ! $item->hasAttribute( 'data-vars-ga-label' ) ) {
  516. $item->setAttribute( 'data-vars-ga-label', $data_attributes[2] );
  517. }
  518. }
  519. }
  520. if ( $this->gadwp->config->options['ga_formsubmit_tracking'] ) {
  521. $form_submits = $dom->getElementsByTagName( 'input' );
  522. foreach ( $form_submits as $item ) {
  523. if ( $item->getAttribute( 'type' ) == 'submit' ) {
  524. if ( ! $item->hasAttribute( 'data-vars-ga-category' ) ) {
  525. $item->setAttribute( 'data-vars-ga-category', 'form' );
  526. }
  527. if ( ! $item->hasAttribute( 'data-vars-ga-action' ) ) {
  528. $item->setAttribute( 'data-vars-ga-action', 'submit' );
  529. }
  530. if ( ! $item->hasAttribute( 'data-vars-ga-label' ) ) {
  531. if ( $item->getAttribute( 'value' ) ) {
  532. $label = $item->getAttribute( 'value' );
  533. }
  534. if ( $item->getAttribute( 'name' ) ) {
  535. $label = $item->getAttribute( 'name' );
  536. }
  537. $item->setAttribute( 'data-vars-ga-label', $label );
  538. }
  539. }
  540. }
  541. }
  542. return GADWP_Tools::get_content_from_dom( $dom );
  543. }
  544. }
  545. return $content;
  546. }
  547. /**
  548. * Inserts the Analytics AMP script in the head section
  549. */
  550. public function load_scripts( $data ) {
  551. if ( ! isset( $data['amp_component_scripts'] ) ) {
  552. $data['amp_component_scripts'] = array();
  553. }
  554. $data['amp_component_scripts']['amp-analytics'] = 'https://cdn.ampproject.org/v0/amp-analytics-0.1.js';
  555. return $data;
  556. }
  557. /**
  558. * Retrieves the AMP config array
  559. */
  560. public function get() {
  561. return $this->config;
  562. }
  563. /**
  564. * Stores the AMP config array
  565. * @param array $config
  566. */
  567. public function set( $config ) {
  568. $this->config = $config;
  569. }
  570. private function build_json() {
  571. $this->config = array();
  572. // Set the Tracking ID
  573. /* @formatter:off */
  574. $this->config['vars'] = array(
  575. 'account' => $this->uaid,
  576. 'documentLocation' => '${canonicalUrl}',
  577. );
  578. /* @formatter:on */
  579. // Set Custom Dimensions as extraUrlParams
  580. $custom_dimensions = $this->build_custom_dimensions();
  581. if ( ! empty( $custom_dimensions ) ) {
  582. foreach ( $custom_dimensions as $index => $value ) {
  583. $dimension = 'cd' . $index;
  584. $this->config['extraUrlParams'][$dimension] = $value;
  585. }
  586. }
  587. // Set Triggers
  588. /* @formatter:off */
  589. $this->config['triggers']['gadwpTrackPageview'] = array(
  590. 'on' => 'visible',
  591. 'request' => 'pageview',
  592. );
  593. /* @formatter:on */
  594. // Set Sampling Rate only if lower than 100%
  595. if ( 100 != $this->gadwp->config->options['ga_user_samplerate'] ) {
  596. /* @formatter:off */
  597. $this->config['triggers']['gadwpTrackPageview']['sampleSpec'] = array(
  598. 'sampleOn' => '${clientId}',
  599. 'threshold' => (int) $this->gadwp->config->options['ga_user_samplerate'],
  600. );
  601. /* @formatter:on */
  602. }
  603. // Set Scroll events
  604. if ( $this->gadwp->config->options['ga_pagescrolldepth_tracking'] ) {
  605. /* @formatter:off */
  606. $this->config['triggers']['gadwpScrollPings'] = array (
  607. 'on' => 'scroll',
  608. 'scrollSpec' => array(
  609. 'verticalBoundaries' => '&#91;25, 50, 75, 100&#93;',
  610. ),
  611. 'request' => 'event',
  612. 'vars' => array(
  613. 'eventCategory' => 'Scroll Depth',
  614. 'eventAction' => 'Percentage',
  615. 'eventLabel' => '${verticalScrollBoundary}%',
  616. ),
  617. );
  618. /* @formatter:on */
  619. $this->config['triggers']['gadwpScrollPings']['extraUrlParams'] = array( 'ni' => true );
  620. }
  621. if ( $this->is_event_tracking( false ) ) {
  622. // Set downloads, outbound links, affiliate links, hashmarks, e-mails, telephones, form submits events
  623. /* @formatter:off */
  624. $this->config['triggers']['gadwpEventTracking'] = array (
  625. 'on' => 'click',
  626. 'selector' => '[data-vars-ga-category][data-vars-ga-action][data-vars-ga-label]',
  627. 'request' => 'event',
  628. 'vars' => array(
  629. 'eventCategory' => '${gaCategory}',
  630. 'eventAction' => '${gaAction}',
  631. 'eventLabel' => '${gaLabel}',
  632. ),
  633. );
  634. /* @formatter:on */
  635. if ( $this->gadwp->config->options['ga_event_bouncerate'] ) {
  636. $this->config['triggers']['gadwpEventTracking']['extraUrlParams'] = array( 'ni' => (bool) $this->gadwp->config->options['ga_event_bouncerate'] );
  637. }
  638. }
  639. do_action( 'gadwp_analytics_amp_config', $this );
  640. }
  641. public function add_amp_client_id() {
  642. GADWP_Tools::load_view( 'front/views/analytics-amp-clientidapi.php' );
  643. }
  644. /**
  645. * Outputs the Google Analytics tracking code for AMP
  646. */
  647. public function output() {
  648. $this->build_json();
  649. if ( version_compare( phpversion(), '5.4.0', '<' ) ) {
  650. $json = json_encode( $this->config );
  651. } else {
  652. $json = json_encode( $this->config, JSON_PRETTY_PRINT );
  653. }
  654. $json = str_replace( array( '"&#91;', '&#93;"' ), array( '[', ']' ), $json ); // make verticalBoundaries a JavaScript array
  655. $data = array( 'json' => $json );
  656. GADWP_Tools::load_view( 'front/views/analytics-amp-code.php', $data );
  657. }
  658. }
  659. }