-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathModelCastEntityType.php
More file actions
69 lines (58 loc) · 2.51 KB
/
Copy pathModelCastEntityType.php
File metadata and controls
69 lines (58 loc) · 2.51 KB
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
<?php
declare(strict_types=1);
/**
* This file is part of CodeIgniter 4 framework.
*
* (c) 2023 CodeIgniter Foundation <admin@codeigniter.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace CodeIgniter\PHPStan\Type;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\Type\CallbackUnresolvedPropertyPrototypeReflection;
use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
/**
* An entity object type whose listed properties are retyped by the `$casts` of the model that produced it.
* CodeIgniter applies the producing model's casts before hydrating the entity, so an entity fetched through
* a model's `asObject()`/`asArray()` picks up that model's casts instead of the bare column types.
*/
final class ModelCastEntityType extends ObjectType
{
/**
* @param array<string, Type> $castedProperties Field name => cast-resolved type
* @param array<string, string> $datamap Property name => field name
*/
public function __construct(
string $className,
private readonly array $castedProperties,
private readonly array $datamap = [],
) {
parent::__construct($className);
}
public function getUnresolvedInstancePropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
{
return $this->withCastOverride($propertyName, parent::getUnresolvedInstancePropertyPrototype($propertyName, $scope));
}
public function getUnresolvedPropertyPrototype(string $propertyName, ClassMemberAccessAnswerer $scope): UnresolvedPropertyPrototypeReflection
{
return $this->withCastOverride($propertyName, parent::getUnresolvedPropertyPrototype($propertyName, $scope));
}
private function withCastOverride(string $propertyName, UnresolvedPropertyPrototypeReflection $prototype): UnresolvedPropertyPrototypeReflection
{
$field = $this->datamap[$propertyName] ?? $propertyName;
if (! isset($this->castedProperties[$field])) {
return $prototype;
}
$naked = $prototype->getNakedProperty();
$overrideType = $this->castedProperties[$field];
return new CallbackUnresolvedPropertyPrototypeReflection(
$naked,
$naked->getDeclaringClass(),
false,
static fn (Type $type): Type => $overrideType,
);
}
}