55namespace Patchlevel \Hydrator \Metadata ;
66
77use ReflectionClass ;
8+ use ReflectionParameter ;
9+
10+ use function array_values ;
811
912/**
1013 * @psalm-type serialized array{
11- * className: class-string,
12- * properties: list< PropertyMetadata>,
14+ * className: class-string<T> ,
15+ * properties: array<string, PropertyMetadata>,
1316 * dataSubjectIdField: string|null,
1417 * postHydrateCallbacks: list<CallbackMetadata>,
1518 * preExtractCallbacks: list<CallbackMetadata>,
1619 * lazy: bool|null,
20+ * extras: array<string, mixed>
1721 * }
1822 * @template T of object = object
1923 */
20- final readonly class ClassMetadata
24+ final class ClassMetadata
2125{
26+ /** @var class-string<T> */
27+ public readonly string $ className ;
28+
29+ /** @var array<string, PropertyMetadata> */
30+ public readonly array $ properties ;
31+
32+ /** @var array<string, ReflectionParameter>|null */
33+ private array |null $ promotedConstructorDefaults = null ;
34+
2235 /**
2336 * @param ReflectionClass<T> $reflection
2437 * @param list<PropertyMetadata> $properties
2538 * @param list<CallbackMetadata> $postHydrateCallbacks
2639 * @param list<CallbackMetadata> $preExtractCallbacks
40+ * @param array<string, mixed> $extras
2741 */
2842 public function __construct (
29- private ReflectionClass $ reflection ,
30- private array $ properties = [],
31- private string |null $ dataSubjectIdField = null ,
32- private array $ postHydrateCallbacks = [],
33- private array $ preExtractCallbacks = [],
34- private bool |null $ lazy = null ,
43+ public readonly ReflectionClass $ reflection ,
44+ array $ properties = [],
45+ public string |null $ dataSubjectIdField = null ,
46+ public array $ postHydrateCallbacks = [],
47+ public array $ preExtractCallbacks = [],
48+ public bool |null $ lazy = null ,
49+ public array $ extras = [],
3550 ) {
51+ $ this ->className = $ reflection ->getName ();
52+
53+ $ map = [];
54+
55+ foreach ($ properties as $ property ) {
56+ $ map [$ property ->propertyName ] = $ property ;
57+ }
58+
59+ $ this ->properties = $ map ;
3660 }
3761
3862 /** @return ReflectionClass<T> */
@@ -44,13 +68,13 @@ public function reflection(): ReflectionClass
4468 /** @return class-string<T> */
4569 public function className (): string
4670 {
47- return $ this ->reflection -> getName () ;
71+ return $ this ->className ;
4872 }
4973
5074 /** @return list<PropertyMetadata> */
5175 public function properties (): array
5276 {
53- return $ this ->properties ;
77+ return array_values ( $ this ->properties ) ;
5478 }
5579
5680 /** @return list<CallbackMetadata> */
@@ -92,16 +116,43 @@ public function newInstance(): object
92116 return $ this ->reflection ->newInstanceWithoutConstructor ();
93117 }
94118
119+ /** @return array<string, ReflectionParameter> */
120+ public function promotedConstructorDefaults (): array
121+ {
122+ if ($ this ->promotedConstructorDefaults !== null ) {
123+ return $ this ->promotedConstructorDefaults ;
124+ }
125+
126+ $ constructor = $ this ->reflection ->getConstructor ();
127+
128+ if (!$ constructor ) {
129+ return $ this ->promotedConstructorDefaults = [];
130+ }
131+
132+ $ result = [];
133+
134+ foreach ($ constructor ->getParameters () as $ parameter ) {
135+ if (!$ parameter ->isPromoted () || !$ parameter ->isDefaultValueAvailable ()) {
136+ continue ;
137+ }
138+
139+ $ result [$ parameter ->getName ()] = $ parameter ;
140+ }
141+
142+ return $ this ->promotedConstructorDefaults = $ result ;
143+ }
144+
95145 /** @return serialized */
96146 public function __serialize (): array
97147 {
98148 return [
99- 'className ' => $ this ->reflection -> getName () ,
149+ 'className ' => $ this ->className ,
100150 'properties ' => $ this ->properties ,
101151 'dataSubjectIdField ' => $ this ->dataSubjectIdField ,
102152 'postHydrateCallbacks ' => $ this ->postHydrateCallbacks ,
103153 'preExtractCallbacks ' => $ this ->preExtractCallbacks ,
104154 'lazy ' => $ this ->lazy ,
155+ 'extras ' => $ this ->extras ,
105156 ];
106157 }
107158
@@ -114,5 +165,6 @@ public function __unserialize(array $data): void
114165 $ this ->postHydrateCallbacks = $ data ['postHydrateCallbacks ' ];
115166 $ this ->preExtractCallbacks = $ data ['preExtractCallbacks ' ];
116167 $ this ->lazy = $ data ['lazy ' ];
168+ $ this ->extras = $ data ['extras ' ];
117169 }
118170}
0 commit comments