Skip to content

Commit f2d247a

Browse files
committed
Allow to use multiple fields
1 parent 5cddcaf commit f2d247a

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
@@ -79,37 +79,26 @@ public function normalize($object, $format = null, array $context = [])
7979
}
8080

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

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

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

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

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

107100
if (false !== $firstObject) {
108-
$data['hydra:view']['hydra:previous'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], [
109-
$cursorPaginationAttribute['field'] => [
110-
$backwardRangeOperator => (string) $this->propertyAccessor->getValue($firstObject, $cursorPaginationAttribute['field']),
111-
],
112-
]));
101+
$data['hydra:view']['hydra:previous'] = IriHelper::createIri($parsed['parts'], array_merge($parsed['parameters'], $this->cursorPaginationFields($cursorPaginationAttribute, -1, $firstObject)));
113102
}
114103
} elseif ($paginated) {
115104
if (null !== $lastPage) {
@@ -146,4 +135,22 @@ public function setNormalizer(NormalizerInterface $normalizer)
146135
$this->collectionNormalizer->setNormalizer($normalizer);
147136
}
148137
}
138+
139+
private function cursorPaginationFields(array $fields, int $direction, $object)
140+
{
141+
$paginationFilters = [];
142+
143+
foreach ($fields as $field) {
144+
$forwardRangeOperator = 'desc' === strtolower($field['direction']) ? 'lt' : 'gt';
145+
$backwardRangeOperator = 'gt' === $forwardRangeOperator ? 'lt' : 'gt';
146+
147+
$operator = $direction > 0 ? $forwardRangeOperator : $backwardRangeOperator;
148+
149+
$paginationFilters[$field['field']] = [
150+
$operator => (string) $this->propertyAccessor->getValue($object, $field['field']),
151+
];
152+
}
153+
154+
return $paginationFilters;
155+
}
149156
}

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
@@ -33,7 +33,7 @@ public function testNormalizeDoesNotChangeSubLevel()
3333
$decoratedNormalizerProphecy->normalize(Argument::any(), null, ['jsonld_sub_level' => true])->willReturn(['foo' => 'bar'])->shouldBeCalled();
3434
$resourceMetadataFactory = $this->prophesize(ResourceMetadataFactoryInterface::class);
3535

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

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

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

0 commit comments

Comments
 (0)