Obtenir entityManager à l'intérieur d'une entité

je voudrais utiliser, quelque chose comme:

$em = $this->getEntityManager();

à l'Intérieur d'une Entité.

je comprends que je devrais faire ce que d'un service mais pour certains tests, je veux accéder à partir d'une Entité.

Est-il possible de réaliser cela?

j'ai essayé:

$em = $this->getEntityManager();
$profile_avatar = $em->getRepository('bundle:Perfils')->findOneByUser($this-getId());

Mais n'est-ce pas de travail.

Fatal error: appel à une méthode non définie ProxieswebBundleEntityUserProxy:: getEntityManager() dans / opt/lampp/htdocs/web/src/Pct/bundle/Entity / User.php sur la ligne de 449

pourquoi j'essaie de le faire de cette façon?

j'ai 3 types d'utilisateurs: Facebook, Twitter et les utilisateurs de MyOwnWebsite. Chacun d'eux a un avatar différent qui lie le profil facebook, twitter ou autre, si son utilisateur myownwebsite, je récupère l'avatar à partir d'une URL dans une base de données. Pour l'instant, je ne veux pas créer un service, parce que je suis juste essayer de le faire fonctionner, de le tester, pas de créer un déploiement final. C'est pourquoi j'essaie d'appeler le directeur D'entité d'une entité. Je ne veux pas, pour l'instant, modifier des fichiers de configuration, juste cette entité.

15
demandé sur Reinherd 2013-02-04 14:25:26

5 réponses

comme l'a souligné (encore) un commentateur, un gestionnaire d'entité à l'intérieur d'une entité est une odeur de code. Pour la situation spécifique de L'OP où il souhaitait acquérir le gestionnaire d'entité, avec le moins d'ennui, une simple injection de setter serait la plus fiable (contrairement à mon exemple original Injection via constructeur).

pour quiconque se retrouvant ici à la recherche d'une solution supérieure au même problème, il y a 2 façons d'y arriver ceci:

  1. mise en oeuvre de la ObjectManagerAware interface comme suggéré par https://stackoverflow.com/a/24766285/1349295

    use Doctrine\Common\Persistence\ObjectManagerAware;
    use Doctrine\Common\Persistence\ObjectManager;
    use Doctrine\Common\Persistence\Mapping\ClassMetadata;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     */
    class Entity implements ObjectManagerAware
    {
        public function injectObjectManager(
            ObjectManager $objectManager,
            ClassMetadata $classMetadata
        ) {
            $this->em = $objectManager;
        }
    }
    
  2. Ou, à l'aide de la @postLoad/@postPersist callbacks du cycle de vie et acquisition du gestionnaire d'entity en utilisant le LifecycleEventArgs argument comme suggéré par https://stackoverflow.com/a/23793897/1349295

    use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\HasLifecycleCallbacks()
     */
    class Entity
    {
        /**
         * @ORM\PostLoad
         * @ORM\PostPersist
         */
        public function fetchEntityManager(LifecycleEventArgs $args)
        {
            $this->setEntityManager($args->getEntityManager());
        }
    }
    

réponse originale

en utilisant un EntityManager à partir de l'intérieur d'un Entity est une très mauvaise pratique. Faire défait le but de découplage de la requête et à la persistance des opérations de l'entité elle-même.

Mais, si vous avez vraiment, vraiment, vraiment besoin d'un gestionnaire d'entité dans une entité et ne peut pas faire autrement, puis à l'injecter dans l'entité.

class Entity
{
    private $em;

    public function __contruct($em)
    {
        $this->em = $em;
    }
}

puis invoquer comme new Entity($em).

20
répondu Czar Pino 2017-05-23 11:46:28

Meilleur moyen est d'utiliser le Cycle de Vie: @ORM\HasLifecycleCallbacks

Et vous pouvez utiliser l'Événement que vous souhaitez obtenir de résultat:

@postLoad
@postPersist
...
5
répondu onalbi 2014-05-21 21:13:33

appeler le Gestionnaire D'entité de l'intérieur d'une entité est une mauvaise pratique! Vous devez garder vos entités aussi simples que possible.

dans quel but devez-vous appeler le Gestionnaire D'entité d'une entité?

3
répondu Ahmed Siouani 2013-02-04 10:29:22

ce que je pense que vous devriez faire est, au lieu d'utiliser le Gestionnaire D'Entity à l'intérieur de votre entity, de créer un dépôt personnalisé pour votre entity.

dans votre fichier ORM entity, ajoutez une entrée comme suit (ou dans vos annotations de classe entity si vous n'utilisez pas YML):

App\Bundle\Profils: 
# Replace the above as appropiate
    type: entity
    table: (your table)
    ....
    repositoryClass: App\Bundle\CustomRepos\ProfilsRepository
    # Replace the above as appropiate. 
    # I always put my custom repos in a common folder, 
    # such as CustomRepos

maintenant, créez une nouvelle classe PHP qui a l'espace de noms ci-dessus:

//Your ProfilsRepository.php
<?php
namespace App\Bundle\CustomRepos;

use Doctrine\ORM\EntityRepository;

class ProfilsRepository extends EntityRepository
{
    /**
     * Will return the user url avatar given the user ID
     * @param integer $userID The user id.
       @return string The avatar url
     */
    public function getUserProfile($userId)
    {
       $em = $this->getEntityManager();
       $qb = $em->createQueryBuilder();
       $qb->select... (your logic to retrieve the profil object);

       $query = $qb->getQuery();
       $result = $query->getResult();

       return $result;
    }
}

Enfin, dans votre Contrôleur:

// Your controller
<?php
   namespace <class namespace>;
   ...
   use App\Bundle\CustomRepos\ProfilsRepository;
   use Symfony\Bundle\FrameworkBundle\Controller\Controller;
   ...
   class YourClassNameController extends Controller
   {
      public function yourAction()
      {
         $userId = <get the user ID>;
         // Pass the name of your entity manager to the 
         // getManager function if you have more than one and
         // didn't define any default
         $em = $this->getDoctrine()->getManager();
         $repo = $em->getRepository('Profils');
         $avatar = $repo->getUserProfile($userId);
         ...

      }
   }
1
répondu Nicolas 2016-11-06 17:21:13

vous devez configurer les services.yml:

services:
    your_service_name:
        class: AppBundle\Controller\ServiceController
        arguments: [ @doctrine.orm.entity_manager ]

vous devez aussi définir le Controller avec le constructeur suivant:

public function __construct(\Doctrine\ORM\EntityManager $em)
{
    $this->em = $em;
}

et utiliser $this->em dans le controller (par exemple,$connection = $this->em->getConnection();)

0
répondu Fabien Thetis 2016-05-02 19:52:14