|
9 | 9 | use ApiSkeletons\Doctrine\GraphQL\Event\FilterCriteria; |
10 | 10 | use ApiSkeletons\Doctrine\GraphQL\Type\Entity; |
11 | 11 | use ApiSkeletons\Doctrine\GraphQL\Type\TypeManager; |
| 12 | +use ArrayObject; |
12 | 13 | use Closure; |
13 | 14 | use Doctrine\Common\Collections\Collection; |
14 | 15 | use Doctrine\Common\Collections\Criteria; |
|
25 | 26 |
|
26 | 27 | class ResolveCollectionFactory |
27 | 28 | { |
28 | | - /** @param mixed[] $metadata */ |
29 | 29 | public function __construct( |
30 | 30 | protected EntityManager $entityManager, |
31 | 31 | protected Config $config, |
32 | 32 | protected FieldResolver $fieldResolver, |
33 | 33 | protected TypeManager $typeManager, |
34 | 34 | protected EventDispatcher $eventDispatcher, |
35 | | - protected array $metadata, |
| 35 | + protected ArrayObject $metadata, |
36 | 36 | ) { |
37 | 37 | } |
38 | 38 |
|
@@ -61,16 +61,17 @@ public function get(Entity $entity): Closure |
61 | 61 | $fieldResolver = $this->fieldResolver; |
62 | 62 | $collection = $fieldResolver($source, $args, $context, $info); |
63 | 63 |
|
64 | | - $collectionMetadata = $this->entityManager->getMetadataFactory() |
65 | | - ->getMetadataFor( |
66 | | - (string) $this->entityManager->getMetadataFactory() |
67 | | - ->getMetadataFor(ClassUtils::getRealClass($source::class)) |
68 | | - ->getAssociationTargetClass($info->fieldName), |
69 | | - ); |
70 | | - |
71 | 64 | $entityClass = ClassUtils::getRealClass($source::class); |
72 | 65 |
|
| 66 | + $targetClassName = (string) $this->entityManager->getMetadataFactory() |
| 67 | + ->getMetadataFor($entityClass) |
| 68 | + ->getAssociationTargetClass($info->fieldName); |
| 69 | + |
| 70 | + $collectionMetadata = $this->entityManager->getMetadataFactory() |
| 71 | + ->getMetadataFor($targetClassName); |
| 72 | + |
73 | 73 | return $this->buildPagination( |
| 74 | + $targetClassName, |
74 | 75 | $args['pagination'] ?? [], |
75 | 76 | $collection, |
76 | 77 | $this->buildCriteria($args['filter'] ?? [], $collectionMetadata), |
@@ -130,6 +131,7 @@ private function buildCriteria(array $filter, ClassMetadata $collectionMetadata) |
130 | 131 | * @return mixed[] |
131 | 132 | */ |
132 | 133 | private function buildPagination( |
| 134 | + string $targetClassName, |
133 | 135 | array $pagination, |
134 | 136 | PersistentCollection $collection, |
135 | 137 | Criteria $criteria, |
@@ -161,7 +163,7 @@ private function buildPagination( |
161 | 163 |
|
162 | 164 | $itemCount = count($collection->matching($criteria)); |
163 | 165 |
|
164 | | - $offsetAndLimit = $this->calculateOffsetAndLimit($paginationFields, $itemCount); |
| 166 | + $offsetAndLimit = $this->calculateOffsetAndLimit($targetClassName, $paginationFields, $itemCount); |
165 | 167 | if ($offsetAndLimit['offset']) { |
166 | 168 | $criteria->setFirstResult($offsetAndLimit['offset']); |
167 | 169 | } |
@@ -244,11 +246,16 @@ protected function buildEdgesAndCursors(Collection $items, array $offsetAndLimit |
244 | 246 | * |
245 | 247 | * @return array<string, int> |
246 | 248 | */ |
247 | | - protected function calculateOffsetAndLimit(array $paginationFields, int $itemCount): array |
| 249 | + protected function calculateOffsetAndLimit(string $targetClassName, array $paginationFields, int $itemCount): array |
248 | 250 | { |
249 | 251 | $offset = 0; |
250 | 252 |
|
251 | | - $limit = $this->config->getLimit(); |
| 253 | + $limit = $this->metadata[$targetClassName]['limit']; |
| 254 | + |
| 255 | + if (! $limit) { |
| 256 | + $limit = $this->config->getLimit(); |
| 257 | + } |
| 258 | + |
252 | 259 | $adjustedLimit = $paginationFields['first'] ?: $paginationFields['last'] ?: $limit; |
253 | 260 |
|
254 | 261 | if ($adjustedLimit < $limit) { |
|
0 commit comments