Passed
Push — master ( 6344e6...ea3537 )
by Simon
01:26
created

GoogleAnalyticsReportService::getDimensions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 6
rs 9.4285
1
<?php
2
3
/**
4
 * Class GoogleAnalyticsReportService
5
 *
6
 * Base service for getting the Analytics report per page from Google.
7
 */
8
class GoogleAnalyticsReportService
9
{
10
11
    /**
12
     * @var GoogleClientService
13
     */
14
    protected $client;
15
16
    /**
17
     * @var Google_Service_AnalyticsReporting_DateRange
18
     */
19
    protected $dateRange;
20
21
    /**
22
     * @var Google_Service_AnalyticsReporting
23
     */
24
    protected $analytics;
25
26
    /**
27
     * @var Google_Service_AnalyticsReporting_Metric
28
     */
29
    protected $metrics;
30
31
    /**
32
     * Should the filter being batched
33
     *
34
     * @var bool
35
     */
36
    public $batched = false;
37
38
    /**
39
     * GoogleReportService constructor.
40
     * @param GoogleClientService $client
41
     */
42
    public function __construct($client)
43
    {
44
        $config = SiteConfig::current_site_config();
0 ignored issues
show
Bug introduced by
The type SiteConfig was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
45
        $this->client = $client;
46
        $this->setDateRange($config->DateRange);
47
        $this->setAnalytics(new Google_Service_AnalyticsReporting($client->getClient()));
48
        $this->setMetrics($config->Metric);
49
    }
50
51
    /**
52
     * @return Google_Service_AnalyticsReporting_GetReportsResponse
53
     */
54
    public function getReport()
55
    {
56
        $request = $this->getReportRequest();
57
58
        $body = new Google_Service_AnalyticsReporting_GetReportsRequest();
59
        $body->setReportRequests([$request]);
60
61
        return $this->analytics->reports->batchGet($body);
62
    }
63
64
    /**
65
     * @return Google_Service_AnalyticsReporting_ReportRequest
66
     */
67
    public function getReportRequest()
68
    {
69
        $config = SiteConfig::current_site_config();
70
71
        $request = new Google_Service_AnalyticsReporting_ReportRequest();
72
        $dimension = $this->getDimensions();
73
        $request->setDimensions($dimension);
74
        $request->setViewId($config->Viewid);
75
        $request->setDimensionFilterClauses($this->getDimensionFilterClauses());
76
        $request->setDateRanges($this->getDateRange());
77
        $request->setMetrics([$this->getMetrics()]);
78
79
        return $request;
80
    }
81
82
    public function getDimensions()
83
    {
84
        $dimension = new Google_Service_AnalyticsReporting_Dimension();
85
        $dimension->setName('ga:pagePath');
86
87
        return [$dimension];
88
    }
89
90
    /**
91
     * @return mixed
92
     */
93
    public function getClient()
94
    {
95
        return $this->client;
96
    }
97
98
    /**
99
     * @param mixed $client
100
     */
101
    public function setClient($client)
102
    {
103
        $this->client = $client;
104
    }
105
106
    /**
107
     * @return Google_Service_AnalyticsReporting_DateRange
108
     */
109
    public function getDateRange()
110
    {
111
        return $this->dateRange;
112
    }
113
114
    /**
115
     * @param int $dateRange
116
     */
117
    public function setDateRange($dateRange)
118
    {
119
        $analyticsRange = new Google_Service_AnalyticsReporting_DateRange();
120
        $analyticsRange->setStartDate($dateRange . 'daysAgo');
121
        $analyticsRange->setEndDate('today');
122
        $this->dateRange = $analyticsRange;
123
    }
124
125
    /**
126
     * @return Google_Service_AnalyticsReporting
127
     */
128
    public function getAnalytics()
129
    {
130
        return $this->analytics;
131
    }
132
133
    /**
134
     * @param Google_Service_AnalyticsReporting $analytics
135
     */
136
    public function setAnalytics($analytics)
137
    {
138
        $this->analytics = $analytics;
139
    }
140
141
    /**
142
     * @return mixed
143
     */
144
    public function getMetrics()
145
    {
146
        return $this->metrics;
147
    }
148
149
    /**
150
     * @param mixed $metrics
151
     */
152
    public function setMetrics($metrics)
153
    {
154
        $metric = new Google_Service_AnalyticsReporting_Metric();
155
        $metric->setExpression($metrics);
156
        $this->metrics = $metric;
157
    }
158
159
    /**
160
     * Set up the Dimension Filters
161
     *
162
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
163
     */
164
    public function getDimensionFilters()
165
    {
166
        $filters = [];
167
        $startWith = config::inst()->get(static::class, 'starts_with');
0 ignored issues
show
Bug introduced by
The type config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
168
        $endWith = config::inst()->get(static::class, 'ends_with');
169
        if ($startWith) {
170
            return $this->createFilter('BEGINS_WITH', $startWith, $filters);
171
        }
172
        if ($endWith) {
173
            return $this->createFilter('ENDS_WITH', $endWith, $filters);
174
        }
175
176
        return $this->getPageDimensionFilters();
177
    }
178
179
    /**
180
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
181
     */
182
    public function getPageDimensionFilters()
183
    {
184
        $filters = [];
185
        // Operators are not constants, see here: https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet#Operator
186
        $operator = 'ENDS_WITH';
187
        $pages = $this->getPages();
188
189
        foreach ($pages as $page) {
190
            // Home is recorded as just a slash in GA, we need an
191
            // exception for that
192
            if ($page === 'home') {
193
                $page = '/';
194
                $operator = 'EXACT';
195
            }
196
197
            $filters = $this->createFilter($operator, $page, $filters);
198
            // Reset the operator
199
            if ($operator === 'EXACT') {
200
                $operator = 'ENDS_WITH';
201
            }
202
        }
203
204
        return $filters;
205
    }
206
207
    /**
208
     * @return Google_Service_AnalyticsReporting_DimensionFilterClause
209
     */
210
    public function getDimensionFilterClauses()
211
    {
212
        $dimensionFilters = $this->getDimensionFilters();
213
        $dimensionClauses = new Google_Service_AnalyticsReporting_DimensionFilterClause();
214
        $dimensionClauses->setFilters($dimensionFilters);
215
        $dimensionClauses->setOperator('OR');
216
217
        return $dimensionClauses;
218
    }
219
220
    /**
221
     * Get the pages filtered by optional blacklisting and whitelisting
222
     * Return an array of the URLSegments, to limit memory abuse
223
     * @return array
224
     */
225
    public function getPages()
226
    {
227
        $blacklist = Config::inst()->get(static::class, 'blacklist');
0 ignored issues
show
Bug introduced by
The type Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
228
        $whitelist = Config::inst()->get(static::class, 'whitelist');
229
        /** @var DataList|Page[] $pages */
230
        $pages = SiteTree::get();
0 ignored issues
show
Bug introduced by
The type SiteTree was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
231
        if ($blacklist) {
232
            $pages = $this->getBlacklist($blacklist, $pages);
233
        }
234
        if ($whitelist) {
235
            $pages = $this->getWhitelistPages($whitelist, $pages);
236
        }
237
238
        if ($pages->count() > 20) {
239
            $this->batched = true;
240
        }
241
242
        // Google limits to 20 reports per complex filter setup
243
        return $pages->limit(20)->column('URLSegment');
244
    }
245
246
    /**
247
     * @param array $blacklist
248
     * @param DataList $pages
249
     * @return DataList
250
     */
251
    protected function getBlacklist($blacklist, $pages)
252
    {
253
        $ids = [];
254
        foreach ($blacklist as $class) {
255
            $blacklistpages = $class::get();
256
            $ids = array_merge($ids, $blacklistpages->column('ID'));
257
        }
258
        $pages = $pages->exclude(['ID' => $ids]);
259
260
        return $pages;
261
    }
262
263
    /**
264
     * @param array $whitelist
265
     * @param DataList $pages
266
     * @return DataList
267
     */
268
    protected function getWhitelistPages($whitelist, $pages)
269
    {
270
        $ids = [];
271
        foreach ($whitelist as $class) {
272
            $nowDate = date('Y-m-d');
273
            $whitelistpages = $class::get()
274
                // This needs to be a where because of `IS NULL`
275
                ->where("(`Page`.`LastAnalyticsUpdate` < $nowDate)
276
                        OR (`Page`.`LastAnalyticsUpdate` IS NULL)");
277
            $ids = array_merge($ids, $whitelistpages->column('ID'));
278
        }
279
        $pages = $pages->filter(['ID' => $ids]);
280
281
        return $pages;
282
    }
283
284
    /**
285
     * @param $operator
286
     * @param $page
287
     * @param $filters
288
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
289
     */
290
    protected function createFilter($operator, $page, $filters)
291
    {
292
        $filter = new Google_Service_AnalyticsReporting_DimensionFilter();
293
        $filter->setOperator($operator);
294
        $filter->setCaseSensitive(false);
295
        $filter->setExpressions([$page]);
296
        $filter->setDimensionName('ga:pagePath');
297
        $filters[] = $filter;
298
299
        return $filters;
300
    }
301
}
302