2012-04-26 10 views
31

Im searing over y no puedo encontrar la respuesta. Tengo un modelo de función de base de datos en mi aplicación. El usuario puede tener un rol, pero este rol debe almacenarse en la base de datos.Servicio de obtención de Symfony 2.0 dentro de la entidad

Pero el usuario debe tener un rol predeterminado agregado desde la base de datos. Así que he creado un servicio:

<?php 

namespace Alef\UserBundle\Service; 

use Alef\UserBundle\Entity\Role; 

/** 
* Description of RoleService 
* 
* @author oracle 
*/ 
class RoleService { 

    const ENTITY_NAME = 'AlefUserBundle:Role'; 

    private $em; 

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

    public function findAll() 
    { 
     return $this->em->getRepository(self::ENTITY_NAME)->findAll(); 
    } 

    public function create(User $user) 
    { 
     // possibly validation here 

     $this->em->persist($user); 
     $this->em->flush($user); 
    } 

    public function addRole($name, $role) { 
     if (($newrole = findRoleByRole($role)) != null) 
      return $newrole; 
     if (($newrole = findRoleByName($name)) != null) 
      return $newrole; 

     //there is no existing role 
     $newrole = new Role(); 
     $newrole->setName($name); 
     $newrole->setRole($role); 

     $em->persist($newrole); 
     $em->flush(); 

     return $newrole; 
    } 

    public function getRoleByName($name) { 
     return $this->em->getRepository(self::ENTITY_NAME)->findBy(array('name' => $name)); 
    } 

    public function getRoleByRole($role) { 
     return $this->em->getRepository(self::ENTITY_NAME)->findBy(array('role' => $role)); 
    } 

} 

mi services.yml es:

alef.role_service: 
    class: Alef\UserBundle\Service\RoleService 
    arguments: [%doctrine.orm.entity_manager%] 

Y ahora quiero utilizarlo en dos lugares: UserController y User entidad. ¿Cómo puedo obtenerlos dentro de la entidad? En cuanto a controlador creo que sólo hay que:

$this->get('alef.role_service'); 

Pero Forma de obtener servicio dentro entidad?

Respuesta

41

No es así. Esta es una pregunta muy común. Las entidades solo deben conocer otras entidades y no sobre el administrador de la entidad u otros servicios de alto nivel. Puede ser un desafío hacer la transición a esta forma de desarrollo, pero por lo general vale la pena.

Lo que quiere hacer es cargar la función cuando carga al usuario. Normalmente terminará con un UserProvider que hace este tipo de cosas. ¿Has leído las secciones sobre seguridad? Eso debería ser su punto de partida:

http://symfony.com/doc/current/book/security.html

13

Si bien es muy desanimado para obtener servicios en entidades, hay es una buena manera de hacerlo que no implica jugar con el núcleo mundial.

Las entidades de doctrina tienen eventos lifeCycle a los que puede conectar un detector de eventos, consulte http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events Por el bien del ejemplo, usaré postload, que se activará poco después de que se cree la entidad.

EventListeners puede se pueden realizar como servicios en los que se inyectan otros servicios.

Agregar a app/config/config.yml:

services: 
    example.listener: 
      class: Alef\UserBundle\EventListener\ExampleListener 
    arguments: 
      - '@alef.role_service' 
    tags: 
      - { name: doctrine.event_listener, event: postLoad } 

Añadir a su Entidad:

use Alef\UserBundle\Service\RoleService; 

private $roleService; 

public function setRoleService(RoleService $roleService) { 
     $this->roleService = $roleService; 
} 

y añadir el nuevo EventListener:

namespace Alef\UserBundle\EventListener; 

use Doctrine\ORM\Event\LifecycleEventArgs; 
use Alef\UserBundle\Service\RoleService; 

class ExampleListener 
{ 
    private $roleService; 

    public function __construct(RoleService $roleService) { 
     $this->roleService = $roleService; 
    } 

    public function postLoad(LifecycleEventArgs $args) 
    { 
     $entity = $args->getEntity(); 
     if(method_exists($entity, 'setRoleService')) { 
      $entity->setRoleService($this->roleService); 
     } 
    } 
} 
+4

Esa es la mejor solución y la respuesta más precisa para la pregunta. Odio las respuestas como "no se puede", "es un patrón de diseño tan equivocado" o "¡Arruinará todo, idiota!" escrito por gurús de la nada. "Peor es (a veces) mejor";) Gracias de nuevo. –

+3

Tristemente, "patrón de diseño incorrecto", "modelo de MCV", "capa de negocios separada", etc. salen por la ventana cuando el "jefe" quiere que se haga "en este momento". Gracias por la respuesta @Kai, es lo que estaba buscando. –

Cuestiones relacionadas