@@ -598,61 +598,21 @@ the :ref:`doctrine-queries` section.
598598 see the web debug toolbar, install the ``profiler `` :ref: `Symfony pack <symfony-packs >`
599599 by running this command: ``composer require --dev symfony/profiler-pack ``.
600600
601+ .. _doctrine-entity-value-resolver :
602+
601603Automatically Fetching Objects (EntityValueResolver)
602604----------------------------------------------------
603605
604- In many cases, you can use the `EntityValueResolver `_ to do the query for you
605- automatically! First, enable the feature:
606-
607- .. configuration-block ::
608-
609- .. code-block :: yaml
610-
611- # config/packages/doctrine.yaml
612- doctrine :
613- orm :
614- controller_resolver :
615- enabled : true
616- auto_mapping : true
617- evict_cache : false
618-
619- .. code-block :: xml
620-
621- <!-- config/packages/doctrine.xml -->
622- <?xml version =" 1.0" encoding =" UTF-8" ?>
623- <container xmlns =" http://symfony.com/schema/dic/services"
624- xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
625- xmlns : doctrine =" http://symfony.com/schema/dic/doctrine"
626- xsi : schemaLocation =" http://symfony.com/schema/dic/services
627- https://symfony.com/schema/dic/services/services-1.0.xsd
628- http://symfony.com/schema/dic/doctrine
629- https://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd" >
630-
631- <doctrine : config >
632- <!-- by convention the env var names are always uppercase -->
633- <doctrine : orm >
634- <doctrine : controller_resolver auto_mapping =" true" evict_cache =" false" />
635- </doctrine : orm >
636- </doctrine : config >
637-
638- </container >
639-
640- .. code-block :: php
606+ .. versionadded :: 6.2
641607
642- // config/packages/doctrine.php
643- use Symfony\Config\DoctrineConfig;
608+ Entity Value Resolver was introduced in Symfony 6.2.
644609
645- return static function (DoctrineConfig $doctrine) {
646- $controllerResolver = $doctrine->orm()
647- ->entityManager('default')
648- // ...
649- ->controllerResolver();
610+ .. versionadded :: 2.7.1
650611
651- $controllerResolver->autoMapping(true);
652- $controllerResolver->evictCache(true);
653- };
612+ Autowiring of the ``EntityValueResolver `` was introduced in DoctrineBundle 2.7.1.
654613
655- Now, simplify your controller::
614+ In many cases, you can use the ``EntityValueResolver `` to do the query for you
615+ automatically! You can simplify the controller to::
656616
657617 // src/Controller/ProductController.php
658618 namespace App\Controller;
@@ -676,15 +636,17 @@ Now, simplify your controller::
676636That's it! The bundle uses the ``{id} `` from the route to query for the ``Product ``
677637by the ``id `` column. If it's not found, a 404 page is generated.
678638
679- This behavior can be enabled on all your controllers, by setting the ``auto_mapping ``
680- parameter to ``true ``. Or individually on the desired controllers by using the
681- ``MapEntity `` attribute:
639+ This behavior is enabled by default on all your controllers. You can
640+ disable it by setting the ``doctrine.orm.controller_resolver.auto_mapping ``
641+ config option to ``false ``.
642+
643+ When disabled, you can enable it individually on the desired controllers by
644+ using the ``MapEntity `` attribute::
682645
683646 // src/Controller/ProductController.php
684647 namespace App\Controller;
685648
686649 use App\Entity\Product;
687- use App\R epository\P roductRepository;
688650 use Symfony\Bridge\Doctrine\Attribute\MapEntity;
689651 use Symfony\Component\HttpFoundation\Response;
690652 use Symfony\Component\Routing\Annotation\Route;
@@ -702,31 +664,41 @@ parameter to ``true``. Or individually on the desired controllers by using the
702664 }
703665 }
704666
667+ .. tip ::
668+
669+ When enabled globally, it's possible to disabled the behavior on a specific
670+ controller, by using the ``MapEntity `` set to ``disabled ``.
671+
672+ public function show(
673+ #[CurrentUser]
674+ #[MapEntity(disabled: true)]
675+ User $user
676+ ): Response {
677+ // User is not resolved by the EntityValueResolver
678+ // ...
679+ }
680+
705681Fetch Automatically
706682~~~~~~~~~~~~~~~~~~~
707683
708684If your route wildcards match properties on your entity, then the resolver
709- will automatically fetch them:
710-
711- .. configuration-block ::
712-
713- .. code-block :: php-attributes
685+ will automatically fetch them::
714686
715- /**
716- * Fetch via primary key because {id} is in the route.
717- */
718- #[Route('/product/{id}')]
719- public function showByPk(Post $post): Response
720- {
721- }
687+ /**
688+ * Fetch via primary key because {id} is in the route.
689+ */
690+ #[Route('/product/{id}')]
691+ public function showByPk(Post $post): Response
692+ {
693+ }
722694
723- /**
724- * Perform a findOneBy() where the slug property matches {slug}.
725- */
726- #[Route('/product/{slug}')]
727- public function showBySlug(Post $post): Response
728- {
729- }
695+ /**
696+ * Perform a findOneBy() where the slug property matches {slug}.
697+ */
698+ #[Route('/product/{slug}')]
699+ public function showBySlug(Post $post): Response
700+ {
701+ }
730702
731703Automatic fetching works in these situations:
732704
@@ -743,145 +715,99 @@ attribute and using the `MapEntity options`_.
743715Fetch via an Expression
744716~~~~~~~~~~~~~~~~~~~~~~~
745717
746- If automatic fetching doesn't work, use an expression:
747-
748- .. configuration-block ::
749-
750- .. code-block :: php-attributes
718+ If automatic fetching doesn't work, you can write an expression using the
719+ :doc: `ExpressionLanguage component </components/expression_language >`::
751720
752- use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
753-
754- #[Route('/product/{product_id}')]
755- public function show(
756- #[MapEntity(expr: 'repository.find(product_id)')]
757- Product $product
758- ): Response {
759- }
760-
761- Use the special ``MapEntity `` attribute with an ``expr `` option to
762- fetch the object by calling a method on your repository. The
763- ``repository `` method will be your entity's Repository class and
764- any route wildcards - like ``{product_id} `` are available as variables.
765-
766- This can also be used to help resolve multiple arguments:
721+ #[Route('/product/{product_id}')]
722+ public function show(
723+ #[MapEntity(expr: 'repository.find(product_id)')]
724+ Product $product
725+ ): Response {
726+ }
767727
768- .. configuration-block ::
728+ In the expression, the ``repository `` variable will be your entity's
729+ Repository class and any route wildcards - like ``{product_id} `` are
730+ available as variables.
769731
770- .. code-block :: php-attributes
732+ This can also be used to help resolve multiple arguments::
771733
772- #[Route('/product/{id}/comments/{comment_id}')]
773- public function show(
774- Product $product
775- #[MapEntity(expr: 'repository.find(comment_id)')]
776- Comment $comment
777- ): Response {
778- }
734+ #[Route('/product/{id}/comments/{comment_id}')]
735+ public function show(
736+ Product $product
737+ #[MapEntity(expr: 'repository.find(comment_id)')]
738+ Comment $comment
739+ ): Response {
740+ }
779741
780- In the example above, the ``$product `` argument is handled automatically,
742+ In the example above, the ``$product `` argument is handled automatically,
781743but ``$comment `` is configured with the attribute since they cannot both follow
782744the default convention.
783745
784- .. _`MapEntity options` :
785-
786-
787746MapEntity Options
788747~~~~~~~~~~~~~~~~~
789748
790- A number of `` options `` are available on the ``MapEntity `` annotation to
749+ A number of options are available on the ``MapEntity `` annotation to
791750control behavior:
792751
793- * ``id ``: If an ``id `` option is configured and matches a route parameter, then
794- the resolver will find by the primary key:
795-
796- .. configuration-block ::
797-
798- .. code-block :: php-attributes
799-
800- #[Route('/product/{product_id}')]
801- public function show(
802- Product $product
803- #[MapEntity(id: 'product_id')]
804- Comment $comment
805- ): Response {
806- }
807-
808- * ``mapping ``: Configures the properties and values to use with the ``findOneBy() ``
809- method: the key is the route placeholder name and the value is the Doctrine
810- property name:
811-
812- .. configuration-block ::
813-
814- .. code-block :: php-attributes
815-
816- #[Route('/product/{category}/{slug}/comments/{comment_slug}')]
817- public function show(
818- #[MapEntity(mapping: ['date' => 'date', 'slug' => 'slug'])]
819- Product $product
820- #[MapEntity(mapping: ['comment_slug' => 'slug'])]
821- Comment $comment
822- ): Response {
823- }
824-
825- * ``exclude `` Configures the properties that should be used in the ``findOneBy() ``
826- method by *excluding * one or more properties so that not *all * are used:
827-
828- .. configuration-block ::
829-
830- .. code-block :: php-attributes
831-
832- #[Route('/product/{slug}/{date}')]
833- public function show(
834- #[MapEntity(exclude: ['date'])]
835- Product $product
836- \DateTime $date
837- ): Response {
838- }
839-
840- * ``stripNull `` If true, then when ``findOneBy() `` is used, any values that
841- are ``null `` will not be used for the query.
842-
843- * ``entityManager `` By default, the ``EntityValueResolver `` uses the *default *
844- entity manager, but you can configure this:
752+ ``id ``
753+ If an ``id `` option is configured and matches a route parameter, then
754+ the resolver will find by the primary key::
845755
846- .. configuration-block ::
756+ #[Route('/product/{product_id}')]
757+ public function show(
758+ Product $product
759+ #[MapEntity(id: 'product_id')]
760+ Comment $comment
761+ ): Response {
762+ }
847763
848- .. code-block :: php-attributes
764+ ``mapping ``
765+ Configures the properties and values to use with the ``findOneBy() ``
766+ method: the key is the route placeholder name and the value is the Doctrine
767+ property name::
849768
850- #[Route('/product/{id}')]
851- public function show(
852- #[MapEntity(entityManager: ['foo'])]
853- Product $product
854- ): Response {
855- }
769+ #[Route('/product/{category}/{slug}/comments/{comment_slug}')]
770+ public function show(
771+ #[MapEntity(mapping: ['date' => 'date', 'slug' => 'slug'])]
772+ Product $product
773+ #[MapEntity(mapping: ['comment_slug' => 'slug'])]
774+ Comment $comment
775+ ): Response {
776+ }
856777
857- * ``evictCache `` If true, forces Doctrine to always fetch the entity from the
858- database instead of cache.
778+ ``exclude ``
779+ Configures the properties that should be used in the ``findOneBy() ``
780+ method by *excluding * one or more properties so that not *all * are used:
859781
860- * ``disabled `` If true, the ``EntityValueResolver `` will not try to replace
861- the argument.
782+ #[Route('/product/{slug}/{date}')]
783+ public function show(
784+ #[MapEntity(exclude: ['date'])]
785+ Product $product
786+ \D ateTime $date
787+ ): Response {
788+ }
862789
863- .. tip ::
790+ ``stripNull ``
791+ If true, then when ``findOneBy() `` is used, any values that are
792+ ``null `` will not be used for the query.
864793
865- When enabled globally, it's possible to disabled the behavior on a specific
866- controller, by using the ``MapEntity `` set to ``disabled ``.
794+ ``entityManager ``
795+ By default, the ``EntityValueResolver `` uses the *default *
796+ entity manager, but you can configure this::
867797
798+ #[Route('/product/{id}')]
868799 public function show(
869- #[CurrentUser]
870- #[MapEntity(disabled: true)]
871- User $user
800+ #[MapEntity(entityManager: ['foo'])]
801+ Product $product
872802 ): Response {
873- // User is not resolved by the EntityValueResolver
874- // ...
875803 }
876804
877- .. versionadded :: 6.2
878-
879- Entity Value Resolver was introduced in Symfony 6.2.
880-
881- .. versionadded :: 2.7.1
805+ ``evictCache ``
806+ If true, forces Doctrine to always fetch the entity from the database
807+ instead of cache.
882808
883- Autowiring of the `` EntityValueResolver `` was introduced in DoctrineBundle
884- 2.7.1 .
809+ `` disabled ``
810+ If true, the `` EntityValueResolver `` will not try to replace the argument .
885811
886812Updating an Object
887813------------------
0 commit comments