Newwebshop/app/Front/controllers/SearchController.php

203 lines
6.7 KiB
PHP

<?php
/**
* Copyright seit 2024 Webshop System
*
* Frontend-Such-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 SearchController
{
public function index()
{
$query = $_GET['q'] ?? '';
$category = $_GET['category'] ?? '';
$sort = $_GET['sort'] ?? 'name';
$order = $_GET['order'] ?? 'asc';
$minPrice = $_GET['min_price'] ?? '';
$maxPrice = $_GET['max_price'] ?? '';
$page = max(1, intval($_GET['page'] ?? 1));
$perPage = 12;
// 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);
// Suchbedingungen aufbauen
$whereConditions = ['p.active = 1'];
$params = [];
if (!empty($query)) {
$whereConditions[] = '(p.name LIKE ? OR p.description LIKE ?)';
$params[] = '%' . $query . '%';
$params[] = '%' . $query . '%';
}
if (!empty($category)) {
$whereConditions[] = 'p.category_id = ?';
$params[] = $category;
}
if (!empty($minPrice)) {
$whereConditions[] = 'p.price >= ?';
$params[] = $minPrice;
}
if (!empty($maxPrice)) {
$whereConditions[] = 'p.price <= ?';
$params[] = $maxPrice;
}
$whereClause = implode(' AND ', $whereConditions);
// Gesamtanzahl für Pagination
$countSql = "
SELECT COUNT(*) as total
FROM ws_product p
LEFT JOIN ws_category c ON p.category_id = c.id
WHERE $whereClause
";
$stmt = $conn->prepare($countSql);
$stmt->execute($params);
$totalCount = $stmt->fetchAssociative()['total'];
// Produkte laden
$offset = ($page - 1) * $perPage;
$sql = "
SELECT p.*, c.name as category_name
FROM ws_product p
LEFT JOIN ws_category c ON p.category_id = c.id
WHERE $whereClause
ORDER BY p.$sort $order
LIMIT $perPage OFFSET $offset
";
$stmt = $conn->prepare($sql);
$stmt->execute($params);
$products = [];
while ($row = $stmt->fetchAssociative()) {
$products[] = $row;
}
// Kategorien für Filter laden
$stmt = $conn->prepare('SELECT id, name FROM ws_category WHERE active = 1 ORDER BY name');
$stmt->execute();
$categories = [];
while ($row = $stmt->fetchAssociative()) {
$categories[] = $row;
}
// Pagination berechnen
$totalPages = ceil($totalCount / $perPage);
$pagination = [
'current' => $page,
'total' => $totalPages,
'per_page' => $perPage,
'total_count' => $totalCount
];
$this->render('front/search/index.html.twig', [
'title' => 'Webshop - Suche',
'query' => $query,
'products' => $products,
'categories' => $categories,
'pagination' => $pagination,
'filters' => [
'category' => $category,
'sort' => $sort,
'order' => $order,
'min_price' => $minPrice,
'max_price' => $maxPrice
]
]);
} catch (Exception $e) {
$this->render('front/search/index.html.twig', [
'title' => 'Webshop - Suche',
'query' => $query,
'products' => [],
'categories' => [],
'pagination' => ['current' => 1, 'total' => 1, 'per_page' => 12, 'total_count' => 0],
'filters' => [],
'error' => 'Datenbankfehler: ' . $e->getMessage()
]);
}
}
public function ajax()
{
// AJAX-Suche für Live-Suggestions
$query = $_GET['q'] ?? '';
if (empty($query) || strlen($query) < 2) {
header('Content-Type: application/json');
echo json_encode(['products' => []]);
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);
$sql = "
SELECT p.id, p.name, p.price, p.image, c.name as category_name
FROM ws_product p
LEFT JOIN ws_category c ON p.category_id = c.id
WHERE p.active = 1 AND (p.name LIKE ? OR p.description LIKE ?)
ORDER BY p.name ASC
LIMIT 5
";
$stmt = $conn->prepare($sql);
$stmt->execute(['%' . $query . '%', '%' . $query . '%']);
$products = [];
while ($row = $stmt->fetchAssociative()) {
$products[] = $row;
}
header('Content-Type: application/json');
echo json_encode(['products' => $products]);
} catch (Exception $e) {
header('Content-Type: application/json');
echo json_encode(['products' => [], 'error' => $e->getMessage()]);
}
}
protected function render($template, $data = [])
{
// Einfache Template-Engine (später durch Twig ersetzen)
extract($data);
include __DIR__ . '/../../templates/' . $template;
}
}