Skip to content

Commit 34447ec

Browse files
committed
default parameters (wwwDir, appDir, ...) are now overridable in user configs
Previously, parameters from getDefaultParameters() were injected into the compiler AFTER all user configs, which silently overrode any redefinition in common.neon. As a result, e.g. `wwwDir: %rootDir%/www` in a config had no effect when the entry script lived outside %rootDir%/www (CLI scripts, MCP servers, scheduled tasks). Fix: snapshot defaults into $defaultParameters at construction. In generateContainer(), inject defaults BEFORE user configs (overridable), then inject only the diff between $staticParameters and defaults AFTER configs (authoritative — preserves back-compat for setTempDirectory(), addStaticParameters() and similar setters).
1 parent b99f2a3 commit 34447ec

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

src/Bootstrap/Configurator.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,13 @@ class Configurator
7676
/** @var list<string|array<string, mixed>> */
7777
protected array $configs = [];
7878

79+
/** @var array<string, mixed> */
80+
private array $defaultParameters;
81+
7982

8083
public function __construct()
8184
{
82-
$this->staticParameters = $this->getDefaultParameters();
85+
$this->defaultParameters = $this->staticParameters = $this->getDefaultParameters();
8386

8487
if (class_exists(InstalledVersions::class) // back compatibility
8588
&& InstalledVersions::isInstalled('nette/caching')
@@ -305,6 +308,9 @@ public function generateContainer(DI\Compiler $compiler): void
305308
$loader = $this->createLoader();
306309
$loader->setParameters($this->staticParameters);
307310

311+
// Defaults FIRST — overridable by user configs (e.g. wwwDir: %rootDir%/www in common.neon)
312+
$compiler->addConfig(['parameters' => DI\Helpers::escape($this->defaultParameters)]);
313+
308314
foreach ($this->configs as $config) {
309315
if (is_string($config)) {
310316
$compiler->loadConfig($config, $loader);
@@ -313,7 +319,8 @@ public function generateContainer(DI\Compiler $compiler): void
313319
}
314320
}
315321

316-
$compiler->addConfig(['parameters' => DI\Helpers::escape($this->staticParameters)]);
322+
$explicit = array_udiff_assoc($this->staticParameters, $this->defaultParameters, fn($a, $b) => $a === $b ? 0 : 1);
323+
$compiler->addConfig(['parameters' => DI\Helpers::escape($explicit)]);
317324
$compiler->setDynamicParameterNames(array_merge(array_keys($this->dynamicParameters), ['baseUrl']));
318325

319326
$builder = $compiler->getContainerBuilder();
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* Test: default parameters (wwwDir, appDir, ...) are overridable by user configs,
5+
* while addStaticParameters() / setTempDirectory() remain authoritative.
6+
*/
7+
8+
use Nette\Bootstrap\Configurator;
9+
use Tester\Assert;
10+
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
// 1) Default wwwDir is overridable by neon config
16+
test('config overrides default wwwDir', function () {
17+
$configurator = new Configurator;
18+
$configurator->setTempDirectory(getTempDir());
19+
$configurator->addConfig([
20+
'parameters' => ['wwwDir' => '/from/config'],
21+
]);
22+
$container = $configurator->createContainer();
23+
Assert::same('/from/config', $container->parameters['wwwDir']);
24+
});
25+
26+
27+
// 2) addStaticParameters() still wins over neon config (back-compat)
28+
test('addStaticParameters wins over config', function () {
29+
$configurator = new Configurator;
30+
$configurator->setTempDirectory(getTempDir());
31+
$configurator->addStaticParameters(['wwwDir' => '/from/static']);
32+
$configurator->addConfig([
33+
'parameters' => ['wwwDir' => '/from/config'],
34+
]);
35+
$container = $configurator->createContainer();
36+
Assert::same('/from/static', $container->parameters['wwwDir']);
37+
});
38+
39+
40+
// 3) setTempDirectory() still wins over neon config (back-compat)
41+
test('setTempDirectory wins over config', function () {
42+
$tempDir = getTempDir();
43+
$configurator = new Configurator;
44+
$configurator->setTempDirectory($tempDir);
45+
$configurator->addConfig([
46+
'parameters' => ['tempDir' => '/from/config'],
47+
]);
48+
$container = $configurator->createContainer();
49+
Assert::same($tempDir, $container->parameters['tempDir']);
50+
});
51+
52+
53+
// 4) Config-defined parameter referencing a default static parameter resolves correctly
54+
test('config can reference default parameter', function () {
55+
$configurator = new Configurator;
56+
$configurator->setTempDirectory(getTempDir());
57+
$configurator->addStaticParameters(['rootDir' => '/my/root']);
58+
$configurator->addConfig([
59+
'parameters' => ['wwwDir' => '%rootDir%/www'],
60+
]);
61+
$container = $configurator->createContainer();
62+
Assert::same('/my/root/www', $container->parameters['wwwDir']);
63+
});

0 commit comments

Comments
 (0)