Backup #1993
| ID | 1993 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Controller/CodeAnalysisController.php |
| Version | 14 |
| Typ |
modified |
| Größe | 7.3 KB |
| Hash | 0db6c448816f6deb034d94090318b18ec43f3bcf0c51a0ecd131dcec760ea095 |
| Datum | 2025-12-28 09:41:41 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?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, 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);
}
// 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;
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 1993 |
14 |
modified |
7.3 KB |
2025-12-28 09:41 |
| 1355 |
13 |
modified |
7.3 KB |
2025-12-25 16:31 |
| 1269 |
12 |
modified |
7.3 KB |
2025-12-25 12:51 |
| 952 |
11 |
modified |
8.0 KB |
2025-12-23 22:08 |
| 947 |
10 |
modified |
8.0 KB |
2025-12-23 22:06 |
| 946 |
9 |
modified |
7.6 KB |
2025-12-23 22:06 |
| 944 |
8 |
modified |
7.6 KB |
2025-12-23 22:00 |
| 943 |
7 |
modified |
7.2 KB |
2025-12-23 21:59 |
| 942 |
6 |
modified |
7.1 KB |
2025-12-23 21:59 |
| 891 |
5 |
modified |
6.8 KB |
2025-12-23 15:40 |
| 889 |
4 |
modified |
2.9 KB |
2025-12-23 15:35 |
| 885 |
3 |
modified |
2.6 KB |
2025-12-23 15:27 |
| 882 |
2 |
modified |
2.1 KB |
2025-12-23 15:21 |
| 876 |
1 |
modified |
2.1 KB |
2025-12-23 09:35 |
← Zurück zur Übersicht