90 lines
3.7 KiB
PHP
90 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\AuditLog;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\View\View;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class AuditLogController extends Controller
|
|
{
|
|
public function index(Request $request): View
|
|
{
|
|
$logs = AuditLog::with(['actor', 'targetUser'])
|
|
->when($request->action, fn ($q, $a) => $q->where('action', $a))
|
|
->when($request->actor_id, fn ($q, $id) => $q->where('actor_user_id', $id))
|
|
->when($request->target_id, fn ($q, $id) => $q->where('target_user_id', $id))
|
|
->when($request->date_from, fn ($q, $d) => $q->whereDate('created_at', '>=', $d))
|
|
->when($request->date_to, fn ($q, $d) => $q->whereDate('created_at', '<=', $d))
|
|
->when($request->search, fn ($q, $s) =>
|
|
$q->where('action', 'like', "%{$s}%")
|
|
->orWhere('justification', 'like', "%{$s}%")
|
|
->orWhere('ip_address', 'like', "%{$s}%")
|
|
)
|
|
->orderByDesc('created_at')
|
|
->paginate(30)
|
|
->withQueryString();
|
|
|
|
$actions = AuditLog::select('action')->distinct()->pluck('action')->sort()->values();
|
|
$admins = User::where('role', 'admin')->orderBy('name')->get(['id', 'name']);
|
|
|
|
return view('admin.audit-logs.index', compact('logs', 'actions', 'admins'));
|
|
}
|
|
|
|
public function export(Request $request): StreamedResponse
|
|
{
|
|
$query = AuditLog::with(['actor', 'targetUser'])
|
|
->when($request->action, fn ($q, $a) => $q->where('action', $a))
|
|
->when($request->actor_id, fn ($q, $id) => $q->where('actor_user_id', $id))
|
|
->when($request->target_id, fn ($q, $id) => $q->where('target_user_id', $id))
|
|
->when($request->date_from, fn ($q, $d) => $q->whereDate('created_at', '>=', $d))
|
|
->when($request->date_to, fn ($q, $d) => $q->whereDate('created_at', '<=', $d))
|
|
->when($request->search, fn ($q, $s) =>
|
|
$q->where('action', 'like', "%{$s}%")
|
|
->orWhere('justification', 'like', "%{$s}%")
|
|
->orWhere('ip_address', 'like', "%{$s}%")
|
|
)
|
|
->orderByDesc('created_at');
|
|
|
|
$filename = 'audit-log-' . now()->format('Ymd-His') . '.csv';
|
|
|
|
return response()->streamDownload(function () use ($query) {
|
|
$handle = fopen('php://output', 'w');
|
|
|
|
// UTF-8 BOM untuk Excel
|
|
fwrite($handle, "\xEF\xBB\xBF");
|
|
|
|
fputcsv($handle, [
|
|
'Masa', 'Oleh', 'Peranan', 'Tindakan',
|
|
'Sasaran', 'Projek ID', 'IP', 'Justifikasi',
|
|
]);
|
|
|
|
$query->chunk(500, function ($logs) use ($handle) {
|
|
foreach ($logs as $log) {
|
|
fputcsv($handle, [
|
|
$log->created_at?->format('d/m/Y H:i:s'),
|
|
$log->actor?->name ?? 'Sistem',
|
|
$log->actor_role ?? '',
|
|
$log->action,
|
|
$log->targetUser?->name ?? ($log->subject_type
|
|
? class_basename($log->subject_type) . '#' . $log->subject_id
|
|
: ''),
|
|
$log->project_id ?? '',
|
|
$log->ip_address ?? '',
|
|
$log->justification ?? '',
|
|
]);
|
|
}
|
|
});
|
|
|
|
fclose($handle);
|
|
}, $filename, [
|
|
'Content-Type' => 'text/csv; charset=UTF-8',
|
|
'Content-Disposition' => "attachment; filename=\"{$filename}\"",
|
|
]);
|
|
}
|
|
}
|