Skip to content

Commit 8c7648b

Browse files
klimesfdg
authored andcommitted
Presenter, ApplicationExtension: changed handling of invalid link
- triggers warnings on production - warning on development are configurable via 'silentLinks'
1 parent 1dcd4a8 commit 8c7648b

4 files changed

Lines changed: 148 additions & 15 deletions

File tree

src/Application/UI/Presenter.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@
3434
abstract class Presenter extends Control implements Application\IPresenter
3535
{
3636
/** bad link handling {@link Presenter::$invalidLinkMode} */
37-
const INVALID_LINK_SILENT = 1,
38-
INVALID_LINK_WARNING = 2,
39-
INVALID_LINK_EXCEPTION = 3;
37+
const INVALID_LINK_SILENT = 0,
38+
INVALID_LINK_WARNING = 1,
39+
INVALID_LINK_EXCEPTION = 2,
40+
INVALID_LINK_TEXTUAL = 4;
4041

4142
/** @internal special parameter key */
4243
const SIGNAL_KEY = 'do',
@@ -1060,15 +1061,14 @@ public static function argsToParams($class, $method, & $args, $supplemental = ar
10601061
*/
10611062
protected function handleInvalidLink(InvalidLinkException $e)
10621063
{
1063-
if ($this->invalidLinkMode === self::INVALID_LINK_SILENT) {
1064-
return '#';
1065-
1066-
} elseif ($this->invalidLinkMode === self::INVALID_LINK_WARNING) {
1067-
return '#error: ' . $e->getMessage();
1068-
1069-
} else { // self::INVALID_LINK_EXCEPTION
1064+
if ($this->invalidLinkMode & self::INVALID_LINK_EXCEPTION) {
10701065
throw $e;
1066+
} elseif ($this->invalidLinkMode & self::INVALID_LINK_WARNING) {
1067+
trigger_error('Invalid link: ' . $e->getMessage(), E_USER_WARNING);
10711068
}
1069+
return $this->invalidLinkMode & self::INVALID_LINK_TEXTUAL
1070+
? '#error: ' . $e->getMessage()
1071+
: '#';
10721072
}
10731073

10741074

src/Bridges/ApplicationDI/ApplicationExtension.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@ class ApplicationExtension extends Nette\DI\CompilerExtension
2626
'scanDirs' => array(),
2727
'scanComposer' => NULL,
2828
'scanFilter' => 'Presenter',
29+
'silentLinks' => FALSE,
2930
);
3031

3132
/** @var bool */
3233
private $debugMode;
3334

35+
/** @var int */
36+
private $invalidLinkMode;
37+
3438

3539
public function __construct($debugMode = FALSE, array $scanDirs = NULL)
3640
{
@@ -47,6 +51,10 @@ public function loadConfiguration()
4751
$container = $this->getContainerBuilder();
4852
$container->addExcludedClasses(array('Nette\Application\UI\Control'));
4953

54+
$this->invalidLinkMode = $this->debugMode
55+
? UI\Presenter::INVALID_LINK_TEXTUAL | ($config['silentLinks'] ? 0 : UI\Presenter::INVALID_LINK_WARNING)
56+
: UI\Presenter::INVALID_LINK_WARNING;
57+
5058
$application = $container->addDefinition($this->prefix('application'))
5159
->setClass('Nette\Application\Application')
5260
->addSetup('$catchExceptions', array($config['catchExceptions']))
@@ -57,11 +65,10 @@ public function loadConfiguration()
5765
}
5866

5967
$touch = $this->debugMode && $config['scanDirs'] ? reset($config['scanDirs']) : NULL; // dir added as dependency
60-
$invalidLinkMode = $this->debugMode ? UI\Presenter::INVALID_LINK_WARNING : UI\Presenter::INVALID_LINK_SILENT;
6168
$presenterFactory = $container->addDefinition($this->prefix('presenterFactory'))
6269
->setClass('Nette\Application\IPresenterFactory')
6370
->setFactory('Nette\Application\PresenterFactory', array(new Nette\DI\Statement(
64-
'Nette\Bridges\ApplicationDI\PresenterFactoryCallback', array(1 => $invalidLinkMode, $touch)
71+
'Nette\Bridges\ApplicationDI\PresenterFactoryCallback', array(1 => $this->invalidLinkMode, $touch)
6572
)));
6673

6774
if ($config['mapping']) {
@@ -99,9 +106,7 @@ public function beforeCompile()
99106
foreach ($all as $def) {
100107
$def->setInject(TRUE)->setAutowired(FALSE)->addTag('nette.presenter', $def->getClass());
101108
if (is_subclass_of($def->getClass(), 'Nette\Application\UI\Presenter')) {
102-
$def->addSetup('$invalidLinkMode', array(
103-
$this->debugMode ? UI\Presenter::INVALID_LINK_WARNING : UI\Presenter::INVALID_LINK_SILENT
104-
));
109+
$def->addSetup('$invalidLinkMode', array($this->invalidLinkMode));
105110
}
106111
}
107112
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/**
4+
* Test: ApplicationExtension
5+
*/
6+
7+
use Nette\DI,
8+
Nette\Bridges\ApplicationDI\ApplicationExtension,
9+
Nette\Application\UI\Presenter,
10+
Tester\Assert;
11+
12+
13+
require __DIR__ . '/../bootstrap.php';
14+
require __DIR__ . '/files/MyPresenter.php';
15+
16+
17+
function createCompiler($config)
18+
{
19+
$compiler = new DI\Compiler;
20+
$compiler->loadConfig(Tester\FileMock::create($config, 'neon'));
21+
$builder = $compiler->getContainerBuilder();
22+
$builder->addDefinition('myRouter')->setClass('Nette\Application\Routers\SimpleRouter');
23+
$builder->addDefinition('myHttpRequest')->setFactory('Nette\Http\Request', array(new DI\Statement('Nette\Http\UrlScript')));
24+
$builder->addDefinition('myHttpResponse')->setClass('Nette\Http\Response');
25+
return $compiler;
26+
}
27+
28+
29+
test(function() {
30+
$compiler = createCompiler('
31+
application:
32+
debugger: no
33+
silentLinks: yes
34+
35+
services:
36+
presenter: Presenter1
37+
');
38+
$compiler->addExtension('application', new ApplicationExtension(TRUE));
39+
$code = $compiler->compile(NULL, 'Container4');
40+
eval($code);
41+
42+
$container = new Container4;
43+
Assert::same(
44+
Presenter::INVALID_LINK_TEXTUAL,
45+
$container->getService('presenter')->invalidLinkMode
46+
);
47+
});
48+
49+
50+
test(function() {
51+
$compiler = createCompiler('
52+
application:
53+
debugger: no
54+
silentLinks: no
55+
56+
services:
57+
presenter: Presenter1
58+
');
59+
$compiler->addExtension('application', new ApplicationExtension(TRUE));
60+
$code = $compiler->compile(NULL, 'Container5');
61+
eval($code);
62+
63+
$container = new Container5;
64+
Assert::same(
65+
Presenter::INVALID_LINK_WARNING | Presenter::INVALID_LINK_TEXTUAL,
66+
$container->getService('presenter')->invalidLinkMode
67+
);
68+
});
69+
70+
71+
test(function() {
72+
$compiler = createCompiler('
73+
application:
74+
debugger: no
75+
silentLinks: yes
76+
77+
services:
78+
presenter: Presenter1
79+
');
80+
$compiler->addExtension('application', new ApplicationExtension(FALSE));
81+
$code = $compiler->compile(NULL, 'Container6');
82+
eval($code);
83+
84+
$container = new Container6;
85+
Assert::same(
86+
Presenter::INVALID_LINK_WARNING,
87+
$container->getService('presenter')->invalidLinkMode
88+
);
89+
});
90+
91+
92+
test(function() {
93+
$compiler = createCompiler('
94+
application:
95+
debugger: no
96+
silentLinks: no
97+
98+
services:
99+
presenter: Presenter1
100+
');
101+
$compiler->addExtension('application', new ApplicationExtension(FALSE));
102+
$code = $compiler->compile(NULL, 'Container7');
103+
eval($code);
104+
105+
$container = new Container7;
106+
Assert::same(
107+
Presenter::INVALID_LINK_WARNING,
108+
$container->getService('presenter')->invalidLinkMode
109+
);
110+
});

tests/Application/Presenter.link().phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class TestPresenter extends Application\UI\Presenter
7777
{
7878
parent::startup();
7979
$this['mycontrol'] = new TestControl;
80+
$this->invalidLinkMode = self::INVALID_LINK_TEXTUAL;
8081

8182
// Presenter & action link
8283
Assert::same( '/index.php?action=product&presenter=Test', $this->link('product', array('var1' => $this->var1)) );
@@ -133,6 +134,23 @@ class TestPresenter extends Application\UI\Presenter
133134
$this['mycontrol']->order = 1;
134135
Assert::same( "#error: Invalid value for persistent parameter 'order' in 'mycontrol', expected array.", $this['mycontrol']->link('click') );
135136
$this['mycontrol']->order = NULL;
137+
138+
// silent invalid link mode
139+
$this->invalidLinkMode = self::INVALID_LINK_SILENT;
140+
Assert::same('#', $this->link('product', array('var1' => null, 'ok' => 'a')));
141+
142+
// warning invalid link mode
143+
$this->invalidLinkMode = self::INVALID_LINK_WARNING;
144+
$me = $this;
145+
Assert::error(function() use ($me) {
146+
Assert::same('#', $me->link('product', array('var1' => null, 'ok' => 'a')));
147+
}, E_USER_WARNING, "Invalid link: Invalid value for persistent parameter 'ok' in 'Test', expected boolean.");
148+
149+
// exception invalid link mode
150+
$this->invalidLinkMode = self::INVALID_LINK_EXCEPTION;
151+
Assert::exception(function() use ($me) {
152+
$me->link('product', array('var1' => null, 'ok' => 'a'));
153+
}, 'Nette\Application\UI\InvalidLinkException', "Invalid value for persistent parameter 'ok' in 'Test', expected boolean.");
136154
}
137155

138156

0 commit comments

Comments
 (0)