move into sonardesk
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Analytics\Services;
|
||||
|
||||
use Modules\Analytics\Models\AnalyticsEvent;
|
||||
use Modules\Analytics\Models\DailyMetric;
|
||||
|
||||
final class AnalyticsAggregator
|
||||
{
|
||||
public function aggregate(?string $date = null): int
|
||||
{
|
||||
$date = $date ?: now()->subHour()->toDateString();
|
||||
$written = 0;
|
||||
$base = AnalyticsEvent::query()->whereDate('occurred_at', $date);
|
||||
foreach ($base->clone()->select('site_id')->distinct()->pluck('site_id') as $siteId) {
|
||||
$query = $base->clone()->where('site_id', $siteId);
|
||||
$metrics = [
|
||||
['page_views', 'all', $query->clone()->where('event_type', 'page_view')->count()],
|
||||
['visitors', 'all', $query->clone()->whereNotNull('visitor_hash')->distinct('visitor_hash')->count('visitor_hash')],
|
||||
['sessions', 'all', $query->clone()->whereNotNull('session_hash')->distinct('session_hash')->count('session_hash')],
|
||||
['conversions', 'all', $query->clone()->where('event_type', 'conversion')->count()],
|
||||
['searches', 'all', $query->clone()->where('event_type', 'search')->count()],
|
||||
];
|
||||
foreach ($metrics as [$metric,$dimension,$value]) {
|
||||
DailyMetric::updateOrCreate(['site_id' => $siteId, 'metric_date' => $date, 'metric' => $metric, 'dimension' => $dimension], ['value' => $value]);
|
||||
$written++;
|
||||
}
|
||||
}
|
||||
|
||||
return $written;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Analytics\Services;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Modules\Analytics\Models\AnalyticsEvent;
|
||||
|
||||
final class AnalyticsTracker
|
||||
{
|
||||
public function track(Request $request, array $payload): ?AnalyticsEvent
|
||||
{
|
||||
if (! config('analytics.enabled')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (config('analytics.respect_dnt') && $request->header('DNT') === '1') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$path = ltrim((string) ($payload['path'] ?? ''), '/');
|
||||
|
||||
foreach (config('analytics.exclude_paths', []) as $excluded) {
|
||||
if ($excluded !== '' && str_starts_with($path, trim($excluded, '/'))) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$ip = (string) $request->ip();
|
||||
$visitorIdentifier = (string) ($payload['visitor_id'] ?? $request->cookie('analytics_visitor', 'guest'));
|
||||
$sessionIdentifier = (string) ($payload['session_id'] ?? $this->sessionIdentifier($request, $visitorIdentifier));
|
||||
|
||||
return AnalyticsEvent::create([
|
||||
'event_id' => (string) Str::uuid(),
|
||||
'site_id' => app()->bound('currentSite') ? app('currentSite')?->id : null,
|
||||
'event_type' => $payload['event_type'] ?? 'page_view',
|
||||
'path' => '/'.$path,
|
||||
'title' => $payload['title'] ?? null,
|
||||
'referrer' => $payload['referrer'] ?? $request->headers->get('referer'),
|
||||
'visitor_hash' => hash('sha256', $visitorIdentifier),
|
||||
'session_hash' => hash('sha256', $sessionIdentifier),
|
||||
'ip_hash' => config('analytics.anonymize_ip') ? hash('sha256', $ip.config('app.key')) : $ip,
|
||||
'device_type' => $payload['device_type'] ?? null,
|
||||
'browser' => $payload['browser'] ?? null,
|
||||
'operating_system' => $payload['operating_system'] ?? null,
|
||||
'subject_type' => $payload['subject_type'] ?? null,
|
||||
'subject_id' => $payload['subject_id'] ?? null,
|
||||
'properties' => $payload['properties'] ?? [],
|
||||
'occurred_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function sessionIdentifier(Request $request, string $visitorIdentifier): string
|
||||
{
|
||||
if ($request->hasSession()) {
|
||||
return $request->session()->getId();
|
||||
}
|
||||
|
||||
return (string) ($request->header('X-Analytics-Session') ?: $visitorIdentifier ?: 'stateless');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user