Kohana_Service_GoogleAnalytics::code()   B
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 15
nc 2
nop 0
1
<?php defined('SYSPATH') OR die('No direct script access.');
2
3
/**
4
 * Google analytics service adapter
5
 * requires 'api-key' configuration
6
 *
7
 * @package    Despark/services-manager
8
 * @author     Ivan Kerin
9
 * @copyright  (c) 2012 Despark Ltd.
10
 * @license    http://creativecommons.org/licenses/by-sa/3.0/legalcode
11
 */
12
abstract class Kohana_Service_GoogleAnalytics extends Service implements Service_Type_Javascript {
13
14
	const SCOPE_VISITOR = 1;
15
16
	const SCOPE_SESSION = 2;
17
18
	const SCOPE_PAGE = 3;
19
20
	protected $_access_token;
21
22
	protected $_events_queue = array();
23
24
	protected $_custom_vars = array();
25
26
	protected $_transaction = array();
27
28
	protected $_items = array();
29
30
	protected $_currency;
31
32
	public function init()
33
	{
34
35
	}
36
37
	public function queue()
38
	{
39
		return $this->_events_queue;
40
	}
41
42
	public function custom_vars()
43
	{
44
		return $this->_custom_vars;
45
	}
46
47
	/**
48
	 * This method accepts four parameters:
49
	 *
50
	 * @param integer index  — The slot for the custom variable. Required.
51
	 * This is a number whose value can range from 1 - 5, inclusive.
52
	 * A custom variable should be placed in one slot only and not be re-used across different slots.
53
	 *
54
	 * @param string $name   — The name for the custom variable. Required.
55
	 * This is a string that identifies the custom variable and appears in the top-level
56
	 * Custom Variables report of the Analytics reports.
57
	 *
58
	 * @param string $value  — The value for the custom variable. Required.
59
	 * This is a string that is paired with a name.
60
	 * You can pair a number of values with a custom variable name.
61
	 * The value appears in the table list of the UI for a selected variable name.
62
	 * Typically, you will have two or more values for a given name.
63
	 * For example, you might define a custom variable name gender and supply male and female as two possible values.
64
	 *
65
	 * @param integer $opt_scope — The scope for the custom variable. Optional.
66
	 * As described above, the scope defines the level of user engagement with your site.
67
	 * It is a number whose possible values are 1 (visitor-level), 2 (session-level),
68
	 * or 3 (page-level). When left undefined, the custom variable scope defaults to page-level interaction.
69
	 */
70
	public function set_custom_var($index, $name, $value, $opt_scope = self::SCOPE_PAGE)
71
	{
72
		if ( ! $this->initialized())
73
			return NULL;
74
75
		$this->_custom_vars[$index] = array(
76
			'index' => $index,
77
			'name' => $name,
78
			'value' => $value,
79
			'opt_scope' => $opt_scope
80
		);
81
	}
82
83
	public function set_currency($currency)
84
	{
85
		if ( ! $this->initialized())
86
			return NULL;
87
88
		$this->_currency = $currency;
89
	}
90
91
	public function set_transaciton(array $transaction)
92
	{
93
		if ( ! $this->initialized())
94
			return NULL;
95
96
		$this->_transaction = $transaction;
97
	}
98
99
	public function set_items(array $items)
100
	{
101
		if ( ! $this->initialized())
102
			return NULL;
103
104
		$this->_items = $items;
105
	}
106
107
	public function track_event($category, $action, $label = NULL, $value = NULL, $opt_noninteraction = NULL)
108
	{
109
		if ( ! $this->initialized())
110
			return NULL;
111
112
		$event_data = array(
113
			'category' => $category,
114
			'action' => $action
115
		);
116
117
		if ($label !== NULL)
118
		{
119
			$event_data['label'] = (string) $label;
120
		}
121
122
		if ($value !== NULL)
123
		{
124
			$event_data['value'] = (int) $value;
125
		}
126
127
		if ($opt_noninteraction !== NULL)
128
		{
129
			$event_data['opt_noninteraction'] = ((bool) $opt_noninteraction) ? 'true':'false';
130
		}
131
132
		$this->_events_queue[] = $event_data;
133
	}
134
135
	/**
136
	 * Render the required code
137
	 * @return string
138
	 */
139
	public function code()
140
	{
141
		if ( ! $this->initialized() OR ! ($api_key = $this->config('api-key')))
142
			return NULL;
143
144
		$events = $this->events_code();
145
		$custom_vars = $this->custom_vars_code();
146
		$ecommerce = $this->ecommerce_code();
147
		$currency = $this->currency_code();
148
149
		return <<<ANALYTICS
150
<script type="text/javascript">
151
	var _gaq = _gaq || [];
152
	_gaq.push(['_setAccount', '{$api_key}']);
153
	_gaq.push(['_trackPageview']);
154
	{$custom_vars}
155
	{$events}
156
	{$currency}
157
	{$ecommerce}
158
	(function() {
159
	  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
160
	  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
161
	  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
162
	})();
163
</script>
164
ANALYTICS;
165
	}
166
167
	protected function events_code()
168
	{
169
		$events = NULL;
170
171
		foreach ($this->queue() as $event)
172
		{
173
			$event_keys = array('category', 'action', 'label', 'value', 'opt_noninteraction');
174
			$params = join(', ', array_filter(Arr::extract($event, $event_keys)));
175
176
			$events .= "_gaq.push(['_trackEvent', {$params}]);\n";
177
		}
178
179
		return $events;
180
	}
181
182
	protected function currency_code()
183
	{
184
		$code = NULL;
185
186
		if ($this->_currency)
187
		{
188
			$code .= "_gaq.push(['_set', 'currencyCode', '{$this->_currency}']);\n";
189
		}
190
191
		return $code;
192
	}
193
194
	protected function ecommerce_code()
195
	{
196
		$code = NULL;
197
198
		if ($this->_transaction AND $this->_items)
199
		{
200
			$transaction_code = array_merge(array('_addTrans'), $this->_transaction);
201
202
			$code .= "_gaq.push(".json_encode($transaction_code).");\n";
203
204
			foreach ($this->_items as $item)
205
			{
206
				$item_code = array_merge(array('_addItem'), $item);
207
				$code .= "_gaq.push(".json_encode($item_code).");\n";
208
			}
209
210
			$code .= "_gaq.push(['_trackTrans']);\n";
211
		}
212
213
		return $code;
214
	}
215
216
	protected function custom_vars_code()
217
	{
218
		$vars = NULL;
219
220
		foreach ($this->custom_vars() as $index => $properties)
221
		{
222
			$vars .= "_gaq.push(['_setCustomVar', {$index}, '{$properties['name']}', \"{$properties['value']}\", {$properties['opt_scope']}]);\n";
223
		}
224
225
		return $vars;
226
	}
227
228
	public function head()
229
	{
230
		return $this->config('in_header') ? $this->code() : NULL;
231
	}
232
233
	public function body()
234
	{
235
		return $this->config('in_header') ? NULL : $this->code();
236
	}
237
}
238