diff --git a/app/composer.json b/app/composer.json index 564d77eb4e396930f5f79afd26e5d1388479ff03..be399e99a066e779e3015ba3f581ad72061505b3 100644 --- a/app/composer.json +++ b/app/composer.json @@ -4,7 +4,7 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", "doctrine/dbal": "^3", diff --git a/app/config/packages/doctrine.yaml b/app/config/packages/doctrine.yaml index bf5aa40f261c4b9a45213683c22be84f11c81bc5..b67e855acedb857cef8a56c4aba956f5a175b6ca 100644 --- a/app/config/packages/doctrine.yaml +++ b/app/config/packages/doctrine.yaml @@ -21,8 +21,8 @@ doctrine: App: type: attribute is_bundle: false - dir: '%kernel.project_dir%/src/Entity' - prefix: 'App\Entity' + dir: '%kernel.project_dir%/src/Shared/Entity' + prefix: 'App\Shared\Entity' alias: App controller_resolver: auto_mapping: true diff --git a/app/config/routes.yaml b/app/config/routes.yaml index 41ef8140ba811c0da46ce1962ffa50d4c56b9840..0370c9f31ee96143a1f488bc5300b7b92a18d416 100644 --- a/app/config/routes.yaml +++ b/app/config/routes.yaml @@ -1,5 +1,11 @@ -controllers: +newsControllers: resource: - path: ../src/Controller/ - namespace: App\Controller + path: ../src/News/Controller/ + namespace: App\News\Controller + type: attribute + +restaurantsControllers: + resource: + path: ../src/Restaurants/Controller/ + namespace: App\Restaurants\Controller type: attribute diff --git a/app/config/services.yaml b/app/config/services.yaml index 2d6a76f94dce138741e2d63ae83a11c1879031d9..55758d431a22ae024c875b53613d61be699b1b8f 100644 --- a/app/config/services.yaml +++ b/app/config/services.yaml @@ -11,14 +11,14 @@ services: autowire: true # Automatically injects dependencies in your services. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/' - exclude: - - '../src/DependencyInjection/' - - '../src/Entity/' - - '../src/Kernel.php' - # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones + + App\Restaurants\: + resource: '../src/Restaurants/' + + App\News\: + resource: '../src/News/' + + App\Shared\: + resource: '../src/Shared/' \ No newline at end of file diff --git a/app/src/Controller/Handle.php b/app/src/Controller/Handle.php deleted file mode 100644 index 97f67159dc07bd8e20843a9d658df0f5dfd491fa..0000000000000000000000000000000000000000 --- a/app/src/Controller/Handle.php +++ /dev/null @@ -1,32 +0,0 @@ -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); -// } - } -} diff --git a/app/src/Dto/DtoInterface.php b/app/src/Dto/DtoInterface.php deleted file mode 100644 index fc7960897c180d4c35d3a1eef1731a8d87bc38e2..0000000000000000000000000000000000000000 --- a/app/src/Dto/DtoInterface.php +++ /dev/null @@ -1,6 +0,0 @@ - $list - * @param NewsFilterVariants $filterVariants - */ - public function __construct( - public PaginationDto $pagination, - - /** @var DtoCollection */ - public DtoCollection $list, - - public NewsFilterVariants $filterVariants, - ) {} -} diff --git a/app/src/Dto/NewsListingElementDto.php b/app/src/Dto/NewsListingElementDto.php deleted file mode 100644 index ef41fea34be91b9e4a903b794865e1225e86c46a..0000000000000000000000000000000000000000 --- a/app/src/Dto/NewsListingElementDto.php +++ /dev/null @@ -1,19 +0,0 @@ -page_size = $limit > 0 ? $limit : 12; - - $this->pages = ceil($total / $this->page_size); - - if (($page > 1) && ($page <= $this->pages)) { - $this->current_page = $page; - } - } -} diff --git a/app/src/Dto/RestaurantDetailElementDto.php b/app/src/Dto/RestaurantDetailElementDto.php deleted file mode 100644 index 13f29c946273c32ab0162eb4c2e14b697336b4d6..0000000000000000000000000000000000000000 --- a/app/src/Dto/RestaurantDetailElementDto.php +++ /dev/null @@ -1,45 +0,0 @@ -|null */ - public ?DtoCollection $kitchen; - - /** @var DtoCollection|null */ - public ?DtoCollection $phone; - - /** @var DtoCollection|null */ - public ?DtoCollection $email; - - /** @var DtoCollection|null */ - public ?DtoCollection $address; - - /** @var DtoCollection|null */ - public ?DtoCollection $tags; - - public ?string $site; - - /** @var FileDto|null Превью фото */ - public ?FileDto $image; - - /** @var DtoCollection|null */ - public ?DtoCollection $gallery; -} diff --git a/app/src/Dto/RestaurantListingElementDto.php b/app/src/Dto/RestaurantListingElementDto.php deleted file mode 100644 index 3b575daa4894394e0ee37ff4f3d1cf345ab944d9..0000000000000000000000000000000000000000 --- a/app/src/Dto/RestaurantListingElementDto.php +++ /dev/null @@ -1,20 +0,0 @@ -message = $violation->getPropertyPath() . ':' . $violation->getMessage(); - $this->code = $violation->getCode(); - } -} diff --git a/app/src/Entity/PrototypeDto.php b/app/src/Entity/PrototypeDto.php deleted file mode 100644 index 19c882216798008c141336bfa2947b8544673c13..0000000000000000000000000000000000000000 --- a/app/src/Entity/PrototypeDto.php +++ /dev/null @@ -1,11 +0,0 @@ -message = $message . ' ' . $this->message; - parent::__construct($this->message); - } -} diff --git a/app/src/Controller/NewsController.php b/app/src/News/Controller/NewsController.php similarity index 54% rename from app/src/Controller/NewsController.php rename to app/src/News/Controller/NewsController.php index 90c6a8c39c9882befd67384f67b7c4863dccc3b5..286ff0755afa0dbd00e5ec69fcc0cd36c2d7913a 100644 --- a/app/src/Controller/NewsController.php +++ b/app/src/News/Controller/NewsController.php @@ -1,49 +1,54 @@ listingService))->handle($request); + return $this->handle($this->listingService, $request); } #[Route('/mainNews', name: 'mainNews', methods: ['GET'])] public function mainNews(EmptyRequest $request): JsonResponse { - return (new Handle($this->mainNewsService))->handle($request); + return $this->handle($this->mainNewsService, $request); } #[Route('/search', name: 'searchNews', methods: ['GET'])] public function search(EmptyRequest $request): JsonResponse { - return (new Handle($this->searchService))->handle($request); + return $this->handle($this->searchService, $request); } #[Route('/{detailId}', name: 'oneNews', methods: ['GET'])] public function oneNews(DetailRequest $request): JsonResponse { - return (new Handle($this->detailService))->handle($request); + return $this->handle($this->detailService, $request); } } diff --git a/app/src/News/Dto/NewsCategoryDto.php b/app/src/News/Dto/NewsCategoryDto.php new file mode 100644 index 0000000000000000000000000000000000000000..21917d90994a712b27008233f74cdffcce7acd2e --- /dev/null +++ b/app/src/News/Dto/NewsCategoryDto.php @@ -0,0 +1,16 @@ + $category */ public function __construct( - /** @var DtoCollection */ public DtoCollection $category, ) {} } diff --git a/app/src/News/Dto/NewsListDto.php b/app/src/News/Dto/NewsListDto.php new file mode 100644 index 0000000000000000000000000000000000000000..d4ffffde8f39ba67c24bfacd9eb753fdc83402c7 --- /dev/null +++ b/app/src/News/Dto/NewsListDto.php @@ -0,0 +1,23 @@ + $list + * @param NewsFilterVariantsDto $filterVariants + */ + public function __construct( + public PaginationDto $pagination, + + public DtoCollection $list, + + public NewsFilterVariantsDto $filterVariants, + ) {} +} diff --git a/app/src/News/Dto/NewsListingElementDto.php b/app/src/News/Dto/NewsListingElementDto.php new file mode 100644 index 0000000000000000000000000000000000000000..dd6c6100ea41714c593ccc44b8ed041bb9580bb1 --- /dev/null +++ b/app/src/News/Dto/NewsListingElementDto.php @@ -0,0 +1,31 @@ +getId(), + name: $category->getName(), + code: $category->getCode(), + ); + } + + /** + * @param Collection $categories + * @return DtoCollection + */ + public function createCollection(Collection $categories): DtoCollection + { + $categoriesDto = $categories->map(function(NewsCategories $category) { + return $this->create($category); + }); + + return new DtoCollection( + NewsCategoryDto::class, + $categoriesDto->toArray() + ); + } +} diff --git a/app/src/News/DtoFactory/NewsDetailElementDtoFactory.php b/app/src/News/DtoFactory/NewsDetailElementDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..c4a82b04ca3db1031d73abfc88a253e60b883ff8 --- /dev/null +++ b/app/src/News/DtoFactory/NewsDetailElementDtoFactory.php @@ -0,0 +1,28 @@ +getId(), + name: $news->getName(), + description: $news->getPreviewText(), + createAt: $news->getCreatedAt()->format('Y-m-d H:i:s'), + text: $news->getDetailText(), + image: $news->getPreviewImage() !== null + ? $this->fileFactory->create($news->getPreviewImage()) + : null, + ); + } +} diff --git a/app/src/News/DtoFactory/NewsFilterVariantsDtoFactory.php b/app/src/News/DtoFactory/NewsFilterVariantsDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..80f54fe535b0ff8064ba801d36b2e547ea6b722a --- /dev/null +++ b/app/src/News/DtoFactory/NewsFilterVariantsDtoFactory.php @@ -0,0 +1,21 @@ + $categories + * @return NewsFilterVariantsDto + */ + public function create(DtoCollection $categories): NewsFilterVariantsDto + { + return new NewsFilterVariantsDto( + $categories + ); + } +} diff --git a/app/src/News/DtoFactory/NewsListDtoFactory.php b/app/src/News/DtoFactory/NewsListDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..40f714f41f092b48a42f9f78750b509300820ebe --- /dev/null +++ b/app/src/News/DtoFactory/NewsListDtoFactory.php @@ -0,0 +1,24 @@ +getId(), + name: $news->getName(), + createAt: $news->getCreatedAt()->format('Y-m-d H:i:s'), + detailLink: "api/v1/news/" . $news->getId(), + description: $news->getPreviewText(), + image: $news->getPreviewImage() !== null + ? $this->fileFactory->create($news->getPreviewImage()) + :null, + ); + } + + /** + * @param Collection $news + * @return DtoCollection + */ + public function createCollection(Collection $news): DtoCollection + { + return new DtoCollection( + NewsListingElementDto::class, + $news->map(function(News $oneNews) { + return $this->create($oneNews); + }) + ->toArray() + ); + } +} diff --git a/app/src/Request/NewsListingRequest.php b/app/src/News/Request/NewsListingRequest.php similarity index 89% rename from app/src/Request/NewsListingRequest.php rename to app/src/News/Request/NewsListingRequest.php index fd570e4c86946b5b1eca00ef13926774e814095d..31d99f6f58e9de98d2499910cac1243077423d75 100644 --- a/app/src/Request/NewsListingRequest.php +++ b/app/src/News/Request/NewsListingRequest.php @@ -1,10 +1,11 @@ news->find($request->detailId); + + return $news !== null + ? $this->dtoFactory->create($news) + : throw new NotFoundError('News not found'); + } +} diff --git a/app/src/News/Service/NewsListingService.php b/app/src/News/Service/NewsListingService.php new file mode 100644 index 0000000000000000000000000000000000000000..fd32d9fa0ff26c54fc453da54e3ad0164d633789 --- /dev/null +++ b/app/src/News/Service/NewsListingService.php @@ -0,0 +1,57 @@ +news->getCountWithFilters($request->news_category); + + $pagination = $this->paginationFactory->create( + $request->page, + $request->limit, + $countOfNews + ); + + $offset = min($pagination->pageSize, $countOfNews) * ($pagination->currentPage - 1); + + $list = $this->listFactory->createCollection( + $this->news->getWithFilters($request->news_category, $request->limit, $offset) + ); + + $categoriesDto = $this->categoryFactory->createCollection( + $this->newsCategories->getAll() + ); + + $filters = $this->filterFactory->create($categoriesDto); + + return $this->listingFactory->create( + $pagination, + $list, + $filters + ); + } +} diff --git a/app/src/News/Service/NewsMainNewsService.php b/app/src/News/Service/NewsMainNewsService.php new file mode 100644 index 0000000000000000000000000000000000000000..784633dc7437fec00e28ca1960b7df562cac64c3 --- /dev/null +++ b/app/src/News/Service/NewsMainNewsService.php @@ -0,0 +1,22 @@ +dtoFactory->create($this->news->getMainNews()); + } +} diff --git a/app/src/News/Service/NewsSearchService.php b/app/src/News/Service/NewsSearchService.php new file mode 100644 index 0000000000000000000000000000000000000000..391d3c9d5e48bf01bbb18f31d0282a06dfece429 --- /dev/null +++ b/app/src/News/Service/NewsSearchService.php @@ -0,0 +1,22 @@ +dtoFactory->create($this->news->getMainNews()); + } +} diff --git a/app/src/Repository/.gitignore b/app/src/Repository/.gitignore deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/app/src/Repository/KitchensRepositoryInterface.php b/app/src/Repository/KitchensRepositoryInterface.php deleted file mode 100644 index afba82d22a0d1aaf46cfbdcb366c875eeeb80b28..0000000000000000000000000000000000000000 --- a/app/src/Repository/KitchensRepositoryInterface.php +++ /dev/null @@ -1,11 +0,0 @@ - */ - public function getAll(): Collection; -} diff --git a/app/src/Repository/NewsRepositoryInterface.php b/app/src/Repository/NewsRepositoryInterface.php deleted file mode 100644 index b67c875995d2f944e8226a7c11d4836c6a1698b7..0000000000000000000000000000000000000000 --- a/app/src/Repository/NewsRepositoryInterface.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * @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/Repository/RestaurantTypeRepositoryInterface.php b/app/src/Repository/RestaurantTypeRepositoryInterface.php deleted file mode 100644 index 61989432aaea428853547a37ba91209b736b496b..0000000000000000000000000000000000000000 --- a/app/src/Repository/RestaurantTypeRepositoryInterface.php +++ /dev/null @@ -1,12 +0,0 @@ - */ - public function getAll(): Collection; -} diff --git a/app/src/Repository/RestaurantsRepositoryInterface.php b/app/src/Repository/RestaurantsRepositoryInterface.php deleted file mode 100644 index e5e2f2fbbea70db9a448b01dac8282e5beaa39e2..0000000000000000000000000000000000000000 --- a/app/src/Repository/RestaurantsRepositoryInterface.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * @method Restaurants|null find($id, $lockMode = null, $lockVersion = null) - */ -interface RestaurantsRepositoryInterface -{ - public function getCountWithFilters(?string $kitchenId, string $typeId): int; - - /** @return Collection */ - public function findByFilters(?string $kitchenId, ?string $typeId, int $limit, int $offset): Collection; -} diff --git a/app/src/Controller/RestaurantsController.php b/app/src/Restaurants/Controller/RestaurantsController.php similarity index 50% rename from app/src/Controller/RestaurantsController.php rename to app/src/Restaurants/Controller/RestaurantsController.php index b268f8367cc3935d6e7c9ae798e900ffd4ccdf3d..5893ecbd3d2f8338c9e388fcf686c150af63bd34 100644 --- a/app/src/Controller/RestaurantsController.php +++ b/app/src/Restaurants/Controller/RestaurantsController.php @@ -1,32 +1,37 @@ listingService))->handle($request); + return $this->handle($this->listingService, $request); } #[Route('/{detailId}', name: 'restaurant', methods: ['GET'])] public function restaurant(DetailRequest $request): JsonResponse { - return (new Handle($this->detailService))->handle($request); + return $this->handle($this->detailService, $request); } } diff --git a/app/src/Restaurants/Dto/KitchenTypeDto.php b/app/src/Restaurants/Dto/KitchenTypeDto.php new file mode 100644 index 0000000000000000000000000000000000000000..e326132867a19ba14ef4a7cf732047ba200e108b --- /dev/null +++ b/app/src/Restaurants/Dto/KitchenTypeDto.php @@ -0,0 +1,16 @@ +|null $kitchen + * @param DtoCollection|null $phone + * @param DtoCollection|null $email + * @param DtoCollection|null $address + * @param DtoCollection|null $tags + * @param string|null $site + * @param FileDto|null $image Превью + * @param DtoCollection|null $gallery + */ + public function __construct( + public string $id, + + public string $name, + + public string $code, + + public string $coordinates, + + public RestaurantTypeDto $type, + + public ?string $check = null, + + public ?string $check_info = null, + + public ?DtoCollection $kitchen = null, + + public ?DtoCollection $phone = null, + + public ?DtoCollection $email = null, + + public ?DtoCollection $address = null, + + public ?DtoCollection $tags = null, + + public ?string $site = null, + + public ?FileDto $image = null, + + public ?DtoCollection $gallery = null, + ) {} +} diff --git a/app/src/Dto/RestaurantFilterVariantsDto.php b/app/src/Restaurants/Dto/RestaurantFilterVariantsDto.php similarity index 66% rename from app/src/Dto/RestaurantFilterVariantsDto.php rename to app/src/Restaurants/Dto/RestaurantFilterVariantsDto.php index 8fd5a95bcadf2b755e149c793c5a98fdffbf2d8a..e4a15c12190628671682225bac262d3621d5d61d 100644 --- a/app/src/Dto/RestaurantFilterVariantsDto.php +++ b/app/src/Restaurants/Dto/RestaurantFilterVariantsDto.php @@ -1,8 +1,9 @@ $kitchen */ public function __construct( - /** @var DtoCollection */ public DtoCollection $type, - /** @var DtoCollection */ public DtoCollection $kitchen, ) {} } diff --git a/app/src/Dto/RestaurantListDto.php b/app/src/Restaurants/Dto/RestaurantListDto.php similarity index 74% rename from app/src/Dto/RestaurantListDto.php rename to app/src/Restaurants/Dto/RestaurantListDto.php index fd500cb65dd92e45b1019575c2f4852faa36fb21..9d7f022c954c3def0fb3b7adb51b90e528a716f6 100644 --- a/app/src/Dto/RestaurantListDto.php +++ b/app/src/Restaurants/Dto/RestaurantListDto.php @@ -1,6 +1,10 @@ */ public DtoCollection $list, public RestaurantFilterVariantsDto $filterVariants, diff --git a/app/src/Restaurants/Dto/RestaurantListingElementDto.php b/app/src/Restaurants/Dto/RestaurantListingElementDto.php new file mode 100644 index 0000000000000000000000000000000000000000..b9b212ea04c5582fad4f15a68b5ede58fdb6ad65 --- /dev/null +++ b/app/src/Restaurants/Dto/RestaurantListingElementDto.php @@ -0,0 +1,25 @@ + */ public DtoCollection $list, ) {} } diff --git a/app/src/Restaurants/DtoFactory/KitchenTypeDtoFactory.php b/app/src/Restaurants/DtoFactory/KitchenTypeDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..04c726018fbaa0b803ef25e80890905e6f0e8ea7 --- /dev/null +++ b/app/src/Restaurants/DtoFactory/KitchenTypeDtoFactory.php @@ -0,0 +1,37 @@ +getId(), + name: $kitchen->getName(), + code: $kitchen->getCode(), + ); + } + + /** + * @param DoctrineCollection|RamseyCollection $kitchens + * @return DtoCollection + */ + public function createCollection(DoctrineCollection|RamseyCollection $kitchens): DtoCollection + { + $kitchenCollection = $kitchens->map(function(Kitchens $kitchen) { + return $this->create($kitchen); + }); + + return new DtoCollection( + KitchenTypeDto::class, + $kitchenCollection->toArray() + ); + } +} diff --git a/app/src/Restaurants/DtoFactory/RestaurantDetailElementDtoFactory.php b/app/src/Restaurants/DtoFactory/RestaurantDetailElementDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..343b8921581ffbaa099669fc132b1edae70c507e --- /dev/null +++ b/app/src/Restaurants/DtoFactory/RestaurantDetailElementDtoFactory.php @@ -0,0 +1,56 @@ +getId(), + name: $restaurant->getName(), + code: $restaurant->getCode(), + coordinates: $restaurant->getCoordinates(), + type: $this->typeFactory->create($restaurant->getType()), + check: $restaurant->getReceipt(), + check_info: $restaurant->getReceiptInfo(), + kitchen: $this->kitchenFactory->createCollection($restaurant->getKitchens()), + phone: $this->decodeJson($restaurant->getPhone()), + email: $this->decodeJson($restaurant->getEmail()), + address: $this->decodeJson($restaurant->getAddress()), + tags: $this->tagFactory->createCollection($restaurant->getTags()), + site: $restaurant->getSite(), + image: $this->fileFactory->create($restaurant->getPreviewImage()), + gallery: $this->fileFactory->createCollection($restaurant->getGallery()), + ); + } + + /** + * @throws \JsonException + */ + private function decodeJson(string $json) + { + return $json === null + ? null + : new DtoCollection( + 'string', + json_decode( + $json, + true, + 512, + JSON_THROW_ON_ERROR + ), + ); + } +} \ No newline at end of file diff --git a/app/src/Restaurants/DtoFactory/RestaurantFilterVariantsDtoFactory.php b/app/src/Restaurants/DtoFactory/RestaurantFilterVariantsDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..91624eb6b574dc8708ff1343c9b04bcdcbcd4b14 --- /dev/null +++ b/app/src/Restaurants/DtoFactory/RestaurantFilterVariantsDtoFactory.php @@ -0,0 +1,19 @@ + $list + * @param RestaurantFilterVariantsDto $filters + * @return RestaurantListDto + */ + public function create( + PaginationDto $pagination, + DtoCollection $list, + RestaurantFilterVariantsDto $filters + ): RestaurantListDto { + return new RestaurantListDto( + $pagination, + $list, + $filters + ); + } +} diff --git a/app/src/Restaurants/DtoFactory/RestaurantListingElementDtoFactory.php b/app/src/Restaurants/DtoFactory/RestaurantListingElementDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..d46d87b7e23ab636405ab5fb82262a2f4bb461a3 --- /dev/null +++ b/app/src/Restaurants/DtoFactory/RestaurantListingElementDtoFactory.php @@ -0,0 +1,45 @@ +getId(), + name: $restaurant->getName(), + code: $restaurant->getCode(), + type: $this->typeFactory->create($restaurant->getType()), + detailLink: 'api/v1/restaurants/' . $restaurant->getId(), + check: $restaurant->getReceipt(), + image: $this->fileFactory->create($restaurant->getPreviewImage()) + ); + } + + /** + * @param Collection $restaurants + * @return DtoCollection + */ + public function createCollection(Collection $restaurants): DtoCollection + { + $restaurantsDto = $restaurants->map(function(Restaurants $restaurant) { + return $this->create($restaurant); + }); + + return new DtoCollection( + RestaurantListingElementDto::class, + $restaurantsDto->toArray(), + ); + } +} diff --git a/app/src/Restaurants/DtoFactory/RestaurantTypeDtoFactory.php b/app/src/Restaurants/DtoFactory/RestaurantTypeDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..30b6ebc434bfb8cc002b63534e659b42af403922 --- /dev/null +++ b/app/src/Restaurants/DtoFactory/RestaurantTypeDtoFactory.php @@ -0,0 +1,36 @@ +getId(), + name: $type->getName(), + code: $type->getCode(), + ); + } + + /** + * @param Collection $types + * @return DtoCollection + */ + public function createCollection(Collection $types): DtoCollection + { + $typesDto = $types->map(function(RestaurantTypes $type) { + return $this->create($type); + }); + + return new DtoCollection( + RestaurantTypeDto::class, + $typesDto->toArray() + ); + } +} diff --git a/app/src/Restaurants/DtoFactory/TagDtoFactory.php b/app/src/Restaurants/DtoFactory/TagDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..174e26e1927d52985a0dfdf780f1e378c45b9548 --- /dev/null +++ b/app/src/Restaurants/DtoFactory/TagDtoFactory.php @@ -0,0 +1,39 @@ + + * @throws JsonException + */ + public function createCollection(string $json): DtoCollection + { + $jsonCollection = new RamseyCollection( + 'array', + json_decode( + $json, + true, + 512, + JSON_THROW_ON_ERROR + ) + ); + + $tagCollection = new DtoCollection(TagDto::class); + + foreach ($jsonCollection as $name => $jsonItem) { + $tagCollection->add( + new TagDto($name, new DtoCollection('string', $jsonItem)) + ); + } + + return $tagCollection; + } +} diff --git a/app/src/Request/RestaurantListingRequest.php b/app/src/Restaurants/Request/RestaurantListingRequest.php similarity index 90% rename from app/src/Request/RestaurantListingRequest.php rename to app/src/Restaurants/Request/RestaurantListingRequest.php index 403a3a9c1d845ea188da2b94cc0c20a43845a703..b85da7f4b3f7ed6a632018de041d481624a9a2e1 100644 --- a/app/src/Request/RestaurantListingRequest.php +++ b/app/src/Restaurants/Request/RestaurantListingRequest.php @@ -1,7 +1,8 @@ restaurants->find($request->detailId); + + if ($restaurant === null) { + throw new NotFoundError('Restaurant not found'); + } + + return $this->dtoFactory->create($restaurant); + } +} diff --git a/app/src/Restaurants/Service/RestaurantListingService.php b/app/src/Restaurants/Service/RestaurantListingService.php new file mode 100644 index 0000000000000000000000000000000000000000..a56b29fa9ff207950048d0fef13da6cb334f5318 --- /dev/null +++ b/app/src/Restaurants/Service/RestaurantListingService.php @@ -0,0 +1,71 @@ +restaurants + ->getCountWithFilters( + $request->restaurant_type_id, + $request->kitchen_id + ); + + $pagination = $this->paginationFactory->create( + $request->page, + $request->limit, + $countOfRestaurants, + ); + + $offset = min($pagination->pageSize, $countOfRestaurants) * ($pagination->currentPage - 1); + + $list = $this->listFactory->createCollection( + $this->restaurants->getWithFilters( + $request->kitchen_id, + $request->restaurant_type_id, + $pagination->pageSize, + $offset, + ), + ); + + + $filters = $this->filterFactory->create( + $this->typeFactory->createCollection($this->types->getAll()), + $this->kitchenFactory->createCollection($this->kitchens->getAll()) + ); + + return $this->listingFactory->create( + $pagination, + $list, + $filters + ); + } +} diff --git a/app/src/Service/NewsDetailService.php b/app/src/Service/NewsDetailService.php deleted file mode 100644 index 19c394d041318209f924c90169a6c302ac29f139..0000000000000000000000000000000000000000 --- a/app/src/Service/NewsDetailService.php +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index 6d7563611255ccdf4469f060366bdec812414774..0000000000000000000000000000000000000000 --- a/app/src/Service/NewsListingService.php +++ /dev/null @@ -1,71 +0,0 @@ -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 deleted file mode 100644 index 16037d31e53162558101a58a84dbcad48288f717..0000000000000000000000000000000000000000 --- a/app/src/Service/NewsMainNewsService.php +++ /dev/null @@ -1,19 +0,0 @@ -news->getMainNews()->getDto(); - } -} diff --git a/app/src/Service/NewsSearchService.php b/app/src/Service/NewsSearchService.php deleted file mode 100644 index ff9713e918b4c13ff1bd58c309aa8649e3a01d58..0000000000000000000000000000000000000000 --- a/app/src/Service/NewsSearchService.php +++ /dev/null @@ -1,18 +0,0 @@ -news->getMainNews()->getExtendedDto(); - } -} diff --git a/app/src/Service/RestaurantDetailService.php b/app/src/Service/RestaurantDetailService.php deleted file mode 100644 index 2547cfaa5085205c28c3bc836f5c913715e335f7..0000000000000000000000000000000000000000 --- a/app/src/Service/RestaurantDetailService.php +++ /dev/null @@ -1,30 +0,0 @@ -restaurants->find($request->detailId); - - if ($restaurant === null) { - throw new NotFoundError('Restaurant'); - } - - return $restaurant->getExtendedDto(); - } -} diff --git a/app/src/Service/RestaurantListingService.php b/app/src/Service/RestaurantListingService.php deleted file mode 100644 index d24741a30b54fe88d49f926b3254636011526d22..0000000000000000000000000000000000000000 --- a/app/src/Service/RestaurantListingService.php +++ /dev/null @@ -1,88 +0,0 @@ -restaurants - ->getCountWithFilters( - $request->restaurant_type_id, - $request->kitchen_id - ); - - $pagination = new PaginationDto( - $request->page, - $request->limit, - $countOfRestaurants, - ); - - $offset = min($pagination->page_size, $countOfRestaurants) * ($pagination->current_page - 1); - - $list = new DtoCollection( - RestaurantListingElementDto::class, - $this - ->restaurants - ->findByFilters( - $request - ->restaurant_type_id, - $request->kitchen_id, - $request->limit, - $offset, - ) - ->map(function (Restaurants $restaurant) { - return $restaurant->getDto(); - }) - ->toArray() - ); - - $filters = new RestaurantFilterVariantsDto( - new DtoCollection( - RestaurantTypeDto::class, - $this->types->getAll() - ->map(function(RestaurantTypes $types) { - return $types->getDto(); - }) - ->toArray() - ), - new DtoCollection( - KitchenTypeDto::class, - $this->kitchens->getAll() - ->map(function(Kitchens $kitchen) { - return $kitchen->getDto(); - }) - ->toArray() - ), - ); - - return new RestaurantListDto( - $pagination, - $list, - $filters, - ); - } -} diff --git a/app/src/Shared/Abstraction/AbstractController.php b/app/src/Shared/Abstraction/AbstractController.php new file mode 100644 index 0000000000000000000000000000000000000000..3d40cc856b2a5c4122c89f40a01bb0611fdb4fb3 --- /dev/null +++ b/app/src/Shared/Abstraction/AbstractController.php @@ -0,0 +1,33 @@ +serve($request)); +// +// } catch (BaseError $error) { +// $errorDto = $this->errorFactory->create($error); +// +// return new JsonResponse($errorDto, $errorDto->status); +// +// } catch (Throwable $exception) { +// $error = new ErrorDto(); +// return new JsonResponse($error, $error->status); +// } + } +} diff --git a/app/src/Request/AbstractRequest.php b/app/src/Shared/Abstraction/AbstractRequest.php similarity index 88% rename from app/src/Request/AbstractRequest.php rename to app/src/Shared/Abstraction/AbstractRequest.php index 9ddccd561dda24cd836c29e859ac988cbc3e50f6..a7be59c6ba0c7c8e0f59caa26127c27cd7c0f805 100644 --- a/app/src/Request/AbstractRequest.php +++ b/app/src/Shared/Abstraction/AbstractRequest.php @@ -1,9 +1,10 @@ add(new ValidateErrorDto($error)); + $messages->add((new ValidateErrorDtoFactory($error))->create()); } if ($messages->count() > 0) { diff --git a/app/src/Shared/Abstraction/DtoInterface.php b/app/src/Shared/Abstraction/DtoInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..60a39cd5a45b6da10d6ba5be2aec0d0428e4b6d6 --- /dev/null +++ b/app/src/Shared/Abstraction/DtoInterface.php @@ -0,0 +1,5 @@ +collectionType; } - /** Метод для сериализации коллекции в JSON */ public function jsonSerialize(): array { return $this->data; diff --git a/app/src/Shared/Dto/ErrorDto.php b/app/src/Shared/Dto/ErrorDto.php new file mode 100644 index 0000000000000000000000000000000000000000..fe14352013204f61f7b9ce01384954d60ee6d9d6 --- /dev/null +++ b/app/src/Shared/Dto/ErrorDto.php @@ -0,0 +1,16 @@ +getStatusCode(), + message: $error->getMessage(), + code: $error->getCode(), + ); + } +} diff --git a/app/src/Shared/DtoFactory/FileDtoFactory.php b/app/src/Shared/DtoFactory/FileDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..6fbc5c9d72af6d7c40b66790efcb7fb3b098f0b7 --- /dev/null +++ b/app/src/Shared/DtoFactory/FileDtoFactory.php @@ -0,0 +1,39 @@ +getId(), + name: $file->getName(), + description: $file->getDescription(), + size: $file->getSize(), + type: $file->getType(), + url: $file->getUrl(), + ); + } + + /** + * @param Collection $files + * @return DtoCollection + */ + public function createCollection(Collection $files): DtoCollection + { + $filesDto = $files->map(function(File $file) { + return $this->create($file); + }); + + return new DtoCollection( + FileDto::class, + $filesDto->toArray() + ); + } +} diff --git a/app/src/Shared/DtoFactory/PaginationDtoFactory.php b/app/src/Shared/DtoFactory/PaginationDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..933de0c51b462ddc14ef7f3a0557eaeccaa3c8a5 --- /dev/null +++ b/app/src/Shared/DtoFactory/PaginationDtoFactory.php @@ -0,0 +1,17 @@ + 0 ? $limit : 12; + $pages = ceil($total / $pageSize); + $page = ($page > 1) && ($page <= $pages) ? $page : 1; + + return new PaginationDto($page, $pages, $pageSize); + } +} diff --git a/app/src/Shared/DtoFactory/ValidateErrorDtoFactory.php b/app/src/Shared/DtoFactory/ValidateErrorDtoFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..9cb815a51824d681755e6d29de93156e5626c4bd --- /dev/null +++ b/app/src/Shared/DtoFactory/ValidateErrorDtoFactory.php @@ -0,0 +1,20 @@ +getPropertyPath() . ' : ' . $error->getMessage(), + code: ErrorCode::ValidateFailed->value, + status: 422 + ); + } +} diff --git a/app/src/Controller/.gitignore b/app/src/Shared/Entity/.gitignore similarity index 100% rename from app/src/Controller/.gitignore rename to app/src/Shared/Entity/.gitignore diff --git a/app/src/Entity/File.php b/app/src/Shared/Entity/File.php similarity index 93% rename from app/src/Entity/File.php rename to app/src/Shared/Entity/File.php index 751cb27e755245e45e1864a4d7619871e37ac453..5c448b7786889245f3ec2985b527c2da8a3d494f 100644 --- a/app/src/Entity/File.php +++ b/app/src/Shared/Entity/File.php @@ -1,17 +1,16 @@ id = $this->getId(); - $dto->name = $this->getName(); - $dto->description = $this->getDescription(); - $dto->size = $this->getSize(); - $dto->type = $this->getType(); - $dto->url = $this->getUrl(); - - return $dto; - } } diff --git a/app/src/Entity/Kitchens.php b/app/src/Shared/Entity/Kitchens.php similarity index 82% rename from app/src/Entity/Kitchens.php rename to app/src/Shared/Entity/Kitchens.php index d45bf0a141cbb6d2ef242c80c114be1ab0f48b5c..b6eb7b1d76293a31a7ac2eefba3bae3597eeee76 100644 --- a/app/src/Entity/Kitchens.php +++ b/app/src/Shared/Entity/Kitchens.php @@ -1,17 +1,16 @@ id = $this->getId(); - $dto->name = $this->getName(); - $dto->code = $this->getCode(); - - return $dto; - } } diff --git a/app/src/Entity/News.php b/app/src/Shared/Entity/News.php similarity index 80% rename from app/src/Entity/News.php rename to app/src/Shared/Entity/News.php index 53a159545f63170072c36039d4568907902d97e5..9640253d0fa70e3bb134bd6ddad7b85aa0759135 100644 --- a/app/src/Entity/News.php +++ b/app/src/Shared/Entity/News.php @@ -1,18 +1,19 @@ id = $this->getId(); - $entity->name = $this->getName(); - $entity->description = $this->getDetailText(); - $entity->image = $this->getPreviewImage()?->getDto(); - $entity->create_at = $this->getCreatedAt()->format('Y-m-d H:i:s'); - $entity->detail_link = "api/v1/restaurants/" . $this->getId(); - - return $entity; - } - - /** @inheritDoc */ - public function getExtendedDto(): DtoInterface - { - $entity = new NewsDetailElementDto(); - - $entity->id = $this->getId(); - $entity->name = $this->getName(); - $entity->description = $this->getPreviewText(); - $entity->text = $this->getDetailText(); - $entity->image = $this->getPreviewImage()?->getDto(); - $entity->create_at = $this->getCreatedAt()->format('Y-m-d H:i:s'); - - return $entity; - } } diff --git a/app/src/Entity/NewsCategories.php b/app/src/Shared/Entity/NewsCategories.php similarity index 81% rename from app/src/Entity/NewsCategories.php rename to app/src/Shared/Entity/NewsCategories.php index 0f77fd1c9a1af2120b56faefede1c795ec1f524b..f4b30cbe48cb2f1d660279135b19be36a105c4de 100644 --- a/app/src/Entity/NewsCategories.php +++ b/app/src/Shared/Entity/NewsCategories.php @@ -1,17 +1,18 @@ id = $this->getId(); - $dto->name = $this->getName(); - $dto->code = $this->getCode(); - - return $dto; - } } diff --git a/app/src/Entity/NewsType.php b/app/src/Shared/Entity/NewsType.php similarity index 95% rename from app/src/Entity/NewsType.php rename to app/src/Shared/Entity/NewsType.php index 8331456cece38db0ea9e0e8233fe9353f1ead6ca..d7d724e70b18aad687fdf58c239e5bed8b303cd5 100644 --- a/app/src/Entity/NewsType.php +++ b/app/src/Shared/Entity/NewsType.php @@ -1,9 +1,8 @@ id = $this->getId(); - $dto->name = $this->getName(); - $dto->code = $this->getCode(); - - return $dto; - } } diff --git a/app/src/Entity/Restaurants.php b/app/src/Shared/Entity/Restaurants.php similarity index 69% rename from app/src/Entity/Restaurants.php rename to app/src/Shared/Entity/Restaurants.php index 69e614c20255091b2883c896f6c1067d168f6182..a88eba41f83388e38d7ab74b9310968a407a85f5 100644 --- a/app/src/Entity/Restaurants.php +++ b/app/src/Shared/Entity/Restaurants.php @@ -1,23 +1,24 @@ id = $this->getId(); - $dto->name = $this->getName(); - $dto->code = $this->getCode(); - $dto->type = $this->getType()->getDto(); - $dto->check = $this->getReceipt(); - $dto->image = $this->getPreviewImage()?->getDto(); - $dto->detail_link = 'api/v1/restaurants/' . $this->getId(); - - return $dto; - } - - /** @inheritDoc - * @throws \JsonException Если получен неправильный json с бд - */ - public function getExtendedDto(): DtoInterface - { - $dto = new RestaurantDetailElementDto(); - - $dto->id = $this->getId(); - $dto->name = $this->getName(); - $dto->code = $this->getCode(); - $dto->coordinates = $this->getCoordinates(); - $dto->type = $this->getType()->getDto(); - $dto->check = $this->getReceipt(); - $dto->check_info = $this->getReceiptInfo(); - - $dto->kitchen = new DtoCollection( - KitchenTypeDto::class, - $this->getKitchens() - ->map(function(Kitchens $kitchen) { - return $kitchen->getDto(); - }) - ->toArray() - ); - - $dto->phone = $this->decode($this->getPhone()); - $dto->email = $this->decode($this->getEmail()); - $dto->address = $this->decode($this->getAddress()); - $dto->tags = $this->decodeTags($this->getTags()); - $dto->site = $this->getSite(); - $dto->image = $this->getPreviewImage()?->getDto(); - $dto->gallery = new DtoCollection( - FileDto::class, - $this->getGallery() - ->map(function(File $file) { - return $file->getDto(); - }) - ->toArray() - ); - - return $dto; - } - - /** - * @throws \JsonException Если получен неправильный json с бд - * @return ?DtoCollection - */ - private function decode(?string $jsonString): ?DtoCollection - { - if ($jsonString === null) { - return null; - } - return new DtoCollection( - 'string', - json_decode( - $jsonString, - true, - 512, - JSON_THROW_ON_ERROR - ) - ); - } - - private function decodeTags(?string $jsonString): ?DtoCollection - { - if ($jsonString === null) { - return null; - } - - $jsonCollection = new RamseyCollection( - 'array', - json_decode( - $jsonString, - true, - 512, - JSON_THROW_ON_ERROR - ) - ); - - $tagCollection = new DtoCollection(TagDto::class); - foreach ($jsonCollection as $name => $jsonItem) { - $tagCollection->add( - new TagDto($name, new DtoCollection('string', $jsonItem)) - ); - } - - return $tagCollection; - } } diff --git a/app/src/Entity/Settlements.php b/app/src/Shared/Entity/Settlements.php similarity index 97% rename from app/src/Entity/Settlements.php rename to app/src/Shared/Entity/Settlements.php index 6f6dc92f55fbef456e1ac65a99350795f2e1df61..3c26eb18a18d49bfdf0b8d6a44cf488f320561ad 100644 --- a/app/src/Entity/Settlements.php +++ b/app/src/Shared/Entity/Settlements.php @@ -1,8 +1,8 @@ value + ); + } +} diff --git a/app/src/Shared/Error/ErrorCode.php b/app/src/Shared/Error/ErrorCode.php new file mode 100644 index 0000000000000000000000000000000000000000..a9495f4c777334d9b46e2edb25411cafeb600d55 --- /dev/null +++ b/app/src/Shared/Error/ErrorCode.php @@ -0,0 +1,10 @@ +createQueryBuilder('n'); - $query = $this->getByFilters($categoryId, $query); + $query = $this->findByFilters($categoryId, $query); return $query->select('COUNT(n.id)')->getQuery()->getSingleScalarResult(); } /** @return Collection */ - public function findByFilters(?string $categoryId, int $limit, int $offset): Collection + public function getWithFilters(?string $categoryId, int $limit, int $offset): Collection { $query = $this->createQueryBuilder('n'); - $query = $this->getByFilters($categoryId, $query); + $query = $this->findByFilters($categoryId, $query); $query = $query->setMaxResults($limit); $query = $query->setFirstResult($offset); return $this->toCollection($query); } - /** @return Collection */ + /** @return Collection */ public function getAll(): Collection { return $this->toCollection($this->createQueryBuilder('n')); } - public function getMain(): News - { - return $this->createQueryBuilder('n') - ->andWhere('n.mainPageRender = true') - ->setMaxResults(1) - ->getQuery() - ->getResult()[0]; - } - /** * @param QueryBuilder $query * @return Collection @@ -81,7 +71,7 @@ class NewsRepository extends ServiceEntityRepository implements NewsRepositoryIn ); } - protected function getByFilters(?string $categoryId, QueryBuilder $query): QueryBuilder + protected function findByFilters(?string $categoryId, QueryBuilder $query): QueryBuilder { if ($categoryId !== null) { $query = $query diff --git a/app/src/Repository/NewsTypeRepository.php b/app/src/Shared/Repository/NewsTypeRepository.php similarity index 92% rename from app/src/Repository/NewsTypeRepository.php rename to app/src/Shared/Repository/NewsTypeRepository.php index e2acd172d1c529658256c69ca9fb1300ca9d2047..e3decdf1337d92c4d089bb97b72d9e7cf4237c31 100644 --- a/app/src/Repository/NewsTypeRepository.php +++ b/app/src/Shared/Repository/NewsTypeRepository.php @@ -1,8 +1,8 @@ where('r.type.id = :typeId') + ->where('r.type = :typeId') ->setParameter('typeId', $typeId); } return $query; @@ -65,7 +65,7 @@ class RestaurantsRepository extends ServiceEntityRepository implements Restauran } /** @return Collection */ - public function findByFilters(?string $kitchenId, ?string $typeId, int $limit, int $offset): Collection + public function getWithFilters(?string $kitchenId, ?string $typeId, int $limit, int $offset): Collection { $query = $this->createQueryBuilder('r'); $query = $this->filterByKitchen($kitchenId, $query); diff --git a/app/src/Repository/SettlementsRepository.php b/app/src/Shared/Repository/SettlementsRepository.php similarity index 90% rename from app/src/Repository/SettlementsRepository.php rename to app/src/Shared/Repository/SettlementsRepository.php index 66a2f2d486efdd05e31003f0f73f8e24424b9344..e83866a8195857f8baa510f1f7c5268bed092654 100644 --- a/app/src/Repository/SettlementsRepository.php +++ b/app/src/Shared/Repository/SettlementsRepository.php @@ -1,8 +1,9 @@