query("SELECT COUNT(*) FROM books WHERE is_fiction = 1")->fetchColumn(); $non_fiction_count = $pdo->query("SELECT COUNT(*) FROM books WHERE is_fiction = 0")->fetchColumn(); // Build the query with filters $query = 'SELECT DISTINCT b.id, b.name, b.slug, b.is_fiction FROM books b'; $params = []; // Initialize params array // Handle genre filters based on match type if (!empty($genre_filters)) { if ($match_all) { // Match ALL genres (using JOINs) foreach ($genre_filters as $index => $genre) { $join_alias = "bbg{$index}"; $bg_alias = "bg{$index}"; $query .= " JOIN book_book_genre {$join_alias} ON b.id = {$join_alias}.book_id JOIN book_genres {$bg_alias} ON {$join_alias}.book_genre_id = {$bg_alias}.id AND {$bg_alias}.slug = ?"; $params[] = $genre; } } else { // Match ANY genres (using EXISTS) $query .= " JOIN book_book_genre bbg ON b.id = bbg.book_id JOIN book_genres bg ON bbg.book_genre_id = bg.id AND bg.slug IN (" . implode(',', array_fill(0, count($genre_filters), '?')) . ")"; $params = array_merge($params, $genre_filters); } } $query .= ' WHERE 1=1'; // Handle fiction filter based on match type if ($match_all && $fiction_filter !== null) { $query .= ' AND b.is_fiction = ?'; $params[] = $fiction_filter; } elseif (!$match_all && !empty($fiction_filters)) { $query .= ' AND b.is_fiction IN (' . implode(',', array_fill(0, count($fiction_filters), '?')) . ')'; $params = array_merge($params, array_map('intval', $fiction_filters)); } // Handle title filter if (!empty($title_filter)) { $title_words = array_filter(array_map('trim', explode(' ', $title_filter))); if (!empty($title_words)) { $title_conditions = []; foreach ($title_words as $word) { $title_conditions[] = 'LOWER(TRIM(b.name)) LIKE LOWER(?)'; $params[] = '%' . $word . '%'; } $query .= ' AND (' . implode(' OR ', $title_conditions) . ')'; } } // Get total count $count_query = str_replace('SELECT DISTINCT b.id, b.name, b.slug, b.is_fiction', 'SELECT COUNT(DISTINCT b.id)', $query); $stmt = $pdo->prepare($count_query); $stmt->execute($params); $total_books = $stmt->fetchColumn(); $total_pages = ceil($total_books / $items_per_page); // Get books for current page $query .= ' ORDER BY b.name ASC LIMIT ? OFFSET ?'; $params[] = $items_per_page; $params[] = $offset; $stmt = $pdo->prepare($query); $stmt->execute($params); $books = $stmt->fetchAll(PDO::FETCH_ASSOC); $query = "SELECT bg.name, bg.slug, COUNT(DISTINCT bbg.book_id) as book_count FROM book_genres bg LEFT JOIN book_book_genre bbg ON bg.id = bbg.book_genre_id GROUP BY bg.id, bg.name, bg.slug ORDER BY bg.name ASC"; $genres = $pdo->query($query)->fetchAll(PDO::FETCH_ASSOC); // Function to build pagination URL with current filters function buildPaginationUrl($page) { $params = $_GET; $params['page'] = $page; return '?' . http_build_query($params); } // Check if there are active filters $has_active_filters = $match_all || $fiction_filter !== null || !empty($fiction_filters) || !empty($genre_filters) || !empty($title_filter); // Function to get genre names from slugs function getGenreNames($slugs, $genres) { $names = []; foreach ($slugs as $slug) { foreach ($genres as $genre) { if ($genre['slug'] === $slug) { $names[] = $genre['name']; break; } } } return $names; } // Build filter summary text $filter_summary = []; if ($match_all || !$match_all) { $filter_summary[] = 'Match ' . ($match_all ? 'ALL' : 'ANY') . ' criteria'; } if ($match_all && $fiction_filter !== null) { $filter_summary[] = $fiction_filter ? 'Fiction' : 'Non-Fiction'; } elseif (!$match_all && !empty($fiction_filters)) { $fiction_labels = []; foreach ($fiction_filters as $f) { $fiction_labels[] = $f === '1' ? 'Fiction' : 'Non-Fiction'; } $filter_summary = array_merge($filter_summary, $fiction_labels); } if (!empty($genre_filters)) { $genre_names = getGenreNames($genre_filters, $genres); $filter_summary = array_merge($filter_summary, $genre_names); } if (!empty($title_filter)) { $filter_summary[] = 'Title contains "' . $title_filter . '"'; } ?> Books - AspireBookClub.com<? echo $current_page > 1 ? " - Page $current_page" : ""; ?> ">

📚 Books

Filter