Skip to content

Commit

Permalink
Presenter::argsToParams() throws exception when parameter has scalar …
Browse files Browse the repository at this point in the history
…type hint, no default value and argument is missing [Closes #112]
  • Loading branch information
dg committed Jan 22, 2016
1 parent 1f61ea3 commit 5aa5388
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 19 deletions.
25 changes: 9 additions & 16 deletions src/Application/UI/Presenter.php
Expand Up @@ -1014,7 +1014,9 @@ public static function argsToParams($class, $method, & $args, $supplemental = ar
$i = 0;
$rm = new \ReflectionMethod($class, $method);
foreach ($rm->getParameters() as $param) {
list($type, $isClass) = PresenterComponentReflection::getParameterType($param);
$name = $param->getName();

if (array_key_exists($i, $args)) {
$args[$name] = $args[$i];
unset($args[$i]);
Expand All @@ -1025,16 +1027,15 @@ public static function argsToParams($class, $method, & $args, $supplemental = ar

} elseif (array_key_exists($name, $supplemental)) {
$args[$name] = $supplemental[$name];

} else {
continue;
}

if ($args[$name] === NULL) {
continue;
if (!isset($args[$name])) {
if ($param->isDefaultValueAvailable() || $type === 'NULL' || $type === 'array' || $isClass) {
continue;
}
throw new InvalidLinkException("Missing parameter \$$name required by $class::{$rm->getName()}()");
}

list($type, $isClass) = PresenterComponentReflection::getParameterType($param);
if (!PresenterComponentReflection::convertType($args[$name], $type, $isClass)) {
throw new InvalidLinkException(sprintf(
'Argument $%s passed to %s() must be %s, %s given.',
Expand All @@ -1045,22 +1046,14 @@ public static function argsToParams($class, $method, & $args, $supplemental = ar
));
}

if ($param->isDefaultValueAvailable()) {
$def = $param->getDefaultValue();
} else {
$def = NULL;
if (!$isClass) {
settype($def, $type);
}
}
$def = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : NULL;
if ($args[$name] === $def || ($def === NULL && is_scalar($args[$name]) && (string) $args[$name] === '')) {
$args[$name] = NULL; // value transmit is unnecessary
}
}

if (array_key_exists($i, $args)) {
$method = $rm->getName();
throw new InvalidLinkException("Passed more parameters than method $class::$method() expects.");
throw new InvalidLinkException("Passed more parameters than method $class::{$rm->getName()}() expects.");
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/UI/Presenter.link().php7.phpt
Expand Up @@ -145,11 +145,11 @@ class TestPresenter extends Application\UI\Presenter
Assert::same('/index.php?action=params&presenter=Test', $this->link('params', ['int' => new stdClass]));

Assert::same('/index.php?action=hints&presenter=Test', $this->link('hints', []));
Assert::same('/index.php?action=hints&presenter=Test', $this->link('hints', ['int' => NULL, 'bool' => NULL, 'str' => NULL, 'arr' => NULL]));
Assert::same('#error: Missing parameter $int required by TestPresenter::actionHints()', $this->link('hints', ['int' => NULL, 'bool' => NULL, 'str' => NULL, 'arr' => NULL]));
Assert::same('/index.php?int=1&bool=1&str=abc&arr%5B0%5D=1&action=hints&presenter=Test', $this->link('hints', ['int' => '1', 'bool' => '1', 'str' => 'abc', 'arr' => [1]]));
Assert::same('/index.php?action=hints&presenter=Test', $this->link('hints', ['int' => 0, 'bool' => FALSE, 'str' => '', 'arr' => []]));
Assert::same('/index.php?int=0&action=hints&presenter=Test', $this->link('hints', ['int' => 0, 'bool' => FALSE, 'str' => '', 'arr' => []]));
Assert::same('#error: Argument $int passed to TestPresenter::actionHints() must be int, string given.', $this->link('hints', ['int' => '']));
Assert::same('/index.php?action=hints&presenter=Test', $this->link('hints', ['int' => new stdClass]));
Assert::same('#error: Missing parameter $bool required by TestPresenter::actionHints()', $this->link('hints', ['int' => new stdClass]));
Assert::same('#error: Argument $int passed to TestPresenter::actionHints() must be int, array given.', $this->link('hints', ['int' => []]));
Assert::same('#error: Argument $bool passed to TestPresenter::actionHints() must be bool, string given.', $this->link('hints', ['int' => '1', 'bool' => '']));
Assert::same('#error: Argument $arr passed to TestPresenter::actionHints() must be array, string given.', $this->link('hints', ['int' => '1', 'bool' => '1', 'str' => '', 'arr' => '']));
Expand Down

0 comments on commit 5aa5388

Please sign in to comment.