Passed
Push — 5.0.0 ( f87479...b41ea8 )
by Fèvre
07:54
created

AnalyticsComponent::buildAllTimeVisitors()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 8
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Xetaravel\Http\Components;
6
7
use Carbon\Carbon;
8
use Google\Analytics\Data\V1beta\Filter;
9
use Google\Analytics\Data\V1beta\FilterExpression;
10
use Illuminate\Support\Collection;
11
use Spatie\Analytics\Facades\Analytics;
12
use Spatie\Analytics\OrderBy;
13
use Spatie\Analytics\Period;
14
15
trait AnalyticsComponent
16
{
17
    /**
18
     * Build the yesterday visitors metric.
19
     *
20
     * @return Collection
21
     */
22
    public function buildYesterdayVisitors(): Collection
23
    {
24
        $startDate = Carbon::yesterday()->startOfDay();
25
        $endDate = Carbon::now();
26
27
        return Analytics::get(Period::create($startDate, $endDate), ['screenPageViews'], ['year']);
28
    }
29
30
    /**
31
     * Build the visitors graph for the last 7 days.
32
     *
33
     * @codeCoverageIgnore
34
     *
35
     * @return Collection
36
     */
37
    public function buildVisitorsGraph(): Collection
38
    {
39
        $startDate = Carbon::now()->subDays(7);
40
41
        $visitorsData = Analytics::get(
42
            Period::create($startDate, Carbon::now()),
43
            ['sessions', 'screenPageViews'],
44
            ['date'],
45
            10,
46
            [OrderBy::dimension('date', true)]
47
        );
48
49
        $visitorsData = $visitorsData->map(function ($item) {
50
            $item['date'] = $item['date']->format('Y-m-d');
51
            return $item;
52
        });
53
54
        return $visitorsData->reverse();
55
    }
56
57
    /**
58
     * Build the browser graph from the beginning.
59
     *
60
     * @codeCoverageIgnore
61
     *
62
     * @return Collection
63
     */
64
    public function buildBrowsersGraph(): Collection
65
    {
66
        $startDate = Carbon::createFromFormat('Y-m-d', config('analytics.start_date'));
67
68
        $browsers = ['Chrome', 'Firefox', 'Edge', 'Safari', 'Opera', 'Brave'];
69
70
        $dimensionFilter = new FilterExpression([
71
            'filter' => new Filter([
72
                'field_name' => 'browser',
73
                'in_list_filter' => new Filter\InListFilter([
74
                    'values' => $browsers,
75
                ]),
76
            ]),
77
        ]);
78
79
        $browsersData = collect(Analytics::get(
80
            Period::create($startDate, Carbon::now()),
81
            ['screenPageViews'],
82
            ['browser'],
83
            10,
84
            [],
85
            0,
86
            $dimensionFilter,
87
            true
88
        ))->keyBy('browser');
89
90
        $totalViews = $browsersData->sum('screenPageViews');
91
92
        return collect($browsers)->map(function ($browser) use ($browsersData, $totalViews) {
0 ignored issues
show
Bug introduced by
$browsers of type array<integer,string> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        return collect(/** @scrutinizer ignore-type */ $browsers)->map(function ($browser) use ($browsersData, $totalViews) {
Loading history...
93
            $screenPageViews = $browsersData[$browser]['screenPageViews'] ?? 0;
94
95
            return [
96
                'browser' => $browser,
97
                'color' => $this->getBrowserColor($browser),
98
                'percentage' => $this->getPercentage($screenPageViews, $totalViews),
99
                'screenPageViews' => $screenPageViews,
100
            ];
101
        });
102
    }
103
104
    /**
105
     * Build the devices graph from the last 7 months.
106
     *
107
     * @return Collection
108
     */
109
    public function buildDevicesGraph(): Collection
110
    {
111
        $startDate = Carbon::now()->subMonths(7);
112
113
        $devices = ['Apple', 'Samsung', 'HTC', 'Huawei', 'Microsoft'];
114
115
        $dimensionFilter = new FilterExpression([
116
            'filter' => new Filter([
117
                'field_name' => 'mobileDeviceBranding',
118
                'in_list_filter' => new Filter\InListFilter([
119
                    'values' => $devices,
120
                ]),
121
            ]),
122
        ]);
123
124
        $devicesData = Analytics::get(
125
            Period::create($startDate, Carbon::now()),
126
            ['screenPageViews'],
127
            ['mobileDeviceBranding', 'yearMonth'],
128
            10,
129
            [OrderBy::dimension('mobileDeviceBranding', true)],
130
            0,
131
            $dimensionFilter,
132
            true
133
        )->keyBy(fn ($item) => $item['yearMonth'] . '-' . $item['mobileDeviceBranding']);
134
135
        $devicesGraph = collect();
136
        foreach (range(0, 7) as $i) {
137
            $date = Carbon::now()->subMonths($i);
138
139
            $devicesGraph->put($date->format('Ym'), [
0 ignored issues
show
Bug introduced by
array('period' => $date-...=> 0, 'Microsoft' => 0) of type array<string,integer|mixed> is incompatible with the type Illuminate\Support\TValue expected by parameter $value of Illuminate\Support\Collection::put(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

139
            $devicesGraph->put($date->format('Ym'), /** @scrutinizer ignore-type */ [
Loading history...
140
                'period' => $date->format('Y-m'),
141
                'Apple' => 0,
142
                'Samsung' => 0,
143
                'Google' => 0,
144
                'HTC' => 0,
145
                'Huawei' => 0,
146
                'Microsoft' => 0
147
            ]);
148
        }
149
150
        $devicesGraph = $devicesGraph->map(function ($row, $yearMonth) use ($devicesData, $devices) {
151
            foreach ($devices as $device) {
152
                $key = $yearMonth . '-' . $device;
153
                $row[$device] = $devicesData[$key]['screenPageViews'] ?? 0;
154
            }
155
            return $row;
156
        });
157
158
        return $devicesGraph->reverse();
159
    }
160
161
    /**
162
     * Build the operating system graph from the last 7 months.
163
     *
164
     * @return Collection
165
     */
166
    public function buildOperatingSystemGraph(): Collection
167
    {
168
        $startDate = Carbon::now()->subMonths(7);
169
170
        $operatingSystems = ['Windows', 'Linux', 'Macintosh'];
171
172
        $dimensionFilter = new FilterExpression([
173
            'filter' => new Filter([
174
                'field_name' => 'operatingSystem',
175
                'in_list_filter' => new Filter\InListFilter([
176
                    'values' => $operatingSystems,
177
                ]),
178
            ]),
179
        ]);
180
181
        $operatingSystemData = Analytics::get(
182
            Period::create($startDate, Carbon::now()),
183
            ['screenPageViews'],
184
            ['operatingSystem', 'yearMonth'],
185
            10,
186
            [OrderBy::dimension('operatingSystem', true)],
187
            0,
188
            $dimensionFilter,
189
            true
190
        )->keyBy(fn ($item) => $item['yearMonth'] . '-' . $item['operatingSystem']);
191
192
        $operatingSystemGraph = collect();
193
        foreach (range(0, 7) as $i) {
194
            $date = Carbon::now()->subMonths($i);
195
196
            $operatingSystemGraph->put($date->format('Ym'), [
0 ignored issues
show
Bug introduced by
array('period' => $date-...sh' => 0, 'Linux' => 0) of type array<string,integer|mixed> is incompatible with the type Illuminate\Support\TValue expected by parameter $value of Illuminate\Support\Collection::put(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

196
            $operatingSystemGraph->put($date->format('Ym'), /** @scrutinizer ignore-type */ [
Loading history...
197
                'period' => $date->format('Y-m'),
198
                'Windows' => 0,
199
                'Macintosh' => 0,
200
                'Linux' => 0,
201
            ]);
202
        }
203
204
        $operatingSystemGraph = $operatingSystemGraph->map(function ($row, $yearMonth) use ($operatingSystemData, $operatingSystems) {
205
            foreach ($operatingSystems as $os) {
206
                $key = $yearMonth . '-' . $os;
207
                $row[$os] = $operatingSystemData[$key]['screenPageViews'] ?? 0;
208
            }
209
            return $row;
210
        });
211
212
        return $operatingSystemGraph->reverse();
213
    }
214
215
    /**
216
     * Get the percentage relative to the total page views.
217
     *
218
     * @param int $pageviews The page views.
219
     * @param int $total The total page views.
220
     *
221
     * @return float
222
     */
223
    protected function getPercentage(int $pageviews, int $total): float
224
    {
225
        $percentage = ($pageviews * 100) / $total;
226
227
        return round($percentage, 1);
228
    }
229
230
    /**
231
     * Get the browser color by his name
232
     *
233
     * @param string $browser The name of the browser.
234
     *
235
     * @return string
236
     */
237
    protected function getBrowserColor(string $browser): string
238
    {
239
        return match ($browser) {
240
            'Chrome' => '#00acac',
241
            'Firefox' => '#f4645f',
242
            'Safari' => '#727cb6',
243
            'Opera' => '#348fe2',
244
            'Edge' => '#75e376',
245
            'Brave' => '#ff3a01',
246
            default => '#ddd',
247
        };
248
    }
249
}
250