-
-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DI not accepting null value of Nette config parameter if parameter is Object #283
Comments
Your steps to reproduce show only extension registration, but not extension config, do you use any?
foo:
redis_client_factory:
replication: [] By default is only structure required(), other Expect:: methods expect value only optionally. With these presumption, your minimal configuration should create following structure:
Always use either nullable() or required() if you want to be sure |
In this scenario, I didn't use any extra configuration for extension. But thanks for the clarification of the What's more important, your comment made me realize, that this fails at the different place than I thought. Internally, we set extra parameters to the application configuration based on the extension configuration: public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
// set extension parameters for use in config
$builder->parameters['redis_client_factory'] = $this->config->redis_client_factory; // this is now stdClass
// ...
} Then we let other extensions to use So what actually happened was, that we made one of the config parameters So the question is different.
|
Extension configuration can be get this way: foreach ($this->compiler->getExtensions(FooExtension::class) as $extension) {
$extension->getConfig();
} Alternatively, you could get extension the same way and call some public method on it. In an extension, parameters are already inlined where they were passed, so any changes to them will affect only extensions that access parameters directly and parameters in generated DIC. Also having an object in parameters was never expected, so that is probably why you got an exception. Personally, I don't like extensions configuring each other, it can mess up really easy. Instead, do most of the config in neon, if it's not more complicated than in extension. Even vendor packages can have neon files, just add them via Configurator as usual. |
But you are right the condition is wrong. It should throw objects are not supported. Ideally I think builder parameters should be marked |
Thanks for the hints. I had a hunch that what I do is not the cleanest approach in the world, so we'll just try to amend it on our side. The rest ( |
(the original description of the issue is outdated and there's no issue with
Structure
, please read the discussion below)Version: 3.0.13
Bug Description
Configuration of Nette extension can be configured by
getConfigSchema()
which returnsNette\Schema\Elements\Structure
. The actual config is then returned asstdClass
.Consider using this config in the extension:
If I don't provide any configuration value to the
redis_client_factory.prefix
, the default (null
) is used. All is fine to this point.The issue is that the DI container reports, that the
redis_client_factory.prefix
is missing, even if it is nullable. The reason why this happen is this snippet:di/src/DI/Helpers.php
Lines 72 to 78 in 5f0b849
In the past, DI could work with the assumption that the config is always array, but it's not true anymore. Now our code throws an exception from the
else
branch.false
, because our config ($val
) is not anarray
, butstdClass
array_key_exists()
withstdClass
would work for now, but it is deprecated - you'd get "array_key_exists(): Using array_key_exists() on objects is deprecated. Use isset() or property_exists() instead".Steps To Reproduce
The fastest would be to try to use such extension in your Nette application. Use the snippet from above in your testing extension.
FooExtension
Now enable the extension in your Nette application:
Expected Behavior
Since the property was defined as
nullable()
, DI should consider "no value" defaulting tonull
as a valid extension configuration.Possible Solution
If I understand the code correctly, another
elseif
branch forstdClass
usingproperty_exists()
should be sufficient, but I can't tell for sure.Thanks for checking.
The text was updated successfully, but these errors were encountered: