repository = $repository; $this->apiFormatter = $apiFormatter; $this->audit = $audit; } /** * GET /semantic-explorer/ontologie * Konzept-Klassen */ public function index(): void { $classes = $this->repository->findAll(); // Properties dekodieren foreach ($classes as &$class) { $class['properties_decoded'] = $this->decodeJson($class['properties'] ?? null); } $stats = $this->repository->getStats(); $this->view('semantic-explorer.ontologie', [ 'title' => 'Ontologie', 'classes' => $classes, 'stats' => $stats, ]); } /** * 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 { $input = $this->getJsonInput(); $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 === '') { $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' ); $this->json($this->apiFormatter->created($id, 'Ontologie-Klasse erstellt')); } catch (\Exception $e) { $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 { $input = $this->getJsonInput(); $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 === '') { $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' ); $this->json($this->apiFormatter->ok('Ontologie-Klasse aktualisiert')); } catch (\Exception $e) { $this->json($this->apiFormatter->error($e->getMessage(), 'SERVER_ERROR'), 500); } } /** * POST /semantic-explorer/ontologie/{id}/delete */ public function destroy(int $id): void { 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' ); $this->json($this->apiFormatter->ok('Ontologie-Klasse gelöscht')); } else { $this->json($this->apiFormatter->error('Klasse hat noch Unterklassen', 'HAS_CHILDREN'), 400); } } catch (\Exception $e) { $this->json($this->apiFormatter->error($e->getMessage(), 'SERVER_ERROR'), 500); } } }