[ 'label' => t('API audit'), 'permission' => 'audit.api.view', 'count_sql' => "select count(*) from api_audit_log where (request_id like ? escape '\\\\' or path like ? escape '\\\\' or error_code like ? escape '\\\\' or ip like ? escape '\\\\')", 'preview_sql' => "select id, request_id, method, path, status_code, created_at from api_audit_log where (request_id like ? escape '\\\\' or path like ? escape '\\\\' or error_code like ? escape '\\\\' or ip like ? escape '\\\\') order by created_at desc limit ?", 'result_sql' => "select id, request_id, method, path, status_code, created_at from api_audit_log where (request_id like ? escape '\\\\' or path like ? escape '\\\\' or error_code like ? escape '\\\\' or ip like ? escape '\\\\') order by created_at desc", ], 'system-audit' => [ 'label' => t('System audit'), 'permission' => 'audit.system.view', 'count_sql' => "select count(*) from system_audit_log where (request_id like ? escape '\\\\' or event_type like ? escape '\\\\' or error_code like ? escape '\\\\' or path like ? escape '\\\\')", 'preview_sql' => "select id, request_id, event_type, outcome, created_at from system_audit_log where (request_id like ? escape '\\\\' or event_type like ? escape '\\\\' or error_code like ? escape '\\\\' or path like ? escape '\\\\') order by created_at desc limit ?", 'result_sql' => "select id, request_id, event_type, outcome, created_at from system_audit_log where (request_id like ? escape '\\\\' or event_type like ? escape '\\\\' or error_code like ? escape '\\\\' or path like ? escape '\\\\') order by created_at desc", ], ]; } public function mapResultItem(string $resourceKey, array $row): ?array { if ($resourceKey === 'api-audit') { return $this->mapApiAuditItem($row); } if ($resourceKey === 'system-audit') { return $this->mapSystemAuditItem($row); } return null; } public function listUrl(string $resourceKey, string $encodedSearch): string { return match ($resourceKey) { 'api-audit' => lurl('admin/api-audit') . '?search=' . $encodedSearch, 'system-audit' => lurl('admin/system-audit') . '?search=' . $encodedSearch, default => '', }; } /** * @param array $row * @return array{title: string, subtitle: string, url: string, icon: string}|null */ private function mapApiAuditItem(array $row): ?array { $method = strtoupper(trim((string) ($row['method'] ?? ''))); $path = trim((string) ($row['path'] ?? '')); $statusCode = (int) ($row['status_code'] ?? 0); $createdAt = trim((string) ($row['created_at'] ?? '')); $title = trim($method . ' ' . $path); if ($title === '') { $title = trim((string) ($row['request_id'] ?? '')); } if ($title === '') { return null; } $subtitleParts = []; if ($statusCode > 0) { $subtitleParts[] = (string) $statusCode; } if ($createdAt !== '') { $subtitleParts[] = $createdAt; } return [ 'title' => $title, 'subtitle' => implode(' — ', $subtitleParts), 'url' => lurl('admin/api-audit/view/' . ($row['id'] ?? '')), 'icon' => 'bi-shield-check', ]; } /** * @param array $row * @return array{title: string, subtitle: string, url: string, icon: string}|null */ private function mapSystemAuditItem(array $row): ?array { $eventType = trim((string) ($row['event_type'] ?? '')); $outcome = strtolower(trim((string) ($row['outcome'] ?? ''))); $createdAt = trim((string) ($row['created_at'] ?? '')); $title = $eventType !== '' ? $eventType : trim((string) ($row['request_id'] ?? '')); if ($title === '') { return null; } $subtitleParts = []; if ($outcome !== '') { $subtitleParts[] = strtoupper($outcome); } if ($createdAt !== '') { $subtitleParts[] = $createdAt; } return [ 'title' => $title, 'subtitle' => implode(' — ', $subtitleParts), 'url' => lurl('admin/system-audit/view/' . ($row['id'] ?? '')), 'icon' => 'bi-journal-lock', ]; } }