getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Kategorien laden mit Hierarchie und Produktanzahl $stmt = $conn->prepare(' SELECT c.*, p.name as parent_name, COUNT(pr.id) as product_count FROM ws_category c LEFT JOIN ws_category p ON c.parent_id = p.id LEFT JOIN ws_product pr ON c.id = pr.category_id GROUP BY c.id ORDER BY c.parent_id ASC, c.sort_order ASC, c.name ASC '); $stmt->execute(); $categories = []; while ($row = $stmt->fetchAssociative()) { $categories[] = $row; } // Hierarchische Struktur erstellen $hierarchicalCategories = $this->buildHierarchy($categories); $this->render('admin/categories/index.html.twig', [ 'title' => 'Webshop Admin - Kategorien', 'user_name' => $_SESSION['admin_user_name'], 'categories' => $categories, 'hierarchicalCategories' => $hierarchicalCategories ]); } catch (Exception $e) { $this->render('admin/categories/index.html.twig', [ 'title' => 'Webshop Admin - Kategorien', 'user_name' => $_SESSION['admin_user_name'], 'categories' => [], 'hierarchicalCategories' => [], 'error' => 'Datenbankfehler: ' . $e->getMessage() ]); } } public function show($id) { // Session prüfen session_start(); if (!isset($_SESSION['admin_user_id'])) { header('Location: /admin/login'); exit; } // DB-Verbindung herstellen $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Kategorie laden $stmt = $conn->prepare(' SELECT c.*, p.name as parent_name FROM ws_category c LEFT JOIN ws_category p ON c.parent_id = p.id WHERE c.id = ? '); $stmt->execute([$id]); $category = $stmt->fetchAssociative(); if (!$category) { header('Location: /admin/categories?error=Kategorie nicht gefunden'); exit; } // Produkte der Kategorie laden $stmt = $conn->prepare(' SELECT p.*, COUNT(op.product_id) as order_count FROM ws_product p LEFT JOIN ws_order_product op ON p.id = op.product_id WHERE p.category_id = ? GROUP BY p.id ORDER BY p.created_at DESC '); $stmt->execute([$id]); $products = []; while ($row = $stmt->fetchAssociative()) { $products[] = $row; } // Unterkategorien laden $stmt = $conn->prepare(' SELECT c.*, COUNT(p.id) as product_count FROM ws_category c LEFT JOIN ws_product p ON c.id = p.category_id WHERE c.parent_id = ? GROUP BY c.id ORDER BY c.sort_order ASC, c.name ASC '); $stmt->execute([$id]); $subcategories = []; while ($row = $stmt->fetchAssociative()) { $subcategories[] = $row; } $this->render('admin/categories/show.html.twig', [ 'title' => 'Webshop Admin - Kategorie Details', 'user_name' => $_SESSION['admin_user_name'], 'category' => $category, 'products' => $products, 'subcategories' => $subcategories ]); } catch (Exception $e) { header('Location: /admin/categories?error=Datenbankfehler: ' . $e->getMessage()); exit; } } public function create() { // Session prüfen session_start(); if (!isset($_SESSION['admin_user_id'])) { header('Location: /admin/login'); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->store(); return; } // Kategorien für Parent-Auswahl laden $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); $stmt = $conn->prepare('SELECT id, name, parent_id FROM ws_category ORDER BY name ASC'); $stmt->execute(); $categories = []; while ($row = $stmt->fetchAssociative()) { $categories[] = $row; } $this->render('admin/categories/create.html.twig', [ 'title' => 'Webshop Admin - Neue Kategorie', 'user_name' => $_SESSION['admin_user_name'], 'categories' => $categories ]); } catch (Exception $e) { header('Location: /admin/categories?error=Datenbankfehler: ' . $e->getMessage()); exit; } } private function store() { $name = $_POST['name'] ?? ''; $description = $_POST['description'] ?? ''; $parent_id = $_POST['parent_id'] ?? null; $sort_order = $_POST['sort_order'] ?? 0; $active = isset($_POST['active']) ? 1 : 0; if (empty($name)) { header('Location: /admin/categories/create?error=Name ist erforderlich'); exit; } $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Prüfen ob Name bereits existiert $stmt = $conn->prepare('SELECT id FROM ws_category WHERE name = ?'); $stmt->execute([$name]); if ($stmt->fetchAssociative()) { header('Location: /admin/categories/create?error=Name bereits vergeben'); exit; } $stmt = $conn->prepare(' INSERT INTO ws_category (name, description, parent_id, sort_order, active) VALUES (?, ?, ?, ?, ?) '); $stmt->execute([$name, $description, $parent_id, $sort_order, $active]); header('Location: /admin/categories?success=Kategorie erfolgreich erstellt'); exit; } catch (Exception $e) { header('Location: /admin/categories/create?error=Datenbankfehler: ' . $e->getMessage()); exit; } } public function edit($id) { // Session prüfen session_start(); if (!isset($_SESSION['admin_user_id'])) { header('Location: /admin/login'); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $this->update($id); return; } $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Kategorie laden $stmt = $conn->prepare('SELECT * FROM ws_category WHERE id = ?'); $stmt->execute([$id]); $category = $stmt->fetchAssociative(); if (!$category) { header('Location: /admin/categories?error=Kategorie nicht gefunden'); exit; } // Alle Kategorien für Parent-Auswahl laden (außer sich selbst) $stmt = $conn->prepare('SELECT id, name, parent_id FROM ws_category WHERE id != ? ORDER BY name ASC'); $stmt->execute([$id]); $categories = []; while ($row = $stmt->fetchAssociative()) { $categories[] = $row; } $this->render('admin/categories/edit.html.twig', [ 'title' => 'Webshop Admin - Kategorie bearbeiten', 'user_name' => $_SESSION['admin_user_name'], 'category' => $category, 'categories' => $categories ]); } catch (Exception $e) { header('Location: /admin/categories?error=Datenbankfehler: ' . $e->getMessage()); exit; } } private function update($id) { $name = $_POST['name'] ?? ''; $description = $_POST['description'] ?? ''; $parent_id = $_POST['parent_id'] ?? null; $sort_order = $_POST['sort_order'] ?? 0; $active = isset($_POST['active']) ? 1 : 0; if (empty($name)) { header('Location: /admin/categories/edit/' . $id . '?error=Name ist erforderlich'); exit; } $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Prüfen ob Name bereits existiert (außer bei dieser Kategorie) $stmt = $conn->prepare('SELECT id FROM ws_category WHERE name = ? AND id != ?'); $stmt->execute([$name, $id]); if ($stmt->fetchAssociative()) { header('Location: /admin/categories/edit/' . $id . '?error=Name bereits vergeben'); exit; } // Prüfen ob Parent-ID nicht auf sich selbst zeigt if ($parent_id == $id) { header('Location: /admin/categories/edit/' . $id . '?error=Kategorie kann nicht ihre eigene Unterkategorie sein'); exit; } $stmt = $conn->prepare(' UPDATE ws_category SET name = ?, description = ?, parent_id = ?, sort_order = ?, active = ?, updated_at = NOW() WHERE id = ? '); $stmt->execute([$name, $description, $parent_id, $sort_order, $active, $id]); header('Location: /admin/categories/show/' . $id . '?success=Kategorie erfolgreich aktualisiert'); exit; } catch (Exception $e) { header('Location: /admin/categories/edit/' . $id . '?error=Datenbankfehler: ' . $e->getMessage()); exit; } } public function delete($id) { // Session prüfen session_start(); if (!isset($_SESSION['admin_user_id'])) { header('Location: /admin/login'); exit; } $connectionParams = [ 'dbname' => getenv('DB_DATABASE') ?: 'freeshop', 'user' => getenv('DB_USERNAME') ?: 'freeshop_user', 'password' => getenv('DB_PASSWORD') ?: 'freeshop_password', 'host' => getenv('DB_HOST') ?: 'db', 'driver' => 'pdo_mysql', 'port' => getenv('DB_PORT') ?: 3306, 'charset' => 'utf8mb4', ]; try { $conn = DriverManager::getConnection($connectionParams); // Prüfen ob Kategorie Produkte hat $stmt = $conn->prepare('SELECT COUNT(*) as count FROM ws_product WHERE category_id = ?'); $stmt->execute([$id]); $productCount = $stmt->fetchAssociative()['count']; if ($productCount > 0) { header('Location: /admin/categories?error=Kategorie kann nicht gelöscht werden, da Produkte vorhanden sind'); exit; } // Prüfen ob Kategorie Unterkategorien hat $stmt = $conn->prepare('SELECT COUNT(*) as count FROM ws_category WHERE parent_id = ?'); $stmt->execute([$id]); $subcategoryCount = $stmt->fetchAssociative()['count']; if ($subcategoryCount > 0) { header('Location: /admin/categories?error=Kategorie kann nicht gelöscht werden, da Unterkategorien vorhanden sind'); exit; } $stmt = $conn->prepare('DELETE FROM ws_category WHERE id = ?'); $stmt->execute([$id]); header('Location: /admin/categories?success=Kategorie erfolgreich gelöscht'); exit; } catch (Exception $e) { header('Location: /admin/categories?error=Datenbankfehler: ' . $e->getMessage()); exit; } } private function buildHierarchy($categories, $parent_id = null) { $hierarchy = []; foreach ($categories as $category) { if ($category['parent_id'] == $parent_id) { $category['children'] = $this->buildHierarchy($categories, $category['id']); $hierarchy[] = $category; } } return $hierarchy; } protected function render($template, $data = []) { // Einfache Template-Engine (später durch Twig ersetzen) extract($data); include __DIR__ . '/../../templates/' . $template; } }