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; } }