diff --git a/src/Model/UserAction.php b/src/Model/UserAction.php index 8cc020ccf..a6713e604 100644 --- a/src/Model/UserAction.php +++ b/src/Model/UserAction.php @@ -9,6 +9,7 @@ use Atk4\Core\InitializerTrait; use Atk4\Core\TrackableTrait; use Atk4\Data\Exception; +use Atk4\Data\Field; use Atk4\Data\Model; /** @@ -66,7 +67,7 @@ class UserAction public $system = false; /** @var array|Model> Argument definition. */ - public $args = []; + public $args = []; // TODO test with positional, named and Model arguments /** @var array|bool Specify which fields may be dirty when invoking action. APPLIES_TO_NO_RECORDS|APPLIES_TO_SINGLE_RECORD scopes for adding/modifying */ public $fields = []; @@ -118,6 +119,46 @@ public function getActionForEntity(Model $entity): self throw new Exception('Action instance not found in model'); } + /** + * @param mixed $value + * + * @return mixed + */ + protected function normalizeArg(string $name, $value) + { + $argFieldSeed = $this->args[$name]; + if ($argFieldSeed instanceof Model) { + return $value === null + ? null + : $argFieldSeed::assertInstanceOf($value); + } + + $argField = new Field($argFieldSeed); + + return $argField->normalize($value); + } + + /** + * @param array $args + * + * @return array + */ + protected function normalizeArgs($args): array + { + $argsNames = array_keys($this->args); + + $res = []; + foreach ($args as $k => $v) { + if (is_int($k)) { + $k = $argsNames[$k]; + } + + $res[$k] = $this->normalizeArg($k, $v); + } + + return $res; + } + /** * Attempt to execute callback of the action. * @@ -142,6 +183,7 @@ public function execute(...$args) try { $this->validateBeforeExecute(); + $args = $this->normalizeArgs($args); if ($passOwner) { array_unshift($args, $this->_getOwner()); } @@ -215,6 +257,7 @@ public function preview(...$args) try { $this->validateBeforeExecute(); + $args = $this->normalizeArgs($args); if ($passOwner) { array_unshift($args, $this->_getOwner()); }