diff --git a/extension.neon b/extension.neon index 4870f24c..cd18f378 100644 --- a/extension.neon +++ b/extension.neon @@ -273,3 +273,8 @@ services: - factory: PHPStan\Type\Symfony\CommandGetHelperDynamicReturnTypeExtension tags: [phpstan.broker.dynamicMethodReturnTypeExtension] + + # ResponseHeaderBag::getCookies() return type + - + factory: PHPStan\Type\Symfony\ResponseHeaderBagDynamicReturnTypeExtension + tags: [phpstan.broker.dynamicMethodReturnTypeExtension] diff --git a/src/Type/Symfony/ResponseHeaderBagDynamicReturnTypeExtension.php b/src/Type/Symfony/ResponseHeaderBagDynamicReturnTypeExtension.php new file mode 100644 index 00000000..a659c684 --- /dev/null +++ b/src/Type/Symfony/ResponseHeaderBagDynamicReturnTypeExtension.php @@ -0,0 +1,65 @@ +getName() === 'getCookies'; + } + + public function getTypeFromMethodCall( + MethodReflection $methodReflection, + MethodCall $methodCall, + Scope $scope + ): Type + { + if (isset($methodCall->getArgs()[0])) { + $node = $methodCall->getArgs()[0]->value; + + if ( + $node instanceof ClassConstFetch && + $node->class instanceof Name && + $node->name instanceof Identifier && + $node->class->toString() === ResponseHeaderBag::class && + $node->name->name === 'COOKIES_ARRAY' + ) { + return new ArrayType( + new StringType(), + new ArrayType( + new StringType(), + new ArrayType( + new StringType(), + new ObjectType(Cookie::class) + ) + ) + ); + } + } + + return new ArrayType(new IntegerType(), new ObjectType(Cookie::class)); + } + +} diff --git a/tests/Type/Symfony/ExtensionTest.php b/tests/Type/Symfony/ExtensionTest.php index 5da566b1..c0aa7f94 100644 --- a/tests/Type/Symfony/ExtensionTest.php +++ b/tests/Type/Symfony/ExtensionTest.php @@ -14,6 +14,7 @@ public function dataFileAsserts(): iterable { yield from $this->gatherAssertTypes(__DIR__ . '/data/envelope_all.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/header_bag_get.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/response_header_bag_get_cookies.php'); if (class_exists('Symfony\Component\HttpFoundation\InputBag')) { yield from $this->gatherAssertTypes(__DIR__ . '/data/input_bag.php'); diff --git a/tests/Type/Symfony/data/response_header_bag_get_cookies.php b/tests/Type/Symfony/data/response_header_bag_get_cookies.php new file mode 100644 index 00000000..f07d5e5b --- /dev/null +++ b/tests/Type/Symfony/data/response_header_bag_get_cookies.php @@ -0,0 +1,12 @@ +setCookie(Cookie::create('cookie_name')); + +assertType('array', $headerBag->getCookies()); +assertType('array', $headerBag->getCookies(ResponseHeaderBag::COOKIES_FLAT)); +assertType('array>>', $headerBag->getCookies(ResponseHeaderBag::COOKIES_ARRAY));