Skip to content

Commit 1de532b

Browse files
committed
LinkGenerator: refactoring, added validateLinkTarget()
1 parent 8a0fb85 commit 1de532b

File tree

2 files changed

+110
-11
lines changed

2 files changed

+110
-11
lines changed

src/Application/LinkGenerator.php

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ public function createRequest(
135135
$method = $reflection->getSignalMethod($signal);
136136
if (!$method) {
137137
throw new UI\InvalidLinkException("Unknown signal '$signal', missing handler {$reflection->getName()}::{$component::formatSignalMethod($signal)}()");
138-
} elseif ($this->isDeprecated($refPresenter, $method)) {
139-
trigger_error("Link to deprecated signal '$signal'" . ($component === $refPresenter ? '' : ' in ' . $component::class) . " from '{$refPresenter->getName()}:{$refPresenter->getAction()}'.", E_USER_DEPRECATED);
140138
}
141139

140+
$this->validateLinkTarget($refPresenter, $method, "signal '$signal'" . ($component === $refPresenter ? '' : ' in ' . $component::class));
141+
142142
// convert indexed parameters to named
143143
UI\ParameterConverter::toParameters($method, $args, [], $missing);
144144
}
@@ -166,9 +166,7 @@ public function createRequest(
166166
$current = $refPresenter && ($action === '*' || strcasecmp($action, $refPresenter->getAction()) === 0) && $presenterClass === $refPresenter::class;
167167

168168
$reflection = new UI\ComponentReflection($presenterClass);
169-
if ($this->isDeprecated($refPresenter, $reflection)) {
170-
trigger_error("Link to deprecated presenter '$presenter' from '{$refPresenter->getName()}:{$refPresenter->getAction()}'.", E_USER_DEPRECATED);
171-
}
169+
$this->validateLinkTarget($refPresenter, $reflection, "presenter '$presenter'");
172170

173171
foreach (array_intersect_key($reflection->getParameters(), $args) as $name => $param) {
174172
if ($args[$name] === $param['def']) {
@@ -178,9 +176,7 @@ public function createRequest(
178176

179177
// counterpart of run() & tryCall()
180178
if ($method = $reflection->getActionRenderMethod($action)) {
181-
if ($this->isDeprecated($refPresenter, $method)) {
182-
trigger_error("Link to deprecated action '$presenter:$action' from '{$refPresenter->getName()}:{$refPresenter->getAction()}'.", E_USER_DEPRECATED);
183-
}
179+
$this->validateLinkTarget($refPresenter, $method, "action '$presenter:$action'");
184180

185181
UI\ParameterConverter::toParameters($method, $args, $path === 'this' ? $refPresenter->getParameters() : [], $missing);
186182

@@ -296,10 +292,17 @@ public function withReferenceUrl(string $url): static
296292
}
297293

298294

299-
private function isDeprecated(?UI\Presenter $presenter, \ReflectionClass|\ReflectionMethod $reflection): bool
295+
private function validateLinkTarget(
296+
?UI\Presenter $presenter,
297+
\ReflectionClass|\ReflectionMethod $element,
298+
string $message,
299+
): void
300300
{
301-
return $presenter?->invalidLinkMode
302-
&& (UI\ComponentReflection::parseAnnotation($reflection, 'deprecated') || $reflection->getAttributes(Attributes\Deprecated::class));
301+
if ($presenter?->invalidLinkMode
302+
&& (UI\ComponentReflection::parseAnnotation($element, 'deprecated') || $element->getAttributes(Attributes\Deprecated::class))
303+
) {
304+
trigger_error("Link to deprecated $message from '{$presenter->getName()}:{$presenter->getAction()}'.", E_USER_DEPRECATED);
305+
}
303306
}
304307

305308

tests/UI/Deprecated.link().phpt

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
/**
4+
* Test: Nette\Application\UI\Presenter::link() and #[Deprecated]
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Nette\Application;
10+
use Nette\Application\Attributes\Deprecated;
11+
use Nette\Http;
12+
use Tester\Assert;
13+
14+
require __DIR__ . '/../bootstrap.php';
15+
16+
17+
class TestPresenter extends Application\UI\Presenter
18+
{
19+
protected function startup(): void
20+
{
21+
parent::startup();
22+
$this->terminate();
23+
}
24+
25+
26+
#[Deprecated]
27+
public function actionFoo()
28+
{
29+
}
30+
31+
32+
#[Deprecated]
33+
public function handleFoo()
34+
{
35+
}
36+
37+
38+
#[Deprecated]
39+
public function renderBar()
40+
{
41+
}
42+
}
43+
44+
45+
#[Deprecated]
46+
class DeprecatedPresenter extends TestPresenter
47+
{
48+
}
49+
50+
51+
$url = new Http\UrlScript('http://localhost/index.php', '/index.php');
52+
53+
$presenterFactory = Mockery::mock(Nette\Application\IPresenterFactory::class);
54+
$presenterFactory->shouldReceive('getPresenterClass')
55+
->andReturnUsing(fn($presenter) => $presenter . 'Presenter');
56+
57+
$presenter = new TestPresenter;
58+
$presenter->injectPrimary(
59+
new Http\Request($url),
60+
new Http\Response,
61+
$presenterFactory,
62+
new Application\Routers\SimpleRouter,
63+
);
64+
65+
$presenter->invalidLinkMode = TestPresenter::InvalidLinkWarning;
66+
67+
$request = new Application\Request('Test', Http\Request::Get, []);
68+
$presenter->run($request);
69+
70+
Assert::error(
71+
fn() => $presenter->link('foo'),
72+
E_USER_DEPRECATED,
73+
"Link to deprecated action 'Test:foo' from 'Test:default'.",
74+
);
75+
76+
Assert::error(
77+
fn() => $presenter->link('bar'),
78+
E_USER_DEPRECATED,
79+
"Link to deprecated action 'Test:bar' from 'Test:default'.",
80+
);
81+
82+
Assert::error(
83+
fn() => $presenter->link('foo!'),
84+
E_USER_DEPRECATED,
85+
"Link to deprecated signal 'foo' from 'Test:default'.",
86+
);
87+
88+
Assert::error(
89+
fn() => $presenter->link('Deprecated:'),
90+
E_USER_DEPRECATED,
91+
"Link to deprecated presenter 'Deprecated' from 'Test:default'.",
92+
);
93+
94+
Assert::noError(
95+
fn() => $presenter->link('Test:'),
96+
);

0 commit comments

Comments
 (0)