MonsterInsights_Events_PHP

The Google Analytics for WordPress by MonsterInsights MonsterInsights Events PHP class.

Defined (1)

The class is defined in the following location(s).

/includes/frontend/events/class-events-php.php  
  1. class MonsterInsights_Events_PHP { 
  2.  
  3. /** 
  4. * Holds the base class object. 
  5. * @since 6.0.0 
  6. * @access public 
  7. * @var object $base Base class object. 
  8. */ 
  9. public $base; 
  10.  
  11. /** 
  12. * Holds the name of the events type. 
  13. * @since 6.0.0 
  14. * @access public 
  15. * @var string $name Name of the events type. 
  16. */ 
  17. public $name = 'php'; 
  18.  
  19. /** 
  20. * Version of the events class. 
  21. * @since 6.0.0 
  22. * @access public 
  23. * @var string $version Version of the events class. 
  24. */ 
  25. public $version = '1.0.0'; 
  26.  
  27. /** 
  28. * Holds the name of the tracking type. 
  29. * @since 6.0.0 
  30. * @access public 
  31. * @var string $name Name of the tracking type. 
  32. */ 
  33. public $tracking = 'ga'; 
  34.  
  35. /** 
  36. * Primary class constructor. 
  37. * @since 6.0.0 
  38. * @access public 
  39. */ 
  40. public function __construct() { 
  41. $this->base = MonsterInsights(); 
  42. $this->tracking = monsterinsights_get_option( 'tracking_mode', false ); 
  43. $events = monsterinsights_get_option( 'events_mode', false ); 
  44.  
  45. if ( $events === 'php' && ( $this->tracking === 'ga' || $this->tracking === 'analytics' ) ) { 
  46. require_once plugin_dir_path( $this->base->file ) . 'includes/frontend/events/class-link.php'; 
  47. add_filter( 'the_content', array( $this, 'the_content' ), 99 ); 
  48. add_filter( 'the_excerpt', array( $this, 'the_content' ), 99 ); 
  49. add_filter( 'widget_text', array( $this, 'widget_content' ), 99 ); 
  50. add_filter( 'wp_list_bookmarks', array( $this, 'widget_content' ), 99 ); 
  51. add_filter( 'comment_text', array( $this, 'comment_text' ), 99 ); 
  52. add_filter( 'wp_nav_menu', array( $this, 'nav_menu' ), 99 ); 
  53.  
  54. /** 
  55. * Get the regular expression used in ga.js and analytics.js PHP tracking to detect links 
  56. * @since 6.0.0 
  57. * @access protected 
  58. * @todo If we don't remove this soon, it'd be far superior to use a real DOM parser. 
  59. *  
  60. * @return string 
  61. */ 
  62. protected function get_link_regex() { 
  63. return '/' 
  64. . '<a' // matches the characters <a literally 
  65. . '\s' // Match any sort of whitespace 
  66. . '([^>]*)' // 1. match a single character not present in the list (Between 0 and * times) 
  67. . '\s' // match any white space character 
  68. . 'href=' // matches the characters href= literally 
  69. . '([\'\"])' // 2. match a single or a double quote 
  70. . '(' // 3. matches the link protocol (between 0 and 1 times) 
  71. . '([a-zA-Z]+)' // 4. matches the link protocol name 
  72. . ':' // matches the character : literally 
  73. . '(?:\/\/)??' // matches the characters 
  74. . ')??' // literally (between 0 and 1 times) 
  75. . '(.*)' // 5. matches any character (except newline) (Between 0 and * times) 
  76. . '\2' // matches the same quote (2nd capturing group) as was used to open the href value 
  77. . '([^>]*)' // 6. match a single character not present in the list below 
  78. . '>' // matches the characters > literally 
  79. . '(.*)' // 7. matches any character (except newline) (Between 0 and * times) 
  80. . '<\/a>' // matches the characters </a> literally 
  81. . '/isU'; // case insensitive, single line, ungreedy 
  82.  
  83.  
  84. /** 
  85. * Parse the_content or the_excerpt for links 
  86. * @since 6.0.0 
  87. * @access public 
  88. *  
  89. * @param string $text Text to parse 
  90. * @return string The resulting content. 
  91. */ 
  92. public function the_content( $text ) { 
  93. if ( ! is_feed() ) { 
  94. $text = preg_replace_callback( $this->get_link_regex(), array( $this, 'parse_article_link' ), $text ); 
  95. return $text; 
  96.  
  97. /** 
  98. * Parse article link 
  99. * @since 6.0.0 
  100. * @access public 
  101. *  
  102. * @param array $matches The matches for links within the content 
  103. * @return string The parsed link string. 
  104. */ 
  105. public function parse_article_link( $matches ) { 
  106. return $this->parse_link( 'outbound-article', $matches ); 
  107.  
  108. /** 
  109. * Parse the widget content for links 
  110. * @since 6.0.0 
  111. * @access public 
  112. *  
  113. * @param string $text The text to parse. 
  114. * @return string The resulting content. 
  115. */ 
  116. public function widget_content( $text ) { 
  117. $text = preg_replace_callback( $this->get_link_regex(), array( $this, 'parse_widget_link' ), $text ); 
  118. return $text; 
  119.  
  120. /** 
  121. * Parse widget link 
  122. * @since 6.0.0 
  123. * @access public 
  124. *  
  125. * @param array $matches The matches for links within the content 
  126. * @return string The parsed link string. 
  127. */ 
  128. public function parse_widget_link( $matches ) { 
  129. return $this->parse_link( 'outbound-widget', $matches ); 
  130.  
  131. /** 
  132. * Parse the nav menu content for links 
  133. * @since 6.0.0 
  134. * @access public 
  135. *  
  136. * @param string $text The text to parse. 
  137. * @return string The resulting content. 
  138. */ 
  139. public function nav_menu( $text ) { 
  140. $text = preg_replace_callback( $this->get_link_regex(), array( $this, 'parse_nav_menu_link' ), $text ); 
  141. return $text; 
  142.  
  143. /** 
  144. * Parse nav menu link 
  145. * @since 6.0.0 
  146. * @access public 
  147. *  
  148. * @param array $matches The matches for links within the content 
  149. * @return string The parsed link string. 
  150. */ 
  151. public function parse_nav_menu_link( $matches ) { 
  152. return $this->parse_link( 'outbound-menu', $matches ); 
  153.  
  154. /** 
  155. * Parse comment text for links 
  156. * @since 6.0.0 
  157. * @access public 
  158. *  
  159. * @param string $text The text to parse. 
  160. * @return string The resulting content. 
  161. */ 
  162. public function comment_text( $text ) { 
  163. if ( ! is_feed() ) { 
  164. $text = preg_replace_callback( $this->get_link_regex(), array( $this, 'parse_comment_link' ), $text ); 
  165.  
  166. return $text; 
  167.  
  168. /** 
  169. * Parse comment link 
  170. * @since 6.0.0 
  171. * @access public 
  172. *  
  173. * @param array $matches The matches for links within the content 
  174. * @return string The parsed link string. 
  175. */ 
  176. public function parse_comment_link( $matches ) { 
  177. return $this->parse_link( 'outbound-comment', $matches ); 
  178.  
  179.  
  180. /** 
  181. * Merge the existing onclick with a new one and append it 
  182. * @since 6.0.0 
  183. * @access public 
  184. *  
  185. * @param string $link_attribute The new onclick value to append. 
  186. * @param string $onclick The existing onclick value. 
  187. * @return string The resulting link attribute for onclick. 
  188. */ 
  189. public function output_add_onclick( $link_attribute, $onclick ) { 
  190. if ( preg_match( '/onclick=[\'\"](.*?;)[\'\"]/i', $link_attribute, $matches ) > 0 && is_string( $onclick ) ) { 
  191. $onclick_with_double = str_replace( "'", '"', $onclick ); 
  192. $js_snippet_single = 'onclick=\'' . $matches[1] . ' ' . $onclick_with_double . '\''; 
  193. $js_snippet_double = 'onclick="' . $matches[1] . ' ' . $onclick . '"'; 
  194.  
  195. $link_attribute = str_replace( 'onclick="' . $matches[1] . '"', $js_snippet_double, $link_attribute ); 
  196. $link_attribute = str_replace( "onclick='" . $matches[1] . "'", $js_snippet_single, $link_attribute ); 
  197.  
  198. return $link_attribute; 
  199. } else if ( preg_match( '/onclick=[\'\"](.*?)[\'\"]/i', $link_attribute, $matches ) > 0 && is_string( $onclick ) ) { // if not closed, see #33 
  200. $onclick_with_double = str_replace( "'", '"', $onclick ); 
  201. if ( strlen( trim ( $matches[1] ) ) > 0 ) { 
  202. $js_snippet_single = 'onclick=\'' . $matches[1] . '; ' . $onclick_with_double . '\''; 
  203. $js_snippet_double = 'onclick="' . $matches[1] . '; ' . $onclick . '"'; 
  204. } else { 
  205. $js_snippet_single = 'onclick=\'' . $matches[1] . ' ' . $onclick_with_double . '\''; 
  206. $js_snippet_double = 'onclick="' . $matches[1] . ' ' . $onclick . '"';  
  207.  
  208. $link_attribute = str_replace( 'onclick="' . $matches[1] . '"', $js_snippet_double, $link_attribute ); 
  209. $link_attribute = str_replace( "onclick='" . $matches[1] . "'", $js_snippet_single, $link_attribute ); 
  210.  
  211. return $link_attribute; 
  212. } else { 
  213. if ( ! empty( $onclick ) && is_string( $onclick ) ) { 
  214. return 'onclick="' . $onclick . '" ' . $link_attribute; 
  215. } else { 
  216. return $link_attribute; 
  217.  
  218. /** 
  219. * Generate the full URL. 
  220. *  
  221. * Takes an existing link that's missing it's protocol 
  222. * and pre-pends the protocol to it. 
  223. *  
  224. * @since 6.0.0 
  225. * @access public 
  226. *  
  227. * @param MonsterInsights_Link $link The protocol-less link. 
  228. * @return string The resulting link (with pre-pended protocol). 
  229. */ 
  230. public function make_full_url( $link ) { 
  231. $protocol = ''; 
  232. switch ( $link->type ) { 
  233. case 'download': 
  234. case 'internal': 
  235. case 'internal-as-outbound': 
  236. case 'outbound': 
  237. $protocol = ! empty( $link->protocol ) ? $link->protocol . '://' : ''; 
  238. break; 
  239. case 'email': 
  240. $protocol = 'mailto:'; 
  241. break; 
  242.  
  243. return $protocol . $link->original_url; 
  244.  
  245. /** 
  246. * Get the output tracking link 
  247. * @since 6.0.0 
  248. * @access protected 
  249. *  
  250. * @param string $category The category of the link (ex: outbound-widget). 
  251. * @param array $matches The matches found for links within the content. 
  252. * @return string The resulting link. 
  253. */ 
  254. protected function parse_link( $category, $matches ) { 
  255. return $this->output_parse_link( $category, new MonsterInsights_Link( $this->base, $category, $matches ) ); 
  256.  
  257. /** 
  258. * Trims the track_internal_as_label option to prevent commas and whitespaces. 
  259. * @since 6.0.0 
  260. * @access protected 
  261. *  
  262. * @return string The internal label to use. 
  263. */ 
  264. protected function sanitize_internal_label() { 
  265. $label = monsterinsights_get_option( 'track_internal_as_label', '' ); 
  266. if ( ! empty( $label ) && is_string( $label ) ) { 
  267. $label = trim( $label, ', ' ); 
  268. $label = trim( $label ); 
  269.  
  270. // If the label is empty, set a default value 
  271. if ( empty( $label ) ) { 
  272. $label = 'int'; 
  273.  
  274. return $label; 
  275.  
  276. /** 
  277. * Create the event tracking link. 
  278. * @since 6.0.0 
  279. * @access protected 
  280. *  
  281. * @param string $category The category of the label (ex: outbound-widget ). 
  282. * @param MonsterInsights_Link $link_target The link object we're working on. 
  283. * @return string The resultant new <a> tag to use. 
  284. */ 
  285. protected function output_parse_link( $category, $link_target ) { 
  286. $object_name = '__gaTracker'; // $this->tracking === 'analytics' 
  287. if ( $this->tracking === 'ga' ) { 
  288. $object_name = '_gaq.push'; 
  289.  
  290. // bail early for links that we can't handle 
  291. if ( $link_target->type === 'internal' ) { 
  292. return $link_target->hyperlink; 
  293.  
  294. $onclick = null; 
  295. $full_url = $this->make_full_url( $link_target ); 
  296. switch ( $link_target->type ) { 
  297. case 'download': 
  298. if ( $this->tracking === 'ga' ) { 
  299. if ( monsterinsights_get_option('track_download_as', '' ) === 'pageview' ) { 
  300. $onclick = $object_name . "(['_trackPageview', 'download/" . esc_js( $full_url ) . "']);"; 
  301. } else { 
  302. $onclick = $object_name . "(['_trackEvent', 'download', '" . esc_js( $full_url ) . "']);"; 
  303. } else { 
  304. if ( monsterinsights_get_option('track_download_as', '' ) === 'pageview' ) { 
  305. $onclick = $object_name . "('send', 'pageview', '" . esc_js( $full_url ) . "');"; 
  306. } else { 
  307. $onclick = $object_name . "('send', 'event', 'download', '" . esc_js( $full_url ) . "');"; 
  308. break; 
  309. case 'email': 
  310. if ( $this->tracking === 'ga' ) { 
  311. $onclick = $object_name . "(['_trackEvent', 'mailto', '" . esc_js( $link_target->original_url ) . "']);"; 
  312. } else { 
  313. $onclick = $object_name . "('send', 'event', 'mailto', '" . esc_js( $link_target->original_url ) . "');"; 
  314. break; 
  315. case 'internal-as-outbound': 
  316. if ( $this->tracking === 'ga' ) {  
  317. $category = $this->sanitize_internal_label(); 
  318. $onclick = $object_name . "(['_trackEvent', '" . esc_js( $link_target->category ) . '-' . esc_js( $category ) . "', '" . esc_js( $full_url ) . "', '" . esc_js( strip_tags( $link_target->link_text ) ) . "']);"; 
  319. } else { 
  320. $category = $this->sanitize_internal_label(); 
  321. $onclick = $object_name . "('send', '" . esc_js( monsterinsights_get_option('track_download_as', '' ) ) . "', '" . esc_js( $link_target->category ) . '-' . esc_js( $category ) . "', '" . esc_js( $full_url ) . "', '" . esc_js( strip_tags( $link_target->link_text ) ) . "');"; 
  322. break; 
  323. case 'outbound': 
  324. if ( $this->tracking === 'ga' ) {  
  325. $onclick = $object_name . "(['_trackEvent', '" . esc_js( $link_target->category ) . "', '" . esc_js( $full_url ) . "', '" . esc_js( strip_tags( $link_target->link_text ) ) . "']);"; 
  326. } else { 
  327. $onclick = $object_name . "('send', 'event', '" . esc_js( $link_target->category ) . "', '" . esc_js( $full_url ) . "', '" . esc_js( strip_tags( $link_target->link_text ) ) . "');"; 
  328. break; 
  329.  
  330. $link_target->link_attributes = $this->output_add_onclick( $link_target->link_attributes, $onclick ); 
  331.  
  332. if ( ! empty( $link_target->link_attributes ) ) { 
  333. return '<a href="' . $full_url . '" ' . trim( $link_target->link_attributes ) . '>' . $link_target->link_text . '</a>'; 
  334.  
  335. return '<a href="' . $full_url . '">' . $link_target->link_text . '</a>';