Completed
Pull Request — master (#2923)
by
unknown
21:02 queued 15:53
created

Connector::getMetrics()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1.0046

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 7
ccs 5
cts 6
cp 0.8333
crap 1.0046
rs 10
c 0
b 0
f 0
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