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
Bug
introduced
by
![]() |
|||||
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
![]() |
|||||
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
![]() |
|||||
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 |