From 38e99e786d952fda148baff3af45d7a1af7b70e3 Mon Sep 17 00:00:00 2001 From: Julian PEREZ-RAMIREZ <julian.perez-ramirez@imt-atlantique.net> Date: Sat, 15 Mar 2025 15:09:51 +0100 Subject: [PATCH] adding filter and pagination to get items endpoint --- .../web_app/src/Controller/ItemController.php | 57 ++++++++++++++----- .../web_app/src/Repository/ItemRepository.php | 27 +++++++++ 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/server/web_app/src/Controller/ItemController.php b/server/web_app/src/Controller/ItemController.php index b200cec..cb5feb7 100644 --- a/server/web_app/src/Controller/ItemController.php +++ b/server/web_app/src/Controller/ItemController.php @@ -33,30 +33,61 @@ final class ItemController extends AbstractController } #[Route('', methods: ['GET'])] - public function getAllItems(): JsonResponse + public function getAllItems(Request $req): JsonResponse { - $items = $this->itemRepository->findAllItems(); + // Validate "onlyBought" as boolean (default: false) + $onlyBought = filter_var($req->query->get('onlyBought', false), + FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false; + + // Validate "sortBy" to allow only 'createdAt' or 'price' + $allowedSortBy = ['createdAt', 'price']; + $sortBy = $req->query->get('sortBy', 'createdAt'); + if (!in_array($sortBy, $allowedSortBy, true)) { + $sortBy = 'price'; + } + + // Validate "sort" to allow only 'asc' or 'desc' + $allowedSort = ['asc', 'desc']; + $sort = strtolower($req->query->get('sort', 'asc')); + if (!in_array($sort, $allowedSort, true)) { + $sort = 'desc'; + } + + // Validate "max" as a positive integer (default: 10) + $max = filter_var($req->query->get('max', 10), FILTER_VALIDATE_INT, + ["options" => ["min_range" => 1]]) ?: 10; + + // Validate "page" as a positive integer (default: 1) + $page = filter_var($req->query->get('page', 1), FILTER_VALIDATE_INT, + ["options" => ["min_range" => 1]]) ?: 1; + + // Fetch items from repository with filters + $items = $this->itemRepository->findAllItemsFiltered($onlyBought, $sortBy, + $sort, $max, $page); if (!$items) { - return new JsonResponse(['error' => 'Item not found'], Response::HTTP_NOT_FOUND); + return new JsonResponse(['error' => 'No items found'], Response::HTTP_NOT_FOUND); } - $itemArray = array_map(fn($item) => - [ + $itemArray = array_map(fn($item) => [ 'id' => $item->getId(), 'wishList' => $item->getWishList(), 'title' => $item->getTitle(), - 'description' =>$item->getDescription(), - 'price' =>$item->getPrice(), - 'purchaseUrl' =>$item->getPurchaseUrl(), - 'createdAt' => $item->getCreatedAt() - ] - , $items); - + 'description' => $item->getDescription(), + 'price' => $item->getPrice(), + 'purchaseUrl' => $item->getPurchaseUrl(), + 'createdAt' => $item->getCreatedAt() + ], $items); + return $this->json([ 'items' => $itemArray, - 'path' => 'src/Controller/ItemController.php', + 'page' => $page, + 'max' => $max, + 'sortBy' => $sortBy, + 'sort' => $sort, + 'onlyBought' => $onlyBought ]); + } #[Route('/{itemId}', methods: ['GET'])] diff --git a/server/web_app/src/Repository/ItemRepository.php b/server/web_app/src/Repository/ItemRepository.php index 48e7dca..abc603f 100644 --- a/server/web_app/src/Repository/ItemRepository.php +++ b/server/web_app/src/Repository/ItemRepository.php @@ -25,4 +25,31 @@ class ItemRepository extends ServiceEntityRepository { return $this->findOneBy(['id' => $id]); } + + // Custom method to manage pagination and filters. + public function findAllItemsFiltered(bool $onlyBought, string $sortBy, string $sort, int $max, int $page) + { + $queryBuilder = $this->createQueryBuilder('i'); + + if ($onlyBought) { + $queryBuilder->innerJoin('App\Entity\Purchase', 'p', 'WITH', 'p.item = i.id'); + } + + // This ensures sortBy is either 'createdAt' or 'price' + if (!in_array($sortBy, ['createdAt', 'price'])) { + $sortBy = 'price'; // Default to sorting by price + } + + // Ensure sort order is either 'asc' or 'desc' + if (!in_array(strtolower($sort), ['asc', 'desc'])) { + $sort = 'desc'; // Default to sorting by desc + } + + $queryBuilder->orderBy("i.$sortBy", $sort) + ->setMaxResults($max) + ->setFirstResult(($page - 1) * $max); + + return $queryBuilder->getQuery()->getResult(); + } + } -- GitLab