Skip to content

Commit 73742cf

Browse files
committed
Presenter: persistent parameters are transmitted between traits (in addition to the class hierarchy) [Closes #183]
1 parent 7765c92 commit 73742cf

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

src/Application/UI/ComponentReflection.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function getPersistentParams(string $class = null): array
5252
if (!$rp->isStatic() && self::parseAnnotation($rp, 'persistent')) {
5353
$params[$name] = [
5454
'def' => $default,
55-
'since' => $isPresenter ? $class : null,
55+
'since' => $isPresenter ? Nette\Utils\Reflection::getPropertyDeclaringClass($rp)->getName() : null,
5656
];
5757
}
5858
}
@@ -94,13 +94,15 @@ public function getPersistentComponents(string $class = null): array
9494
*/
9595
public function saveState(Component $component, array &$params): void
9696
{
97+
$tree = self::getClassesAndTraits(get_class($component));
98+
9799
foreach ($this->getPersistentParams() as $name => $meta) {
98100
if (isset($params[$name])) {
99101
// injected value
100102

101103
} elseif (
102104
array_key_exists($name, $params) // nulls are skipped
103-
|| (isset($meta['since']) && !$component instanceof $meta['since']) // not related
105+
|| (isset($meta['since']) && !isset($tree[$meta['since']])) // not related
104106
|| !isset($component->$name)
105107
) {
106108
continue;
@@ -285,4 +287,23 @@ public function getMethods($filter = -1): array
285287
}
286288
return $res;
287289
}
290+
291+
292+
/**
293+
* return string[]
294+
*/
295+
public static function getClassesAndTraits(string $class): array
296+
{
297+
$res = [$class => $class] + class_parents($class);
298+
$addTraits = function ($type) use (&$res, &$addTraits) {
299+
$res += class_uses($type);
300+
foreach (class_uses($type) as $trait) {
301+
$addTraits($trait);
302+
}
303+
};
304+
foreach ($res as $type) {
305+
$addTraits($type);
306+
}
307+
return $res;
308+
}
288309
}

src/Application/UI/Presenter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,7 @@ protected function getGlobalState(string $forClass = null): array
11001100
}
11011101

11021102
if ($forClass !== null) {
1103+
$tree = ComponentReflection::getClassesAndTraits($forClass);
11031104
$since = null;
11041105
foreach ($state as $key => $foo) {
11051106
if (!isset($sinces[$key])) {
@@ -1109,7 +1110,7 @@ protected function getGlobalState(string $forClass = null): array
11091110
}
11101111
if ($since !== $sinces[$key]) {
11111112
$since = $sinces[$key];
1112-
$ok = $since && is_a($forClass, $since, true);
1113+
$ok = $since && isset($tree[$since]);
11131114
}
11141115
if (!$ok) {
11151116
unset($state[$key]);

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class TestPresenter extends BasePresenter
6464
$this->t2 = 4;
6565
Assert::same('/index.php?p2=2&p1=1&t1=3&t2=4&action=default&presenter=Test', $this->link('this'));
6666
Assert::same('/index.php?p1=1&t1=3&action=default&presenter=Second', $this->link('Second:'));
67-
Assert::same('/index.php?p1=1&t1=3&action=default&presenter=Third', $this->link('Third:'));
67+
Assert::same('/index.php?p1=1&t1=3&t2=4&action=default&presenter=Third', $this->link('Third:'));
6868

6969
$this->p1 = 20;
7070
Assert::same('/index.php?t1=3&action=default&presenter=Second', $this->link('Second:'));
@@ -97,27 +97,27 @@ class ThirdPresenter extends BasePresenter
9797

9898
Assert::same([
9999
'p1' => ['def' => null, 'since' => 'BasePresenter'],
100-
't1' => ['def' => null, 'since' => 'BasePresenter'],
100+
't1' => ['def' => null, 'since' => 'PersistentParam1'],
101101
], BasePresenter::getReflection()->getPersistentParams());
102102

103103
Assert::same([
104104
'p2' => ['def' => null, 'since' => 'TestPresenter'],
105105
'p1' => ['def' => null, 'since' => 'BasePresenter'],
106-
't1' => ['def' => null, 'since' => 'BasePresenter'],
107-
't2' => ['def' => null, 'since' => 'TestPresenter'],
106+
't1' => ['def' => null, 'since' => 'PersistentParam1'],
107+
't2' => ['def' => null, 'since' => 'PersistentParam2A'],
108108
], TestPresenter::getReflection()->getPersistentParams());
109109

110110
Assert::same([
111111
'p1' => ['def' => 20, 'since' => 'BasePresenter'],
112112
'p3' => ['def' => null, 'since' => 'SecondPresenter'],
113-
't1' => ['def' => null, 'since' => 'BasePresenter'],
114-
't3' => ['def' => null, 'since' => 'SecondPresenter'],
113+
't1' => ['def' => null, 'since' => 'PersistentParam1'],
114+
't3' => ['def' => null, 'since' => 'PersistentParam3'],
115115
], SecondPresenter::getReflection()->getPersistentParams());
116116

117117
Assert::same([
118118
'p1' => ['def' => null, 'since' => 'BasePresenter'],
119-
't1' => ['def' => null, 'since' => 'BasePresenter'],
120-
't2' => ['def' => null, 'since' => 'ThirdPresenter'],
119+
't1' => ['def' => null, 'since' => 'PersistentParam1'],
120+
't2' => ['def' => null, 'since' => 'PersistentParam2A'],
121121
], ThirdPresenter::getReflection()->getPersistentParams());
122122

123123

0 commit comments

Comments
 (0)