$this->getString('directory'), 'namespace' => $this->getString('namespace'), 'extension' => $this->getString('extension'), 'search' => $this->getString('search'), 'has_classes' => $this->getString('has_classes'), ], fn ($v) => $v !== ''); $this->view('docs.code', [ 'title' => 'Code-Analyse', 'stats' => $this->useCase->getStatistics(), 'files' => $this->useCase->execute($filters, 200, 0), 'filterOptions' => $this->useCase->getFilterOptions(), 'currentFilters' => $filters, ]); } public function show(string $id): void { $file = $this->useCase->findById((int) $id); if ($file === null) { $this->notFound('Datei nicht gefunden'); } $classes = json_decode($file['classes'] ?? '[]', true); $functions = json_decode($file['functions'] ?? '[]', true); $uses = json_decode($file['uses'] ?? '[]', true); $implements = json_decode($file['implements_interfaces'] ?? '[]', true); $traits = json_decode($file['traits_used'] ?? '[]', true); $constructorDeps = json_decode($file['constructor_deps'] ?? '[]', true); // Build FQCN for reverse lookup $dependents = []; if (!empty($classes)) { $namespace = $file['namespace'] ?? ''; $className = $classes[0]['name']; $fqcn = $namespace ? $namespace . '\\' . $className : $className; $dependents = $this->useCase->findDependents($fqcn); } $this->view('docs.code-show', [ 'title' => $file['file_name'], 'file' => $file, 'classes' => $classes, 'functions' => $functions, 'uses' => $uses, 'extendsClass' => $file['extends_class'], 'implements' => $implements, 'traits' => $traits, 'constructorDeps' => $constructorDeps, 'dependents' => $dependents, ]); } public function scan(): void { $this->requireCsrf(); $result = $this->useCase->runScan('web'); $this->json([ 'success' => true, 'scan_id' => $result['scan_id'], 'files_scanned' => $result['files_scanned'], 'files_with_errors' => $result['files_with_errors'], 'total_classes' => $result['total_classes'], 'total_functions' => $result['total_functions'], 'duration_ms' => $result['duration_ms'], ]); } }