From b83b7d43940cc00bd1acd72acd865d13b393533c Mon Sep 17 00:00:00 2001 From: soyuka Date: Thu, 28 May 2026 14:52:02 +0200 Subject: [PATCH] fix(phpstan): correct json_decode args, narrow Eloquent rules, prune stale ignores - EntrypointAction: drop JSON_ERROR_NONE (wrong constant family for $flags), rely on defaults - ApiTestAssertionsTrait: JSON_THROW_ON_ERROR belongs in $flags, not $depth; use named arg - EloquentResourceCollectionMetadataFactory: filter rules to string-keyed entries before passing to replaceRequiredWithSometimes (Metadata::getRules() returns mixed, is_array narrows to array which loses the expected shape) - ParameterResourceMetadataCollectionFactory: remove obsolete @phpstan-ignore-line - phpstan.neon.dist: drop unmatched getInnermostType ignore pattern --- phpstan.neon.dist | 1 - src/GraphQl/Action/EntrypointAction.php | 6 +++--- .../EloquentResourceCollectionMetadataFactory.php | 8 +++++++- .../ParameterResourceMetadataCollectionFactory.php | 2 +- src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index d621e1f5e89..a2ee511dd99 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -85,7 +85,6 @@ parameters: # Expected, due to backward compatibility - '#Method GraphQL\\Type\\Definition\\WrappingType::getWrappedType\(\) invoked with 1 parameter, 0 required\.#' - '#Access to an undefined property GraphQL\\Type\\Definition\\NamedType&GraphQL\\Type\\Definition\\Type::\$name\.#' - - "#Call to function method_exists\\(\\) with GraphQL\\\\Type\\\\Definition\\\\Type&GraphQL\\\\Type\\\\Definition\\\\WrappingType and 'getInnermostType' will always evaluate to true\\.#" - "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component\\\\\\\\PropertyInfo\\\\\\\\PropertyInfoExtractor' and 'getType' will always evaluate to true\\.#" - "#Call to function method_exists\\(\\) with 'Symfony\\\\\\\\Component\\\\\\\\HttpFoundation\\\\\\\\Request' and 'getContentTypeFormat' will always evaluate to true\\.#" - '#Call to an undefined method Symfony\\Component\\HttpFoundation\\Request::getContentType\(\)\.#' diff --git a/src/GraphQl/Action/EntrypointAction.php b/src/GraphQl/Action/EntrypointAction.php index 1c4fa44b68e..eb3a24cdb10 100644 --- a/src/GraphQl/Action/EntrypointAction.php +++ b/src/GraphQl/Action/EntrypointAction.php @@ -125,7 +125,7 @@ private function parseRequest(Request $request): array */ private function parseData(?string $query, ?string $operationName, array $variables, string $jsonContent): array { - if (!\is_array($data = json_decode($jsonContent, true, 512, \JSON_ERROR_NONE))) { + if (!\is_array($data = json_decode($jsonContent, true))) { throw new BadRequestHttpException('GraphQL data is not valid JSON.'); } @@ -162,7 +162,7 @@ private function parseMultipartRequest(?string $query, ?string $operationName, a [$query, $operationName, $variables] = $this->parseData($query, $operationName, $variables, $operations); /** @var string $map */ - if (!\is_array($decodedMap = json_decode($map, true, 512, \JSON_ERROR_NONE))) { + if (!\is_array($decodedMap = json_decode($map, true))) { throw new BadRequestHttpException('GraphQL multipart request map is not valid JSON.'); } @@ -218,7 +218,7 @@ private function applyMapToVariables(array $map, array $variables, array $files) */ private function decodeVariables(string $variables): array { - if (!\is_array($decoded = json_decode($variables, true, 512, \JSON_ERROR_NONE))) { + if (!\is_array($decoded = json_decode($variables, true))) { throw new BadRequestHttpException('GraphQL variables are not valid JSON.'); } diff --git a/src/Laravel/Eloquent/Metadata/Factory/Resource/EloquentResourceCollectionMetadataFactory.php b/src/Laravel/Eloquent/Metadata/Factory/Resource/EloquentResourceCollectionMetadataFactory.php index 8425ede6bc3..97ef6dae952 100644 --- a/src/Laravel/Eloquent/Metadata/Factory/Resource/EloquentResourceCollectionMetadataFactory.php +++ b/src/Laravel/Eloquent/Metadata/Factory/Resource/EloquentResourceCollectionMetadataFactory.php @@ -111,7 +111,13 @@ public function create(string $resourceClass): ResourceMetadataCollection if ($this->partialPatchValidation && $operation instanceof Patch) { $rules = $operation->getRules(); if (\is_array($rules)) { - $operation = $operation->withRules($this->replaceRequiredWithSometimes($rules)); + $stringKeyedRules = []; + foreach ($rules as $field => $fieldRules) { + if (\is_string($field)) { + $stringKeyedRules[$field] = $fieldRules; + } + } + $operation = $operation->withRules($this->replaceRequiredWithSometimes($stringKeyedRules)); } } diff --git a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php index 91682149343..f55734196e5 100644 --- a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php +++ b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php @@ -212,7 +212,7 @@ private function getProperties(string $resourceClass, ?Parameter $parameter = nu } if (($filter = $this->getFilterInstance($parameter->getFilter())) && $filter instanceof PropertyAwareFilterInterface) { - if (!method_exists($filter, 'getProperties')) { // @phpstan-ignore-line todo 5.x remove this check + if (!method_exists($filter, 'getProperties')) { // todo 5.x remove this check trigger_deprecation('api-platform/core', 'In API Platform 5.0 "%s" will implement a method named "getProperties"', PropertyAwareFilterInterface::class); $refl = new \ReflectionClass($filter); $filterProperties = $refl->hasProperty('properties') ? $refl->getProperty('properties')->getValue($filter) : []; diff --git a/src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php b/src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php index 7ac6daa9080..f4283c7eef3 100644 --- a/src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php +++ b/src/Symfony/Bundle/Test/ApiTestAssertionsTrait.php @@ -166,7 +166,7 @@ public static function getMercureMessage(int $index = 0, ?string $hubName = null public static function assertMercureUpdateMatchesJsonSchema(Update $update, array $topics, array|object|string $jsonSchema = '', bool $private = false, ?string $id = null, ?string $type = null, ?int $retry = null, string $message = ''): void { static::assertSame($topics, $update->getTopics(), $message); - static::assertThat(json_decode($update->getData(), true, \JSON_THROW_ON_ERROR), new MatchesJsonSchema($jsonSchema), $message); + static::assertThat(json_decode($update->getData(), true, flags: \JSON_THROW_ON_ERROR), new MatchesJsonSchema($jsonSchema), $message); static::assertSame($private, $update->isPrivate(), $message); static::assertSame($id, $update->getId(), $message); static::assertSame($type, $update->getType(), $message);