Spin-off from #1943846: Improve ParamConverterManager and developer experience for ParamConverters to keep that issue solely focused on the ParamConverter and basic upcasting.
Quick summary, copy&pasted from the other issue:
This patch introduces a new layer to our upcasting strategy. In order to increase the DX when composing new route definitions we can potentially use some magic to automatically discover the typed data types for the parameters of a route instead of having to manually define them one-by-one.
Here is how the entire concept would look (the new layer being the typed data resolvers):
TypedDataResolverManager (automatically deriving typed data types)
Invoked by a RoutingEvents::ALTER subscriber (TypedDataSubscriber). Iterates over every registered typed data resolver service (TypedDataResolverInterface) to try and generate typed data definitions based on whatever strategy that resolver service implements. So far we got two resolver strategies: a) EntityResolver (_entity_form/_entity_list) and b) Reflection (match the type hint of a controller argument to a typed data type).
ParamConverterManager (registering converters)
Invoked by a RoutingEvents::ALTER subscriber (ParamConverterSubscriber) with lower priority than that of TypedDataSubscriber so it runs after we run through the different typed data type resolver strategies. Iterates over every parameter defined in $route->getOption('parameters') (basically, the array structures our typed data resolvers previously filled with stuff and all the parameters that were defined manually). And tries to find a converter service for each of them. There is a maximum of one converter service for each parameter as multiple layers of parameter converters for the same parameter don't make much sense imho. If it finds one that applies, it writes the it's id in the route options ($parameter['converter'] = $id_of_service_that_applies) and continues with the next parameter (if any).
RouteEnhancer (actual upcasting)
The ParamConverterManager is also a RouteEnhancer (as it was before too). It then iterates over all defined parameters and invokes the previously set converter to try and upcast the given argument.
I am filing as feature request although that makes me feel kinda uneasy as I hope we can still get this in for D8 as it was part of the original proposal.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 2041907-3-do-not-test.patch | 57.33 KB | fubhy |
| #2 | merlin-the-magic-puppy.jpg | 14.54 KB | fubhy |
| #1 | 2041907-1.patch | 84.39 KB | fubhy |
Comments
Comment #1
fubhy commentedUploading the patch from #1943846: Improve ParamConverterManager and developer experience for ParamConverters and removing ParamConverter/UpcastingTest.php for now... Will rewrite that as a unit test instead as it needs to be rewritten for the changes in ParamConverter anyways.
Comment #2
fubhy commentedMerlin the magic puppy
"This pup vanishes ..." - Just like our parameter definitions in routing.yml!
Comment #3
fubhy commentedAnd here a easier shorter/easier-to-review version of the above patch: This is what the patch looks like when you filter out *.routing.yml changes from the diff and also exclude the code from the blocking issues (namely #1943846: Improve ParamConverterManager and developer experience for ParamConverters and #1983100: Provide a LoadableInterface for Typed Data objects).
Comment #4
dawehnerMissing "\"
Do we really have to care about that? I know this exist in other places as well, but without it, it might be actually better to throw the exception of $container->getDefinition
Let's order them properly, or at least put symfony somewhere else.
That method name is a copy and paste from the access one. A better name would seriously helpful.
Haven't I reviewed that bit before? @inheritdoc
Missing dot.
So we remove it to be able to add later?
I kind of prefer strotk instead.
Should have the full namespace.
I don't see the need for the ternary here.
Is there any reason why we don't use the entity_test entity types instead? There are multiple of them.
Comment #5
xjmComment #6
effulgentsia commentedRetitling the part of this that I think qualifies as a task, not a feature. Plus, I think it's major, due to the potential for collisions between entity type names and local parameter names once contrib is factored in, as explained in #1906810-20: Require type hints for automatic entity upcasting.
Also, adding the DX tag, since I think that current HEAD's approach of making assumptions about the type of a parameter based solely on its name is a WTF that doesn't match any conventional programming principles. Whereas, this issue's suggestion to use a PHP type hint to guide decisions about what type to upcast to both makes logical sense, and has precedent in Symfony.
I'm also retitling this issue to focus on entities for clarity of purpose and scope. If the solution here ends up working generically for all of TypedData, fine, but I don't think that's a requirement. We have #1906810: Require type hints for automatic entity upcasting for that.
Finally, I see nothing about this issue that would require it to be done before beta. There might be some minor API changes needed, but nothing that would affect any but a very tiny percentage of contrib modules, so I think it's in scope right up until RC.
If anyone disagrees with any of the above, please say so. Thanks.
Comment #7
dawehnerWe agreed a long time ago that #1906810: Require type hints for automatic entity upcasting won't be a generic solution but a specific one just for entity upcasting,
so I wonder whether we really want to keep this issue, or post the last patch from the other issue here and continue it here.
Comment #8
tim.plunkettThe other issue switched from generic TypedData to entities anyway, so moving this back.
Comment #9
dawehnerI am really not sure whether this issue is helpful any longer.
Comment #10
dawehnerI am really not sure whether this issue is helpful any longer.
Comment #11
fubhy commentedRight... It basically kinda died with SCOTCH. Tim, you have been working on Page Manager from what I heard? How do you see this? Will we need something like this or can we solve it in contrib? Typed data definitions on the routes will still make it more generic and easier to implement something like Page Manager I guess... We could still add those definitions for all core routes in contrib of course.
Comment #12
Crell commentedThis seems like it should now be a follow-up to #1906810: Require type hints for automatic entity upcasting. That one is, I think, keeping the current name-based logic for deriving the type but also adding a requirement that the controller type hint properly. Next step is to make it use ONLY the type hint, which presumably is this issue.
Comment #13
tim.plunkettI'm going to wait for that issue to land, but I don't think @Crell accurately described the goal of the issue.
I need to look at what I have for page manager and what @EclipseGc has from a while back, and see if this issue is still 100% needed.
Comment #14
tim.plunkettComment #15
wim leersCan we get an update here? #1906810: Require type hints for automatic entity upcasting may have helped, but it's not clear to me what part of the problem remains.
Let's either close this issue or make clear what still needs to happen.
E.g. the one case that I remember being very frustrating and a huge WTF:
I had to type
{view_mode_id}instead of{view_mode}, otherwise Drupal would try to load the corresponding entity, which caused Drupal to WSOD IIRC.Comment #16
dawehnerThat particular problem was fixed with #1906810: Require type hints for automatic entity upcasting
This issue was more about doing crazy things on typed data level, but I don't think things like
LoadableInterfacewill have a chance to happen.Comment #17
fubhy commentedYep, this issue was mainly about entirely replacing / enhancing the paramconverter resolving based on the slug name with reflection (looking at the typehint of the controller arguments and their names) which would have required some sort of hard-wiring interfaces with typed data types or some other type system. Probably not going to happen. I am not so sure about this idea anymore anyways and rather tend towards annotated type declaration on the controller instead but that's a different story and nothing I would be able to look into due to time constraints :(. We can chat at devdays though.
Comment #18
wim leersI tested and confirmed that it is now possible to write
{view_mode}instead of{view_mode_id}without crashing Drupal. So, from that POV, this is a duplicate.Should we close this issue?
Comment #19
dawehnerI'd like to chat with you about things, indeed!
Well, this is basically what we do now, but just on the entity level. Let's mark this issue as won't fix, okay?