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