Initial commit: Animexe Laravel platform
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
use App\Models\UserActivityLog;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ActivityLogger
|
||||
{
|
||||
public static function log(
|
||||
string $action,
|
||||
?int $userId = null,
|
||||
?string $subjectType = null,
|
||||
?int $subjectId = null,
|
||||
?array $meta = null,
|
||||
?Request $request = null
|
||||
): void {
|
||||
try {
|
||||
$req = $request ?? request();
|
||||
$ip = $req->ip();
|
||||
$ua = $req->userAgent() ?? '';
|
||||
$isBot = (bool) $req->attributes->get('is_bot', false);
|
||||
$geo = cache()->remember("geo_{$ip}", 3600, fn() => self::geoIp($ip));
|
||||
|
||||
UserActivityLog::create([
|
||||
'user_id' => $userId ?? auth()->id(),
|
||||
'session_id' => session()->getId(),
|
||||
'action' => $action,
|
||||
'subject_type' => $subjectType,
|
||||
'subject_id' => $subjectId,
|
||||
'ip' => $ip,
|
||||
'country' => $geo['country'] ?? null,
|
||||
'city' => $geo['city'] ?? null,
|
||||
'device' => self::device($ua),
|
||||
'browser' => self::browser($ua),
|
||||
'user_agent' => mb_substr($ua, 0, 500),
|
||||
'is_bot' => $isBot,
|
||||
'meta' => $meta,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
} catch (\Throwable) {
|
||||
// never break the app
|
||||
}
|
||||
}
|
||||
|
||||
private static function geoIp(string $ip): array
|
||||
{
|
||||
try {
|
||||
if (in_array($ip, ['127.0.0.1', '::1']) || str_starts_with($ip, '192.168.') || str_starts_with($ip, '10.')) {
|
||||
return ['country' => 'Local', 'city' => null];
|
||||
}
|
||||
$r = \Illuminate\Support\Facades\Http::timeout(2)->get("http://ip-api.com/json/{$ip}?fields=country,city,status");
|
||||
$d = $r->json();
|
||||
return ($d['status'] ?? '') === 'success' ? ['country' => $d['country'], 'city' => $d['city']] : [];
|
||||
} catch (\Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private static function device(string $ua): string
|
||||
{
|
||||
$ua = strtolower($ua);
|
||||
if (str_contains($ua, 'mobile') || str_contains($ua, 'android') || str_contains($ua, 'iphone')) return 'mobile';
|
||||
if (str_contains($ua, 'tablet') || str_contains($ua, 'ipad')) return 'tablet';
|
||||
return 'desktop';
|
||||
}
|
||||
|
||||
private static function browser(string $ua): string
|
||||
{
|
||||
if (str_contains($ua, 'Chrome')) return 'Chrome';
|
||||
if (str_contains($ua, 'Firefox')) return 'Firefox';
|
||||
if (str_contains($ua, 'Safari')) return 'Safari';
|
||||
if (str_contains($ua, 'Edge')) return 'Edge';
|
||||
if (str_contains($ua, 'Opera')) return 'Opera';
|
||||
return 'Other';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user