db = DatabaseFactory::content(); } /** * {@inheritDoc} */ public function findAll(): array { return $this->db->query( 'SELECT oc.*, COUNT(DISTINCT ec.entity_id) as entity_count, (SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id = oc.id) as subclass_count FROM ontology_classes oc LEFT JOIN entity_classifications ec ON oc.id = ec.ontology_class_id GROUP BY oc.id ORDER BY oc.name' )->fetchAll(); } /** * {@inheritDoc} */ public function getStats(): array { $result = $this->db->query( 'SELECT (SELECT COUNT(*) FROM ontology_classes) as total_classes, (SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id IS NULL) as root_classes, (SELECT COUNT(DISTINCT entity_id) FROM entity_classifications) as classified_entities' )->fetch(); return $result !== false ? $result : [ 'total_classes' => 0, 'root_classes' => 0, 'classified_entities' => 0, ]; } /** * {@inheritDoc} */ public function find(int $id): ?array { $stmt = $this->db->prepare('SELECT * FROM ontology_classes WHERE id = :id'); $stmt->execute(['id' => $id]); $result = $stmt->fetch(); return $result === false ? null : $result; } /** * {@inheritDoc} */ public function create(string $name, ?int $parentId = null, ?string $description = null, array $properties = []): int { $stmt = $this->db->prepare( 'INSERT INTO ontology_classes (name, parent_class_id, description, properties, created_at) VALUES (:name, :parent, :description, :properties, NOW())' ); $stmt->execute([ 'name' => $name, 'parent' => $parentId, 'description' => $description, 'properties' => json_encode($properties), ]); return (int) $this->db->lastInsertId(); } /** * {@inheritDoc} */ public function update(int $id, string $name, ?int $parentId = null, ?string $description = null, array $properties = []): bool { $stmt = $this->db->prepare( 'UPDATE ontology_classes SET name = :name, parent_class_id = :parent, description = :description, properties = :properties WHERE id = :id' ); return $stmt->execute([ 'id' => $id, 'name' => $name, 'parent' => $parentId, 'description' => $description, 'properties' => json_encode($properties), ]); } /** * {@inheritDoc} */ public function delete(int $id): bool { // Check for subclasses $stmt = $this->db->prepare('SELECT COUNT(*) FROM ontology_classes WHERE parent_class_id = :id'); $stmt->execute(['id' => $id]); if ((int) $stmt->fetchColumn() > 0) { return false; // Has subclasses, cannot delete } // Delete entity classifications $stmt = $this->db->prepare('DELETE FROM entity_classifications WHERE ontology_class_id = :id'); $stmt->execute(['id' => $id]); // Delete class $stmt = $this->db->prepare('DELETE FROM ontology_classes WHERE id = :id'); return $stmt->execute(['id' => $id]); } /** * {@inheritDoc} */ public function findForSelect(): array { return $this->db->query('SELECT id, name FROM ontology_classes ORDER BY name')->fetchAll(); } }