From 0e64a562da7ee739127844fa6f52456fab4c39e5 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 17:51:08 +0500 Subject: [PATCH] =?UTF-8?q?STA-966=20|=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- src/Controller/NewsController.php | 18 ++- src/Controller/RestaurantController.php | 64 ++-------- src/Entity/Restaurant.php | 23 +++- src/Exception/NewsExceptionEnum.php | 4 +- src/Exception/NewsNotFoundException.php | 11 ++ src/Exception/RestaurantExceptionEnum.php | 4 +- src/Exception/RestaurantNotFoundException.php | 11 ++ src/Mapper/FileMapper.php | 21 ++++ src/Mapper/NewsMapper.php | 47 +++---- src/Mapper/RestaurantMapper.php | 117 +++++++----------- src/Model/File.php | 8 +- src/Model/KitchenType.php | 9 +- src/Model/NewsCategory.php | 1 - src/Model/RestaurantDetailElement.php | 7 +- src/Model/RestaurantListingElement.php | 8 +- src/Model/RestaurantType.php | 8 +- src/Model/Review.php | 15 +-- src/Repository/GalleryRepository.php | 30 +---- .../Interface/GalleryRepositoryInterface.php | 8 ++ .../Interface/NewsRepositoryInterface.php | 2 +- .../RestaurantRepositoryInterface.php | 4 +- src/Repository/NewsRepository.php | 9 +- src/Repository/RestaurantRepository.php | 18 ++- src/Requests/NewsListRequest.php | 2 - src/Requests/RestaurantListRequest.php | 6 +- src/Service/NewsService.php | 47 +++++-- src/Service/RestaurantService.php | 78 +++++++++--- 28 files changed, 319 insertions(+), 263 deletions(-) create mode 100644 src/Exception/NewsNotFoundException.php create mode 100644 src/Exception/RestaurantNotFoundException.php create mode 100644 src/Mapper/FileMapper.php create mode 100644 src/Repository/Interface/GalleryRepositoryInterface.php diff --git a/.env b/.env index 8c34a32..679fb18 100644 --- a/.env +++ b/.env @@ -26,7 +26,7 @@ APP_SECRET=ea3ebbf899855d483050e0d1aad6a759 # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4" -DATABASE_URL="postgresql://postgres:12345@127.0.0.1:5433/postgres?serverVersion=16&charset=utf8" +DATABASE_URL="postgresql://postgres:12345@postgres/postgres?serverVersion=16&charset=utf8" ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### diff --git a/src/Controller/NewsController.php b/src/Controller/NewsController.php index ae4ea9f..6102cad 100644 --- a/src/Controller/NewsController.php +++ b/src/Controller/NewsController.php @@ -4,8 +4,8 @@ declare(strict_types=1); namespace App\Controller; +use App\Exception\NewsNotFoundException; use App\Requests\NewsListRequest; -use Exception; use App\Service\NewsService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -20,11 +20,7 @@ class NewsController extends AbstractController #[Route('/news', name: 'news', methods: ['GET'])] public function news(NewsListRequest $request): Response { - $page = $request->getRequest()->query->get('page'); - $limit = $request->getRequest()->query->get('limit'); - $newsCategory = $request->getRequest()->query->get('news_category'); - $news = $this->newsService->getNews($page, $limit, $newsCategory); - return $this->json($news); + return $this->json($this->newsService->getNewsByRequest($request)); } #[Route('/news/mainNews', name: 'mainNews', methods: ['GET'])] @@ -45,11 +41,13 @@ class NewsController extends AbstractController public function newsOne(Request $request): Response { try { - $newsId = $request->get('newsId');; - $news = $this->newsService->getNewsOne($newsId); + $news = $this->newsService->getNewsOneByRequest($request); return $this->json($news); - } catch (Exception $e) { - return new Response($e->getMessage(), $e->getCode()); + } catch (NewsNotFoundException $e) { + return $this->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], $e->getCode()); } } } diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php index d6f3983..701ff93 100644 --- a/src/Controller/RestaurantController.php +++ b/src/Controller/RestaurantController.php @@ -4,18 +4,13 @@ declare(strict_types=1); namespace App\Controller; +use App\Exception\RestaurantNotFoundException; use App\Requests\RestaurantListRequest; -use Exception; use App\Service\RestaurantService; -use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Attributes as OA; -use OpenApi\Attributes\Schema; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Attribute\Route; -use App\Model\RestaurantList; -use Symfony\Component\Serializer\SerializerInterface; #[Route("/api/v1")] class RestaurantController extends AbstractController @@ -23,58 +18,25 @@ class RestaurantController extends AbstractController public function __construct(private RestaurantService $restaurantService) {} #[Route('/restaurants', name: 'restaurants', methods: ['GET'])] - #[OA\Response(response: 200, description: "Листинг ресторанов")] - #[OA\Parameter( - name: "page", - description: "Номер страницы", - in: "query", - schema: new Schema(type: "integer", default: 1, example: 1) - )] - #[OA\Parameter( - name: "limit", - description: "Лимит", - in: "query", - schema: new Schema(type: "integer", default: 12, example: 12) - )] - #[OA\Parameter( - name: "restaurant_type_id", - description: "Идентификатор типа ресторанов", - in: "query", - schema: new Schema(type: "integer") - )] - #[OA\Parameter( - name: "kitchen_id", - description: "Идентификатор кухни", - in: "query", - schema: new Schema(type: "integer") - )] - #[Model(type: RestaurantList::class)] public function restaurants(RestaurantListRequest $request): Response { - $page = $request->getRequest()->query->get('page'); - $limit = $request->getRequest()->query->get('limit'); - $restaurantTypeId = $request->getRequest()->query->get('restaurant_type_id'); - $kitchenId = $request->getRequest()->query->get('kitchen_id'); - $restaurantsList = $this->restaurantService->getRestaurants( - $page, $limit, $restaurantTypeId, $kitchenId - ); - return $this->json($restaurantsList); + return $this->json($this->restaurantService->getRestaurantsByRequest($request)); } #[Route('/restaurants/{restaurantId}', name: 'restaurant', methods: ['GET'])] - public function restaurant(Request $request, SerializerInterface $serializer): Response + public function restaurant(Request $request): Response { try { - $restaurantId = (int)$request->get('restaurantId'); - $restaurant = $this->restaurantService->getRestaurant($restaurantId); - $json = $serializer->serialize($restaurant, 'json', [ - 'circular_reference_handler' => function ($object) { - return $object->getId(); - } - ]); - return new Response($json, Response::HTTP_OK, ['Content-Type' => 'application/json']); - } catch (Exception $e) { - return new Response($e->getMessage(), $e->getCode()); + return new Response( + $this->restaurantService->getRestaurantByRequest($request), + Response::HTTP_OK, + ['Content-Type' => 'application/json'] + ); + } catch (RestaurantNotFoundException $e) { + return $this->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], $e->getCode()); } } } diff --git a/src/Entity/Restaurant.php b/src/Entity/Restaurant.php index 281d25a..ff7d311 100644 --- a/src/Entity/Restaurant.php +++ b/src/Entity/Restaurant.php @@ -60,7 +60,7 @@ class Restaurant /** * @var Collection */ - #[ORM\OneToMany(targetEntity: Kitchen::class, mappedBy: 'restaurant')] + #[ORM\OneToMany(targetEntity: Kitchen::class, mappedBy: 'restaurant', fetch: 'EAGER')] private Collection $kitchen; #[ORM\Column] @@ -75,7 +75,7 @@ class Restaurant /** * @var Collection */ - #[ORM\OneToMany(targetEntity: Tags::class, mappedBy: 'restaurant')] + #[ORM\OneToMany(targetEntity: Tags::class, mappedBy: 'restaurant', fetch: 'EAGER')] private Collection $tags; #[ORM\Column(length: 255)] @@ -90,11 +90,11 @@ class Restaurant #[ORM\Column(type: Types::TEXT)] private ?string $howToFind = null; - #[ORM\ManyToOne] + #[ORM\ManyToOne(fetch: 'EAGER')] #[ORM\JoinColumn(nullable: false)] private ?Seo $seo = null; - #[ORM\OneToOne(cascade: ['persist', 'remove'])] + #[ORM\OneToOne(cascade: ['persist', 'remove'], fetch: 'EAGER')] #[ORM\JoinColumn(nullable: false)] private ?File $file = null; @@ -405,4 +405,19 @@ class Restaurant return $this; } + + public function getPhone(): array + { + return $this->phone; + } + + public function getEmail(): array + { + return $this->email; + } + + public function getAddress(): array + { + return $this->address; + } } diff --git a/src/Exception/NewsExceptionEnum.php b/src/Exception/NewsExceptionEnum.php index 6535eff..38c5c28 100644 --- a/src/Exception/NewsExceptionEnum.php +++ b/src/Exception/NewsExceptionEnum.php @@ -2,7 +2,9 @@ namespace App\Exception; +use Symfony\Component\HttpFoundation\Response; + enum NewsExceptionEnum: int { - case NotFound = 404; + case NotFound = Response::HTTP_NOT_FOUND; } diff --git a/src/Exception/NewsNotFoundException.php b/src/Exception/NewsNotFoundException.php new file mode 100644 index 0000000..9b4dd01 --- /dev/null +++ b/src/Exception/NewsNotFoundException.php @@ -0,0 +1,11 @@ +value); + } +} \ No newline at end of file diff --git a/src/Exception/RestaurantExceptionEnum.php b/src/Exception/RestaurantExceptionEnum.php index fe3469d..6f3f8fa 100644 --- a/src/Exception/RestaurantExceptionEnum.php +++ b/src/Exception/RestaurantExceptionEnum.php @@ -2,7 +2,9 @@ namespace App\Exception; +use Symfony\Component\HttpFoundation\Response; + enum RestaurantExceptionEnum: int { - case NotFound = 404; + case NotFound = Response::HTTP_NOT_FOUND; } diff --git a/src/Exception/RestaurantNotFoundException.php b/src/Exception/RestaurantNotFoundException.php new file mode 100644 index 0000000..25f78ab --- /dev/null +++ b/src/Exception/RestaurantNotFoundException.php @@ -0,0 +1,11 @@ +value); + } +} \ No newline at end of file diff --git a/src/Mapper/FileMapper.php b/src/Mapper/FileMapper.php new file mode 100644 index 0000000..f6cd5f7 --- /dev/null +++ b/src/Mapper/FileMapper.php @@ -0,0 +1,21 @@ +getId(), + $file->getName(), + $file->getDescription(), + $file->getSize(), + $file->getType(), + $file->getUrl() + ); + } +} \ No newline at end of file diff --git a/src/Mapper/NewsMapper.php b/src/Mapper/NewsMapper.php index 65cf34d..420dbf7 100644 --- a/src/Mapper/NewsMapper.php +++ b/src/Mapper/NewsMapper.php @@ -4,7 +4,6 @@ namespace App\Mapper; use App\Entity\News; use App\Entity\NewsCategory; -use App\Model\File; use App\Model\NewsDetailElement; use App\Model\NewsFilterVariants; use App\Model\NewsList; @@ -16,24 +15,24 @@ use Ramsey\Collection\Collection; class NewsMapper { public static function mapToNewsList( - $news, - $newsCategory, - $page, - $limit, - $count): NewsList - { + Collection $news, + Collection $newsCategory, + int $page, + int $limit, + int $count + ): NewsList { return new NewsList( new Pagination($page, ceil($count / $limit), $limit), new Collection(NewsListingElement::class, array_map( function (News $newsOne) { return self::mapToListingElement($newsOne); - }, $news) + }, $news->toArray()) ), new NewsFilterVariants( new Collection(NewsCategoryModel::class, array_map( function (NewsCategory $newsCategoryOne) { return self::mapToNewsCategory($newsCategoryOne); - }, $newsCategory) + }, $newsCategory->toArray()) ) ) ); @@ -41,44 +40,28 @@ class NewsMapper public static function mapToListingElement(News $newsOne): NewsListingElement { - $file = new File( - 1, - "asd", - "Краткое описание", - 1024, - "png", - "/upload/asd.png" - ); return new NewsListingElement( $newsOne->getId(), $newsOne->getPreviewText(), $newsOne->getDetailText(), - $file, - $newsOne->getCreateAt()->format('d.m.Y'), + FileMapper::mapToFile($newsOne->getFile()), + $newsOne->getCreateAt()?->format('d.m.Y'), "/{$newsOne->getCode()}/code/" ); } public static function mapToDetailElement(News $newsOne): NewsDetailElement { - $file = new File( - 1, - "asd", - "Краткое описание", - 1024, - "png", - "/upload/asd.png" - ); return new NewsDetailElement( $newsOne->getId(), $newsOne->getPreviewText(), $newsOne->getDetailText(), $newsOne->getDetailText(), - $file, - $newsOne->getCreateAt()->format('d.m.Y'), - "Отель «Арктика»", - "otel-arktika", - "otel-arktika" + FileMapper::mapToFile($newsOne->getFile()), + $newsOne->getCreateAt()?->format('d.m.Y'), + $newsOne->getSeo()?->getTitle(), + $newsOne->getSeo()?->getDescription(), + $newsOne->getSeo()?->getKeywords() ); } diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php index 62bc18a..a300f1f 100644 --- a/src/Mapper/RestaurantMapper.php +++ b/src/Mapper/RestaurantMapper.php @@ -2,14 +2,11 @@ namespace App\Mapper; -use App\Entity\Address; -use App\Entity\Email; +use App\Entity\Gallery; use App\Entity\Kitchen; -use App\Entity\Phone; use App\Entity\Restaurant; use App\Entity\RestaurantType; use App\Entity\Tags; -use App\Model\File; use App\Model\KitchenType; use App\Model\Pagination; use App\Model\RestaurantDetailElement; @@ -18,37 +15,38 @@ use App\Model\RestaurantList; use App\Model\RestaurantListingElement; use App\Model\RestaurantType as RestaurantTypeModel; use App\Model\Tag; +use App\Model\File; use Ramsey\Collection\Collection; class RestaurantMapper { public static function mapToRestaurantList( - $restaurants, - $restaurantTypes, - $kitchens, - $page, - $limit, - $count): RestaurantList - { + Collection $restaurants, + Collection $restaurantTypes, + Collection $kitchens, + int $page, + int $limit, + int $count + ): RestaurantList { return new RestaurantList( new Pagination($page, ceil($count / $limit), $limit), new Collection(RestaurantListingElement::class, array_map( function (Restaurant $restaurant) { - return RestaurantMapper::mapToListElement($restaurant); - }, $restaurants)), + return self::mapToListElement($restaurant); + }, $restaurants->toArray())), new RestaurantFilterVariants( new Collection( RestaurantTypeModel::class, array_map( function (RestaurantType $restaurantType) { - return RestaurantMapper::mapToRestaurantType($restaurantType); - }, $restaurantTypes + return self::mapToRestaurantType($restaurantType); + }, $restaurantTypes->toArray() ) ), new Collection( KitchenType::class, array_map( function (Kitchen $kitchen) { - return RestaurantMapper::mapToKitchenType($kitchen); - }, $kitchens + return self::mapToKitchenType($kitchen); + }, $kitchens->toArray() ), ) ) @@ -63,28 +61,13 @@ class RestaurantMapper $restaurant->getCode(), self::mapToRestaurantType($restaurant->getTypeId()), $restaurant->getCheckInfo(), - new File( - 1, - "name", - "description", - 10, - "jpg", - $restaurant->getPreviewImage() - ), + FileMapper::mapToFile($restaurant->getFile()), $restaurant->getSite() ); } - public static function mapToDetailElement(Restaurant $restaurant): RestaurantDetailElement + public static function mapToDetailElement(Restaurant $restaurant, Collection $gallery): RestaurantDetailElement { - $file = new File( - 1, - "name", - "description", - 10, - "jpg", - $restaurant->getPreviewImage() - ); return new RestaurantDetailElement( $restaurant->getId(), $restaurant->getName(), @@ -99,35 +82,21 @@ class RestaurantMapper return self::mapToKitchenType($kitchen); }, $restaurant->getKitchen()->toArray()), ), - new Collection("string", array_map( - function (Phone $phone) { - return self::mapToPhone($phone); - }, $restaurant->getPhone()->toArray() - )), - new Collection("string", array_map( - function (Email $email) { - return self::mapToEmail($email); - }, $restaurant->getEmail()->toArray() - )), - new Collection("string", array_map( - function (Address $address) { - return self::mapToAddress($address); - }, $restaurant->getAddress()->toArray() - )), - new Collection(Tag::class, array_map( - function (Tags $tag) { - return new Tag( - "группа тегов 1", - new Collection("string", [$tag->getName()]), - ); - }, $restaurant->getTags()->toArray() - )), + new Collection("string", $restaurant->getPhone()), + new Collection("string", $restaurant->getEmail()), + new Collection("string", $restaurant->getAddress()), + self::mapToTag( + new Collection( + Tags::class, + $restaurant->getTags()->toArray() + ) + ), $restaurant->getSite(), - $file, - new Collection(File::class, [$file]), - "Отель Арктика", - "otel arktika", - "otel arktika" + FileMapper::mapToFile($restaurant->getFile()), + self::mapToGallery($gallery), + $restaurant->getSeo()?->getTitle(), + $restaurant->getSeo()?->getDescription(), + $restaurant->getSeo()?->getKeywords() ); } @@ -148,18 +117,24 @@ class RestaurantMapper ); } - public static function mapToPhone(Phone $phone): string - { - return $phone->getName(); - } - - public static function mapToEmail(Email $email): string + public static function mapToTag(Collection $tags): Collection { - return $email->getName(); + return new Collection(Tag::class, array_map( + function (Tags $tag) { + return new Tag( + $tag->getName(), + new Collection("string", $tag->getList()) + ); + }, $tags->toArray()) + ); } - public static function mapToAddress(Address $address): string + public static function mapToGallery(Collection $gallery): Collection { - return $address->getName(); + return new Collection(File::class, array_map( + function (Gallery $galleryOne) { + return FileMapper::mapToFile($galleryOne->getFile()); + }, $gallery->toArray()) + ); } } \ No newline at end of file diff --git a/src/Model/File.php b/src/Model/File.php index 2cbf0a7..9d3d006 100644 --- a/src/Model/File.php +++ b/src/Model/File.php @@ -2,9 +2,11 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class File { - private int $id; + private Uuid $id; private string $name; private string $description; private int $size; @@ -12,7 +14,7 @@ class File private string $url; public function __construct( - int $id, + Uuid $id, string $name, string $description, int $size, @@ -27,7 +29,7 @@ class File $this->url = $url; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/KitchenType.php b/src/Model/KitchenType.php index 34e125b..69640ec 100644 --- a/src/Model/KitchenType.php +++ b/src/Model/KitchenType.php @@ -2,19 +2,20 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class KitchenType { - private int $id; + private Uuid $id; private string $name; - - public function __construct(int $id, string $name) + public function __construct(Uuid $id, string $name) { $this->id = $id; $this->name = $name; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/NewsCategory.php b/src/Model/NewsCategory.php index e22f456..e28a9be 100644 --- a/src/Model/NewsCategory.php +++ b/src/Model/NewsCategory.php @@ -10,7 +10,6 @@ class NewsCategory private string $name; private string $code; - public function __construct(Uuid $id, string $name, string $code) { $this->id = $id; diff --git a/src/Model/RestaurantDetailElement.php b/src/Model/RestaurantDetailElement.php index face2bf..f9d90f0 100644 --- a/src/Model/RestaurantDetailElement.php +++ b/src/Model/RestaurantDetailElement.php @@ -3,10 +3,11 @@ namespace App\Model; use Ramsey\Collection\Collection; +use Symfony\Component\Uid\Uuid; class RestaurantDetailElement { - private int $id; + private Uuid $id; private string $name; private string $code; private string $coordinates; @@ -44,7 +45,7 @@ class RestaurantDetailElement private string $seoKeywords; public function __construct( - int $id, + Uuid $id, string $name, string $code, string $coordinates, @@ -83,7 +84,7 @@ class RestaurantDetailElement $this->seoKeywords = $seoKeywords; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/RestaurantListingElement.php b/src/Model/RestaurantListingElement.php index 6aeb904..d7bb15f 100644 --- a/src/Model/RestaurantListingElement.php +++ b/src/Model/RestaurantListingElement.php @@ -2,9 +2,11 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class RestaurantListingElement { - private int $id; + private Uuid $id; private string $name; private string $code; private RestaurantType $type; @@ -13,7 +15,7 @@ class RestaurantListingElement private string $detailLink; public function __construct( - int $id, + Uuid $id, string $name, string $code, RestaurantType $type, @@ -30,7 +32,7 @@ class RestaurantListingElement $this->detailLink = $detailLink; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/RestaurantType.php b/src/Model/RestaurantType.php index a10325b..e91219d 100644 --- a/src/Model/RestaurantType.php +++ b/src/Model/RestaurantType.php @@ -2,20 +2,22 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class RestaurantType { - private int $id; + private Uuid $id; private string $name; private string $code; - public function __construct(int $id, string $name, string $code) + public function __construct(Uuid $id, string $name, string $code) { $this->id = $id; $this->name = $name; $this->code = $code; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/Review.php b/src/Model/Review.php index 3af98fd..298e263 100644 --- a/src/Model/Review.php +++ b/src/Model/Review.php @@ -2,19 +2,20 @@ namespace App\Model; -use DateTime; +use DateTimeImmutable; +use Symfony\Component\Uid\Uuid; class Review { - private int $id; - private DateTime $date; + private Uuid $id; + private DateTimeImmutable $date; private int $score; private string $text; private string $userName; public function __construct( - int $id, - DateTime $date, + Uuid $id, + DateTimeImmutable $date, int $score, string $text, string $userName @@ -26,12 +27,12 @@ class Review $this->userName = $userName; } - public function getId(): int + public function getId(): Uuid { return $this->id; } - public function getDate(): DateTime + public function getDate(): DateTimeImmutable { return $this->date; } diff --git a/src/Repository/GalleryRepository.php b/src/Repository/GalleryRepository.php index d15e89a..b11bc05 100644 --- a/src/Repository/GalleryRepository.php +++ b/src/Repository/GalleryRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Gallery; +use App\Repository\Interface\GalleryRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +15,16 @@ use Doctrine\Persistence\ManagerRegistry; * @method Gallery[] findAll() * @method Gallery[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class GalleryRepository extends ServiceEntityRepository +class GalleryRepository extends ServiceEntityRepository implements GalleryRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Gallery::class); } -// /** -// * @return Gallery[] Returns an array of Gallery objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('g') -// ->andWhere('g.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('g.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } -// public function findOneBySomeField($value): ?Gallery -// { -// return $this->createQueryBuilder('g') -// ->andWhere('g.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getGalleryByRestaurantId(string $restaurantId): array + { + return $this->findBy(['restaurant' => $restaurantId]); + } } diff --git a/src/Repository/Interface/GalleryRepositoryInterface.php b/src/Repository/Interface/GalleryRepositoryInterface.php new file mode 100644 index 0000000..05e9650 --- /dev/null +++ b/src/Repository/Interface/GalleryRepositoryInterface.php @@ -0,0 +1,8 @@ + @@ -24,7 +24,7 @@ class NewsRepository extends ServiceEntityRepository implements NewsRepositoryIn parent::__construct($registry, News::class); } - public function getAll($page, $limit, $newsCategory): array + public function getAll(int $page, int $limit, string|null $newsCategory): array { $query = $this->getEntityManager()->createQueryBuilder(); $query->select('n')->from(News::class, 'n'); @@ -51,9 +51,10 @@ class NewsRepository extends ServiceEntityRepository implements NewsRepositoryIn public function getNewsById(string $newsId): News|null { try { - return $this->find(['id' => $newsId]); + $uuid = new Uuid($newsId); + return $this->find($uuid); } catch (Exception $e) { - throw new Exception("News not found", NewsExceptionEnum::NotFound->value); + return null; } } } diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 0f2061e..6ff1315 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -6,6 +6,7 @@ use App\Entity\Restaurant; use App\Repository\Interface\RestaurantRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Component\Uid\Uuid; /** * @extends ServiceEntityRepository @@ -22,8 +23,12 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant parent::__construct($registry, Restaurant::class); } - public function getAll($page, $limit, $restaurantTypeId, $kitchenId): array - { + public function getAll( + int $page, + int $limit, + string|null $restaurantTypeId, + string|null $kitchenId + ): array { $query = $this->createQueryBuilder('r'); $query->select('r'); if ($restaurantTypeId !== null) { @@ -45,8 +50,13 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant return $this->count(); } - public function getById(int $id): Restaurant|null + public function getById(string $id): Restaurant|null { - return $this->find($id); + try { + $uuid = new Uuid($id); + return $this->find($uuid); + } catch (\Exception $e) { + return null; + } } } diff --git a/src/Requests/NewsListRequest.php b/src/Requests/NewsListRequest.php index 914a3c8..b3d2111 100644 --- a/src/Requests/NewsListRequest.php +++ b/src/Requests/NewsListRequest.php @@ -9,10 +9,8 @@ use Symfony\Component\Validator\Constraints as Assert; class NewsListRequest extends BaseRequest { #[Assert\Type('int')] - #[Assert\NotBlank] public $page; #[Assert\Type('int')] - #[Assert\NotBlank] public $limit; #[Assert\Uuid] public $news_category; diff --git a/src/Requests/RestaurantListRequest.php b/src/Requests/RestaurantListRequest.php index 701674d..7f940ba 100644 --- a/src/Requests/RestaurantListRequest.php +++ b/src/Requests/RestaurantListRequest.php @@ -7,14 +7,12 @@ use Symfony\Component\Validator\Constraints as Assert; class RestaurantListRequest extends BaseRequest { #[Assert\Type('int')] - #[Assert\NotBlank] public $page; #[Assert\Type('int')] - #[Assert\NotBlank] public $limit; - #[Assert\Type('int')] + #[Assert\Uuid] public $restaurant_type_id; - #[Assert\Type('int')] + #[Assert\Uuid] public $kitchen_id; protected function populate(): void diff --git a/src/Service/NewsService.php b/src/Service/NewsService.php index 043d000..fca6f8a 100644 --- a/src/Service/NewsService.php +++ b/src/Service/NewsService.php @@ -2,25 +2,48 @@ namespace App\Service; -use Exception; -use App\Exception\NewsExceptionEnum; +use App\Entity\News; +use App\Entity\NewsCategory; +use App\Exception\NewsNotFoundException; use App\Mapper\NewsMapper; use App\Model\NewsDetailElement; use App\Model\NewsList; use App\Model\NewsListingElement; use App\Repository\Interface\NewsCategoryRepositoryInterface; use App\Repository\Interface\NewsRepositoryInterface; +use App\Requests\NewsListRequest; +use Ramsey\Collection\Collection; +use Symfony\Component\HttpFoundation\Request; class NewsService { + private const DEFAULT_PAGE = 1; + private const DEFAULT_LIMIT = 12; + public function __construct( private NewsRepositoryInterface $newsRepository, - private NewsCategoryRepositoryInterface $newsCategoryRepository) {} + private NewsCategoryRepositoryInterface $newsCategoryRepository + ) {} + + public function getNewsByRequest(NewsListRequest $request): NewsList + { + $page = $request->getRequest()->query->get('page') ?? self::DEFAULT_PAGE; + $limit = $request->getRequest()->query->get('limit') ?? self::DEFAULT_LIMIT; + $newsCategory = $request->getRequest()->query->get('news_category'); + return $this->getNews($page, $limit, $newsCategory); + } - public function getNews($page, $limit, $newsCategory): NewsList + public function getNews(int $page, int $limit, string|null $newsCategory): NewsList { - $news = $this->newsRepository->getAll($page, $limit, $newsCategory); - $newsCategories = $this->newsCategoryRepository->getAll(); + $news = new Collection( + News::class, + $this->newsRepository->getAll( + $page, + $limit, + $newsCategory + ) + ); + $newsCategories = new Collection(NewsCategory::class, $this->newsCategoryRepository->getAll()); $count = $this->newsRepository->getCount(); return NewsMapper::mapToNewsList($news, $newsCategories, $page, $limit, $count); } @@ -37,11 +60,17 @@ class NewsService return NewsMapper::mapToDetailElement($mainNews); } - public function getNewsOne($newsId): NewsDetailElement + public function getNewsOneByRequest(Request $request): NewsDetailElement + { + $newsId = $request->get('newsId'); + return $this->getNewsOne($newsId); + } + + public function getNewsOne(string $newsId): NewsDetailElement { $news = $this->newsRepository->getNewsById($newsId); - if ($news == null) { - throw new Exception("News not found", NewsExceptionEnum::NotFound->value); + if ($news === null) { + throw new NewsNotFoundException(); } return NewsMapper::mapToDetailElement($news); } diff --git a/src/Service/RestaurantService.php b/src/Service/RestaurantService.php index 8f1a42a..199efb4 100644 --- a/src/Service/RestaurantService.php +++ b/src/Service/RestaurantService.php @@ -2,37 +2,64 @@ namespace App\Service; -use App\Exception\RestaurantExceptionEnum; -use Exception; +use App\Entity\Gallery; +use App\Entity\Kitchen; +use App\Entity\Restaurant; +use App\Entity\RestaurantType; +use App\Exception\RestaurantNotFoundException; +use App\Repository\Interface\GalleryRepositoryInterface; +use App\Requests\RestaurantListRequest; use App\Mapper\RestaurantMapper; use App\Model\RestaurantDetailElement; use App\Model\RestaurantList; use App\Repository\Interface\KitchenRepositoryInterface; use App\Repository\Interface\RestaurantRepositoryInterface; use App\Repository\Interface\RestaurantTypeRepositoryInterface; +use Ramsey\Collection\Collection; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Serializer\SerializerInterface; class RestaurantService { + private const DEFAULT_PAGE = 1; + private const DEFAULT_LIMIT = 12; + public function __construct( private RestaurantRepositoryInterface $restaurantRepository, private RestaurantTypeRepositoryInterface $restaurantTypeRepository, private KitchenRepositoryInterface $kitchenRepository, + private GalleryRepositoryInterface $galleryRepository, + private SerializerInterface $serializer, ) {} - public function getRestaurants( - $page, - $limit, - $restaurantTypeId, - $kitchenId): RestaurantList + public function getRestaurantsByRequest(RestaurantListRequest $request): RestaurantList { - $restaurants = $this->restaurantRepository->getAll( - $page, - $limit, - $restaurantTypeId, - $kitchenId); + $page = $request->getRequest()->query->get('page') ?? self::DEFAULT_PAGE; + $limit = $request->getRequest()->query->get('limit') ?? self::DEFAULT_LIMIT; + $restaurantTypeId = $request->getRequest()->query->get('restaurant_type_id'); + $kitchenId = $request->getRequest()->query->get('kitchen_id'); + return $this->getRestaurants( + $page, $limit, $restaurantTypeId, $kitchenId + ); + } + + public function getRestaurants( + int $page, + int $limit, + string|null $restaurantTypeId, + string|null $kitchenId + ): RestaurantList { + $restaurants = new Collection(Restaurant::class, + $this->restaurantRepository->getAll( + $page, + $limit, + $restaurantTypeId, + $kitchenId + ) + ); $count = $this->restaurantRepository->getCount(); - $restaurantTypes = $this->restaurantTypeRepository->getAll(); - $kitchens = $this->kitchenRepository->getAll(); + $restaurantTypes = new Collection(RestaurantType::class, $this->restaurantTypeRepository->getAll()); + $kitchens = new Collection(Kitchen::class, $this->kitchenRepository->getAll()); return RestaurantMapper::mapToRestaurantList( $restaurants, $restaurantTypes, @@ -43,12 +70,27 @@ class RestaurantService ); } - public function getRestaurant(int $id): RestaurantDetailElement + public function getRestaurantByRequest(Request $request): string + { + $restaurantId = $request->get('restaurantId'); + $restaurant = $this->getRestaurant($restaurantId); + return $this->serializer->serialize($restaurant, 'json', [ + 'circular_reference_handler' => function ($object) { + return $object->getId(); + } + ]); + } + + public function getRestaurant(string $id): RestaurantDetailElement { $restaurant = $this->restaurantRepository->getById($id); - if ($restaurant == null) { - throw new Exception("Restaurant not found", RestaurantExceptionEnum::NotFound->value); + if ($restaurant === null) { + throw new RestaurantNotFoundException(); } - return RestaurantMapper::mapToDetailElement($restaurant); + $gallery = new Collection( + Gallery::class, + $this->galleryRepository->getGalleryByRestaurantId($restaurant->getId()) + ); + return RestaurantMapper::mapToDetailElement($restaurant, $gallery); } } \ No newline at end of file -- GitLab