{
"event": "PreToolUse",
"tool_name": "Edit",
"tool_input": {
"file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/Persistence\/OntologyRepository.php",
"old_string": " \/**\n * {@inheritDoc}\n *\/\n public function findForSelect(): array\n {\n return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();\n }\n}",
"new_string": " \/**\n * {@inheritDoc}\n *\/\n public function findForSelect(): array\n {\n return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function findClassifiedEntities(string $search = '', string $classFilter = '', int $limit = 50, int $offset = 0): array\n {\n $sql = 'SELECT e.id as entity_id, e.name as entity_name, e.type as entity_type,\n e.description, e.canonical_name,\n oc.id as class_id, oc.name as class_name,\n ec.confidence,\n GROUP_CONCAT(DISTINCT CONCAT(er.relation_type, \":\", e2.name) SEPARATOR \", \") as relations\n FROM entities e\n INNER JOIN entity_classifications ec ON e.id = ec.entity_id\n INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id\n LEFT JOIN entity_relations er ON e.id = er.source_entity_id\n LEFT JOIN entities e2 ON er.target_entity_id = e2.id\n WHERE 1=1';\n\n $params = [];\n\n if ($search !== '') {\n $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';\n $params['search'] = '%' . $search . '%';\n $params['search2'] = '%' . $search . '%';\n }\n\n if ($classFilter !== '') {\n $sql .= ' AND oc.id = :class_id';\n $params['class_id'] = $classFilter;\n }\n\n $sql .= ' GROUP BY e.id, e.name, e.type, e.description, e.canonical_name, oc.id, oc.name, ec.confidence';\n $sql .= ' ORDER BY oc.name, e.name LIMIT ' . $limit . ' OFFSET ' . $offset;\n\n $stmt = $this->db->prepare($sql);\n $stmt->execute($params);\n\n return $stmt->fetchAll();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function countClassifiedEntities(string $search = '', string $classFilter = ''): int\n {\n $sql = 'SELECT COUNT(DISTINCT e.id)\n FROM entities e\n INNER JOIN entity_classifications ec ON e.id = ec.entity_id\n INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id\n WHERE 1=1';\n\n $params = [];\n\n if ($search !== '') {\n $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';\n $params['search'] = '%' . $search . '%';\n $params['search2'] = '%' . $search . '%';\n }\n\n if ($classFilter !== '') {\n $sql .= ' AND oc.id = :class_id';\n $params['class_id'] = $classFilter;\n }\n\n $stmt = $this->db->prepare($sql);\n $stmt->execute($params);\n\n return (int) $stmt->fetchColumn();\n }\n}"
}
}
{
"tool_response": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/Infrastructure\/Persistence\/OntologyRepository.php",
"oldString": " \/**\n * {@inheritDoc}\n *\/\n public function findForSelect(): array\n {\n return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();\n }\n}",
"newString": " \/**\n * {@inheritDoc}\n *\/\n public function findForSelect(): array\n {\n return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function findClassifiedEntities(string $search = '', string $classFilter = '', int $limit = 50, int $offset = 0): array\n {\n $sql = 'SELECT e.id as entity_id, e.name as entity_name, e.type as entity_type,\n e.description, e.canonical_name,\n oc.id as class_id, oc.name as class_name,\n ec.confidence,\n GROUP_CONCAT(DISTINCT CONCAT(er.relation_type, \":\", e2.name) SEPARATOR \", \") as relations\n FROM entities e\n INNER JOIN entity_classifications ec ON e.id = ec.entity_id\n INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id\n LEFT JOIN entity_relations er ON e.id = er.source_entity_id\n LEFT JOIN entities e2 ON er.target_entity_id = e2.id\n WHERE 1=1';\n\n $params = [];\n\n if ($search !== '') {\n $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';\n $params['search'] = '%' . $search . '%';\n $params['search2'] = '%' . $search . '%';\n }\n\n if ($classFilter !== '') {\n $sql .= ' AND oc.id = :class_id';\n $params['class_id'] = $classFilter;\n }\n\n $sql .= ' GROUP BY e.id, e.name, e.type, e.description, e.canonical_name, oc.id, oc.name, ec.confidence';\n $sql .= ' ORDER BY oc.name, e.name LIMIT ' . $limit . ' OFFSET ' . $offset;\n\n $stmt = $this->db->prepare($sql);\n $stmt->execute($params);\n\n return $stmt->fetchAll();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function countClassifiedEntities(string $search = '', string $classFilter = ''): int\n {\n $sql = 'SELECT COUNT(DISTINCT e.id)\n FROM entities e\n INNER JOIN entity_classifications ec ON e.id = ec.entity_id\n INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id\n WHERE 1=1';\n\n $params = [];\n\n if ($search !== '') {\n $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';\n $params['search'] = '%' . $search . '%';\n $params['search2'] = '%' . $search . '%';\n }\n\n if ($classFilter !== '') {\n $sql .= ' AND oc.id = :class_id';\n $params['class_id'] = $classFilter;\n }\n\n $stmt = $this->db->prepare($sql);\n $stmt->execute($params);\n\n return (int) $stmt->fetchColumn();\n }\n}",
"originalFile": "<?php\n\ndeclare(strict_types=1);\n\nnamespace Infrastructure\\Persistence;\n\n\/\/ @responsibility: CRUD-Operationen für Ontologie-Klassen (Hierarchie + JSON-Properties)\n\nuse Domain\\Repository\\OntologyRepositoryInterface;\nuse PDO;\n\nfinal class OntologyRepository implements OntologyRepositoryInterface\n{\n private PDO $db;\n\n public function __construct(PDO $pdo)\n {\n $this->db = $pdo;\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function findAll(): array\n {\n return $this->db->query(\n 'SELECT oc.*,\n COUNT(DISTINCT ec.entity_id) as entity_count,\n (SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id = oc.id) as subclass_count\n FROM ontology_classes oc\n LEFT JOIN entity_classifications ec ON oc.id = ec.ontology_class_id\n GROUP BY oc.id\n ORDER BY oc.name'\n )->fetchAll();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function getStats(): array\n {\n $result = $this->db->query(\n 'SELECT\n (SELECT COUNT(*) FROM ontology_classes) as total_classes,\n (SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id IS NULL) as root_classes,\n (SELECT COUNT(DISTINCT entity_id) FROM entity_classifications) as classified_entities'\n )->fetch();\n\n return $result !== false ? $result : [\n 'total_classes' => 0,\n 'root_classes' => 0,\n 'classified_entities' => 0,\n ];\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function find(int $id): ?array\n {\n $stmt = $this->db->prepare('SELECT * FROM ontology_classes WHERE id = :id');\n $stmt->execute(['id' => $id]);\n $result = $stmt->fetch();\n\n return $result === false ? null : $result;\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function create(string $name, ?int $parentId = null, ?string $description = null, array $properties = []): int\n {\n $stmt = $this->db->prepare(\n 'INSERT INTO ontology_classes (name, parent_class_id, description, properties, created_at)\n VALUES (:name, :parent, :description, :properties, NOW())'\n );\n $stmt->execute([\n 'name' => $name,\n 'parent' => $parentId,\n 'description' => $description,\n 'properties' => json_encode($properties),\n ]);\n\n return (int) $this->db->lastInsertId();\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function update(int $id, string $name, ?int $parentId = null, ?string $description = null, array $properties = []): bool\n {\n $stmt = $this->db->prepare(\n 'UPDATE ontology_classes SET name = :name, parent_class_id = :parent,\n description = :description, properties = :properties WHERE id = :id'\n );\n\n return $stmt->execute([\n 'id' => $id,\n 'name' => $name,\n 'parent' => $parentId,\n 'description' => $description,\n 'properties' => json_encode($properties),\n ]);\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function delete(int $id): bool\n {\n \/\/ Check for subclasses\n $stmt = $this->db->prepare('SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id = :id');\n $stmt->execute(['id' => $id]);\n\n if ((int) $stmt->fetchColumn() > 0) {\n return false; \/\/ Has subclasses, cannot delete\n }\n\n \/\/ Delete entity classifications\n $stmt = $this->db->prepare('DELETE FROM entity_classifications WHERE ontology_class_id = :id');\n $stmt->execute(['id' => $id]);\n\n \/\/ Delete class\n $stmt = $this->db->prepare('DELETE FROM ontology_classes WHERE id = :id');\n\n return $stmt->execute(['id' => $id]);\n }\n\n \/**\n * {@inheritDoc}\n *\/\n public function findForSelect(): array\n {\n return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();\n }\n}\n",
"structuredPatch": [
{
"oldStart": 133,
"oldLines": 4,
"newStart": 133,
"newLines": 73,
"lines": [
" {",
" return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll();",
" }",
"+",
"+ \/**",
"+ * {@inheritDoc}",
"+ *\/",
"+ public function findClassifiedEntities(string $search = '', string $classFilter = '', int $limit = 50, int $offset = 0): array",
"+ {",
"+ $sql = 'SELECT e.id as entity_id, e.name as entity_name, e.type as entity_type,",
"+ e.description, e.canonical_name,",
"+ oc.id as class_id, oc.name as class_name,",
"+ ec.confidence,",
"+ GROUP_CONCAT(DISTINCT CONCAT(er.relation_type, \":\", e2.name) SEPARATOR \", \") as relations",
"+ FROM entities e",
"+ INNER JOIN entity_classifications ec ON e.id = ec.entity_id",
"+ INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id",
"+ LEFT JOIN entity_relations er ON e.id = er.source_entity_id",
"+ LEFT JOIN entities e2 ON er.target_entity_id = e2.id",
"+ WHERE 1=1';",
"+",
"+ $params = [];",
"+",
"+ if ($search !== '') {",
"+ $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';",
"+ $params['search'] = '%' . $search . '%';",
"+ $params['search2'] = '%' . $search . '%';",
"+ }",
"+",
"+ if ($classFilter !== '') {",
"+ $sql .= ' AND oc.id = :class_id';",
"+ $params['class_id'] = $classFilter;",
"+ }",
"+",
"+ $sql .= ' GROUP BY e.id, e.name, e.type, e.description, e.canonical_name, oc.id, oc.name, ec.confidence';",
"+ $sql .= ' ORDER BY oc.name, e.name LIMIT ' . $limit . ' OFFSET ' . $offset;",
"+",
"+ $stmt = $this->db->prepare($sql);",
"+ $stmt->execute($params);",
"+",
"+ return $stmt->fetchAll();",
"+ }",
"+",
"+ \/**",
"+ * {@inheritDoc}",
"+ *\/",
"+ public function countClassifiedEntities(string $search = '', string $classFilter = ''): int",
"+ {",
"+ $sql = 'SELECT COUNT(DISTINCT e.id)",
"+ FROM entities e",
"+ INNER JOIN entity_classifications ec ON e.id = ec.entity_id",
"+ INNER JOIN ontology_classes oc ON ec.ontology_class_id = oc.id",
"+ WHERE 1=1';",
"+",
"+ $params = [];",
"+",
"+ if ($search !== '') {",
"+ $sql .= ' AND (e.name LIKE :search OR e.description LIKE :search2)';",
"+ $params['search'] = '%' . $search . '%';",
"+ $params['search2'] = '%' . $search . '%';",
"+ }",
"+",
"+ if ($classFilter !== '') {",
"+ $sql .= ' AND oc.id = :class_id';",
"+ $params['class_id'] = $classFilter;",
"+ }",
"+",
"+ $stmt = $this->db->prepare($sql);",
"+ $stmt->execute($params);",
"+",
"+ return (int) $stmt->fetchColumn();",
"+ }",
" }"
]
}
],
"userModified": false,
"replaceAll": false
}
}