Skip to content

Commit e286d72

Browse files
committed
[WIP] Fix some Behat tests
1 parent 39900b9 commit e286d72

File tree

9 files changed

+686
-785
lines changed

9 files changed

+686
-785
lines changed

features/doctrine/date_filter.feature

Lines changed: 346 additions & 658 deletions
Large diffs are not rendered by default.

features/hydra/collection.feature

Lines changed: 257 additions & 88 deletions
Large diffs are not rendered by default.

src/Bridge/Doctrine/Common/Filter/DateFilterTrait.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
namespace ApiPlatform\Core\Bridge\Doctrine\Common\Filter;
1515

1616
use ApiPlatform\Core\Bridge\Doctrine\Common\PropertyHelperTrait;
17+
use ApiPlatform\Core\Exception\InvalidArgumentException;
18+
use Psr\Log\LoggerInterface;
1719

1820
/**
1921
* Trait for filtering the collection by date intervals.
@@ -54,6 +56,8 @@ public function getDescription(string $resourceClass): array
5456

5557
abstract protected function getProperties(): ?array;
5658

59+
abstract protected function getLogger(): LoggerInterface;
60+
5761
/**
5862
* Determines whether the given property refers to a date field.
5963
*/
@@ -75,4 +79,17 @@ protected function getFilterDescription(string $property, string $period): array
7579
],
7680
];
7781
}
82+
83+
private function normalizeValue(string $value, string $dateTimeClass, string $property, string $parameterType): ?\DateTimeInterface
84+
{
85+
try {
86+
return new $dateTimeClass($value);
87+
} catch (\Exception $e) {
88+
$this->getLogger()->notice('Invalid filter ignored', [
89+
'exception' => new InvalidArgumentException(sprintf('Invalid value for "%s[%s]". Use date/time string supported by %s::__construct', $property, $parameterType, $dateTimeClass)),
90+
]);
91+
92+
return null;
93+
}
94+
}
7895
}

src/Bridge/Doctrine/MongoDbOdm/Filter/DateFilter.php

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ protected function filterProperty(string $property, $values, Builder $aggregatio
6969
$matchField,
7070
self::PARAMETER_BEFORE,
7171
$values[self::PARAMETER_BEFORE],
72-
$nullManagement
72+
$nullManagement,
73+
$property
7374
);
7475
}
7576

@@ -79,7 +80,8 @@ protected function filterProperty(string $property, $values, Builder $aggregatio
7980
$matchField,
8081
self::PARAMETER_STRICTLY_BEFORE,
8182
$values[self::PARAMETER_STRICTLY_BEFORE],
82-
$nullManagement
83+
$nullManagement,
84+
$property
8385
);
8486
}
8587

@@ -89,7 +91,8 @@ protected function filterProperty(string $property, $values, Builder $aggregatio
8991
$matchField,
9092
self::PARAMETER_AFTER,
9193
$values[self::PARAMETER_AFTER],
92-
$nullManagement
94+
$nullManagement,
95+
$property
9396
);
9497
}
9598

@@ -99,24 +102,18 @@ protected function filterProperty(string $property, $values, Builder $aggregatio
99102
$matchField,
100103
self::PARAMETER_STRICTLY_AFTER,
101104
$values[self::PARAMETER_STRICTLY_AFTER],
102-
$nullManagement
105+
$nullManagement,
106+
$property
103107
);
104108
}
105109
}
106110

107111
/**
108112
* Adds the match stage according to the chosen null management.
109113
*/
110-
private function addMatch(Builder $aggregationBuilder, string $field, string $operator, string $value, string $nullManagement = null): void
114+
private function addMatch(Builder $aggregationBuilder, string $field, string $operator, string $value, ?string $nullManagement, string $property): void
111115
{
112-
try {
113-
$value = new \DateTime($value);
114-
} catch (\Exception $e) {
115-
// Silently ignore this filter if it can not be transformed to a \DateTime
116-
$this->logger->notice('Invalid filter ignored', [
117-
'exception' => new InvalidArgumentException(sprintf('The field "%s" has a wrong date format. Use one accepted by the \DateTime constructor', $field)),
118-
]);
119-
116+
if (null === $value = $this->normalizeValue($value, 'DateTime', $property, $operator)) {
120117
return;
121118
}
122119

@@ -129,7 +126,7 @@ private function addMatch(Builder $aggregationBuilder, string $field, string $op
129126

130127
if ((self::INCLUDE_NULL_BEFORE === $nullManagement && \in_array($operator, [self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE], true)) ||
131128
(self::INCLUDE_NULL_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER], true)) ||
132-
(self::INCLUDE_NULL_BEFORE_AND_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER, self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE], true))
129+
(self::INCLUDE_NULL_BEFORE_AND_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE, self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER], true))
133130
) {
134131
$aggregationBuilder->match()->addOr(
135132
$aggregationBuilder->matchExpr()->field($field)->operator($operatorValue[$operator], $value),

src/Bridge/Doctrine/Orm/Filter/DateFilter.php

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
7979
self::PARAMETER_BEFORE,
8080
$values[self::PARAMETER_BEFORE],
8181
$nullManagement,
82-
$type
82+
$type,
83+
$property
8384
);
8485
}
8586

@@ -92,7 +93,8 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
9293
self::PARAMETER_STRICTLY_BEFORE,
9394
$values[self::PARAMETER_STRICTLY_BEFORE],
9495
$nullManagement,
95-
$type
96+
$type,
97+
$property
9698
);
9799
}
98100

@@ -105,7 +107,8 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
105107
self::PARAMETER_AFTER,
106108
$values[self::PARAMETER_AFTER],
107109
$nullManagement,
108-
$type
110+
$type,
111+
$property
109112
);
110113
}
111114

@@ -118,7 +121,8 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
118121
self::PARAMETER_STRICTLY_AFTER,
119122
$values[self::PARAMETER_STRICTLY_AFTER],
120123
$nullManagement,
121-
$type
124+
$type,
125+
$property
122126
);
123127
}
124128
}
@@ -128,20 +132,35 @@ protected function filterProperty(string $property, $values, QueryBuilder $query
128132
*
129133
* @param string|DBALType $type
130134
*/
131-
protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, string $operator, string $value, string $nullManagement = null, $type = null)
135+
protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $alias, string $field, string $operator, string $value, string $nullManagement = null, $type = null/*, string $property*/)
132136
{
137+
if (\func_num_args() > 8) {
138+
$property = func_get_arg(8);
139+
} else {
140+
if (__CLASS__ !== \get_class($this)) {
141+
$r = new \ReflectionMethod($this, __FUNCTION__);
142+
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
143+
@trigger_error(sprintf('Method %s() will have 9 non-optional arguments in API Platform 3.0. Not passing arguments 7-9 is deprecated since API Platform 2.4.', __FUNCTION__), E_USER_DEPRECATED);
144+
}
145+
}
146+
}
147+
133148
$type = (string) $type;
134-
try {
135-
$value = false === strpos($type, '_immutable') ? new \DateTime($value) : new \DateTimeImmutable($value);
136-
} catch (\Exception $e) {
137-
// Silently ignore this filter if it can not be transformed to a \DateTime
138-
$this->logger->notice('Invalid filter ignored', [
139-
'exception' => new InvalidArgumentException(sprintf('The field "%s" has a wrong date format. Use one accepted by the \DateTime constructor', $field)),
140-
]);
149+
$dateTimeClass = false === strpos($type, '_immutable') ? 'DateTime' : 'DateTimeImmutable';
141150

151+
if (null === $value = $this->normalizeValue($value, $dateTimeClass, $property ?? $field, $operator)) {
142152
return;
143153
}
144154

155+
/*
156+
* Doctrine ORM/DBAL uses the PHP default timezone
157+
*
158+
* @see https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/working-with-datetime.html#default-timezone-gotcha
159+
*/
160+
if (false === strpos($type, 'tz')) {
161+
$value = $value->setTimezone(new \DateTimeZone(date_default_timezone_get()));
162+
}
163+
145164
$valueParameter = $queryNameGenerator->generateParameterName($field);
146165
$operatorValue = [
147166
self::PARAMETER_BEFORE => '<=',
@@ -156,7 +175,7 @@ protected function addWhere(QueryBuilder $queryBuilder, QueryNameGeneratorInterf
156175
} elseif (
157176
(self::INCLUDE_NULL_BEFORE === $nullManagement && \in_array($operator, [self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE], true)) ||
158177
(self::INCLUDE_NULL_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER], true)) ||
159-
(self::INCLUDE_NULL_BEFORE_AND_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER, self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE], true))
178+
(self::INCLUDE_NULL_BEFORE_AND_AFTER === $nullManagement && \in_array($operator, [self::PARAMETER_BEFORE, self::PARAMETER_STRICTLY_BEFORE, self::PARAMETER_AFTER, self::PARAMETER_STRICTLY_AFTER], true))
160179
) {
161180
$queryBuilder->andWhere($queryBuilder->expr()->orX(
162181
$baseWhere,

src/Hal/Serializer/CollectionNormalizer.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ final class CollectionNormalizer extends AbstractCollectionNormalizer
3232
*/
3333
protected function getPaginationData($object, array $context = []): array
3434
{
35-
[$paginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems] = $this->getPaginationConfig($object, $context);
35+
[$isPaginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems] = $this->getPaginationConfig($object, $context);
3636
$parsed = IriHelper::parseIri($context['request_uri'] ?? '/', $this->pageParameterName);
3737

3838
$data = [
@@ -51,7 +51,7 @@ protected function getPaginationData($object, array $context = []): array
5151
$data['_links']['prev']['href'] = IriHelper::createIri($parsed['parts'], $parsed['parameters'], $this->pageParameterName, $currentPage - 1.);
5252
}
5353

54-
if ((null !== $lastPage && $currentPage !== $lastPage) || (null === $lastPage && $pageTotalItems >= $itemsPerPage)) {
54+
if (null !== $lastPage && $currentPage !== $lastPage || null === $lastPage && $pageTotalItems >= $itemsPerPage) {
5555
$data['_links']['next']['href'] = IriHelper::createIri($parsed['parts'], $parsed['parameters'], $this->pageParameterName, $currentPage + 1.);
5656
}
5757
}
@@ -60,7 +60,7 @@ protected function getPaginationData($object, array $context = []): array
6060
$data['totalItems'] = $totalItems;
6161
}
6262

63-
if ($paginator) {
63+
if ($isPaginator) {
6464
$data['itemsPerPage'] = (int) $itemsPerPage;
6565
}
6666

src/Hydra/Serializer/PartialCollectionViewNormalizer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,14 @@ public function normalize($object, $format = null, array $context = [])
4949
return $data;
5050
}
5151

52-
$currentPage = $lastPage = $itemsPerPage = $pageTotalItems = null;
52+
$currentPage = null;
53+
$lastPage = null;
54+
$itemsPerPage = null;
55+
$pageTotalItems = null;
5356
if ($paginated = $object instanceof PartialPaginatorInterface) {
5457
if ($object instanceof PaginatorInterface) {
55-
$paginated = 1. !== $lastPage = $object->getLastPage();
58+
$paginated = true;
59+
$lastPage = $object->getLastPage();
5660
} else {
5761
$itemsPerPage = $object->getItemsPerPage();
5862
$pageTotalItems = (float) \count($object);

src/JsonApi/Serializer/CollectionNormalizer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class CollectionNormalizer extends AbstractCollectionNormalizer
3333
*/
3434
protected function getPaginationData($object, array $context = []): array
3535
{
36-
[$paginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems] = $this->getPaginationConfig($object, $context);
36+
[$isPaginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems] = $this->getPaginationConfig($object, $context);
3737
$parsed = IriHelper::parseIri($context['request_uri'] ?? '/', $this->pageParameterName);
3838

3939
$data = [
@@ -61,7 +61,7 @@ protected function getPaginationData($object, array $context = []): array
6161
$data['meta']['totalItems'] = $totalItems;
6262
}
6363

64-
if ($paginator) {
64+
if ($isPaginator) {
6565
$data['meta']['itemsPerPage'] = (int) $itemsPerPage;
6666
$data['meta']['currentPage'] = (int) $currentPage;
6767
}

src/Serializer/AbstractCollectionNormalizer.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,20 @@ protected function normalizeRawCollection($object, $format = null, array $contex
116116
*/
117117
protected function getPaginationConfig($object, array $context = []): array
118118
{
119-
$currentPage = $lastPage = $itemsPerPage = $pageTotalItems = $totalItems = null;
120-
$paginated = $paginator = false;
119+
$currentPage = null;
120+
$lastPage = null;
121+
$itemsPerPage = null;
122+
$pageTotalItems = null;
123+
$totalItems = null;
124+
$paginated = false;
125+
$isPaginator = false;
121126

122127
if ($object instanceof PartialPaginatorInterface) {
123-
$paginated = $paginator = true;
128+
$paginated = true;
129+
$isPaginator = true;
124130
if ($object instanceof PaginatorInterface) {
125-
$paginated = 1. !== $lastPage = $object->getLastPage();
131+
$paginated = true;
132+
$lastPage = $object->getLastPage();
126133
$totalItems = $object->getTotalItems();
127134
} else {
128135
$pageTotalItems = (float) \count($object);
@@ -134,7 +141,7 @@ protected function getPaginationConfig($object, array $context = []): array
134141
$totalItems = \count($object);
135142
}
136143

137-
return [$paginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems];
144+
return [$isPaginator, $paginated, $currentPage, $itemsPerPage, $lastPage, $pageTotalItems, $totalItems];
138145
}
139146

140147
/**

0 commit comments

Comments
 (0)