Newwebshop/app/Admin/controllers/AdminCategoryController.php

448 lines
16 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Admin-Kategorien-Controller für das Webshop-System
*
* @author Webshop System
* @license GPL v3
*/
namespace App\Admin\Controllers;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
class AdminCategoryController
{
public function index()
{
// 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);
// 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;
}
}