Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access to database in a listener in Symfony 2

We need to access to database info in a listener. We configure the listener in a service.yml The listener is like:

namespace company\MyBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class RequestListener
{
    protected $container;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}

public function onKernelRequest(GetResponseEvent $event)
{
...

How can we access to doctrine at onKernelRequest function?

I tried to extends from controller and do:

        $em = $this->getDoctrine()->getEntityManager(); 

and it works but I think this is a bad practice.

like image 499
Santi Avatar asked Jan 11 '12 17:01

Santi


4 Answers

You can just inject the service container. First change the constructor to get an EntityManager:

use Doctrine\ORM\EntityManager;

class RequestListener {
    protected $em;
    function __construct(EntityManager $em)
    {
        $this->em = $em;
    }
    //...
}

And next configure your service:

#...
services:
    foo.requestlistener:
        class: %foo.requestlistener.class%
        arguments:
            - @doctrine.orm.entity_manager
like image 123
solarc Avatar answered Oct 18 '22 22:10

solarc


If your use case allows you to use a Doctrine Event Listener directely

#services.yml
qis.listener.contractBundleStatusListener:
    class: Acme\AppBundle\EventListener\MyListener
    tags:
        - { name: doctrine.event_listener, event: postPersist }

you can get the Entity Manager from the LifecycleEventArgs:

<?php

use Doctrine\ORM\Event\LifecycleEventArgs;

class MyListener
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Foo) {
            $entityManager = $args->getEntityManager();

            $entityManager->persist($entity);
            $entityManager->flush();
        }
    }
}
like image 41
webDEVILopers Avatar answered Oct 19 '22 00:10

webDEVILopers


It seems like you're injecting the service container into the listener, so you can access Doctrine this way:

$doctrine = $this->container->get('doctrine');
like image 2
Alessandro Desantis Avatar answered Oct 18 '22 23:10

Alessandro Desantis


I'm kind of a novice at Symfony still, but have you tried passing the doctrine service to your listener instead of the service container?

Alternately, you are already passing the service container, so it should be as simple as calling
$this->container->get('doctrine'). Also, I was told in IRC some time ago that passing the service container is usually considered bad practice. It's better to pass the individual services that you need.

like image 1
simshaun Avatar answered Oct 18 '22 23:10

simshaun