0

Can somebody helps me with autowiring in Symfony3.4?

I'm trying to implement the following Listener, but i don't know to inject the VoteManagerInterface. Here's the error, my code and my config.Thank you for your help :)

Cannot autowire service "AppBundle\EventListener\CommentVoteListener": argument "$voteManager" of method "__construct()" references interface "FOS\CommentBundle\Model\VoteManagerInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "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 }

or

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 }
theWM
  • 23
  • 4
  • Replace app.listener.vote with the fully qualified class name. The auto part of autowire is trying to automatically wire your listener because no service with the class as a key exits. – Cerad Jun 11 '18 at 22:08
  • I don't understand well @Cerad. I have the same structure with another listener for a Thread Pre Persist and it works well, here's it: `app.listener.thread:` `class: AppBundle\EventListener\PostThreadListener` `arguments:` `- "@security.token_storage"` `tags:` `- { name: kernel.event_listener, event: fos_comment.thread.pre_persist, method: onThreadPrePersist }` – theWM Jun 12 '18 at 04:00

1 Answers1

0

Thank you, problem solved with the fully qualified class name like Cerad suggested. Even if I wonder why it worked for the app.listener.thread case :)

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 }
theWM
  • 23
  • 4
  • Part of the autowire process is scanning all the classes under your src directory and attempting to create service definitions. The process starts by looking up the class name in services.yaml and, if found, using your manual definition. If the class name is not found then autowire takes over. Your post thread listener only has the security token as an argument and autowire knows how to inject it. Hence it adds a second service definition for it though it won't be tagged. Your vote listener has an arg that cannot be autowired. Hence it fails. – Cerad Jun 12 '18 at 11:43
  • If you really want to understand then add a VoteManagerInterface per the docs and change your listener to a subscriber. After which, no services.yaml entry will be required. Oddly enough your listener is already a subscriber. You should not need the tag section at all. – Cerad Jun 12 '18 at 11:46