Symfony 3.4 FOSCommentBundle не может автоматически подключать сервис внутри слушателя

Может кто-нибудь поможет мне с автонастройкой в ​​Symfony3.4?

Я пытаюсь реализовать следующий прослушиватель, но не знаю, как ввести VoteManagerInterface. Вот ошибка, мой код и мой конфиг. Спасибо за помощь :)

Не удается выполнить автоматическое подключение службы "AppBundle \ EventListener \ CommentVoteListener": аргумент "$ voteManager" метода "__construct ()" ссылается на интерфейс "FOS \ CommentBundle \ Model \ VoteManagerInterface", но такой службы не существует. Возможно, вам следует присвоить этому интерфейсу псевдоним одной из существующих служб: «fos_comment.manager.vote.default», «fos_comment.manager.vote.acl».

    <?php

namespace AppBundle\EventListener;

use FOS\CommentBundle\Event\VotePersistEvent;
use FOS\CommentBundle\Events;
use FOS\CommentBundle\Model\VoteManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Description of CommentVoteListener
 *
 */
class CommentVoteListener implements EventSubscriberInterface {

    private $voteManager;
    private $token_storage;

    public function __construct(VoteManagerInterface $voteManager, TokenStorageInterface $token_storage) {
        $this->voteManager = $voteManager;
        $this->token_storage = $token_storage;
    }

    /**
     * Assumptions:
     *  1) User is logged in (caught by FOSCB acl)
     *  2) VoteBlamerListener has already run which assigned the voter (this event has priority of -1)
     *
     * Make sure the user has not already voted, and make sure that the user is not the author.
     *
     * @param VotePersistEvent $event
     * @return void
     */
    public function onVotePrePersist(VotePersistEvent $event) {
        $vote = $event->getVote();
        $user = $this->token_storage->getToken()->getUser();

        // make sure user is not the author
        if ($vote->getComment()->getAuthor() === $user) {
            $this->stopPersistence($event);
        }

        // make sure user hasn't already voted
        $existingVote = $this->voteManager->findVoteBy(array('comment' => $vote->getComment(), 'voter' => $user));
        if (null !== $existingVote && $vote->getValue() === $existingVote->getValue()) {
            $this->stopPersistence($event);
        }
    }

    protected function stopPersistence(VotePersistEvent $event) {
        $event->abortPersistence();
        $event->stopPropagation();
    }

    public static function getSubscribedEvents() {
        return array(
            Events::VOTE_PRE_PERSIST => array('onVotePrePersist', -1),
        );
    }
}

}

app.listener.vote:
    class: AppBundle\EventListener\CommentVoteListener
    arguments:
        - "@fos_comment.manager.vote.acl"
        - "@security.token_storage"
    tags:
    - { name: kernel.event_listener, event: fos_comment.vote.pre_persist, method: onVotePrePersist }

или же

app.listener.vote:
    class: AppBundle\EventListener\CommentVoteListener
    arguments: ["@fos_comment.manager.vote.acl", "@security.token_storage"]
    tags:
    - { name: kernel.event_listener, event: fos_comment.vote.pre_persist, method: onVotePrePersist }

Замените app.listener.vote полным именем класса. Автоматическая часть autowire пытается автоматически подключить ваш слушатель, потому что ни одна служба с классом в качестве ключа не завершается.

Cerad 12.06.2018 00:08

Я плохо понимаю @Cerad. У меня такая же структура с другим слушателем для Thread Pre Persist, и он хорошо работает, вот он: app.listener.thread:class: AppBundle\EventListener\PostThreadListenerarguments:- "@security.token_storage"tags:- { name: kernel.event_listener, event: fos_comment.thread.pre_persist, method: onThreadPrePersist }

theWM 12.06.2018 06:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
2
325
1

Ответы 1

Спасибо, проблема решена с использованием полного имени класса, как предложил Cerad. Даже если мне интересно, почему это сработало для случая app.listener.thread :)

AppBundle\EventListener\CommentVoteListener:
    arguments:
        - "@fos_comment.manager.vote.acl"
        - "@security.token_storage"
    tags:
    - { name: kernel.event_listener, event: fos_comment.vote.pre_persist, method: onVotePrePersist }

Частью процесса autowire является сканирование всех классов в вашем каталоге src и попытка создания определений служб. Процесс начинается с поиска имени класса в services.yaml и, если он найден, с использованием вашего ручного определения. Если имя класса не найдено, то autowire берет на себя. У слушателя вашей цепочки сообщений в качестве аргумента есть только токен безопасности, и autowire знает, как его ввести. Следовательно, он добавляет для него второе определение службы, хотя оно не будет помечено. У вашего слушателя голосования есть аргумент, который не может быть подключен автоматически. Следовательно, это не удается.

Cerad 12.06.2018 13:43

Если вы действительно хотите понять, добавьте VoteManagerInterface в документацию и измените своего слушателя на подписчика. После этого запись в services.yaml не потребуется. Как ни странно ваш слушатель уже является подписчиком. Раздел тегов вам вообще не понадобится.

Cerad 12.06.2018 13:46

Другие вопросы по теме