pdo = new \PDO( 'mysql:host=localhost;dbname=ki_dev;charset=utf8mb4', 'root', $this->getPassword(), [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, ] ); } private function getPassword(): string { $file = '/var/www/docs/credentials/credentials.md'; $content = file_get_contents($file); foreach (explode("\n", $content) as $line) { if (str_contains($line, 'MariaDB') && str_contains($line, 'root')) { $parts = explode('|', $line); if (count($parts) >= 4) { return trim($parts[3]); } } } return ''; } public function findById(int $id): ?array { $stmt = $this->pdo->prepare('SELECT * FROM dokumentation WHERE id = :id'); $stmt->execute(['id' => $id]); $result = $stmt->fetch(); return $result !== false ? $result : null; } public function findByPath(string $path): ?array { $stmt = $this->pdo->prepare('SELECT * FROM dokumentation WHERE path = :path AND status = :status'); $stmt->execute(['path' => $path, 'status' => 'published']); $result = $stmt->fetch(); return $result !== false ? $result : null; } public function findBySlug(string $slug, ?int $parentId = null): ?array { if ($parentId === null) { $stmt = $this->pdo->prepare('SELECT * FROM dokumentation WHERE slug = :slug AND parent_id IS NULL AND status = :status'); $stmt->execute(['slug' => $slug, 'status' => 'published']); } else { $stmt = $this->pdo->prepare('SELECT * FROM dokumentation WHERE slug = :slug AND parent_id = :parent_id AND status = :status'); $stmt->execute(['slug' => $slug, 'parent_id' => $parentId, 'status' => 'published']); } $result = $stmt->fetch(); return $result !== false ? $result : null; } public function findDocBySlug(string $slug): ?array { $stmt = $this->pdo->prepare('SELECT * FROM dokumentation WHERE slug = :slug AND status = :status LIMIT 1'); $stmt->execute(['slug' => $slug, 'status' => 'published']); $result = $stmt->fetch(); return $result !== false ? $result : null; } public function findChildren(int $parentId): array { $stmt = $this->pdo->prepare(' SELECT * FROM dokumentation WHERE parent_id = :parent_id AND status = :status ORDER BY sort_order ASC '); $stmt->execute(['parent_id' => $parentId, 'status' => 'published']); return $stmt->fetchAll(); } public function findRootDocuments(): array { $stmt = $this->pdo->prepare(' SELECT * FROM dokumentation WHERE parent_id IS NULL AND status = :status ORDER BY sort_order ASC '); $stmt->execute(['status' => 'published']); return $stmt->fetchAll(); } public function getHierarchy(): array { $roots = $this->findRootDocuments(); return $this->buildTree($roots); } private function buildTree(array $items): array { $result = []; foreach ($items as $item) { $children = $this->findChildren((int) $item['id']); $item['children'] = $this->buildTree($children); $result[] = $item; } return $result; } public function getBreadcrumb(int $docId): array { $breadcrumb = []; $doc = $this->findById($docId); while ($doc !== null) { array_unshift($breadcrumb, [ 'title' => $doc['title'], 'path' => $doc['path'], ]); if ($doc['parent_id'] !== null) { $doc = $this->findById((int) $doc['parent_id']); } else { $doc = null; } } return $breadcrumb; } public function getSiblings(int $docId): array { $doc = $this->findById($docId); if ($doc === null) { return []; } if ($doc['parent_id'] === null) { return $this->findRootDocuments(); } return $this->findChildren((int) $doc['parent_id']); } public function getStatistics(): array { $stats = []; $stmt = $this->pdo->query('SELECT COUNT(*) FROM dokumentation'); $stats['total'] = (int) $stmt->fetchColumn(); $stmt = $this->pdo->query('SELECT depth, COUNT(*) as count FROM dokumentation GROUP BY depth ORDER BY depth'); $stats['by_depth'] = $stmt->fetchAll(); $stmt = $this->pdo->query('SELECT status, COUNT(*) as count FROM dokumentation GROUP BY status'); $stats['by_status'] = $stmt->fetchAll(); return $stats; } }