Passed
Push — master ( 0e5cc9...6344e6 )
by Simon
01:22
created

GoogleAnalyticsReportService::getReportRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 12
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
        $request->setDimensions(['name' => 'ga:pagePath']);
73
        $request->setViewId($config->Viewid);
74
        $request->setDimensionFilterClauses($this->getDimensionFilterClauses());
75
        $request->setDateRanges($this->getDateRange());
76
        $request->setMetrics([$this->getMetrics()]);
77
78
        return $request;
79
    }
80
81
    /**
82
     * @return mixed
83
     */
84
    public function getClient()
85
    {
86
        return $this->client;
87
    }
88
89
    /**
90
     * @param mixed $client
91
     */
92
    public function setClient($client)
93
    {
94
        $this->client = $client;
95
    }
96
97
    /**
98
     * @return Google_Service_AnalyticsReporting_DateRange
99
     */
100
    public function getDateRange()
101
    {
102
        return $this->dateRange;
103
    }
104
105
    /**
106
     * @param int $dateRange
107
     */
108
    public function setDateRange($dateRange)
109
    {
110
        $analyticsRange = new Google_Service_AnalyticsReporting_DateRange();
111
        $analyticsRange->setStartDate($dateRange . 'daysAgo');
112
        $analyticsRange->setEndDate('today');
113
        $this->dateRange = $analyticsRange;
114
    }
115
116
    /**
117
     * @return Google_Service_AnalyticsReporting
118
     */
119
    public function getAnalytics()
120
    {
121
        return $this->analytics;
122
    }
123
124
    /**
125
     * @param Google_Service_AnalyticsReporting $analytics
126
     */
127
    public function setAnalytics($analytics)
128
    {
129
        $this->analytics = $analytics;
130
    }
131
132
    /**
133
     * @return mixed
134
     */
135
    public function getMetrics()
136
    {
137
        return $this->metrics;
138
    }
139
140
    /**
141
     * @param mixed $metrics
142
     */
143
    public function setMetrics($metrics)
144
    {
145
        $metric = new Google_Service_AnalyticsReporting_Metric();
146
        $metric->setExpression($metrics);
147
        $this->metrics = $metric;
148
    }
149
150
    /**
151
     * Set up the Dimension Filters
152
     *
153
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
154
     */
155
    public function getDimensionFilters()
156
    {
157
        $filters = [];
158
        $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...
159
        $endWith = config::inst()->get(static::class, 'ends_with');
160
        if ($startWith) {
161
            return $this->createFilter('BEGINS_WITH', $startWith, $filters);
162
        }
163
        if ($endWith) {
164
            return $this->createFilter('ENDS_WITH', $endWith, $filters);
165
        }
166
167
        return $this->getPageDimensionFilters();
168
    }
169
170
    /**
171
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
172
     */
173
    public function getPageDimensionFilters()
174
    {
175
        $filters = [];
176
        // Operators are not constants, see here: https://developers.google.com/analytics/devguides/reporting/core/v4/rest/v4/reports/batchGet#Operator
177
        $operator = 'ENDS_WITH';
178
        $pages = $this->getPages();
179
180
        foreach ($pages as $page) {
181
            // Home is recorded as just a slash in GA, we need an
182
            // exception for that
183
            if ($page === 'home') {
184
                $page = '/';
185
                $operator = 'EXACT';
186
            }
187
188
            $filters = $this->createFilter($operator, $page, $filters);
189
            // Reset the operator
190
            if ($operator === 'EXACT') {
191
                $operator = 'ENDS_WITH';
192
            }
193
        }
194
195
        return $filters;
196
    }
197
198
    /**
199
     * @return Google_Service_AnalyticsReporting_DimensionFilterClause
200
     */
201
    public function getDimensionFilterClauses()
202
    {
203
        $dimensionFilters = $this->getDimensionFilters();
204
        $dimensionClauses = new Google_Service_AnalyticsReporting_DimensionFilterClause();
205
        $dimensionClauses->setFilters($dimensionFilters);
206
        $dimensionClauses->setOperator('OR');
207
208
        return $dimensionClauses;
209
    }
210
211
    /**
212
     * Get the pages filtered by optional blacklisting and whitelisting
213
     * Return an array of the URLSegments, to limit memory abuse
214
     * @return array
215
     */
216
    public function getPages()
217
    {
218
        $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...
219
        $whitelist = Config::inst()->get(static::class, 'whitelist');
220
        /** @var DataList|Page[] $pages */
221
        $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...
222
        if ($blacklist) {
223
            $pages = $this->getBlacklist($blacklist, $pages);
224
        }
225
        if ($whitelist) {
226
            $pages = $this->getWhitelistPages($whitelist, $pages);
227
        }
228
229
        if ($pages->count() > 20) {
230
            $this->batched = true;
231
        }
232
233
        // Google limits to 20 reports per complex filter setup
234
        return $pages->limit(20)->column('URLSegment');
235
    }
236
237
    /**
238
     * @param array $blacklist
239
     * @param DataList $pages
240
     * @return DataList
241
     */
242
    protected function getBlacklist($blacklist, $pages)
243
    {
244
        $ids = [];
245
        foreach ($blacklist as $class) {
246
            $blacklistpages = $class::get();
247
            $ids = array_merge($ids, $blacklistpages->column('ID'));
248
        }
249
        $pages = $pages->exclude(['ID' => $ids]);
250
251
        return $pages;
252
    }
253
254
    /**
255
     * @param array $whitelist
256
     * @param DataList $pages
257
     * @return DataList
258
     */
259
    protected function getWhitelistPages($whitelist, $pages)
260
    {
261
        $ids = [];
262
        foreach ($whitelist as $class) {
263
            $nowDate = date('Y-m-d');
264
            $whitelistpages = $class::get()
265
                // This needs to be a where because of `IS NULL`
266
                ->where("(`Page`.`LastAnalyticsUpdate` < $nowDate)
267
                        OR (`Page`.`LastAnalyticsUpdate` IS NULL)");
268
            $ids = array_merge($ids, $whitelistpages->column('ID'));
269
        }
270
        $pages = $pages->filter(['ID' => $ids]);
271
272
        return $pages;
273
    }
274
275
    /**
276
     * @param $operator
277
     * @param $page
278
     * @param $filters
279
     * @return array|Google_Service_AnalyticsReporting_DimensionFilter[]
280
     */
281
    protected function createFilter($operator, $page, $filters)
282
    {
283
        $filter = new Google_Service_AnalyticsReporting_DimensionFilter();
284
        $filter->setOperator($operator);
285
        $filter->setCaseSensitive(false);
286
        $filter->setExpressions([$page]);
287
        $filter->setDimensionName('ga:pagePath');
288
        $filters[] = $filter;
289
290
        return $filters;
291
    }
292
}
293