From c1a9f0f45de3002f633d387bb4587eebb7b3f47e Mon Sep 17 00:00:00 2001 From: Sergey Logachev Date: Tue, 17 Dec 2019 18:35:00 +0300 Subject: [PATCH 1/2] Check `pagination_use_output_walkers` attribute for graphQl operation --- .../Orm/Extension/PaginationExtension.php | 20 ++++++--- .../Orm/Extension/PaginationExtensionTest.php | 42 +++++++++++++++---- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php index b7954378ed4..39d88c78c3d 100644 --- a/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php +++ b/src/Bridge/Doctrine/Orm/Extension/PaginationExtension.php @@ -164,8 +164,8 @@ public function getResult(QueryBuilder $queryBuilder, string $resourceClass = nu $query->setHint(CountWalker::HINT_DISTINCT, false); } - $doctrineOrmPaginator = new DoctrineOrmPaginator($query, $this->shouldDoctrinePaginatorFetchJoinCollection($queryBuilder, $resourceClass, $operationName)); - $doctrineOrmPaginator->setUseOutputWalkers($this->shouldDoctrinePaginatorUseOutputWalkers($queryBuilder, $resourceClass, $operationName)); + $doctrineOrmPaginator = new DoctrineOrmPaginator($query, $this->shouldDoctrinePaginatorFetchJoinCollection($queryBuilder, $resourceClass, $operationName, $context)); + $doctrineOrmPaginator->setUseOutputWalkers($this->shouldDoctrinePaginatorUseOutputWalkers($queryBuilder, $resourceClass, $operationName, $context)); if (null === $this->requestStack) { $isPartialEnabled = $this->pagination->isPartialEnabled($resourceClass, $operationName, $context); @@ -317,12 +317,16 @@ private function addCountToContext(QueryBuilder $queryBuilder, array $context): /** * Determines the value of the $fetchJoinCollection argument passed to the Doctrine ORM Paginator. */ - private function shouldDoctrinePaginatorFetchJoinCollection(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null): bool + private function shouldDoctrinePaginatorFetchJoinCollection(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null, array $context = []): bool { if (null !== $resourceClass) { $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); - if (null !== $fetchJoinCollection = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_fetch_join_collection', null, true)) { + if (isset($context['collection_operation_name']) && null !== $fetchJoinCollection = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_fetch_join_collection', null, true)) { + return $fetchJoinCollection; + } + + if (isset($context['graphql_operation_name']) && null !== $fetchJoinCollection = $resourceMetadata->getGraphqlAttribute($operationName, 'pagination_fetch_join_collection', null, true)) { return $fetchJoinCollection; } } @@ -348,12 +352,16 @@ private function shouldDoctrinePaginatorFetchJoinCollection(QueryBuilder $queryB /** * Determines whether the Doctrine ORM Paginator should use output walkers. */ - private function shouldDoctrinePaginatorUseOutputWalkers(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null): bool + private function shouldDoctrinePaginatorUseOutputWalkers(QueryBuilder $queryBuilder, string $resourceClass = null, string $operationName = null, array $context = []): bool { if (null !== $resourceClass) { $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); - if (null !== $useOutputWalkers = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_use_output_walkers', null, true)) { + if (isset($context['collection_operation_name']) && null !== $useOutputWalkers = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_use_output_walkers', null, true)) { + return $useOutputWalkers; + } + + if (isset($context['graphql_operation_name']) && null !== $useOutputWalkers = $resourceMetadata->getGraphqlAttribute($operationName, 'pagination_use_output_walkers', null, true)) { return $useOutputWalkers; } } diff --git a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php index cddca47dc65..18d36b055e5 100644 --- a/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php +++ b/tests/Bridge/Doctrine/Orm/Extension/PaginationExtensionTest.php @@ -1043,7 +1043,10 @@ public function testLegacyGetResult() $this->assertInstanceOf(PaginatorInterface::class, $result); } - public function testGetResultWithFetchJoinCollectionDisabled() + /** + * @dataProvider fetchJoinCollectionProvider + */ + public function testGetResultWithFetchJoinCollection(array $attributes, array $context, bool $expected) { $dummyMetadata = new ClassMetadata(Dummy::class); @@ -1064,7 +1067,7 @@ public function testGetResultWithFetchJoinCollectionDisabled() $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($entityManagerProphecy); $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, null, ['pagination_fetch_join_collection' => false])); + $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, null, $attributes)); $paginationExtension = new PaginationExtension( $managerRegistryProphecy->reveal(), @@ -1072,7 +1075,7 @@ public function testGetResultWithFetchJoinCollectionDisabled() new Pagination($resourceMetadataFactoryProphecy->reveal()) ); - $result = $paginationExtension->getResult($queryBuilder, Dummy::class, 'get'); + $result = $paginationExtension->getResult($queryBuilder, Dummy::class, 'get', $context); $this->assertInstanceOf(PartialPaginatorInterface::class, $result); $this->assertInstanceOf(PaginatorInterface::class, $result); @@ -1081,7 +1084,17 @@ public function testGetResultWithFetchJoinCollectionDisabled() $doctrinePaginatorReflectionProperty->setAccessible(true); $doctrinePaginator = $doctrinePaginatorReflectionProperty->getValue($result); - $this->assertFalse($doctrinePaginator->getFetchJoinCollection()); + $this->assertSame($expected, $doctrinePaginator->getFetchJoinCollection()); + } + + public function fetchJoinCollectionProvider(): array + { + return [ + 'collection disabled' => [['pagination_fetch_join_collection' => false], ['collection_operation_name' => 'get'], false], + 'collection enabled' => [['pagination_fetch_join_collection' => true], ['collection_operation_name' => 'get'], true], + 'graphql disabled' => [['pagination_fetch_join_collection' => false], ['graphql_operation_name' => 'query'], false], + 'graphql enabled' => [['pagination_fetch_join_collection' => true], ['graphql_operation_name' => 'query'], true], + ]; } /** @@ -1133,7 +1146,10 @@ public function testLegacyGetResultWithFetchJoinCollectionDisabled() $this->assertFalse($doctrinePaginator->getFetchJoinCollection()); } - public function testGetResultWithUseOutputWalkersDisabled() + /** + * @dataProvider fetchUseOutputWalkersProvider + */ + public function testGetResultWithUseOutputWalkers(array $attributes, array $context, bool $expected) { $dummyMetadata = new ClassMetadata(Dummy::class); @@ -1154,7 +1170,7 @@ public function testGetResultWithUseOutputWalkersDisabled() $managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($entityManagerProphecy); $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class); - $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, null, ['pagination_use_output_walkers' => false])); + $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, null, $attributes)); $paginationExtension = new PaginationExtension( $managerRegistryProphecy->reveal(), @@ -1162,7 +1178,7 @@ public function testGetResultWithUseOutputWalkersDisabled() new Pagination($resourceMetadataFactoryProphecy->reveal()) ); - $result = $paginationExtension->getResult($queryBuilder, Dummy::class, 'get'); + $result = $paginationExtension->getResult($queryBuilder, Dummy::class, 'get', $context); $this->assertInstanceOf(PartialPaginatorInterface::class, $result); $this->assertInstanceOf(PaginatorInterface::class, $result); @@ -1171,7 +1187,17 @@ public function testGetResultWithUseOutputWalkersDisabled() $doctrinePaginatorReflectionProperty->setAccessible(true); $doctrinePaginator = $doctrinePaginatorReflectionProperty->getValue($result); - $this->assertFalse($doctrinePaginator->getUseOutputWalkers()); + $this->assertSame($expected, $doctrinePaginator->getUseOutputWalkers()); + } + + public function fetchUseOutputWalkersProvider(): array + { + return [ + 'collection disabled' => [['pagination_use_output_walkers' => false], ['collection_operation_name' => 'get'], false], + 'collection enabled' => [['pagination_use_output_walkers' => true], ['collection_operation_name' => 'get'], true], + 'graphql disabled' => [['pagination_use_output_walkers' => false], ['graphql_operation_name' => 'query'], false], + 'graphql enabled' => [['pagination_use_output_walkers' => true], ['graphql_operation_name' => 'query'], true], + ]; } /** From 12d68befc4f7a28764901aa480bad573a2e2fe30 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 9 Mar 2021 15:35:21 +0100 Subject: [PATCH 2/2] chore: add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e590147558b..36e7fc765c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 2.6.4 * Doctrine: Fix purging HTTP cache for unreadable relations (#3441) +* GraphQL: Manage `pagination_use_output_walkers` and `pagination_fetch_join_collection` for operations (#3311) * Swagger UI: Remove Google fonts (#4112) ## 2.6.3