CodeAnalysisController.php
- Pfad:
src/Controller/CodeAnalysisController.php
- Namespace: Controller
- Zeilen: 229 | Größe: 7,519 Bytes
- Geändert: 2025-12-28 09:41:41 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 99
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 90 (10%)
Issues 1
| Zeile |
Typ |
Beschreibung |
| 34 |
magic_number |
Magic Number gefunden: 1000 |
Dependencies 6
- extends Framework\Controller
- constructor UseCases\CodeAnalysis\GetCodeAnalysisUseCase
- constructor Domain\Repository\FileBackupRepositoryInterface
- use Domain\Repository\FileBackupRepositoryInterface
- use Framework\Controller
- use UseCases\CodeAnalysis\GetCodeAnalysisUseCase
Klassen 1
-
CodeAnalysisController
class
Zeile 13
Funktionen 10
-
__construct()
public
Zeile 15
-
index()
public
Zeile 21
-
show()
public
Zeile 40
-
scan()
public
Zeile 82
-
graph()
public
Zeile 99
-
graphData()
public
Zeile 119
-
globalGraph()
public
Zeile 195
-
globalGraphData()
public
Zeile 202
-
shortClassName()
private
Zeile 208
-
nodeExists()
private
Zeile 218
Versionen 14
-
v14
2025-12-28 09:41 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v13
2025-12-25 16:31 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v12
2025-12-25 12:51 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v11
2025-12-23 22:08 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v10
2025-12-23 22:06 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v9
2025-12-23 22:06 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v8
2025-12-23 22:00 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v7
2025-12-23 21:59 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v6
2025-12-23 21:59 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v5
2025-12-23 15:40 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v4
2025-12-23 15:35 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v3
2025-12-23 15:27 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v2
2025-12-23 15:21 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v1
2025-12-23 09:35 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
Code
<?php
declare(strict_types=1);
namespace Controller;
// @responsibility: HTTP-Endpunkte für Code-Analyse
use Domain\Repository\FileBackupRepositoryInterface;
use Framework\Controller;
use UseCases\CodeAnalysis\GetCodeAnalysisUseCase;
class CodeAnalysisController extends Controller
{
public function __construct(
private GetCodeAnalysisUseCase $useCase,
private FileBackupRepositoryInterface $backupRepo
) {
}
public function index(): void
{
$filters = array_filter([
'directory' => $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 Hygiene',
'stats' => $this->useCase->getStatistics(),
'files' => $this->useCase->execute($filters, 1000, 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);
}
// Backup history
$backupHistory = $this->backupRepo->findByFilePath($file['file_path']);
$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,
'backupHistory' => $backupHistory,
]);
}
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'],
]);
}
public function graph(string $id): void
{
$file = $this->useCase->findById((int) $id);
if ($file === null) {
$this->notFound('Datei nicht gefunden');
}
$classes = json_decode($file['classes'] ?? '[]', true);
$namespace = $file['namespace'] ?? '';
$className = !empty($classes) ? $classes[0]['name'] : $file['file_name'];
$fqcn = $namespace ? $namespace . '\\' . $className : $className;
$this->view('docs.code-graph', [
'title' => 'Dependency Graph: ' . $className,
'file' => $file,
'fqcn' => $fqcn,
]);
}
public function graphData(string $id): void
{
$file = $this->useCase->findById((int) $id);
if ($file === null) {
$this->json(['error' => 'Not found'], 404);
return;
}
$classes = json_decode($file['classes'] ?? '[]', true);
$uses = json_decode($file['uses'] ?? '[]', true);
$namespace = $file['namespace'] ?? '';
$className = !empty($classes) ? $classes[0]['name'] : $file['file_name'];
$fqcn = $namespace ? $namespace . '\\' . $className : $className;
$nodes = [];
$links = [];
// Central node
$nodes[] = [
'id' => $fqcn,
'label' => $className,
'type' => 'center',
'fileId' => $file['id'],
];
// Dependencies (outgoing)
if ($file['extends_class']) {
$shortName = $this->shortClassName($file['extends_class']);
$nodes[] = ['id' => $file['extends_class'], 'label' => $shortName, 'type' => 'extends'];
$links[] = ['source' => $fqcn, 'target' => $file['extends_class'], 'type' => 'extends'];
}
foreach (json_decode($file['implements_interfaces'] ?? '[]', true) as $iface) {
$shortName = $this->shortClassName($iface);
$nodes[] = ['id' => $iface, 'label' => $shortName, 'type' => 'implements'];
$links[] = ['source' => $fqcn, 'target' => $iface, 'type' => 'implements'];
}
foreach (json_decode($file['constructor_deps'] ?? '[]', true) as $dep) {
$shortName = $this->shortClassName($dep);
$nodes[] = ['id' => $dep, 'label' => $shortName, 'type' => 'constructor'];
$links[] = ['source' => $fqcn, 'target' => $dep, 'type' => 'constructor'];
}
// Dependents (incoming) - limit to 20
$dependents = $this->useCase->findDependents($fqcn);
$count = 0;
foreach ($dependents as $dep) {
if ($count >= 20) {
break;
}
$depFqcn = $dep['namespace'] ? $dep['namespace'] . '\\' . pathinfo($dep['file_name'], PATHINFO_FILENAME) : $dep['file_name'];
$shortName = pathinfo($dep['file_name'], PATHINFO_FILENAME);
if (!$this->nodeExists($nodes, $depFqcn)) {
$nodes[] = ['id' => $depFqcn, 'label' => $shortName, 'type' => 'dependent', 'fileId' => $dep['id']];
}
$links[] = ['source' => $depFqcn, 'target' => $fqcn, 'type' => $dep['dependency_type']];
$count++;
}
// Deduplicate nodes
$uniqueNodes = [];
foreach ($nodes as $node) {
$uniqueNodes[$node['id']] = $node;
}
$this->json([
'nodes' => array_values($uniqueNodes),
'links' => $links,
'center' => $fqcn,
]);
}
public function globalGraph(): void
{
$this->view('docs.code-graph-global', [
'title' => 'Projekt Dependency Graph',
]);
}
public function globalGraphData(): void
{
$stats = $this->useCase->getGlobalGraphData();
$this->json($stats);
}
private function shortClassName(string $fqcn): string
{
$parts = explode('\\', $fqcn);
return end($parts);
}
/**
* @param array<array<string, mixed>> $nodes
*/
private function nodeExists(array $nodes, string $id): bool
{
foreach ($nodes as $node) {
if ($node['id'] === $id) {
return true;
}
}
return false;
}
}