Skip to content
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

[DoctrineBridge] Add an Entity Argument Resolver #43854

Merged
merged 2 commits into from
Jul 20, 2022

Conversation

jderusse
Copy link
Member

@jderusse jderusse commented Oct 31, 2021

Q A
Branch? 6.1
Bug fix? no
New feature? yes
Deprecations? no
Tickets part of #40333
License MIT
Doc PR todo

This PR provides an Argument Resolver for Doctrine entities.

This would replace the SensioFramework's DoctrineParamConverter (in fact most of the code is copy/pasted from here) and helps users to disable the paramConverter and fix the related issue.

usage:

sensio_framework_extra:
    request:
        converters: false
services:
    Symfony\Bridge\Doctrine\ArgumentResolver\EntityValueResolver: ~
#[Route('/blog/{slug}')]
public function show(Post $post)
{
}

or with custom options

#[Route('/blog/{id}')]
public function show(
  #[MapEntity(entityManager: 'foo', expr: 'repository.findNotDeletedById(id)')]
  Post $post
)
{
}

@jderusse jderusse added this to the 6.1 milestone Oct 31, 2021
@carsonbot carsonbot changed the title Add an Entity Argument Resolver [DoctrineBridge] Add an Entity Argument Resolver Oct 31, 2021
@carsonbot carsonbot modified the milestones: 6.1, 6.0 Oct 31, 2021
@jderusse jderusse force-pushed the doctrine-resolver branch 4 times, most recently from bfff004 to 5be70c3 Compare October 31, 2021 11:13
@fabpot fabpot modified the milestones: 6.0, 6.1 Nov 3, 2021
Copy link
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a constructor flag to make the resolver opt-in? I'd like to keep it dormant unless I use the attribute.

@jderusse
Copy link
Member Author

Can we add a constructor flag to make the resolver opt-in? I'd like to keep it dormant unless I use the attribute.

Added a constructor option that make the resolver ignoring arguments without attribute

Copy link
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far. About the test: This whole feature is tested with a fully mocked entity manager. Since Doctrine ORM is an external library, this could make the tests brittle and hard to maintain if the ORM changes it's behavior (for whatever reason).

Shall we try to test agains a real EM with an in-memory SQLite DB?

@jderusse jderusse force-pushed the doctrine-resolver branch 2 times, most recently from b75c376 to 9fa044e Compare December 19, 2021 13:53
@stof
Copy link
Member

stof commented Jun 7, 2022

I think the main reason why you see the EM being lazy in most cases is because DoctrineBundle makes the EM lazy to make it resettable (by resetting the proxy), not to lazy-load its dependency graph.

@nicolas-grekas
Copy link
Member

DoctrineBundle makes the EM lazy to make it resettable (by resetting the proxy), not to lazy-load its dependency graph.

Indeed, that answers my concerns!

The conflict between resolvers will be handled by registering the tag with the right priority (like we do for all other argumentResolvers).

I'd like to see this approach before adding an option to opt-in.

I rebased the PR on your fork and submitted jderusse#3 on top.
After that patch, I'll be 👍 as is.

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve - other than fabbot.

In DoctrineBundle (where the wiring will live), the entire feature should be opt-in, right? I mean, it should require some sort of param_converter: true config in doctrine.yaml, which we could ship in the doctrine.yaml recipe. I think that's needed, otherwise I could imagine the auto-enabling of this feature could cause some edge-case weird situations.

}
}

private function getOptions(ArgumentMetadata $argument): MapEntity
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor - but getMapEntity() or getMapEntityAttribute() might be better - and $mapEntityAttribute instead of $options in the code. But this is purely for the enjoyment of me reading the code ;)

6.2
---

* Add `#[MapEntity]` with its corresponding `EntityArgumentResolver`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Add `#[MapEntity]` with its corresponding `EntityArgumentResolver`
* Add `#[MapEntity]` with its corresponding `EntityValueResolver`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in abfdc54

@dunglas
Copy link
Member

dunglas commented Jul 14, 2022

@weaverryan but when these edge cases appear, users can opt-out.

I prefer to have this kind of feature on by default, this helps making the framework easy to use for newcomers and to make the catchy features more discoverable. This also allow to not bloat the "default" config generated by Flex.

For instance, I would like to enable auto-validation by default. Sure there are some known edge cases, but they are easy to fix by disabling the feature for an entity or a property (require some googling but that's all). On the other hand, with the current situation (not enabled by default), only advanced users leverage this feature while it mostly targets newcomers who except (rightly imho) to not have to duplicate similar metadata (ORM, validation, PHPDoc...).

Bundles should be opiniated but configurable, enabling by default features with a high DX value like this one is a huge one for newcomers and for the simplicity of use of the framework.

@chalasr
Copy link
Member

chalasr commented Jul 14, 2022

I’d at least make it explicitly opt-in when FrameworkExtraBundle is installed to prevent any conflicting situations or ambiguity

@derrabus
Copy link
Member

I prefer to have this kind of feature on by default

I agree, the question is where this "on by default" happens. I'd prefer it to happen in the recipe which would make it consistent with other magic behavior like autowiring. And we would also make the "off switch" discoverable.

@dunglas
Copy link
Member

dunglas commented Jul 14, 2022

The verbose config that we generate per default just to enable these features increase the perceived complexity of Symfony. Take a look at the default services.yaml file, it can be a bit scary and discouraging for newcomers just starting a new project.

IMHO the DX is better is it just works with as few generated config as possible by default, but you can tweak every features by reading the documentation.

jderusse and others added 2 commits July 20, 2022 19:10
Co-authored-by: Jérémy Derussé <jeremy@derusse.com>
@fabpot
Copy link
Member

fabpot commented Jul 20, 2022

Thank you @jderusse.

@janklan
Copy link

janklan commented Aug 2, 2022

I know this comment is coming rather late and possibly a bit off-topic, but I'm wondering if the converting behaviour I described in #47166 is a bug or a feature and may be worth addressing during the transition from SensioFrameworkExtraBundle to the new resolver?

@nicolas-grekas
Copy link
Member

I opened doctrine/DoctrineBundle#1554 to wire this into doctrine-bundle.

@jderusse jderusse deleted the doctrine-resolver branch October 12, 2022 15:20
@fabpot fabpot mentioned this pull request Oct 24, 2022
jasperweyne added a commit to jasperweyne/helpless-kiwi that referenced this pull request Nov 23, 2022
This reverts commit d92865d. This is
necessary per symfony/symfony#40333, since
LocalAccount is both a Doctrine entity and the CurrentUser class, which
is a won'tfix for the FrameworkExtraBundle. With Symfony 6.2, this will
be fixed by the EntityArgumentResolver
(symfony/symfony#43854). Until then, let's stick
to what we have.
@Nugjii

This comment was marked as off-topic.

@ruudk

This comment was marked as off-topic.

@symfony symfony locked as resolved and limited conversation to collaborators Dec 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.