Skip to content

Commit 5245c1a

Browse files
authored
Merge pull request #3038 from alanpoulain/merge-2.4
Merge 2.4 into master
2 parents 6e9ccf7 + b0cd959 commit 5245c1a

File tree

12 files changed

+130
-14
lines changed

12 files changed

+130
-14
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ parameters:
2424
# Real problems, hard to fix
2525
- '#Parameter \#2 \$dqlPart of method Doctrine\\ORM\\QueryBuilder::add\(\) expects array\|object, string given\.#'
2626
-
27-
message: '#Return type \(int\) of method ApiPlatform\\Core\\Identifier\\Normalizer\\IntegerDenormalizer::denormalize\(\) should be compatible with return type \(object\) of method Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::denormalize\(\)#'
27+
message: '#Return type \(int\) of method ApiPlatform\\Core\\Identifier\\Normalizer\\IntegerDenormalizer::denormalize\(\) should be compatible with return type \(array\|object\) of method Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::denormalize\(\)#'
2828
path: %currentWorkingDirectory%/src/Identifier/Normalizer/IntegerDenormalizer.php
2929

3030
# False positives

src/Bridge/Doctrine/Orm/CollectionDataProvider.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
2121
use ApiPlatform\Core\Exception\RuntimeException;
2222
use Doctrine\Common\Persistence\ManagerRegistry;
23-
use Doctrine\Common\Persistence\ObjectManager;
2423
use Doctrine\ORM\EntityManagerInterface;
2524

2625
/**
@@ -56,7 +55,7 @@ public function supports(string $resourceClass, string $operationName = null, ar
5655
*/
5756
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
5857
{
59-
/** @var ObjectManager $manager */
58+
/** @var EntityManagerInterface $manager */
6059
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
6160

6261
$repository = $manager->getRepository($resourceClass);

src/Bridge/Elasticsearch/DataProvider/ItemDataProvider.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ public function getItem(string $resourceClass, $id, ?string $operationName = nul
101101
return null;
102102
}
103103

104-
return $this->denormalizer->denormalize($document, $resourceClass, ItemNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true]);
104+
$item = $this->denormalizer->denormalize($document, $resourceClass, ItemNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true]);
105+
if (!\is_object($item) && null !== $item) {
106+
throw new \UnexpectedValueException('Expected item to be an object or null.');
107+
}
108+
109+
return $item;
105110
}
106111
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<services>
8-
<service id="test.api_platform.client" class="ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client" public="true">
8+
<service id="test.api_platform.client" class="ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client" shared="false" public="true">
99
<argument type="service" id="test.client" />
1010
</service>
1111
</services>

src/Bridge/Symfony/Bundle/Test/ApiTestCase.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ abstract class ApiTestCase extends KernelTestCase
2828
{
2929
use ApiTestAssertionsTrait;
3030

31-
protected function doTearDown(): void
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
protected function tearDown(): void
3235
{
33-
parent::doTearDown();
36+
parent::tearDown();
37+
3438
self::getClient(null);
3539
}
3640

src/Bridge/Symfony/Bundle/Test/Client.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,18 @@ public function request(string $method, string $url, array $options = []): Respo
8989
$basic = $options['auth_basic'] ?? null;
9090
[$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions);
9191
$resolvedUrl = implode('', $url);
92-
9392
$server = [];
93+
9494
// Convert headers to a $_SERVER-like array
95-
foreach ($options['headers'] as $key => $value) {
95+
foreach (self::extractHeaders($options) as $key => $value) {
9696
if ('content-type' === $key) {
9797
$server['CONTENT_TYPE'] = $value[0] ?? '';
9898

9999
continue;
100100
}
101101

102102
// BrowserKit doesn't support setting several headers with the same name
103-
$server['HTTP_'.strtoupper(str_replace('-', '_', $key))] = $value[0] ?? '';
103+
$server['HTTP_'.strtoupper(strtr($key, '-', '_'))] = $value[0] ?? '';
104104
}
105105

106106
if ($basic) {
@@ -212,4 +212,28 @@ public function enableReboot(): void
212212
{
213213
$this->kernelBrowser->enableReboot();
214214
}
215+
216+
/**
217+
* Extracts headers depending on the symfony/http-client version being used.
218+
*
219+
* @return array<string, string[]>
220+
*/
221+
private static function extractHeaders(array $options): array
222+
{
223+
if (!isset($options['normalized_headers'])) {
224+
return $options['headers'];
225+
}
226+
227+
$headers = [];
228+
229+
/** @var string $key */
230+
foreach ($options['normalized_headers'] as $key => $values) {
231+
foreach ($values as $value) {
232+
[, $value] = explode(': ', $value, 2);
233+
$headers[$key][] = $value;
234+
}
235+
}
236+
237+
return $headers;
238+
}
215239
}

src/Bridge/Symfony/Bundle/Test/Response.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function __construct(HttpFoundationResponse $httpFoundationResponse, Brow
5555
}
5656
}
5757

58-
$this->content = $httpFoundationResponse->getContent();
58+
$this->content = (string) $httpFoundationResponse->getContent();
5959
$this->info = [
6060
'http_code' => $httpFoundationResponse->getStatusCode(),
6161
'error' => null,

src/GraphQl/Resolver/Stage/DeserializeStage.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ public function __invoke($objectToPopulate, string $resourceClass, string $opera
5454
$denormalizationContext[AbstractNormalizer::OBJECT_TO_POPULATE] = $objectToPopulate;
5555
}
5656

57-
return $this->denormalizer->denormalize($context['args']['input'], $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);
57+
$item = $this->denormalizer->denormalize($context['args']['input'], $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);
58+
59+
if (!\is_object($item)) {
60+
throw new \UnexpectedValueException('Expected item to be an object.');
61+
}
62+
63+
return $item;
5864
}
5965
}

src/HttpCache/EventListener/AddHeadersListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function onKernelResponse(FilterResponseEvent $event): void
6363
}
6464

6565
if ($this->etag && !$response->getEtag()) {
66-
$response->setEtag(md5($response->getContent()));
66+
$response->setEtag(md5((string) $response->getContent()));
6767
}
6868

6969
if (null !== ($maxAge = $resourceCacheHeaders['max_age'] ?? $this->maxAge) && !$response->headers->hasCacheControlDirective('max-age')) {

src/Serializer/AbstractItemNormalizer.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ public function denormalize($data, $class, $format = null, array $context = [])
183183
throw new LogicException('Cannot denormalize the input because the injected serializer is not a denormalizer');
184184
}
185185
$denormalizedInput = $this->serializer->denormalize($data, $inputClass, $format, $context);
186+
if (!\is_object($denormalizedInput)) {
187+
throw new \UnexpectedValueException('Expected denormalized input to be an object.');
188+
}
186189

187190
return $dataTransformer->transform($denormalizedInput, $resourceClass, $dataTransformerContext);
188191
}
@@ -437,7 +440,12 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $
437440
}
438441

439442
try {
440-
return $this->serializer->denormalize($value, $className, $format, $context);
443+
$item = $this->serializer->denormalize($value, $className, $format, $context);
444+
if (!\is_object($item) && null !== $item) {
445+
throw new \UnexpectedValueException('Expected item to be an object or null.');
446+
}
447+
448+
return $item;
441449
} catch (InvalidValueException $e) {
442450
if (!$supportsPlainIdentifiers) {
443451
throw $e;

0 commit comments

Comments
 (0)