Newwebshop/app/Front/controllers/CustomerController.php

523 lines
18 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Frontend-Kunden-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 CustomerController
{
public function register()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$this->processRegistration();
} else {
$this->render('front/customer/register.html.twig', [
'title' => 'Webshop - Registrierung'
]);
}
}
private function processRegistration()
{
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$confirmPassword = $_POST['confirm_password'] ?? '';
$firstName = $_POST['first_name'] ?? '';
$lastName = $_POST['last_name'] ?? '';
$phone = $_POST['phone'] ?? '';
$newsletter = isset($_POST['newsletter']) ? 1 : 0;
// Validierung
$errors = [];
if (empty($email)) {
$errors[] = 'E-Mail-Adresse ist erforderlich';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Ungültige E-Mail-Adresse';
}
if (empty($password)) {
$errors[] = 'Passwort ist erforderlich';
} elseif (strlen($password) < 6) {
$errors[] = 'Passwort muss mindestens 6 Zeichen lang sein';
}
if ($password !== $confirmPassword) {
$errors[] = 'Passwörter stimmen nicht überein';
}
if (empty($firstName)) {
$errors[] = 'Vorname ist erforderlich';
}
if (empty($lastName)) {
$errors[] = 'Nachname ist erforderlich';
}
if (!empty($errors)) {
$this->render('front/customer/register.html.twig', [
'title' => 'Webshop - Registrierung',
'errors' => $errors,
'old' => $_POST
]);
return;
}
// 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);
// Prüfen ob E-Mail bereits existiert
$stmt = $conn->prepare('SELECT id FROM ws_customer WHERE email = ?');
$stmt->execute([$email]);
$existingCustomer = $stmt->fetchAssociative();
if ($existingCustomer) {
$this->render('front/customer/register.html.twig', [
'title' => 'Webshop - Registrierung',
'errors' => ['E-Mail-Adresse ist bereits registriert'],
'old' => $_POST
]);
return;
}
// Kunde erstellen
$stmt = $conn->prepare('
INSERT INTO ws_customer (email, password, first_name, last_name, phone, newsletter, active, created_at)
VALUES (?, ?, ?, ?, ?, ?, 1, NOW())
');
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt->execute([$email, $hashedPassword, $firstName, $lastName, $phone, $newsletter]);
$customerId = $conn->lastInsertId();
// Session starten
session_start();
$_SESSION['customer_id'] = $customerId;
$_SESSION['customer_email'] = $email;
$_SESSION['customer_name'] = $firstName . ' ' . $lastName;
// Willkommens-E-Mail senden
$this->sendWelcomeEmail($email, $firstName);
// Weiterleitung zum Kundenkonto
header('Location: /account');
exit;
} catch (Exception $e) {
$this->render('front/customer/register.html.twig', [
'title' => 'Webshop - Registrierung',
'errors' => ['Registrierungsfehler: ' . $e->getMessage()],
'old' => $_POST
]);
}
}
public function login()
{
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$this->processLogin();
} else {
$this->render('front/customer/login.html.twig', [
'title' => 'Webshop - Anmeldung'
]);
}
}
private function processLogin()
{
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$remember = isset($_POST['remember']);
if (empty($email) || empty($password)) {
$this->render('front/customer/login.html.twig', [
'title' => 'Webshop - Anmeldung',
'errors' => ['E-Mail und Passwort sind erforderlich'],
'old' => $_POST
]);
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 id, email, password, first_name, last_name, active
FROM ws_customer
WHERE email = ?
');
$stmt->execute([$email]);
$customer = $stmt->fetchAssociative();
if (!$customer || !password_verify($password, $customer['password'])) {
$this->render('front/customer/login.html.twig', [
'title' => 'Webshop - Anmeldung',
'errors' => ['Ungültige E-Mail oder Passwort'],
'old' => $_POST
]);
return;
}
if (!$customer['active']) {
$this->render('front/customer/login.html.twig', [
'title' => 'Webshop - Anmeldung',
'errors' => ['Ihr Konto ist deaktiviert'],
'old' => $_POST
]);
return;
}
// Session starten
session_start();
$_SESSION['customer_id'] = $customer['id'];
$_SESSION['customer_email'] = $customer['email'];
$_SESSION['customer_name'] = $customer['first_name'] . ' ' . $customer['last_name'];
// Remember Me
if ($remember) {
$token = bin2hex(random_bytes(32));
$stmt = $conn->prepare('
INSERT INTO ws_customer_token (customer_id, token, expires_at)
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 30 DAY))
');
$stmt->execute([$customer['id'], $token]);
setcookie('remember_token', $token, time() + (30 * 24 * 60 * 60), '/', '', true, true);
}
// Weiterleitung
$redirect = $_GET['redirect'] ?? '/account';
header('Location: ' . $redirect);
exit;
} catch (Exception $e) {
$this->render('front/customer/login.html.twig', [
'title' => 'Webshop - Anmeldung',
'errors' => ['Anmeldefehler: ' . $e->getMessage()],
'old' => $_POST
]);
}
}
public function logout()
{
session_start();
session_destroy();
// Remember Me Token löschen
if (isset($_COOKIE['remember_token'])) {
$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('DELETE FROM ws_customer_token WHERE token = ?');
$stmt->execute([$_COOKIE['remember_token']]);
} catch (Exception $e) {
// Ignore errors
}
setcookie('remember_token', '', time() - 3600, '/');
}
header('Location: /');
exit;
}
public function account()
{
if (!isset($_SESSION['customer_id'])) {
header('Location: /login?redirect=' . urlencode('/account'));
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);
// Kundeninformationen laden
$stmt = $conn->prepare('
SELECT * FROM ws_customer WHERE id = ?
');
$stmt->execute([$_SESSION['customer_id']]);
$customer = $stmt->fetchAssociative();
// Bestellungen laden
$stmt = $conn->prepare('
SELECT * FROM ws_order
WHERE customer_id = ?
ORDER BY created_at DESC
LIMIT 10
');
$stmt->execute([$_SESSION['customer_id']]);
$orders = $stmt->fetchAllAssociative();
// Wunschliste laden
$stmt = $conn->prepare('
SELECT w.*, p.name, p.price, p.image
FROM ws_wishlist w
LEFT JOIN ws_product p ON w.product_id = p.id
WHERE w.customer_id = ?
ORDER BY w.created_at DESC
');
$stmt->execute([$_SESSION['customer_id']]);
$wishlist = $stmt->fetchAllAssociative();
// Bewertungen laden
$stmt = $conn->prepare('
SELECT r.*, p.name as product_name, p.id as product_id
FROM ws_review r
LEFT JOIN ws_product p ON r.product_id = p.id
WHERE r.customer_id = ?
ORDER BY r.created_at DESC
');
$stmt->execute([$_SESSION['customer_id']]);
$reviews = $stmt->fetchAllAssociative();
$this->render('front/customer/account.html.twig', [
'title' => 'Webshop - Mein Konto',
'customer' => $customer,
'orders' => $orders,
'wishlist' => $wishlist,
'reviews' => $reviews
]);
} catch (Exception $e) {
$this->render('front/customer/account.html.twig', [
'title' => 'Webshop - Mein Konto',
'error' => 'Fehler beim Laden der Daten: ' . $e->getMessage()
]);
}
}
public function profile()
{
if (!isset($_SESSION['customer_id'])) {
header('Location: /login?redirect=' . urlencode('/profile'));
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$this->updateProfile();
} else {
$this->loadProfile();
}
}
private function loadProfile()
{
$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 * FROM ws_customer WHERE id = ?');
$stmt->execute([$_SESSION['customer_id']]);
$customer = $stmt->fetchAssociative();
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'customer' => $customer
]);
} catch (Exception $e) {
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'error' => 'Fehler beim Laden der Daten: ' . $e->getMessage()
]);
}
}
private function updateProfile()
{
$firstName = $_POST['first_name'] ?? '';
$lastName = $_POST['last_name'] ?? '';
$phone = $_POST['phone'] ?? '';
$newsletter = isset($_POST['newsletter']) ? 1 : 0;
$currentPassword = $_POST['current_password'] ?? '';
$newPassword = $_POST['new_password'] ?? '';
$confirmPassword = $_POST['confirm_password'] ?? '';
$errors = [];
if (empty($firstName)) {
$errors[] = 'Vorname ist erforderlich';
}
if (empty($lastName)) {
$errors[] = 'Nachname ist erforderlich';
}
if (!empty($newPassword)) {
if (empty($currentPassword)) {
$errors[] = 'Aktuelles Passwort ist erforderlich';
}
if (strlen($newPassword) < 6) {
$errors[] = 'Neues Passwort muss mindestens 6 Zeichen lang sein';
}
if ($newPassword !== $confirmPassword) {
$errors[] = 'Neue Passwörter stimmen nicht überein';
}
}
if (!empty($errors)) {
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'errors' => $errors,
'old' => $_POST
]);
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);
// Aktuelles Passwort prüfen
if (!empty($newPassword)) {
$stmt = $conn->prepare('SELECT password FROM ws_customer WHERE id = ?');
$stmt->execute([$_SESSION['customer_id']]);
$customer = $stmt->fetchAssociative();
if (!password_verify($currentPassword, $customer['password'])) {
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'errors' => ['Aktuelles Passwort ist falsch'],
'old' => $_POST
]);
return;
}
}
// Profil aktualisieren
if (!empty($newPassword)) {
$hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);
$stmt = $conn->prepare('
UPDATE ws_customer
SET first_name = ?, last_name = ?, phone = ?, newsletter = ?, password = ?, updated_at = NOW()
WHERE id = ?
');
$stmt->execute([$firstName, $lastName, $phone, $newsletter, $hashedPassword, $_SESSION['customer_id']]);
} else {
$stmt = $conn->prepare('
UPDATE ws_customer
SET first_name = ?, last_name = ?, phone = ?, newsletter = ?, updated_at = NOW()
WHERE id = ?
');
$stmt->execute([$firstName, $lastName, $phone, $newsletter, $_SESSION['customer_id']]);
}
// Session aktualisieren
$_SESSION['customer_name'] = $firstName . ' ' . $lastName;
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'success' => 'Profil erfolgreich aktualisiert',
'customer' => [
'first_name' => $firstName,
'last_name' => $lastName,
'phone' => $phone,
'newsletter' => $newsletter
]
]);
} catch (Exception $e) {
$this->render('front/customer/profile.html.twig', [
'title' => 'Webshop - Profil bearbeiten',
'errors' => ['Fehler beim Aktualisieren: ' . $e->getMessage()],
'old' => $_POST
]);
}
}
private function sendWelcomeEmail($email, $firstName)
{
// Einfache E-Mail-Funktion (später durch PHPMailer ersetzen)
$to = $email;
$subject = 'Willkommen bei Webshop!';
$message = "Hallo $firstName,\n\n";
$message .= "Vielen Dank für Ihre Registrierung bei Webshop!\n";
$message .= "Sie können sich jetzt mit Ihrer E-Mail-Adresse anmelden.\n\n";
$message .= "Mit freundlichen Grüßen\n";
$message .= "Ihr Webshop-Team";
$headers = 'From: noreply@webshop-system.de' . "\r\n" .
'Reply-To: info@webshop-system.de' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
}
protected function render($template, $data = [])
{
// Einfache Template-Engine (später durch Twig ersetzen)
extract($data);
include __DIR__ . '/../../templates/' . $template;
}
}