Skip to content

Commit 300adab

Browse files
committed
Component: createComponent<name> methods are checked by checkRequirements()
1 parent 8bb00ee commit 300adab

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

src/Application/UI/Component.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ public function getUniqueId(): string
7373

7474
protected function createComponent(string $name): ?Nette\ComponentModel\IComponent
7575
{
76+
if (method_exists($this, $method = 'createComponent' . $name)) {
77+
$this->checkRequirements(new \ReflectionMethod($this, $method));
78+
}
7679
$res = parent::createComponent($name);
7780
if ($res && !$res instanceof SignalReceiver && !$res instanceof StatePersistent) {
7881
$type = $res::class;

tests/UI/Requires.locations.phpt

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@ class TestMethodHandlePresenter extends Nette\Application\UI\Presenter
5252
}
5353

5454

55+
class TestMethodCreateComponentPresenter extends Nette\Application\UI\Presenter
56+
{
57+
#[Requires(forward: true)]
58+
public function createComponentFoo(): never
59+
{
60+
$this->terminate();
61+
}
62+
63+
64+
public function createComponentBar(): TestMethodCreateComponentControl
65+
{
66+
return new TestMethodCreateComponentControl;
67+
}
68+
}
69+
70+
class TestMethodCreateComponentControl extends Nette\Application\UI\Control
71+
{
72+
#[Requires(forward: true)]
73+
public function createComponentFoo(): never
74+
{
75+
$this->getPresenter()->terminate();
76+
}
77+
78+
79+
#[Requires(actions: 'foo')]
80+
public function createComponentBad(): void
81+
{
82+
}
83+
}
84+
85+
86+
5587
// class-level attribute
5688
$presenter = createPresenter(TestClassPresenter::class);
5789
Assert::noError(
@@ -102,3 +134,38 @@ Assert::exception(
102134
Application\BadRequestException::class,
103135
'Forwarded request is required by TestMethodHandlePresenter::handleFoo()',
104136
);
137+
138+
139+
// method createComponent<name>()
140+
$presenter = createPresenter(TestMethodCreateComponentPresenter::class);
141+
Assert::noError(
142+
fn() => $presenter->run(new Application\Request('', Application\Request::FORWARD, ['foo-a' => 1])),
143+
);
144+
145+
Assert::exception(
146+
fn() => $presenter->run(new Application\Request('', Http\Request::Get, ['foo-a' => 1])),
147+
Application\BadRequestException::class,
148+
'Forwarded request is required by TestMethodCreateComponentPresenter::createComponentFoo()',
149+
);
150+
151+
152+
// method createComponent<name>() in component
153+
$presenter = createPresenter(TestMethodCreateComponentPresenter::class);
154+
Assert::noError(
155+
fn() => $presenter->run(new Application\Request('', Application\Request::FORWARD, ['bar-foo-a' => 1])),
156+
);
157+
158+
Assert::exception(
159+
fn() => $presenter->run(new Application\Request('', Http\Request::Get, ['bar-foo-a' => 1])),
160+
Application\BadRequestException::class,
161+
'Forwarded request is required by TestMethodCreateComponentControl::createComponentFoo()',
162+
);
163+
164+
165+
// option actions in method createComponent<name>() in component
166+
$presenter = createPresenter(TestMethodCreateComponentPresenter::class);
167+
Assert::exception(
168+
fn() => $presenter->run(new Application\Request('', Http\Request::Get, ['bar-bad-a' => 1])),
169+
Nette\InvalidStateException::class,
170+
"Option 'actions' used by TestMethodCreateComponentControl::createComponentBad() is allowed only in presenter.",
171+
);

0 commit comments

Comments
 (0)