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); // Produkt mit Kategorie laden $stmt = $conn->prepare(' SELECT p.*, c.name as category_name, c.id as category_id FROM ws_product p LEFT JOIN ws_category c ON p.category_id = c.id WHERE p.id = ? AND p.active = 1 '); $stmt->execute([$id]); $product = $stmt->fetchAssociative(); if (!$product) { $this->render('front/error/404.html.twig', [ 'title' => 'Webshop - Produkt nicht gefunden', 'message' => 'Das angeforderte Produkt wurde nicht gefunden.' ]); return; } // Bewertungen laden $stmt = $conn->prepare(' SELECT r.*, c.first_name, c.last_name FROM ws_review r LEFT JOIN ws_customer c ON r.customer_id = c.id WHERE r.product_id = ? AND r.active = 1 ORDER BY r.created_at DESC '); $stmt->execute([$id]); $reviews = $stmt->fetchAllAssociative(); // Durchschnittsbewertung berechnen $stmt = $conn->prepare(' SELECT AVG(rating) as avg_rating, COUNT(*) as total_reviews FROM ws_review WHERE product_id = ? AND active = 1 '); $stmt->execute([$id]); $ratingStats = $stmt->fetchAssociative(); // Verwandte Produkte laden (gleiche Kategorie) $stmt = $conn->prepare(' SELECT p.*, c.name as category_name FROM ws_product p LEFT JOIN ws_category c ON p.category_id = c.id WHERE p.category_id = ? AND p.id != ? AND p.active = 1 ORDER BY RAND() LIMIT 4 '); $stmt->execute([$product['category_id'], $id]); $relatedProducts = $stmt->fetchAllAssociative(); // Produktbilder laden $stmt = $conn->prepare(' SELECT * FROM ws_product_image WHERE product_id = ? ORDER BY sort_order ASC '); $stmt->execute([$id]); $productImages = $stmt->fetchAllAssociative(); // Produktvarianten laden (falls vorhanden) $stmt = $conn->prepare(' SELECT * FROM ws_product_variant WHERE product_id = ? AND active = 1 ORDER BY sort_order ASC '); $stmt->execute([$id]); $productVariants = $stmt->fetchAllAssociative(); $this->render('front/product/show.html.twig', [ 'title' => 'Webshop - ' . $product['name'], 'product' => $product, 'reviews' => $reviews, 'ratingStats' => $ratingStats, 'relatedProducts' => $relatedProducts, 'productImages' => $productImages, 'productVariants' => $productVariants ]); } catch (Exception $e) { $this->render('front/error/500.html.twig', [ 'title' => 'Webshop - Fehler', 'message' => 'Ein Fehler ist aufgetreten: ' . $e->getMessage() ]); } } public function addReview() { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header('Location: /'); return; } $productId = $_POST['product_id'] ?? null; $rating = $_POST['rating'] ?? null; $comment = $_POST['comment'] ?? ''; $customerId = $_SESSION['customer_id'] ?? null; if (!$productId || !$rating || !$customerId) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Ungültige Daten']); 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); // Prüfen ob bereits eine Bewertung existiert $stmt = $conn->prepare(' SELECT id FROM ws_review WHERE product_id = ? AND customer_id = ? '); $stmt->execute([$productId, $customerId]); $existingReview = $stmt->fetchAssociative(); if ($existingReview) { // Bewertung aktualisieren $stmt = $conn->prepare(' UPDATE ws_review SET rating = ?, comment = ?, updated_at = NOW() WHERE id = ? '); $stmt->execute([$rating, $comment, $existingReview['id']]); } else { // Neue Bewertung erstellen $stmt = $conn->prepare(' INSERT INTO ws_review (product_id, customer_id, rating, comment, active, created_at) VALUES (?, ?, ?, ?, 1, NOW()) '); $stmt->execute([$productId, $customerId, $rating, $comment]); } header('Content-Type: application/json'); echo json_encode(['success' => true, 'message' => 'Bewertung erfolgreich gespeichert']); } catch (Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Fehler: ' . $e->getMessage()]); } } public function addToWishlist() { if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Ungültige Anfrage']); return; } $productId = $_POST['product_id'] ?? null; $customerId = $_SESSION['customer_id'] ?? null; if (!$productId || !$customerId) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Nicht angemeldet']); 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); // Prüfen ob bereits in Wunschliste $stmt = $conn->prepare(' SELECT id FROM ws_wishlist WHERE product_id = ? AND customer_id = ? '); $stmt->execute([$productId, $customerId]); $existing = $stmt->fetchAssociative(); if ($existing) { // Aus Wunschliste entfernen $stmt = $conn->prepare('DELETE FROM ws_wishlist WHERE id = ?'); $stmt->execute([$existing['id']]); $message = 'Aus Wunschliste entfernt'; $inWishlist = false; } else { // Zur Wunschliste hinzufügen $stmt = $conn->prepare(' INSERT INTO ws_wishlist (product_id, customer_id, created_at) VALUES (?, ?, NOW()) '); $stmt->execute([$productId, $customerId]); $message = 'Zur Wunschliste hinzugefügt'; $inWishlist = true; } header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'message' => $message, 'in_wishlist' => $inWishlist ]); } catch (Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Fehler: ' . $e->getMessage()]); } } public function quickView() { $productId = $_GET['id'] ?? null; if (!$productId) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Produkt-ID fehlt']); 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); $stmt = $conn->prepare(' SELECT p.*, c.name as category_name FROM ws_product p LEFT JOIN ws_category c ON p.category_id = c.id WHERE p.id = ? AND p.active = 1 '); $stmt->execute([$productId]); $product = $stmt->fetchAssociative(); if (!$product) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Produkt nicht gefunden']); return; } // Quick View HTML generieren $html = $this->generateQuickViewHtml($product); header('Content-Type: application/json'); echo json_encode([ 'success' => true, 'html' => $html ]); } catch (Exception $e) { header('Content-Type: application/json'); echo json_encode(['success' => false, 'message' => 'Fehler: ' . $e->getMessage()]); } } private function generateQuickViewHtml($product) { return ' '; } protected function render($template, $data = []) { // Einfache Template-Engine (später durch Twig ersetzen) extract($data); include __DIR__ . '/../../templates/' . $template; } }