diff --git a/.env b/.env index 8c34a326a40015c9cdede0156064122ce291bc5f..679fb184e57080a3090e2bf4fa075c8db8ad41fd 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 b4e8fa85c17abe252ced221ed44e24f84c416c69..72f280cdff26c1c1e856b0cc4ce451c0827b89d3 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.*", @@ -41,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", @@ -97,6 +100,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 45f3c979bd82b3a193fdf2cb0843b2728db3ba31..c4fecf9d01c96e8ba34983e105231aa442cb0212 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": "814cfe23efd2a11a49bcfec687d342ba", "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 4e3a56077fb806de5799fe7e82171145e3ce4ff5..deb909d3fbabd31282dfc52cc0e250feb3fe21d7 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/config/packages/nelmio_api_doc.yaml b/config/packages/nelmio_api_doc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e5eb77810479b1316ac7df9735a9cdcc1dbb004f --- /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 0000000000000000000000000000000000000000..f350dd6cf19db43b8a6845c9ec3bd597e8a863e6 --- /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/Version20240426064235.php b/migrations/Version20240426064235.php new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/Controller/NewsController.php b/src/Controller/NewsController.php new file mode 100644 index 0000000000000000000000000000000000000000..12d0a6ebb07be1ed59bf192ee8a1df0e67fcd8df --- /dev/null +++ b/src/Controller/NewsController.php @@ -0,0 +1,58 @@ +json( + $this->newsService->getNewsByRequest($request) + ); + } + + #[Route('/news/mainNews', name: 'mainNews', methods: ['GET'])] + public function mainNews(): Response + { + return $this->json( + $this->newsService->getMainNews() + ); + } + + #[Route('/news/search', name: 'newsSearch', methods: ['GET'])] + public function newsSearch(): Response + { + return $this->json( + $this->newsService->getNewsSearch() + ); + } + + #[Route('/news/{newsId}', name: 'newsOne', methods: ['GET'])] + public function newsOne(Request $request): Response + { + try { + return $this->json( + $this->newsService->getNewsOneByRequest($request) + ); + } 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 new file mode 100644 index 0000000000000000000000000000000000000000..8f842cb2cac290ea6645ee58ffe50422a17844c3 --- /dev/null +++ b/src/Controller/RestaurantController.php @@ -0,0 +1,42 @@ +json( + $this->restaurantService->getRestaurantsByRequest($request) + ); + } + + #[Route('/restaurants/{restaurantId}', name: 'restaurant', methods: ['GET'])] + public function restaurant(Request $request): Response + { + try { + return $this->json( + $this->restaurantService->getRestaurantByRequest($request), + ); + } catch (RestaurantNotFoundException $e) { + return $this->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], $e->getCode()); + } + } +} diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php new file mode 100644 index 0000000000000000000000000000000000000000..987f6fe955c778c958d11e0929d0f2526f821bb1 --- /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 0000000000000000000000000000000000000000..ccda304c9b0aee7b7b0c8d4b1cea6ac614a63f56 --- /dev/null +++ b/src/DataFixtures/NewsDataFixtures.php @@ -0,0 +1,61 @@ +setName("Статья"); + $newsCategory = (new NewsCategory()) + ->setId(Uuid::v4()) + ->setName("Культура") + ->setCode("kultura"); + $user = (new User()) + ->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()) + ->setSort(1) + ->setActive(true) + ->setDetailImage("/upload/news-detail.jpg") + ->setPreviewImage("/upload/news-preview.jpg") + ->setType($newsType) + ->setCreateAt(new DateTimeImmutable("23-04-2024")) + ->setCode("yamal-museum") + ->setUpdateAt(new DateTimeImmutable("23-04-2024")) + ->setDetailText("Это самый большой музей на Ямале. Здесь вы найдете всё о жизни региона, традициях и обычаях народов севера и посетите виртуальную выставку, организованную по последнему слову современных технологий.") + ->setMainPageRender(true) + ->setPreviewText("Два часа на знакомство с тысячелетней историей Ямала.") + ->addNewsCategory($newsCategory) + ->setFile($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 new file mode 100644 index 0000000000000000000000000000000000000000..02d223589fc3f866ae67c91c8e6103cca8af2b4e --- /dev/null +++ b/src/DataFixtures/RestaurantDataFixtures.php @@ -0,0 +1,82 @@ +setName("Ресторан") + ->setCode("restoran"); + $settlement = (new Settlement()) + ->setName("г. Тюмень") + ->setCode("tyumen") + ->setCoordinates([142, 214]) + ->setCreateAt(new DateTimeImmutable("02-12-2023")) + ->setUpdateAt(new DateTimeImmutable("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); + $restaurant = (new Restaurant()) + ->setName("Ресторан «Арктика»") + ->setCode("restoran-arktika") + ->setCoordinates([123, 321]) + ->setCreateAt(new DateTimeImmutable("12-02-2024")) + ->setUpdateAt(new DateTimeImmutable("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) + ->setPhone(["7999999999"]) + ->setEmail(["test@mail.ru"]) + ->setAddress(["ул.Пушкина дом Колотушкина"]) + ->setSeo($seo) + ->setFile($file); + $gallery = (new Gallery()) + ->setFile($file) + ->setRestaurant($restaurant); + $kitchen = (new Kitchen()) + ->setName("Азиатская") + ->setRestaurant($restaurant); + $tags = (new Tags()) + ->setName("группа тегов 1") + ->setList(["тег1", "тег2"]) + ->setRestaurant($restaurant); + $manager->persist($restaurantType); + $manager->persist($seo); + $manager->persist($file); + $manager->persist($settlement); + $manager->persist($restaurant); + $manager->persist($gallery); + $manager->persist($kitchen); + $manager->persist($tags); + $manager->flush(); + } +} \ No newline at end of file diff --git a/src/Entity/File.php b/src/Entity/File.php index cb72c42ce414e8b8e64e73f6ad70e17690965b19..ed9842f43ace877b90cae425682dcaf8db3da226 100644 --- a/src/Entity/File.php +++ b/src/Entity/File.php @@ -37,6 +37,13 @@ class File 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/Entity/News.php b/src/Entity/News.php index 296d6bedeeafdef3749239f7f9a0a578cb9b5fd3..1cca2ff66661a948db65dedc90200d8a477b6716 100644 --- a/src/Entity/News.php +++ b/src/Entity/News.php @@ -56,7 +56,7 @@ class News /** * @var Collection */ - #[ORM\ManyToMany(targetEntity: NewsCategory::class)] + #[ORM\ManyToMany(targetEntity: NewsCategory::class, inversedBy: "newsCategories")] private Collection $newsCategories; #[ORM\ManyToOne] @@ -77,6 +77,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 96ace33c74f3398b13ea96b6f3f45c90e43b86a6..f6aa6b667000a68e9dd8a68f2f8ba04ea0c37745 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\Bridge\Doctrine\Types\UuidType; @@ -24,11 +23,20 @@ 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; } + public function setId(?Uuid $id): static + { + $this->id = $id; + return $this; + } + public function getName(): ?string { return $this->name; diff --git a/src/Entity/Restaurant.php b/src/Entity/Restaurant.php index b7b252c887e488599da94a4637d3b17f60545e58..ff7d311aba42895e808972b04f3ac1dbf2d1e66d 100644 --- a/src/Entity/Restaurant.php +++ b/src/Entity/Restaurant.php @@ -40,11 +40,11 @@ class Restaurant #[ORM\Column(type: 'simple_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; @@ -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 new file mode 100644 index 0000000000000000000000000000000000000000..38c5c28b8508ce83ff0cfbb7c942eb77a7882738 --- /dev/null +++ b/src/Exception/NewsExceptionEnum.php @@ -0,0 +1,10 @@ +value); + } +} \ No newline at end of file diff --git a/src/Exception/RestaurantExceptionEnum.php b/src/Exception/RestaurantExceptionEnum.php new file mode 100644 index 0000000000000000000000000000000000000000..6f3f8fa9871a3d7b68784b85faedb4b7e55018e0 --- /dev/null +++ b/src/Exception/RestaurantExceptionEnum.php @@ -0,0 +1,10 @@ +value); + } +} \ No newline at end of file diff --git a/src/Mapper/FileMapper.php b/src/Mapper/FileMapper.php new file mode 100644 index 0000000000000000000000000000000000000000..f6cd5f7dfcc81d3f188b0a27e84ec4ddeaa27590 --- /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 new file mode 100644 index 0000000000000000000000000000000000000000..4b06e81280f3f341e99e4fc4fc71fadfa960f6d3 --- /dev/null +++ b/src/Mapper/NewsMapper.php @@ -0,0 +1,77 @@ +toArray()) + ), + new NewsFilterVariants( + new Collection(NewsCategoryModel::class, array_map( + function (NewsCategory $newsCategoryOne) { + return self::mapToNewsCategory($newsCategoryOne); + }, $newsCategory->toArray()) + ) + ) + ); + } + + public static function mapToListingElement(News $newsOne): NewsListingElement + { + return new NewsListingElement( + $newsOne->getId(), + $newsOne->getPreviewText(), + $newsOne->getDetailText(), + FileMapper::mapToFile($newsOne->getFile()), + $newsOne->getCreateAt()?->format('d.m.Y'), + "/{$newsOne->getCode()}/code/" + ); + } + + public static function mapToDetailElement(News $newsOne): NewsDetailElement + { + return new NewsDetailElement( + $newsOne->getId(), + $newsOne->getPreviewText(), + $newsOne->getDetailText(), + $newsOne->getDetailText(), + FileMapper::mapToFile($newsOne->getFile()), + $newsOne->getCreateAt()?->format('d.m.Y'), + $newsOne->getSeo()?->getTitle(), + $newsOne->getSeo()?->getDescription(), + $newsOne->getSeo()?->getKeywords() + ); + } + + 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 new file mode 100644 index 0000000000000000000000000000000000000000..fc72b1520568a617d193e7c6712b59f10d28f9e4 --- /dev/null +++ b/src/Mapper/RestaurantMapper.php @@ -0,0 +1,144 @@ +toArray())), + new RestaurantFilterVariants( + new Collection( + RestaurantTypeModel::class, array_map( + function (RestaurantType $restaurantType) { + return self::mapToRestaurantType($restaurantType); + }, $restaurantTypes->toArray() + ) + ), + new Collection( + KitchenType::class, array_map( + function (Kitchen $kitchen) { + return self::mapToKitchenType($kitchen); + }, $kitchens->toArray() + ), + ) + ) + ); + } + + public static function mapToListElement( + Restaurant $restaurant + ): RestaurantListingElement { + return new RestaurantListingElement( + $restaurant->getId(), + $restaurant->getName(), + $restaurant->getCode(), + self::mapToRestaurantType($restaurant->getTypeId()), + $restaurant->getCheckInfo(), + FileMapper::mapToFile($restaurant->getFile()), + $restaurant->getSite() + ); + } + + public static function mapToDetailElement( + Restaurant $restaurant, + Collection $gallery + ): RestaurantDetailElement { + 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("string", $restaurant->getPhone()), + new Collection("string", $restaurant->getEmail()), + new Collection("string", $restaurant->getAddress()), + self::mapToTag( + new Collection( + Tags::class, + $restaurant->getTags()->toArray() + ) + ), + $restaurant->getSite(), + FileMapper::mapToFile($restaurant->getFile()), + self::mapToGallery($gallery), + $restaurant->getSeo()?->getTitle(), + $restaurant->getSeo()?->getDescription(), + $restaurant->getSeo()?->getKeywords() + ); + } + + 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() + ); + } + + public static function mapToTag(Collection $tags): Collection + { + 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 mapToGallery(Collection $gallery): Collection + { + 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 new file mode 100644 index 0000000000000000000000000000000000000000..9d3d006ac2a2ea737d8cd296f6aca5d62f61c672 --- /dev/null +++ b/src/Model/File.php @@ -0,0 +1,61 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->size = $size; + $this->type = $type; + $this->url = $url; + } + + public function getId(): Uuid + { + 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 0000000000000000000000000000000000000000..69640ec0cc7e6caff259fa20795bb4e5e46f1df4 --- /dev/null +++ b/src/Model/KitchenType.php @@ -0,0 +1,27 @@ +id = $id; + $this->name = $name; + } + + public function getId(): Uuid + { + return $this->id; + } + + public function getName(): string + { + return $this->name; + } +} \ No newline at end of file diff --git a/src/Model/NewsCategory.php b/src/Model/NewsCategory.php new file mode 100644 index 0000000000000000000000000000000000000000..e28a9be5dfaeb5ea822a591a3caf3e64400f5e27 --- /dev/null +++ b/src/Model/NewsCategory.php @@ -0,0 +1,34 @@ +id = $id; + $this->name = $name; + $this->code = $code; + } + + public function getId(): Uuid + { + 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 0000000000000000000000000000000000000000..c125aae36ea473d2fc33030e0911719719b9f0c8 --- /dev/null +++ b/src/Model/NewsDetailElement.php @@ -0,0 +1,85 @@ +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(): Uuid + { + 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 0000000000000000000000000000000000000000..e0a7c97c8f67007f5d392df23f195700b59307e5 --- /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 0000000000000000000000000000000000000000..ffde5cd6c3e76be2d775b2a4afb4eb4fb65bd63a --- /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 0000000000000000000000000000000000000000..dd1b0a0a5a87b62434c2dcd2264031dc721da4c5 --- /dev/null +++ b/src/Model/NewsListingElement.php @@ -0,0 +1,61 @@ +id = $id; + $this->name = $name; + $this->description = $description; + $this->image = $image; + $this->createAt = $createAt; + $this->detailLink = $detailLink; + } + + public function getId(): Uuid + { + 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 0000000000000000000000000000000000000000..31f1221e58b7cd195478cec5fa38c5c279d8246b --- /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 0000000000000000000000000000000000000000..f9d90f09519a809d46aef6d7fa109c66da652a8f --- /dev/null +++ b/src/Model/RestaurantDetailElement.php @@ -0,0 +1,176 @@ + + */ + 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( + Uuid $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(): Uuid + { + 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 0000000000000000000000000000000000000000..8b158b5f2434f5178a4f0525d23d4406b92f9d43 --- /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 0000000000000000000000000000000000000000..4132402145f73701e2b5fcad3ea48f7f5636efc3 --- /dev/null +++ b/src/Model/RestaurantList.php @@ -0,0 +1,41 @@ + + */ + 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 0000000000000000000000000000000000000000..d7bb15fd4b97056a69f6eec099f53714c661c888 --- /dev/null +++ b/src/Model/RestaurantListingElement.php @@ -0,0 +1,69 @@ +id = $id; + $this->name = $name; + $this->code = $code; + $this->type = $type; + $this->check = $check; + $this->image = $image; + $this->detailLink = $detailLink; + } + + public function getId(): Uuid + { + 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 0000000000000000000000000000000000000000..e91219d23ea4a287c312205ab196c7b0202541e7 --- /dev/null +++ b/src/Model/RestaurantType.php @@ -0,0 +1,34 @@ +id = $id; + $this->name = $name; + $this->code = $code; + } + + public function getId(): Uuid + { + 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 0000000000000000000000000000000000000000..298e26361c65b8ce42ac5c15ace7c31d40a066c7 --- /dev/null +++ b/src/Model/Review.php @@ -0,0 +1,54 @@ +id = $id; + $this->date = $date; + $this->score = $score; + $this->text = $text; + $this->userName = $userName; + } + + public function getId(): Uuid + { + return $this->id; + } + + public function getDate(): DateTimeImmutable + { + 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 0000000000000000000000000000000000000000..403896eb7d707cd32dbcc4b9280a6d909079c642 --- /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 diff --git a/src/Repository/GalleryRepository.php b/src/Repository/GalleryRepository.php index d15e89a133dcaaebd53199e97f053366e3250b60..b11bc056f6ab52f9db6c1cbbbeb904c2e64b3f58 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 0000000000000000000000000000000000000000..05e96506bc29b56d50e62d36cc940ddad71b4738 --- /dev/null +++ b/src/Repository/Interface/GalleryRepositoryInterface.php @@ -0,0 +1,8 @@ +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/NewsCategoryRepository.php b/src/Repository/NewsCategoryRepository.php index 3a5eeebb501dc92019e437a531fbe0fcbf9d5093..0b0308be8979130b270c3260180dd5c1f0893d49 100644 --- a/src/Repository/NewsCategoryRepository.php +++ b/src/Repository/NewsCategoryRepository.php @@ -3,6 +3,7 @@ namespace App\Repository; use App\Entity\NewsCategory; +use App\Repository\Interface\NewsCategoryRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -14,35 +15,15 @@ use Doctrine\Persistence\ManagerRegistry; * @method NewsCategory[] findAll() * @method NewsCategory[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class NewsCategoryRepository extends ServiceEntityRepository +class NewsCategoryRepository extends ServiceEntityRepository implements NewsCategoryRepositoryInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, NewsCategory::class); } -// /** -// * @return NewsCategory[] Returns an array of NewsCategory 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 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 3b5d8645e9d224f41d8510010eb2ad51d0675722..597484efde1f03a418249fc778da24bcc5ecd6f9 100644 --- a/src/Repository/NewsRepository.php +++ b/src/Repository/NewsRepository.php @@ -2,9 +2,12 @@ namespace App\Repository; +use Exception; use App\Entity\News; +use App\Repository\Interface\NewsRepositoryInterface; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; +use Symfony\Component\Uid\Uuid; /** * @extends ServiceEntityRepository @@ -14,35 +17,44 @@ 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(int $page, int $limit, string|null $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 { + $uuid = new Uuid($newsId); + return $this->find($uuid); + } catch (Exception $e) { + return null; + } + } } diff --git a/src/Repository/RestaurantRepository.php b/src/Repository/RestaurantRepository.php index 8b5b18df316298e7c5f5aed58b29bfcd3da3ae1c..3a23833c0aed436afc3c087a8c01ea53bde11a0e 100644 --- a/src/Repository/RestaurantRepository.php +++ b/src/Repository/RestaurantRepository.php @@ -3,8 +3,10 @@ namespace App\Repository; 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 @@ -14,35 +16,50 @@ 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( + int $page, + int $limit, + string|null $restaurantTypeId, + string|null $kitchenId + ): 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') + ->setParameter('kitchenId', $kitchenId); + } + + $query->setMaxResults($limit) + ->setFirstResult(($page - 1) * $limit); + + return $query->getQuery()->getResult(); + } + + public function getCount(): int + { + return $this->count(); + } + + public function getById(string $id): Restaurant|null + { + try { + $uuid = new Uuid($id); + return $this->find($uuid); + } catch (\Exception $e) { + return null; + } + } } diff --git a/src/Repository/RestaurantTypeRepository.php b/src/Repository/RestaurantTypeRepository.php index 30e6a42d09a2e21561edae74dc89787c2546293e..aa1f62104bf26d4c2efa06d8440f0ee7a4960a72 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/src/Requests/NewsListRequest.php b/src/Requests/NewsListRequest.php new file mode 100644 index 0000000000000000000000000000000000000000..b3d2111b2f18e36a6b536d9402d65496120ef219 --- /dev/null +++ b/src/Requests/NewsListRequest.php @@ -0,0 +1,26 @@ +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 0000000000000000000000000000000000000000..7f940ba2f5c5787f2201f0e66c0a8ba1e7740c01 --- /dev/null +++ b/src/Requests/RestaurantListRequest.php @@ -0,0 +1,26 @@ +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 0000000000000000000000000000000000000000..52bdd28bfe12389a23346e3cc8504649c7c4fdb4 --- /dev/null +++ b/src/Service/NewsService.php @@ -0,0 +1,86 @@ +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(int $page, int $limit, string|null $newsCategory): NewsList + { + $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); + } + + public function getMainNews(): NewsListingElement + { + return NewsMapper::mapToListingElement( + $this->newsRepository->getMainNews() + ); + } + + public function getNewsSearch(): NewsDetailElement + { + return NewsMapper::mapToDetailElement( + $this->newsRepository->getMainNews() + ); + } + + public function getNewsOneByRequest(Request $request): NewsDetailElement + { + return $this->getNewsOne( + $request->get('newsId') + ); + } + + public function getNewsOne(string $newsId): NewsDetailElement + { + $news = $this->newsRepository->getNewsById($newsId); + 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 new file mode 100644 index 0000000000000000000000000000000000000000..23ade5987d82fd50c87649347211d974bc1e5640 --- /dev/null +++ b/src/Service/RestaurantService.php @@ -0,0 +1,102 @@ +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 = new Collection( + RestaurantType::class, + $this->restaurantTypeRepository->getAll() + ); + $kitchens = new Collection( + Kitchen::class, + $this->kitchenRepository->getAll() + ); + + return RestaurantMapper::mapToRestaurantList( + $restaurants, + $restaurantTypes, + $kitchens, + $page, + $limit, + $count + ); + } + + public function getRestaurantByRequest(Request $request): RestaurantDetailElement + { + return $this->getRestaurant( + $request->get('restaurantId') + ); + } + + public function getRestaurant(string $id): RestaurantDetailElement + { + $restaurant = $this->restaurantRepository->getById($id); + 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 diff --git a/symfony.lock b/symfony.lock index f28d08f531406d6b080e5cdc72fd6a610cf26b3f..922ad4558d1cfa9b559ecc709fe527f774c51e80 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": {