web-dev-qa-db-fra.com

Comment accéder aux méthodes de référentiel pour une entité dans symfony2?

Je suis coincé avec un problème s'il vous plaît aidez-moi avec elle. Voici le scenarario:

J'ai une entité "Utilisateur" et le référentiel correspondant "UserRepository". Dans mon entité, il n'y a que des méthodes de lecture et de définition. Toutes les requêtes personnalisées que j'ai écrites sur UserRepository. Maintenant, dans mon UserController, j'essaie d'accéder à des méthodes de référentiel auxquelles je ne suis pas capable de le faire .. Entité utilisateur:

class User
{
    ...

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        return $this->id=$id;
    }
    public function setProperty($property)
    {
        $this->property = $property;
    }


    public function getProperty()
    {
        return $this->property;
    }

    ....

    }
  ?>

UserRepository:

class UserRepository extends EntityRepository
{


    public function findUsersListingById($id)
    {
        $queryBuilder = $this->getEntityManager()->createQueryBuilder();

       $query = $em->createQuery(
                    "SELECT U
                    FROM  UserEntityPathGoesHere
                    WHERE U.id IN (".implode(",", $id).")"
                );

        $users = $query->getResult();

        return $users;
    }

    public function sayHelloWorld(){

        echo ' Hello World';
    }

}
?>

UserController

class UserController
{
 ...


$users=$this->getDoctrine()
        ->getRepository('MyUserEntityPath')
        ->findUsersListingById($ids);

    //now I have multiple users I want to iterate through each user for associating additional data with each user

     foreach($users as $user)
     {
        $temp = array();

        //I am able to access getId method which is  defined in User entity
        $temp['id'] = $user->getId();

        //however I am not able to  access method from UserRepository, I tried something like below which gives me error  call to undefined function sayHelloWorld
        $temp['status'] = $user->sayHelloWorld();

       ....

     }


}

....

Comment puis-je accéder aux méthodes de référentiel pour une entité? C'est possible ? Si non, alors quelles sont les alternatives pour la solution?

11
Rahul

Tout est possible Cependant vous ne devriez pas accéder au référentiel de l'entité à partir de l'entité elle-même en raison de la séparation des problèmes.

Voir cette réponse Stackoverflow pour plus de détails .

En gros, l’idée principale est que vous souhaitiez organiser votre application de la manière suivante.

En bref: 

Contrôleur > Référentiel > Entités.

Cela ne devrait pas aller dans l'autre sens, sinon cela créerait un désordre.

Si vous voulez aller un peu plus loin dans la séparation des préoccupations, vous pouvez procéder comme suit.

Contrôleur > Service > Référentiel > Entités

Solutions alternatives:

  • Créez une extension Twig qui accède à un service (qui accède à un référentiel) ou à un référentiel.
  • Créez une méthode dans votre référentiel, appelez-la dans votre contrôleur, mappez les données aux ID (les clés du tableau sont les ID), passez le tableau au modèle, puis extrayez les données du tableau à l'aide des ID d'entité.
  • Créez une méthode dans votre référentiel, appelez-la dans votre contrôleur, injectez les données dans vos entités et accédez aux données via l'entité de votre modèle.

Il y en a probablement d'autres, mais vous saurez mieux comment votre application est organisée.

19
Thomas Potaire

Vous devez déclarer la UserRepository en tant que EntityRepository pour votre entité utilisateur. Dans votre entité User, ajoutez cette annotation:

/**
 * @ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\UserRepository")
 */

Voir la documentation pour une description plus détaillée.

1
ferdynator

Si le paquet est Acme/DemoBundle, alors on pourrait s’attendre à un minimum

Entité utilisateur

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;


/**
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Acme/DemoBundle/Entity/UserRepository")
 */
class User 
{
...
}

Référentiel d'utilisateurs

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;

class UserRepository extends EntityRepository
{
...
}   

Il est également vrai qu'avec un tableau d'identifiants, on peut également effectuer les opérations suivantes dans un contrôleur:

...
$em = $this->getDoctrine()->getManager();
$users = $em->getRepository("AcmeDemoBundle:User")->findAllById($idArray);
...

Pour parcourir les utilisateurs d'un contrôleur, on peut alors utiliser une boucle foreach comme dans:

foreach ($users as $user) {
//each user is an array
...
$id = $user['id'];
...
}

ou dans un modèle:

{% for user in users %}
...
{{ user.firstName }}
...
{% endfor %}
1
geoB

Vous pouvez utiliser l'événement postLoad de doctrine et injecter tout ce que vous voulez dans l'entité. L'écouteur d'événement ressemble à ceci:

    <?php
namespace AppBundle\EventListener;


use AppBundle\Entity\MyEntity;
use Doctrine\ORM\Event\LifecycleEventArgs;

/**
 * Class MyEntityListener
 */
class MyEntityListener
{

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        /** @var MyEntity $document */
        $document = $eventArgs->getEntity();
        if(!($document instanceof MyEntity)){
            return;
        }
        $document->setEntityManager($eventArgs->getEntityManager());

    }
}

et service.yml:

services:
app.myentity.listener:
  class: AppBundle\EventListener\MyEntityListener
  tags:
    - { name: doctrine.event_listener, event: postLoad }

Bien entendu, votre entité a besoin de la méthode setEntityManager et vous êtes prêt.

0
Rawburner