Symfony внедряет EntityManager в SwitchUserListener - PullRequest
0 голосов
/ 07 ноября 2018

Мой вопрос о том, как внедрить менеджер сущностей в SwitchUserListener, у которого уже есть 9 параметров.

У меня есть пользовательский поток пользовательского коммутатора, где мне нужно установить ExternalClient, передаваемый вместе с параметром _switch_user (? _Switch_user = user1 & external_client_id = 1) в сеансе. Сначала мне нужно извлечь ExternalClient из базы данных, прежде чем я смогу его установить.

В settings.yml я добавил

security.authentication.switchuser_listener.class: App\Bundle\Listener\SwitchUserListener

А для содержимого App\Bundle\Listener\SwitchUserListener я использовал Symfony SwitchUserListener Symfony \ Component \ Security \ Http \ Firewall \ SwitchUserListener.php

Все работает, и когда я получаю параметр external_client_id из переменной запроса в слушателе, он заполняется. Но я не могу получить доступ к менеджеру сущностей.

Вещи, которые я пробовал:

  1. Добавить декоратор в services.yml

    app.decorating_switch_user:
      class:     App\Bundle\Listener\SwitchUserListener
      decorates: security.authentication.switchuser_listener
      arguments: ['@app.decorating_switch_user.inner', '@doctrine.orm.entity_manager']
      public:    false
    
  2. Переопределение родительских зависимостей в services.yml

    security.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']
    
  3. Вместо этого прослушивайте SwitchUserEvent

     app.switch_user_listener:
       class: App\Bundle\Listener\SwitchUserListener
       tags:
          - { name: kernel.event_listener, event: security.switch_user, method: onSwitchUser }
    

    Здесь я заменил содержимое 'App \ Bundle \ Listener \ SwitchUserListener' на:

    <code>class SwitchUserListener
    {
        public function onSwitchUser(SwitchUserEvent $event)
        {
            $request = $event->getRequest();
            echo "<pre>";
            dump($externalClientId = $request->get('external_client_id'));
            echo "
    "; выход; } }

    Я также получаю external_client_id с этой попыткой, но я не знаю, как внедрить менеджер сущностей. И даже если бы я это сделал, у меня не было бы способа получить первоначального пользователя, который инициировал запрос _switch_user. SwitchUserEvent имеет доступ только к методу getTargetUser().

Вывод:

Если кто-то имеет опыт в этой теме и готов поделиться им, это было бы здорово. В идеале я бы добавил службу менеджера сущностей к предыдущим 9 аргументам функции __construct. Я расширяю этот класс так же, как это делает Мэтт: Symfony2: сделать олицетворение пользователя более дружелюбным

1 Ответ

0 голосов
/ 07 ноября 2018

Вы можете переопределить услугу следующим образом. Вам может понадобиться посмотреть / изменить конкретный порядок служебных аргументов, так как он меняется между версиями Symfony. Некоторые аргументы, такие как $providerKey, можно оставить пустыми, так как они будут автоматически изменены / введены symfony.

Чтобы сэкономить некоторое время, вам не нужно переопределять конструктор, если вы используете установку сеттера.

Взгляд на значение по умолчанию Symfony SwitchUserListener (переключение на тег / версию, используемую в вашем приложении) поможет при реализации вашего нового метода handle.

# app/config/services.yml
services:
  # [..]
  security.authentication.switchuser_listener:
    class: 'Your\Namespace\SwitchUserListener'
    public: false
    abstract: true
    arguments: 
      - '@security.context'
      - ~
      - '@security.user_checker' 
      - ~
      - '@security.access.decision_manager' 
      - '@?logger' 
      - '_switch_user' 
      - ~
      - '@?event_dispatcher' 
      - ~
    calls:
      - [ 'setEntityManager', [ '@doctrine.orm.entity_manager' ]]
    tags:
      - { name: monolog.logger, channel: security }

Теперь ваш SwitchUserListener может выглядеть так:

namespace Your\Namespace;

use Symfony\Component\Security\Http\Firewall\SwitchUserListener as DefaultListener;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class SwitchUserListener extends DefaultListener
{
    /** @var EntityManagerInterface */
    protected $em;

    public function setEntityManager(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    /**
     * Handles the switch to another user.
     *
     * @throws \LogicException if switching to a user failed
     */
     public function handle(GetResponseEvent $event)
     {
          // Do your custom switching logic here
     }
}

Не забудьте очистить кеш!

...