Skip to content

Commit 5fa9b56

Browse files
authored
Merge pull request #3291 from alanpoulain/merge-2.5
Merge 2.5
2 parents f56f21d + 6179699 commit 5fa9b56

File tree

14 files changed

+35
-48
lines changed

14 files changed

+35
-48
lines changed

.circleci/config.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,6 @@ executors:
183183
type: string
184184
docker:
185185
- image: circleci/php:<< parameters.php_version >>-node
186-
environment:
187-
SYMFONY_REQUIRE: ^3.4 || ^4.0 || ^5.0
188186

189187
jobs:
190188
php-cs-fixer:

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ env:
1111
EXT_MONGODB_VERSION: '1.6.0'
1212
EXT_PCOV_VERSION: '1.0.6'
1313
LEGACY: '0'
14-
SYMFONY_REQUIRE: ^3.4 || ^4.0 || ^5.0
1514

1615
jobs:
1716
phpunit:

.travis.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
language: php
22

3-
env:
4-
global:
5-
- SYMFONY_REQUIRE='^3.4 || ^4.0 || ^5.0'
6-
73
cache:
84
directories:
95
- $HOME/.composer/cache

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
* MongoDB: Possibility to add execute options (aggregate command fields) for a resource, like `allowDiskUse` (#3144)
66
* GraphQL: Allow to format GraphQL errors based on exceptions (#3063)
77
* GraphQL: Add page-based pagination (#3175)
8-
* OpenAPI: Add PHP default values to the documentation (#2386)
8+
* OpenAPI: Add PHP default values to the documentation (#2386)
9+
10+
## 2.5.3
11+
12+
* Compatibility with Symfony 5
13+
* GraphQL: Fix `hasNextPage` when `offset > itemsPerPage`
914

1015
## 2.5.2
1116

composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@
5151
"phpdocumentor/type-resolver": "^0.3 || ^0.4",
5252
"phpspec/prophecy": "^1.8",
5353
"phpstan/extension-installer": "^1.0",
54-
"phpstan/phpstan": "^0.11.10",
5554
"phpstan/phpstan-doctrine": "^0.11.5",
5655
"phpstan/phpstan-phpunit": "^0.11.2",
56+
"phpstan/phpstan-shim": "^0.11.10",
5757
"phpstan/phpstan-symfony": "^0.11.6",
5858
"phpunit/phpunit": "^7.5.2 || ^8.0",
5959
"psr/log": "^1.0",
@@ -128,6 +128,9 @@
128128
"extra": {
129129
"branch-alias": {
130130
"dev-master": "2.6.x-dev"
131+
},
132+
"symfony": {
133+
"require": "^3.4 || ^4.0 || ^5.0"
131134
}
132135
}
133136
}

phpstan.neon.dist

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -107,28 +107,14 @@ parameters:
107107
- '#Method ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Filter\\(AbstractFilter|FilterInterface)::apply\(\) invoked with 5 parameters, 3-4 required\.#'
108108
- '#Method ApiPlatform\\Core\\PathResolver\\OperationPathResolverInterface::resolveOperationPath\(\) invoked with 4 parameters, 3 required\.#'
109109

110-
# Expected, due to forward compatibility
111-
-
112-
message: '#Class Symfony\\Component\\ErrorHandler\\ErrorRenderer\\ErrorRendererInterface not found\.#'
113-
path: %currentWorkingDirectory%/tests/Fixtures/app/AppKernel.php
114-
- '#Class Symfony\\Component\\ErrorHandler\\Exception\\FlattenException not found\.#'
115-
-
116-
message: '#Class Symfony\\Component\\HttpKernel\\EventListener\\ErrorListener not found\.#'
117-
path: %currentWorkingDirectory%/src/EventListener/ExceptionListener.php
118-
-
119-
message: '#Instantiated class Symfony\\Component\\HttpKernel\\EventListener\\ErrorListener not found\.#'
120-
path: %currentWorkingDirectory%/src/EventListener/ExceptionListener.php
110+
# Expected, due to backward compatibility
121111
-
122-
message: '#Parameter \$exception of method ApiPlatform\\Core\\Action\\ExceptionAction::__invoke\(\) has invalid typehint type Symfony\\Component\\ErrorHandler\\Exception\\FlattenException\.#'
123-
path: %currentWorkingDirectory%/src/Action/ExceptionAction.php
124-
- '#Call to method get(Class|Headers|StatusCode)\(\) on an unknown class Symfony\\Component\\ErrorHandler\\Exception\\FlattenException\.#'
112+
message: "#Call to function method_exists\\(\\) with ApiPlatform\\\\Core\\\\JsonApi\\\\Serializer\\\\ItemNormalizer and 'setCircularReferenc…' will always evaluate to false\\.#"
113+
path: %currentWorkingDirectory%/tests/JsonApi/Serializer/ItemNormalizerTest.php
114+
115+
# Expected, due to forward compatibility
125116
-
126117
message: "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component.+' and 'getThrowable' will always evaluate to false\\.#"
127118
paths:
128119
- %currentWorkingDirectory%/tests/Bridge/Symfony/Validator/EventListener/ValidationExceptionListenerTest.php
129120
- %currentWorkingDirectory%/tests/EventListener/ExceptionListenerTest.php
130-
-
131-
message: '#Instanceof between bool\|float\|int|null and ArrayObject will always evaluate to false\.#'
132-
paths:
133-
- %currentWorkingDirectory%/src/JsonApi/Serializer/ItemNormalizer.php
134-
- %currentWorkingDirectory%/src/Serializer/AbstractItemNormalizer.php

src/Bridge/Symfony/Bundle/Resources/config/api.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@
214214
<service id="api_platform.listener.exception" class="ApiPlatform\Core\EventListener\ExceptionListener">
215215
<argument>api_platform.action.exception</argument>
216216
<argument type="service" id="logger" on-invalid="null" />
217+
<argument>false</argument>
218+
<argument type="service" id="exception_listener" on-invalid="null" />
217219

218220
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" priority="-96" />
219221
<tag name="monolog.logger" channel="request" />

src/EventListener/ExceptionListener.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Psr\Log\LoggerInterface;
1818
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
1919
use Symfony\Component\HttpKernel\EventListener\ErrorListener;
20-
use Symfony\Component\HttpKernel\EventListener\ExceptionListener as BaseExceptionListener;
20+
use Symfony\Component\HttpKernel\EventListener\ExceptionListener as LegacyExceptionListener;
2121

2222
/**
2323
* Handles requests errors.
@@ -29,13 +29,9 @@ final class ExceptionListener
2929
{
3030
private $exceptionListener;
3131

32-
public function __construct($controller, LoggerInterface $logger = null, $debug = false)
32+
public function __construct($controller, LoggerInterface $logger = null, $debug = false, ErrorListener $errorListener = null)
3333
{
34-
if (class_exists(ErrorListener::class)) {
35-
$this->exceptionListener = new ErrorListener($controller, $logger, $debug);
36-
} else {
37-
$this->exceptionListener = new BaseExceptionListener($controller, $logger, $debug);
38-
}
34+
$this->exceptionListener = $errorListener ? new ErrorListener($controller, $logger, $debug) : new LegacyExceptionListener($controller, $logger, $debug);
3935
}
4036

4137
public function onKernelException(ExceptionEvent $event): void

src/GraphQl/Resolver/Stage/SerializeStage.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ private function serializeCursorBasedPaginatedCollection(iterable $collection, a
149149
$data['pageInfo']['startCursor'] = base64_encode((string) $offset);
150150
$end = $offset + $nbPageItems - 1;
151151
$data['pageInfo']['endCursor'] = base64_encode((string) ($end >= 0 ? $end : 0));
152-
$data['pageInfo']['hasNextPage'] = (float) $offset + $collection->getItemsPerPage() * $collection->getCurrentPage() < $totalItems;
152+
$itemsPerPage = $collection->getItemsPerPage();
153+
$data['pageInfo']['hasNextPage'] = (float) ($itemsPerPage > 0 ? $offset % $itemsPerPage : $offset) + $itemsPerPage * $collection->getCurrentPage() < $totalItems;
153154
$data['pageInfo']['hasPreviousPage'] = $offset > 0;
154155
}
155156

src/Serializer/AbstractItemNormalizer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function __construct(PropertyNameCollectionFactoryInterface $propertyName
6868
return $this->iriConverter->getIriFromItem($object);
6969
};
7070
}
71-
if (!interface_exists(AdvancedNameConverterInterface::class)) {
71+
if (!interface_exists(AdvancedNameConverterInterface::class) && method_exists($this, 'setCircularReferenceHandler')) {
7272
$this->setCircularReferenceHandler($defaultContext['circular_reference_handler']);
7373
}
7474

tests/EventListener/ExceptionListenerTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\HttpFoundation\Request;
2020
use Symfony\Component\HttpFoundation\Response;
2121
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
22+
use Symfony\Component\HttpKernel\EventListener\ErrorListener;
2223
use Symfony\Component\HttpKernel\HttpKernelInterface;
2324

2425
/**
@@ -44,7 +45,7 @@ public function testOnKernelException(Request $request)
4445
$eventProphecy->getKernel()->willReturn($kernel);
4546
$eventProphecy->setResponse(Argument::type(Response::class))->shouldBeCalled();
4647

47-
$listener = new ExceptionListener('foo:bar');
48+
$listener = new ExceptionListener('foo:bar', null, false, class_exists(ErrorListener::class) ? $this->prophesize(ErrorListener::class)->reveal() : null);
4849
$listener->onKernelException($eventProphecy->reveal());
4950
}
5051

@@ -62,7 +63,7 @@ public function testDoNothingWhenNotAnApiCall()
6263
$eventProphecy->getRequest()->willReturn(new Request());
6364
$eventProphecy->setResponse(Argument::type(Response::class))->shouldNotBeCalled();
6465

65-
$listener = new ExceptionListener('foo:bar');
66+
$listener = new ExceptionListener('foo:bar', null, false, class_exists(ErrorListener::class) ? $this->prophesize(ErrorListener::class)->reveal() : null);
6667
$listener->onKernelException($eventProphecy->reveal());
6768
}
6869

@@ -75,7 +76,7 @@ public function testDoNothingWhenHtmlRequested()
7576
$eventProphecy->getRequest()->willReturn($request);
7677
$eventProphecy->setResponse(Argument::type(Response::class))->shouldNotBeCalled();
7778

78-
$listener = new ExceptionListener('foo:bar');
79+
$listener = new ExceptionListener('foo:bar', null, false, class_exists(ErrorListener::class) ? $this->prophesize(ErrorListener::class)->reveal() : null);
7980
$listener->onKernelException($eventProphecy->reveal());
8081
}
8182
}

tests/GraphQl/Resolver/Stage/SerializeStageTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function applyCollectionWithPaginationProvider(): array
144144
'paginator' => [new ArrayPaginator([new \stdClass(), new \stdClass(), new \stdClass()], 0, 2), [], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MA=='], ['node' => ['normalized_item'], 'cursor' => 'MQ==']], 'pageInfo' => ['startCursor' => 'MA==', 'endCursor' => 'MQ==', 'hasNextPage' => true, 'hasPreviousPage' => false]]],
145145
'paginator with after cursor' => [new ArrayPaginator([new \stdClass(), new \stdClass(), new \stdClass()], 1, 2), ['after' => 'MA=='], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ=='], ['node' => ['normalized_item'], 'cursor' => 'Mg==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'Mg==', 'hasNextPage' => false, 'hasPreviousPage' => true]]],
146146
'paginator with bad after cursor' => [new ArrayPaginator([], 0, 0), ['after' => '-'], null, \UnexpectedValueException::class, 'Cursor - is invalid'],
147-
'paginator with before cursor' => [new ArrayPaginator([new \stdClass(), new \stdClass(), new \stdClass()], 1, 1), ['before' => 'Mg=='], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'MQ==', 'hasNextPage' => false, 'hasPreviousPage' => true]]],
147+
'paginator with before cursor' => [new ArrayPaginator([new \stdClass(), new \stdClass(), new \stdClass()], 1, 1), ['before' => 'Mg=='], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'MQ==', 'hasNextPage' => true, 'hasPreviousPage' => true]]],
148148
'paginator with bad before cursor' => [new ArrayPaginator([], 0, 0), ['before' => '-'], null, \UnexpectedValueException::class, 'Cursor - is invalid'],
149149
'paginator with last' => [new ArrayPaginator([new \stdClass(), new \stdClass(), new \stdClass()], 1, 2), ['last' => 2], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ=='], ['node' => ['normalized_item'], 'cursor' => 'Mg==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'Mg==', 'hasNextPage' => false, 'hasPreviousPage' => true]]],
150150
];

tests/JsonApi/Serializer/ItemNormalizerTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,17 +256,17 @@ public function testNormalizeCircularReference()
256256
$normalizer->setSerializer($this->prophesize(SerializerInterface::class)->reveal());
257257

258258
$circularReferenceLimit = 2;
259-
if (interface_exists(AdvancedNameConverterInterface::class)) {
259+
if (!interface_exists(AdvancedNameConverterInterface::class) && method_exists($normalizer, 'setCircularReferenceLimit')) {
260+
$normalizer->setCircularReferenceLimit($circularReferenceLimit);
261+
260262
$context = [
261-
'circular_reference_limit' => $circularReferenceLimit,
262-
'circular_reference_limit_counters' => [spl_object_hash($circularReferenceEntity) => 2],
263+
'circular_reference_limit' => [spl_object_hash($circularReferenceEntity) => 2],
263264
'cache_error' => function () {},
264265
];
265266
} else {
266-
$normalizer->setCircularReferenceLimit($circularReferenceLimit);
267-
268267
$context = [
269-
'circular_reference_limit' => [spl_object_hash($circularReferenceEntity) => 2],
268+
'circular_reference_limit' => $circularReferenceLimit,
269+
'circular_reference_limit_counters' => [spl_object_hash($circularReferenceEntity) => 2],
270270
'cache_error' => function () {},
271271
];
272272
}

tests/Serializer/AbstractItemNormalizerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public function testNormalize()
181181
]);
182182
$normalizer->setSerializer($serializerProphecy->reveal());
183183

184-
if (!interface_exists(AdvancedNameConverterInterface::class)) {
184+
if (!interface_exists(AdvancedNameConverterInterface::class) && method_exists($normalizer, 'setIgnoredAttributes')) {
185185
$normalizer->setIgnoredAttributes(['alias']);
186186
}
187187

0 commit comments

Comments
 (0)