1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Backend\Modules\Analytics\GoogleClient; |
4
|
|
|
|
5
|
|
|
use Common\ModulesSettings; |
6
|
|
|
use Google_Service_Analytics; |
7
|
|
|
use Google_Service_Analytics_GaData; |
8
|
|
|
use Psr\Cache\CacheItemPoolInterface; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* The class that will do query's on the google analytics API |
12
|
|
|
*/ |
13
|
|
|
final class Connector |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var Google_Service_Analytics |
17
|
|
|
*/ |
18
|
|
|
private $analytics; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var CacheItemPoolInterface |
22
|
|
|
*/ |
23
|
|
|
private $cache; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var ModulesSettings |
27
|
|
|
*/ |
28
|
|
|
private $settings; |
29
|
|
|
|
30
|
7 |
|
public function __construct( |
31
|
|
|
Google_Service_Analytics $analytics, |
32
|
|
|
CacheItemPoolInterface $cache, |
33
|
|
|
ModulesSettings $settings |
34
|
|
|
) { |
35
|
7 |
|
$this->analytics = $analytics; |
36
|
7 |
|
$this->cache = $cache; |
37
|
7 |
|
$this->settings = $settings; |
38
|
7 |
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Returns the amount of pageviews in a period |
42
|
|
|
* |
43
|
|
|
* @param int $startDate |
44
|
|
|
* @param int $endDate |
45
|
|
|
* |
46
|
|
|
* @return int |
47
|
|
|
*/ |
48
|
|
|
public function getPageViews(int $startDate, int $endDate): int |
49
|
|
|
{ |
50
|
|
|
$results = $this->getData($startDate, $endDate); |
51
|
|
|
|
52
|
|
|
return $results['metrics']['ga:pageviews']; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Returns the amount of visitors in a period |
57
|
|
|
* |
58
|
|
|
* @param int $startDate |
59
|
|
|
* @param int $endDate |
60
|
|
|
* |
61
|
|
|
* @return int |
62
|
|
|
*/ |
63
|
|
|
public function getVisitors(int $startDate, int $endDate): int |
64
|
|
|
{ |
65
|
|
|
$results = $this->getData($startDate, $endDate); |
66
|
|
|
|
67
|
|
|
return $results['metrics']['ga:users']; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Returns the amount of pages per visit in a period |
72
|
|
|
* |
73
|
|
|
* @param int $startDate |
74
|
|
|
* @param int $endDate |
75
|
|
|
* |
76
|
|
|
* @return float |
77
|
|
|
*/ |
78
|
|
|
public function getPagesPerVisit(int $startDate, int $endDate): float |
79
|
|
|
{ |
80
|
|
|
$results = $this->getData($startDate, $endDate); |
81
|
|
|
|
82
|
|
|
return $results['metrics']['ga:pageviewsPerSession']; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Returns the average time on the site in a certain period |
87
|
|
|
* |
88
|
|
|
* @param int $startDate |
89
|
|
|
* @param int $endDate |
90
|
|
|
* |
91
|
|
|
* @return float |
92
|
|
|
*/ |
93
|
|
|
public function getTimeOnSite(int $startDate, int $endDate): float |
94
|
|
|
{ |
95
|
|
|
$results = $this->getData($startDate, $endDate); |
96
|
|
|
|
97
|
|
|
return $results['metrics']['ga:avgSessionDuration']; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Returns the percentage of new sessions in a certain period |
102
|
|
|
* |
103
|
|
|
* @param int $startDate |
104
|
|
|
* @param int $endDate |
105
|
|
|
* |
106
|
|
|
* @return float |
107
|
|
|
*/ |
108
|
|
|
public function getNewSessionsPercentage(int $startDate, int $endDate): float |
109
|
|
|
{ |
110
|
|
|
$results = $this->getData($startDate, $endDate); |
111
|
|
|
|
112
|
|
|
return $results['metrics']['ga:percentNewSessions']; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Returns the bounce rate in a certain period |
117
|
|
|
* |
118
|
|
|
* @param int $startDate |
119
|
|
|
* @param int $endDate |
120
|
|
|
* |
121
|
|
|
* @return float |
122
|
|
|
*/ |
123
|
|
|
public function getBounceRate(int $startDate, int $endDate): float |
124
|
|
|
{ |
125
|
|
|
$results = $this->getData($startDate, $endDate); |
126
|
|
|
|
127
|
|
|
return $results['metrics']['ga:bounceRate']; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Returns the visitors graph data |
132
|
|
|
* |
133
|
|
|
* @param int $startDate |
134
|
|
|
* @param int $endDate |
135
|
|
|
* |
136
|
|
|
* @return array |
137
|
|
|
*/ |
138
|
7 |
|
public function getVisitorsGraphData(int $startDate, int $endDate): array |
139
|
|
|
{ |
140
|
7 |
|
$results = $this->getData($startDate, $endDate); |
141
|
|
|
|
142
|
|
|
return $results['visitGraphData']; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Returns the source graph data |
147
|
|
|
* |
148
|
|
|
* @param int $startDate |
149
|
|
|
* @param int $endDate |
150
|
|
|
* |
151
|
|
|
* @return array |
152
|
|
|
*/ |
153
|
7 |
|
public function getSourceGraphData(int $startDate, int $endDate): array |
154
|
|
|
{ |
155
|
7 |
|
$results = $this->getData($startDate, $endDate); |
156
|
|
|
|
157
|
|
|
return $results['sourceGraphData']; |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
/** |
161
|
|
|
* Returns the source graph data |
162
|
|
|
* |
163
|
|
|
* @param int $startDate |
164
|
|
|
* @param int $endDate |
165
|
|
|
* |
166
|
|
|
* @return array |
167
|
|
|
*/ |
168
|
|
|
public function getMostVisitedPagesData(int $startDate, int $endDate): array |
169
|
|
|
{ |
170
|
|
|
$results = $this->getData($startDate, $endDate); |
171
|
|
|
|
172
|
|
|
return $results['pageViews']; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Fetches all the needed data and caches it in our statistics array |
177
|
|
|
* |
178
|
|
|
* @param int $startDate |
179
|
|
|
* @param int $endDate |
180
|
|
|
* |
181
|
|
|
* @return array |
182
|
|
|
*/ |
183
|
7 |
|
private function getData(int $startDate, int $endDate): array |
184
|
|
|
{ |
185
|
7 |
|
$dateRange = $startDate . '-' . $endDate; |
186
|
|
|
|
187
|
7 |
|
$item = $this->cache->getItem('analytics-' . $dateRange); |
188
|
7 |
|
if ($item->isHit()) { |
189
|
|
|
return $item->get(); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
$data = [ |
193
|
7 |
|
'metrics' => $this->getMetrics($startDate, $endDate), |
194
|
|
|
'visitGraphData' => $this->collectVisitGraphData($startDate, $endDate), |
195
|
|
|
'pageViews' => $this->collectMostVisitedPagesData($startDate, $endDate), |
196
|
|
|
'sourceGraphData' => $this->collectSourceGraphData($startDate, $endDate), |
197
|
|
|
]; |
198
|
|
|
|
199
|
|
|
$item->set($data); |
200
|
|
|
$this->cache->save($item); |
201
|
|
|
|
202
|
|
|
return $data; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Fetches some metrics for a certain date range |
207
|
|
|
* |
208
|
|
|
* @param int $startDate |
209
|
|
|
* @param int $endDate |
210
|
|
|
* |
211
|
|
|
* @return array |
212
|
|
|
*/ |
213
|
7 |
|
private function getMetrics(int $startDate, int $endDate): array |
214
|
|
|
{ |
215
|
7 |
|
return $this->getAnalyticsData( |
216
|
7 |
|
$startDate, |
217
|
7 |
|
$endDate, |
218
|
7 |
|
'ga:pageviews,ga:users,ga:pageviewsPerSession,ga:avgSessionDuration,ga:percentNewSessions,ga:bounceRate' |
219
|
|
|
)->getTotalsForAllResults(); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Fetches the data needed to build the visitors graph for a date range |
224
|
|
|
* |
225
|
|
|
* @param int $startDate |
226
|
|
|
* @param int $endDate |
227
|
|
|
* |
228
|
|
|
* @return array |
229
|
|
|
*/ |
230
|
|
|
private function collectVisitGraphData(int $startDate, int $endDate): array |
231
|
|
|
{ |
232
|
|
|
$visitGraphData = $this->getAnalyticsData( |
233
|
|
|
$startDate, |
234
|
|
|
$endDate, |
235
|
|
|
'ga:pageviews,ga:users', |
236
|
|
|
[ |
237
|
|
|
'dimensions' => 'ga:date', |
238
|
|
|
'sort' => 'ga:date', |
239
|
|
|
] |
240
|
|
|
); |
241
|
|
|
|
242
|
|
|
// make sure our column headers are the metric names, not just numbers |
243
|
|
|
$namedRows = []; |
244
|
|
|
foreach ((array) $visitGraphData->getRows() as $dataRow) { |
245
|
|
|
$namedRow = []; |
246
|
|
|
foreach ($dataRow as $key => $value) { |
247
|
|
|
$headerName = $visitGraphData->getColumnHeaders()[$key]['name']; |
248
|
|
|
|
249
|
|
|
// convert the date to a timestamp |
250
|
|
|
if ($headerName === 'ga:date') { |
251
|
|
|
$value = \DateTime::createFromFormat('Ymd H:i:s', $value . ' 00:00:00')->format('U'); |
252
|
|
|
} |
253
|
|
|
$namedRow[str_replace(':', '_', $headerName)] = $value; |
254
|
|
|
} |
255
|
|
|
$namedRows[] = $namedRow; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
return $namedRows; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Fetches the data needed to build the source graph for a date range |
263
|
|
|
* |
264
|
|
|
* @param int $startDate |
265
|
|
|
* @param int $endDate |
266
|
|
|
* |
267
|
|
|
* @return array |
268
|
|
|
*/ |
269
|
|
|
private function collectSourceGraphData(int $startDate, int $endDate): array |
270
|
|
|
{ |
271
|
|
|
$sourceGraphData = $this->getAnalyticsData( |
272
|
|
|
$startDate, |
273
|
|
|
$endDate, |
274
|
|
|
'ga:pageviews', |
275
|
|
|
[ |
276
|
|
|
'dimensions' => 'ga:medium', |
277
|
|
|
'sort' => '-ga:pageviews', |
278
|
|
|
] |
279
|
|
|
); |
280
|
|
|
|
281
|
|
|
// make sure our column headers are the metric names, not just numbers |
282
|
|
|
$namedRows = []; |
283
|
|
|
foreach ((array) $sourceGraphData->getRows() as $dataRow) { |
284
|
|
|
$namedRow = []; |
285
|
|
|
foreach ($dataRow as $key => $value) { |
286
|
|
|
$headerName = $sourceGraphData->getColumnHeaders()[$key]['name']; |
287
|
|
|
$namedRow[str_replace(':', '_', $headerName)] = $value; |
288
|
|
|
} |
289
|
|
|
$namedRows[] = $namedRow; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
return $namedRows; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Fetches the data needed to build the list with most visited pages |
297
|
|
|
* |
298
|
|
|
* @param int $startDate |
299
|
|
|
* @param int $endDate |
300
|
|
|
* |
301
|
|
|
* @return array |
302
|
|
|
*/ |
303
|
|
|
private function collectMostVisitedPagesData(int $startDate, int $endDate): array |
304
|
|
|
{ |
305
|
|
|
$sourceGraphData = $this->getAnalyticsData( |
306
|
|
|
$startDate, |
307
|
|
|
$endDate, |
308
|
|
|
'ga:pageviews', |
309
|
|
|
[ |
310
|
|
|
'dimensions' => 'ga:pagePath', |
311
|
|
|
'sort' => '-ga:pageviews', |
312
|
|
|
'max-results' => 20, |
313
|
|
|
] |
314
|
|
|
); |
315
|
|
|
|
316
|
|
|
// make sure our column headers are the metric names, not just numbers |
317
|
|
|
$namedRows = []; |
318
|
|
|
foreach ((array) $sourceGraphData->getRows() as $dataRow) { |
319
|
|
|
$namedRow = []; |
320
|
|
|
foreach ($dataRow as $key => $value) { |
321
|
|
|
$headerName = $sourceGraphData->getColumnHeaders()[$key]['name']; |
322
|
|
|
$namedRow[str_replace(':', '_', $headerName)] = $value; |
323
|
|
|
} |
324
|
|
|
$namedRows[] = $namedRow; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
return $namedRows; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* Returns Analytics data for our coupled profile |
332
|
|
|
* |
333
|
|
|
* @param int $startDate |
334
|
|
|
* @param int $endDate |
335
|
|
|
* @param string $metrics A comma-separated list of Analytics metrics. |
336
|
|
|
* @param array $optParams Optional parameters. |
337
|
|
|
* |
338
|
|
|
* @return Google_Service_Analytics_GaData |
339
|
|
|
*/ |
340
|
7 |
|
private function getAnalyticsData( |
341
|
|
|
int $startDate, |
342
|
|
|
int $endDate, |
343
|
|
|
string $metrics, |
344
|
|
|
array $optParams = [] |
345
|
|
|
): Google_Service_Analytics_GaData { |
346
|
7 |
|
return $this->analytics->data_ga->get( |
347
|
7 |
|
'ga:' . $this->settings->get('Analytics', 'profile'), |
348
|
7 |
|
date('Y-m-d', $startDate), |
349
|
7 |
|
date('Y-m-d', $endDate), |
350
|
7 |
|
$metrics, |
351
|
7 |
|
$optParams |
352
|
|
|
); |
353
|
|
|
} |
354
|
|
|
} |
355
|
|
|
|