Skip to content

Commit 5ab82a4

Browse files
committed
Fix for unioned id
1 parent 519f6ed commit 5ab82a4

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/Type/ModelFindReturnTypeExtension.php

+19-9
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
use PHPStan\Type\ArrayType;
2323
use PHPStan\Type\DynamicMethodReturnTypeExtension;
2424
use PHPStan\Type\IntegerType;
25+
use PHPStan\Type\IntersectionType;
2526
use PHPStan\Type\Type;
2627
use PHPStan\Type\TypeCombinator;
28+
use PHPStan\Type\TypeTraverser;
29+
use PHPStan\Type\UnionType;
2730

2831
final class ModelFindReturnTypeExtension implements DynamicMethodReturnTypeExtension
2932
{
@@ -74,19 +77,26 @@ private function getTypeFromFind(MethodReflection $methodReflection, MethodCall
7477
return $this->getTypeFromFindAll($methodReflection, $methodCall, $scope);
7578
}
7679

77-
$idType = $scope->getType($args[0]->value);
80+
return TypeTraverser::map(
81+
$scope->getType($args[0]->value),
82+
function (Type $idType, callable $traverse) use ($methodReflection, $methodCall, $scope): Type {
83+
if ($idType instanceof UnionType || $idType instanceof IntersectionType) {
84+
return $traverse($idType);
85+
}
7886

79-
if ($idType->isNull()->yes()) {
80-
return $this->getTypeFromFindAll($methodReflection, $methodCall, $scope);
81-
}
87+
if ($idType->isNull()->yes()) {
88+
return $this->getTypeFromFindAll($methodReflection, $methodCall, $scope);
89+
}
8290

83-
if ($idType->isInteger()->yes() || $idType->isString()->yes()) {
84-
$classReflection = $this->getClassReflection($methodCall, $scope);
91+
if ($idType->isInteger()->yes() || $idType->isString()->yes()) {
92+
$classReflection = $this->getClassReflection($methodCall, $scope);
8593

86-
return TypeCombinator::addNull($this->modelFetchedReturnTypeHelper->getFetchedReturnType($classReflection, $scope));
87-
}
94+
return TypeCombinator::addNull($this->modelFetchedReturnTypeHelper->getFetchedReturnType($classReflection, $scope));
95+
}
8896

89-
return $this->getTypeFromFindAll($methodReflection, $methodCall, $scope);
97+
return $this->getTypeFromFindAll($methodReflection, $methodCall, $scope);
98+
}
99+
);
90100
}
91101

92102
private function getTypeFromFindAll(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type

tests/Fixtures/Type/model-find.php

+10
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,13 @@
2727
assertType('list<array{user_id: int, group: string, created_at: string}>', $groups->find());
2828
assertType('list<array{user_id: int, group: string, created_at: string}>', $groups->find(null));
2929
assertType('list<array{user_id: int, group: string, created_at: string}>', $groups->find([1, 2, 3]));
30+
31+
/**
32+
* @param int|string|null $id
33+
*/
34+
function bar($id): void
35+
{
36+
$model = model(UserModel::class);
37+
38+
assertType('list<CodeIgniter\Shield\Entities\User>|CodeIgniter\Shield\Entities\User|null', $model->find($id));
39+
}

0 commit comments

Comments
 (0)