Browse Source

Add array type coercion for controller action params.

ADmad 4 years ago
parent
commit
a75a5e760f

+ 3 - 1
src/Controller/ControllerFactory.php

@@ -250,7 +250,7 @@ class ControllerFactory implements ControllerFactoryInterface, RequestHandlerInt
      *
      * @param string $argument Argument to coerce
      * @param \ReflectionNamedType $type Parameter type
-     * @return string|float|int|bool|null
+     * @return array|string|float|int|bool|null
      */
     protected function coerceStringToType(string $argument, ReflectionNamedType $type)
     {
@@ -263,6 +263,8 @@ class ControllerFactory implements ControllerFactoryInterface, RequestHandlerInt
                 return ctype_digit($argument) ? (int)$argument : null;
             case 'bool':
                 return $argument === '0' ? false : ($argument === '1' ? true : null);
+            case 'array':
+                return explode(',', $argument);
         }
 
         return null;

+ 3 - 3
tests/TestCase/Controller/ControllerFactoryTest.php

@@ -684,7 +684,7 @@ class ControllerFactoryTest extends TestCase
                 'plugin' => null,
                 'controller' => 'Dependencies',
                 'action' => 'requiredTyped',
-                'pass' => ['1.0', '02', '0'],
+                'pass' => ['1.0', '02', '0', '8,9'],
             ],
         ]);
         $controller = $this->factory->create($request);
@@ -693,7 +693,7 @@ class ControllerFactoryTest extends TestCase
         $data = json_decode((string)$result->getBody(), true);
 
         $this->assertNotNull($data);
-        $this->assertSame(['one' => 1.0, 'two' => 2, 'three' => false], $data);
+        $this->assertSame(['one' => 1.0, 'two' => 2, 'three' => false, 'four' => ['8', '9']], $data);
     }
 
     /**
@@ -799,7 +799,7 @@ class ControllerFactoryTest extends TestCase
         $controller = $this->factory->create($request);
 
         $this->expectException(InvalidParameterException::class);
-        $this->expectExceptionMessage('Unable to coerce "test" to `array` for `one` in action Dependencies::unsupportedTyped()');
+        $this->expectExceptionMessage('Unable to coerce "test" to `iterable` for `one` in action Dependencies::unsupportedTyped()');
         $this->factory->invoke($controller);
     }
 

+ 6 - 3
tests/test_app/TestApp/Controller/DependenciesController.php

@@ -43,9 +43,12 @@ class DependenciesController extends Controller
         return $this->response->withStringBody(json_encode(compact('str')));
     }
 
-    public function requiredTyped(float $one, int $two, bool $three)
+    public function requiredTyped(float $one, int $two, bool $three, array $four)
     {
-        return $this->response->withStringBody(json_encode(compact('one', 'two', 'three'), JSON_PRESERVE_ZERO_FRACTION));
+        return $this->response->withStringBody(json_encode(
+            compact('one', 'two', 'three', 'four'),
+            JSON_PRESERVE_ZERO_FRACTION
+        ));
     }
 
     public function optionalTyped(float $one = 1.0, int $two = 2, bool $three = true)
@@ -53,7 +56,7 @@ class DependenciesController extends Controller
         return $this->response->withStringBody(json_encode(compact('one', 'two', 'three'), JSON_PRESERVE_ZERO_FRACTION));
     }
 
-    public function unsupportedTyped(array $one)
+    public function unsupportedTyped(iterable $one)
     {
         return $this->response->withStringBody(json_encode(compact('one')));
     }