I setup a listener class where i'll set the ownerid column on any doctrine prePersist. My services.yml file looks like this ...
services:
my.listener:
class: App\SharedBundle\Listener\EntityListener
arguments: ["@security.context"]
tags:
- { name: doctrine.event_listener, event: prePersist }
and my class looks like this ...
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\SecurityContextInterface;
class EntityListener
{
protected $securityContext;
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
/**
*
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$entityManager = $args->getEntityManager();
$entity->setCreatedby();
}
}
The result of this is the following error.
ServiceCircularReferenceException: Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> my.listener -> security.context -> security.authentication.manager -> fos_user.user_manager".
My assumption is that the security context has already been injected somewhere in the chain but I don't know how to access it. Any ideas?
I use the doctrine config files to set
preUpdate
orprePersist
methods:And the methods are declared in the entity, this way you don't need a listener and if you need a more general method you can make a BaseEntity to keep that method and extend the other entites from that. Hope it helps!
I had similar problems and the only workaround was to pass the whole container in the constructor (
arguments: ['@service_container']
).There's a great answer already in this thread but everything changes. Now there're entity listeners classes in Doctrine: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#entity-listeners-class
So you can add an annotation to your entity like:
And create a class like this:
Also you should define this listener in
services.yml
like that:As of Symfony 2.6 this issue should be fixed. A pull request has just been accepted into the master. Your problem is described in here. https://github.com/symfony/symfony/pull/11690
As of Symfony 2.6, you can inject the
security.token_storage
into your listener. This service will contain the token as used by theSecurityContext
in <=2.5. In 3.0 this service will replace theSecurityContext::getToken()
altogether. You can see a basic change list here: http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements#deprecated-the-security-context-serviceExample usage in 2.6:
Your configuration:
Your Listener
For a nice created_by example, you can use https://github.com/hostnet/entity-blamable-component/blob/master/src/Listener/BlamableListener.php for inspiration. It uses the hostnet/entity-tracker-component which provides a special event that is fired when an entity is changed during your request. There's also a bundle to configure this in Symfony2