448 lines
16 KiB
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;
|
|
}
|
|
}
|