{
"tool_response": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Controller\/SemanticExplorerController.php",
"oldString": " 'stats' => $stats,\n 'currentSentiment' => $sentiment,\n 'currentPage' => $page,\n 'totalCount' => $totalCount,\n 'totalPages' => ceil($totalCount \/ $limit),\n ]);\n }\n}",
"newString": " 'stats' => $stats,\n 'currentSentiment' => $sentiment,\n 'currentPage' => $page,\n 'totalCount' => $totalCount,\n 'totalPages' => ceil($totalCount \/ $limit),\n ]);\n }\n\n \/\/ =========================================================================\n \/\/ ENTITIES - CRUD\n \/\/ =========================================================================\n\n \/**\n * GET \/semantic-explorer\/entitaeten\/new\n *\/\n public function entitaetNew(): void\n {\n $this->view('semantic-explorer.entitaeten.new', [\n 'title' => 'Neue Entitaet',\n 'types' => $this->repository->getEntityTypes(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/entitaeten\n *\/\n public function entitaetStore(): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $name = trim($input['name'] ?? '');\n $type = trim($input['type'] ?? '');\n $description = trim($input['description'] ?? '') ?: null;\n\n if ($name === '' || $type === '') {\n $this->json(['success' => false, 'error' => 'Name und Typ sind erforderlich'], 400);\n\n return;\n }\n\n try {\n $id = $this->repository->createEntity($name, $type, $description);\n $this->json(['success' => true, 'id' => $id]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * GET \/semantic-explorer\/entitaeten\/{id}\/edit\n *\/\n public function entitaetEdit(int $id): void\n {\n $entity = $this->repository->getEntity($id);\n\n if ($entity === null) {\n http_response_code(404);\n echo '404 - Entitaet nicht gefunden';\n\n return;\n }\n\n $this->view('semantic-explorer.entitaeten.edit', [\n 'title' => 'Entitaet bearbeiten',\n 'entity' => $entity,\n 'types' => $this->repository->getEntityTypes(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/entitaeten\/{id}\n *\/\n public function entitaetUpdate(int $id): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $name = trim($input['name'] ?? '');\n $type = trim($input['type'] ?? '');\n $description = trim($input['description'] ?? '') ?: null;\n\n if ($name === '' || $type === '') {\n $this->json(['success' => false, 'error' => 'Name und Typ sind erforderlich'], 400);\n\n return;\n }\n\n try {\n $this->repository->updateEntity($id, $name, $type, $description);\n $this->json(['success' => true]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * POST \/semantic-explorer\/entitaeten\/{id}\/delete\n *\/\n public function entitaetDelete(int $id): void\n {\n try {\n $success = $this->repository->deleteEntity($id);\n if ($success) {\n $this->json(['success' => true]);\n } else {\n $this->json(['success' => false, 'error' => 'Entitaet hat noch Relationen'], 400);\n }\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/\/ =========================================================================\n \/\/ RELATIONS - CRUD\n \/\/ =========================================================================\n\n \/**\n * GET \/semantic-explorer\/relationen\/new\n *\/\n public function relationNew(): void\n {\n $this->view('semantic-explorer.relationen.new', [\n 'title' => 'Neue Relation',\n 'entities' => $this->repository->getAllEntitiesSimple(),\n 'relationTypes' => $this->repository->getRelationTypesList(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/relationen\n *\/\n public function relationStore(): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $sourceId = (int) ($input['source_entity_id'] ?? 0);\n $targetId = (int) ($input['target_entity_id'] ?? 0);\n $type = trim($input['relation_type'] ?? '');\n $strength = (float) ($input['strength'] ?? 1.0);\n\n if ($sourceId === 0 || $targetId === 0 || $type === '') {\n $this->json(['success' => false, 'error' => 'Alle Felder sind erforderlich'], 400);\n\n return;\n }\n\n try {\n $id = $this->repository->createRelation($sourceId, $targetId, $type, $strength);\n $this->json(['success' => true, 'id' => $id]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * GET \/semantic-explorer\/relationen\/{id}\/edit\n *\/\n public function relationEdit(int $id): void\n {\n $relation = $this->repository->getRelation($id);\n\n if ($relation === null) {\n http_response_code(404);\n echo '404 - Relation nicht gefunden';\n\n return;\n }\n\n $this->view('semantic-explorer.relationen.edit', [\n 'title' => 'Relation bearbeiten',\n 'relation' => $relation,\n 'relationTypes' => $this->repository->getRelationTypesList(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/relationen\/{id}\n *\/\n public function relationUpdate(int $id): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $type = trim($input['relation_type'] ?? '');\n $strength = (float) ($input['strength'] ?? 1.0);\n\n if ($type === '') {\n $this->json(['success' => false, 'error' => 'Beziehungstyp ist erforderlich'], 400);\n\n return;\n }\n\n try {\n $this->repository->updateRelation($id, $type, $strength);\n $this->json(['success' => true]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * POST \/semantic-explorer\/relationen\/{id}\/delete\n *\/\n public function relationDelete(int $id): void\n {\n try {\n $this->repository->deleteRelation($id);\n $this->json(['success' => true]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/\/ =========================================================================\n \/\/ TAXONOMY - CRUD\n \/\/ =========================================================================\n\n \/**\n * GET \/semantic-explorer\/taxonomie\/new\n *\/\n public function taxonomieNew(): void\n {\n $this->view('semantic-explorer.taxonomie.new', [\n 'title' => 'Neuer Taxonomie-Begriff',\n 'terms' => $this->repository->getTaxonomyTermsForSelect(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/taxonomie\n *\/\n public function taxonomieStore(): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $name = trim($input['name'] ?? '');\n $parentId = isset($input['parent_id']) && $input['parent_id'] !== '' ? (int) $input['parent_id'] : null;\n\n if ($name === '') {\n $this->json(['success' => false, 'error' => 'Name ist erforderlich'], 400);\n\n return;\n }\n\n try {\n $id = $this->repository->createTaxonomyTerm($name, $parentId);\n $this->json(['success' => true, 'id' => $id]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * GET \/semantic-explorer\/taxonomie\/{id}\/edit\n *\/\n public function taxonomieEdit(int $id): void\n {\n $term = $this->repository->getTaxonomyTerm($id);\n\n if ($term === null) {\n http_response_code(404);\n echo '404 - Begriff nicht gefunden';\n\n return;\n }\n\n $this->view('semantic-explorer.taxonomie.edit', [\n 'title' => 'Begriff bearbeiten',\n 'term' => $term,\n 'terms' => $this->repository->getTaxonomyTermsForSelect(),\n ]);\n }\n\n \/**\n * POST \/semantic-explorer\/taxonomie\/{id}\n *\/\n public function taxonomieUpdate(int $id): void\n {\n $input = json_decode(file_get_contents('php:\/\/input'), true);\n\n $name = trim($input['name'] ?? '');\n $parentId = isset($input['parent_id']) && $input['parent_id'] !== '' ? (int) $input['parent_id'] : null;\n\n if ($name === '') {\n $this->json(['success' => false, 'error' => 'Name ist erforderlich'], 400);\n\n return;\n }\n\n try {\n $this->repository->updateTaxonomyTerm($id, $name, $parentId);\n $this->json(['success' => true]);\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/**\n * POST \/semantic-explorer\/taxonomie\/{id}\/delete\n *\/\n public function taxonomieDelete(int $id): void\n {\n try {\n $success = $this->repository->deleteTaxonomyTerm($id);\n if ($success) {\n $this->json(['success' => true]);\n } else {\n $this->json(['success' => false, 'error' => 'Begriff hat noch Unterbegriffe'], 400);\n }\n } catch (\\Exception $e) {\n $this->json(['success' => false, 'error' => $e->getMessage()], 500);\n }\n }\n\n \/\/ =========================================================================\n \/\/ ONTOLOGY - CRUD\n \/\/ =========================================================================\n\n \/**\n * GET \/semantic-explorer\/ontologie\/new\n *\/\n public function ontologieNew(): void\n {\n $this->view('semantic-explorer.ontologie.new', [\n 'title' => 'Neue Ontologie-Klasse',\n ... [TRUNCATED-4dceb793a469a34a]",
"originalFile": "<?php\n\nnamespace Controller;\n\nuse Framework\\Controller;\nuse Infrastructure\\SemanticExplorerRepository;\n\n\/**\n * SemanticExplorerController - Nutzdaten Explorer\n *\n * Zeigt Dokumente und Chunks aus Nextcloud (documents, chunks Tabellen).\n * Für Endnutzer - Coaching-Materialien, PDFs, später Mails.\n *\/\nclass SemanticExplorerController extends Controller\n{\n private SemanticExplorerRepository $repository;\n\n public function __construct()\n {\n $this->repository = new SemanticExplorerRepository();\n }\n\n \/**\n * GET \/semantic-explorer\n * Dashboard mit Statistiken\n *\/\n public function index(): void\n {\n $docStats = $this->repository->getDocumentStats();\n $chunkStats = $this->repository->getChunkStats();\n $documents = $this->repository->getDocuments();\n $recentChunks = $this->repository->getRecentChunks(5);\n\n $this->view('semantic-explorer.index', [\n 'title' => 'Semantic Explorer',\n 'docStats' => $docStats,\n 'chunkStats' => $chunkStats,\n 'documents' => $documents,\n 'recentChunks' => $recentChunks,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/dokumente\n * Liste aller Dokumente\n *\/\n public function dokumente(): void\n {\n $status = $_GET['status'] ?? '';\n $search = $_GET['search'] ?? '';\n\n $documents = $this->repository->getDocumentsFiltered($status, $search);\n\n $this->view('semantic-explorer.dokumente.index', [\n 'title' => 'Dokumente',\n 'documents' => $documents,\n 'currentStatus' => $status,\n 'currentSearch' => $search,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/dokumente\/{id}\n * Dokument-Details mit Chunks\n *\/\n public function dokumentShow(int $id): void\n {\n $document = $this->repository->getDocument($id);\n\n if ($document === null) {\n http_response_code(404);\n echo '404 - Dokument nicht gefunden';\n\n return;\n }\n\n $chunks = $this->repository->getChunksForDocument($id);\n\n \/\/ Heading-Paths dekodieren\n foreach ($chunks as &$chunk) {\n $chunk['heading_path_decoded'] = json_decode($chunk['heading_path'] ?? '[]', true) ?: [];\n $chunk['metadata_decoded'] = json_decode($chunk['metadata'] ?? '{}', true) ?: [];\n }\n\n $this->view('semantic-explorer.dokumente.show', [\n 'title' => $document['filename'],\n 'document' => $document,\n 'chunks' => $chunks,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/chunks\n * Liste aller Chunks\n *\/\n public function chunks(): void\n {\n $search = $_GET['search'] ?? '';\n $embedded = $_GET['embedded'] ?? '';\n $page = max(1, (int) ($_GET['page'] ?? 1));\n $limit = 50;\n $offset = ($page - 1) * $limit;\n\n $totalCount = $this->repository->getChunksCount($search, $embedded);\n $chunks = $this->repository->getChunksFiltered($search, $embedded, $limit, $offset);\n\n $this->view('semantic-explorer.chunks.index', [\n 'title' => 'Chunks',\n 'chunks' => $chunks,\n 'currentSearch' => $search,\n 'currentEmbedded' => $embedded,\n 'currentPage' => $page,\n 'totalCount' => $totalCount,\n 'totalPages' => ceil($totalCount \/ $limit),\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/chunks\/{id}\n * Chunk-Details\n *\/\n public function chunkShow(int $id): void\n {\n $chunk = $this->repository->getChunk($id);\n\n if ($chunk === null) {\n http_response_code(404);\n echo '404 - Chunk nicht gefunden';\n\n return;\n }\n\n \/\/ JSON-Felder dekodieren\n $chunk['heading_path_decoded'] = json_decode($chunk['heading_path'] ?? '[]', true) ?: [];\n $chunk['metadata_decoded'] = json_decode($chunk['metadata'] ?? '{}', true) ?: [];\n\n \/\/ Nachbar-Chunks\n $prevChunk = $this->repository->getChunkByDocumentAndIndex(\n $chunk['document_id'],\n $chunk['chunk_index'] - 1\n );\n $nextChunk = $this->repository->getChunkByDocumentAndIndex(\n $chunk['document_id'],\n $chunk['chunk_index'] + 1\n );\n\n $this->view('semantic-explorer.chunks.show', [\n 'title' => 'Chunk #' . $chunk['id'],\n 'chunk' => $chunk,\n 'prevChunk' => $prevChunk,\n 'nextChunk' => $nextChunk,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/suche\n * Semantische Suche in Nutzdaten\n *\/\n public function suche(): void\n {\n $query = $_GET['q'] ?? '';\n $limit = min(20, max(1, (int) ($_GET['limit'] ?? 10)));\n\n $results = [];\n\n if ($query !== '') {\n \/\/ Vektor-Suche via Qdrant\n $results = $this->vectorSearch($query, $limit);\n }\n\n $this->view('semantic-explorer.suche', [\n 'title' => 'Semantische Suche',\n 'query' => $query,\n 'results' => $results,\n 'limit' => $limit,\n ]);\n }\n\n \/**\n * Vektor-Suche in documents Collection\n *\/\n private function vectorSearch(string $query, int $limit): array\n {\n \/\/ Embedding generieren\n $embedding = $this->getEmbedding($query);\n if (empty($embedding)) {\n return [];\n }\n\n \/\/ Qdrant suchen\n $response = $this->qdrantSearch($embedding, $limit);\n if (empty($response)) {\n return [];\n }\n\n \/\/ Chunk-Details aus DB laden\n $results = [];\n foreach ($response as $point) {\n $chunkId = $point['payload']['chunk_id'] ?? null;\n if ($chunkId === null) {\n continue;\n }\n\n $chunk = $this->repository->getChunkById($chunkId);\n\n if ($chunk !== null) {\n $chunk['score'] = $point['score'];\n $chunk['heading_path_decoded'] = json_decode($chunk['heading_path'] ?? '[]', true) ?: [];\n $results[] = $chunk;\n }\n }\n\n return $results;\n }\n\n \/**\n * Embedding via Ollama\n *\/\n private function getEmbedding(string $text): array\n {\n $ch = curl_init('http:\/\/localhost:11434\/api\/embeddings');\n curl_setopt_array($ch, [\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_POST => true,\n CURLOPT_HTTPHEADER => ['Content-Type: application\/json'],\n CURLOPT_POSTFIELDS => json_encode([\n 'model' => 'mxbai-embed-large',\n 'prompt' => $text,\n ]),\n ]);\n\n $response = curl_exec($ch);\n curl_close($ch);\n\n $data = json_decode($response, true);\n\n return $data['embedding'] ?? [];\n }\n\n \/**\n * Qdrant-Suche\n *\/\n private function qdrantSearch(array $embedding, int $limit): array\n {\n $ch = curl_init('http:\/\/localhost:6333\/collections\/documents\/points\/search');\n curl_setopt_array($ch, [\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_POST => true,\n CURLOPT_HTTPHEADER => ['Content-Type: application\/json'],\n CURLOPT_POSTFIELDS => json_encode([\n 'vector' => $embedding,\n 'limit' => $limit,\n 'with_payload' => true,\n ]),\n ]);\n\n $response = curl_exec($ch);\n curl_close($ch);\n\n $data = json_decode($response, true);\n\n return $data['result'] ?? [];\n }\n\n \/**\n * GET \/semantic-explorer\/entitaeten\n * Liste aller Entitaeten\n *\/\n public function entitaeten(): void\n {\n $type = $_GET['type'] ?? '';\n $search = $_GET['search'] ?? '';\n\n $entities = $this->repository->getEntitiesFiltered($type, $search);\n $stats = $this->repository->getEntityStats();\n\n $this->view('semantic-explorer.entitaeten.index', [\n 'title' => 'Entitaeten',\n 'entities' => $entities,\n 'stats' => $stats,\n 'currentType' => $type,\n 'currentSearch' => $search,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/entitaeten\/{id}\n * Entitaet-Details\n *\/\n public function entitaetShow(int $id): void\n {\n $entity = $this->repository->getEntity($id);\n\n if ($entity === null) {\n http_response_code(404);\n echo '404 - Entitaet nicht gefunden';\n\n return;\n }\n\n $synonyms = $this->repository->getEntitySynonyms($id);\n $outgoingRelations = $this->repository->getOutgoingRelations($id);\n $incomingRelations = $this->repository->getIncomingRelations($id);\n $chunks = $this->repository->getChunksForEntity($id);\n $classifications = $this->repository->getEntityClassifications($id);\n\n $this->view('semantic-explorer.entitaeten.show', [\n 'title' => $entity['name'],\n 'entity' => $entity,\n 'synonyms' => $synonyms,\n 'outgoingRelations' => $outgoingRelations,\n 'incomingRelations' => $incomingRelations,\n 'chunks' => $chunks,\n 'classifications' => $classifications,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/relationen\n * Beziehungen zwischen Entitaeten\n *\/\n public function relationen(): void\n {\n $type = $_GET['type'] ?? '';\n\n $relations = $this->repository->getRelationsFiltered($type);\n $relationTypes = $this->repository->getRelationTypes();\n $stats = $this->repository->getRelationStats();\n\n $this->view('semantic-explorer.relationen', [\n 'title' => 'Relationen',\n 'relations' => $relations,\n 'relationTypes' => $relationTypes,\n 'stats' => $stats,\n 'currentType' => $type,\n ]);\n }\n\n \/**\n * GET \/semantic-explorer\/taxonomie\n * Hierarchische Kategorisierung\n *\/\n public function taxonomie()... [TRUNCATED-58ccedb7efd46c84]",
"structuredPatch": [
{
"oldStart": 424,
"oldLines": 4,
"newStart": 424,
"newLines": 413,
"lines": [
" 'totalPages' => ceil($totalCount \/ $limit),",
" ]);",
" }",
"+",
"+ \/\/ =========================================================================",
"+ \/\/ ENTITIES - CRUD",
"+ \/\/ =========================================================================",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/entitaeten\/new",
"+ *\/",
"+ public function entitaetNew(): void",
"+ {",
"+ $this->view('semantic-explorer.entitaeten.new', [",
"+ 'title' => 'Neue Entitaet',",
"+ 'types' => $this->repository->getEntityTypes(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/entitaeten",
"+ *\/",
"+ public function entitaetStore(): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $name = trim($input['name'] ?? '');",
"+ $type = trim($input['type'] ?? '');",
"+ $description = trim($input['description'] ?? '') ?: null;",
"+",
"+ if ($name === '' || $type === '') {",
"+ $this->json(['success' => false, 'error' => 'Name und Typ sind erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $id = $this->repository->createEntity($name, $type, $description);",
"+ $this->json(['success' => true, 'id' => $id]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/entitaeten\/{id}\/edit",
"+ *\/",
"+ public function entitaetEdit(int $id): void",
"+ {",
"+ $entity = $this->repository->getEntity($id);",
"+",
"+ if ($entity === null) {",
"+ http_response_code(404);",
"+ echo '404 - Entitaet nicht gefunden';",
"+",
"+ return;",
"+ }",
"+",
"+ $this->view('semantic-explorer.entitaeten.edit', [",
"+ 'title' => 'Entitaet bearbeiten',",
"+ 'entity' => $entity,",
"+ 'types' => $this->repository->getEntityTypes(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/entitaeten\/{id}",
"+ *\/",
"+ public function entitaetUpdate(int $id): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $name = trim($input['name'] ?? '');",
"+ $type = trim($input['type'] ?? '');",
"+ $description = trim($input['description'] ?? '') ?: null;",
"+",
"+ if ($name === '' || $type === '') {",
"+ $this->json(['success' => false, 'error' => 'Name und Typ sind erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $this->repository->updateEntity($id, $name, $type, $description);",
"+ $this->json(['success' => true]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/entitaeten\/{id}\/delete",
"+ *\/",
"+ public function entitaetDelete(int $id): void",
"+ {",
"+ try {",
"+ $success = $this->repository->deleteEntity($id);",
"+ if ($success) {",
"+ $this->json(['success' => true]);",
"+ } else {",
"+ $this->json(['success' => false, 'error' => 'Entitaet hat noch Relationen'], 400);",
"+ }",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/\/ =========================================================================",
"+ \/\/ RELATIONS - CRUD",
"+ \/\/ =========================================================================",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/relationen\/new",
"+ *\/",
"+ public function relationNew(): void",
"+ {",
"+ $this->view('semantic-explorer.relationen.new', [",
"+ 'title' => 'Neue Relation',",
"+ 'entities' => $this->repository->getAllEntitiesSimple(),",
"+ 'relationTypes' => $this->repository->getRelationTypesList(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/relationen",
"+ *\/",
"+ public function relationStore(): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $sourceId = (int) ($input['source_entity_id'] ?? 0);",
"+ $targetId = (int) ($input['target_entity_id'] ?? 0);",
"+ $type = trim($input['relation_type'] ?? '');",
"+ $strength = (float) ($input['strength'] ?? 1.0);",
"+",
"+ if ($sourceId === 0 || $targetId === 0 || $type === '') {",
"+ $this->json(['success' => false, 'error' => 'Alle Felder sind erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $id = $this->repository->createRelation($sourceId, $targetId, $type, $strength);",
"+ $this->json(['success' => true, 'id' => $id]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/relationen\/{id}\/edit",
"+ *\/",
"+ public function relationEdit(int $id): void",
"+ {",
"+ $relation = $this->repository->getRelation($id);",
"+",
"+ if ($relation === null) {",
"+ http_response_code(404);",
"+ echo '404 - Relation nicht gefunden';",
"+",
"+ return;",
"+ }",
"+",
"+ $this->view('semantic-explorer.relationen.edit', [",
"+ 'title' => 'Relation bearbeiten',",
"+ 'relation' => $relation,",
"+ 'relationTypes' => $this->repository->getRelationTypesList(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/relationen\/{id}",
"+ *\/",
"+ public function relationUpdate(int $id): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $type = trim($input['relation_type'] ?? '');",
"+ $strength = (float) ($input['strength'] ?? 1.0);",
"+",
"+ if ($type === '') {",
"+ $this->json(['success' => false, 'error' => 'Beziehungstyp ist erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $this->repository->updateRelation($id, $type, $strength);",
"+ $this->json(['success' => true]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/relationen\/{id}\/delete",
"+ *\/",
"+ public function relationDelete(int $id): void",
"+ {",
"+ try {",
"+ $this->repository->deleteRelation($id);",
"+ $this->json(['success' => true]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/\/ =========================================================================",
"+ \/\/ TAXONOMY - CRUD",
"+ \/\/ =========================================================================",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/taxonomie\/new",
"+ *\/",
"+ public function taxonomieNew(): void",
"+ {",
"+ $this->view('semantic-explorer.taxonomie.new', [",
"+ 'title' => 'Neuer Taxonomie-Begriff',",
"+ 'terms' => $this->repository->getTaxonomyTermsForSelect(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/taxonomie",
"+ *\/",
"+ public function taxonomieStore(): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $name = trim($input['name'] ?? '');",
"+ $parentId = isset($input['parent_id']) && $input['parent_id'] !== '' ? (int) $input['parent_id'] : null;",
"+",
"+ if ($name === '') {",
"+ $this->json(['success' => false, 'error' => 'Name ist erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $id = $this->repository->createTaxonomyTerm($name, $parentId);",
"+ $this->json(['success' => true, 'id' => $id]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/taxonomie\/{id}\/edit",
"+ *\/",
"+ public function taxonomieEdit(int $id): void",
"+ {",
"+ $term = $this->repository->getTaxonomyTerm($id);",
"+",
"+ if ($term === null) {",
"+ http_response_code(404);",
"+ echo '404 - Begriff nicht gefunden';",
"+",
"+ return;",
"+ }",
"+",
"+ $this->view('semantic-explorer.taxonomie.edit', [",
"+ 'title' => 'Begriff bearbeiten',",
"+ 'term' => $term,",
"+ 'terms' => $this->repository->getTaxonomyTermsForSelect(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/taxonomie\/{id}",
"+ *\/",
"+ public function taxonomieUpdate(int $id): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $name = trim($input['name'] ?? '');",
"+ $parentId = isset($input['parent_id']) && $input['parent_id'] !== '' ? (int) $input['parent_id'] : null;",
"+",
"+ if ($name === '') {",
"+ $this->json(['success' => false, 'error' => 'Name ist erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $this->repository->updateTaxonomyTerm($id, $name, $parentId);",
"+ $this->json(['success' => true]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/taxonomie\/{id}\/delete",
"+ *\/",
"+ public function taxonomieDelete(int $id): void",
"+ {",
"+ try {",
"+ $success = $this->repository->deleteTaxonomyTerm($id);",
"+ if ($success) {",
"+ $this->json(['success' => true]);",
"+ } else {",
"+ $this->json(['success' => false, 'error' => 'Begriff hat noch Unterbegriffe'], 400);",
"+ }",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/\/ =========================================================================",
"+ \/\/ ONTOLOGY - CRUD",
"+ \/\/ =========================================================================",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/ontologie\/new",
"+ *\/",
"+ public function ontologieNew(): void",
"+ {",
"+ $this->view('semantic-explorer.ontologie.new', [",
"+ 'title' => 'Neue Ontologie-Klasse',",
"+ 'classes' => $this->repository->getOntologyClassesForSelect(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/ontologie",
"+ *\/",
"+ public function ontologieStore(): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $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(['success' => false, 'error' => 'Name ist erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $id = $this->repository->createOntologyClass($name, $parentId, $description, $properties);",
"+ $this->json(['success' => true, 'id' => $id]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * GET \/semantic-explorer\/ontologie\/{id}\/edit",
"+ *\/",
"+ public function ontologieEdit(int $id): void",
"+ {",
"+ $class = $this->repository->getOntologyClass($id);",
"+",
"+ if ($class === null) {",
"+ http_response_code(404);",
"+ echo '404 - Klasse nicht gefunden';",
"+",
"+ return;",
"+ }",
"+",
"+ $this->view('semantic-explorer.ontologie.edit', [",
"+ 'title' => 'Klasse bearbeiten',",
"+ 'class' => $class,",
"+ 'classes' => $this->repository->getOntologyClassesForSelect(),",
"+ ]);",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/ontologie\/{id}",
"+ *\/",
"+ public function ontologieUpdate(int $id): void",
"+ {",
"+ $input = json_decode(file_get_contents('php:\/\/input'), true);",
"+",
"+ $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(['success' => false, 'error' => 'Name ist erforderlich'], 400);",
"+",
"+ return;",
"+ }",
"+",
"+ try {",
"+ $this->repository->updateOntologyClass($id, $name, $parentId, $description, $properties);",
"+ $this->json(['success' => true]);",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
"+",
"+ \/**",
"+ * POST \/semantic-explorer\/ontologie\/{id}\/delete",
"+ *\/",
"+ public function ontologieDelete(int $id): void",
"+ {",
"+ try {",
"+ $success = $this->repository->deleteOntologyClass($id);",
"+ if ($success) {",
"+ $this->json(['success' => true]);",
"+ } else {",
"+ $this->json(['success' => false, 'error' => 'Klasse hat noch Unterklassen'], 400);",
"+ }",
"+ } catch (\\Exception $e) {",
"+ $this->json(['success' => false, 'error' => $e->getMessage()], 500);",
"+ }",
"+ }",
" }"
]
}
],
"userModified": false,
"replaceAll": false
}
}