I am using Gedmo Loggable to keep track of changes that users make to entities. The username is not stored by default for each change, but it is necessary to provide it to the listener.
An example of this, is found in the documentation of Loggable:
$loggableListener = new Gedmo\Loggable\LoggableListener;
$loggableListener->setAnnotationReader($cachedAnnotationReader);
$loggableListener->setUsername('admin');
$evm->addEventSubscriber($loggableListener);
This does not work for me for two reasons:
- I am registering the listener in services.yml, not in a controller
- I do not wish to store a pre-known username like in the example but the username of the user that is logged in
The method setUsername of the loggableListener either expects a string or an object with a method getUsername that provides a string.
How can I pass either one to the listener? I found a way to pass the security_token but this is not sufficient. What I currently have is this:
(...)
gedmo.listener.loggable:
class: Gedmo\Loggable\LoggableListener
tags:
- { name: doctrine.event_subscriber, connection: default }
calls:
- [ setAnnotationReader, [ "@annotation_reader" ] ]
#- [ setUsername, [ "A fixed value works" ] ]
- [ setUserValue, [ @security.??? ] ]
I am also using Blameable and found a nice workaround for a similar problem (the entire listener is overriden). I tried to do the same for Loggable, but this appears to be a bit more complex.
Main question: how can I pass the security user object (or its username) to a listener in services.yml?
Update
Matteo showed me how to pass the result of a function as a parameter to a listener. This almost solves the problem. There is another service, that provides the username when given the token_storage. But this means that I need to pass a parameter, to a service, that is given as a parameter to another service. This example will explain:
- [ setUsername, [ "@=service('gedmo.listener.blameable').getUsername( @security.token_storage )" ] ]
The problem now is, that @security.token_storage is not accepted in this context. How can I pass a parameter to the method getUsername() ?
You can use the Symfony Service Expressions, as example you can try the following:
But in some case the user can be
null
, so you can a condition with?
(see the doc).Hope this help