Home » Php » php – Symfony 2.0 getting service inside entity

php – Symfony 2.0 getting service inside entity

Posted by: admin April 23, 2020 Leave a comment

Questions:

Im seraching over and cannot find answer.
I have database role model in my application. User can have a role but this role must be stored into database.

But then user needs to have default role added from database. So i created a service:

<?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));
    }

}

my services.yml is:

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

And now I want to use it in two places:
UserController and User entity. How can i get them inside entity?
As for controller i think i just need to:

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

But how to get service inside entity?

How to&Answers:

You don’t. This is a very common question. Entities should only know about other entities and not about the entity manager or other high level services. It can be a bit of a challenge to make the transition to this way of developing but it’s usually worth it.

What you want to do is to load the role when you load the user. Typically you will end up with a UserProvider which does this sort of thing. Have you read through the sections on security? That should be your starting point:

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

Answer:

While it’s very discouraged to get services into entities, there is a nice way to do it that does not involve messing with the global kernel.

Doctrine entities have lifeCycle events which you can hook an event listener to, see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events For the sake of the example, I’ll use postLoad, which triggers soon after the Entity is created.

EventListeners can be made as services which you inject other services into.

Add to app/config/config.yml:

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

Add to your Entity:

 use Alef\UserBundle\Service\RoleService;

 private $roleService;

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

And add the new 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);
         }
     }
}