Skip to content

Commit 99d4ce8

Browse files
committed
Introduce get_post_types dynamic return service
Account for different results from `get_post_types` based on the arguments passed. Also submitted a pull request upstream and simply keeping this here in case that does not get merged. @todo Remove this extension if the pull request gets merged and released upstream szepeviktor/phpstan-wordpress#177
1 parent 776f78c commit 99d4ce8

File tree

3 files changed

+79
-20
lines changed

3 files changed

+79
-20
lines changed

.idea/phpstan.iml

+17-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension.neon

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
services:
2+
- class: Lipe\Lib\Phpstan\Services\GetPostTypesDynamicFunctionReturnTypeExtension
3+
tags:
4+
- phpstan.broker.dynamicFunctionReturnTypeExtension
5+
16
parameters:
27
dynamicConstantNames:
38
- COOKIEPATH
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
declare( strict_types=1 );
3+
4+
namespace Lipe\Lib\Phpstan\Services;
5+
6+
use PhpParser\Node\Expr\FuncCall;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Reflection\FunctionReflection;
9+
use PHPStan\Type\ArrayType;
10+
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
11+
use PHPStan\Type\IntegerType;
12+
use PHPStan\Type\ObjectType;
13+
use PHPStan\Type\StringType;
14+
use PHPStan\Type\Type;
15+
16+
/**
17+
* The `get_post_types` function returns different results based on the
18+
* arguments passed to the function.
19+
*
20+
* @author Mat Lipe
21+
* @since 2.6.0
22+
*
23+
* @todo Remove this extension if the pull request gets merged and released upstream
24+
*
25+
* @link https://github.com/szepeviktor/phpstan-wordpress/pull/177
26+
* @link https://phpstan.org/developing-extensions/dynamic-return-type-extensions
27+
*
28+
*/
29+
class GetPostTypesDynamicFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension {
30+
public function isFunctionSupported( FunctionReflection $functionReflection ) : bool {
31+
return $functionReflection->getName() === 'get_post_types';
32+
}
33+
34+
35+
/**
36+
* - Return `string[]` if default or `$output = 'names'`.
37+
* - Return `WP_Post_Type[]` if `$output` is anything but 'names';
38+
*
39+
* @link https://developer.wordpress.org/reference/functions/get_post_types/#parameters
40+
*/
41+
public function getTypeFromFunctionCall( FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope ) : ?Type {
42+
$args = $functionCall->getArgs();
43+
44+
if ( count( $args ) < 2 ) {
45+
return new ArrayType( new IntegerType(), new StringType() );
46+
}
47+
48+
$argumentType = $scope->getType( $args[1]->value );
49+
if ( count( $argumentType->getConstantStrings() ) === 1 ) {
50+
if ( 'names' === $argumentType->getConstantStrings()[0]->getValue() ) {
51+
return new ArrayType( new IntegerType(), new StringType() );
52+
}
53+
}
54+
55+
return new ArrayType( new IntegerType(), new ObjectType( 'WP_Post_Type' ) );
56+
}
57+
}

0 commit comments

Comments
 (0)