使用侦听器计算 Symfony2 中的缓存

Count cache in Symfony2 with a listener

我正在用 Symfony2 构建一个博客,它有两个实体:BlogBlogComment(这是一个简化的示例)。 BlogBlogComment 具有 OneToMany 关系。当发布 BlogComment 时,属性 published 设置为 false。管理员批准 BlogComment 后,设置为 true.

我想创建一个包含我所有 Blog 帖子的概览,并在两个单独的字段中显示 BlogComment 的数量,即 published = truepublished = false。可以将所有 BlogComment 放在一个循环中并计数,但由于它可能是 Blog 的一个非常大的概述-帖子这不是我的首选。

我在 Blog 创建了两个属性:published_comments_countunpublished_comments_count。为了更新这些字段,我创建了一个 BlogComment:

的监听​​器
class BlogCommentListener
{
    public function onFlush(OnFlushEventArgs $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        $entities = array_merge(
            $uow->getScheduledEntityInsertions(),
            $uow->getScheduledEntityUpdates(),
            $uow->getScheduledEntityDeletions()
        );

        foreach($entities as $entity){
            if($entity instanceof BlogComment){
                $Blog = $entity->getBlog();

                $published_comments_count = 0;
                $unpublished_comments_count = 0;

                foreach($Blog->getComments() as $BlogComment){
                    if($BlogComment->getPublished()){
                        $published_comments_count++;
                    } else {
                        $unpublished_comments_count++;
                    }
                }

                $Blog->setPublishedCommentsCount($published_comments_count);
                $Blog->setUnpublishedCommentsCount($unpublished_comments_count);

                $em->persist($Blog);

                $md = $em->getClassMetadata(get_class($Blog));
                $uow->recomputeSingleEntityChangeSet($md, $Blog);
            }
        }
    }
}

它工作得很好,但是当我添加一个新评论时,它还不在 $Blog->getComments() 的 ArrayCollection 中。有没有办法计算这个 ArrayCollection 中的变化?

我认为无法计算 arrayCollection 中的更改,但您可以通过为每个实体添加或删除 1 来更改逻辑:

class BlogCommentListener
{
    public function onFlush(OnFlushEventArgs $args)
    {
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        $insertions = $uow->getScheduledEntityInsertions();
        $deletions = $uow->getScheduledEntityDeletions();

        foreach($insertions as $entity){
            if($entity instanceof BlogComment){
                $Blog = $entity->getBlog();

                $Blog->setUnpublishedCommentsCount($Blog->getUnpublishedCommentsCount()+1);//Here the comment inserted must be unpublished

                $em->persist($Blog);

                $md = $em->getClassMetadata(get_class($Blog));
                $uow->recomputeSingleEntityChangeSet($md, $Blog);
            }
        }
    }
    foreach($deletions as $entity){
        if($entity instanceof BlogComment) {
            $Blog = $entity->getBlog();

            if ($entity->getPublished()) {

                $Blog->setPublishedCommentsCount($Blog->getPublishedCommentsCount()-1);//Here the comment inserted must be unpublished
            } else {
                 $Blog->setUnpublishedCommentsCount($Blog->getUnpublishedCommentsCount()-1);
            }                
            $em->persist($Blog);

            $md = $em->getClassMetadata(get_class($Blog));
            $uow->recomputeSingleEntityChangeSet($md, $Blog);
        }
    }
}

另外,我会为您提供一个更简单的解决方案:在您的树枝模板中使用计数过滤器:

{% for blog in blogs %}
    <li><h4>blog.title</h4>
    <p>comments published : {{ blog.comments.published|count }}</p>
    <p>comments non-published : {{ (not blog.comments.published)|count }}</p>
{% endfor %}