1
votes

I currently have an error with a service since I updated to Symfony 3.4 from 3.0.

I have a SwitchUserListener which receives a couple of objects in its construct but it fails to receive the EntityManager even though i have it Type-Hinted. I also added a public key to my services

I get a FatalThrowableError because the class gets instantiated with a boolean instead of an EntityManager Object.

Error Message

Type error: Argument 10 passed to Dbm\UserBundle\Security\SwitchUserListener::__construct() must be an instance of Doctrine\ORM\EntityManager, boolean given, called in C:\wamp64\www\Portail\var\cache\dev\ContainerWyiblvw\getSecurity_Authentication_SwitchuserListener_MainService.php on line 8

FatalThrowableError Line

SwitchUserListener->__construct(object(TokenStorage), object(EmailUserProvider), object(UserChecker), 'main', object(TraceableAccessDecisionManager), object(Logger), '_switch_user', 'ROLE_ALLOWED_TO_SWITCH', object(TraceableEventDispatcher), false, object(AuthorizationChecker)) in var\cache\dev\ContainerWyiblvw\getSecurity_Authentication_SwitchuserListener_MainService.php

Here is what I have right now.

services.yml

services:
    _defaults:
        public: true
        autowire: true
        autoconfigure: true

    security.authentication.switchuser_listener:
        class: Dbm\UserBundle\Security\SwitchUserListener
        arguments:
            - '@security.token_storage'
            - ~
            - '@security.user_checker'
            - ~
            - '@security.access.decision_manager'
            - '@logger'
            - ''
            - ''
            - '@event_dispatcher'
            - '@doctrine.orm.entity_manager'
            - '@security.authorization_checker'
        tags:
            - { name: monolog.logger, channel: security }

SwitchUserListener.php

namespace Dbm\UserBundle\Security;
...
use Doctrine\ORM\EntityManager;

class SwitchUserListener implements ListenerInterface
{
    private $tokenStorage;
    private $provider;
    private $userChecker;
    private $providerKey;
    private $accessDecisionManager;
    private $usernameParameter;
    private $role;
    private $logger;
    private $dispatcher;
    private $em;
    private $authCheck;

    public function __construct(TokenStorageInterface $tokenStorage,
                                UserProviderInterface $provider,
                                UserCheckerInterface $userChecker,
                                $providerKey,
                                AccessDecisionManagerInterface $accessDecisionManager,
                                LoggerInterface $logger = null,
                                $usernameParameter = '_switch_user',
                                $role = 'ROLE_ALLOWED_TO_SWITCH',
                                EventDispatcherInterface $dispatcher = null,
                                EntityManager $em,
                                AuthorizationChecker $authCheck)
    {
        ...
    }
1
Have you cleared your cache?iiirxs
Yes, I deleted my Cache folder just to be sure.Phil
Maybe there is an issue in your yaml.iiirxs
Never seen that combination of service ids, tildes and blank strings before. Maybe try setting autowire to false. Typically with autowire you would only specify things like strings. It might be getting confused.Cerad
It didn't do anything. I tried all combinaison with public/autowire/autoconfigure and I always cleared the cache just to be sure... Nothing :(Phil

1 Answers

0
votes

EDIT

Finally found my error. I was overriding the switchuser_listener from "Symfony\Bundle\SecurityBundle\Resources\config\securityListeners.xml" with my own service and I guess the last args from their list (the 10th one hehe..heh...) which wasn't there before my updates, forced me to have it in my services.yml file too

security_listeners.xml

    <service id="security.authentication.switchuser_listener" class="Symfony\Component\Security\Http\Firewall\SwitchUserListener" abstract="true">
        <tag name="monolog.logger" channel="security" />
        <argument type="service" id="security.token_storage" />
        <argument /> <!-- User Provider -->
        <argument /> <!-- User Checker -->
        <argument /> <!--  Provider Key -->
        <argument type="service" id="security.access.decision_manager" />
        <argument type="service" id="logger" on-invalid="null" />
        <argument>_switch_user</argument>
        <argument>ROLE_ALLOWED_TO_SWITCH</argument>
        <argument type="service" id="event_dispatcher" on-invalid="null"/>
        <argument>false</argument> <!-- Stateless -->
    </service>

The text below is still valid, it is the right answer to the issue. But the reason why is in this edit.

END OF EDIT

I was somehow able to fix this weird issue by setting autowire to false AND I also added an extra parameter where the "false" was (10th args).

Only by doing so I was able to "Skip" the issue. It's a little dirty to do it like this. But it works.

The arguments sent by the dependencyInjection were just not correct. (At least, that's what I think)

This is a workaround, I will not mark it as answered so if anyone finds the actual answer to this I will mark it as the right answer

Here are the changes

services.yml I simply added an extra empty args at the 10th position

services:
    _defaults:
        public: true
        autowire: true
        autoconfigure: true

    security.authentication.switchuser_listener:
        class: Dbm\UserBundle\Security\SwitchUserListener
        autowire: false
        arguments: 
            - '@security.token_storage'
            - ~
            - '@security.user_checker'
            - ''
            - '@security.access.decision_manager'
            - '@logger'
            - ''
            - ''
            - '@event_dispatcher'
            - ''  
            - '@doctrine.orm.entity_manager'
            - '@security.authorization_checker'
        tags:
            - { name: monolog.logger, channel: security }

SwitchUserListener.php I simply added an extra param at the 10th position

public function __construct(TokenStorageInterface $tokenStorage,
                            UserProviderInterface $provider,
                            UserCheckerInterface $userChecker,
                            $providerKey,
                            AccessDecisionManagerInterface $accessDecisionManager,
                            LoggerInterface $logger = null,
                            $usernameParameter = '_switch_user',
                            $role = 'ROLE_ALLOWED_TO_SWITCH',
                            EventDispatcherInterface $dispatcher = null,
                            $buggyParam, //Not doing anything with this
                            EntityManagerInterface $em,
                            AuthorizationChecker $authCheck)
{