OntologyController.php
- Pfad:
src/Controller/OntologyController.php - Namespace: Controller
- Zeilen: 261 | Größe: 8,318 Bytes
- Geändert: 2025-12-27 12:33:37 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 100
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 8
- extends Framework\Controller
- constructor Domain\Repository\OntologyRepositoryInterface
- constructor Infrastructure\Formatter\ApiResponseFormatter
- constructor Infrastructure\Audit\AuditService
- use Domain\Repository\OntologyRepositoryInterface
- use Framework\Controller
- use Infrastructure\Audit\AuditService
- use Infrastructure\Formatter\ApiResponseFormatter
Klassen 1
-
OntologyControllerclass Zeile 14
Funktionen 7
-
__construct()public Zeile 20 -
index()public Zeile 34 -
create()public Zeile 69 -
store()public Zeile 80 -
edit()public Zeile 137 -
update()public Zeile 155 -
destroy()public Zeile 216
Versionen 22
-
v22
2025-12-27 12:33 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v21
2025-12-27 12:33 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v20
2025-12-27 12:32 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v19
2025-12-27 12:31 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v18
2025-12-26 07:01 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v17
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v16
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v15
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v14
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v13
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v12
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v11
2025-12-25 02:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v10
2025-12-24 20:20 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v9
2025-12-24 20:20 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v8
2025-12-24 20:19 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v7
2025-12-23 07:52 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v6
2025-12-23 04:42 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v5
2025-12-22 15:47 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v4
2025-12-22 15:47 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v3
2025-12-22 15:47 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v2
2025-12-22 08:04 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v1
2025-12-22 08:03 | 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 Semantic Explorer Ontologie (CRUD)
use Domain\Repository\OntologyRepositoryInterface;
use Framework\Controller;
use Infrastructure\Audit\AuditService;
use Infrastructure\Formatter\ApiResponseFormatter;
class OntologyController extends Controller
{
private OntologyRepositoryInterface $repository;
private ApiResponseFormatter $apiFormatter;
private AuditService $audit;
public function __construct(
OntologyRepositoryInterface $repository,
ApiResponseFormatter $apiFormatter,
AuditService $audit
) {
$this->repository = $repository;
$this->apiFormatter = $apiFormatter;
$this->audit = $audit;
}
/**
* GET /semantic-explorer/ontologie
* Klassifizierte Entities mit Ontologie-Klassen und Verbindungen
*/
public function index(): void
{
$search = $this->getString('search');
$classFilter = $this->getString('class');
$pagination = $this->getPagination(50);
// Ontologie-Klassen für Filter-Dropdown
$classes = $this->repository->findAll();
foreach ($classes as &$class) {
$class['properties_decoded'] = $this->decodeJson($class['properties'] ?? null);
}
// Klassifizierte Entities mit Relationen
$totalCount = $this->repository->countClassifiedEntities($search, $classFilter);
$entities = $this->repository->findClassifiedEntities($search, $classFilter, $pagination->limit, $pagination->offset);
$pagination = $pagination->withTotal($totalCount);
$stats = $this->repository->getStats();
$this->view('semantic-explorer.ontologie', [
'title' => 'Ontologie',
'classes' => $classes,
'entities' => $entities,
'stats' => $stats,
'currentSearch' => $search,
'currentClass' => $classFilter,
'currentPage' => $pagination->page,
'totalCount' => $pagination->totalCount,
'totalPages' => $pagination->totalPages(),
]);
}
/**
* GET /semantic-explorer/ontologie/new
*/
public function create(): void
{
$this->view('semantic-explorer.ontologie.new', [
'title' => 'Neue Ontologie-Klasse',
'classes' => $this->repository->findForSelect(),
]);
}
/**
* POST /semantic-explorer/ontologie
*/
public function store(): void
{
$this->requireCsrf();
$input = $this->getJsonInput();
if (empty($input)) {
$input = $_POST;
}
$name = trim($input['name'] ?? '');
$parentId = isset($input['parent_class_id']) && $input['parent_class_id'] !== '' ? (int) $input['parent_class_id'] : null;
$description = trim($input['description'] ?? '') ?: null;
$properties = $input['properties'] ?? [];
if ($name === '') {
if ($this->isHtmxRequest()) {
$this->htmxError('Name ist erforderlich');
return;
}
$this->json($this->apiFormatter->validationError('Name ist erforderlich', ['name' => 'Pflichtfeld']), 400);
return;
}
try {
$id = $this->repository->create($name, $parentId, $description, $properties);
// Audit log
$this->audit->logCreate(
table: 'ontology_classes',
id: $id,
data: ['name' => $name, 'parent_class_id' => $parentId, 'description' => $description],
actor: 'user',
actorType: 'user'
);
if ($this->isHtmxRequest()) {
$this->htmxRedirect('/semantic-explorer/ontologie/' . $id);
return;
}
$this->json($this->apiFormatter->created($id, 'Ontologie-Klasse erstellt'));
} catch (\Exception $e) {
if ($this->isHtmxRequest()) {
$this->htmxError($e->getMessage());
return;
}
$this->json($this->apiFormatter->error($e->getMessage(), 'SERVER_ERROR'), 500);
}
}
/**
* GET /semantic-explorer/ontologie/{id}/edit
*/
public function edit(int $id): void
{
$class = $this->repository->find($id);
if ($class === null) {
$this->notFound('Klasse nicht gefunden');
}
$this->view('semantic-explorer.ontologie.edit', [
'title' => 'Klasse bearbeiten',
'class' => $class,
'classes' => $this->repository->findForSelect(),
]);
}
/**
* POST /semantic-explorer/ontologie/{id}
*/
public function update(int $id): void
{
$this->requireCsrf();
$input = $this->getJsonInput();
if (empty($input)) {
$input = $_POST;
}
$name = trim($input['name'] ?? '');
$parentId = isset($input['parent_class_id']) && $input['parent_class_id'] !== '' ? (int) $input['parent_class_id'] : null;
$description = trim($input['description'] ?? '') ?: null;
$properties = $input['properties'] ?? [];
if ($name === '') {
if ($this->isHtmxRequest()) {
$this->htmxError('Name ist erforderlich');
return;
}
$this->json($this->apiFormatter->validationError('Name ist erforderlich', ['name' => 'Pflichtfeld']), 400);
return;
}
try {
// Get old state for audit
$oldClass = $this->repository->find($id);
$this->repository->update($id, $name, $parentId, $description, $properties);
// Audit log
$this->audit->logUpdate(
table: 'ontology_classes',
id: $id,
oldData: $oldClass !== null ? ['name' => $oldClass['name'], 'description' => $oldClass['description'] ?? null] : [],
newData: ['name' => $name, 'parent_class_id' => $parentId, 'description' => $description],
actor: 'user',
actorType: 'user'
);
if ($this->isHtmxRequest()) {
$this->htmxRedirect('/semantic-explorer/ontologie/' . $id);
return;
}
$this->json($this->apiFormatter->ok('Ontologie-Klasse aktualisiert'));
} catch (\Exception $e) {
if ($this->isHtmxRequest()) {
$this->htmxError($e->getMessage());
return;
}
$this->json($this->apiFormatter->error($e->getMessage(), 'SERVER_ERROR'), 500);
}
}
/**
* POST /semantic-explorer/ontologie/{id}/delete
*/
public function destroy(int $id): void
{
$this->requireCsrf();
try {
// Get data before delete for audit
$class = $this->repository->find($id);
$success = $this->repository->delete($id);
if ($success) {
// Audit log
$this->audit->logDelete(
table: 'ontology_classes',
id: $id,
data: $class !== null ? ['name' => $class['name'], 'description' => $class['description'] ?? null] : [],
reason: 'User deleted via UI',
actor: 'user',
actorType: 'user'
);
if ($this->isHtmxRequest()) {
$this->htmxRedirect('/semantic-explorer/ontologie');
return;
}
$this->json($this->apiFormatter->ok('Ontologie-Klasse gelöscht'));
} else {
if ($this->isHtmxRequest()) {
$this->htmxError('Klasse hat noch Unterklassen');
return;
}
$this->json($this->apiFormatter->error('Klasse hat noch Unterklassen', 'HAS_CHILDREN'), 400);
}
} catch (\Exception $e) {
if ($this->isHtmxRequest()) {
$this->htmxError($e->getMessage());
return;
}
$this->json($this->apiFormatter->error($e->getMessage(), 'SERVER_ERROR'), 500);
}
}
}