Visitor management app with SSO, kiosk, badges, reports, and Gitea CI deploy to frontdesk.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
80 lines
3.0 KiB
PHP
80 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Frontdesk;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Controllers\Frontdesk\Concerns\ScopesToAccount;
|
|
use App\Models\AuditLog;
|
|
use App\Models\Visit;
|
|
use App\Models\Visitor;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\View\View;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class AuditLogController extends Controller
|
|
{
|
|
use ScopesToAccount;
|
|
|
|
public function index(Request $request): View
|
|
{
|
|
$this->authorizeAbility($request, 'audit.view');
|
|
$organization = $this->organization($request);
|
|
|
|
$logs = $this->query($request, $organization)->paginate(50)->withQueryString();
|
|
|
|
return view('frontdesk.audit.index', [
|
|
'logs' => $logs,
|
|
'organization' => $organization,
|
|
'actions' => config('frontdesk.audit_actions'),
|
|
'canExport' => app(\App\Services\Frontdesk\FrontdeskPermissions::class)
|
|
->can($this->member($request), 'audit.export'),
|
|
]);
|
|
}
|
|
|
|
public function export(Request $request): StreamedResponse
|
|
{
|
|
$this->authorizeAbility($request, 'audit.export');
|
|
$organization = $this->organization($request);
|
|
|
|
$filename = 'frontdesk-audit-'.now()->format('Y-m-d-His').'.csv';
|
|
|
|
return response()->streamDownload(function () use ($request, $organization) {
|
|
$handle = fopen('php://output', 'w');
|
|
fputcsv($handle, ['Time', 'Action', 'Actor', 'Subject', 'Metadata', 'IP']);
|
|
|
|
$this->query($request, $organization)->chunk(200, function ($logs) use ($handle) {
|
|
foreach ($logs as $log) {
|
|
fputcsv($handle, [
|
|
$log->created_at?->toDateTimeString(),
|
|
$log->action,
|
|
$log->actor_ref ?? '—',
|
|
$log->subject_type ? class_basename($log->subject_type).' #'.$log->subject_id : '—',
|
|
json_encode($log->metadata ?? []),
|
|
$log->ip_address ?? '—',
|
|
]);
|
|
}
|
|
});
|
|
|
|
fclose($handle);
|
|
}, $filename, ['Content-Type' => 'text/csv']);
|
|
}
|
|
|
|
protected function query(Request $request, $organization)
|
|
{
|
|
return AuditLog::owned($this->ownerRef($request))
|
|
->where('organization_id', $organization->id)
|
|
->when($request->action, fn ($q, $action) => $q->where('action', $action))
|
|
->when($request->from, fn ($q, $from) => $q->where('created_at', '>=', Carbon::parse($from)->startOfDay()))
|
|
->when($request->to, fn ($q, $to) => $q->where('created_at', '<=', Carbon::parse($to)->endOfDay()))
|
|
->when($request->q, function ($q, $search) {
|
|
$q->where(function ($inner) use ($search) {
|
|
$inner->where('action', 'like', "%{$search}%")
|
|
->orWhere('metadata', 'like', "%{$search}%");
|
|
});
|
|
})
|
|
->orderByDesc('created_at');
|
|
}
|
|
}
|