Newwebshop/app/Front/controllers/ProductController.php

340 lines
13 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Frontend-Produktdetail-Controller für das Webshop-System
*
* @author Webshop System
* @license GPL v3
*/
namespace App\Front\Controllers;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Exception;
class ProductController
{
public function show($id)
{
// 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);
// 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 '
<div class="modal-header">
<h5 class="modal-title">' . htmlspecialchars($product['name']) . '</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<img src="' . htmlspecialchars($product['image']) . '"
class="img-fluid"
alt="' . htmlspecialchars($product['name']) . '">
</div>
<div class="col-md-6">
<h6>' . htmlspecialchars($product['name']) . '</h6>
<p class="text-muted">' . htmlspecialchars($product['category_name']) . '</p>
<p>' . htmlspecialchars(substr($product['description'], 0, 200)) . '...</p>
<h5 class="text-success">€' . number_format($product['price'], 2, ',', '.') . '</h5>
<button class="btn btn-primary add-to-cart-quick"
data-product-id="' . $product['id'] . '">
<i class="fas fa-cart-plus me-2"></i>Zum Warenkorb
</button>
</div>
</div>
</div>';
}
protected function render($template, $data = [])
{
// Einfache Template-Engine (später durch Twig ersetzen)
extract($data);
include __DIR__ . '/../../templates/' . $template;
}
}