Может кто-нибудь поможет мне с автонастройкой в 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 }
Я плохо понимаю @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 }




Спасибо, проблема решена с использованием полного имени класса, как предложил 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 знает, как его ввести. Следовательно, он добавляет для него второе определение службы, хотя оно не будет помечено. У вашего слушателя голосования есть аргумент, который не может быть подключен автоматически. Следовательно, это не удается.
Если вы действительно хотите понять, добавьте VoteManagerInterface в документацию и измените своего слушателя на подписчика. После этого запись в services.yaml не потребуется. Как ни странно ваш слушатель уже является подписчиком. Раздел тегов вам вообще не понадобится.
Замените app.listener.vote полным именем класса. Автоматическая часть autowire пытается автоматически подключить ваш слушатель, потому что ни одна служба с классом в качестве ключа не завершается.