optimizations
This commit is contained in:
68
app/Http/Middleware/UpdateLastVisit.php
Normal file
68
app/Http/Middleware/UpdateLastVisit.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
final class UpdateLastVisit
|
||||
{
|
||||
private const SESSION_KEY = 'last_visit.logged_at';
|
||||
|
||||
private const THROTTLE_SECONDS = 300;
|
||||
|
||||
private static ?bool $usersTableHasLastVisitAt = null;
|
||||
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
$user = $request->user();
|
||||
if (! $user) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
if (! $this->usersTableHasLastVisitAt()) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$now = now();
|
||||
$session = $request->hasSession() ? $request->session() : null;
|
||||
$lastLoggedAt = $session?->get(self::SESSION_KEY);
|
||||
|
||||
if (is_numeric($lastLoggedAt) && ((int) $lastLoggedAt + self::THROTTLE_SECONDS) > $now->getTimestamp()) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$lastVisitAt = $user->last_visit_at;
|
||||
if ($lastVisitAt !== null && method_exists($lastVisitAt, 'getTimestamp')) {
|
||||
if (($lastVisitAt->getTimestamp() + self::THROTTLE_SECONDS) > $now->getTimestamp()) {
|
||||
$session?->put(self::SESSION_KEY, $lastVisitAt->getTimestamp());
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
DB::table('users')
|
||||
->where('id', $user->id)
|
||||
->update([
|
||||
'last_visit_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
|
||||
$user->forceFill(['last_visit_at' => $now]);
|
||||
$session?->put(self::SESSION_KEY, $now->getTimestamp());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function usersTableHasLastVisitAt(): bool
|
||||
{
|
||||
return self::$usersTableHasLastVisitAt ??= Schema::hasColumn('users', 'last_visit_at');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user