58 lines
1.5 KiB
PHP
58 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Domains\Analytics\Jobs\RecordClickJob;
|
|
use App\Domains\Link\Models\Link;
|
|
use App\Domains\Link\Services\LinkCacheService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class RedirectController extends Controller
|
|
{
|
|
public function __construct(private LinkCacheService $cache) {}
|
|
|
|
public function __invoke(Request $request, string $slug): RedirectResponse
|
|
{
|
|
// 1. Redis-first lookup (domain_id = null for default domain)
|
|
$data = $this->cache->get($slug);
|
|
|
|
if ($data === null) {
|
|
// Cache miss — try DB
|
|
$link = Link::where('slug', $slug)
|
|
->whereNull('domain_id')
|
|
->first();
|
|
|
|
if (! $link) {
|
|
abort(404);
|
|
}
|
|
|
|
$this->cache->warmFromLink($link);
|
|
$data = $this->cache->get($slug);
|
|
}
|
|
|
|
// 2. Status check
|
|
if (($data['status'] ?? '') !== 'active') {
|
|
abort(410);
|
|
}
|
|
|
|
// 3. Expiry check
|
|
$expiresAt = $data['expires_at'] ?? '';
|
|
if ($expiresAt !== '' && (int) $expiresAt < time()) {
|
|
abort(410);
|
|
}
|
|
|
|
// 4. RecordClickJob dispatched in Task 7
|
|
RecordClickJob::dispatch(
|
|
(int) $data['link_id'],
|
|
$request->ip() ?? '',
|
|
$request->userAgent() ?? '',
|
|
$request->headers->all(),
|
|
$request->query(),
|
|
)->onQueue('clicks');
|
|
|
|
// 5. 302 redirect
|
|
return redirect($data['target'], 302);
|
|
}
|
|
}
|