Skip to content

Commit 0f0c24c

Browse files
committed
DI extensions: are using configuration Schema
1 parent d8141c0 commit 0f0c24c

File tree

4 files changed

+79
-61
lines changed

4 files changed

+79
-61
lines changed

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"mockery/mockery": "^1.0"
3737
},
3838
"conflict": {
39-
"nette/di": "<2.4",
39+
"nette/di": "<3.0",
4040
"nette/forms": "<3.0",
4141
"nette/latte": "<3.0"
4242
},

src/Bridges/ApplicationDI/ApplicationExtension.php

+37-31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Composer\Autoload\ClassLoader;
1313
use Nette;
1414
use Nette\Application\UI;
15+
use Nette\DI\Config\Expect;
16+
use Nette\DI\Definitions;
1517
use Tracy;
1618

1719

@@ -20,20 +22,12 @@
2022
*/
2123
final class ApplicationExtension extends Nette\DI\CompilerExtension
2224
{
23-
private $defaults = [
24-
'debugger' => null,
25-
'errorPresenter' => 'Nette:Error',
26-
'catchExceptions' => null,
27-
'mapping' => null,
28-
'scanDirs' => [],
29-
'scanComposer' => null,
30-
'scanFilter' => 'Presenter',
31-
'silentLinks' => false,
32-
];
33-
3425
/** @var bool */
3526
private $debugMode;
3627

28+
/** @var array */
29+
private $scanDirs;
30+
3731
/** @var int */
3832
private $invalidLinkMode;
3933

@@ -43,48 +37,60 @@ final class ApplicationExtension extends Nette\DI\CompilerExtension
4337

4438
public function __construct(bool $debugMode = false, array $scanDirs = null, string $tempDir = null)
4539
{
46-
$this->defaults['debugger'] = interface_exists(Tracy\IBarPanel::class);
47-
$this->defaults['scanDirs'] = (array) $scanDirs;
48-
$this->defaults['scanComposer'] = class_exists(ClassLoader::class);
49-
$this->defaults['catchExceptions'] = !$debugMode;
5040
$this->debugMode = $debugMode;
41+
$this->scanDirs = (array) $scanDirs;
5142
$this->tempDir = $tempDir;
5243
}
5344

5445

46+
public function getConfigSchema(): Nette\DI\Config\Schema
47+
{
48+
return Expect::structure([
49+
'debugger' => Expect::bool(interface_exists(Tracy\IBarPanel::class)),
50+
'errorPresenter' => Expect::string('Nette:Error')->dynamic(),
51+
'catchExceptions' => Expect::bool(!$this->debugMode)->dynamic(),
52+
'mapping' => Expect::arrayOf('string')->dynamic(),
53+
'scanDirs' => Expect::enum(Expect::arrayOf('string')->default($this->scanDirs), false),
54+
'scanComposer' => Expect::bool(class_exists(ClassLoader::class)),
55+
'scanFilter' => Expect::string('Presenter'),
56+
'silentLinks' => Expect::bool(),
57+
]);
58+
}
59+
60+
5561
public function loadConfiguration()
5662
{
57-
$config = $this->validateConfig($this->defaults);
63+
$config = $this->config;
5864
$builder = $this->getContainerBuilder();
5965
$builder->addExcludedClasses([UI\Presenter::class]);
6066

6167
$this->invalidLinkMode = $this->debugMode
62-
? UI\Presenter::INVALID_LINK_TEXTUAL | ($config['silentLinks'] ? 0 : UI\Presenter::INVALID_LINK_WARNING)
68+
? UI\Presenter::INVALID_LINK_TEXTUAL | ($config->silentLinks ? 0 : UI\Presenter::INVALID_LINK_WARNING)
6369
: UI\Presenter::INVALID_LINK_WARNING;
6470

6571
$application = $builder->addDefinition($this->prefix('application'))
6672
->setFactory(Nette\Application\Application::class)
67-
->addSetup('$catchExceptions', [$config['catchExceptions']])
68-
->addSetup('$errorPresenter', [$config['errorPresenter']]);
73+
->addSetup('$catchExceptions', [$config->catchExceptions])
74+
->addSetup('$errorPresenter', [$config->errorPresenter]);
6975

70-
if ($config['debugger']) {
76+
if ($config->debugger) {
7177
$application->addSetup([Nette\Bridges\ApplicationTracy\RoutingPanel::class, 'initializePanel']);
7278
}
7379

74-
$touch = $this->debugMode && $config['scanDirs'] && $this->tempDir ? $this->tempDir . '/touch' : null;
80+
$touch = $this->debugMode && $config->scanDirs && $this->tempDir ? $this->tempDir . '/touch' : null;
7581
$presenterFactory = $builder->addDefinition($this->prefix('presenterFactory'))
7682
->setType(Nette\Application\IPresenterFactory::class)
77-
->setFactory(Nette\Application\PresenterFactory::class, [new Nette\DI\Definitions\Statement(
83+
->setFactory(Nette\Application\PresenterFactory::class, [new Definitions\Statement(
7884
Nette\Bridges\ApplicationDI\PresenterFactoryCallback::class, [1 => $this->invalidLinkMode, $touch]
7985
)]);
8086

81-
if ($config['mapping']) {
82-
$presenterFactory->addSetup('setMapping', [$config['mapping']]);
87+
if ($config->mapping) {
88+
$presenterFactory->addSetup('setMapping', [$config->mapping]);
8389
}
8490

8591
$builder->addDefinition($this->prefix('linkGenerator'))
8692
->setFactory(Nette\Application\LinkGenerator::class, [
87-
1 => new Nette\DI\Definitions\Statement('@Nette\Http\IRequest::getUrl'),
93+
1 => new Definitions\Statement('@Nette\Http\IRequest::getUrl'),
8894
]);
8995

9096
if ($this->name === 'application') {
@@ -115,7 +121,7 @@ public function beforeCompile()
115121
$def->addTag(Nette\DI\Extensions\InjectExtension::TAG_INJECT)
116122
->setAutowired(false);
117123

118-
if (is_subclass_of($def->getType(), UI\Presenter::class)) {
124+
if (is_subclass_of($def->getType(), UI\Presenter::class) && $def instanceof Definitions\ServiceDefinition) {
119125
$def->addSetup('$invalidLinkMode', [$this->invalidLinkMode]);
120126
}
121127
}
@@ -127,13 +133,13 @@ private function findPresenters(): array
127133
$config = $this->getConfig();
128134
$classes = [];
129135

130-
if ($config['scanDirs']) {
136+
if ($config->scanDirs) {
131137
if (!class_exists(Nette\Loaders\RobotLoader::class)) {
132138
throw new Nette\NotSupportedException("RobotLoader is required to find presenters, install package `nette/robot-loader` or disable option {$this->prefix('scanDirs')}: false");
133139
}
134140
$robot = new Nette\Loaders\RobotLoader;
135-
$robot->addDirectory(...$config['scanDirs']);
136-
$robot->acceptFiles = ['*' . $config['scanFilter'] . '*.php'];
141+
$robot->addDirectory(...$config->scanDirs);
142+
$robot->acceptFiles = ['*' . $config->scanFilter . '*.php'];
137143
if ($this->tempDir) {
138144
$robot->setTempDirectory($this->tempDir);
139145
$robot->refresh();
@@ -144,7 +150,7 @@ private function findPresenters(): array
144150
$this->getContainerBuilder()->addDependency($this->tempDir . '/touch');
145151
}
146152

147-
if ($config['scanComposer']) {
153+
if ($config->scanComposer) {
148154
$rc = new \ReflectionClass(ClassLoader::class);
149155
$classFile = dirname($rc->getFileName()) . '/autoload_classmap.php';
150156
if (is_file($classFile)) {
@@ -158,7 +164,7 @@ private function findPresenters(): array
158164
$presenters = [];
159165
foreach (array_unique($classes) as $class) {
160166
if (
161-
strpos($class, $config['scanFilter']) !== false
167+
strpos($class, $config->scanFilter) !== false
162168
&& class_exists($class)
163169
&& ($rc = new \ReflectionClass($class))
164170
&& $rc->implementsInterface(Nette\Application\IPresenter::class)

src/Bridges/ApplicationDI/LatteExtension.php

+17-13
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,6 @@
1818
*/
1919
final class LatteExtension extends Nette\DI\CompilerExtension
2020
{
21-
public $defaults = [
22-
'xhtml' => false,
23-
'macros' => [],
24-
'templateClass' => null,
25-
'strictTypes' => false,
26-
];
27-
2821
/** @var bool */
2922
private $debugMode;
3023

@@ -36,6 +29,17 @@ public function __construct(string $tempDir, bool $debugMode = false)
3629
{
3730
$this->tempDir = $tempDir;
3831
$this->debugMode = $debugMode;
32+
33+
$this->config = new class {
34+
/** @var bool */
35+
public $xhtml = false;
36+
/** @var string[] */
37+
public $macros = [];
38+
/** @var ?string */
39+
public $templateClass;
40+
/** @var bool */
41+
public $strictTypes = false;
42+
};
3943
}
4044

4145

@@ -45,7 +49,7 @@ public function loadConfiguration()
4549
return;
4650
}
4751

48-
$config = $this->validateConfig($this->defaults);
52+
$config = $this->config;
4953
$builder = $this->getContainerBuilder();
5054

5155
$latteFactory = $builder->addFactoryDefinition($this->prefix('latteFactory'))
@@ -54,19 +58,19 @@ public function loadConfiguration()
5458
->setFactory(Latte\Engine::class)
5559
->addSetup('setTempDirectory', [$this->tempDir])
5660
->addSetup('setAutoRefresh', [$this->debugMode])
57-
->addSetup('setContentType', [$config['xhtml'] ? Latte\Compiler::CONTENT_XHTML : Latte\Compiler::CONTENT_HTML])
58-
->addSetup('Nette\Utils\Html::$xhtml = ?', [(bool) $config['xhtml']]);
61+
->addSetup('setContentType', [$config->xhtml ? Latte\Compiler::CONTENT_XHTML : Latte\Compiler::CONTENT_HTML])
62+
->addSetup('Nette\Utils\Html::$xhtml = ?', [$config->xhtml]);
5963

60-
if ($config['strictTypes']) {
64+
if ($config->strictTypes) {
6165
$latteFactory->addSetup('setStrictTypes', [true]);
6266
}
6367

6468
$builder->addDefinition($this->prefix('templateFactory'))
6569
->setType(Nette\Application\UI\ITemplateFactory::class)
6670
->setFactory(Nette\Bridges\ApplicationLatte\TemplateFactory::class)
67-
->setArguments(['templateClass' => $config['templateClass']]);
71+
->setArguments(['templateClass' => $config->templateClass]);
6872

69-
foreach ($config['macros'] as $macro) {
73+
foreach ($config->macros as $macro) {
7074
$this->addMacro($macro);
7175
}
7276

src/Bridges/ApplicationDI/RoutingExtension.php

+24-16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace Nette\Bridges\ApplicationDI;
1111

1212
use Nette;
13+
use Nette\DI\Definitions;
1314
use Tracy;
1415

1516

@@ -18,36 +19,38 @@
1819
*/
1920
final class RoutingExtension extends Nette\DI\CompilerExtension
2021
{
21-
public $defaults = [
22-
'debugger' => null,
23-
'routes' => [], // of [mask => action]
24-
'routeClass' => null,
25-
'cache' => false,
26-
];
27-
2822
/** @var bool */
2923
private $debugMode;
3024

3125

3226
public function __construct(bool $debugMode = false)
3327
{
34-
$this->defaults['debugger'] = interface_exists(Tracy\IBarPanel::class);
3528
$this->debugMode = $debugMode;
29+
30+
$this->config = new class {
31+
/** @var bool */
32+
public $debugger;
33+
/** @var string[] */
34+
public $routes = [];
35+
/** @var ?string */
36+
public $routeClass = Nette\Application\Routers\Route::class;
37+
/** @var bool */
38+
public $cache = false;
39+
};
40+
$this->config->debugger = interface_exists(Tracy\IBarPanel::class);
3641
}
3742

3843

3944
public function loadConfiguration()
4045
{
41-
$config = $this->validateConfig($this->defaults);
4246
$builder = $this->getContainerBuilder();
4347

4448
$router = $builder->addDefinition($this->prefix('router'))
4549
->setType(Nette\Application\IRouter::class)
4650
->setFactory(Nette\Application\Routers\RouteList::class);
4751

48-
$routeClass = $config['routeClass'] ?: Nette\Application\Routers\Route::class;
49-
foreach ($config['routes'] as $mask => $action) {
50-
$router->addSetup('$service[] = new ' . $routeClass . '(?, ?)', [$mask, $action]);
52+
foreach ($this->config->routes as $mask => $action) {
53+
$router->addSetup('$service[] = new ' . $this->config->routeClass . '(?, ?)', [$mask, $action]);
5154
}
5255

5356
if ($this->name === 'routing') {
@@ -60,17 +63,22 @@ public function beforeCompile()
6063
{
6164
$builder = $this->getContainerBuilder();
6265

63-
if ($this->debugMode && $this->config['debugger'] && $application = $builder->getByType(Nette\Application\Application::class)) {
64-
$builder->getDefinition($application)->addSetup('@Tracy\Bar::addPanel', [
65-
new Nette\DI\Definitions\Statement(Nette\Bridges\ApplicationTracy\RoutingPanel::class),
66+
if (
67+
$this->debugMode &&
68+
$this->config->debugger &&
69+
($name = $builder->getByType(Nette\Application\Application::class)) &&
70+
($application = $builder->getDefinition($name)) instanceof Definitions\ServiceDefinition
71+
) {
72+
$application->addSetup('@Tracy\Bar::addPanel', [
73+
new Definitions\Statement(Nette\Bridges\ApplicationTracy\RoutingPanel::class),
6674
]);
6775
}
6876
}
6977

7078

7179
public function afterCompile(Nette\PhpGenerator\ClassType $class)
7280
{
73-
if (!empty($this->config['cache'])) {
81+
if ($this->config->cache) {
7482
$method = $class->getMethod(Nette\DI\Container::getMethodName($this->prefix('router')));
7583
try {
7684
$router = eval($method->getBody());

0 commit comments

Comments
 (0)