/libraries/joomla/google/embed/analytics.php

https://github.com/pjwiseman/joomla-cms · PHP · 330 lines · 143 code · 37 blank · 150 comment · 6 complexity · 05fac9366628dec10ea666e0fa5f2d03 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Google
  5. *
  6. * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Google Analytics embed class for the Joomla Platform.
  12. *
  13. * @since 12.3
  14. */
  15. class JGoogleEmbedAnalytics extends JGoogleEmbed
  16. {
  17. /**
  18. * Method to get the tracking code
  19. *
  20. * @return string The Google Analytics tracking code
  21. *
  22. * @since 12.3
  23. */
  24. public function getCode()
  25. {
  26. return $this->getOption('code');
  27. }
  28. /**
  29. * Method to set the tracking code
  30. *
  31. * @param string $code The Google Analytics tracking code
  32. *
  33. * @return JGoogleEmbedAnalytics The object for method chaining
  34. *
  35. * @since 12.3
  36. */
  37. public function setCode($code)
  38. {
  39. $this->setOption('code', $code);
  40. return $this;
  41. }
  42. /**
  43. * Checks if the javascript is set to be asynchronous
  44. *
  45. * @return boolean True if asynchronous
  46. *
  47. * @since 12.3
  48. */
  49. public function isAsync()
  50. {
  51. return $this->getOption('async') === null ? true : $this->getOption('async');
  52. }
  53. /**
  54. * Load javascript asynchronously
  55. *
  56. * @return JGoogleEmbedAnalytics The object for method chaining
  57. *
  58. * @since 12.3
  59. */
  60. public function useAsync()
  61. {
  62. $this->setOption('async', true);
  63. return $this;
  64. }
  65. /**
  66. * Load javascript synchronously
  67. *
  68. * @return JGoogleEmbedAnalytics The object for method chaining
  69. *
  70. * @since 12.3
  71. */
  72. public function useSync()
  73. {
  74. $this->setOption('async', false);
  75. return $this;
  76. }
  77. /**
  78. * Add an analytics call
  79. *
  80. * @param string $method The name of the function
  81. * @param array $params The parameters for the call
  82. *
  83. * @return array The added call
  84. *
  85. * @since 12.3
  86. */
  87. public function addCall($method, $params = array())
  88. {
  89. $call = array('name' => $method, 'params' => $params);
  90. $calls = $this->listCalls();
  91. $calls[] = $call;
  92. $this->setOption('calls', $calls);
  93. return $call;
  94. }
  95. /**
  96. * List the analytics calls to be executed
  97. *
  98. * @return array A list of calls
  99. *
  100. * @since 12.3
  101. */
  102. public function listCalls()
  103. {
  104. return $this->getOption('calls') ? $this->getOption('calls') : array();
  105. }
  106. /**
  107. * Delete a call from the stack
  108. *
  109. * @param int $index Index of call to delete (defaults to last added call)
  110. *
  111. * @return array The deleted call
  112. *
  113. * @since 12.3
  114. */
  115. public function deleteCall($index = null)
  116. {
  117. $calls = $this->listCalls();
  118. if ($index === null)
  119. {
  120. $index = count($calls) - 1;
  121. }
  122. $call = $calls[$index];
  123. unset($calls[$index]);
  124. $calls = array_values($calls);
  125. $this->setOption('calls', $calls);
  126. return $call;
  127. }
  128. /**
  129. * Create a javascript function from the call parameters
  130. *
  131. * @param string $method The name of the function
  132. * @param array $params The parameters for the call
  133. *
  134. * @return string The created call
  135. *
  136. * @since 12.3
  137. */
  138. public function createCall($method, $params = array())
  139. {
  140. $params = array_values($params);
  141. if ($this->isAsync())
  142. {
  143. $output = "_gaq.push(['{$method}',";
  144. $output .= substr(json_encode($params), 1, -1);
  145. $output .= ']);';
  146. }
  147. else
  148. {
  149. $output = "pageTracker.{$method}(";
  150. $output .= substr(json_encode($params), 1, -1);
  151. $output .= ');';
  152. }
  153. return $output;
  154. }
  155. /**
  156. * Add a custom variable to the analytics
  157. *
  158. * @param int $slot The slot to store the variable in (1-5)
  159. * @param string $name The variable name
  160. * @param string $value The variable value
  161. * @param int $scope The scope of the variable (1: visitor level, 2: session level, 3: page level)
  162. *
  163. * @return array The added call
  164. *
  165. * @since 12.3
  166. */
  167. public function addCustomVar($slot, $name, $value, $scope = 3)
  168. {
  169. return $this->addCall('_setCustomVar', array($slot, $name, $value, $scope));
  170. }
  171. /**
  172. * Get the code to create a custom analytics variable
  173. *
  174. * @param int $slot The slot to store the variable in (1-5)
  175. * @param string $name The variable name
  176. * @param string $value The variable value
  177. * @param int $scope The scope of the variable (1: visitor level, 2: session level, 3: page level)
  178. *
  179. * @return string The created call
  180. *
  181. * @since 12.3
  182. */
  183. public function createCustomVar($slot, $name, $value, $scope = 3)
  184. {
  185. return $this->createCall('_setCustomVar', array($slot, $name, $value, $scope));
  186. }
  187. /**
  188. * Track an analytics event
  189. *
  190. * @param string $category The general event category
  191. * @param string $action The event action
  192. * @param string $label The event description
  193. * @param string $value The value of the event
  194. * @param boolean $noninteract Don't allow this event to impact bounce statistics
  195. *
  196. * @return array The added call
  197. *
  198. * @since 12.3
  199. */
  200. public function addEvent($category, $action, $label = null, $value = null, $noninteract = false)
  201. {
  202. return $this->addCall('_trackEvent', array($category, $action, $label, $value, $noninteract));
  203. }
  204. /**
  205. * Get the code to track an analytics event
  206. *
  207. * @param string $category The general event category
  208. * @param string $action The event action
  209. * @param string $label The event description
  210. * @param string $value The value of the event
  211. * @param boolean $noninteract Don't allow this event to impact bounce statistics
  212. *
  213. * @return string The created call
  214. *
  215. * @since 12.3
  216. */
  217. public function createEvent($category, $action, $label = null, $value = null, $noninteract = false)
  218. {
  219. return $this->createCall('_trackEvent', array($category, $action, $label, $value, $noninteract));
  220. }
  221. /**
  222. * Get code to load Google Analytics javascript
  223. *
  224. * @return string Javascript code
  225. *
  226. * @since 12.3
  227. */
  228. public function getHeader()
  229. {
  230. if (!$this->isAsync())
  231. {
  232. // Synchronous code is included only in the body
  233. return '';
  234. }
  235. if (!$this->getOption('code'))
  236. {
  237. throw new UnexpectedValueException('A Google Analytics tracking code is required.');
  238. }
  239. $code = $this->getOption('code');
  240. $output = '<script type="text/javascript">';
  241. $output .= 'var _gaq = _gaq || [];';
  242. $output .= "_gaq.push(['_setAccount', '{$code}']);";
  243. foreach ($this->listCalls() as $call)
  244. {
  245. $output .= $this->createCall($call['name'], $call['params']);
  246. }
  247. $output .= '_gaq.push(["_trackPageview"]);';
  248. $output .= '</script>';
  249. return $output;
  250. }
  251. /**
  252. * Google Analytics only needs to be included in the header
  253. *
  254. * @return null
  255. *
  256. * @since 12.3
  257. */
  258. public function getBody()
  259. {
  260. if (!$this->getOption('code'))
  261. {
  262. throw new UnexpectedValueException('A Google Analytics tracking code is required.');
  263. }
  264. $prefix = $this->isSecure() ? 'https://ssl' : 'http://www';
  265. $code = $this->getOption('code');
  266. if ($this->isAsync())
  267. {
  268. $output = '<script type="text/javascript">';
  269. $output .= '(function() {';
  270. $output .= 'var ga = document.createElement("script"); ga.type = "text/javascript"; ga.async = true;';
  271. $output .= "ga.src = '{$prefix}.google-analytics.com/ga.js';";
  272. $output .= 'var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ga, s);';
  273. $output .= '})();';
  274. $output .= '</script>';
  275. }
  276. else
  277. {
  278. $output = '<script type="text/javascript">';
  279. $output .= "document.write(unescape(\"%3Cscript src='{$prefix}.google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E\"));";
  280. $output .= '</script>';
  281. $output .= '<script type="text/javascript">';
  282. $output .= 'try{';
  283. $output .= "var pageTracker = _gat._getTracker('{$code}');";
  284. foreach ($this->listCalls() as $call)
  285. {
  286. $output .= $this->createCall($call['name'], $call['params']);
  287. }
  288. $output .= 'pageTracker._trackPageview();';
  289. $output .= '} catch(err) {}</script>';
  290. }
  291. return $output;
  292. }
  293. }