Skip to content

Commit 86eb0ee

Browse files
JanTvrdikdg
authored andcommitted
Presenter: fixed creating link with required persistent parameters (#148)
1 parent 9889522 commit 86eb0ee

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

src/Application/LinkGenerator.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ public function link($dest, array $params = [])
6161
if (method_exists($class, $method = $class::formatActionMethod($action))
6262
|| method_exists($class, $method = $class::formatRenderMethod($action))
6363
) {
64-
UI\Presenter::argsToParams($class, $method, $params);
64+
UI\Presenter::argsToParams($class, $method, $params, [], $missing);
65+
if ($missing) {
66+
$rp = $missing[0];
67+
throw new UI\InvalidLinkException("Missing parameter \${$rp->getName()} required by {$rp->getDeclaringClass()->getName()}::{$rp->getDeclaringFunction()->getName()}()");
68+
}
69+
6570
} elseif (array_key_exists(0, $params)) {
6671
throw new UI\InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method.");
6772
}

src/Application/UI/Presenter.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ protected function createRequest($component, $destination, array $args, $mode)
869869
throw new InvalidLinkException("Unknown signal '$signal', missing handler {$reflection->getName()}::$method()");
870870
}
871871
// convert indexed parameters to named
872-
self::argsToParams(get_class($component), $method, $args, [], $mode === 'test');
872+
self::argsToParams(get_class($component), $method, $args, [], $missing);
873873
}
874874

875875
// counterpart of IStatePersistent
@@ -911,7 +911,7 @@ protected function createRequest($component, $destination, array $args, $mode)
911911
throw new InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method.");
912912
}
913913
} else {
914-
self::argsToParams($presenterClass, $method, $args, $destination === 'this' ? $this->params : [], $mode === 'test');
914+
self::argsToParams($presenterClass, $method, $args, $destination === 'this' ? $this->params : [], $missing);
915915
}
916916

917917
// counterpart of IStatePersistent
@@ -936,6 +936,14 @@ protected function createRequest($component, $destination, array $args, $mode)
936936
$args += $globalState;
937937
}
938938

939+
if ($mode !== 'test' && !empty($missing)) {
940+
foreach ($missing as $rp) {
941+
if (!array_key_exists($rp->getName(), $args)) {
942+
throw new InvalidLinkException("Missing parameter \${$rp->getName()} required by {$rp->getDeclaringClass()->getName()}::{$rp->getDeclaringFunction()->getName()}()");
943+
}
944+
}
945+
}
946+
939947
// ADD ACTION & SIGNAL & FLASH
940948
if ($action) {
941949
$args[self::ACTION_KEY] = $action;
@@ -995,12 +1003,12 @@ protected function createRequest($component, $destination, array $args, $mode)
9951003
* @param string method name
9961004
* @param array arguments
9971005
* @param array supplemental arguments
998-
* @param bool prevents 'Missing parameter' exception
1006+
* @param ReflectionParameter[] missing arguments
9991007
* @return void
10001008
* @throws InvalidLinkException
10011009
* @internal
10021010
*/
1003-
public static function argsToParams($class, $method, & $args, $supplemental = [], $ignoreMissing = FALSE)
1011+
public static function argsToParams($class, $method, & $args, $supplemental = [], & $missing = [])
10041012
{
10051013
$i = 0;
10061014
$rm = new \ReflectionMethod($class, $method);
@@ -1021,10 +1029,11 @@ public static function argsToParams($class, $method, & $args, $supplemental = []
10211029
}
10221030

10231031
if (!isset($args[$name])) {
1024-
if ($param->isDefaultValueAvailable() || $type === 'NULL' || $type === 'array' || $ignoreMissing) {
1025-
continue;
1032+
if (!$param->isDefaultValueAvailable() && $type !== 'NULL' && $type !== 'array') {
1033+
$missing[] = $param;
1034+
unset($args[$name]);
10261035
}
1027-
throw new InvalidLinkException("Missing parameter \$$name required by $class::{$rm->getName()}()");
1036+
continue;
10281037
}
10291038

10301039
if (!ComponentReflection::convertType($args[$name], $type, $isClass)) {

tests/UI/Presenter.link().php7.phpt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class TestPresenter extends Application\UI\Presenter
100100
Assert::same('/index.php?pint=0&pbool=0&p=0&action=params&presenter=Test', $this->link('params', ['pint' => FALSE, 'pbool' => FALSE, 'p' => FALSE, 'parr' => NULL]));
101101
Assert::same("#error: Value passed to persistent parameter 'pbool' in presenter Test must be boolean, string given.", $this->link('this', ['p' => NULL, 'pbool' => 'a']));
102102
Assert::same("#error: Value passed to persistent parameter 'p' in presenter Test must be scalar, array given.", $this->link('this', ['p' => [1], 'pbool' => FALSE]));
103+
Assert::same('/index.php?action=persistent&presenter=Test', $this->link('persistent'));
103104

104105
// Other presenter & action link
105106
Assert::same('/index.php?action=product&presenter=Other', $this->link('Other:product', ['p' => $this->p]));
@@ -238,6 +239,12 @@ class TestPresenter extends Application\UI\Presenter
238239
{
239240
}
240241

242+
243+
public function actionPersistent(int $pint)
244+
{
245+
}
246+
247+
241248
public function handleSignal($x = 1, $y = 1)
242249
{
243250
}

0 commit comments

Comments
 (0)