Skip to content

Commit a60b771

Browse files
committed
Allow to use multiple fields
1 parent 7efd9f8 commit a60b771

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

src/Hydra/Serializer/PartialCollectionViewNormalizer.php

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,37 +78,26 @@ public function normalize($object, $format = null, array $context = [])
7878
}
7979

8080
$metadata = isset($context['resource_class']) && null !== $this->resourceMetadataFactory ? $this->resourceMetadataFactory->create($context['resource_class']) : null;
81-
$isPaginatedWithCursor = $paginated && null !== $metadata && null !== $cursorPaginationAttribute = $metadata->getCollectionOperationAttribute('pagination_via_cursor');
81+
$isPaginatedWithCursor = $paginated && null !== $metadata && null !== $cursorPaginationAttribute = $metadata->getCollectionOperationAttribute($context['collection_operation_name'], 'pagination_via_cursor', null, true);
8282

8383
$data['hydra:view'] = [
8484
'@id' => IriHelper::createIri($parsed['parts'], $parsed['parameters'], $this->pageParameterName, $paginated && !$isPaginatedWithCursor ? $currentPage : null),
8585
'@type' => 'hydra:PartialCollectionView',
8686
];
8787

8888
if ($isPaginatedWithCursor) {
89-
$forwardRangeOperator = 'desc' === strtolower($cursorPaginationAttribute['direction']) ? 'lt' : 'gt';
90-
$backwardRangeOperator = 'gt' === $forwardRangeOperator ? 'lt' : 'gt';
91-
9289
$objects = iterator_to_array($object);
9390
$firstObject = current($objects);
9491
$lastObject = end($objects);
9592

9693
$data['hydra:view']['@id'] = IriHelper::createIri($parsed['parts'], $parsed['parameters']);
9794

9895
if (false !== $lastObject) {
99-
$data['hydra:view']['hydra:next'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], [
100-
$cursorPaginationAttribute['field'] => [
101-
$forwardRangeOperator => (string) $this->propertyAccessor->getValue($lastObject, $cursorPaginationAttribute['field']),
102-
],
103-
]));
96+
$data['hydra:view']['hydra:next'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], $this->cursorPaginationFields($cursorPaginationAttribute, 1, $lastObject)));
10497
}
10598

10699
if (false !== $firstObject) {
107-
$data['hydra:view']['hydra:previous'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], [
108-
$cursorPaginationAttribute['field'] => [
109-
$backwardRangeOperator => (string) $this->propertyAccessor->getValue($firstObject, $cursorPaginationAttribute['field']),
110-
],
111-
]));
100+
$data['hydra:view']['hydra:previous'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], $this->cursorPaginationFields($cursorPaginationAttribute, -1, $firstObject)));
112101
}
113102
} elseif ($paginated) {
114103
if (null !== $lastPage) {
@@ -153,4 +142,22 @@ public function setNormalizer(NormalizerInterface $normalizer)
153142
$this->collectionNormalizer->setNormalizer($normalizer);
154143
}
155144
}
145+
146+
private function cursorPaginationFields(array $fields, int $direction, $object)
147+
{
148+
$paginationFilters = [];
149+
150+
foreach ($fields as $field) {
151+
$forwardRangeOperator = 'desc' === strtolower($field['direction']) ? 'lt' : 'gt';
152+
$backwardRangeOperator = 'gt' === $forwardRangeOperator ? 'lt' : 'gt';
153+
154+
$operator = $direction > 0 ? $forwardRangeOperator : $backwardRangeOperator;
155+
156+
$paginationFilters[$field['field']] = [
157+
$operator => (string) $this->propertyAccessor->getValue($object, $field['field']),
158+
];
159+
}
160+
161+
return $paginationFilters;
162+
}
156163
}

tests/Fixtures/TestBundle/Entity/SoMany.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
* @ApiResource(attributes={
2525
* "pagination_partial"=true,
2626
* "pagination_via_cursor"={
27-
* "field"="id",
28-
* "direction"="DESC"
27+
* {"field"="id", "direction"="DESC"}
2928
* }
3029
* })
3130
*

tests/Hydra/Serializer/PartialCollectionViewNormalizerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function testNormalizeDoesNotChangeSubLevel()
3434
$decoratedNormalizerProphecy->normalize(Argument::any(), null, ['jsonld_sub_level' => true])->willReturn(['foo' => 'bar'])->shouldBeCalled();
3535
$resourceMetadataFactory = $this->prophesize(ResourceMetadataFactoryInterface::class);
3636

37-
$normalizer = new PartialCollectionViewNormalizer($decoratedNormalizerProphecy->reveal(), $resourceMetadataFactory->reveal());
37+
$normalizer = new PartialCollectionViewNormalizer($decoratedNormalizerProphecy->reveal(), 'page', 'pagination', $resourceMetadataFactory->reveal());
3838
$this->assertEquals(['foo' => 'bar'], $normalizer->normalize(new \stdClass(), null, ['jsonld_sub_level' => true]));
3939
}
4040

@@ -44,7 +44,7 @@ public function testNormalizeDoesNotChangeWhenNoFilterNorPagination()
4444
$decoratedNormalizerProphecy->normalize(Argument::any(), null, Argument::type('array'))->willReturn(['foo' => 'bar'])->shouldBeCalled();
4545
$resourceMetadataFactory = $this->prophesize(ResourceMetadataFactoryInterface::class);
4646

47-
$normalizer = new PartialCollectionViewNormalizer($decoratedNormalizerProphecy->reveal(), $resourceMetadataFactory->reveal());
47+
$normalizer = new PartialCollectionViewNormalizer($decoratedNormalizerProphecy->reveal(), 'page', 'pagination', $resourceMetadataFactory->reveal());
4848
$this->assertEquals(['foo' => 'bar'], $normalizer->normalize(new \stdClass(), null, ['request_uri' => '/?page=1&pagination=1']));
4949
}
5050

0 commit comments

Comments
 (0)