How to get the instance of Kernel in the Entity class in Symfony2
doctrine-orm, php, symfony
Solution
Needing the container/kernel in an entity is most of the time, wrong. An entity shouldn't be aware of any services. Why is that?
Basically, an entity is an object which represents a thing. An entity is mostly used in a relationnal database, but you can at any time use this entity for other matters (serialize it, instanciate it from an HTTP layer...). You want your entity to be unit-testable, this means you need to be able to instanciate your entity easily, without anything around, mostly, without any piece of business logic.
You should move your logic into another layer, the one that will instanciate your entity. For your use case, I think, the most easy way is to use a doctrine event.
services.yml
services:
acme_foo.bar_listener:
class: Acme\FooBundle\Bar\BarListener
arguments:
- @kernel
tags:
- { name: doctrine.event_listener, event: postLoad }
Acme\FooBundle\Bar\BarListener
use Symfony\Component\HttpKernel\KernelInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Acme\FooBundle\Entity\Bar;
class BarListener
{
protected $kernel;
/**
* Constructor
*
* @param KernelInterface $kernel A kernel instance
*/
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
}
/**
* On Post Load
* This method will be trigerred once an entity gets loaded
*
* @param LifecycleEventArgs $args Doctrine event
*/
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!($entity instanceof Bar)) {
return;
}
$entity->setEnvironment($this->kernel->getEnvironment());
}
}
And there you go, your entity remains flat without dependencies, and you can easily unit test your event listener
Problem
The title explains the question pretty well. I am in the lifecycle callback of the Doctrine Entity class and want to do some extra DB entries. For this I need to get an instance of the Kernel. How can I do this?