Skip to content

Commit

Permalink
fix bug in pagination behavior, refactor
Browse files Browse the repository at this point in the history
bug fixed: on page X, products from previous pages should not be displayed
  • Loading branch information
creme332 committed May 18, 2024
1 parent 7b14f95 commit 35e8113
Showing 1 changed file with 47 additions and 18 deletions.
65 changes: 47 additions & 18 deletions src/controllers/Shop.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Shop
use Controller;

private array $data;
private static int $MAX_PRODUCTS_PER_PAGE = 4;

/**
* Check if a product matches the category filter (if any)
Expand Down Expand Up @@ -71,7 +72,7 @@ private function sort_product(Product $a, Product $b): int
return 0;
}

// sort by date
// sort by descending date
if ($_GET['sort'] === 'newest') {
return ($a->getCreatedDate() > $b->getCreatedDate()) ? -1 : 1;
}
Expand Down Expand Up @@ -99,6 +100,46 @@ private function sort_product(Product $a, Product $b): int
return 0; // no sorting if invalid sorting option
}

/**
* @return Product[] Array of products which match filters (excluding pagination) and sorting applied by user
*/
public function getMatchingProducts(): array
{
// Fetch all products from the database
$all_products = Product::getAll();

// Apply filtering based on search keyword and category (existing functionality)
$filtered_products = array_filter($all_products, array($this, "match_keyword"));
$filtered_products = array_filter($filtered_products, array($this, "match_category"));

// Sort the filtered products (existing functionality)
usort($filtered_products, array($this, "sort_product"));

return $filtered_products;
}

/**
* @return int Page number on shop page. Defaults to 1.
*/
public function getPageNumber(): int
{
return (int)($_GET['page'] ?? 1);
}

/**
* @param $products
* @return array Products which should be displayed on current page
*/
public function applyPagination($products): array
{
// Slice the products based on pagination
return array_slice(
$products,
($this->getPageNumber() - 1) * Shop::$MAX_PRODUCTS_PER_PAGE,
Shop::$MAX_PRODUCTS_PER_PAGE
);
}

public function index(): void
{
// check if URL follows format /shop/products/<number>
Expand All @@ -115,32 +156,20 @@ public function index(): void
return;
}

// Retrieve the page number from the URL query parameters
$page = $_GET['page'] ?? 1;
$perPage = (int) $page * 4; // Number of products per page

// Fetch all products from the database
$all_products = Product::getAll();

$this->data['all_products'] = $all_products;

// Apply filtering based on search keyword and category (existing functionality)
$filtered_products = array_filter($all_products, array($this, "match_keyword"));
$filtered_products = array_filter($filtered_products, array($this, "match_category"));

// Sort the filtered products (existing functionality)
usort($filtered_products, array($this, "sort_product"));
// get all products that match user criteria
$filtered_products = $this->getMatchingProducts();

// Slice the products based on pagination
$paginated_products = array_slice($filtered_products, 0, $perPage);
$paginated_products = $this->applyPagination($filtered_products);

// Initialize view variables (existing functionality)
$this->data['products'] = $paginated_products;
$this->data['search_keyword'] = $_GET['keyword'] ?? "";
$this->data['categories'] = Product::getCategories();
$this->data['sort_option'] = $_GET['sort'] ?? "";
$this->data['selected_categories'] = $_GET['categories'] ?? [];
$this->data['page'] = $page;
$this->data['page'] = $this->getPageNumber();
$this->data['totalPages'] = ceil(count($filtered_products) / Shop::$MAX_PRODUCTS_PER_PAGE);

// Render the view with pagination information
$this->view(
Expand Down

0 comments on commit 35e8113

Please sign in to comment.