My question is about how to inject the entity manager in the SwitchUserListener that already has 9 parameters.
I have a custom switch user flow where I need to set the ExternalClient passed along with the _switch_user parameter (?_switch_user=user1&external_client_id=1) in the session. I first have to fetch the ExternalClient from the database before I can set it.
In parameters.yml I've added
security.authentication.switchuser_listener.class: App\Bundle\Listener\SwitchUserListener
And for the content of App\Bundle\Listener\SwitchUserListener I used the Symfony SwitchUserListener Symfony\Component\Security\Http\Firewall\SwitchUserListener.php
Everything works and when I fetch the external_client_id parameter from the request variable in the listener it is populated. But I can't seem to get access to the entity manager.
Things I've tried:
Add decorator in
services.ymlapp.decorating_switch_user: class: App\Bundle\Listener\SwitchUserListener decorates: security.authentication.switchuser_listener arguments: ['@app.decorating_switch_user.inner', '@doctrine.orm.entity_manager'] public: falseOverriding parent dependencies in
services.ymlsecurity.authentication.switchuser_listener: abstract: true test: class: "%security.authentication.switchuser_listener.class%" parent: security.authentication.switchuser_listener public: false # appends the '@doctrine.orm.entity_manager' argument to the parent # argument list arguments: ['@doctrine.orm.entity_manager']Listen to SwitchUserEvent insteadapp.switch_user_listener: class: App\Bundle\Listener\SwitchUserListener tags: - { name: kernel.event_listener, event: security.switch_user, method: onSwitchUser }Here I've replace the contents of 'App\Bundle\Listener\SwitchUserListener' with:
class SwitchUserListener { public function onSwitchUser(SwitchUserEvent $event) { $request = $event->getRequest(); echo "<pre>"; dump($externalClientId = $request->get('external_client_id')); echo "</pre>"; exit; } }I'm getting the external_client_id as well with this attempt but I have no idea how to inject the entity manager. And even If I did, I'd have no way of getting the original user that initiated the _switch_user request. SwitchUserEvent only has access to the
getTargetUser()method.
Conclusion:
If anybody has experience with this topic and is willing to share it that would be great. Ideally I would add the entity manager service to the previous 9 arguments of the __construct function. I'm expanding that class just like Matt is doing here: Symfony2: Making impersonating a user more friendly
You can override the service as follows. You may need to look up/change the concrete order of service arguments as it changed between symfony versions. Some arguments like
$providerKeycan be left empty as they will be changed/injected automatically by symfony.In order to save some time coding you won't need to override the constructor if you use setter injection.
A look at Symfony's default SwitchUserListener (switch to the tag/version used in your application) will help when implementing your new
handlemethod.Now your SwitchUserListener might look like this:
Don't forget to clear your cache!