Issues (264)

app/Http/Components/AnalyticsComponent.php (3 issues)

Labels
Severity
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
     * Get the percentage relative to the total page views.
19
     *
20
     * @param int $pageviews The page views.
21
     * @param int $total The total page views.
22
     *
23
     * @return float
24
     */
25
    protected function getPercentage(int $pageviews, int $total): float
26
    {
27
        $percentage = ($pageviews * 100) / $total;
28
29
        return round($percentage, 1);
30
    }
31
32
    /**
33
     * Get the browser color by his name
34
     *
35
     * @param string $browser The name of the browser.
36
     *
37
     * @return string
38
     */
39
    protected function getBrowserColor(string $browser): string
40
    {
41
        return match ($browser) {
42
            'Chrome' => '#00acac',
43
            'Firefox' => '#f4645f',
44
            'Safari' => '#727cb6',
45
            'Opera' => '#348fe2',
46
            'Edge' => '#75e376',
47
            'Brave' => '#ff3a01',
48
            default => '#ddd',
49
        };
50
    }
51
    /**
52
     * Build the yesterday visitors metric.
53
     *
54
     * @return Collection
55
     */
56
    public function buildYesterdayVisitors(): Collection
57
    {
58
        $startDate = Carbon::yesterday()->startOfDay();
59
        $endDate = Carbon::yesterday()->endOfDay();
60
61
        return Analytics::get(Period::create($startDate, $endDate), ['screenPageViews'], ['year']);
62
    }
63
64
    /**
65
     * Build the visitors graph for the last 7 days.
66
     *
67
     * @codeCoverageIgnore
68
     *
69
     * @return Collection
70
     */
71
    public function buildVisitorsGraph(): Collection
72
    {
73
        $startDate = Carbon::now()->subDays(7);
74
75
        $visitorsData = Analytics::get(
76
            Period::create($startDate, Carbon::now()),
77
            ['sessions', 'screenPageViews'],
78
            ['date'],
79
            10,
80
            [OrderBy::dimension('date', true)]
81
        );
82
83
        $visitorsData = $visitorsData->map(function ($item) {
84
            $item['date'] = $item['date']->format('Y-m-d');
85
            return $item;
86
        });
87
88
        return $visitorsData->reverse();
89
    }
90
91
    /**
92
     * Build the browser graph from the beginning.
93
     *
94
     * @codeCoverageIgnore
95
     *
96
     * @return Collection
97
     */
98
    public function buildBrowsersGraph(): Collection
99
    {
100
        $startDate = Carbon::createFromFormat('Y-m-d', config('analytics.start_date'));
101
102
        $browsers = ['Chrome', 'Firefox', 'Edge', 'Safari', 'Opera', 'Brave'];
103
104
        $dimensionFilter = new FilterExpression([
105
            'filter' => new Filter([
106
                'field_name' => 'browser',
107
                'in_list_filter' => new Filter\InListFilter([
108
                    'values' => $browsers,
109
                ]),
110
            ]),
111
        ]);
112
113
        $browsersData = collect(Analytics::get(
114
            Period::create($startDate, Carbon::now()),
115
            ['screenPageViews'],
116
            ['browser'],
117
            10,
118
            [],
119
            0,
120
            $dimensionFilter,
121
            true
122
        ))->keyBy('browser');
123
124
        $totalViews = $browsersData->sum('screenPageViews');
125
126
        return collect($browsers)->map(function ($browser) use ($browsersData, $totalViews) {
0 ignored issues
show
$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

126
        return collect(/** @scrutinizer ignore-type */ $browsers)->map(function ($browser) use ($browsersData, $totalViews) {
Loading history...
127
            $screenPageViews = $browsersData[$browser]['screenPageViews'] ?? 0;
128
129
            return [
130
                'browser' => $browser,
131
                'color' => $this->getBrowserColor($browser),
132
                'percentage' => $this->getPercentage($screenPageViews, $totalViews),
133
                'screenPageViews' => $screenPageViews,
134
            ];
135
        });
136
    }
137
138
    /**
139
     * Build the devices graph from the last 7 months.
140
     *
141
     * @return Collection
142
     */
143
    public function buildDevicesGraph(): Collection
144
    {
145
        $startDate = Carbon::now()->subMonths(7);
146
147
        $devices = ['Apple', 'Samsung', 'HTC', 'Huawei', 'Microsoft'];
148
149
        $dimensionFilter = new FilterExpression([
150
            'filter' => new Filter([
151
                'field_name' => 'mobileDeviceBranding',
152
                'in_list_filter' => new Filter\InListFilter([
153
                    'values' => $devices,
154
                ]),
155
            ]),
156
        ]);
157
158
        $devicesData = Analytics::get(
159
            Period::create($startDate, Carbon::now()),
160
            ['screenPageViews'],
161
            ['mobileDeviceBranding', 'yearMonth'],
162
            10,
163
            [OrderBy::dimension('mobileDeviceBranding', true)],
164
            0,
165
            $dimensionFilter,
166
            true
167
        )->keyBy(fn ($item) => $item['yearMonth'] . '-' . $item['mobileDeviceBranding']);
168
169
        $devicesGraph = collect();
170
        foreach (range(0, 7) as $i) {
171
            $date = Carbon::now()->subMonths($i);
172
173
            $devicesGraph->put($date->format('Ym'), [
0 ignored issues
show
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

173
            $devicesGraph->put($date->format('Ym'), /** @scrutinizer ignore-type */ [
Loading history...
174
                'period' => $date->format('Y-m'),
175
                'Apple' => 0,
176
                'Samsung' => 0,
177
                'Google' => 0,
178
                'HTC' => 0,
179
                'Huawei' => 0,
180
                'Microsoft' => 0
181
            ]);
182
        }
183
184
        $devicesGraph = $devicesGraph->map(function ($row, $yearMonth) use ($devicesData, $devices) {
185
            foreach ($devices as $device) {
186
                $key = $yearMonth . '-' . $device;
187
                $row[$device] = $devicesData[$key]['screenPageViews'] ?? 0;
188
            }
189
            return $row;
190
        });
191
192
        return $devicesGraph->reverse();
193
    }
194
195
    /**
196
     * Build the operating system graph from the last 7 months.
197
     *
198
     * @return Collection
199
     */
200
    public function buildOperatingSystemGraph(): Collection
201
    {
202
        $startDate = Carbon::now()->subMonths(7);
203
204
        $operatingSystems = ['Windows', 'Linux', 'Macintosh'];
205
206
        $dimensionFilter = new FilterExpression([
207
            'filter' => new Filter([
208
                'field_name' => 'operatingSystem',
209
                'in_list_filter' => new Filter\InListFilter([
210
                    'values' => $operatingSystems,
211
                ]),
212
            ]),
213
        ]);
214
215
        $operatingSystemData = Analytics::get(
216
            Period::create($startDate, Carbon::now()),
217
            ['screenPageViews'],
218
            ['operatingSystem', 'yearMonth'],
219
            10,
220
            [OrderBy::dimension('operatingSystem', true)],
221
            0,
222
            $dimensionFilter,
223
            true
224
        )->keyBy(fn ($item) => $item['yearMonth'] . '-' . $item['operatingSystem']);
225
226
        $operatingSystemGraph = collect();
227
        foreach (range(0, 7) as $i) {
228
            $date = Carbon::now()->subMonths($i);
229
230
            $operatingSystemGraph->put($date->format('Ym'), [
0 ignored issues
show
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

230
            $operatingSystemGraph->put($date->format('Ym'), /** @scrutinizer ignore-type */ [
Loading history...
231
                'period' => $date->format('Y-m'),
232
                'Windows' => 0,
233
                'Macintosh' => 0,
234
                'Linux' => 0,
235
            ]);
236
        }
237
238
        $operatingSystemGraph = $operatingSystemGraph->map(function ($row, $yearMonth) use ($operatingSystemData, $operatingSystems) {
239
            foreach ($operatingSystems as $os) {
240
                $key = $yearMonth . '-' . $os;
241
                $row[$os] = $operatingSystemData[$key]['screenPageViews'] ?? 0;
242
            }
243
            return $row;
244
        });
245
246
        return $operatingSystemGraph->reverse();
247
    }
248
}
249