From 302240ed1fbdfaf135a16d4fc563a538f3c1b220 Mon Sep 17 00:00:00 2001 From: soyuka Date: Wed, 17 Jun 2026 20:16:17 +0200 Subject: [PATCH 1/2] chore(phpstan): fix level 6 errors on 4.3 Drop the dead getWrappedType(true) backward-compat branch in FieldsBuilder (webonyx/graphql-php ^15 always exposes getInnermostType() and getWrappedType() takes no argument), and remove the now-unmatched ignore pattern. Silence the always-true method_exists() BC shim in ParameterResourceMetadataCollectionFactory the same way its twin in ParameterExtensionTrait already is. --- phpstan.neon.dist | 1 - src/GraphQl/Type/FieldsBuilder.php | 6 +----- .../Factory/ParameterResourceMetadataCollectionFactory.php | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f930e2637c1..c89e42edec1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -83,7 +83,6 @@ parameters: path: src/GraphQl/Tests/Type/TypesContainerTest.php # 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 '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\\.#" diff --git a/src/GraphQl/Type/FieldsBuilder.php b/src/GraphQl/Type/FieldsBuilder.php index 4d674368723..7f63a2d1ba5 100644 --- a/src/GraphQl/Type/FieldsBuilder.php +++ b/src/GraphQl/Type/FieldsBuilder.php @@ -435,11 +435,7 @@ private function getResourceFieldConfiguration(?string $property, ?string $field $graphqlWrappedType = $graphqlType; if ($graphqlType instanceof WrappingType) { - if (method_exists($graphqlType, 'getInnermostType')) { - $graphqlWrappedType = $graphqlType->getInnermostType(); - } else { - $graphqlWrappedType = $graphqlType->getWrappedType(true); - } + $graphqlWrappedType = $graphqlType->getInnermostType(); } $isStandardGraphqlType = \in_array($graphqlWrappedType, GraphQLType::getStandardTypes(), true); if ($isStandardGraphqlType) { diff --git a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php index f55734196e5..289c601500f 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')) { // todo 5.x remove this check + if (!method_exists($filter, 'getProperties')) { // @phpstan-ignore-line todo 5.x remove this check @see interface 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) : []; From 829f7edb3d36d85e746a681ae2f898a33b778455 Mon Sep 17 00:00:00 2001 From: soyuka Date: Wed, 17 Jun 2026 20:24:17 +0200 Subject: [PATCH 2/2] chore(phpstan): fix larastan level 7 errors on 4.3 The metadata-dump tests added in #8290 trip larastan: stubResourceClasses is typed list yet intentionally receives a non-model class name, readDump returns the untyped result of unserialize(), and the Log::spy()/shouldHaveReceived() spy chain is not statically resolvable. Loosen the stub to list, validate and reshape the dump payload, and assert the stale-fingerprint warning with Log::shouldReceive() as the rest of the suite already does. --- .../Tests/Console/DumpMetadataCommandTest.php | 13 ++++++++++--- .../Tests/Metadata/DumpedMetadataBootTest.php | 10 ++++------ .../ParameterResourceMetadataCollectionFactory.php | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Laravel/Tests/Console/DumpMetadataCommandTest.php b/src/Laravel/Tests/Console/DumpMetadataCommandTest.php index 1506bc75c39..c72099dac5f 100644 --- a/src/Laravel/Tests/Console/DumpMetadataCommandTest.php +++ b/src/Laravel/Tests/Console/DumpMetadataCommandTest.php @@ -123,7 +123,7 @@ private function seedCommandModelMetadata(array $attributes, array $relations): } /** - * @param list $classes + * @param list $classes */ private function stubResourceClasses(array $classes): void { @@ -144,7 +144,7 @@ private function runDump(): PendingCommand } /** - * @return array{fingerprint: string, attributes: array, relations: array} + * @return array{fingerprint: string, attributes: array, relations: array} */ private function readDump(): array { @@ -158,6 +158,13 @@ private function readDump(): array $this->fail('The dump file did not contain an array.'); } - return $dumped; + $fingerprint = $dumped['fingerprint'] ?? null; + $attributes = $dumped['attributes'] ?? null; + $relations = $dumped['relations'] ?? null; + if (!\is_string($fingerprint) || !\is_array($attributes) || !\is_array($relations)) { + $this->fail('The dump file did not contain the expected structure.'); + } + + return ['fingerprint' => $fingerprint, 'attributes' => $attributes, 'relations' => $relations]; } } diff --git a/src/Laravel/Tests/Metadata/DumpedMetadataBootTest.php b/src/Laravel/Tests/Metadata/DumpedMetadataBootTest.php index 8267d1f92e2..fb2c9dfda1c 100644 --- a/src/Laravel/Tests/Metadata/DumpedMetadataBootTest.php +++ b/src/Laravel/Tests/Metadata/DumpedMetadataBootTest.php @@ -75,12 +75,12 @@ public function testItWarnsWhenTheDumpFingerprintIsStale(): void { // The canned dump written in setUp() carries no fingerprint, so it never matches the // current migrations and must be reported as stale. - Log::spy(); + Log::shouldReceive('warning') + ->once() + ->withArgs(static fn (string $message): bool => str_contains($message, 'stale')); $this->app->forgetInstance(ModelMetadata::class); $this->app->make(ModelMetadata::class); - - Log::shouldHaveReceived('warning')->withArgs(static fn (string $message): bool => str_contains($message, 'stale'))->once(); } public function testItDoesNotWarnWhenTheFingerprintMatches(): void @@ -91,12 +91,10 @@ public function testItDoesNotWarnWhenTheFingerprintMatches(): void 'relations' => [Book::class => self::CANNED_RELATIONS], ])); - Log::spy(); + Log::shouldReceive('warning')->never(); $this->app->forgetInstance(ModelMetadata::class); $this->app->make(ModelMetadata::class); - - Log::shouldNotHaveReceived('warning'); } public function testItIsNotSeededWhenDebugIsEnabled(): void diff --git a/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php b/src/Metadata/Resource/Factory/ParameterResourceMetadataCollectionFactory.php index 289c601500f..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 @see interface + 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) : [];