44
55namespace Tempest \Http \Mappers ;
66
7+ use ReflectionClass ;
78use Tempest \Http \Request ;
9+ use Tempest \Http \RequestParametersIncludedReservedNames ;
810use Tempest \Mapper \Mapper ;
911use Tempest \Mapper \Mappers \ArrayToObjectMapper ;
12+ use Tempest \Reflection \ClassReflector ;
13+ use Tempest \Reflection \PropertyReflector ;
1014use Tempest \Validation \Exceptions \ValidationFailed ;
1115use Tempest \Validation \Validator ;
1216
1317use function Tempest \map ;
18+ use function Tempest \Support \arr ;
1419
1520final readonly class RequestToObjectMapper implements Mapper
1621{
@@ -22,9 +27,17 @@ public function canMap(mixed $from, mixed $to): bool
2227 public function map (mixed $ from , mixed $ to ): array |object
2328 {
2429 /** @var Request $from */
25- $ data = $ from ->body ;
30+ $ data = [... $ from ->files , ... $ from -> body , ... $ from -> query ] ;
2631
2732 if (is_a ($ to , Request::class, true )) {
33+ $ invalidReservedProperties = arr (new ClassReflector (Request::class)->getProperties ())
34+ ->map (fn (PropertyReflector $ property ) => $ property ->getName ())
35+ ->filter (fn (string $ property ) => array_key_exists ($ property , $ data ));
36+
37+ if ($ invalidReservedProperties ->isNotEmpty ()) {
38+ throw new RequestParametersIncludedReservedNames ($ to , $ invalidReservedProperties );
39+ }
40+
2841 $ data = [
2942 ...[
3043 'method ' => $ from ->method ,
@@ -36,8 +49,6 @@ public function map(mixed $from, mixed $to): array|object
3649 'files ' => $ from ->files ,
3750 'cookies ' => $ from ->cookies ,
3851 ],
39- ...$ from ->files ,
40- ...$ from ->query ,
4152 ...$ data ,
4253 ];
4354 }
0 commit comments