-
-
Notifications
You must be signed in to change notification settings - Fork 24
/
GetPostsDynamicFunctionReturnTypeExtension.php
77 lines (65 loc) · 2.5 KB
/
GetPostsDynamicFunctionReturnTypeExtension.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
/**
* Set return type of get_posts().
*/
declare(strict_types=1);
namespace SzepeViktor\PHPStan\WordPress;
use PhpParser\Node\Expr\FuncCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Type\Type;
use PHPStan\Type\ArrayType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantStringType;
class GetPostsDynamicFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunctionReturnTypeExtension
{
public function isFunctionSupported(FunctionReflection $functionReflection): bool
{
return $functionReflection->getName() === 'get_posts';
}
/**
* @see https://developer.wordpress.org/reference/classes/wp_query/#return-fields-parameter
*/
// phpcs:ignore SlevomatCodingStandard.Functions.UnusedParameter
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
{
$args = $functionCall->getArgs();
// Called without arguments
if (count($args) === 0) {
return new ArrayType(new IntegerType(), new ObjectType('WP_Post'));
}
$argumentType = $scope->getType($args[0]->value);
// Called with an array argument
if ($argumentType instanceof ConstantArrayType) {
foreach ($argumentType->getKeyTypes() as $index => $key) {
if (! $key instanceof ConstantStringType || $key->getValue() !== 'fields') {
continue;
}
$fieldsType = $argumentType->getValueTypes()[$index];
if ($fieldsType instanceof ConstantStringType) {
$fields = $fieldsType->getValue();
}
break;
}
}
// Called with a string argument
if ($argumentType instanceof ConstantStringType) {
parse_str($argumentType->getValue(), $variables);
$fields = $variables['fields'] ?? 'all';
}
// Without constant argument return default return type
if (! isset($fields)) {
return new ArrayType(new IntegerType(), new ObjectType('WP_Post'));
}
switch ($fields) {
case 'id=>parent':
case 'ids':
return new ArrayType(new IntegerType(), new IntegerType());
case 'all':
default:
return new ArrayType(new IntegerType(), new ObjectType('WP_Post'));
}
}
}