-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[DependencyInjection] Introduce a new ParameterResolver #17192
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
Conversation
@@ -264,6 +219,9 @@ public function escapeValue($value) | |||
return $value; | |||
} | |||
|
|||
/** | |||
* {@inheritdoc} | |||
*/ | |||
public function unescapeValue($value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if this function should also be moved in the ParameterResolver
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not really related to resolving values, is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is, after resolving a value we must want to unescape it.
An example if I use
$resolver = new ParameterResolver(function() { return 'foobar'; });
$resolver->resolveValue('foo %bar% %%');
I will obtain foo foobar %%
which is still escaped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks like an issue with resolveValue, isn't it? I'd expect resolveValue to resolve parameters and escaping in the same run (but without exposing any specific public method for that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that it was mostly introduced in #4707.
We can still add a new argument to resolveValue()
which would specify if the value must be unescaped (and change its default value in 4.0) and deprecate unescapeValue
and escapeValue
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nicolas-grekas I added BC layers in the latest commits to unescape values by default but I'm not sure we should do that in this PR (this makes a lot of changes).
Should I open a new PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolveValue
can return different values depending if the ParameterBag
is resolved or not...
See this example:
$parameterBag = new ParameterBag(array(
'foo' => '100 %%',
));
$parameterBag->resolveValue('%foo% %%'); // will return '100 %% %%'
$parameterBag->resolve();
$parameterBag->resolveValue('%foo% %%'); // will return '100% %%'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only solution I see to fix this inconsistency is to manage the entire unescaping process in resolveValue
@xabbuh Do you prefer this solution where the values fetched are resolved in the |
My second proposition needs a more complex callback but in case we use the Container instead of a ParameterBag to resolve values, this is more natural (no need to mark the values as resolved). |
private function getResolver() | ||
{ | ||
if (null === $this->resolver) { | ||
$self = $this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for that as this is targetting master (which requires php 5.5)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right I didn't know that this changed in php 5.5
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it actually chnaged in php 5.4 :}
a06941d
to
4623434
Compare
{ | ||
$this->parameters = $parameters; | ||
$this->resolved = true; | ||
$this->resolver = $resolver; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the resolver useless here in the frozen bag ? Shoudn't everything already being resolved ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FrozenParameterBag::resolveValue()
can still be used.
I'm wondering if instead of using a |
No, you wouldn't be able to change the resolver then (and thus the point of such a class would be next to none). But it could be defined as a trait |
Generic names like |
@unkind you're right, makes even more sense now that there is a trait... But are you sure |
* | ||
* @throws ParameterNotFoundException if the parameter is not defined | ||
*/ | ||
abstract protected function getParameter($name, $resolving = array()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this function should be named getParameter
or something else to avoid conflicts...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like having an abstract method in the trait. What about adding a private setParameterBag()
method instead that must be called by the consuming class? This method could populate an internal ParameterBag
property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like it to work on top of a any container (and a container may not use ParameterBag
). I didn't find anything better to solve this abstraction issue.
Other reviews? |
@@ -227,7 +159,7 @@ public function testEscapeValue() | |||
/** | |||
* @dataProvider stringsWithSpacesProvider | |||
*/ | |||
public function testResolveStringWithSpacesReturnsString($expected, $test, $description) | |||
public function testLegacyResolveStringWithSpacesReturnsString($expected, $test, $description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add the @group legacy
annotation
5082a50
to
a5c5247
Compare
The build failure doesn't seem related... |
a5c5247
to
126f934
Compare
In fact it is... I'll try to fix them |
I reverted the last commits because this is a big subject and they just make this PR bigger than it has to be... |
@Ener-Getick Very nice PR! Thanks for great job |
dbe15d2
to
3a65c98
Compare
Deprecation message updated to |
3a65c98
to
8c0875c
Compare
* @throws ParameterCircularReferenceException if a circular reference is detected | ||
* @throws RuntimeException when a given parameter has a type problem. | ||
*/ | ||
public function resolveValue($value, array $resolving = array()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo the public interface should not leak the $resolving
argument (it's an implementation detail). We could add a private method that does the actual resolving an let resolveValue()
call it with an empty array as the second argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And by the way, the ParameterResolverInterface
even doesn't require this second argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine for me.
Besides that, I'm wondering if we shouldn't make this method private by default: in userland it is unlikely to be used outside the class using the trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: I agree, but we can't do that for bc reasons, see our previous conversation
/** | ||
* Implementation of {@link ParameterResolverInterface}. | ||
* | ||
* @author Guilhem N. <egetick@gmail.com> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add the author(s) of the ParameterBag
class too (the main logic was only slightly touched).
* | ||
* @author Guilhem N. <egetick@gmail.com> | ||
*/ | ||
interface ParameterResolverInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need an extra interface for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking using it for other classes than ParameterBag
but indeed we can remove it unless someone explicitly requests it.
91e6f1a
to
83f3954
Compare
83f3954
to
2ff482a
Compare
Shouldn't this one be closed in favor of #20276? |
@nicolas-grekas the goal is not the same. I'd like to use this to resolve values at runtime (in annotations for example) without copying a large portion of code like what we did in FOSRestBundle. |
I agree with @GuilhemN and I would like to see this in 3.3 too. |
@xabbuh would you like to take over this PR? I personally don't get its point but I think that's just because I'm not in this part of the business :) |
I'll try to do that by the end of the week. If someone wants to take over before, just feel free to do so. |
Could this be solved differently with #25288? |
@nicolas-grekas it looks like it does indeed, 👍 for your approach :) |
Cool, closing then. Cheers. |
As suggested by @xabbuh, this PR creates a new
ParameterResolver
used internally by theParameterBag
.