diff --git a/app/src/Controller/AbstractController.php b/app/src/Controller/AbstractController.php index 82b59691c8d531a91f7736c1273bd99c4765b34d..61d805ea1960894b9d0722a69a3e33f14e642508 100644 --- a/app/src/Controller/AbstractController.php +++ b/app/src/Controller/AbstractController.php @@ -18,21 +18,21 @@ abstract class AbstractController extends BundleController protected function build(AbstractRequest $request): JsonResponse { - try { +// try { return new JsonResponse($this->service->serve($request)); - - } catch (AbstractError $error) { - $errorDto = new ErrorDto(); - - $errorDto->message = $error->message; - $errorDto->code = $error->code; - $errorDto->status = $error->status; - - return new JsonResponse($errorDto, $error->status); - - } catch (Throwable $exception) { - $error = new ErrorDto(); - return new JsonResponse($error, $error->status); - } +// +// } catch (AbstractError $error) { +// $errorDto = new ErrorDto(); +// +// $errorDto->message = $error->message; +// $errorDto->code = $error->code; +// $errorDto->status = $error->status; +// +// return new JsonResponse($errorDto, $error->status); +// +// } catch (Throwable $exception) { +// $error = new ErrorDto(); +// return new JsonResponse($error, $error->status); +// } } } diff --git a/app/src/Controller/NewsController.php b/app/src/Controller/NewsController.php new file mode 100644 index 0000000000000000000000000000000000000000..b321457b90f30ea0a5f7792826641ef4c90d5816 --- /dev/null +++ b/app/src/Controller/NewsController.php @@ -0,0 +1,23 @@ +build($request); + } +} diff --git a/app/src/Controller/NewsDetailController.php b/app/src/Controller/NewsDetailController.php new file mode 100644 index 0000000000000000000000000000000000000000..e236d8c5c9eea447f27f3359cf7cf89f8932f46a --- /dev/null +++ b/app/src/Controller/NewsDetailController.php @@ -0,0 +1,23 @@ +build($request); + } +} diff --git a/app/src/Controller/NewsMainNewsController.php b/app/src/Controller/NewsMainNewsController.php new file mode 100644 index 0000000000000000000000000000000000000000..2595dfe61ae59275ebf95995248ab795473319cd --- /dev/null +++ b/app/src/Controller/NewsMainNewsController.php @@ -0,0 +1,23 @@ +build($request); + } +} \ No newline at end of file diff --git a/app/src/Controller/NewsSearchController.php b/app/src/Controller/NewsSearchController.php new file mode 100644 index 0000000000000000000000000000000000000000..a6b0fa694884b81ddd9fb6bd15923b90d8d16205 --- /dev/null +++ b/app/src/Controller/NewsSearchController.php @@ -0,0 +1,23 @@ +build($request); + } +} \ No newline at end of file diff --git a/app/src/Controller/RestaurantDetailController.php b/app/src/Controller/RestaurantDetailController.php index b297bac95136fa1c4e6b62ab451a77f2e15f395a..8b547ae44d707bed3e0470c28acac73256bd6fd5 100644 --- a/app/src/Controller/RestaurantDetailController.php +++ b/app/src/Controller/RestaurantDetailController.php @@ -2,7 +2,7 @@ namespace App\Controller; -use App\Request\RestaurantDetailRequest; +use App\Request\DetailRequest; use App\Service\RestaurantDetailService; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Attribute\Route; @@ -15,10 +15,9 @@ class RestaurantDetailController extends AbstractController parent::__construct($service); } - /** Листинг ресторанов */ - #[Route('{restaurantId}', name: 'restaurant')] - public function index(RestaurantDetailRequest $request): JsonResponse + #[Route('{detailId}', name: 'restaurant')] + public function index(DetailRequest $request): JsonResponse { return $this->build($request); } -} \ No newline at end of file +} diff --git a/app/src/Controller/RestaurantsController.php b/app/src/Controller/RestaurantsController.php index 5840dbfbdf7c408584aa26c15e4c77764c24bfa5..3be18903a8de2a4958a5b5638b3edb0b747d2cd0 100644 --- a/app/src/Controller/RestaurantsController.php +++ b/app/src/Controller/RestaurantsController.php @@ -5,7 +5,6 @@ namespace App\Controller; use App\Request\RestaurantListingRequest; use App\Service\RestaurantListingService; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpKernel\Attribute\MapQueryParameter; use Symfony\Component\Routing\Attribute\Route; #[Route('/api/v1/restaurants/')] diff --git a/app/src/Dto/NewsFilterVariants.php b/app/src/Dto/NewsFilterVariants.php index b1d55e4d30c991f4d6cc3bcb27d2d6888419e2da..2a48144f78b5dc199a53dc7d50daacb0a1116463 100644 --- a/app/src/Dto/NewsFilterVariants.php +++ b/app/src/Dto/NewsFilterVariants.php @@ -4,6 +4,12 @@ namespace App\Dto; class NewsFilterVariants implements DtoInterface { - /** @var DtoCollection */ - public DtoCollection $category; + + /** + * @param DtoCollection $category + */ + public function __construct( + /** @var DtoCollection */ + public DtoCollection $category, + ) {} } diff --git a/app/src/Dto/NewsListDto.php b/app/src/Dto/NewsListDto.php index 93928bfbdb381f1d12518b947e3ea74c5bcc9927..ae4971e5a8cfe14b1e7e256f32f8855a60f22817 100644 --- a/app/src/Dto/NewsListDto.php +++ b/app/src/Dto/NewsListDto.php @@ -4,10 +4,17 @@ namespace App\Dto; class NewsListDto implements DtoInterface { - public PaginationDto $pagination; + /** + * @param PaginationDto $pagination + * @param DtoCollection $list + * @param NewsFilterVariants $filterVariants + */ + public function __construct( + public PaginationDto $pagination, - /** @var DtoCollection */ - public DtoCollection $list; + /** @var DtoCollection */ + public DtoCollection $list, - public NewsFilterVariants $filterVariants; + public NewsFilterVariants $filterVariants, + ) {} } diff --git a/app/src/Entity/News.php b/app/src/Entity/News.php index e84bdc8d42315e52952a2b6d8d4e99e0ce7fd4ae..53a159545f63170072c36039d4568907902d97e5 100644 --- a/app/src/Entity/News.php +++ b/app/src/Entity/News.php @@ -255,7 +255,7 @@ class News implements PrototypeElementDto $entity->name = $this->getName(); $entity->description = $this->getDetailText(); $entity->image = $this->getPreviewImage()?->getDto(); - $entity->create_at = $this->getCreatedAt(); + $entity->create_at = $this->getCreatedAt()->format('Y-m-d H:i:s'); $entity->detail_link = "api/v1/restaurants/" . $this->getId(); return $entity; @@ -271,7 +271,7 @@ class News implements PrototypeElementDto $entity->description = $this->getPreviewText(); $entity->text = $this->getDetailText(); $entity->image = $this->getPreviewImage()?->getDto(); - $entity->create_at = $this->getCreatedAt(); + $entity->create_at = $this->getCreatedAt()->format('Y-m-d H:i:s'); return $entity; } diff --git a/app/src/Repository/NewsCategoriesRepository.php b/app/src/Repository/NewsCategoriesRepository.php index 215cbe31b3d944f06031360fc9f739a2ba299b6d..fb739005a6f84fcb2de6e8870e243f4ea2422a11 100644 --- a/app/src/Repository/NewsCategoriesRepository.php +++ b/app/src/Repository/NewsCategoriesRepository.php @@ -15,7 +15,7 @@ use Ramsey\Collection\Collection; * @method NewsCategories[] findAll() * @method NewsCategories[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class NewsCategoriesRepository extends ServiceEntityRepository +class NewsCategoriesRepository extends ServiceEntityRepository implements NewsCategoriesRepositoryInterface { public function __construct(ManagerRegistry $registry) { diff --git a/app/src/Repository/NewsCategoriesRepositoryInterface.php b/app/src/Repository/NewsCategoriesRepositoryInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..a3c7cfeed900c157be01495116dcdbbf41e82f6f --- /dev/null +++ b/app/src/Repository/NewsCategoriesRepositoryInterface.php @@ -0,0 +1,12 @@ + */ + public function getAll(): Collection; +} diff --git a/app/src/Repository/NewsRepository.php b/app/src/Repository/NewsRepository.php index b5031deddcfce301221041d3a8e11aa9be1f3f67..44e4ef45c26ddc4db4e850d4eefe294dad631240 100644 --- a/app/src/Repository/NewsRepository.php +++ b/app/src/Repository/NewsRepository.php @@ -18,36 +18,20 @@ use Ramsey\Collection\Collection; * @method News[] findAll() * @method News[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class NewsRepository extends ServiceEntityRepository +class NewsRepository extends ServiceEntityRepository implements NewsRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, News::class); } - /** - * @param QueryBuilder $query - * @return Collection - */ - protected function toCollection(QueryBuilder $query): Collection - { - return new Collection( - News::class, - $query - ->orderBy('n.sort', 'ASC') - ->getQuery() - ->getResult() - ); - } - - protected function getByFilters(?string $categoryId, QueryBuilder $query): QueryBuilder + public function getMainNews(): News { - if ($categoryId !== null) { - $query = $query - ->innerJoin('n.categories', 'c', Join::WITH, 'c.id = :typeId') - ->setParameter('typeId', $categoryId); - } - return $query; + return $this->createQueryBuilder('n') + ->andWhere('n.mainPageRender = true') + ->setMaxResults(1) + ->getQuery() + ->getResult()[0]; } public function getCountWithFilters(?string $categoryId): int @@ -58,11 +42,12 @@ class NewsRepository extends ServiceEntityRepository } /** @return Collection */ - public function findByFilters(?string $categoryId, int $limit): Collection + public function findByFilters(?string $categoryId, int $limit, int $offset): Collection { $query = $this->createQueryBuilder('n'); $query = $this->getByFilters($categoryId, $query); $query = $query->setMaxResults($limit); + $query = $query->setFirstResult($offset); return $this->toCollection($query); } @@ -80,4 +65,29 @@ class NewsRepository extends ServiceEntityRepository ->getQuery() ->getResult()[0]; } + + /** + * @param QueryBuilder $query + * @return Collection + */ + protected function toCollection(QueryBuilder $query): Collection + { + return new Collection( + News::class, + $query + ->orderBy('n.sort', 'ASC') + ->getQuery() + ->getResult() + ); + } + + protected function getByFilters(?string $categoryId, QueryBuilder $query): QueryBuilder + { + if ($categoryId !== null) { + $query = $query + ->innerJoin('n.categories', 'c', Join::WITH, 'c.id = :typeId') + ->setParameter('typeId', $categoryId); + } + return $query; + } } diff --git a/app/src/Repository/NewsRepositoryInterface.php b/app/src/Repository/NewsRepositoryInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..b67c875995d2f944e8226a7c11d4836c6a1698b7 --- /dev/null +++ b/app/src/Repository/NewsRepositoryInterface.php @@ -0,0 +1,20 @@ + + * + * @method News|null find($id, $lockMode = null, $lockVersion = null) + */ +interface NewsRepositoryInterface +{ + public function getMainNews(): News; + public function getCountWithFilters(?string $categoryId): int; + + /** @return Collection */ + public function findByFilters(?string $categoryId, int $limit, int $offset): Collection; +} diff --git a/app/src/Request/RestaurantDetailRequest.php b/app/src/Request/DetailRequest.php similarity index 57% rename from app/src/Request/RestaurantDetailRequest.php rename to app/src/Request/DetailRequest.php index 05b07e0d73910521d27326e4498c64f713e3fa62..ac690b84ac5e7de0a82b752c265adf1a4d0351c6 100644 --- a/app/src/Request/RestaurantDetailRequest.php +++ b/app/src/Request/DetailRequest.php @@ -5,21 +5,21 @@ namespace App\Request; use Symfony\Component\Validator\Constraints\Uuid; use Symfony\Contracts\Service\Attribute\Required; -class RestaurantDetailRequest extends AbstractRequest +class DetailRequest extends AbstractRequest { #[Required] #[Uuid] - public $restaurantId; + public $detailId; protected function populate(): void { $requestUrl = $this->getRequest()->getUri(); $index = strrpos($requestUrl, "/") + 1; - $restaurantId = substr($requestUrl, $index); + $detailId = substr($requestUrl, $index); - if (property_exists($this, "restaurantId")) { - $this->{"restaurantId"} = $restaurantId; + if (property_exists($this, "detailId")) { + $this->{"detailId"} = $detailId; } } } diff --git a/app/src/Request/EmptyRequest.php b/app/src/Request/EmptyRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..9ea7ad0f93d3ae3a14764b4cb228db3c5a5625ab --- /dev/null +++ b/app/src/Request/EmptyRequest.php @@ -0,0 +1,8 @@ +getRequest(); + foreach ($request->query->getIterator() as $property => $value) { + if (property_exists($this, $property)) { + $this->{$property} = $value; + } + } + } +} \ No newline at end of file diff --git a/app/src/Service/NewsDetailService.php b/app/src/Service/NewsDetailService.php new file mode 100644 index 0000000000000000000000000000000000000000..19c394d041318209f924c90169a6c302ac29f139 --- /dev/null +++ b/app/src/Service/NewsDetailService.php @@ -0,0 +1,26 @@ +news->find($request->detailId); + + if ($news === null) { + throw new NotFoundError('News'); + } + + return $news->getExtendedDto(); + } +} diff --git a/app/src/Service/NewsListingService.php b/app/src/Service/NewsListingService.php new file mode 100644 index 0000000000000000000000000000000000000000..6d7563611255ccdf4469f060366bdec812414774 --- /dev/null +++ b/app/src/Service/NewsListingService.php @@ -0,0 +1,71 @@ +news-> + getCountWithFilters($request->news_category); + + $pagination = new PaginationDto( + $request->page, + $request->limit, + $countOfRestaurants + ); + + $offset = min($pagination->page_size, $countOfRestaurants) * ($pagination->current_page - 1); + + $list = new DtoCollection( + NewsListingElementDto::class, + $this + ->news + ->findByFilters( + $request->news_category, + $request->limit, $offset + ) + ->map(function(News $news) { + return $news->getDto(); + }) + ->toArray() + ); + + $filters = new NewsFilterVariants( + new DtoCollection( + NewsCategoryDto::class, + $this->newsCategories->getAll() + ->map(function(NewsCategories $category) { + return $category->getDto(); + }) + ->toArray() + ), + ); + + return new NewsListDto( + $pagination, + $list, + $filters + ); + } +} diff --git a/app/src/Service/NewsMainNewsService.php b/app/src/Service/NewsMainNewsService.php new file mode 100644 index 0000000000000000000000000000000000000000..16037d31e53162558101a58a84dbcad48288f717 --- /dev/null +++ b/app/src/Service/NewsMainNewsService.php @@ -0,0 +1,19 @@ +news->getMainNews()->getDto(); + } +} diff --git a/app/src/Service/NewsSearchService.php b/app/src/Service/NewsSearchService.php new file mode 100644 index 0000000000000000000000000000000000000000..ff9713e918b4c13ff1bd58c309aa8649e3a01d58 --- /dev/null +++ b/app/src/Service/NewsSearchService.php @@ -0,0 +1,18 @@ +news->getMainNews()->getExtendedDto(); + } +} diff --git a/app/src/Service/RestaurantDetailService.php b/app/src/Service/RestaurantDetailService.php index 5cc7111c30d665e688de6ddd409db969734aa795..2547cfaa5085205c28c3bc836f5c913715e335f7 100644 --- a/app/src/Service/RestaurantDetailService.php +++ b/app/src/Service/RestaurantDetailService.php @@ -19,7 +19,7 @@ class RestaurantDetailService implements ServiceInterface */ public function serve(AbstractRequest $request): DtoInterface { - $restaurant = $this->restaurants->find($request->restaurantId); + $restaurant = $this->restaurants->find($request->detailId); if ($restaurant === null) { throw new NotFoundError('Restaurant');