99use Nette \Utils \JsonException ;
1010use TypeError ;
1111
12+ /**
13+ * @template TKey of string|int
14+ * @template TValue of mixed
15+ * @extends AbstractEntity<TKey, TValue>
16+ */
1217abstract class BasicEntity extends AbstractEntity
1318{
1419
@@ -23,7 +28,7 @@ public function getRequestProperties(): array
2328 }
2429
2530 /**
26- * @return BasicEntity|null
31+ * @return BasicEntity<TKey, TValue> |null
2732 */
2833 public function fromRequest (ApiRequest $ request ): ?IRequestEntity
2934 {
@@ -39,8 +44,8 @@ public function fromRequest(ApiRequest $request): ?IRequestEntity
3944 }
4045
4146 /**
42- * @param array<string, mixed > $data
43- * @return static
47+ * @param array<TKey, TValue > $data
48+ * @return static<TKey, TValue>
4449 */
4550 public function factory (array $ data ): self
4651 {
@@ -49,20 +54,35 @@ public function factory(array $data): self
4954 // Fill properties with real data
5055 $ properties = $ inst ->getRequestProperties ();
5156 foreach ($ properties as $ property ) {
52- if (!array_key_exists ($ property ['name ' ], $ data )) {
57+ /** @var TKey $propName */
58+ $ propName = $ property ['name ' ];
59+ if (!array_key_exists ($ propName , $ data )) {
5360 continue ;
5461 }
5562
56- $ value = $ data [$ property [ ' name ' ] ];
63+ $ value = $ data [$ propName ];
5764
5865 // Normalize & convert value (only not null values)
5966 if ($ value !== null ) {
60- $ value = $ this ->normalize ($ property [ ' name ' ] , $ value );
67+ $ value = $ this ->normalize ($ propName , $ value );
6168 }
6269
6370 // Fill single property
6471 try {
65- $ inst ->{$ property ['name ' ]} = $ value ;
72+ $ propNameStr = (string ) $ propName ;
73+ if (property_exists ($ inst , $ propNameStr )) {
74+ $ ref = new \ReflectionProperty ($ inst , $ propNameStr );
75+ $ wasAccessible = $ ref ->isPublic ();
76+ if (!$ wasAccessible ) {
77+ $ ref ->setAccessible (true );
78+ }
79+ $ ref ->setValue ($ inst , $ value );
80+ if (!$ wasAccessible ) {
81+ $ ref ->setAccessible (false );
82+ }
83+ } elseif (method_exists ($ inst , '__set ' )) {
84+ $ inst ->__set ($ propName , $ value );
85+ }
6686 } catch (TypeError ) {
6787 // do nothing, entity will be invalid if something is missing and ValidationException will be thrown
6888 }
@@ -71,13 +91,18 @@ public function factory(array $data): self
7191 return $ inst ;
7292 }
7393
74- protected function normalize (string $ property , mixed $ value ): mixed
94+ /**
95+ * @param TKey $property
96+ * @param TValue $value
97+ * @return TValue
98+ */
99+ protected function normalize (int |string $ property , mixed $ value ): mixed
75100 {
76101 return $ value ;
77102 }
78103
79104 /**
80- * @return static
105+ * @return static<TKey, TValue>
81106 */
82107 protected function fromBodyRequest (ApiRequest $ request ): self
83108 {
@@ -91,7 +116,7 @@ protected function fromBodyRequest(ApiRequest $request): self
91116 }
92117
93118 /**
94- * @return static
119+ * @return static<TKey, TValue>
95120 */
96121 protected function fromGetRequest (ApiRequest $ request ): self
97122 {
0 commit comments