diff --git a/server/web_app/src/Controller/ItemController.php b/server/web_app/src/Controller/ItemController.php index b200cec963f26c3c2e7fa1497cbc3df12cc02e57..cb5feb7846493d72ad8bf392d59afa06058a2cdd 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 48e7dca15a9807de8561f9318696c0391cb429ae..abc603f086d833a347fe554b0dad500a7eba1db0 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(); + } + }