From 2fbe21a032e580606b1d0a91fcca91c46eca177b Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Tue, 23 Apr 2024 14:12:41 +0500 Subject: [PATCH 01/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Model/File.php | 59 +++++++++ src/Model/KitchenType.php | 33 +++++ src/Model/NewsCategory.php | 33 +++++ src/Model/NewsDetailElement.php | 83 ++++++++++++ src/Model/NewsFilterVariants.php | 23 ++++ src/Model/NewsList.php | 40 ++++++ src/Model/NewsListingElement.php | 59 +++++++++ src/Model/Pagination.php | 32 +++++ src/Model/RestaurantDetailElement.php | 175 +++++++++++++++++++++++++ src/Model/RestaurantFilterVariants.php | 33 +++++ src/Model/RestaurantList.php | 40 ++++++ src/Model/RestaurantListingElement.php | 67 ++++++++++ src/Model/RestaurantType.php | 32 +++++ src/Model/Review.php | 53 ++++++++ src/Model/Tag.php | 30 +++++ 15 files changed, 792 insertions(+) create mode 100644 src/Model/File.php create mode 100644 src/Model/KitchenType.php create mode 100644 src/Model/NewsCategory.php create mode 100644 src/Model/NewsDetailElement.php create mode 100644 src/Model/NewsFilterVariants.php create mode 100644 src/Model/NewsList.php create mode 100644 src/Model/NewsListingElement.php create mode 100644 src/Model/Pagination.php create mode 100644 src/Model/RestaurantDetailElement.php create mode 100644 src/Model/RestaurantFilterVariants.php create mode 100644 src/Model/RestaurantList.php create mode 100644 src/Model/RestaurantListingElement.php create mode 100644 src/Model/RestaurantType.php create mode 100644 src/Model/Review.php create mode 100644 src/Model/Tag.php diff --git a/src/Model/File.php b/src/Model/File.php new file mode 100644 index 0000000..2cbf0a7 --- /dev/null +++ b/src/Model/File.php @@ -0,0 +1,59 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->size = $size; + $this->type = $type; + $this->url = $url; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getSize(): int + { + return $this->size; + } + + public function getType(): string + { + return $this->type; + } + + public function getUrl(): string + { + return $this->url; + } +} \ No newline at end of file diff --git a/src/Model/KitchenType.php b/src/Model/KitchenType.php new file mode 100644 index 0000000..b9d532b --- /dev/null +++ b/src/Model/KitchenType.php @@ -0,0 +1,33 @@ +id = $id; + $this->name = $name; + $this->code = $code; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCode(): string + { + return $this->code; + } +} \ No newline at end of file diff --git a/src/Model/NewsCategory.php b/src/Model/NewsCategory.php new file mode 100644 index 0000000..ba1e1a5 --- /dev/null +++ b/src/Model/NewsCategory.php @@ -0,0 +1,33 @@ +id = $id; + $this->name = $name; + $this->code = $code; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCode(): string + { + return $this->code; + } +} \ No newline at end of file diff --git a/src/Model/NewsDetailElement.php b/src/Model/NewsDetailElement.php new file mode 100644 index 0000000..99b3453 --- /dev/null +++ b/src/Model/NewsDetailElement.php @@ -0,0 +1,83 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->text = $text; + $this->image = $image; + $this->createAt = $createAt; + $this->seoTitle = $seoTitle; + $this->seoDescription = $seoDescription; + $this->seoKeywords = $seoKeywords; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getText(): string + { + return $this->text; + } + + public function getImage(): File + { + return $this->image; + } + + public function getCreateAt(): string + { + return $this->createAt; + } + + public function getSeoTitle(): string + { + return $this->seoTitle; + } + + public function getSeoDescription(): string + { + return $this->seoDescription; + } + + public function getSeoKeywords(): string + { + return $this->seoKeywords; + } +} \ No newline at end of file diff --git a/src/Model/NewsFilterVariants.php b/src/Model/NewsFilterVariants.php new file mode 100644 index 0000000..9154ad1 --- /dev/null +++ b/src/Model/NewsFilterVariants.php @@ -0,0 +1,23 @@ + + */ + private Collection $category; + + public function __construct(Collection $category) + { + $this->category = $category; + } + + public function getCategory(): Collection + { + return $this->category; + } +} \ No newline at end of file diff --git a/src/Model/NewsList.php b/src/Model/NewsList.php new file mode 100644 index 0000000..0d53703 --- /dev/null +++ b/src/Model/NewsList.php @@ -0,0 +1,40 @@ + + */ + private Collection $list; + private NewsFilterVariants $filterVariants; + + public function __construct( + Pagination $pagination, + Collection $list, + NewsFilterVariants $filterVariants + ) { + $this->pagination = $pagination; + $this->list = $list; + $this->filterVariants = $filterVariants; + } + + public function getPagination(): Pagination + { + return $this->pagination; + } + + public function getList(): Collection + { + return $this->list; + } + + public function getFilterVariants(): NewsFilterVariants + { + return $this->filterVariants; + } +} \ No newline at end of file diff --git a/src/Model/NewsListingElement.php b/src/Model/NewsListingElement.php new file mode 100644 index 0000000..5134307 --- /dev/null +++ b/src/Model/NewsListingElement.php @@ -0,0 +1,59 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->image = $image; + $this->createAt = $createAt; + $this->detailLink = $detailLink; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getDescription(): string + { + return $this->description; + } + + public function getImage(): File + { + return $this->image; + } + + public function getCreateAt(): string + { + return $this->createAt; + } + + public function getDetailLink(): string + { + return $this->detailLink; + } +} \ No newline at end of file diff --git a/src/Model/Pagination.php b/src/Model/Pagination.php new file mode 100644 index 0000000..31f1221 --- /dev/null +++ b/src/Model/Pagination.php @@ -0,0 +1,32 @@ +currentPage = $currentPage; + $this->pages = $pages; + $this->pageSize = $pageSize; + } + + public function getCurrentPage(): int + { + return $this->currentPage; + } + + public function getPages(): int + { + return $this->pages; + } + + public function getPageSize(): int + { + return $this->pageSize; + } +} \ No newline at end of file diff --git a/src/Model/RestaurantDetailElement.php b/src/Model/RestaurantDetailElement.php new file mode 100644 index 0000000..fc8bbf7 --- /dev/null +++ b/src/Model/RestaurantDetailElement.php @@ -0,0 +1,175 @@ + + */ + private Collection $kitchen; + /** + * @var Collection + */ + private Collection $phone; + /** + * @var Collection + */ + private Collection $email; + /** + * @var Collection + */ + private Collection $address; + /** + * @var Collection + */ + private Collection $tags; + private string $site; + private File $image; + /** + * @var Collection + */ + private Collection $gallery; + private string $seoTitle; + private string $seoDescription; + private string $seoKeywords; + + public function __construct( + int $id, + string $name, + string $code, + string $coordinates, + RestaurantType $type, + string $check, + string $checkInfo, + Collection $kitchen, + Collection $phone, + Collection $email, + Collection $address, + Collection $tags, + string $site, + File $image, + Collection $gallery, + string $seoTitle, + string $seoDescription, + string $seoKeywords + ) { + $this->id = $id; + $this->name = $name; + $this->code = $code; + $this->coordinates = $coordinates; + $this->type = $type; + $this->check = $check; + $this->checkInfo = $checkInfo; + $this->kitchen = $kitchen; + $this->phone = $phone; + $this->email = $email; + $this->address = $address; + $this->tags = $tags; + $this->site = $site; + $this->image = $image; + $this->gallery = $gallery; + $this->seoTitle = $seoTitle; + $this->seoDescription = $seoDescription; + $this->seoKeywords = $seoKeywords; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCode(): string + { + return $this->code; + } + + public function getCoordinates(): string + { + return $this->coordinates; + } + + public function getType(): RestaurantType + { + return $this->type; + } + + public function getCheck(): string + { + return $this->check; + } + + public function getCheckInfo(): string + { + return $this->checkInfo; + } + + public function getKitchen(): Collection + { + return $this->kitchen; + } + + public function getPhone(): Collection + { + return $this->phone; + } + + public function getEmail(): Collection + { + return $this->email; + } + + public function getAddress(): Collection + { + return $this->address; + } + + public function getTags(): Collection + { + return $this->tags; + } + + public function getSite(): string + { + return $this->site; + } + + public function getImage(): File + { + return $this->image; + } + + public function getGallery(): Collection + { + return $this->gallery; + } + + public function getSeoTitle(): string + { + return $this->seoTitle; + } + + public function getSeoDescription(): string + { + return $this->seoDescription; + } + + public function getSeoKeywords(): string + { + return $this->seoKeywords; + } +} \ No newline at end of file diff --git a/src/Model/RestaurantFilterVariants.php b/src/Model/RestaurantFilterVariants.php new file mode 100644 index 0000000..04d31d0 --- /dev/null +++ b/src/Model/RestaurantFilterVariants.php @@ -0,0 +1,33 @@ + + */ + private Collection $type; + /** + * @var Collection + */ + private Collection $kitchen; + + public function __construct(Collection $type, Collection $kitchen) + { + $this->type = $type; + $this->kitchen = $kitchen; + } + + public function getType(): Collection + { + return $this->type; + } + + public function getKitchen(): Collection + { + return $this->kitchen; + } +} \ No newline at end of file diff --git a/src/Model/RestaurantList.php b/src/Model/RestaurantList.php new file mode 100644 index 0000000..28a6630 --- /dev/null +++ b/src/Model/RestaurantList.php @@ -0,0 +1,40 @@ + + */ + private Collection $list; + private RestaurantFilterVariants $filterVariants; + + public function __construct( + Pagination $pagination, + Collection $list, + RestaurantFilterVariants $filterVariants + ) { + $this->pagination = $pagination; + $this->list = $list; + $this->filterVariants = $filterVariants; + } + + public function getPagination(): Pagination + { + return $this->pagination; + } + + public function getList(): Collection + { + return $this->list; + } + + public function getFilterVariants(): RestaurantFilterVariants + { + return $this->filterVariants; + } +} \ No newline at end of file diff --git a/src/Model/RestaurantListingElement.php b/src/Model/RestaurantListingElement.php new file mode 100644 index 0000000..6aeb904 --- /dev/null +++ b/src/Model/RestaurantListingElement.php @@ -0,0 +1,67 @@ +id = $id; + $this->name = $name; + $this->code = $code; + $this->type = $type; + $this->check = $check; + $this->image = $image; + $this->detailLink = $detailLink; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCode(): string + { + return $this->code; + } + + public function getType(): RestaurantType + { + return $this->type; + } + + public function getCheck(): string + { + return $this->check; + } + + public function getImage(): File + { + return $this->image; + } + + public function getDetailLink(): string + { + return $this->detailLink; + } +} \ No newline at end of file diff --git a/src/Model/RestaurantType.php b/src/Model/RestaurantType.php new file mode 100644 index 0000000..a10325b --- /dev/null +++ b/src/Model/RestaurantType.php @@ -0,0 +1,32 @@ +id = $id; + $this->name = $name; + $this->code = $code; + } + + public function getId(): int + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } + + public function getCode(): string + { + return $this->code; + } +} \ No newline at end of file diff --git a/src/Model/Review.php b/src/Model/Review.php new file mode 100644 index 0000000..3af98fd --- /dev/null +++ b/src/Model/Review.php @@ -0,0 +1,53 @@ +id = $id; + $this->date = $date; + $this->score = $score; + $this->text = $text; + $this->userName = $userName; + } + + public function getId(): int + { + return $this->id; + } + + public function getDate(): DateTime + { + return $this->date; + } + + public function getScore(): int + { + return $this->score; + } + + public function getText(): string + { + return $this->text; + } + + public function getUserName(): string + { + return $this->userName; + } +} \ No newline at end of file diff --git a/src/Model/Tag.php b/src/Model/Tag.php new file mode 100644 index 0000000..5c2d1cf --- /dev/null +++ b/src/Model/Tag.php @@ -0,0 +1,30 @@ + + */ + private Collection $list; + + public function __construct(string $name, Collection $list) + { + $this->name = $name; + $this->list = $list; + } + + public function getName(): string + { + return $this->name; + } + + public function getList(): Collection + { + return $this->list; + } +} \ No newline at end of file -- GitLab From e4fe75fa97dbf45fc8447ecaf9526494493bb913 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Wed, 24 Apr 2024 10:36:45 +0500 Subject: [PATCH 02/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- composer.json | 3 + composer.lock | 458 +++++++++++++++++++- config/bundles.php | 2 + docker-compose.yaml | 2 +- migrations/Version20240423071100.php | 103 ----- migrations/Version20240423071601.php | 40 -- src/DataFixtures/AppFixtures.php | 17 + src/DataFixtures/NewsDataFixtures.php | 48 ++ src/DataFixtures/RestaurantDataFixtures.php | 75 ++++ src/Entity/News.php | 6 + src/Entity/NewsCategory.php | 7 +- src/Model/KitchenType.php | 9 +- src/Model/NewsFilterVariants.php | 2 +- src/Model/NewsList.php | 2 +- src/Model/RestaurantDetailElement.php | 2 +- src/Model/RestaurantFilterVariants.php | 2 +- src/Model/RestaurantList.php | 3 +- src/Model/Tag.php | 2 +- src/Repository/KitchenRepository.php | 31 +- src/Repository/RestaurantRepository.php | 31 +- src/Repository/RestaurantTypeRepository.php | 31 +- symfony.lock | 25 ++ 23 files changed, 667 insertions(+), 236 deletions(-) delete mode 100644 migrations/Version20240423071100.php delete mode 100644 migrations/Version20240423071601.php create mode 100644 src/DataFixtures/AppFixtures.php create mode 100644 src/DataFixtures/NewsDataFixtures.php create mode 100644 src/DataFixtures/RestaurantDataFixtures.php diff --git a/.env b/.env index 0a0d6c5..687a18b 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/composer.json b/composer.json index b4e8fa8..fbf9fbc 100644 --- a/composer.json +++ b/composer.json @@ -11,8 +11,10 @@ "doctrine/doctrine-bundle": "^2.12", "doctrine/doctrine-migrations-bundle": "^3.3", "doctrine/orm": "^3.1", + "nelmio/api-doc-bundle": "^4.26", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpdoc-parser": "^1.28", + "ramsey/collection": "^2.0", "symfony/asset": "7.0.*", "symfony/asset-mapper": "7.0.*", "symfony/console": "7.0.*", @@ -97,6 +99,7 @@ } }, "require-dev": { + "doctrine/doctrine-fixtures-bundle": "*", "phpunit/phpunit": "^9.5", "symfony/browser-kit": "7.0.*", "symfony/css-selector": "7.0.*", diff --git a/composer.lock b/composer.lock index 45f3c97..ec268ac 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b1f7459f48c910e2a39af6ee5a9b80eb", + "content-hash": "b57c193bd8eed3bbe092186cd3648c51", "packages": [ { "name": "composer/semver", @@ -1474,6 +1474,121 @@ ], "time": "2024-04-12T21:02:21+00:00" }, + { + "name": "nelmio/api-doc-bundle", + "version": "v4.26.1", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioApiDocBundle.git", + "reference": "2af8c5d55d48c488ef1a650b9ef7133e3c583623" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/2af8c5d55d48c488ef1a650b9ef7133e3c583623", + "reference": "2af8c5d55d48c488ef1a650b9ef7133e3c583623", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.4", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0", + "phpdocumentor/type-resolver": "^1.8.2", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/container": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4.24 || ^6.0 || ^7.0", + "symfony/http-foundation": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/property-info": "^5.4.10 || ^6.0 || ^7.0", + "symfony/routing": "^5.4 || ^6.0 || ^7.0", + "zircote/swagger-php": "^4.6.1" + }, + "conflict": { + "zircote/swagger-php": "4.8.7" + }, + "require-dev": { + "api-platform/core": "^2.7.0 || ^3", + "composer/package-versions-deprecated": "1.11.99.1", + "doctrine/annotations": "^2.0", + "friendsofphp/php-cs-fixer": "^3.52", + "friendsofsymfony/rest-bundle": "^2.8 || ^3.0", + "jms/serializer": "^1.14 || ^3.0", + "jms/serializer-bundle": "^2.3 || ^3.0 || ^4.0 || ^5.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^9.6 || ^10.5", + "symfony/asset": "^5.4 || ^6.0 || ^7.0", + "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/dom-crawler": "^5.4 || ^6.0 || ^7.0", + "symfony/expression-language": "^5.4 || ^6.0 || ^7.0", + "symfony/form": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.4", + "symfony/property-access": "^5.4 || ^6.0 || ^7.0", + "symfony/security-csrf": "^5.4 || ^6.0 || ^7.0", + "symfony/serializer": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/templating": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "willdurand/hateoas-bundle": "^1.0 || ^2.0" + }, + "suggest": { + "api-platform/core": "For using an API oriented framework.", + "doctrine/annotations": "For using doctrine annotations", + "friendsofsymfony/rest-bundle": "For using the parameters annotations.", + "jms/serializer-bundle": "For describing your models.", + "symfony/asset": "For using the Swagger UI.", + "symfony/cache": "For using a PSR-6 compatible cache implementation with the API doc generator.", + "symfony/form": "For describing your form type models.", + "symfony/monolog-bundle": "For using a PSR-3 compatible logger implementation with the API PHP describer.", + "symfony/security-csrf": "For using csrf protection tokens in forms.", + "symfony/serializer": "For describing your models.", + "symfony/twig-bundle": "For using the Swagger UI.", + "symfony/validator": "For describing the validation constraints in your models.", + "willdurand/hateoas-bundle": "For extracting HATEOAS metadata." + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Nelmio\\ApiDocBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors" + } + ], + "description": "Generates documentation for your REST API from annotations and attributes", + "keywords": [ + "api", + "doc", + "documentation", + "rest" + ], + "support": { + "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.26.1" + }, + "time": "2024-04-20T11:19:38+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -2002,6 +2117,95 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "ramsey/collection", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2022-12-31T21:50:55+00:00" + }, { "name": "symfony/asset", "version": "v7.0.3", @@ -7590,9 +7794,261 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "zircote/swagger-php", + "version": "4.9.0", + "source": { + "type": "git", + "url": "https://github.com/zircote/swagger-php.git", + "reference": "b46a36d006f4db4d761995a5add1e7ab0386ed1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/b46a36d006f4db4d761995a5add1e7ab0386ed1d", + "reference": "b46a36d006f4db4d761995a5add1e7ab0386ed1d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.2", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/deprecation-contracts": "^2 || ^3", + "symfony/finder": ">=2.2", + "symfony/yaml": ">=3.3" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11", + "doctrine/annotations": "^1.7 || ^2.0", + "friendsofphp/php-cs-fixer": "^2.17 || ^3.47.1", + "phpstan/phpstan": "^1.6", + "phpunit/phpunit": ">=8", + "vimeo/psalm": "^4.23" + }, + "suggest": { + "doctrine/annotations": "^1.7 || ^2.0" + }, + "bin": [ + "bin/openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "OpenApi\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Robert Allen", + "email": "zircote@gmail.com" + }, + { + "name": "Bob Fanger", + "email": "bfanger@gmail.com", + "homepage": "https://bfanger.nl" + }, + { + "name": "Martin Rademacher", + "email": "mano@radebatz.net", + "homepage": "https://radebatz.net" + } + ], + "description": "swagger-php - Generate interactive documentation for your RESTful API using phpdoc annotations", + "homepage": "https://github.com/zircote/swagger-php/", + "keywords": [ + "api", + "json", + "rest", + "service discovery" + ], + "support": { + "issues": "https://github.com/zircote/swagger-php/issues", + "source": "https://github.com/zircote/swagger-php/tree/4.9.0" + }, + "time": "2024-04-18T22:32:11+00:00" } ], "packages-dev": [ + { + "name": "doctrine/data-fixtures", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/data-fixtures.git", + "reference": "bbcb74f2ac6dbe81a14b3c3687d7623490a0448f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/bbcb74f2ac6dbe81a14b3c3687d7623490a0448f", + "reference": "bbcb74f2ac6dbe81a14b3c3687d7623490a0448f", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^0.5.3 || ^1.0", + "doctrine/persistence": "^2.0|^3.0", + "php": "^7.4 || ^8.0" + }, + "conflict": { + "doctrine/dbal": "<3.5 || >=5", + "doctrine/orm": "<2.14 || >=4", + "doctrine/phpcr-odm": "<1.3.0" + }, + "require-dev": { + "doctrine/annotations": "^1.12 || ^2", + "doctrine/coding-standard": "^12", + "doctrine/dbal": "^3.5 || ^4", + "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0", + "doctrine/orm": "^2.14 || ^3", + "ext-sqlite3": "*", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6.13 || ^10.4.2", + "symfony/cache": "^5.4 || ^6.3 || ^7", + "symfony/var-exporter": "^5.4 || ^6.3 || ^7", + "vimeo/psalm": "^5.9" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)", + "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures", + "doctrine/orm": "For loading ORM fixtures", + "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\DataFixtures\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Data Fixtures for all Doctrine Object Managers", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "database" + ], + "support": { + "issues": "https://github.com/doctrine/data-fixtures/issues", + "source": "https://github.com/doctrine/data-fixtures/tree/1.7.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures", + "type": "tidelift" + } + ], + "time": "2023-11-24T11:18:31+00:00" + }, + { + "name": "doctrine/doctrine-fixtures-bundle", + "version": "3.5.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", + "reference": "c808a0c85c38c8ee265cc8405b456c1d2b38567d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/c808a0c85c38c8ee265cc8405b456c1d2b38567d", + "reference": "c808a0c85c38c8ee265cc8405b456c1d2b38567d", + "shasum": "" + }, + "require": { + "doctrine/data-fixtures": "^1.3", + "doctrine/doctrine-bundle": "^2.2", + "doctrine/orm": "^2.14.0 || ^3.0", + "doctrine/persistence": "^2.4|^3.0", + "php": "^7.4 || ^8.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/doctrine-bridge": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0" + }, + "conflict": { + "doctrine/dbal": "< 3" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10.39", + "phpunit/phpunit": "^9.6.13", + "symfony/phpunit-bridge": "^6.3.6", + "vimeo/psalm": "^5.15" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\FixturesBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Doctrine Project", + "homepage": "https://www.doctrine-project.org" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DoctrineFixturesBundle", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "Fixture", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/DoctrineFixturesBundle/issues", + "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.5.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-fixtures-bundle", + "type": "tidelift" + } + ], + "time": "2023-11-19T12:48:54+00:00" + }, { "name": "masterminds/html5", "version": "2.9.0", diff --git a/config/bundles.php b/config/bundles.php index 4e3a560..deb909d 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -13,4 +13,6 @@ return [ Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], + Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], + Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true], ]; diff --git a/docker-compose.yaml b/docker-compose.yaml index 9a33442..b87becc 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -9,7 +9,7 @@ services: POSTGRES_PASSWORD: 12345 POSTGRES_HOST_AUTH_METHOD: trust ports: - - "${DATABASE_PORT}:${DATABASE_PORT}" + - "5433:${DATABASE_PORT}" networks: - internal nginx: diff --git a/migrations/Version20240423071100.php b/migrations/Version20240423071100.php deleted file mode 100644 index f16e9f8..0000000 --- a/migrations/Version20240423071100.php +++ /dev/null @@ -1,103 +0,0 @@ -addSql('CREATE SEQUENCE address_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE email_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE news_comment_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE news_type_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE phone_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE restaurant_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE SEQUENCE tags_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); - $this->addSql('CREATE TABLE address (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_D4E6F81B1E7706E ON address (restaurant_id)'); - $this->addSql('CREATE TABLE email (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_E7927C74B1E7706E ON email (restaurant_id)'); - $this->addSql('CREATE TABLE news (id UUID NOT NULL, type_id INT NOT NULL, code VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, sort INT NOT NULL, preview_image VARCHAR(255) NOT NULL, detail_image VARCHAR(255) NOT NULL, preview_text TEXT NOT NULL, detail_text TEXT NOT NULL, main_page_render BOOLEAN NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_1DD39950C54C8C93 ON news (type_id)'); - $this->addSql('COMMENT ON COLUMN news.id IS \'(DC2Type:uuid)\''); - $this->addSql('CREATE TABLE news_comment (id INT NOT NULL, news_id_id UUID NOT NULL, moderator_id_id INT NOT NULL, user_id_id INT NOT NULL, moderated BOOLEAN NOT NULL, user_name VARCHAR(255) NOT NULL, text VARCHAR(255) NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE UNIQUE INDEX UNIQ_C3904E8A5FB1909 ON news_comment (news_id_id)'); - $this->addSql('CREATE INDEX IDX_C3904E8ACEB712DF ON news_comment (moderator_id_id)'); - $this->addSql('CREATE INDEX IDX_C3904E8A9D86650F ON news_comment (user_id_id)'); - $this->addSql('COMMENT ON COLUMN news_comment.news_id_id IS \'(DC2Type:uuid)\''); - $this->addSql('CREATE TABLE news_type (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE TABLE phone (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_444F97DDB1E7706E ON phone (restaurant_id)'); - $this->addSql('CREATE TABLE restaurant (id INT NOT NULL, type_id_id INT NOT NULL, settlement_id_id INT NOT NULL, uuid UUID NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, sort INT NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, coordinates TEXT NOT NULL, description TEXT NOT NULL, check_price VARCHAR(255) NOT NULL, check_info TEXT NOT NULL, site VARCHAR(255) NOT NULL, preview_image VARCHAR(255) NOT NULL, detail_image VARCHAR(255) NOT NULL, how_to_find TEXT NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE UNIQUE INDEX UNIQ_EB95123FD17F50A6 ON restaurant (uuid)'); - $this->addSql('CREATE INDEX IDX_EB95123F714819A0 ON restaurant (type_id_id)'); - $this->addSql('CREATE INDEX IDX_EB95123F45EC589B ON restaurant (settlement_id_id)'); - $this->addSql('COMMENT ON COLUMN restaurant.uuid IS \'(DC2Type:uuid)\''); - $this->addSql('COMMENT ON COLUMN restaurant.coordinates IS \'(DC2Type:array)\''); - $this->addSql('CREATE TABLE tags (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); - $this->addSql('CREATE INDEX IDX_6FBC9426B1E7706E ON tags (restaurant_id)'); - $this->addSql('ALTER TABLE address ADD CONSTRAINT FK_D4E6F81B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE email ADD CONSTRAINT FK_E7927C74B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE news ADD CONSTRAINT FK_1DD39950C54C8C93 FOREIGN KEY (type_id) REFERENCES news_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8A5FB1909 FOREIGN KEY (news_id_id) REFERENCES news (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8ACEB712DF FOREIGN KEY (moderator_id_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8A9D86650F FOREIGN KEY (user_id_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE phone ADD CONSTRAINT FK_444F97DDB1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE restaurant ADD CONSTRAINT FK_EB95123F714819A0 FOREIGN KEY (type_id_id) REFERENCES restaurant_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE restaurant ADD CONSTRAINT FK_EB95123F45EC589B FOREIGN KEY (settlement_id_id) REFERENCES settlement (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE tags ADD CONSTRAINT FK_6FBC9426B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE kitchen ADD restaurant_id INT NOT NULL'); - $this->addSql('ALTER TABLE kitchen ADD CONSTRAINT FK_EAA3CE34B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('CREATE INDEX IDX_EAA3CE34B1E7706E ON kitchen (restaurant_id)'); - $this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649D17F50A6 ON "user" (uuid)'); - } - - public function down(Schema $schema): void - { - // this down() migration is auto-generated, please modify it to your needs - $this->addSql('CREATE SCHEMA public'); - $this->addSql('ALTER TABLE kitchen DROP CONSTRAINT FK_EAA3CE34B1E7706E'); - $this->addSql('DROP SEQUENCE address_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE email_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE news_comment_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE news_type_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE phone_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE restaurant_id_seq CASCADE'); - $this->addSql('DROP SEQUENCE tags_id_seq CASCADE'); - $this->addSql('ALTER TABLE address DROP CONSTRAINT FK_D4E6F81B1E7706E'); - $this->addSql('ALTER TABLE email DROP CONSTRAINT FK_E7927C74B1E7706E'); - $this->addSql('ALTER TABLE news DROP CONSTRAINT FK_1DD39950C54C8C93'); - $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8A5FB1909'); - $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8ACEB712DF'); - $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8A9D86650F'); - $this->addSql('ALTER TABLE phone DROP CONSTRAINT FK_444F97DDB1E7706E'); - $this->addSql('ALTER TABLE restaurant DROP CONSTRAINT FK_EB95123F714819A0'); - $this->addSql('ALTER TABLE restaurant DROP CONSTRAINT FK_EB95123F45EC589B'); - $this->addSql('ALTER TABLE tags DROP CONSTRAINT FK_6FBC9426B1E7706E'); - $this->addSql('DROP TABLE address'); - $this->addSql('DROP TABLE email'); - $this->addSql('DROP TABLE news'); - $this->addSql('DROP TABLE news_comment'); - $this->addSql('DROP TABLE news_type'); - $this->addSql('DROP TABLE phone'); - $this->addSql('DROP TABLE restaurant'); - $this->addSql('DROP TABLE tags'); - $this->addSql('DROP INDEX UNIQ_8D93D649D17F50A6'); - $this->addSql('DROP INDEX IDX_EAA3CE34B1E7706E'); - $this->addSql('ALTER TABLE kitchen DROP restaurant_id'); - } -} diff --git a/migrations/Version20240423071601.php b/migrations/Version20240423071601.php deleted file mode 100644 index c8b2ca7..0000000 --- a/migrations/Version20240423071601.php +++ /dev/null @@ -1,40 +0,0 @@ -addSql('CREATE TABLE news_news_category (news_id UUID NOT NULL, news_category_id UUID NOT NULL, PRIMARY KEY(news_id, news_category_id))'); - $this->addSql('CREATE INDEX IDX_1A91D6D6B5A459A0 ON news_news_category (news_id)'); - $this->addSql('CREATE INDEX IDX_1A91D6D63B732BAD ON news_news_category (news_category_id)'); - $this->addSql('COMMENT ON COLUMN news_news_category.news_id IS \'(DC2Type:uuid)\''); - $this->addSql('COMMENT ON COLUMN news_news_category.news_category_id IS \'(DC2Type:uuid)\''); - $this->addSql('ALTER TABLE news_news_category ADD CONSTRAINT FK_1A91D6D6B5A459A0 FOREIGN KEY (news_id) REFERENCES news (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - $this->addSql('ALTER TABLE news_news_category ADD CONSTRAINT FK_1A91D6D63B732BAD FOREIGN KEY (news_category_id) REFERENCES news_category (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); - } - - public function down(Schema $schema): void - { - // this down() migration is auto-generated, please modify it to your needs - $this->addSql('CREATE SCHEMA public'); - $this->addSql('ALTER TABLE news_news_category DROP CONSTRAINT FK_1A91D6D6B5A459A0'); - $this->addSql('ALTER TABLE news_news_category DROP CONSTRAINT FK_1A91D6D63B732BAD'); - $this->addSql('DROP TABLE news_news_category'); - } -} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php new file mode 100644 index 0000000..987f6fe --- /dev/null +++ b/src/DataFixtures/AppFixtures.php @@ -0,0 +1,17 @@ +persist($product); + + $manager->flush(); + } +} diff --git a/src/DataFixtures/NewsDataFixtures.php b/src/DataFixtures/NewsDataFixtures.php new file mode 100644 index 0000000..8b1a01a --- /dev/null +++ b/src/DataFixtures/NewsDataFixtures.php @@ -0,0 +1,48 @@ +setName("Статья"); + $newsCategory = (new NewsCategory()) + ->setId(Uuid::v4()) + ->setName("Культура") + ->setCode("kultura"); + $user = (new User()) + ->setName("Модератор") + ->setUuid(Uuid::v4()); + $news = (new News()) + ->setId(Uuid::v4()) + ->setSort(1) + ->setActive(true) + ->setDetailImage("/upload/news-detail.jpg") + ->setPreviewImage("/upload/news-preview.jpg") + ->setType($newsType) + ->setCreateAt(new DateTime("23-04-2024")) + ->setCode("yamal-museum") + ->setUpdateAt(new DateTime("23-04-2024")) + ->setDetailText("Это самый большой музей на Ямале. Здесь вы найдете всё о жизни региона, традициях и обычаях народов севера и посетите виртуальную выставку, организованную по последнему слову современных технологий.") + ->setMainPageRender(true) + ->setPreviewText("Два часа на знакомство с тысячелетней историей Ямала.") + ->addNewsCategory($newsCategory); + $manager->persist($newsType); + $manager->persist($newsCategory); + $manager->persist($user); + $manager->persist($news); + $manager->flush(); + + } +} \ No newline at end of file diff --git a/src/DataFixtures/RestaurantDataFixtures.php b/src/DataFixtures/RestaurantDataFixtures.php new file mode 100644 index 0000000..8534031 --- /dev/null +++ b/src/DataFixtures/RestaurantDataFixtures.php @@ -0,0 +1,75 @@ +setName("Ресторан") + ->setCode("restoran"); + $settlement = (new Settlement()) + ->setUuid(Uuid::v4()) + ->setName("г. Тюмень") + ->setCode("tyumen") + ->setCoordinates([142, 214]) + ->setCreateAt(new DateTime("02-12-2023")) + ->setUpdateAt(new DateTime("05-12-2023")); + $restaurant = (new Restaurant()) + ->setUuid(Uuid::v4()) + ->setName("Ресторан «Арктика»") + ->setCode("restoran-arktika") + ->setCoordinates([123, 321]) + ->setCreateAt(new DateTime("12-02-2024")) + ->setUpdateAt(new DateTime("09-03-2024")) + ->setActive(true) + ->setCheckPrice("от 1 до 2 || от 1 || до 1000") + ->setCheckInfo("bla bla") + ->setDescription("Описание ресторана Описание ресторана") + ->setHowToFind("Возле набережной") + ->setPreviewImage("/upload/preview.png") + ->setDetailImage("/upload/detail.png") + ->setTypeId($restaurantType) + ->setSettlementId($settlement) + ->setSite("https://visityamal.ru/") + ->setSort(1); + $phone = (new Phone()) + ->setName("7999999999") + ->setRestaurant($restaurant); + $email = (new Email()) + ->setName("test@mail.ru") + ->setRestaurant($restaurant); + $address = (new Address()) + ->setName("ул.Пушкина дом Колотушкина") + ->setRestaurant($restaurant); + $kitchen = (new Kitchen()) + ->setName("Азиатская") + ->setRestaurant($restaurant); + $tags = (new Tags()) + ->setName("тег1") + ->setRestaurant($restaurant); + $manager->persist($restaurantType); + $manager->persist($settlement); + $manager->persist($restaurant); + $manager->persist($phone); + $manager->persist($email); + $manager->persist($address); + $manager->persist($kitchen); + $manager->persist($tags); + $manager->flush(); + } +} \ No newline at end of file diff --git a/src/Entity/News.php b/src/Entity/News.php index a4de9af..092b75e 100644 --- a/src/Entity/News.php +++ b/src/Entity/News.php @@ -66,6 +66,12 @@ class News return $this->id; } + public function setId(?Uuid $id): static + { + $this->id = $id; + return $this; + } + public function getCode(): ?string { return $this->code; diff --git a/src/Entity/NewsCategory.php b/src/Entity/NewsCategory.php index 974a99c..6190e58 100644 --- a/src/Entity/NewsCategory.php +++ b/src/Entity/NewsCategory.php @@ -3,7 +3,6 @@ namespace App\Entity; use App\Repository\NewsCategoryRepository; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\Uuid; @@ -26,6 +25,12 @@ class NewsCategory return $this->id; } + public function setId(?Uuid $id): static + { + $this->id = $id; + return $this; + } + public function getName(): ?string { return $this->name; diff --git a/src/Model/KitchenType.php b/src/Model/KitchenType.php index b9d532b..34e125b 100644 --- a/src/Model/KitchenType.php +++ b/src/Model/KitchenType.php @@ -6,14 +6,12 @@ class KitchenType { private int $id; private string $name; - private string $code; - public function __construct(int $id, string $name, string $code) + public function __construct(int $id, string $name) { $this->id = $id; $this->name = $name; - $this->code = $code; } public function getId(): int @@ -25,9 +23,4 @@ class KitchenType { return $this->name; } - - public function getCode(): string - { - return $this->code; - } } \ No newline at end of file diff --git a/src/Model/NewsFilterVariants.php b/src/Model/NewsFilterVariants.php index 9154ad1..e0a7c97 100644 --- a/src/Model/NewsFilterVariants.php +++ b/src/Model/NewsFilterVariants.php @@ -2,7 +2,7 @@ namespace App\Model; -use Doctrine\Common\Collections\Collection; +use Ramsey\Collection\Collection; class NewsFilterVariants { diff --git a/src/Model/NewsList.php b/src/Model/NewsList.php index 0d53703..ffde5cd 100644 --- a/src/Model/NewsList.php +++ b/src/Model/NewsList.php @@ -2,7 +2,7 @@ namespace App\Model; -use Doctrine\Common\Collections\Collection; +use Ramsey\Collection\Collection; class NewsList { diff --git a/src/Model/RestaurantDetailElement.php b/src/Model/RestaurantDetailElement.php index fc8bbf7..face2bf 100644 --- a/src/Model/RestaurantDetailElement.php +++ b/src/Model/RestaurantDetailElement.php @@ -2,7 +2,7 @@ namespace App\Model; -use Doctrine\Common\Collections\Collection; +use Ramsey\Collection\Collection; class RestaurantDetailElement { diff --git a/src/Model/RestaurantFilterVariants.php b/src/Model/RestaurantFilterVariants.php index 04d31d0..8b158b5 100644 --- a/src/Model/RestaurantFilterVariants.php +++ b/src/Model/RestaurantFilterVariants.php @@ -2,7 +2,7 @@ namespace App\Model; -use Doctrine\Common\Collections\Collection; +use Ramsey\Collection\Collection; class RestaurantFilterVariants { diff --git a/src/Model/RestaurantList.php b/src/Model/RestaurantList.php index 28a6630..4132402 100644 --- a/src/Model/RestaurantList.php +++ b/src/Model/RestaurantList.php @@ -2,7 +2,8 @@ namespace App\Model; -use Doctrine\Common\Collections\Collection; + +use Ramsey\Collection\Collection; class RestaurantList { diff --git a/src/Model/Tag.php b/src/Model/Tag.php index 5c2d1cf..403896e 100644 --- a/src/Model/Tag.php +++ b/src/Model/Tag.php @@ -2,7 +2,7 @@ namespace App\Model; -use phpDocumentor\Reflection\Types\Collection; +use Ramsey\Collection\Collection; class Tag { diff --git a/src/Repository/KitchenRepository.php b/src/Repository/KitchenRepository.php index 745766d..6fef2bc 100644 --- a/src/Repository/KitchenRepository.php +++ b/src/Repository/KitchenRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Kitchen; +use App\Repository\Interface\KitchenRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +15,15 @@ use Doctrine\Persistence\ManagerRegistry; * @method Kitchen[] findAll() * @method Kitchen[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class KitchenRepository extends ServiceEntityRepository +class KitchenRepository extends ServiceEntityRepository implements KitchenRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Kitchen::class); } -// /** -// * @return Kitchen[] Returns an array of Kitchen objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('k') -// ->andWhere('k.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('k.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?Kitchen -// { -// return $this->createQueryBuilder('k') -// ->andWhere('k.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getAll(): array + { + return $this->findAll(); + } } diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 8b5b18d..361489d 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\Restaurant; +use App\Repository\Interface\RestaurantRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +15,15 @@ use Doctrine\Persistence\ManagerRegistry; * @method Restaurant[] findAll() * @method Restaurant[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class RestaurantRepository extends ServiceEntityRepository +class RestaurantRepository extends ServiceEntityRepository implements RestaurantRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Restaurant::class); } -// /** -// * @return Restaurant[] Returns an array of Restaurant objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('r') -// ->andWhere('r.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('r.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?Restaurant -// { -// return $this->createQueryBuilder('r') -// ->andWhere('r.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getAll(): array + { + return $this->findAll(); + } } diff --git a/src/Repository/RestaurantTypeRepository.php b/src/Repository/RestaurantTypeRepository.php index 30e6a42..aa1f621 100644 --- a/src/Repository/RestaurantTypeRepository.php +++ b/src/Repository/RestaurantTypeRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\RestaurantType; +use App\Repository\Interface\RestaurantTypeRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +15,15 @@ use Doctrine\Persistence\ManagerRegistry; * @method RestaurantType[] findAll() * @method RestaurantType[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class RestaurantTypeRepository extends ServiceEntityRepository +class RestaurantTypeRepository extends ServiceEntityRepository implements RestaurantTypeRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, RestaurantType::class); } -// /** -// * @return RestaurantType[] Returns an array of RestaurantType objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('r') -// ->andWhere('r.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('r.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?RestaurantType -// { -// return $this->createQueryBuilder('r') -// ->andWhere('r.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getAll(): array + { + return $this->findAll(); + } } diff --git a/symfony.lock b/symfony.lock index f28d08f..922ad45 100644 --- a/symfony.lock +++ b/symfony.lock @@ -13,6 +13,18 @@ "./src/Repository/.gitignore" ] }, + "doctrine/doctrine-fixtures-bundle": { + "version": "3.5", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "3.0", + "ref": "1f5514cfa15b947298df4d771e694e578d4c204d" + }, + "files": [ + "./src/DataFixtures/AppFixtures.php" + ] + }, "doctrine/doctrine-migrations-bundle": { "version": "3.3", "recipe": { @@ -26,6 +38,19 @@ "./migrations/.gitignore" ] }, + "nelmio/api-doc-bundle": { + "version": "4.26", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "main", + "version": "3.0", + "ref": "c8e0c38e1a280ab9e37587a8fa32b251d5bc1c94" + }, + "files": [ + "./config/packages/nelmio_api_doc.yaml", + "./config/routes/nelmio_api_doc.yaml" + ] + }, "phpunit/phpunit": { "version": "9.6", "recipe": { -- GitLab From fcef8fb71b2bb85d8d896d23ecc467dbf8d891b1 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Wed, 24 Apr 2024 14:03:13 +0500 Subject: [PATCH 03/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/packages/nelmio_api_doc.yaml | 9 ++ config/routes/nelmio_api_doc.yaml | 12 ++ migrations/Version20240424072545.php | 148 ++++++++++++++++++ src/Controller/RestaurantController.php | 38 +++++ src/Mapper/RestaurantMapper.php | 55 +++++++ .../Interface/KitchenRepositoryInterface.php | 8 + .../RestaurantRepositoryInterface.php | 8 + .../RestaurantTypeRepositoryInterface.php | 8 + src/Service/RestaurantService.php | 58 +++++++ 9 files changed, 344 insertions(+) create mode 100644 config/packages/nelmio_api_doc.yaml create mode 100644 config/routes/nelmio_api_doc.yaml create mode 100644 migrations/Version20240424072545.php create mode 100644 src/Controller/RestaurantController.php create mode 100644 src/Mapper/RestaurantMapper.php create mode 100644 src/Repository/Interface/KitchenRepositoryInterface.php create mode 100644 src/Repository/Interface/RestaurantRepositoryInterface.php create mode 100644 src/Repository/Interface/RestaurantTypeRepositoryInterface.php create mode 100644 src/Service/RestaurantService.php diff --git a/config/packages/nelmio_api_doc.yaml b/config/packages/nelmio_api_doc.yaml new file mode 100644 index 0000000..e5eb778 --- /dev/null +++ b/config/packages/nelmio_api_doc.yaml @@ -0,0 +1,9 @@ +nelmio_api_doc: + documentation: + info: + title: Yamal + description: + version: 1.0.0 + areas: # to filter documented areas + path_patterns: + - ^/api/v1 # Accepts routes under /api except /api/doc diff --git a/config/routes/nelmio_api_doc.yaml b/config/routes/nelmio_api_doc.yaml new file mode 100644 index 0000000..f350dd6 --- /dev/null +++ b/config/routes/nelmio_api_doc.yaml @@ -0,0 +1,12 @@ +# Expose your documentation as JSON swagger compliant +app.swagger: + path: /api/doc.json + methods: GET + defaults: { _controller: nelmio_api_doc.controller.swagger } + +## Requires the Asset component and the Twig bundle +## $ composer require twig asset +app.swagger_ui: + path: /api/doc + methods: GET + defaults: { _controller: nelmio_api_doc.controller.swagger_ui } diff --git a/migrations/Version20240424072545.php b/migrations/Version20240424072545.php new file mode 100644 index 0000000..b77fac7 --- /dev/null +++ b/migrations/Version20240424072545.php @@ -0,0 +1,148 @@ +addSql('CREATE SEQUENCE address_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE email_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE kitchen_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE news_comment_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE news_type_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE phone_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE restaurant_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE restaurant_type_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE settlement_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE tags_id_seq INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE SEQUENCE "user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1'); + $this->addSql('CREATE TABLE address (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_D4E6F81B1E7706E ON address (restaurant_id)'); + $this->addSql('CREATE TABLE email (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_E7927C74B1E7706E ON email (restaurant_id)'); + $this->addSql('CREATE TABLE kitchen (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_EAA3CE34B1E7706E ON kitchen (restaurant_id)'); + $this->addSql('CREATE TABLE news (id UUID NOT NULL, type_id INT NOT NULL, code VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, sort INT NOT NULL, preview_image VARCHAR(255) NOT NULL, detail_image VARCHAR(255) NOT NULL, preview_text TEXT NOT NULL, detail_text TEXT NOT NULL, main_page_render BOOLEAN NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_1DD39950C54C8C93 ON news (type_id)'); + $this->addSql('COMMENT ON COLUMN news.id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE news_news_category (news_id UUID NOT NULL, news_category_id UUID NOT NULL, PRIMARY KEY(news_id, news_category_id))'); + $this->addSql('CREATE INDEX IDX_1A91D6D6B5A459A0 ON news_news_category (news_id)'); + $this->addSql('CREATE INDEX IDX_1A91D6D63B732BAD ON news_news_category (news_category_id)'); + $this->addSql('COMMENT ON COLUMN news_news_category.news_id IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN news_news_category.news_category_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE news_category (id UUID NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('COMMENT ON COLUMN news_category.id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE news_comment (id INT NOT NULL, news_id_id UUID NOT NULL, moderator_id_id INT NOT NULL, user_id_id INT NOT NULL, moderated BOOLEAN NOT NULL, user_name VARCHAR(255) NOT NULL, text VARCHAR(255) NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_C3904E8A5FB1909 ON news_comment (news_id_id)'); + $this->addSql('CREATE INDEX IDX_C3904E8ACEB712DF ON news_comment (moderator_id_id)'); + $this->addSql('CREATE INDEX IDX_C3904E8A9D86650F ON news_comment (user_id_id)'); + $this->addSql('COMMENT ON COLUMN news_comment.news_id_id IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE news_type (id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE phone (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_444F97DDB1E7706E ON phone (restaurant_id)'); + $this->addSql('CREATE TABLE restaurant (id INT NOT NULL, type_id_id INT NOT NULL, settlement_id_id INT NOT NULL, uuid UUID NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, active BOOLEAN NOT NULL, sort INT NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, coordinates TEXT NOT NULL, description TEXT NOT NULL, check_price VARCHAR(255) NOT NULL, check_info TEXT NOT NULL, site VARCHAR(255) NOT NULL, preview_image VARCHAR(255) NOT NULL, detail_image VARCHAR(255) NOT NULL, how_to_find TEXT NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_EB95123FD17F50A6 ON restaurant (uuid)'); + $this->addSql('CREATE INDEX IDX_EB95123F714819A0 ON restaurant (type_id_id)'); + $this->addSql('CREATE INDEX IDX_EB95123F45EC589B ON restaurant (settlement_id_id)'); + $this->addSql('COMMENT ON COLUMN restaurant.uuid IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN restaurant.coordinates IS \'(DC2Type:array)\''); + $this->addSql('CREATE TABLE restaurant_type (id INT NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE TABLE settlement (id INT NOT NULL, uuid UUID NOT NULL, name VARCHAR(255) NOT NULL, code VARCHAR(255) NOT NULL, coordinates TEXT NOT NULL, create_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, update_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_DD9F1B51D17F50A6 ON settlement (uuid)'); + $this->addSql('COMMENT ON COLUMN settlement.uuid IS \'(DC2Type:uuid)\''); + $this->addSql('COMMENT ON COLUMN settlement.coordinates IS \'(DC2Type:array)\''); + $this->addSql('CREATE TABLE tags (id INT NOT NULL, restaurant_id INT NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_6FBC9426B1E7706E ON tags (restaurant_id)'); + $this->addSql('CREATE TABLE "user" (id INT NOT NULL, uuid UUID NOT NULL, name VARCHAR(255) NOT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE UNIQUE INDEX UNIQ_8D93D649D17F50A6 ON "user" (uuid)'); + $this->addSql('COMMENT ON COLUMN "user".uuid IS \'(DC2Type:uuid)\''); + $this->addSql('CREATE TABLE messenger_messages (id BIGSERIAL NOT NULL, body TEXT NOT NULL, headers TEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, available_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, delivered_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)'); + $this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)'); + $this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)'); + $this->addSql('COMMENT ON COLUMN messenger_messages.created_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN messenger_messages.available_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('COMMENT ON COLUMN messenger_messages.delivered_at IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('CREATE OR REPLACE FUNCTION notify_messenger_messages() RETURNS TRIGGER AS $$ + BEGIN + PERFORM pg_notify(\'messenger_messages\', NEW.queue_name::text); + RETURN NEW; + END; + $$ LANGUAGE plpgsql;'); + $this->addSql('DROP TRIGGER IF EXISTS notify_trigger ON messenger_messages;'); + $this->addSql('CREATE TRIGGER notify_trigger AFTER INSERT OR UPDATE ON messenger_messages FOR EACH ROW EXECUTE PROCEDURE notify_messenger_messages();'); + $this->addSql('ALTER TABLE address ADD CONSTRAINT FK_D4E6F81B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE email ADD CONSTRAINT FK_E7927C74B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE kitchen ADD CONSTRAINT FK_EAA3CE34B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news ADD CONSTRAINT FK_1DD39950C54C8C93 FOREIGN KEY (type_id) REFERENCES news_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news_news_category ADD CONSTRAINT FK_1A91D6D6B5A459A0 FOREIGN KEY (news_id) REFERENCES news (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news_news_category ADD CONSTRAINT FK_1A91D6D63B732BAD FOREIGN KEY (news_category_id) REFERENCES news_category (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8A5FB1909 FOREIGN KEY (news_id_id) REFERENCES news (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8ACEB712DF FOREIGN KEY (moderator_id_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE news_comment ADD CONSTRAINT FK_C3904E8A9D86650F FOREIGN KEY (user_id_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE phone ADD CONSTRAINT FK_444F97DDB1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE restaurant ADD CONSTRAINT FK_EB95123F714819A0 FOREIGN KEY (type_id_id) REFERENCES restaurant_type (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE restaurant ADD CONSTRAINT FK_EB95123F45EC589B FOREIGN KEY (settlement_id_id) REFERENCES settlement (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('ALTER TABLE tags ADD CONSTRAINT FK_6FBC9426B1E7706E FOREIGN KEY (restaurant_id) REFERENCES restaurant (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE SCHEMA public'); + $this->addSql('DROP SEQUENCE address_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE email_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE kitchen_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE news_comment_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE news_type_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE phone_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE restaurant_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE restaurant_type_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE settlement_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE tags_id_seq CASCADE'); + $this->addSql('DROP SEQUENCE "user_id_seq" CASCADE'); + $this->addSql('ALTER TABLE address DROP CONSTRAINT FK_D4E6F81B1E7706E'); + $this->addSql('ALTER TABLE email DROP CONSTRAINT FK_E7927C74B1E7706E'); + $this->addSql('ALTER TABLE kitchen DROP CONSTRAINT FK_EAA3CE34B1E7706E'); + $this->addSql('ALTER TABLE news DROP CONSTRAINT FK_1DD39950C54C8C93'); + $this->addSql('ALTER TABLE news_news_category DROP CONSTRAINT FK_1A91D6D6B5A459A0'); + $this->addSql('ALTER TABLE news_news_category DROP CONSTRAINT FK_1A91D6D63B732BAD'); + $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8A5FB1909'); + $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8ACEB712DF'); + $this->addSql('ALTER TABLE news_comment DROP CONSTRAINT FK_C3904E8A9D86650F'); + $this->addSql('ALTER TABLE phone DROP CONSTRAINT FK_444F97DDB1E7706E'); + $this->addSql('ALTER TABLE restaurant DROP CONSTRAINT FK_EB95123F714819A0'); + $this->addSql('ALTER TABLE restaurant DROP CONSTRAINT FK_EB95123F45EC589B'); + $this->addSql('ALTER TABLE tags DROP CONSTRAINT FK_6FBC9426B1E7706E'); + $this->addSql('DROP TABLE address'); + $this->addSql('DROP TABLE email'); + $this->addSql('DROP TABLE kitchen'); + $this->addSql('DROP TABLE news'); + $this->addSql('DROP TABLE news_news_category'); + $this->addSql('DROP TABLE news_category'); + $this->addSql('DROP TABLE news_comment'); + $this->addSql('DROP TABLE news_type'); + $this->addSql('DROP TABLE phone'); + $this->addSql('DROP TABLE restaurant'); + $this->addSql('DROP TABLE restaurant_type'); + $this->addSql('DROP TABLE settlement'); + $this->addSql('DROP TABLE tags'); + $this->addSql('DROP TABLE "user"'); + $this->addSql('DROP TABLE messenger_messages'); + } +} diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php new file mode 100644 index 0000000..d1dc2fc --- /dev/null +++ b/src/Controller/RestaurantController.php @@ -0,0 +1,38 @@ +restaurantService->getRestaurants(); + return $this->json($restaurantsList); + } + + +} diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php new file mode 100644 index 0000000..53a7e12 --- /dev/null +++ b/src/Mapper/RestaurantMapper.php @@ -0,0 +1,55 @@ +getId(), + $restaurant->getName(), + $restaurant->getCode(), + new RestaurantTypeModel( + $restaurant->getTypeId()->getId(), + $restaurant->getTypeId()->getName(), + $restaurant->getTypeId()->getCode() + ), + $restaurant->getCheckInfo(), + new File( + 1, + "name", + "description", + 10, + "jpg", + $restaurant->getPreviewImage() + ), + $restaurant->getSite() + ); + } + + public static function mapToRestaurantType(RestaurantType $restaurantType): RestaurantTypeModel + { + return new RestaurantTypeModel( + $restaurantType->getId(), + $restaurantType->getName(), + $restaurantType->getCode(), + ); + } + + public static function mapToKitchenType(Kitchen $kitchen): KitchenType + { + return new KitchenType( + $kitchen->getId(), + $kitchen->getName() + ); + } +} \ No newline at end of file diff --git a/src/Repository/Interface/KitchenRepositoryInterface.php b/src/Repository/Interface/KitchenRepositoryInterface.php new file mode 100644 index 0000000..b93005a --- /dev/null +++ b/src/Repository/Interface/KitchenRepositoryInterface.php @@ -0,0 +1,8 @@ +restaurantRepository->getAll(); + $restaurantTypes = $this->restaurantTypeRepository->getAll(); + $kitchens = $this->kitchenRepository->getAll(); + + return new RestaurantList( + new Pagination(1, floor(count($restaurants)) / 5, 16), + new Collection(RestaurantListingElement::class, array_map( + function (Restaurant $restaurant) { + return RestaurantMapper::mapToListElement($restaurant); + }, $restaurants)), + new RestaurantFilterVariants( + new Collection( + RestaurantTypeModel::class, array_map( + function (RestaurantType $restaurantType) { + return RestaurantMapper::mapToRestaurantType($restaurantType); + }, $restaurantTypes + ) + ), + new Collection( + KitchenType::class, array_map( + function (Kitchen $kitchen) { + return RestaurantMapper::mapToKitchenType($kitchen); + }, $kitchens + ), + ) + ) + ); + } +} \ No newline at end of file -- GitLab From f75396fd908db78e003445bf7ef426df797847bf Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Wed, 24 Apr 2024 17:27:10 +0500 Subject: [PATCH 04/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=B2=D1=82=D0=BE=D1=80=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 1 + composer.lock | 2 +- src/Controller/RestaurantController.php | 58 ++++++++++++++----- src/Mapper/RestaurantMapper.php | 53 ++++++++++++++++- src/Model/RestaurantDetailElement.php | 14 ++--- .../RestaurantRepositoryInterface.php | 8 ++- src/Repository/RestaurantRepository.php | 27 ++++++++- src/Service/RestaurantService.php | 28 +++++++-- 8 files changed, 161 insertions(+), 30 deletions(-) diff --git a/composer.json b/composer.json index fbf9fbc..72f280c 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ "symfony/uid": "7.0.*", "symfony/ux-turbo": "^2.16", "symfony/validator": "6.4.*", + "symfony/var-exporter": "6.4.5", "symfony/web-link": "7.0.*", "symfony/yaml": "7.0.*", "twig/extra-bundle": "^2.12|^3.0", diff --git a/composer.lock b/composer.lock index ec268ac..c4fecf9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b57c193bd8eed3bbe092186cd3648c51", + "content-hash": "814cfe23efd2a11a49bcfec687d342ba", "packages": [ { "name": "composer/semver", diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php index d1dc2fc..9f665fc 100644 --- a/src/Controller/RestaurantController.php +++ b/src/Controller/RestaurantController.php @@ -6,9 +6,11 @@ namespace App\Controller; use App\Service\RestaurantService; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +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; @@ -17,22 +19,50 @@ class RestaurantController extends AbstractController { public function __construct(private RestaurantService $restaurantService) {} - /** - @OA\OpenApi\Response(response=200, description="Листинг ресторанов") - * @OA\Parameter( - * name="page", - * in="query", - * description="Номер страницы", - * @OA\Schema(type="integer") - * ) - * @Model(type=RestaurantList::class) - */ #[Route('/restaurants', name: 'restaurants', methods: ['GET'])] - public function index(int $page): Response + #[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(Request $request): Response { - $restaurantsList = $this->restaurantService->getRestaurants(); + $page = $request->query->getInt('page'); + $limit = $request->query->getInt('limit'); + $restaurantTypeId = $request->query->getInt('restaurant_type_id'); + $kitchenId = $request->query->getInt('kitchen_id'); + $restaurantsList = $this->restaurantService->getRestaurants( + $page, $limit, $restaurantTypeId, $kitchenId + ); return $this->json($restaurantsList); } - + #[Route('/restaurants/{restaurantId}', name: 'restaurant', methods: ['GET'])] + public function restaurant(Request $request): Response + { + $restaurantId = (int)$request->get('restaurantId'); + $restaurant = $this->restaurantService->getRestaurant($restaurantId); + return $this->json($restaurant); + } } diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php index 53a7e12..5f9b6ae 100644 --- a/src/Mapper/RestaurantMapper.php +++ b/src/Mapper/RestaurantMapper.php @@ -2,13 +2,20 @@ namespace App\Mapper; +use App\Entity\Address; +use App\Entity\Email; 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\RestaurantDetailElement; use App\Model\RestaurantListingElement; use App\Model\RestaurantType as RestaurantTypeModel; +use App\Model\Tag; +use Ramsey\Collection\Collection; class RestaurantMapper { @@ -36,12 +43,56 @@ class RestaurantMapper ); } + public static function mapToDetailElement(Restaurant $restaurant): RestaurantDetailElement + { + $file = new File( + 1, + "name", + "description", + 10, + "jpg", + $restaurant->getPreviewImage() + ); + return new RestaurantDetailElement( + $restaurant->getId(), + $restaurant->getName(), + $restaurant->getCode(), + implode(',', $restaurant->getCoordinates()), + //self::mapToRestaurantType($restaurant->getTypeId()), + $restaurant->getCheckPrice(), + $restaurant->getCheckInfo(), + new Collection( + KitchenType::class, array_map( + function (Kitchen $kitchen) { + return self::mapToKitchenType($kitchen); + }, $restaurant->getKitchen()->toArray()), + ), + new Collection(Phone::class, $restaurant->getPhone()->toArray()), + new Collection(Email::class, $restaurant->getEmail()->toArray()), + new Collection(Address::class, $restaurant->getAddress()->toArray()), + new Collection(Tag::class, array_map( + function (Tags $tag) { + return new Tag( + "группа тегов 1", + new Collection($tag->getName()), + ); + }, $restaurant->getTags()->toArray() + )), + $restaurant->getSite(), + $file, + new Collection(File::class, [$file]), + "Отель Арктика", + "otel arktika", + "otel arktika" + ); + } + public static function mapToRestaurantType(RestaurantType $restaurantType): RestaurantTypeModel { return new RestaurantTypeModel( $restaurantType->getId(), $restaurantType->getName(), - $restaurantType->getCode(), + $restaurantType->getCode() ); } diff --git a/src/Model/RestaurantDetailElement.php b/src/Model/RestaurantDetailElement.php index face2bf..01e3e67 100644 --- a/src/Model/RestaurantDetailElement.php +++ b/src/Model/RestaurantDetailElement.php @@ -10,7 +10,7 @@ class RestaurantDetailElement private string $name; private string $code; private string $coordinates; - private RestaurantType $type; + //private RestaurantType $type; private string $check; private string $checkInfo; /** @@ -48,7 +48,7 @@ class RestaurantDetailElement string $name, string $code, string $coordinates, - RestaurantType $type, + //RestaurantType $type, string $check, string $checkInfo, Collection $kitchen, @@ -67,7 +67,7 @@ class RestaurantDetailElement $this->name = $name; $this->code = $code; $this->coordinates = $coordinates; - $this->type = $type; + //$this->type = $type; $this->check = $check; $this->checkInfo = $checkInfo; $this->kitchen = $kitchen; @@ -103,10 +103,10 @@ class RestaurantDetailElement return $this->coordinates; } - public function getType(): RestaurantType - { - return $this->type; - } +// public function getType(): RestaurantType +// { +// return $this->type; +// } public function getCheck(): string { diff --git a/src/Repository/Interface/RestaurantRepositoryInterface.php b/src/Repository/Interface/RestaurantRepositoryInterface.php index f5fa2f2..6bffa21 100644 --- a/src/Repository/Interface/RestaurantRepositoryInterface.php +++ b/src/Repository/Interface/RestaurantRepositoryInterface.php @@ -2,7 +2,13 @@ namespace App\Repository\Interface; +use App\Entity\Restaurant; + interface RestaurantRepositoryInterface { - public function getAll(): array; + public function getAll($page, $limit, $restaurantTypeId, $kitchenId): array; + + public function getCount(): int; + + public function getById(int $id): Restaurant; } \ No newline at end of file diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 361489d..53c0561 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -22,8 +22,31 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant parent::__construct($registry, Restaurant::class); } - public function getAll(): array + public function getAll($page, $limit, $restaurantTypeId, $kitchenId): array { - return $this->findAll(); + $query = $this->createQueryBuilder('r'); + $query->select('r'); + if ($restaurantTypeId !== 0) { + $query->andWhere('r.typeId = :restaurantTypeId') + ->setParameter('restaurantTypeId', $restaurantTypeId); + } + if ($kitchenId !== 0) { + $query->join('r.kitchen', 'k') + ->andWhere('k.id = :kitchenId') + ->setParameter('kitchenId', $kitchenId); + } + $query->setMaxResults($limit) + ->setFirstResult(($page - 1) * $limit); + return $query->getQuery()->getResult(); + } + + public function getCount(): int + { + return $this->count(); + } + + public function getById(int $id): Restaurant + { + return $this->find($id); } } diff --git a/src/Service/RestaurantService.php b/src/Service/RestaurantService.php index d9f26f9..7e1866d 100644 --- a/src/Service/RestaurantService.php +++ b/src/Service/RestaurantService.php @@ -2,12 +2,18 @@ namespace App\Service; +use App\Entity\Address; +use App\Entity\Email; use App\Entity\Kitchen; +use App\Entity\Phone; use App\Entity\Restaurant; use App\Entity\RestaurantType; +use App\Entity\Tags; use App\Mapper\RestaurantMapper; +use App\Model\File; use App\Model\KitchenType; use App\Model\Pagination; +use App\Model\RestaurantDetailElement; use App\Model\RestaurantFilterVariants; use App\Model\RestaurantList; use App\Model\RestaurantListingElement; @@ -25,14 +31,22 @@ class RestaurantService private KitchenRepositoryInterface $kitchenRepository, ) {} - public function getRestaurants(): RestaurantList + public function getRestaurants( + $page, + $limit, + $restaurantTypeId, + $kitchenId): RestaurantList { - $restaurants = $this->restaurantRepository->getAll(); + $restaurants = $this->restaurantRepository->getAll( + $page, + $limit, + $restaurantTypeId, + $kitchenId); + $count = $this->restaurantRepository->getCount(); $restaurantTypes = $this->restaurantTypeRepository->getAll(); $kitchens = $this->kitchenRepository->getAll(); - return new RestaurantList( - new Pagination(1, floor(count($restaurants)) / 5, 16), + new Pagination($page, ceil($count / $limit), $limit), new Collection(RestaurantListingElement::class, array_map( function (Restaurant $restaurant) { return RestaurantMapper::mapToListElement($restaurant); @@ -55,4 +69,10 @@ class RestaurantService ) ); } + + public function getRestaurant(int $id): RestaurantDetailElement + { + $restaurant = $this->restaurantRepository->getById($id); + return RestaurantMapper::mapToDetailElement($restaurant); + } } \ No newline at end of file -- GitLab From ee110a9ad822c5d1fcae4a4018333d846bde24e0 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Fri, 26 Apr 2024 11:57:14 +0500 Subject: [PATCH 05/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB?= =?UTF-8?q?=D0=BB=D0=B5=D1=80=D1=8B=20=D0=B4=D0=BB=D1=8F=20News=20=D0=B8?= =?UTF-8?q?=20=D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- docker-compose.yaml | 4 +- ...24072545.php => Version20240426064235.php} | 2 +- src/Controller/NewsController.php | 55 +++++++++++ src/Controller/RestaurantController.php | 30 ++++-- src/Entity/News.php | 2 +- src/Entity/NewsCategory.php | 3 + src/Entity/Restaurant.php | 6 +- src/Exception/NewsExceptionEnum.php | 8 ++ src/Exception/RestaurantExceptionEnum.php | 8 ++ src/Mapper/NewsMapper.php | 93 +++++++++++++++++++ src/Mapper/RestaurantMapper.php | 79 ++++++++++++++-- src/Model/NewsCategory.php | 8 +- src/Model/NewsDetailElement.php | 8 +- src/Model/NewsListingElement.php | 8 +- src/Model/RestaurantDetailElement.php | 14 +-- .../NewsCategoryRepositoryInterface.php | 8 ++ .../Interface/NewsRepositoryInterface.php | 13 +++ .../RestaurantRepositoryInterface.php | 4 +- src/Repository/NewsCategoryRepository.php | 31 ++----- src/Repository/NewsRepository.php | 59 +++++++----- src/Repository/RestaurantRepository.php | 6 +- src/Requests/NewsListRequest.php | 28 ++++++ src/Requests/RestaurantListRequest.php | 28 ++++++ src/Service/NewsService.php | 48 ++++++++++ src/Service/RestaurantService.php | 48 +++------- 26 files changed, 471 insertions(+), 134 deletions(-) rename migrations/{Version20240424072545.php => Version20240426064235.php} (99%) create mode 100644 src/Controller/NewsController.php create mode 100644 src/Exception/NewsExceptionEnum.php create mode 100644 src/Exception/RestaurantExceptionEnum.php create mode 100644 src/Mapper/NewsMapper.php create mode 100644 src/Repository/Interface/NewsCategoryRepositoryInterface.php create mode 100644 src/Repository/Interface/NewsRepositoryInterface.php create mode 100644 src/Requests/NewsListRequest.php create mode 100644 src/Requests/RestaurantListRequest.php create mode 100644 src/Service/NewsService.php diff --git a/.gitignore b/.gitignore index 930e1e2..f8810d3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ /public/assets/ /assets/vendor/ ###< symfony/asset-mapper ### -/.idea \ No newline at end of file +/.idea +.env +.env.test \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index b87becc..5548380 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -9,7 +9,7 @@ services: POSTGRES_PASSWORD: 12345 POSTGRES_HOST_AUTH_METHOD: trust ports: - - "5433:${DATABASE_PORT}" + - "${DATABASE_PORT}:${DATABASE_PORT}" networks: - internal nginx: @@ -33,8 +33,6 @@ services: APP_BASE_DIR: ${APP_BASE_DIR-.} volumes: - ".:/app" - ports: - - "9000:9000" restart: unless-stopped networks: - internal diff --git a/migrations/Version20240424072545.php b/migrations/Version20240426064235.php similarity index 99% rename from migrations/Version20240424072545.php rename to migrations/Version20240426064235.php index b77fac7..9142542 100644 --- a/migrations/Version20240424072545.php +++ b/migrations/Version20240426064235.php @@ -10,7 +10,7 @@ use Doctrine\Migrations\AbstractMigration; /** * Auto-generated Migration: Please modify to your needs! */ -final class Version20240424072545 extends AbstractMigration +final class Version20240426064235 extends AbstractMigration { public function getDescription(): string { diff --git a/src/Controller/NewsController.php b/src/Controller/NewsController.php new file mode 100644 index 0000000..ae4ea9f --- /dev/null +++ b/src/Controller/NewsController.php @@ -0,0 +1,55 @@ +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); + } + + #[Route('/news/mainNews', name: 'mainNews', methods: ['GET'])] + public function mainNews(): Response + { + $mainNews = $this->newsService->getMainNews(); + return $this->json($mainNews); + } + + #[Route('/news/search', name: 'newsSearch', methods: ['GET'])] + public function newsSearch(): Response + { + $newsSearch = $this->newsService->getNewsSearch(); + return $this->json($newsSearch); + } + + #[Route('/news/{newsId}', name: 'newsOne', methods: ['GET'])] + public function newsOne(Request $request): Response + { + try { + $newsId = $request->get('newsId');; + $news = $this->newsService->getNewsOne($newsId); + return $this->json($news); + } catch (Exception $e) { + return new Response($e->getMessage(), $e->getCode()); + } + } +} diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php index 9f665fc..d6f3983 100644 --- a/src/Controller/RestaurantController.php +++ b/src/Controller/RestaurantController.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Controller; +use App\Requests\RestaurantListRequest; +use Exception; use App\Service\RestaurantService; use Nelmio\ApiDocBundle\Annotation\Model; use OpenApi\Attributes as OA; @@ -13,6 +15,7 @@ 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 @@ -46,12 +49,12 @@ class RestaurantController extends AbstractController schema: new Schema(type: "integer") )] #[Model(type: RestaurantList::class)] - public function restaurants(Request $request): Response + public function restaurants(RestaurantListRequest $request): Response { - $page = $request->query->getInt('page'); - $limit = $request->query->getInt('limit'); - $restaurantTypeId = $request->query->getInt('restaurant_type_id'); - $kitchenId = $request->query->getInt('kitchen_id'); + $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 ); @@ -59,10 +62,19 @@ class RestaurantController extends AbstractController } #[Route('/restaurants/{restaurantId}', name: 'restaurant', methods: ['GET'])] - public function restaurant(Request $request): Response + public function restaurant(Request $request, SerializerInterface $serializer): Response { - $restaurantId = (int)$request->get('restaurantId'); - $restaurant = $this->restaurantService->getRestaurant($restaurantId); - return $this->json($restaurant); + 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()); + } } } diff --git a/src/Entity/News.php b/src/Entity/News.php index 092b75e..3b588b2 100644 --- a/src/Entity/News.php +++ b/src/Entity/News.php @@ -53,7 +53,7 @@ class News /** * @var Collection */ - #[ORM\ManyToMany(targetEntity: NewsCategory::class)] + #[ORM\ManyToMany(targetEntity: NewsCategory::class, inversedBy: "newsCategories")] private Collection $newsCategories; public function __construct() diff --git a/src/Entity/NewsCategory.php b/src/Entity/NewsCategory.php index 6190e58..fa3a554 100644 --- a/src/Entity/NewsCategory.php +++ b/src/Entity/NewsCategory.php @@ -20,6 +20,9 @@ class NewsCategory #[ORM\Column(length: 255)] private ?string $code = null; + #[ORM\ManyToMany(targetEntity: News::class, mappedBy: 'news')] + private Collection $news; + public function getId(): ?Uuid { return $this->id; diff --git a/src/Entity/Restaurant.php b/src/Entity/Restaurant.php index 02fd3b1..a743f1b 100644 --- a/src/Entity/Restaurant.php +++ b/src/Entity/Restaurant.php @@ -41,11 +41,11 @@ class Restaurant #[ORM\Column(type: Types::ARRAY)] private array $coordinates = []; - #[ORM\ManyToOne(inversedBy: 'restaurants')] + #[ORM\ManyToOne(fetch: 'EAGER', inversedBy: 'restaurants')] #[ORM\JoinColumn(nullable: false)] private ?RestaurantType $typeId = null; - #[ORM\ManyToOne(inversedBy: 'restaurants')] + #[ORM\ManyToOne(fetch: 'EAGER', inversedBy: 'restaurants')] #[ORM\JoinColumn(nullable: false)] private ?Settlement $settlementId = null; @@ -67,7 +67,7 @@ class Restaurant /** * @var Collection */ - #[ORM\OneToMany(targetEntity: Phone::class, mappedBy: 'restaurant')] + #[ORM\OneToMany(targetEntity: Phone::class, mappedBy: 'restaurant')] private Collection $phone; /** diff --git a/src/Exception/NewsExceptionEnum.php b/src/Exception/NewsExceptionEnum.php new file mode 100644 index 0000000..6535eff --- /dev/null +++ b/src/Exception/NewsExceptionEnum.php @@ -0,0 +1,8 @@ +getId(), + $newsOne->getPreviewText(), + $newsOne->getDetailText(), + $file, + $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" + ); + } + + public static function mapToNewsCategory(NewsCategory $newsCategory): NewsCategoryModel + { + return new NewsCategoryModel( + $newsCategory->getId(), + $newsCategory->getName(), + $newsCategory->getCode(), + ); + } +} \ No newline at end of file diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php index 5f9b6ae..62bc18a 100644 --- a/src/Mapper/RestaurantMapper.php +++ b/src/Mapper/RestaurantMapper.php @@ -11,7 +11,10 @@ use App\Entity\RestaurantType; use App\Entity\Tags; use App\Model\File; use App\Model\KitchenType; +use App\Model\Pagination; use App\Model\RestaurantDetailElement; +use App\Model\RestaurantFilterVariants; +use App\Model\RestaurantList; use App\Model\RestaurantListingElement; use App\Model\RestaurantType as RestaurantTypeModel; use App\Model\Tag; @@ -19,17 +22,46 @@ use Ramsey\Collection\Collection; class RestaurantMapper { + public static function mapToRestaurantList( + $restaurants, + $restaurantTypes, + $kitchens, + $page, + $limit, + $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)), + new RestaurantFilterVariants( + new Collection( + RestaurantTypeModel::class, array_map( + function (RestaurantType $restaurantType) { + return RestaurantMapper::mapToRestaurantType($restaurantType); + }, $restaurantTypes + ) + ), + new Collection( + KitchenType::class, array_map( + function (Kitchen $kitchen) { + return RestaurantMapper::mapToKitchenType($kitchen); + }, $kitchens + ), + ) + ) + ); + } + public static function mapToListElement(Restaurant $restaurant): RestaurantListingElement { return new RestaurantListingElement( $restaurant->getId(), $restaurant->getName(), $restaurant->getCode(), - new RestaurantTypeModel( - $restaurant->getTypeId()->getId(), - $restaurant->getTypeId()->getName(), - $restaurant->getTypeId()->getCode() - ), + self::mapToRestaurantType($restaurant->getTypeId()), $restaurant->getCheckInfo(), new File( 1, @@ -58,7 +90,7 @@ class RestaurantMapper $restaurant->getName(), $restaurant->getCode(), implode(',', $restaurant->getCoordinates()), - //self::mapToRestaurantType($restaurant->getTypeId()), + self::mapToRestaurantType($restaurant->getTypeId()), $restaurant->getCheckPrice(), $restaurant->getCheckInfo(), new Collection( @@ -67,14 +99,26 @@ class RestaurantMapper return self::mapToKitchenType($kitchen); }, $restaurant->getKitchen()->toArray()), ), - new Collection(Phone::class, $restaurant->getPhone()->toArray()), - new Collection(Email::class, $restaurant->getEmail()->toArray()), - new Collection(Address::class, $restaurant->getAddress()->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($tag->getName()), + new Collection("string", [$tag->getName()]), ); }, $restaurant->getTags()->toArray() )), @@ -103,4 +147,19 @@ class RestaurantMapper $kitchen->getName() ); } + + public static function mapToPhone(Phone $phone): string + { + return $phone->getName(); + } + + public static function mapToEmail(Email $email): string + { + return $email->getName(); + } + + public static function mapToAddress(Address $address): string + { + return $address->getName(); + } } \ No newline at end of file diff --git a/src/Model/NewsCategory.php b/src/Model/NewsCategory.php index ba1e1a5..e22f456 100644 --- a/src/Model/NewsCategory.php +++ b/src/Model/NewsCategory.php @@ -2,21 +2,23 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class NewsCategory { - 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/NewsDetailElement.php b/src/Model/NewsDetailElement.php index 99b3453..c125aae 100644 --- a/src/Model/NewsDetailElement.php +++ b/src/Model/NewsDetailElement.php @@ -2,9 +2,11 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class NewsDetailElement { - private int $id; + private Uuid $id; private string $name; private string $description; private string $text; @@ -15,7 +17,7 @@ class NewsDetailElement private string $seoKeywords; public function __construct( - int $id, + Uuid $id, string $name, string $description, string $text, @@ -36,7 +38,7 @@ class NewsDetailElement $this->seoKeywords = $seoKeywords; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/NewsListingElement.php b/src/Model/NewsListingElement.php index 5134307..dd1b0a0 100644 --- a/src/Model/NewsListingElement.php +++ b/src/Model/NewsListingElement.php @@ -2,9 +2,11 @@ namespace App\Model; +use Symfony\Component\Uid\Uuid; + class NewsListingElement { - private int $id; + private Uuid $id; private string $name; private string $description; private File $image; @@ -12,7 +14,7 @@ class NewsListingElement private string $detailLink; public function __construct( - int $id, + Uuid $id, string $name, string $description, File $image, @@ -27,7 +29,7 @@ class NewsListingElement $this->detailLink = $detailLink; } - public function getId(): int + public function getId(): Uuid { return $this->id; } diff --git a/src/Model/RestaurantDetailElement.php b/src/Model/RestaurantDetailElement.php index 01e3e67..face2bf 100644 --- a/src/Model/RestaurantDetailElement.php +++ b/src/Model/RestaurantDetailElement.php @@ -10,7 +10,7 @@ class RestaurantDetailElement private string $name; private string $code; private string $coordinates; - //private RestaurantType $type; + private RestaurantType $type; private string $check; private string $checkInfo; /** @@ -48,7 +48,7 @@ class RestaurantDetailElement string $name, string $code, string $coordinates, - //RestaurantType $type, + RestaurantType $type, string $check, string $checkInfo, Collection $kitchen, @@ -67,7 +67,7 @@ class RestaurantDetailElement $this->name = $name; $this->code = $code; $this->coordinates = $coordinates; - //$this->type = $type; + $this->type = $type; $this->check = $check; $this->checkInfo = $checkInfo; $this->kitchen = $kitchen; @@ -103,10 +103,10 @@ class RestaurantDetailElement return $this->coordinates; } -// public function getType(): RestaurantType -// { -// return $this->type; -// } + public function getType(): RestaurantType + { + return $this->type; + } public function getCheck(): string { diff --git a/src/Repository/Interface/NewsCategoryRepositoryInterface.php b/src/Repository/Interface/NewsCategoryRepositoryInterface.php new file mode 100644 index 0000000..c2d7e4d --- /dev/null +++ b/src/Repository/Interface/NewsCategoryRepositoryInterface.php @@ -0,0 +1,8 @@ +createQueryBuilder('n') -// ->andWhere('n.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('n.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?NewsCategory -// { -// return $this->createQueryBuilder('n') -// ->andWhere('n.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getAll(): array + { + return $this->findAll(); + } } diff --git a/src/Repository/NewsRepository.php b/src/Repository/NewsRepository.php index 3b5d864..011be28 100644 --- a/src/Repository/NewsRepository.php +++ b/src/Repository/NewsRepository.php @@ -2,7 +2,10 @@ namespace App\Repository; +use App\Exception\NewsExceptionEnum; +use Exception; use App\Entity\News; +use App\Repository\Interface\NewsRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +17,43 @@ use Doctrine\Persistence\ManagerRegistry; * @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); } -// /** -// * @return News[] Returns an array of News objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('n') -// ->andWhere('n.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('n.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } + public function getAll($page, $limit, $newsCategory): array + { + $query = $this->getEntityManager()->createQueryBuilder(); + $query->select('n')->from(News::class, 'n'); + if ($newsCategory !== null) { + $query->join('n.newsCategories', 'nc') + ->andWhere('nc.id = :newsCategory') + ->setParameter('newsCategory', $newsCategory); + } + $query->setMaxResults($limit) + ->setFirstResult(($page - 1) * $limit); + return $query->getQuery()->getResult(); + } + + public function getCount(): int + { + return $this->count(); + } -// public function findOneBySomeField($value): ?News -// { -// return $this->createQueryBuilder('n') -// ->andWhere('n.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } + public function getMainNews(): News + { + return $this->findOneBy(['mainPageRender' => true]); + } + + public function getNewsById(string $newsId): News|null + { + try { + return $this->find(['id' => $newsId]); + } catch (Exception $e) { + throw new Exception("News not found", NewsExceptionEnum::NotFound->value); + } + } } diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 53c0561..0f2061e 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -26,11 +26,11 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant { $query = $this->createQueryBuilder('r'); $query->select('r'); - if ($restaurantTypeId !== 0) { + if ($restaurantTypeId !== null) { $query->andWhere('r.typeId = :restaurantTypeId') ->setParameter('restaurantTypeId', $restaurantTypeId); } - if ($kitchenId !== 0) { + if ($kitchenId !== null) { $query->join('r.kitchen', 'k') ->andWhere('k.id = :kitchenId') ->setParameter('kitchenId', $kitchenId); @@ -45,7 +45,7 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant return $this->count(); } - public function getById(int $id): Restaurant + public function getById(int $id): Restaurant|null { return $this->find($id); } diff --git a/src/Requests/NewsListRequest.php b/src/Requests/NewsListRequest.php new file mode 100644 index 0000000..914a3c8 --- /dev/null +++ b/src/Requests/NewsListRequest.php @@ -0,0 +1,28 @@ +getRequest()->query as $property => $value) { + if (property_exists($this, $property)) { + $this->{$property} = ctype_digit($value) ? (int)$value : $value; + } + } + } +} \ No newline at end of file diff --git a/src/Requests/RestaurantListRequest.php b/src/Requests/RestaurantListRequest.php new file mode 100644 index 0000000..701674d --- /dev/null +++ b/src/Requests/RestaurantListRequest.php @@ -0,0 +1,28 @@ +getRequest()->query as $property => $value) { + if (property_exists($this, $property)) { + $this->{$property} = ctype_digit($value) ? (int)$value : $value; + } + } + } +} \ No newline at end of file diff --git a/src/Service/NewsService.php b/src/Service/NewsService.php new file mode 100644 index 0000000..043d000 --- /dev/null +++ b/src/Service/NewsService.php @@ -0,0 +1,48 @@ +newsRepository->getAll($page, $limit, $newsCategory); + $newsCategories = $this->newsCategoryRepository->getAll(); + $count = $this->newsRepository->getCount(); + return NewsMapper::mapToNewsList($news, $newsCategories, $page, $limit, $count); + } + + public function getMainNews(): NewsListingElement + { + $mainNews = $this->newsRepository->getMainNews(); + return NewsMapper::mapToListingElement($mainNews); + } + + public function getNewsSearch(): NewsDetailElement + { + $mainNews = $this->newsRepository->getMainNews(); + return NewsMapper::mapToDetailElement($mainNews); + } + + public function getNewsOne($newsId): NewsDetailElement + { + $news = $this->newsRepository->getNewsById($newsId); + if ($news == null) { + throw new Exception("News not found", NewsExceptionEnum::NotFound->value); + } + return NewsMapper::mapToDetailElement($news); + } +} \ No newline at end of file diff --git a/src/Service/RestaurantService.php b/src/Service/RestaurantService.php index 7e1866d..8f1a42a 100644 --- a/src/Service/RestaurantService.php +++ b/src/Service/RestaurantService.php @@ -2,26 +2,14 @@ namespace App\Service; -use App\Entity\Address; -use App\Entity\Email; -use App\Entity\Kitchen; -use App\Entity\Phone; -use App\Entity\Restaurant; -use App\Entity\RestaurantType; -use App\Entity\Tags; +use App\Exception\RestaurantExceptionEnum; +use Exception; use App\Mapper\RestaurantMapper; -use App\Model\File; -use App\Model\KitchenType; -use App\Model\Pagination; use App\Model\RestaurantDetailElement; -use App\Model\RestaurantFilterVariants; use App\Model\RestaurantList; -use App\Model\RestaurantListingElement; -use App\Model\RestaurantType as RestaurantTypeModel; use App\Repository\Interface\KitchenRepositoryInterface; use App\Repository\Interface\RestaurantRepositoryInterface; use App\Repository\Interface\RestaurantTypeRepositoryInterface; -use Ramsey\Collection\Collection; class RestaurantService { @@ -45,34 +33,22 @@ class RestaurantService $count = $this->restaurantRepository->getCount(); $restaurantTypes = $this->restaurantTypeRepository->getAll(); $kitchens = $this->kitchenRepository->getAll(); - return new RestaurantList( - new Pagination($page, ceil($count / $limit), $limit), - new Collection(RestaurantListingElement::class, array_map( - function (Restaurant $restaurant) { - return RestaurantMapper::mapToListElement($restaurant); - }, $restaurants)), - new RestaurantFilterVariants( - new Collection( - RestaurantTypeModel::class, array_map( - function (RestaurantType $restaurantType) { - return RestaurantMapper::mapToRestaurantType($restaurantType); - }, $restaurantTypes - ) - ), - new Collection( - KitchenType::class, array_map( - function (Kitchen $kitchen) { - return RestaurantMapper::mapToKitchenType($kitchen); - }, $kitchens - ), - ) - ) + return RestaurantMapper::mapToRestaurantList( + $restaurants, + $restaurantTypes, + $kitchens, + $page, + $limit, + $count ); } public function getRestaurant(int $id): RestaurantDetailElement { $restaurant = $this->restaurantRepository->getById($id); + if ($restaurant == null) { + throw new Exception("Restaurant not found", RestaurantExceptionEnum::NotFound->value); + } return RestaurantMapper::mapToDetailElement($restaurant); } } \ No newline at end of file -- GitLab From 9ef72413552efe05ead5735e46e1a9437030a35c Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Fri, 26 Apr 2024 12:05:46 +0500 Subject: [PATCH 06/15] =?UTF-8?q?STA-966=20|=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20.env=20=D0=B2=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 ++ docker-compose.yaml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 687a18b..1d384c6 100644 --- a/.env +++ b/.env @@ -42,3 +42,5 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 DATABASE_PORT="5432" NGINX_PORT="80" APP_BASE_DIR="./" +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="12345" \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 5548380..b41d486 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,8 +5,8 @@ services: container_name: postgres image: postgres:16.2-alpine environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: 12345 + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_HOST_AUTH_METHOD: trust ports: - "${DATABASE_PORT}:${DATABASE_PORT}" -- GitLab From cc61a9fce98926118e9a2103e3f4cd69511cd9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=B4=D0=BB=D0=B0=D0=BD=20=D0=A8=D0=B0=D0=BC=D0=B0?= =?UTF-8?q?=D0=B2=D0=BE=D0=B2?= Date: Fri, 26 Apr 2024 07:06:26 +0000 Subject: [PATCH 07/15] Delete .env --- .env | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 1d384c6..0000000 --- a/.env +++ /dev/null @@ -1,46 +0,0 @@ -# In all environments, the following files are loaded if they exist, -# the latter taking precedence over the former: -# -# * .env contains default values for the environment variables needed by the app -# * .env.local uncommitted file with local overrides -# * .env.$APP_ENV committed environment-specific defaults -# * .env.$APP_ENV.local uncommitted environment-specific overrides -# -# Real environment variables win over .env files. -# -# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. -# https://symfony.com/doc/current/configuration/secrets.html -# -# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). -# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration - -###> symfony/framework-bundle ### -APP_ENV=dev -APP_SECRET=ea3ebbf899855d483050e0d1aad6a759 -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml -# -# 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@postgres/postgres?serverVersion=16&charset=utf8" -###< doctrine/doctrine-bundle ### - -###> symfony/messenger ### -# Choose one of the transports below -# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages -# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 -###< symfony/messenger ### - -###> symfony/mailer ### -# MAILER_DSN=null://null -###< symfony/mailer ### -DATABASE_PORT="5432" -NGINX_PORT="80" -APP_BASE_DIR="./" -POSTGRES_USER="postgres" -POSTGRES_PASSWORD="12345" \ No newline at end of file -- GitLab From f6d6f500a9b6f726e1920438387946b104fa6ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=B4=D0=BB=D0=B0=D0=BD=20=D0=A8=D0=B0=D0=BC=D0=B0?= =?UTF-8?q?=D0=B2=D0=BE=D0=B2?= Date: Fri, 26 Apr 2024 07:06:33 +0000 Subject: [PATCH 08/15] Delete .env.test --- .env.test | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .env.test diff --git a/.env.test b/.env.test deleted file mode 100644 index 9e7162f..0000000 --- a/.env.test +++ /dev/null @@ -1,6 +0,0 @@ -# define your env variables for the test env here -KERNEL_CLASS='App\Kernel' -APP_SECRET='$ecretf0rt3st' -SYMFONY_DEPRECATIONS_HELPER=999999 -PANTHER_APP_ENV=panther -PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots -- GitLab From 80e92927dd413791b3063210ed4bbac1417e5374 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 13:33:32 +0500 Subject: [PATCH 09/15] =?UTF-8?q?STA-966=20|=20=D0=9E=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=84=D0=B8=D0=BA=D1=81=D1=82=D1=83=D1=80?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataFixtures/RestaurantDataFixtures.php | 44 +++++++++++---------- src/Entity/File.php | 12 +++--- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/DataFixtures/RestaurantDataFixtures.php b/src/DataFixtures/RestaurantDataFixtures.php index 8534031..cdfd692 100644 --- a/src/DataFixtures/RestaurantDataFixtures.php +++ b/src/DataFixtures/RestaurantDataFixtures.php @@ -2,18 +2,17 @@ namespace App\DataFixtures; +use App\Entity\File; +use App\Entity\Gallery; use App\Entity\Restaurant; +use App\Entity\Seo; use App\Entity\Tags; use DateTime; -use App\Entity\Address; -use App\Entity\Email; use App\Entity\Kitchen; -use App\Entity\Phone; use App\Entity\RestaurantType; use App\Entity\Settlement; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; -use Symfony\Component\Uid\Uuid; class RestaurantDataFixtures extends Fixture { @@ -23,14 +22,24 @@ class RestaurantDataFixtures extends Fixture ->setName("Ресторан") ->setCode("restoran"); $settlement = (new Settlement()) - ->setUuid(Uuid::v4()) ->setName("г. Тюмень") ->setCode("tyumen") ->setCoordinates([142, 214]) ->setCreateAt(new DateTime("02-12-2023")) ->setUpdateAt(new DateTime("05-12-2023")); + $seo = (new Seo()) + ->setTitle("Отель Арктика") + ->setDescription("otel-arktika") + ->setKeywords("otel-arktika"); + $file = (new File()) + ->setName("asd") + ->setDescription("Краткое описание") + ->setType("png") + ->setUrl("/upload/asd.png") + ->setSize(1024); + $gallery = (new Gallery()) + ->setFile($file) $restaurant = (new Restaurant()) - ->setUuid(Uuid::v4()) ->setName("Ресторан «Арктика»") ->setCode("restoran-arktika") ->setCoordinates([123, 321]) @@ -46,28 +55,23 @@ class RestaurantDataFixtures extends Fixture ->setTypeId($restaurantType) ->setSettlementId($settlement) ->setSite("https://visityamal.ru/") - ->setSort(1); - $phone = (new Phone()) - ->setName("7999999999") - ->setRestaurant($restaurant); - $email = (new Email()) - ->setName("test@mail.ru") - ->setRestaurant($restaurant); - $address = (new Address()) - ->setName("ул.Пушкина дом Колотушкина") - ->setRestaurant($restaurant); + ->setSort(1) + ->setPhone(["7999999999"]) + ->setEmail(["test@mail.ru"]) + ->setAddress(["ул.Пушкина дом Колотушкина"]) + ->setSeo($seo) + ->addGallery(); $kitchen = (new Kitchen()) ->setName("Азиатская") ->setRestaurant($restaurant); $tags = (new Tags()) - ->setName("тег1") + ->setName("группа тегов 1") + ->setList(["тег1", "тег2"]) ->setRestaurant($restaurant); $manager->persist($restaurantType); + $manager->persist($seo); $manager->persist($settlement); $manager->persist($restaurant); - $manager->persist($phone); - $manager->persist($email); - $manager->persist($address); $manager->persist($kitchen); $manager->persist($tags); $manager->flush(); diff --git a/src/Entity/File.php b/src/Entity/File.php index 712eb87..f75b55d 100644 --- a/src/Entity/File.php +++ b/src/Entity/File.php @@ -34,12 +34,12 @@ class File return $this->id; } - public function setId(Uuid $id): static - { - $this->id = $id; - - return $this; - } +// public function setId(Uuid $id): static +// { +// $this->id = $id; +// +// return $this; +// } public function getName(): ?string { -- GitLab From 785fcbfaff5f641d78cbffc754b2fa68a8cedb23 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 13:50:15 +0500 Subject: [PATCH 10/15] =?UTF-8?q?STA-966=20|=20=D0=9F=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=84=D0=B8=D0=BA=D1=81=D1=82=D1=83?= =?UTF-8?q?=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataFixtures/NewsDataFixtures.php | 23 ++++++++++++++++----- src/DataFixtures/RestaurantDataFixtures.php | 7 +++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/DataFixtures/NewsDataFixtures.php b/src/DataFixtures/NewsDataFixtures.php index 8b1a01a..0b272af 100644 --- a/src/DataFixtures/NewsDataFixtures.php +++ b/src/DataFixtures/NewsDataFixtures.php @@ -2,6 +2,8 @@ namespace App\DataFixtures; +use App\Entity\File; +use App\Entity\Seo; use DateTime; use App\Entity\News; use App\Entity\NewsType; @@ -22,10 +24,18 @@ class NewsDataFixtures extends Fixture ->setName("Культура") ->setCode("kultura"); $user = (new User()) - ->setName("Модератор") - ->setUuid(Uuid::v4()); + ->setName("Модератор"); + $file = (new File()) + ->setName("asd") + ->setDescription("Краткое описание") + ->setType("png") + ->setUrl("/upload/asd.png") + ->setSize(1024); + $seo = (new Seo()) + ->setTitle("Отель Арктика") + ->setDescription("otel-arktika") + ->setKeywords("otel-arktika"); $news = (new News()) - ->setId(Uuid::v4()) ->setSort(1) ->setActive(true) ->setDetailImage("/upload/news-detail.jpg") @@ -37,12 +47,15 @@ class NewsDataFixtures extends Fixture ->setDetailText("Это самый большой музей на Ямале. Здесь вы найдете всё о жизни региона, традициях и обычаях народов севера и посетите виртуальную выставку, организованную по последнему слову современных технологий.") ->setMainPageRender(true) ->setPreviewText("Два часа на знакомство с тысячелетней историей Ямала.") - ->addNewsCategory($newsCategory); + ->addNewsCategory($newsCategory) + ->addFile($file) + ->setSeo($seo); $manager->persist($newsType); + $manager->persist($file); + $manager->persist($seo); $manager->persist($newsCategory); $manager->persist($user); $manager->persist($news); $manager->flush(); - } } \ No newline at end of file diff --git a/src/DataFixtures/RestaurantDataFixtures.php b/src/DataFixtures/RestaurantDataFixtures.php index cdfd692..508dcc8 100644 --- a/src/DataFixtures/RestaurantDataFixtures.php +++ b/src/DataFixtures/RestaurantDataFixtures.php @@ -38,7 +38,7 @@ class RestaurantDataFixtures extends Fixture ->setUrl("/upload/asd.png") ->setSize(1024); $gallery = (new Gallery()) - ->setFile($file) + ->addFile($file); $restaurant = (new Restaurant()) ->setName("Ресторан «Арктика»") ->setCode("restoran-arktika") @@ -60,7 +60,8 @@ class RestaurantDataFixtures extends Fixture ->setEmail(["test@mail.ru"]) ->setAddress(["ул.Пушкина дом Колотушкина"]) ->setSeo($seo) - ->addGallery(); + ->setFile($file) + ->addGallery($gallery); $kitchen = (new Kitchen()) ->setName("Азиатская") ->setRestaurant($restaurant); @@ -70,6 +71,8 @@ class RestaurantDataFixtures extends Fixture ->setRestaurant($restaurant); $manager->persist($restaurantType); $manager->persist($seo); + $manager->persist($file); + $manager->persist($gallery); $manager->persist($settlement); $manager->persist($restaurant); $manager->persist($kitchen); -- GitLab From c3818c60492532ff554a72c29147692b98095dbf Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 13:59:49 +0500 Subject: [PATCH 11/15] =?UTF-8?q?STA-966=20|=20=D0=9F=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=84=D0=B8=D0=BA=D1=81=D1=82=D1=83?= =?UTF-8?q?=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 2 +- src/DataFixtures/NewsDataFixtures.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env b/.env index 679fb18..8c34a32 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@postgres/postgres?serverVersion=16&charset=utf8" +DATABASE_URL="postgresql://postgres:12345@127.0.0.1:5433/postgres?serverVersion=16&charset=utf8" ###< doctrine/doctrine-bundle ### ###> symfony/messenger ### diff --git a/src/DataFixtures/NewsDataFixtures.php b/src/DataFixtures/NewsDataFixtures.php index 0b272af..35f73d9 100644 --- a/src/DataFixtures/NewsDataFixtures.php +++ b/src/DataFixtures/NewsDataFixtures.php @@ -48,7 +48,7 @@ class NewsDataFixtures extends Fixture ->setMainPageRender(true) ->setPreviewText("Два часа на знакомство с тысячелетней историей Ямала.") ->addNewsCategory($newsCategory) - ->addFile($file) + ->setFile($file) ->setSeo($seo); $manager->persist($newsType); $manager->persist($file); -- GitLab From 92a80b0d8206cf083e3ef6dbd499f05af8f147eb Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 14:56:29 +0500 Subject: [PATCH 12/15] =?UTF-8?q?STA-966=20|=20=D0=A4=D0=B8=D0=BA=D1=81?= =?UTF-8?q?=D1=82=D1=83=D1=80=D1=8B=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=D1=8E=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/DataFixtures/NewsDataFixtures.php | 6 +++--- src/DataFixtures/RestaurantDataFixtures.php | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/DataFixtures/NewsDataFixtures.php b/src/DataFixtures/NewsDataFixtures.php index 35f73d9..ccda304 100644 --- a/src/DataFixtures/NewsDataFixtures.php +++ b/src/DataFixtures/NewsDataFixtures.php @@ -4,7 +4,7 @@ namespace App\DataFixtures; use App\Entity\File; use App\Entity\Seo; -use DateTime; +use DateTimeImmutable; use App\Entity\News; use App\Entity\NewsType; use App\Entity\NewsCategory; @@ -41,9 +41,9 @@ class NewsDataFixtures extends Fixture ->setDetailImage("/upload/news-detail.jpg") ->setPreviewImage("/upload/news-preview.jpg") ->setType($newsType) - ->setCreateAt(new DateTime("23-04-2024")) + ->setCreateAt(new DateTimeImmutable("23-04-2024")) ->setCode("yamal-museum") - ->setUpdateAt(new DateTime("23-04-2024")) + ->setUpdateAt(new DateTimeImmutable("23-04-2024")) ->setDetailText("Это самый большой музей на Ямале. Здесь вы найдете всё о жизни региона, традициях и обычаях народов севера и посетите виртуальную выставку, организованную по последнему слову современных технологий.") ->setMainPageRender(true) ->setPreviewText("Два часа на знакомство с тысячелетней историей Ямала.") diff --git a/src/DataFixtures/RestaurantDataFixtures.php b/src/DataFixtures/RestaurantDataFixtures.php index 508dcc8..02d2235 100644 --- a/src/DataFixtures/RestaurantDataFixtures.php +++ b/src/DataFixtures/RestaurantDataFixtures.php @@ -7,7 +7,7 @@ use App\Entity\Gallery; use App\Entity\Restaurant; use App\Entity\Seo; use App\Entity\Tags; -use DateTime; +use DateTimeImmutable; use App\Entity\Kitchen; use App\Entity\RestaurantType; use App\Entity\Settlement; @@ -25,8 +25,8 @@ class RestaurantDataFixtures extends Fixture ->setName("г. Тюмень") ->setCode("tyumen") ->setCoordinates([142, 214]) - ->setCreateAt(new DateTime("02-12-2023")) - ->setUpdateAt(new DateTime("05-12-2023")); + ->setCreateAt(new DateTimeImmutable("02-12-2023")) + ->setUpdateAt(new DateTimeImmutable("05-12-2023")); $seo = (new Seo()) ->setTitle("Отель Арктика") ->setDescription("otel-arktika") @@ -37,14 +37,12 @@ class RestaurantDataFixtures extends Fixture ->setType("png") ->setUrl("/upload/asd.png") ->setSize(1024); - $gallery = (new Gallery()) - ->addFile($file); $restaurant = (new Restaurant()) ->setName("Ресторан «Арктика»") ->setCode("restoran-arktika") ->setCoordinates([123, 321]) - ->setCreateAt(new DateTime("12-02-2024")) - ->setUpdateAt(new DateTime("09-03-2024")) + ->setCreateAt(new DateTimeImmutable("12-02-2024")) + ->setUpdateAt(new DateTimeImmutable("09-03-2024")) ->setActive(true) ->setCheckPrice("от 1 до 2 || от 1 || до 1000") ->setCheckInfo("bla bla") @@ -60,8 +58,10 @@ class RestaurantDataFixtures extends Fixture ->setEmail(["test@mail.ru"]) ->setAddress(["ул.Пушкина дом Колотушкина"]) ->setSeo($seo) + ->setFile($file); + $gallery = (new Gallery()) ->setFile($file) - ->addGallery($gallery); + ->setRestaurant($restaurant); $kitchen = (new Kitchen()) ->setName("Азиатская") ->setRestaurant($restaurant); @@ -72,9 +72,9 @@ class RestaurantDataFixtures extends Fixture $manager->persist($restaurantType); $manager->persist($seo); $manager->persist($file); - $manager->persist($gallery); $manager->persist($settlement); $manager->persist($restaurant); + $manager->persist($gallery); $manager->persist($kitchen); $manager->persist($tags); $manager->flush(); -- GitLab From 0e64a562da7ee739127844fa6f52456fab4c39e5 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 17:51:08 +0500 Subject: [PATCH 13/15] =?UTF-8?q?STA-966=20|=20=D0=9F=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=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 From e67782aa57a8e1840c0249417ca5d3d4f3afe924 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 2 May 2024 18:01:13 +0500 Subject: [PATCH 14/15] Merge branch 'main' into STA-966 --- .env | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/.env b/.env index e69de29..679fb18 100644 --- a/.env +++ b/.env @@ -0,0 +1,46 @@ +# In all environments, the following files are loaded if they exist, +# the latter taking precedence over the former: +# +# * .env contains default values for the environment variables needed by the app +# * .env.local uncommitted file with local overrides +# * .env.$APP_ENV committed environment-specific defaults +# * .env.$APP_ENV.local uncommitted environment-specific overrides +# +# Real environment variables win over .env files. +# +# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. +# https://symfony.com/doc/current/configuration/secrets.html +# +# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). +# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET=ea3ebbf899855d483050e0d1aad6a759 +###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +# 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@postgres/postgres?serverVersion=16&charset=utf8" +###< doctrine/doctrine-bundle ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 +###< symfony/messenger ### + +###> symfony/mailer ### +# MAILER_DSN=null://null +###< symfony/mailer ### +DATABASE_PORT="5433" +NGINX_PORT="80" +APP_BASE_DIR="./" +POSTGRES_USER="postgres" +POSTGRES_PASSWORD="12345" \ No newline at end of file -- GitLab From 819d40f201617bfc36fbca96145ad20c52f74302 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Fri, 3 May 2024 10:39:09 +0500 Subject: [PATCH 15/15] =?UTF-8?q?STA-966=20|=20=D0=A0=D0=B5=D1=84=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/NewsController.php | 19 +++++++----- src/Controller/RestaurantController.php | 8 ++--- src/Mapper/NewsMapper.php | 5 ++-- src/Mapper/RestaurantMapper.php | 24 ++++++++------- src/Repository/RestaurantRepository.php | 7 +++-- src/Service/NewsService.php | 27 +++++++++++------ src/Service/RestaurantService.php | 40 ++++++++++++++----------- 7 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/Controller/NewsController.php b/src/Controller/NewsController.php index 6102cad..12d0a6e 100644 --- a/src/Controller/NewsController.php +++ b/src/Controller/NewsController.php @@ -20,29 +20,34 @@ class NewsController extends AbstractController #[Route('/news', name: 'news', methods: ['GET'])] public function news(NewsListRequest $request): Response { - return $this->json($this->newsService->getNewsByRequest($request)); + return $this->json( + $this->newsService->getNewsByRequest($request) + ); } #[Route('/news/mainNews', name: 'mainNews', methods: ['GET'])] public function mainNews(): Response { - $mainNews = $this->newsService->getMainNews(); - return $this->json($mainNews); + return $this->json( + $this->newsService->getMainNews() + ); } #[Route('/news/search', name: 'newsSearch', methods: ['GET'])] public function newsSearch(): Response { - $newsSearch = $this->newsService->getNewsSearch(); - return $this->json($newsSearch); + return $this->json( + $this->newsService->getNewsSearch() + ); } #[Route('/news/{newsId}', name: 'newsOne', methods: ['GET'])] public function newsOne(Request $request): Response { try { - $news = $this->newsService->getNewsOneByRequest($request); - return $this->json($news); + return $this->json( + $this->newsService->getNewsOneByRequest($request) + ); } catch (NewsNotFoundException $e) { return $this->json([ 'success' => false, diff --git a/src/Controller/RestaurantController.php b/src/Controller/RestaurantController.php index 701ff93..8f842cb 100644 --- a/src/Controller/RestaurantController.php +++ b/src/Controller/RestaurantController.php @@ -20,17 +20,17 @@ class RestaurantController extends AbstractController #[Route('/restaurants', name: 'restaurants', methods: ['GET'])] public function restaurants(RestaurantListRequest $request): Response { - return $this->json($this->restaurantService->getRestaurantsByRequest($request)); + return $this->json( + $this->restaurantService->getRestaurantsByRequest($request) + ); } #[Route('/restaurants/{restaurantId}', name: 'restaurant', methods: ['GET'])] public function restaurant(Request $request): Response { try { - return new Response( + return $this->json( $this->restaurantService->getRestaurantByRequest($request), - Response::HTTP_OK, - ['Content-Type' => 'application/json'] ); } catch (RestaurantNotFoundException $e) { return $this->json([ diff --git a/src/Mapper/NewsMapper.php b/src/Mapper/NewsMapper.php index 420dbf7..4b06e81 100644 --- a/src/Mapper/NewsMapper.php +++ b/src/Mapper/NewsMapper.php @@ -65,8 +65,9 @@ class NewsMapper ); } - public static function mapToNewsCategory(NewsCategory $newsCategory): NewsCategoryModel - { + public static function mapToNewsCategory( + NewsCategory $newsCategory + ): NewsCategoryModel { return new NewsCategoryModel( $newsCategory->getId(), $newsCategory->getName(), diff --git a/src/Mapper/RestaurantMapper.php b/src/Mapper/RestaurantMapper.php index a300f1f..fc72b15 100644 --- a/src/Mapper/RestaurantMapper.php +++ b/src/Mapper/RestaurantMapper.php @@ -44,17 +44,18 @@ class RestaurantMapper ), new Collection( KitchenType::class, array_map( - function (Kitchen $kitchen) { - return self::mapToKitchenType($kitchen); - }, $kitchens->toArray() - ), + function (Kitchen $kitchen) { + return self::mapToKitchenType($kitchen); + }, $kitchens->toArray() + ), ) ) ); } - public static function mapToListElement(Restaurant $restaurant): RestaurantListingElement - { + public static function mapToListElement( + Restaurant $restaurant + ): RestaurantListingElement { return new RestaurantListingElement( $restaurant->getId(), $restaurant->getName(), @@ -66,8 +67,10 @@ class RestaurantMapper ); } - public static function mapToDetailElement(Restaurant $restaurant, Collection $gallery): RestaurantDetailElement - { + public static function mapToDetailElement( + Restaurant $restaurant, + Collection $gallery + ): RestaurantDetailElement { return new RestaurantDetailElement( $restaurant->getId(), $restaurant->getName(), @@ -100,8 +103,9 @@ class RestaurantMapper ); } - public static function mapToRestaurantType(RestaurantType $restaurantType): RestaurantTypeModel - { + public static function mapToRestaurantType( + RestaurantType $restaurantType + ): RestaurantTypeModel { return new RestaurantTypeModel( $restaurantType->getId(), $restaurantType->getName(), diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 6ff1315..3a23833 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -31,17 +31,20 @@ class RestaurantRepository extends ServiceEntityRepository implements Restaurant ): array { $query = $this->createQueryBuilder('r'); $query->select('r'); + if ($restaurantTypeId !== null) { $query->andWhere('r.typeId = :restaurantTypeId') ->setParameter('restaurantTypeId', $restaurantTypeId); } if ($kitchenId !== null) { $query->join('r.kitchen', 'k') - ->andWhere('k.id = :kitchenId') + ->andWhere('k.id = :kitchenId') ->setParameter('kitchenId', $kitchenId); } + $query->setMaxResults($limit) - ->setFirstResult(($page - 1) * $limit); + ->setFirstResult(($page - 1) * $limit); + return $query->getQuery()->getResult(); } diff --git a/src/Service/NewsService.php b/src/Service/NewsService.php index fca6f8a..52bdd28 100644 --- a/src/Service/NewsService.php +++ b/src/Service/NewsService.php @@ -27,9 +27,10 @@ class NewsService public function getNewsByRequest(NewsListRequest $request): NewsList { - $page = $request->getRequest()->query->get('page') ?? self::DEFAULT_PAGE; - $limit = $request->getRequest()->query->get('limit') ?? self::DEFAULT_LIMIT; + $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); } @@ -43,27 +44,34 @@ class NewsService $newsCategory ) ); - $newsCategories = new Collection(NewsCategory::class, $this->newsCategoryRepository->getAll()); + $newsCategories = new Collection( + NewsCategory::class, + $this->newsCategoryRepository->getAll() + ); $count = $this->newsRepository->getCount(); + return NewsMapper::mapToNewsList($news, $newsCategories, $page, $limit, $count); } public function getMainNews(): NewsListingElement { - $mainNews = $this->newsRepository->getMainNews(); - return NewsMapper::mapToListingElement($mainNews); + return NewsMapper::mapToListingElement( + $this->newsRepository->getMainNews() + ); } public function getNewsSearch(): NewsDetailElement { - $mainNews = $this->newsRepository->getMainNews(); - return NewsMapper::mapToDetailElement($mainNews); + return NewsMapper::mapToDetailElement( + $this->newsRepository->getMainNews() + ); } public function getNewsOneByRequest(Request $request): NewsDetailElement { - $newsId = $request->get('newsId'); - return $this->getNewsOne($newsId); + return $this->getNewsOne( + $request->get('newsId') + ); } public function getNewsOne(string $newsId): NewsDetailElement @@ -72,6 +80,7 @@ class NewsService if ($news === null) { throw new NewsNotFoundException(); } + return NewsMapper::mapToDetailElement($news); } } \ No newline at end of file diff --git a/src/Service/RestaurantService.php b/src/Service/RestaurantService.php index 199efb4..23ade59 100644 --- a/src/Service/RestaurantService.php +++ b/src/Service/RestaurantService.php @@ -17,7 +17,6 @@ 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 { @@ -29,15 +28,16 @@ class RestaurantService private RestaurantTypeRepositoryInterface $restaurantTypeRepository, private KitchenRepositoryInterface $kitchenRepository, private GalleryRepositoryInterface $galleryRepository, - private SerializerInterface $serializer, ) {} - public function getRestaurantsByRequest(RestaurantListRequest $request): RestaurantList - { - $page = $request->getRequest()->query->get('page') ?? self::DEFAULT_PAGE; - $limit = $request->getRequest()->query->get('limit') ?? self::DEFAULT_LIMIT; + public function getRestaurantsByRequest( + RestaurantListRequest $request + ): RestaurantList { + $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 ); @@ -49,7 +49,8 @@ class RestaurantService string|null $restaurantTypeId, string|null $kitchenId ): RestaurantList { - $restaurants = new Collection(Restaurant::class, + $restaurants = new Collection( + Restaurant::class, $this->restaurantRepository->getAll( $page, $limit, @@ -58,8 +59,15 @@ class RestaurantService ) ); $count = $this->restaurantRepository->getCount(); - $restaurantTypes = new Collection(RestaurantType::class, $this->restaurantTypeRepository->getAll()); - $kitchens = new Collection(Kitchen::class, $this->kitchenRepository->getAll()); + $restaurantTypes = new Collection( + RestaurantType::class, + $this->restaurantTypeRepository->getAll() + ); + $kitchens = new Collection( + Kitchen::class, + $this->kitchenRepository->getAll() + ); + return RestaurantMapper::mapToRestaurantList( $restaurants, $restaurantTypes, @@ -70,15 +78,11 @@ class RestaurantService ); } - public function getRestaurantByRequest(Request $request): string + public function getRestaurantByRequest(Request $request): RestaurantDetailElement { - $restaurantId = $request->get('restaurantId'); - $restaurant = $this->getRestaurant($restaurantId); - return $this->serializer->serialize($restaurant, 'json', [ - 'circular_reference_handler' => function ($object) { - return $object->getId(); - } - ]); + return $this->getRestaurant( + $request->get('restaurantId') + ); } public function getRestaurant(string $id): RestaurantDetailElement @@ -87,10 +91,12 @@ class RestaurantService if ($restaurant === null) { throw new RestaurantNotFoundException(); } + $gallery = new Collection( Gallery::class, $this->galleryRepository->getGalleryByRestaurantId($restaurant->getId()) ); + return RestaurantMapper::mapToDetailElement($restaurant, $gallery); } } \ No newline at end of file -- GitLab