query("SELECT value FROM settings WHERE `key` = 'active_theme'");
$res =$stmt->fetchColumn();
if ($res) { $active_theme =$res; }
} catch (Exception $e) {}
$theme_dir = __DIR__ . '/themes/' .$active_theme;
if (!is_dir($theme_dir)) {
$active_theme = 'default';$theme_dir = __DIR__ . '/themes/default';
}
// --- Αρχικοποίηση Twig ---
$loader = new \Twig\Loader\FilesystemLoader($theme_dir);
$twig = new \Twig\Environment($loader, ['cache' => false]);
$twig->addGlobal('session',$_SESSION);
$twig->addGlobal('current_lang',$current_lang);
// --- Φόρτωση Δυναμικών Κειμένων Site ---
$siteTexts = [];
try {
$text_column = ($current_lang === 'en') ? 'text_value_en' : 'text_value_el';
$textsStmt =$pdo->query("SELECT text_key, {$text_column} as text_value FROM site_texts");
while ($row = $textsStmt->fetch(PDO::FETCH_ASSOC)) {$siteTexts[$row['text_key']] =$row['text_value'];
}
} catch (Exception $e) {}
$twig->addGlobal('text',$siteTexts);
// --- Φόρτωση Logo Site ---
$site_logo = '';
try {
$logoStmt =$pdo->prepare("SELECT value FROM settings WHERE `key` = 'site_logo'");
$logoStmt->execute();
$site_logo =$logoStmt->fetchColumn();
} catch (Exception $e) {}
$twig->addGlobal('site_logo',$site_logo);
try {
// --- Φόρτωση Κατηγοριών ---
$categoriesRaw =$pdo->query("SELECT * FROM categories ORDER BY sort_order ASC, name_el ASC")->fetchAll(PDO::FETCH_ASSOC);
$categories = [];
foreach ($categoriesRaw as $cat) {$cat['display_name'] = ($current_lang === 'en' && !empty($cat['name_en'])) ? $cat['name_en'] :$cat['name_el'];
$categories[] =$cat;
}
// --- Λήψη Παραμέτρων Φίλτρων & ΣΕΛΙΔΟΠΟΙΗΣΗΣ ---
$category_id = isset($_GET['category_id']) ? (int)$_GET['category_id'] : 0;
$sort = isset($_GET['sort']) ?$_GET['sort'] : 'newest';
$min_price = (isset($_GET['min_price']) && is_numeric($_GET['min_price'])) ? (float)$_GET['min_price'] : null;
$max_price = (isset($_GET['max_price']) && is_numeric($_GET['max_price'])) ? (float)$_GET['max_price'] : null;
$search_query = isset($_GET['q']) ? trim($_GET['q']) : '';
// Παράμετροι Σελιδοποίησης
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 30;
if (!in_array($limit, [30, 50, 100])) { $limit = 30; } // Default & Safety$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if ($page < 1) {$page = 1; }
$current_category_name = null;
$category_attributes = [];
// --- ΔΙΑΣΠΑΣΗ ΤΟΥ SQL QUERY (Για να μετράμε και το σύνολο) ---
$sql_select = "SELECT p.id, p.sku, p.title, p.price, p.created_at, pi.image_path";
$sql_from = " FROM products p LEFT JOIN product_images pi ON (p.id = pi.product_id AND pi.is_primary = 1)";
$sql_where = " WHERE p.status = 'available'";
$params = [];
// 1. Φίλτρο Κατηγορίας
if ($category_id > 0) {
$catStmt =$pdo->prepare("SELECT name_el, name_en, attribute_group_id FROM categories WHERE id = ?");
$catStmt->execute([$category_id]);
$catData =$catStmt->fetch(PDO::FETCH_ASSOC);
if ($catData) {
$current_category_name = ($current_lang === 'en' && !empty($catData['name_en'])) ?$catData['name_en'] : $catData['name_el'];$sql_where .= " AND (p.category_id = ? OR p.category_id IN (SELECT id FROM categories WHERE parent_id = ?))";
$params[] =$category_id;
$params[] =$category_id;
if ($catData['attribute_group_id']) {
$attrStmt =$pdo->prepare("
SELECT a.id, a.name as name_el, a.name_en, a.unit,
(SELECT GROUP_CONCAT(DISTINCT value SEPARATOR '||') FROM product_attribute_values WHERE attribute_id = a.id) as distinct_values
FROM attributes a
WHERE a.group_id = ?
");
$attrStmt->execute([$catData['attribute_group_id']]);
$catAttrsRaw =$attrStmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($catAttrsRaw as $a) {$a['display_name'] = ($current_lang === 'en' && !empty($a['name_en'])) ? $a['name_en'] :$a['name_el'];
$category_attributes[] =$a;
}
}
}
}
// 2. Έξυπνο Φίλτρο Αναζήτησης (Βελτιωμένο)
if ($search_query !== '') {
$clean_query = preg_replace('/[^\p{L}\p{N}\s\-]/u', ' ',$search_query);
$words = preg_split('/\s+/', mb_strtolower($clean_query, 'UTF-8'));
$words = array_filter($words, function($w) { return mb_strlen(trim($w)) > 1; });
if (!empty($words)) {$whereClauses = [];
foreach ($words as $word) {$whereClauses[] = "(LOWER(COALESCE(p.sku, '')) LIKE CONCAT('%', ?, '%') OR LOWER(COALESCE(p.title, '')) LIKE CONCAT('%', ?, '%') OR LOWER(COALESCE(p.description, '')) LIKE CONCAT('%', ?, '%') OR LOWER(COALESCE(p.search_tags, '')) LIKE CONCAT('%', ?, '%'))";
array_push($params, $word,$word, $word,$word);
}
$sql_where .= " AND (" . implode(" AND ", $whereClauses) . ")";
}
}
// 3. Φίλτρο Τιμής
if ($min_price !== null) {$sql_where .= " AND p.price >= ?"; $params[] =$min_price; }
if ($max_price !== null) {$sql_where .= " AND p.price <= ?"; $params[] =$max_price; }
// 4. Φίλτρο Δυναμικών Χαρακτηριστικών
if (isset($_GET['attr']) && is_array($_GET['attr'])) {
foreach ($_GET['attr'] as $attr_id =>$attr_val) {
if (!empty($attr_val)) {$sql_where .= " AND EXISTS (SELECT 1 FROM product_attribute_values pav WHERE pav.product_id = p.id AND pav.attribute_id = ? AND pav.value = ?)";
$params[] = (int)$attr_id;
$params[] =$attr_val;
}
}
}
// --- ΜΕΤΡΗΣΗ ΣΥΝΟΛΙΚΩΝ ΠΡΟΪΟΝΤΩΝ ΓΙΑ ΣΕΛΙΔΟΠΟΙΗΣΗ ---
$countSql = "SELECT COUNT(p.id)" . $sql_from .$sql_where;
$stmtCount = $pdo->prepare($countSql);
$stmtCount->execute($params);
$total_products = (int)$stmtCount->fetchColumn();
$total_pages = ceil($total_products / $limit);
if ($page >$total_pages && $total_pages > 0) {$page = $total_pages; }$offset = ($page - 1) *$limit;
// --- ΤΕΛΙΚΟ QUERY ΠΡΟΪΟΝΤΩΝ ΜΕ ΟΡΙΑ ---
$sql =$sql_select . $sql_from .$sql_where;
// 5. Ταξινόμηση
if ($sort === 'price_asc') {$sql .= " ORDER BY p.price ASC"; }
elseif ($sort === 'price_desc') {$sql .= " ORDER BY p.price DESC"; }
else { $sql .= " ORDER BY p.id DESC"; }
// 6. Προσθήκη Ορίων (Pagination)
$sql .= " LIMIT " . $limit . " OFFSET " . $offset;
// Εκτέλεση
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$products =$stmt->fetchAll(PDO::FETCH_ASSOC);
// --- ΕΝΣΩΜΑΤΩΣΗ ΧΑΡΑΚΤΗΡΙΣΤΙΚΩΝ ΣΤΑ ΠΡΟΪΟΝΤΑ ---
if (!empty($products)) {
$product_ids = array_column($products, 'id');
$inQuery = implode(',', array_fill(0, count($product_ids), '?'));
$attrValsStmt =$pdo->prepare("
SELECT pav.product_id, a.name as name_el, a.name_en, a.unit, pav.value
FROM product_attribute_values pav
JOIN attributes a ON pav.attribute_id = a.id
WHERE pav.product_id IN ($inQuery)
");
$attrValsStmt->execute($product_ids);
$all_attrs =$attrValsStmt->fetchAll(PDO::FETCH_ASSOC);
$attrs_by_pid = [];
foreach ($all_attrs as $attr) {$attr_name = ($current_lang === 'en' && !empty($attr['name_en'])) ? $attr['name_en'] :$attr['name_el'];
$attrs_by_pid[$attr['product_id']][] = [
'name' => $attr_name,
'value' => $attr['value'],
'unit' => $attr['unit']
];
}
foreach ($products as &$prod) {$prod['attributes'] = $attrs_by_pid[$prod['id']] ?? [];
}
unset($prod);
}
// --- ΔΗΜΙΟΥΡΓΙΑ BASE URL ΓΙΑ ΤΑ ΚΟΥΜΠΙΑ ΣΕΛΙΔΟΠΟΙΗΣΗΣ ---
$qs =$_GET;
unset($qs['page']); // Αφαιρούμε το page για να το βάλει δυναμικά το Twig
$base_qs = http_build_query($qs);$pagination_url = 'index.php?' . ($base_qs ? $base_qs . '&' : '') . 'page=';
} catch (Exception $e) {
die("Σφάλμα ανάγνωσης δεδομένων: " . $e->getMessage());
}
echo $twig->render('index.html.twig', [
'site_title' => 'Hockey Gear CMS',
'categories' => $categories,
'products' => $products,
'current_category_name' => $current_category_name,
'category_id' => $category_id,
'category_attributes' => $category_attributes,
'search_query' => $search_query,
'filters' => $_GET,
// Νέες μεταβλητές Σελιδοποίησης
'current_page' => $page,
'total_pages' => $total_pages,
'limit' => $limit,
'total_products' => $total_products,
'pagination_url' => $pagination_url
]);