getRouteParam('knowledgeId'); $documentId = $request->getRouteParam('documentId'); $data = $request->getParsedBody(); if (!$knowledgeId || !$documentId) { throw new BadRequest('Knowledge ID and Document ID are required'); } // Verify entities exist $knowledge = $this->entityManager->getEntityById('CAIKnowledge', $knowledgeId); if (!$knowledge) { throw new NotFound('Knowledge entry not found'); } $document = $this->entityManager->getEntityById('CDokumente', $documentId); if (!$document) { throw new NotFound('Document not found'); } $pdo = $this->entityManager->getPDO(); // Check if link already exists $existing = $this->checkIfLinked($knowledgeId, $documentId); if ($existing) { // Link exists - update junction columns return $this->updateExisting($knowledgeId, $documentId, $data); } // Create new link via ORM (triggers hooks like DokumenteSyncStatus) $this->entityManager->getRDBRepository('CAIKnowledge') ->getRelation($knowledge, 'dokumentes') ->relate($document); // Now set junction columns if provided if (!empty((array)$data)) { return $this->updateExisting($knowledgeId, $documentId, $data); } // Return created entry $result = $this->getJunctionEntry($knowledgeId, $documentId); return ResponseComposer::json($result); } private function checkIfLinked(string $knowledgeId, string $documentId): bool { $pdo = $this->entityManager->getPDO(); $sql = " SELECT COUNT(*) as count FROM c_a_i_knowledge_dokumente WHERE c_a_i_knowledge_id = :knowledgeId AND c_dokumente_id = :documentId AND deleted = 0 "; $sth = $pdo->prepare($sql); $sth->execute([ 'knowledgeId' => $knowledgeId, 'documentId' => $documentId ]); $result = $sth->fetch(\PDO::FETCH_ASSOC); return $result['count'] > 0; } private function updateExisting(string $knowledgeId, string $documentId, \stdClass $data): Response { $pdo = $this->entityManager->getPDO(); // Build dynamic UPDATE SET clause $setClauses = []; $params = [ 'knowledgeId' => $knowledgeId, 'documentId' => $documentId ]; if (isset($data->aiDocumentId)) { $setClauses[] = "ai_document_id = :aiDocumentId"; $params['aiDocumentId'] = $data->aiDocumentId; } if (isset($data->syncstatus)) { $allowedStatuses = ['new', 'unclean', 'synced', 'failed', 'unsupported']; if (!in_array($data->syncstatus, $allowedStatuses)) { throw new BadRequest('Invalid syncstatus value. Allowed: ' . implode(', ', $allowedStatuses)); } $setClauses[] = "syncstatus = :syncstatus"; $params['syncstatus'] = $data->syncstatus; } if (isset($data->lastSync)) { $setClauses[] = "last_sync = :lastSync"; $params['lastSync'] = $data->lastSync; } elseif (isset($data->updateLastSync) && $data->updateLastSync === true) { $setClauses[] = "last_sync = NOW()"; } if (!empty($setClauses)) { $sql = " UPDATE c_a_i_knowledge_dokumente SET " . implode(', ', $setClauses) . " WHERE c_a_i_knowledge_id = :knowledgeId AND c_dokumente_id = :documentId AND deleted = 0 "; $sth = $pdo->prepare($sql); $sth->execute($params); } // Return updated data $result = $this->getJunctionEntry($knowledgeId, $documentId); return ResponseComposer::json($result); } private function getJunctionEntry(string $knowledgeId, string $documentId): array { $pdo = $this->entityManager->getPDO(); $sql = " SELECT id as junctionId, c_a_i_knowledge_id as cAIKnowledgeId, c_dokumente_id as cDokumenteId, ai_document_id as aiDocumentId, syncstatus, last_sync as lastSync FROM c_a_i_knowledge_dokumente WHERE c_a_i_knowledge_id = :knowledgeId AND c_dokumente_id = :documentId AND deleted = 0 "; $sth = $pdo->prepare($sql); $sth->execute([ 'knowledgeId' => $knowledgeId, 'documentId' => $documentId ]); $result = $sth->fetch(\PDO::FETCH_ASSOC); if (!$result) { throw new NotFound('Junction entry not found'); } return $result; } }