, headers get sent and header() // would silently fail. A relative Location needs no SITE_URL, so it works here. if (isset($_GET['page']) && (int)($_GET['page']) > 1) { $__p = $_GET; unset($__p['page']); $__qs = http_build_query($__p); header('Location: products.php' . ($__qs !== '' ? '?' . $__qs : ''), true, 302); exit; } // --------------------------------------------------------------------------- require_once __DIR__ . '/config.php'; require_once __DIR__ . '/includes/url_helpers.php'; require_once __DIR__ . '/includes/breadcrumb_helpers.php'; require_once __DIR__ . '/includes/social_proof_helpers.php'; $selected_slug = isset($_GET['category']) ? trim($_GET['category']) : ''; $selected_brand = isset($_GET['brand']) ? trim($_GET['brand']) : ''; $min_price = isset($_GET['min_price']) && $_GET['min_price'] !== '' ? (float)$_GET['min_price'] : null; $max_price = isset($_GET['max_price']) && $_GET['max_price'] !== '' ? (float)$_GET['max_price'] : null; $sort = isset($_GET['sort']) ? $_GET['sort'] : 'newest'; $search_q = isset($_GET['q']) ? trim($_GET['q']) : ''; $page = max(1, (int)($_GET['page'] ?? 1)); $is_mobile_ua = preg_match('/Mobi|Android(?!.*Tablet)|iPhone/i', $_SERVER['HTTP_USER_AGENT'] ?? ''); $per_page = $is_mobile_ua ? 6 : 8; $page_title = $search_q !== '' ? 'Search: ' . htmlspecialchars($search_q) . ' — MobiCare.pk' : ($selected_slug ? ucwords(str_replace('-', ' ', $selected_slug)) . ' — MobiCare.pk' : 'All Products — MobiCare.pk'); $meta_description = 'Browse mobile accessories including power banks, cables, chargers, earbuds and smart watches at MobiCare.pk.'; // Look up the selected category early so we can use its name + custom meta // description (if set) in the page's /<meta> tags before header.php runs. $selected_category_row = null; if ($selected_slug !== '') { $cat_stmt = $conn->prepare("SELECT * FROM categories WHERE slug = ?"); $cat_stmt->bind_param('s', $selected_slug); $cat_stmt->execute(); $selected_category_row = $cat_stmt->get_result()->fetch_assoc(); if ($selected_category_row) { $page_title = $selected_category_row['name'] . ' — MobiCare.pk'; if (!empty($selected_category_row['meta_description'])) { $meta_description = $selected_category_row['meta_description']; } } } // Canonical URL intentionally drops sort/min_price/max_price/brand — those // are refinements of the same listing, not distinct pages, so we don't want // Google treating every filter combination as separate content to index. // Category, search term, and pagination ARE kept, since those represent // genuinely different listings. $canonical_params = []; if ($selected_slug !== '') $canonical_params['category'] = $selected_slug; if ($search_q !== '') $canonical_params['q'] = $search_q; if ($page > 1) $canonical_params['page'] = $page; $canonical_url = SITE_URL . '/products.php' . (!empty($canonical_params) ? '?' . http_build_query($canonical_params) : ''); // Keep search-result pages out of the index (thin, unbounded). Plain category // pages and their pagination stay indexable; sort/brand/price permutations // already collapse to the clean category via the canonical above. $robots_noindex = ($search_q !== ''); require_once __DIR__ . '/includes/header.php'; $cats = $conn->query("SELECT * FROM categories ORDER BY name ASC"); $all_cats = []; while ($row = $cats->fetch_assoc()) $all_cats[] = $row; require_once __DIR__ . '/includes/category_helpers.php'; $cat_tree = get_category_tree($conn); // top-level cats, each with a 'children' array $brands_result = $conn->query("SELECT DISTINCT brand FROM products WHERE brand IS NOT NULL AND brand != '' ORDER BY brand ASC"); $all_brands = []; while ($row = $brands_result->fetch_assoc()) $all_brands[] = $row['brand']; require_once __DIR__ . '/includes/product_query.php'; $pq = mobicare_build_product_query($conn, [ 'selected_slug' => $selected_slug, 'selected_brand' => $selected_brand, 'min_price' => $min_price, 'max_price' => $max_price, 'search_q' => $search_q, 'sort' => $sort, 'page' => $page, 'per_page' => $per_page, ]); $products = $pq['products']; $total_products = $pq['total_products']; $total_pages = $pq['total_pages']; $page = $pq['page']; $offset = $pq['offset']; // Helper to keep current filters when building links function qs($overrides = []) { $current = $_GET; foreach ($overrides as $k => $v) { if ($v === null) unset($current[$k]); else $current[$k] = $v; } return '?' . http_build_query($current); } ?> <div class="wrap">