From 730a640744c48e22aeee5e4069c6b04336ee78e0 Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:30:41 +0100 Subject: [PATCH 01/32] chore: update deps --- composer.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 9251be4..91d2b59 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require" : { "php" : ">=8.1", "ext-json": "*", - "thecodingmachine/graphqlite" : "^6.0", + "thecodingmachine/graphqlite" : "^7.0", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", @@ -28,7 +28,7 @@ "doctrine/annotations": "^1.13 || ^2.0.1", "symfony/psr-http-message-bridge": "^2.0 || ^7.0", "nyholm/psr7": "^1.1", - "laminas/laminas-diactoros": "^2.2.2", + "laminas/laminas-diactoros": "^2.2.2 || ^3.0", "overblog/graphiql-bundle": "^0.2 || ^0.3 || ^1", "thecodingmachine/cache-utils": "^1" }, @@ -60,6 +60,12 @@ "TheCodingMachine\\GraphQLite\\Bundle\\" : "" } }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/fogrye/graphqlite-symfony-validator-bridge.git" + } + ], "extra": { "branch-alias": { "dev-master": "6.0.x-dev" From c6fdb1ad4e34bb85e8b19615f7c27b83bf45e568 Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:31:26 +0100 Subject: [PATCH 02/32] fix: replace ClassNameMapper with Finder --- .../GraphQLiteCompilerPass.php | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/DependencyInjection/GraphQLiteCompilerPass.php b/DependencyInjection/GraphQLiteCompilerPass.php index bee4783..af4b9dd 100644 --- a/DependencyInjection/GraphQLiteCompilerPass.php +++ b/DependencyInjection/GraphQLiteCompilerPass.php @@ -4,10 +4,12 @@ namespace TheCodingMachine\GraphQLite\Bundle\DependencyInjection; use Doctrine\Common\Annotations\PsrCachedReader; +use Generator; use GraphQL\Server\ServerConfig; use GraphQL\Validator\Rules\DisableIntrospection; use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\Rules\QueryDepth; +use Kcs\ClassFinder\Finder\ComposerFinder; use ReflectionNamedType; use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; @@ -19,7 +21,6 @@ use function class_exists; use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; -use Mouf\Composer\ClassNameMapper; use Psr\SimpleCache\CacheInterface; use ReflectionParameter; use function filter_var; @@ -40,7 +41,6 @@ use TheCodingMachine\CacheUtils\ClassBoundCacheContractInterface; use TheCodingMachine\CacheUtils\ClassBoundMemoryAdapter; use TheCodingMachine\CacheUtils\FileBoundCache; -use TheCodingMachine\ClassExplorer\Glob\GlobClassExplorer; use TheCodingMachine\GraphQLite\AggregateControllerQueryProviderFactory; use TheCodingMachine\GraphQLite\AnnotationReader; use TheCodingMachine\GraphQLite\Annotations\Autowire; @@ -479,34 +479,18 @@ private function getCodeCache(): ClassBoundCacheContractInterface * Returns the array of globbed classes. * Only instantiable classes are returned. * - * @return array> Key: fully qualified class name + * @param string $namespace + * @return array>|Generator Key: fully qualified class name */ - private function getClassList(string $namespace, int $globTtl = 2, bool $recursive = true): array + private function getClassList(string $namespace): array|Generator { - $explorer = new GlobClassExplorer($namespace, $this->getPsr16Cache(), $globTtl, ClassNameMapper::createFromComposerFile(null, null, true), $recursive); - $allClasses = $explorer->getClassMap(); - $classes = []; - foreach ($allClasses as $className => $phpFile) { - if (! class_exists($className, false)) { - // Let's try to load the file if it was not imported yet. - // We are importing the file manually to avoid triggering the autoloader. - // The autoloader might trigger errors if the file does not respect PSR-4 or if the - // Symfony DebugAutoLoader is installed. (see https://github.com/thecodingmachine/graphqlite/issues/216) - require_once $phpFile; - // @phpstan-ignore-next-line Does it exist now? - if (! class_exists($className, false)) { - continue; - } - } - - $refClass = new ReflectionClass($className); - if (! $refClass->isInstantiable()) { + $finder = new ComposerFinder(); + foreach ($finder->inNamespace($namespace) as $class) { + if (!$class instanceof ReflectionClass){ continue; } - $classes[$className] = $refClass; + yield $class->getName() => $class; } - - return $classes; } } From 830af6a3648c50324a0d75cb5bce85a79ce0f31b Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:21:18 +0100 Subject: [PATCH 03/32] fix: namespace should not end with \ --- DependencyInjection/GraphQLiteExtension.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/GraphQLiteExtension.php b/DependencyInjection/GraphQLiteExtension.php index 8fa97ce..a6b4b10 100644 --- a/DependencyInjection/GraphQLiteExtension.php +++ b/DependencyInjection/GraphQLiteExtension.php @@ -43,7 +43,7 @@ public function load(array $configs, ContainerBuilder $container): void } $namespaceController = array_map( function($namespace): string { - return rtrim($namespace, '\\') . '\\'; + return rtrim($namespace, '\\'); }, $controllers ); @@ -57,7 +57,7 @@ function($namespace): string { } $namespaceType = array_map( function($namespace): string { - return rtrim($namespace, '\\') . '\\'; + return rtrim($namespace, '\\'); }, $types ); From 574677ed72fa63be55bb070a89b025378451e916 Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:24:55 +0100 Subject: [PATCH 04/32] rm fork --- composer.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/composer.json b/composer.json index 91d2b59..db0beb8 100644 --- a/composer.json +++ b/composer.json @@ -60,12 +60,6 @@ "TheCodingMachine\\GraphQLite\\Bundle\\" : "" } }, - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/fogrye/graphqlite-symfony-validator-bridge.git" - } - ], "extra": { "branch-alias": { "dev-master": "6.0.x-dev" From 523f2672b8da3dcd54f9d74b1443087c638dd7b8 Mon Sep 17 00:00:00 2001 From: Yurii <141632421+fogrye@users.noreply.github.com> Date: Fri, 29 Mar 2024 14:34:44 +0100 Subject: [PATCH 05/32] Update composer.json Co-authored-by: homersimpsons --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index db0beb8..20ea4d9 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,6 @@ "composer/semver": "^3.4" }, "conflict": { - "mouf/classname-mapper": "<1.0.2", "symfony/event-dispatcher": "<4.3", "symfony/security-core": "<4.3", "symfony/routing": "<4.3", From 2965602a13e473efc75dc9dee8587aa9161d78c9 Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Fri, 29 Mar 2024 16:09:45 +0100 Subject: [PATCH 06/32] fix: typing --- DependencyInjection/GraphQLiteCompilerPass.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DependencyInjection/GraphQLiteCompilerPass.php b/DependencyInjection/GraphQLiteCompilerPass.php index af4b9dd..691dff5 100644 --- a/DependencyInjection/GraphQLiteCompilerPass.php +++ b/DependencyInjection/GraphQLiteCompilerPass.php @@ -480,9 +480,9 @@ private function getCodeCache(): ClassBoundCacheContractInterface * Only instantiable classes are returned. * * @param string $namespace - * @return array>|Generator Key: fully qualified class name + * @return Generator, void, void> */ - private function getClassList(string $namespace): array|Generator + private function getClassList(string $namespace): Generator { $finder = new ComposerFinder(); foreach ($finder->inNamespace($namespace) as $class) { From 5a05d3a509b5e4ff94413b0d3df2f57592ac9a7e Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Fri, 29 Mar 2024 18:04:24 +0100 Subject: [PATCH 07/32] fix: assertion --- DependencyInjection/GraphQLiteCompilerPass.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/DependencyInjection/GraphQLiteCompilerPass.php b/DependencyInjection/GraphQLiteCompilerPass.php index 691dff5..a13be84 100644 --- a/DependencyInjection/GraphQLiteCompilerPass.php +++ b/DependencyInjection/GraphQLiteCompilerPass.php @@ -486,9 +486,7 @@ private function getClassList(string $namespace): Generator { $finder = new ComposerFinder(); foreach ($finder->inNamespace($namespace) as $class) { - if (!$class instanceof ReflectionClass){ - continue; - } + assert($class instanceof ReflectionClass); yield $class->getName() => $class; } } From d9e86ce38720dd7eb349a7e047a45de469b0e263 Mon Sep 17 00:00:00 2001 From: Yurii Kuvshynov <141632421+fogrye@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:45:35 +0200 Subject: [PATCH 08/32] chore: correct validator version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 20ea4d9..dfa18b3 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "php" : ">=8.1", "ext-json": "*", "thecodingmachine/graphqlite" : "^7.0", - "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0", + "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", "symfony/framework-bundle": "^6.4 || ^7", From f00dd6c4d2e97b81a9bb9ab226dbd34779496fb4 Mon Sep 17 00:00:00 2001 From: Yurii <141632421+fogrye@users.noreply.github.com> Date: Sat, 4 May 2024 10:46:45 +0200 Subject: [PATCH 09/32] chore: bump php version to satisfy symfony packages --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dfa18b3..7a11226 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require" : { - "php" : ">=8.1", + "php" : ">=8.2", "ext-json": "*", "thecodingmachine/graphqlite" : "^7.0", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", From f6aac0e33ac26184ee81b5a28caeab3819155644 Mon Sep 17 00:00:00 2001 From: Yurii <141632421+fogrye@users.noreply.github.com> Date: Sun, 5 May 2024 10:57:51 +0200 Subject: [PATCH 10/32] fix(ci): bump ci php version --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 94e9a36..1882ae9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -12,7 +12,7 @@ jobs: strategy: matrix: install-args: [''] - php-version: ['8.1'] + php-version: ['8.2'] fail-fast: false steps: # Cancel previous runs of the same branch From 10e191f4aa34b9ca6d4960623d3079e67281d326 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sat, 16 Nov 2024 23:54:26 +0200 Subject: [PATCH 11/32] :package: Make it compatible with PHP 8.1+ again - bundle is compatible with Symfony 6, which is not require 8.2+ --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 7a11226..dfa18b3 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require" : { - "php" : ">=8.2", + "php" : ">=8.1", "ext-json": "*", "thecodingmachine/graphqlite" : "^7.0", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", From 8d0a0dae79f1c0c5078e5e25c30222267717fba2 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sat, 16 Nov 2024 23:54:26 +0200 Subject: [PATCH 12/32] :package: Don't use Doctrine annotation for Symfony Validator - in v7 of validator there's dropped support for annotations --- Tests/Fixtures/Controller/TestGraphqlController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Fixtures/Controller/TestGraphqlController.php b/Tests/Fixtures/Controller/TestGraphqlController.php index 17c5ba0..eb2694e 100644 --- a/Tests/Fixtures/Controller/TestGraphqlController.php +++ b/Tests/Fixtures/Controller/TestGraphqlController.php @@ -129,8 +129,8 @@ public function getUri(Request $request): string /** * @Query - * @Assertion(for="email", constraint=@Assert\Email()) */ + #[Assertion(for: 'email', constraint: new Assert\Email())] public function findByMail(string $email = 'a@a.com'): string { return $email; From c21cfdf40a9780639cae8dd09528f6b6d50003a9 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sat, 16 Nov 2024 23:54:26 +0200 Subject: [PATCH 13/32] :package: Rework bundle structure according to the latest Symfony recommendations, simplify phpunit config and to improve autoloader configuration --- .travis.yml | 2 +- composer.json | 7 +++- phpstan.neon | 2 +- phpunit.xml.dist | 13 +++---- .../Command}/DumpSchemaCommand.php | 0 .../Context}/SymfonyGraphQLContext.php | 0 .../SymfonyRequestContextInterface.php | 0 .../GraphQL/InvalidUserPasswordException.php | 0 .../Controller}/GraphQL/LoginController.php | 2 +- .../Controller}/GraphQL/MeController.php | 0 .../Controller}/GraphQLiteController.php | 20 +++++------ .../DependencyInjection}/Configuration.php | 0 .../GraphQLiteCompilerPass.php | 35 +++++++++---------- .../GraphQLiteExtension.php | 6 ++-- .../OverblogGraphiQLEndpointWiringPass.php | 0 .../GraphQLiteBundle.php | 6 ++-- .../GraphiQL}/EndpointResolver.php | 0 {Mappers => src/Mappers}/RequestParameter.php | 0 .../Mappers}/RequestParameterMiddleware.php | 0 .../config/container/graphqlite.xml | 0 .../Resources}/config/routes.xml | 0 .../Security}/AuthenticationService.php | 0 .../Security}/AuthorizationService.php | 0 {Server => src/Server}/ServerConfig.php | 0 .../Types}/SymfonyUserInterfaceType.php | 0 .../Command/DumpSchemaCommandTest.php | 0 .../Fixtures/Controller/MyException.php | 0 .../Controller/TestGraphqlController.php | 0 .../Controller/TestPhp8GraphqlController.php | 0 .../Fixtures/Entities/BadClass.php | 0 .../Fixtures/Entities/Contact.php | 0 .../Fixtures/Entities/Product.php | 0 .../Fixtures/Types/ContactType.php | 0 .../Fixtures/Types/ProductFactory.php | 0 .../Fixtures/Types/ProductType.php | 0 .../Fixtures/config/services.yaml | 0 {Tests => tests}/FunctionalTest.php | 4 +-- {Tests => tests}/GraphQLiteTestingKernel.php | 4 +-- .../Controller/EchoController.php | 0 {Tests => tests}/NoSecurityBundleTest.php | 0 40 files changed, 50 insertions(+), 51 deletions(-) rename {Command => src/Command}/DumpSchemaCommand.php (100%) rename {Context => src/Context}/SymfonyGraphQLContext.php (100%) rename {Context => src/Context}/SymfonyRequestContextInterface.php (100%) rename {Controller => src/Controller}/GraphQL/InvalidUserPasswordException.php (100%) rename {Controller => src/Controller}/GraphQL/LoginController.php (99%) rename {Controller => src/Controller}/GraphQL/MeController.php (100%) rename {Controller => src/Controller}/GraphQLiteController.php (100%) rename {DependencyInjection => src/DependencyInjection}/Configuration.php (100%) rename {DependencyInjection => src/DependencyInjection}/GraphQLiteCompilerPass.php (99%) rename {DependencyInjection => src/DependencyInjection}/GraphQLiteExtension.php (100%) rename {DependencyInjection => src/DependencyInjection}/OverblogGraphiQLEndpointWiringPass.php (100%) rename GraphQLiteBundle.php => src/GraphQLiteBundle.php (100%) rename {GraphiQL => src/GraphiQL}/EndpointResolver.php (100%) rename {Mappers => src/Mappers}/RequestParameter.php (100%) rename {Mappers => src/Mappers}/RequestParameterMiddleware.php (100%) rename {Resources => src/Resources}/config/container/graphqlite.xml (100%) rename {Resources => src/Resources}/config/routes.xml (100%) rename {Security => src/Security}/AuthenticationService.php (100%) rename {Security => src/Security}/AuthorizationService.php (100%) rename {Server => src/Server}/ServerConfig.php (100%) rename {Types => src/Types}/SymfonyUserInterfaceType.php (100%) rename {Tests => tests}/Command/DumpSchemaCommandTest.php (100%) rename {Tests => tests}/Fixtures/Controller/MyException.php (100%) rename {Tests => tests}/Fixtures/Controller/TestGraphqlController.php (100%) rename {Tests => tests}/Fixtures/Controller/TestPhp8GraphqlController.php (100%) rename {Tests => tests}/Fixtures/Entities/BadClass.php (100%) rename {Tests => tests}/Fixtures/Entities/Contact.php (100%) rename {Tests => tests}/Fixtures/Entities/Product.php (100%) rename {Tests => tests}/Fixtures/Types/ContactType.php (100%) rename {Tests => tests}/Fixtures/Types/ProductFactory.php (100%) rename {Tests => tests}/Fixtures/Types/ProductType.php (100%) rename {Tests => tests}/Fixtures/config/services.yaml (100%) rename {Tests => tests}/FunctionalTest.php (100%) rename {Tests => tests}/GraphQLiteTestingKernel.php (98%) rename {Tests => tests}/NoSecurityBundleFixtures/Controller/EchoController.php (100%) rename {Tests => tests}/NoSecurityBundleTest.php (100%) diff --git a/.travis.yml b/.travis.yml index 92ed00d..fb04ca0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ script: - if [[ $PHPSTAN == true ]]; then composer phpstan; fi #- ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml # Let's test without the security bundle - - if [[ $TESTNOSECURITYBUNDLE == true ]]; then composer remove --dev symfony/security-bundle && ./vendor/bin/simple-phpunit Tests/NoSecurityBundleTest.php; fi + - if [[ $TESTNOSECURITYBUNDLE == true ]]; then composer remove --dev symfony/security-bundle && ./vendor/bin/simple-phpunit tests/NoSecurityBundleTest.php; fi after_script: - ./vendor/bin/php-coveralls -v diff --git a/composer.json b/composer.json index dfa18b3..11071d5 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,12 @@ }, "autoload" : { "psr-4" : { - "TheCodingMachine\\GraphQLite\\Bundle\\" : "" + "TheCodingMachine\\GraphQLite\\Bundle\\" : "src" + } + }, + "autoload-dev" : { + "psr-4" : { + "TheCodingMachine\\GraphQLite\\Bundle\\Tests\\" : "tests" } }, "extra": { diff --git a/phpstan.neon b/phpstan.neon index fe0c558..f4dcf24 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,7 +8,7 @@ parameters: - vendor - cache - .phpstan-cache - - Tests + - tests level: max polluteScopeWithLoopInitialAssignments: false polluteScopeWithAlwaysIterableForeach: false diff --git a/phpunit.xml.dist b/phpunit.xml.dist index cdfcc0f..97d95df 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,22 +16,17 @@ - - ./Tests/ + + ./tests/ - ./ + ./src/ - cache - build - ./Resources - ./Tests - ./vendor - ./var + ./src/Resources diff --git a/Command/DumpSchemaCommand.php b/src/Command/DumpSchemaCommand.php similarity index 100% rename from Command/DumpSchemaCommand.php rename to src/Command/DumpSchemaCommand.php diff --git a/Context/SymfonyGraphQLContext.php b/src/Context/SymfonyGraphQLContext.php similarity index 100% rename from Context/SymfonyGraphQLContext.php rename to src/Context/SymfonyGraphQLContext.php diff --git a/Context/SymfonyRequestContextInterface.php b/src/Context/SymfonyRequestContextInterface.php similarity index 100% rename from Context/SymfonyRequestContextInterface.php rename to src/Context/SymfonyRequestContextInterface.php diff --git a/Controller/GraphQL/InvalidUserPasswordException.php b/src/Controller/GraphQL/InvalidUserPasswordException.php similarity index 100% rename from Controller/GraphQL/InvalidUserPasswordException.php rename to src/Controller/GraphQL/InvalidUserPasswordException.php diff --git a/Controller/GraphQL/LoginController.php b/src/Controller/GraphQL/LoginController.php similarity index 99% rename from Controller/GraphQL/LoginController.php rename to src/Controller/GraphQL/LoginController.php index de07ddf..335897d 100644 --- a/Controller/GraphQL/LoginController.php +++ b/src/Controller/GraphQL/LoginController.php @@ -57,7 +57,7 @@ public function __construct(UserProviderInterface $userProvider, UserPasswordHas /** * @Mutation() * - * @phpstan-return TUser + * @phpstan-return UserInterface */ public function login(string $userName, string $password, Request $request): UserInterface { diff --git a/Controller/GraphQL/MeController.php b/src/Controller/GraphQL/MeController.php similarity index 100% rename from Controller/GraphQL/MeController.php rename to src/Controller/GraphQL/MeController.php diff --git a/Controller/GraphQLiteController.php b/src/Controller/GraphQLiteController.php similarity index 100% rename from Controller/GraphQLiteController.php rename to src/Controller/GraphQLiteController.php index 6988566..9ef3d44 100644 --- a/Controller/GraphQLiteController.php +++ b/src/Controller/GraphQLiteController.php @@ -4,22 +4,17 @@ namespace TheCodingMachine\GraphQLite\Bundle\Controller; -use Laminas\Diactoros\ResponseFactory; -use Laminas\Diactoros\ServerRequestFactory; -use Laminas\Diactoros\StreamFactory; -use Laminas\Diactoros\UploadedFileFactory; -use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; -use TheCodingMachine\GraphQLite\Http\HttpCodeDecider; -use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface; -use function array_map; use GraphQL\Executor\ExecutionResult; use GraphQL\Server\ServerConfig; use GraphQL\Server\StandardServer; use GraphQL\Upload\UploadMiddleware; -use function class_exists; -use function json_decode; +use Laminas\Diactoros\ResponseFactory; +use Laminas\Diactoros\ServerRequestFactory; +use Laminas\Diactoros\StreamFactory; +use Laminas\Diactoros\UploadedFileFactory; use Psr\Http\Message\ServerRequestInterface; use RuntimeException; +use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -27,6 +22,11 @@ use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use TheCodingMachine\GraphQLite\Bundle\Context\SymfonyGraphQLContext; +use TheCodingMachine\GraphQLite\Http\HttpCodeDecider; +use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface; +use function array_map; +use function class_exists; +use function json_decode; /** * Listens to every single request and forward Graphql requests to Graphql Webonix standardServer. diff --git a/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php similarity index 100% rename from DependencyInjection/Configuration.php rename to src/DependencyInjection/Configuration.php diff --git a/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php similarity index 99% rename from DependencyInjection/GraphQLiteCompilerPass.php rename to src/DependencyInjection/GraphQLiteCompilerPass.php index a13be84..a83b7c8 100644 --- a/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -3,6 +3,8 @@ namespace TheCodingMachine\GraphQLite\Bundle\DependencyInjection; +use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader; +use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\Annotations\PsrCachedReader; use Generator; use GraphQL\Server\ServerConfig; @@ -10,30 +12,19 @@ use GraphQL\Validator\Rules\QueryComplexity; use GraphQL\Validator\Rules\QueryDepth; use Kcs\ClassFinder\Finder\ComposerFinder; +use Psr\SimpleCache\CacheInterface; +use ReflectionClass; +use ReflectionMethod; use ReflectionNamedType; +use ReflectionParameter; use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\Cache\Psr16Cache; -use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; -use TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapperFactory; -use Webmozart\Assert\Assert; -use function assert; -use function class_exists; -use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader; -use Doctrine\Common\Annotations\AnnotationRegistry; -use Psr\SimpleCache\CacheInterface; -use ReflectionParameter; -use function filter_var; -use function function_exists; -use ReflectionClass; -use ReflectionMethod; -use function ini_get; -use function interface_exists; -use function strpos; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\User\UserInterface; use TheCodingMachine\CacheUtils\ClassBoundCache; @@ -49,10 +40,18 @@ use TheCodingMachine\GraphQLite\Annotations\Query; use TheCodingMachine\GraphQLite\Bundle\Controller\GraphQL\LoginController; use TheCodingMachine\GraphQLite\Bundle\Controller\GraphQL\MeController; +use TheCodingMachine\GraphQLite\Bundle\Types\SymfonyUserInterfaceType; use TheCodingMachine\GraphQLite\GraphQLRuntimeException as GraphQLException; +use TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapperFactory; use TheCodingMachine\GraphQLite\Mappers\StaticTypeMapper; use TheCodingMachine\GraphQLite\SchemaFactory; -use TheCodingMachine\GraphQLite\Bundle\Types\SymfonyUserInterfaceType; +use Webmozart\Assert\Assert; +use function assert; +use function class_exists; +use function filter_var; +use function ini_get; +use function interface_exists; +use function strpos; /** * Detects controllers and types automatically and tag them. @@ -440,7 +439,7 @@ private function getAnnotationReader(): AnnotationReader $doctrineAnnotationReader = new PsrCachedReader($doctrineAnnotationReader, new ApcuAdapter('graphqlite'), true); } - $this->annotationReader = new AnnotationReader($doctrineAnnotationReader, AnnotationReader::LAX_MODE); + $this->annotationReader = new AnnotationReader(/*$doctrineAnnotationReader, AnnotationReader::LAX_MODE*/); } return $this->annotationReader; } diff --git a/DependencyInjection/GraphQLiteExtension.php b/src/DependencyInjection/GraphQLiteExtension.php similarity index 100% rename from DependencyInjection/GraphQLiteExtension.php rename to src/DependencyInjection/GraphQLiteExtension.php index a6b4b10..7142518 100644 --- a/DependencyInjection/GraphQLiteExtension.php +++ b/src/DependencyInjection/GraphQLiteExtension.php @@ -5,15 +5,15 @@ use GraphQL\Error\DebugFlag; -use TheCodingMachine\GraphQLite\Mappers\Root\RootTypeMapperFactoryInterface; -use function array_map; use GraphQL\Server\ServerConfig; use GraphQL\Type\Definition\ObjectType; -use function rtrim; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use TheCodingMachine\GraphQLite\Mappers\Root\RootTypeMapperFactoryInterface; +use function array_map; +use function rtrim; class GraphQLiteExtension extends Extension { diff --git a/DependencyInjection/OverblogGraphiQLEndpointWiringPass.php b/src/DependencyInjection/OverblogGraphiQLEndpointWiringPass.php similarity index 100% rename from DependencyInjection/OverblogGraphiQLEndpointWiringPass.php rename to src/DependencyInjection/OverblogGraphiQLEndpointWiringPass.php diff --git a/GraphQLiteBundle.php b/src/GraphQLiteBundle.php similarity index 100% rename from GraphQLiteBundle.php rename to src/GraphQLiteBundle.php index b9005ab..95f9c16 100644 --- a/GraphQLiteBundle.php +++ b/src/GraphQLiteBundle.php @@ -3,13 +3,13 @@ namespace TheCodingMachine\GraphQLite\Bundle; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use TheCodingMachine\GraphQLite\Bundle\DependencyInjection\GraphQLiteExtension; -use TheCodingMachine\GraphQLite\Bundle\DependencyInjection\OverblogGraphiQLEndpointWiringPass; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\HttpKernel\Bundle\Bundle; use TheCodingMachine\GraphQLite\Bundle\DependencyInjection\GraphQLiteCompilerPass; +use TheCodingMachine\GraphQLite\Bundle\DependencyInjection\GraphQLiteExtension; +use TheCodingMachine\GraphQLite\Bundle\DependencyInjection\OverblogGraphiQLEndpointWiringPass; class GraphQLiteBundle extends Bundle { diff --git a/GraphiQL/EndpointResolver.php b/src/GraphiQL/EndpointResolver.php similarity index 100% rename from GraphiQL/EndpointResolver.php rename to src/GraphiQL/EndpointResolver.php diff --git a/Mappers/RequestParameter.php b/src/Mappers/RequestParameter.php similarity index 100% rename from Mappers/RequestParameter.php rename to src/Mappers/RequestParameter.php diff --git a/Mappers/RequestParameterMiddleware.php b/src/Mappers/RequestParameterMiddleware.php similarity index 100% rename from Mappers/RequestParameterMiddleware.php rename to src/Mappers/RequestParameterMiddleware.php diff --git a/Resources/config/container/graphqlite.xml b/src/Resources/config/container/graphqlite.xml similarity index 100% rename from Resources/config/container/graphqlite.xml rename to src/Resources/config/container/graphqlite.xml diff --git a/Resources/config/routes.xml b/src/Resources/config/routes.xml similarity index 100% rename from Resources/config/routes.xml rename to src/Resources/config/routes.xml diff --git a/Security/AuthenticationService.php b/src/Security/AuthenticationService.php similarity index 100% rename from Security/AuthenticationService.php rename to src/Security/AuthenticationService.php diff --git a/Security/AuthorizationService.php b/src/Security/AuthorizationService.php similarity index 100% rename from Security/AuthorizationService.php rename to src/Security/AuthorizationService.php diff --git a/Server/ServerConfig.php b/src/Server/ServerConfig.php similarity index 100% rename from Server/ServerConfig.php rename to src/Server/ServerConfig.php diff --git a/Types/SymfonyUserInterfaceType.php b/src/Types/SymfonyUserInterfaceType.php similarity index 100% rename from Types/SymfonyUserInterfaceType.php rename to src/Types/SymfonyUserInterfaceType.php diff --git a/Tests/Command/DumpSchemaCommandTest.php b/tests/Command/DumpSchemaCommandTest.php similarity index 100% rename from Tests/Command/DumpSchemaCommandTest.php rename to tests/Command/DumpSchemaCommandTest.php diff --git a/Tests/Fixtures/Controller/MyException.php b/tests/Fixtures/Controller/MyException.php similarity index 100% rename from Tests/Fixtures/Controller/MyException.php rename to tests/Fixtures/Controller/MyException.php diff --git a/Tests/Fixtures/Controller/TestGraphqlController.php b/tests/Fixtures/Controller/TestGraphqlController.php similarity index 100% rename from Tests/Fixtures/Controller/TestGraphqlController.php rename to tests/Fixtures/Controller/TestGraphqlController.php diff --git a/Tests/Fixtures/Controller/TestPhp8GraphqlController.php b/tests/Fixtures/Controller/TestPhp8GraphqlController.php similarity index 100% rename from Tests/Fixtures/Controller/TestPhp8GraphqlController.php rename to tests/Fixtures/Controller/TestPhp8GraphqlController.php diff --git a/Tests/Fixtures/Entities/BadClass.php b/tests/Fixtures/Entities/BadClass.php similarity index 100% rename from Tests/Fixtures/Entities/BadClass.php rename to tests/Fixtures/Entities/BadClass.php diff --git a/Tests/Fixtures/Entities/Contact.php b/tests/Fixtures/Entities/Contact.php similarity index 100% rename from Tests/Fixtures/Entities/Contact.php rename to tests/Fixtures/Entities/Contact.php diff --git a/Tests/Fixtures/Entities/Product.php b/tests/Fixtures/Entities/Product.php similarity index 100% rename from Tests/Fixtures/Entities/Product.php rename to tests/Fixtures/Entities/Product.php diff --git a/Tests/Fixtures/Types/ContactType.php b/tests/Fixtures/Types/ContactType.php similarity index 100% rename from Tests/Fixtures/Types/ContactType.php rename to tests/Fixtures/Types/ContactType.php diff --git a/Tests/Fixtures/Types/ProductFactory.php b/tests/Fixtures/Types/ProductFactory.php similarity index 100% rename from Tests/Fixtures/Types/ProductFactory.php rename to tests/Fixtures/Types/ProductFactory.php diff --git a/Tests/Fixtures/Types/ProductType.php b/tests/Fixtures/Types/ProductType.php similarity index 100% rename from Tests/Fixtures/Types/ProductType.php rename to tests/Fixtures/Types/ProductType.php diff --git a/Tests/Fixtures/config/services.yaml b/tests/Fixtures/config/services.yaml similarity index 100% rename from Tests/Fixtures/config/services.yaml rename to tests/Fixtures/config/services.yaml diff --git a/Tests/FunctionalTest.php b/tests/FunctionalTest.php similarity index 100% rename from Tests/FunctionalTest.php rename to tests/FunctionalTest.php index 896485f..cdc90ed 100644 --- a/Tests/FunctionalTest.php +++ b/tests/FunctionalTest.php @@ -2,17 +2,17 @@ namespace TheCodingMachine\GraphQLite\Bundle\Tests; -use Symfony\Component\Security\Core\User\InMemoryUser; -use function json_decode; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\User\InMemoryUser; use TheCodingMachine\GraphQLite\Bundle\Controller\GraphQLiteController; use TheCodingMachine\GraphQLite\GraphQLRuntimeException as GraphQLException; use TheCodingMachine\GraphQLite\Schema; +use function json_decode; class FunctionalTest extends TestCase { diff --git a/Tests/GraphQLiteTestingKernel.php b/tests/GraphQLiteTestingKernel.php similarity index 98% rename from Tests/GraphQLiteTestingKernel.php rename to tests/GraphQLiteTestingKernel.php index 5ec06d1..a4be232 100644 --- a/Tests/GraphQLiteTestingKernel.php +++ b/tests/GraphQLiteTestingKernel.php @@ -188,7 +188,7 @@ public function configureContainer(ContainerBuilder $c, LoaderInterface $loader) $container->loadFromExtension('graphqlite', $graphqliteConf); }); - $confDir = $this->getProjectDir().'/Tests/Fixtures/config'; + $confDir = $this->getProjectDir().'/tests/Fixtures/config'; $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob'); $loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); @@ -199,7 +199,7 @@ public function configureContainer(ContainerBuilder $c, LoaderInterface $loader) // Note: typing is disabled because using different classes in Symfony 4 and 5 protected function configureRoutes(/*RoutingConfigurator*/ $routes) { - $routes->import(__DIR__.'/../Resources/config/routes.xml'); + $routes->import(__DIR__.'/../src/Resources/config/routes.xml'); } public function getCacheDir(): string diff --git a/Tests/NoSecurityBundleFixtures/Controller/EchoController.php b/tests/NoSecurityBundleFixtures/Controller/EchoController.php similarity index 100% rename from Tests/NoSecurityBundleFixtures/Controller/EchoController.php rename to tests/NoSecurityBundleFixtures/Controller/EchoController.php diff --git a/Tests/NoSecurityBundleTest.php b/tests/NoSecurityBundleTest.php similarity index 100% rename from Tests/NoSecurityBundleTest.php rename to tests/NoSecurityBundleTest.php From 3d4c71aac89abfc73fd0cac87559b0df018139b1 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sat, 16 Nov 2024 23:54:26 +0200 Subject: [PATCH 14/32] :package: Fix compatibility with graphqlite v7 --- src/Controller/GraphQL/InvalidUserPasswordException.php | 2 +- tests/Fixtures/Controller/TestGraphqlController.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/GraphQL/InvalidUserPasswordException.php b/src/Controller/GraphQL/InvalidUserPasswordException.php index 48bdbbc..e409002 100644 --- a/src/Controller/GraphQL/InvalidUserPasswordException.php +++ b/src/Controller/GraphQL/InvalidUserPasswordException.php @@ -10,6 +10,6 @@ class InvalidUserPasswordException extends GraphQLException { public static function create(Exception $previous = null): self { - return new self('The provided user / password is incorrect.', 401, $previous, 'Security'); + return new self('The provided user / password is incorrect.', 401, $previous, ['category' => 'Security']); } } diff --git a/tests/Fixtures/Controller/TestGraphqlController.php b/tests/Fixtures/Controller/TestGraphqlController.php index eb2694e..5da428f 100644 --- a/tests/Fixtures/Controller/TestGraphqlController.php +++ b/tests/Fixtures/Controller/TestGraphqlController.php @@ -81,7 +81,7 @@ public function triggerException(int $code = 0): string public function triggerAggregateException(): string { $exception1 = new GraphQLException('foo', 401); - $exception2 = new GraphQLException('bar', 404, null, 'MyCat', ['field' => 'baz', 'category' => 'MyCat']); + $exception2 = new GraphQLException('bar', 404, null, ['field' => 'baz', 'category' => 'MyCat']); throw new GraphQLAggregateException([$exception1, $exception2]); } From 77f48c1a86d5b343d0b35c653bc0e6330fa1031c Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 00:06:22 +0200 Subject: [PATCH 15/32] :package: Use `dev-master` for graphqlite because of improved performance, dropped support for doctrine annotations. Drop support for doctrine annotations --- composer.json | 4 ++-- .../GraphQLiteCompilerPass.php | 23 +++---------------- src/Resources/config/container/graphqlite.xml | 8 +------ 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 11071d5..0c8e2d1 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require" : { "php" : ">=8.1", "ext-json": "*", - "thecodingmachine/graphqlite" : "^7.0", + "thecodingmachine/graphqlite" : "dev-master as 7.1", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", @@ -52,7 +52,7 @@ "phpstan": "phpstan analyse GraphQLiteBundle.php DependencyInjection/ Controller/ Resources/ Security/ -c phpstan.neon --level=7 --no-progress" }, "suggest": { - "symfony/security-bundle": "To use @Logged or @Right annotations" + "symfony/security-bundle": "To use #[Logged] or #[Right] attributes" }, "autoload" : { "psr-4" : { diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index a83b7c8..da51120 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -3,9 +3,6 @@ namespace TheCodingMachine\GraphQLite\Bundle\DependencyInjection; -use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader; -use Doctrine\Common\Annotations\AnnotationRegistry; -use Doctrine\Common\Annotations\PsrCachedReader; use Generator; use GraphQL\Server\ServerConfig; use GraphQL\Validator\Rules\DisableIntrospection; @@ -59,7 +56,7 @@ class GraphQLiteCompilerPass implements CompilerPassInterface { /** - * @var AnnotationReader + * @var AnnotationReader|null */ private $annotationReader; @@ -422,26 +419,12 @@ private static function getParametersByName(ReflectionMethod $method): array } /** - * Returns a cached Doctrine annotation reader. + * Returns a GraphQLite annotation reader. * Note: we cannot get the annotation reader service in the container as we are in a compiler pass. */ private function getAnnotationReader(): AnnotationReader { - if ($this->annotationReader === null) { - // @phpstan-ignore-next-line "registerLoader exists in doctrine/annotations:v1.x" - if (method_exists(AnnotationRegistry::class, 'registerLoader')) { - AnnotationRegistry::registerLoader('class_exists'); - } - - $doctrineAnnotationReader = new DoctrineAnnotationReader(); - - if (ApcuAdapter::isSupported()) { - $doctrineAnnotationReader = new PsrCachedReader($doctrineAnnotationReader, new ApcuAdapter('graphqlite'), true); - } - - $this->annotationReader = new AnnotationReader(/*$doctrineAnnotationReader, AnnotationReader::LAX_MODE*/); - } - return $this->annotationReader; + return $this->annotationReader ??= new AnnotationReader(); } /** diff --git a/src/Resources/config/container/graphqlite.xml b/src/Resources/config/container/graphqlite.xml index bda653f..c0dfb68 100644 --- a/src/Resources/config/container/graphqlite.xml +++ b/src/Resources/config/container/graphqlite.xml @@ -5,10 +5,6 @@ xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd" > - - LAX_MODE - - @@ -40,9 +36,7 @@ - - %graphqlite.annotations.error_mode% - + From 75ea33858f97eef21072e326f80a81e06b77bac6 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 00:27:57 +0200 Subject: [PATCH 16/32] :package: Don't use deprecated method from `graphqlite` --- src/DependencyInjection/GraphQLiteCompilerPass.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index da51120..68fc5f9 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -236,14 +236,14 @@ public function process(ContainerBuilder $container): void } foreach ($controllersNamespaces as $controllersNamespace) { - $schemaFactory->addMethodCall('addControllerNamespace', [ $controllersNamespace ]); + $schemaFactory->addMethodCall('addNamespace', [ $controllersNamespace ]); foreach ($this->getClassList($controllersNamespace) as $className => $refClass) { $this->makePublicInjectedServices($refClass, $reader, $container, true); } } foreach ($typesNamespaces as $typeNamespace) { - $schemaFactory->addMethodCall('addTypeNamespace', [ $typeNamespace ]); + $schemaFactory->addMethodCall('addNamespace', [ $typeNamespace ]); foreach ($this->getClassList($typeNamespace) as $className => $refClass) { $this->makePublicInjectedServices($refClass, $reader, $container, false); } From 818ff34b03a2b27d8f861d65717e8851eabbc7de Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 01:06:12 +0200 Subject: [PATCH 17/32] :package: Migrate to attributes - since support for Doctrine annotations dropped --- src/Types/SymfonyUserInterfaceType.php | 10 +-- .../Controller/TestGraphqlController.php | 63 ++++++------------- tests/Fixtures/Entities/BadClass.php | 1 - tests/Fixtures/Entities/Contact.php | 46 ++++++-------- tests/Fixtures/Entities/Product.php | 2 - tests/Fixtures/Types/ContactType.php | 8 +-- tests/Fixtures/Types/ProductFactory.php | 5 +- tests/Fixtures/Types/ProductType.php | 12 ++-- .../Controller/EchoController.php | 6 +- 9 files changed, 47 insertions(+), 106 deletions(-) diff --git a/src/Types/SymfonyUserInterfaceType.php b/src/Types/SymfonyUserInterfaceType.php index f895319..26ea2f4 100644 --- a/src/Types/SymfonyUserInterfaceType.php +++ b/src/Types/SymfonyUserInterfaceType.php @@ -9,14 +9,10 @@ use Symfony\Component\Security\Core\User\UserInterface; use TheCodingMachine\GraphQLite\FieldNotFoundException; -/** - * @Type(class=UserInterface::class) - */ +#[Type(class: UserInterface::class)] class SymfonyUserInterfaceType { - /** - * @Field - */ + #[Field] public function getUserName(UserInterface $user): string { // @phpstan-ignore-next-line Forward Compatibility for Symfony >=5.3 @@ -33,9 +29,9 @@ public function getUserName(UserInterface $user): string } /** - * @Field() * @return string[] */ + #[Field] public function getRoles(UserInterface $user): array { $roles = []; diff --git a/tests/Fixtures/Controller/TestGraphqlController.php b/tests/Fixtures/Controller/TestGraphqlController.php index 5da428f..f969b51 100644 --- a/tests/Fixtures/Controller/TestGraphqlController.php +++ b/tests/Fixtures/Controller/TestGraphqlController.php @@ -20,19 +20,16 @@ class TestGraphqlController { - - /** - * @Query() - */ + #[Query] public function test(string $foo): string { return 'echo ' .$foo; } /** - * @Query() * @return Product[] */ + #[Query] public function products(): array { return [ @@ -40,44 +37,34 @@ public function products(): array ]; } - /** - * @Query() - */ + #[Query] public function contact(): Contact { return new Contact('Mouf'); } - /** - * @Mutation() - */ + #[Mutation] public function saveProduct(Product $product): Product { return $product; } /** - * @Query() * @return Contact[] */ + #[Query] public function contacts(): ArrayResult { return new ArrayResult([new Contact('Mouf')]); } - /** - * @Query() - * @return string - */ + #[Query] public function triggerException(int $code = 0): string { throw new MyException('Boom', $code); } - /** - * @Query() - * @return string - */ + #[Query] public function triggerAggregateException(): string { $exception1 = new GraphQLException('foo', 401); @@ -85,51 +72,37 @@ public function triggerAggregateException(): string throw new GraphQLAggregateException([$exception1, $exception2]); } - /** - * @Query() - * @Logged() - * @FailWith(null) - * @return string - */ + #[Query] + #[Logged] + #[FailWith(null)] public function loggedQuery(): string { return 'foo'; } - /** - * @Query() - * @Right("ROLE_ADMIN") - * @FailWith(null) - * @return string - */ + #[Query] + #[Right('ROLE_ADMIN')] + #[FailWith(null)] public function withAdminRight(): string { return 'foo'; } - /** - * @Query() - * @Right("ROLE_USER") - * @FailWith(null) - * @return string - */ + #[Query] + #[Right('ROLE_USER')] + #[FailWith(null)] public function withUserRight(): string { return 'foo'; } - /** - * @Query() - * @return string - */ + #[Query] public function getUri(Request $request): string { return $request->getPathInfo(); } - /** - * @Query - */ + #[Query] #[Assertion(for: 'email', constraint: new Assert\Email())] public function findByMail(string $email = 'a@a.com'): string { diff --git a/tests/Fixtures/Entities/BadClass.php b/tests/Fixtures/Entities/BadClass.php index 7c89188..f8f04d5 100644 --- a/tests/Fixtures/Entities/BadClass.php +++ b/tests/Fixtures/Entities/BadClass.php @@ -1,6 +1,5 @@ name = $name; } - /** - * @Field(name="name") - */ + #[Field(name: 'name')] public function getName(): string { return $this->name; } - /** - * @Field() - * @Autowire(for="$testService") - * @Autowire(for="$someService", identifier="someService") - * @Autowire(for="$someAlias", identifier="someAlias") - * @return string - */ - public function injectService(TestGraphqlController $testService = null, stdClass $someService = null, stdClass $someAlias = null): string - { + #[Field] + public function injectService( + #[Autowire] + TestGraphqlController $testService = null, + #[Autowire(identifier: 'someService')] + stdClass $someService = null, + #[Autowire(identifier: 'someAlias')] + stdClass $someAlias = null, + ): string { if (!$testService instanceof TestGraphqlController || $someService === null || $someAlias === null) { return 'KO'; } return 'OK'; } - /** - * @Field(prefetchMethod="prefetchData") - */ + #[Field(prefetchMethod: 'prefetchData')] public function injectServicePrefetch($prefetchData): string { return $prefetchData; } - /** - * @Autowire(for="$someOtherService", identifier="someOtherService") - */ - public function prefetchData(iterable $iterable, stdClass $someOtherService = null) - { + public function prefetchData( + iterable $iterable, + #[Autowire(identifier: 'someOtherService')] + stdClass $someOtherService = null, + ) { if ($someOtherService === null) { return 'KO'; } return 'OK'; } - /** - * @Field() - */ + #[Field] public function getManager(): ?Contact { return null; diff --git a/tests/Fixtures/Entities/Product.php b/tests/Fixtures/Entities/Product.php index b77e094..d33194a 100644 --- a/tests/Fixtures/Entities/Product.php +++ b/tests/Fixtures/Entities/Product.php @@ -1,9 +1,7 @@ getName()); diff --git a/tests/Fixtures/Types/ProductFactory.php b/tests/Fixtures/Types/ProductFactory.php index c28f853..1e38b91 100644 --- a/tests/Fixtures/Types/ProductFactory.php +++ b/tests/Fixtures/Types/ProductFactory.php @@ -9,10 +9,7 @@ class ProductFactory { - - /** - * @Factory() - */ + #[Factory] public function buildProduct(string $name, float $price): Product { return new Product($name, $price); diff --git a/tests/Fixtures/Types/ProductType.php b/tests/Fixtures/Types/ProductType.php index 94e3d8c..2aa3831 100644 --- a/tests/Fixtures/Types/ProductType.php +++ b/tests/Fixtures/Types/ProductType.php @@ -10,16 +10,12 @@ use TheCodingMachine\GraphQLite\Bundle\Tests\Fixtures\Entities\Product; -/** - * @Type(class=Product::class) - * @SourceField(name="name") - * @SourceField(name="price") - */ +#[Type(class: Product::class)] +#[SourceField(name: 'name')] +#[SourceField(name: 'price')] class ProductType { - /** - * @Field() - */ + #[Field] public function getSeller(Product $product): ?Contact { return null; diff --git a/tests/NoSecurityBundleFixtures/Controller/EchoController.php b/tests/NoSecurityBundleFixtures/Controller/EchoController.php index 64dfe19..3521ed2 100644 --- a/tests/NoSecurityBundleFixtures/Controller/EchoController.php +++ b/tests/NoSecurityBundleFixtures/Controller/EchoController.php @@ -1,16 +1,12 @@ Date: Sun, 17 Nov 2024 01:19:03 +0200 Subject: [PATCH 18/32] :sparkles: Use service locator for `AggregateControllerQueryProviderFactory` instead of global DI container --- src/DependencyInjection/GraphQLiteCompilerPass.php | 10 ++++++++++ src/Resources/config/container/graphqlite.xml | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index 68fc5f9..d59d01e 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -17,6 +17,7 @@ use Symfony\Component\Cache\Adapter\ApcuAdapter; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\Cache\Psr16Cache; +use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -297,12 +298,21 @@ public function process(ContainerBuilder $container): void private function registerController(string $controllerClassName, ContainerBuilder $container): void { $aggregateQueryProvider = $container->findDefinition(AggregateControllerQueryProviderFactory::class); + $controllersList = $aggregateQueryProvider->getArgument(0); if (!is_array($controllersList)){ throw new GraphQLException(sprintf('Expecting array in %s, arg #1', AggregateControllerQueryProviderFactory::class)); } + $controllersList[] = $controllerClassName; $aggregateQueryProvider->setArgument(0, $controllersList); + + $serviceLocatorMap = []; + foreach ($controllersList as $controller) { + $serviceLocatorMap[$controller] = new Reference($controller); + } + + $aggregateQueryProvider->setArgument(1, new ServiceLocatorArgument($serviceLocatorMap)); } /** diff --git a/src/Resources/config/container/graphqlite.xml b/src/Resources/config/container/graphqlite.xml index c0dfb68..545ec0e 100644 --- a/src/Resources/config/container/graphqlite.xml +++ b/src/Resources/config/container/graphqlite.xml @@ -26,10 +26,13 @@ + - + + + From 6b90bd4120d4a2a13ec293e4b4447f9dd47379eb Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 01:38:49 +0200 Subject: [PATCH 19/32] :package: Improve readability --- tests/GraphQLiteTestingKernel.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/GraphQLiteTestingKernel.php b/tests/GraphQLiteTestingKernel.php index a4be232..c92ad95 100644 --- a/tests/GraphQLiteTestingKernel.php +++ b/tests/GraphQLiteTestingKernel.php @@ -204,7 +204,14 @@ protected function configureRoutes(/*RoutingConfigurator*/ $routes) public function getCacheDir(): string { - return __DIR__.'/../cache/'.($this->enableSession?'withSession':'withoutSession').$this->enableLogin.($this->enableSecurity?'withSecurity':'withoutSecurity').$this->enableMe.'_'.($this->introspection?'withIntrospection':'withoutIntrospection').'_'.$this->maximumQueryComplexity.'_'.$this->maximumQueryDepth.'_'.md5(serialize($this->controllersNamespace).'_'.md5(serialize($this->typesNamespace))); + $prefix = ($this->enableSession?'withSession':'withoutSession') + .$this->enableLogin + .($this->enableSecurity?'withSecurity':'withoutSecurity') + .$this->enableMe + .'_' + .($this->introspection?'withIntrospection':'withoutIntrospection'); + + return __DIR__.'/../cache/'.$prefix.'_'.$this->maximumQueryComplexity.'_'.$this->maximumQueryDepth.'_'.md5(serialize($this->controllersNamespace).'_'.md5(serialize($this->typesNamespace))); } public function process(ContainerBuilder $container): void From 30dce85ae3662727527a8cb553d5b321abccae78 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 01:39:42 +0200 Subject: [PATCH 20/32] :fire: Drop useless assert --- tests/NoSecurityBundleTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/NoSecurityBundleTest.php b/tests/NoSecurityBundleTest.php index 46f6e13..6def734 100644 --- a/tests/NoSecurityBundleTest.php +++ b/tests/NoSecurityBundleTest.php @@ -18,7 +18,6 @@ public function testServiceWiring(): void $kernel = new GraphQLiteTestingKernel(true, null, false, null, true, null, null, ['TheCodingMachine\\GraphQLite\\Bundle\\Tests\\NoSecurityBundleFixtures\\Controller\\']); $kernel->boot(); $container = $kernel->getContainer(); - self::assertNotNull($container); $schema = $container->get(Schema::class); $this->assertInstanceOf(Schema::class, $schema); From 06f4664639861b2ed6ad12af144eb94653c8251f Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 02:10:00 +0200 Subject: [PATCH 21/32] :rotating_light: Apply workaround for cache-related issue in tests --- tests/NoSecurityBundleTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/NoSecurityBundleTest.php b/tests/NoSecurityBundleTest.php index 6def734..91632fb 100644 --- a/tests/NoSecurityBundleTest.php +++ b/tests/NoSecurityBundleTest.php @@ -2,6 +2,7 @@ namespace TheCodingMachine\GraphQLite\Bundle\Tests; +use Symfony\Component\Cache\Adapter\ApcuAdapter; use function json_decode; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; @@ -15,6 +16,13 @@ class NoSecurityBundleTest extends TestCase { public function testServiceWiring(): void { + // tech debt: for some reason when we're running full test suite + // - from APCu cache we're getting old controllers for available graphql and this fails test + if (ApcuAdapter::isSupported()) { + $apcu = new ApcuAdapter(); + $apcu->clear(); + } + $kernel = new GraphQLiteTestingKernel(true, null, false, null, true, null, null, ['TheCodingMachine\\GraphQLite\\Bundle\\Tests\\NoSecurityBundleFixtures\\Controller\\']); $kernel->boot(); $container = $kernel->getContainer(); From 189589de06ec968396f3261c333ea4835d007355 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 02:31:22 +0200 Subject: [PATCH 22/32] :package: Migrate to attributes - since support for Doctrine annotations dropped --- src/Controller/GraphQL/LoginController.php | 10 ++-------- src/Controller/GraphQL/MeController.php | 4 +--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Controller/GraphQL/LoginController.php b/src/Controller/GraphQL/LoginController.php index 335897d..08ed1f2 100644 --- a/src/Controller/GraphQL/LoginController.php +++ b/src/Controller/GraphQL/LoginController.php @@ -54,11 +54,7 @@ public function __construct(UserProviderInterface $userProvider, UserPasswordHas $this->eventDispatcher = $eventDispatcher; } - /** - * @Mutation() - * - * @phpstan-return UserInterface - */ + #[Mutation] public function login(string $userName, string $password, Request $request): UserInterface { try { @@ -95,9 +91,7 @@ public function login(string $userName, string $password, Request $request): Use return $user; } - /** - * @Mutation() - */ + #[Mutation] public function logout(Request $request): bool { $this->tokenStorage->setToken(null); diff --git a/src/Controller/GraphQL/MeController.php b/src/Controller/GraphQL/MeController.php index 087832a..16c389c 100644 --- a/src/Controller/GraphQL/MeController.php +++ b/src/Controller/GraphQL/MeController.php @@ -18,9 +18,7 @@ public function __construct(TokenStorageInterface $tokenStorage) $this->tokenStorage = $tokenStorage; } - /** - * @Query() - */ + #[Query] public function me(): ?UserInterface { $token = $this->tokenStorage->getToken(); From a966ef1954e806be9bcc16336146f9a7be532089 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 18:02:34 +0200 Subject: [PATCH 23/32] :bug: Fix support for autowiring attribute in compiler pass - it is now targeted to the method --- .../GraphQLiteCompilerPass.php | 36 +++++++++---------- tests/Fixtures/Entities/Contact.php | 1 + 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index d59d01e..e1f00d1 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -377,33 +377,29 @@ private function makePublicInjectedServices(ReflectionClass $refClass, Annotatio */ private function getListOfInjectedServices(ReflectionMethod $method, ContainerBuilder $container): array { + /** @var array $services */ $services = []; - /** - * @var Autowire[] $autowireAnnotations - */ - $autowireAnnotations = $this->getAnnotationReader()->getMethodAnnotations($method, Autowire::class); - $parametersByName = null; - foreach ($autowireAnnotations as $autowire) { - $target = $autowire->getTarget(); - - if ($parametersByName === null) { - $parametersByName = self::getParametersByName($method); - } + $annotations = $this->getAnnotationReader()->getParameterAnnotationsPerParameter($method->getParameters()); + foreach ($annotations as $parameterName => $parameterAnnotations) { + $parameterAutowireAnnotation = $parameterAnnotations->getAnnotationsByType(Autowire::class); + foreach ($parameterAutowireAnnotation as $autowire) { + $id = $autowire->getIdentifier(); + if ($id !== null) { + $services[$id] = $id; + continue; + } - if (!isset($parametersByName[$target])) { - throw new GraphQLException('In method '.$method->getDeclaringClass()->getName().'::'.$method->getName().', the @Autowire annotation refers to a non existing parameter named "'.$target.'"'); - } + $parametersByName ??= self::getParametersByName($method); + if (!isset($parametersByName[$parameterName])) { + throw new \LogicException('Should not happen'); + } - $id = $autowire->getIdentifier(); - if ($id !== null) { - $services[$id] = $id; - } else { - $parameter = $parametersByName[$target]; + $parameter = $parametersByName[$parameterName]; $type = $parameter->getType(); - if ($type !== null && $type instanceof ReflectionNamedType) { + if ($type instanceof ReflectionNamedType) { $fqcn = $type->getName(); if ($container->has($fqcn)) { $services[$fqcn] = $fqcn; diff --git a/tests/Fixtures/Entities/Contact.php b/tests/Fixtures/Entities/Contact.php index 3e13abc..fc90f60 100644 --- a/tests/Fixtures/Entities/Contact.php +++ b/tests/Fixtures/Entities/Contact.php @@ -39,6 +39,7 @@ public function injectService( if (!$testService instanceof TestGraphqlController || $someService === null || $someAlias === null) { return 'KO'; } + return 'OK'; } From d608925b5ce91a13088f0a35ca938939772efb39 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 18:03:23 +0200 Subject: [PATCH 24/32] :package: Fix phpstan command after reworking directory structure --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0c8e2d1..d943938 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "phpdocumentor/type-resolver": "<1.4" }, "scripts": { - "phpstan": "phpstan analyse GraphQLiteBundle.php DependencyInjection/ Controller/ Resources/ Security/ -c phpstan.neon --level=7 --no-progress" + "phpstan": "phpstan analyse -c phpstan.neon --level=7 --no-progress" }, "suggest": { "symfony/security-bundle": "To use #[Logged] or #[Right] attributes" From c84f9226587213d8d6e84ae33215a59f260f4220 Mon Sep 17 00:00:00 2001 From: Andrii Date: Sun, 17 Nov 2024 18:19:01 +0200 Subject: [PATCH 25/32] :fire: Drop bad class from test suite - this feature (ignoring psr-4 structure mismatch) is not supported anymore --- src/DependencyInjection/GraphQLiteCompilerPass.php | 3 +++ tests/Fixtures/Entities/BadClass.php | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) delete mode 100644 tests/Fixtures/Entities/BadClass.php diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index e1f00d1..fc9844e 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -472,6 +472,9 @@ private function getCodeCache(): ClassBoundCacheContractInterface */ private function getClassList(string $namespace): Generator { + // dev note: this code will be broken if there's a broken class (which has mismatch in real namespace + // with PSR-4 configuration) in the configured namespace + // see also: https://github.com/alekitto/class-finder/issues/24#issuecomment-2480847327 $finder = new ComposerFinder(); foreach ($finder->inNamespace($namespace) as $class) { assert($class instanceof ReflectionClass); diff --git a/tests/Fixtures/Entities/BadClass.php b/tests/Fixtures/Entities/BadClass.php deleted file mode 100644 index f8f04d5..0000000 --- a/tests/Fixtures/Entities/BadClass.php +++ /dev/null @@ -1,7 +0,0 @@ - Date: Tue, 19 Nov 2024 00:54:10 +0200 Subject: [PATCH 26/32] :poop: Use own `graphqlite` fork with applied fixes to show that CI is now green --- composer.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d943938..a7a6820 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require" : { "php" : ">=8.1", "ext-json": "*", - "thecodingmachine/graphqlite" : "dev-master as 7.1", + "thecodingmachine/graphqlite" : "dev-symfony7-pack as 7.1", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", @@ -69,5 +69,11 @@ "dev-master": "6.0.x-dev" } }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/andrew-demb/graphqlite.git" + } + ], "prefer-stable": true } From 8c4836731c7d2a735256dcabc26c94479d6c634e Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 27 Nov 2024 22:27:59 +0200 Subject: [PATCH 27/32] :package: Switch back to the `dev-master` for origin `graphqlite` - required PR's is merged now --- composer.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/composer.json b/composer.json index a7a6820..d943938 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require" : { "php" : ">=8.1", "ext-json": "*", - "thecodingmachine/graphqlite" : "dev-symfony7-pack as 7.1", + "thecodingmachine/graphqlite" : "dev-master as 7.1", "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", @@ -69,11 +69,5 @@ "dev-master": "6.0.x-dev" } }, - "repositories": [ - { - "type": "git", - "url": "https://github.com/andrew-demb/graphqlite.git" - } - ], "prefer-stable": true } From 67d2b0727acc8417d6d328712d78b8ef992d002f Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 18 Dec 2024 12:33:37 +0200 Subject: [PATCH 28/32] :package: Use stable graphqlite (v8). Use dev version of graphqlite validator bridge (unreleased, unmerged) --- composer.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d943938..61b70a5 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ "require" : { "php" : ">=8.1", "ext-json": "*", - "thecodingmachine/graphqlite" : "dev-master as 7.1", - "thecodingmachine/graphqlite-symfony-validator-bridge" : "^6.0 || ^7.0", + "thecodingmachine/graphqlite" : "^8", + "thecodingmachine/graphqlite-symfony-validator-bridge": "dev-graphqlite-8 as v7.1.0", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", "symfony/framework-bundle": "^6.4 || ^7", @@ -54,6 +54,12 @@ "suggest": { "symfony/security-bundle": "To use #[Logged] or #[Right] attributes" }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/andrew-demb/graphqlite-symfony-validator-bridge.git" + } + ], "autoload" : { "psr-4" : { "TheCodingMachine\\GraphQLite\\Bundle\\" : "src" From d1583282b7477c07dc368d148bceb222f8edd92e Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 18 Dec 2024 12:34:08 +0200 Subject: [PATCH 29/32] :package: Avoid deprecated --- tests/Fixtures/Controller/TestGraphqlController.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/Fixtures/Controller/TestGraphqlController.php b/tests/Fixtures/Controller/TestGraphqlController.php index f969b51..d768e61 100644 --- a/tests/Fixtures/Controller/TestGraphqlController.php +++ b/tests/Fixtures/Controller/TestGraphqlController.php @@ -103,9 +103,10 @@ public function getUri(Request $request): string } #[Query] - #[Assertion(for: 'email', constraint: new Assert\Email())] - public function findByMail(string $email = 'a@a.com'): string - { + public function findByMail( + #[Assertion(constraint: new Assert\Email())] + string $email = 'a@a.com' + ): string { return $email; } } From 90ef14ce4f257575d76d238e2206c5a703e31a95 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 18 Dec 2024 13:22:44 +0200 Subject: [PATCH 30/32] :fire: Doctrine annotations is not supported since GraphQLite 7 - drop dependency --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 61b70a5..c319a9c 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "symfony/framework-bundle": "^6.4 || ^7", "symfony/validator": "^6.4 || ^7", "symfony/translation": "^6.4 || ^7", - "doctrine/annotations": "^1.13 || ^2.0.1", "symfony/psr-http-message-bridge": "^2.0 || ^7.0", "nyholm/psr7": "^1.1", "laminas/laminas-diactoros": "^2.2.2 || ^3.0", From 25b690ce2c19bc656b6bea3c035006a19caa6d60 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 18 Dec 2024 13:35:45 +0200 Subject: [PATCH 31/32] :package: Declare properties before methods. Add typing. Drop useless phpdoc tags --- .../GraphQLiteCompilerPass.php | 40 +++++-------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/src/DependencyInjection/GraphQLiteCompilerPass.php b/src/DependencyInjection/GraphQLiteCompilerPass.php index fc9844e..acc29d0 100644 --- a/src/DependencyInjection/GraphQLiteCompilerPass.php +++ b/src/DependencyInjection/GraphQLiteCompilerPass.php @@ -56,15 +56,14 @@ */ class GraphQLiteCompilerPass implements CompilerPassInterface { - /** - * @var AnnotationReader|null - */ - private $annotationReader; + private ?AnnotationReader $annotationReader = null; + + private string $cacheDir; + + private ?CacheInterface $cache = null; + + private ?ClassBoundCacheContractInterface $codeCache = null; - /** - * @var string - */ - private $cacheDir; /** * You can modify the container here before it is dumped to PHP code. @@ -317,9 +316,6 @@ private function registerController(string $controllerClassName, ContainerBuilde /** * Register a method call on SchemaFactory for each tagged service, passing the service in parameter. - * - * @param string $tag - * @param string $methodName */ private function mapAdderToTag(string $tag, string $methodName, ContainerBuilder $container, Definition $schemaFactory): void { @@ -371,8 +367,6 @@ private function makePublicInjectedServices(ReflectionClass $refClass, Annotatio } /** - * @param ReflectionMethod $method - * @param ContainerBuilder $container * @return array key = value = service name */ private function getListOfInjectedServices(ReflectionMethod $method, ContainerBuilder $container): array @@ -412,7 +406,6 @@ private function getListOfInjectedServices(ReflectionMethod $method, ContainerBu } /** - * @param ReflectionMethod $method * @return array */ private static function getParametersByName(ReflectionMethod $method): array @@ -433,11 +426,6 @@ private function getAnnotationReader(): AnnotationReader return $this->annotationReader ??= new AnnotationReader(); } - /** - * @var CacheInterface - */ - private $cache; - private function getPsr16Cache(): CacheInterface { if ($this->cache === null) { @@ -447,27 +435,21 @@ private function getPsr16Cache(): CacheInterface $this->cache = new Psr16Cache(new PhpFilesAdapter('graphqlite_bundle', 0, $this->cacheDir)); } } + return $this->cache; } - /** - * @var ClassBoundCacheContractInterface - */ - private $codeCache; - private function getCodeCache(): ClassBoundCacheContractInterface { - if ($this->codeCache === null) { - $this->codeCache = new ClassBoundCacheContract(new ClassBoundMemoryAdapter(new ClassBoundCache(new FileBoundCache($this->getPsr16Cache())))); - } - return $this->codeCache; + return $this->codeCache ??= new ClassBoundCacheContract( + new ClassBoundMemoryAdapter(new ClassBoundCache(new FileBoundCache($this->getPsr16Cache()))) + ); } /** * Returns the array of globbed classes. * Only instantiable classes are returned. * - * @param string $namespace * @return Generator, void, void> */ private function getClassList(string $namespace): Generator From ae4511ad37d925a73a8f5ee58429e12ea6d755b9 Mon Sep 17 00:00:00 2001 From: Andrii Date: Fri, 3 Jan 2025 19:39:42 +0100 Subject: [PATCH 32/32] :package: Switch to original and stable version of validator-bridge --- composer.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/composer.json b/composer.json index b630592..1ad1550 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "php" : ">=8.1", "ext-json": "*", "thecodingmachine/graphqlite" : "^8", - "thecodingmachine/graphqlite-symfony-validator-bridge": "dev-graphqlite-8 as v7.1.0", + "thecodingmachine/graphqlite-symfony-validator-bridge": "^7.1.1", "symfony/config": "^6.4 || ^7", "symfony/console": "^6.4 || ^7", "symfony/framework-bundle": "^6.4 || ^7", @@ -52,12 +52,6 @@ "suggest": { "symfony/security-bundle": "To use #[Logged] or #[Right] attributes" }, - "repositories": [ - { - "type": "git", - "url": "https://github.com/andrew-demb/graphqlite-symfony-validator-bridge.git" - } - ], "autoload" : { "psr-4" : { "TheCodingMachine\\GraphQLite\\Bundle\\" : "src"