FriendsOfSymfony / FOSCommentBundle

Threaded comments for Symfony
http://friendsofsymfony.github.com/
MIT License
462 stars 230 forks source link

How to differentiate from triggered events if a comment is being created, updated or deleted? #588

Closed victorbstan closed 7 years ago

victorbstan commented 7 years ago

I'm hooking into the COMMENT_POST_PERSIST event, but this event fires for new, updated, or deleted comments. How can I detect what state a message is at in an event, or hook into an event based on these 3 states of a message? I have noticed that comments have a state attribute, which is 0 for new messages, 0 for updated messages and 1 for deleted messages... not sure if this is a coincidence or if it truly is part of some message status flag.

XWB commented 7 years ago

Inject the CommentManager and use the isNewComment method.

https://github.com/FriendsOfSymfony/FOSCommentBundle/blob/master/Entity/CommentManager.php#L151

victorbstan commented 7 years ago

I'm using your recommended method inside of the comment post persist, however, new comments isNewComment returns false for newly posted comments.

This is my service.yml entry:

tes_comments.comment_created_listener:
      class: XXX\Bundle\CommentBundle\EventListener\CommentCreatedListener
      arguments: ['@security.token_storage', '@logger', '@tes_user.client_manager', '@fos_comment.manager.comment']
      tags:
        - { name: 'kernel.event_listener', event: 'fos_comment.comment.post_persist', method: 'onCommentPostPersist' }

I'm debugging and I see this method seems to return false when the comment is new:

public function isNewComment(CommentInterface $comment)
    {
        return !$this->em->getUnitOfWork()->isInIdentityMap($comment);
    }

My CommentCreateListener.php code is like this:

/**
 * Listener responsible to send email notifications when a comment is persisted
 */
class CommentCreatedListener implements EventSubscriberInterface
{

    const QUEUE_URL = "XXX";

    /**
     * @var TokenStorageInterface
     */
    protected $tokenStorage;
    /**
     * @var CommentController
     */
    protected $userRelationshipManager;

    public function __construct(
        TokenStorageInterface $tokenStorage,
        Logger $logger,
        ClientManager $clientManager,
        CommentManager $commentManager
    ) {
        $this->tokenStorage = $tokenStorage;
        $this->logger = $logger;
        $this->clientManager = $clientManager;
        $this->commentManager = $commentManager;
    }

    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            Events::COMMENT_POST_PERSIST => 'onCommentPostPersist',
        );
    }

    public function onCommentPostPersist(CommentEvent $event, $eventName, \Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher $dispatcher)
    {
        $comment = $event->getComment();
        $thread = $comment->getThread();
        $author = $comment->getAuthor();

        // Return if comment is not new
        if ($this->commentManager->isNewComment($comment) == false) {
            return;
        }
...

New comment posts return false when they are expected to return true, at least in my case here.

PS.

composer.lock using:

"name": "friendsofsymfony/comment-bundle",
            "version": "dev-master",
XWB commented 7 years ago

You will need to use the COMMENT_PRE_PERSIST event. The isNewComment method can only return true when a comment has no id. Once you persist a new comment, it will have a id.

victorbstan commented 7 years ago

Thanks, ultimately, I needed some extra information about the creator of the comment, which isn't available by default in the PRE_PERSIST event, but got around this by adding a updated_at column to comments, and checking the diff between the created_at and updated_at dates to verify new, vs edited comments. Wondering if it wouldn't have been nice if an updated_at column existed by default, as I personally think that's a nice thing to have on any DB row that can be updated.

XWB commented 7 years ago

:+1: