Doctrine orm 如何禁用symfony中条令的软删除(软删除)筛选器

Doctrine orm 如何禁用symfony中条令的软删除(软删除)筛选器,doctrine-orm,symfony,soft-delete,Doctrine Orm,Symfony,Soft Delete,为条令2安装和使用SoftDeleteable行为扩展非常简单。问题通常是试图对某些代码部分禁用它,然后再次启用。您可能希望这样做: 加载软删除的实体 完全绕过软删除筛选器从数据库中删除实体 那么如何禁用它呢?1。如何加载软删除实体 根据文档,禁用实体管理器的过滤器: $em->getFilters()->disable('softdeleteable'); $object = $em->find('AppBundle:Object', 1); // soft-deleted

为条令2安装和使用SoftDeleteable行为扩展非常简单。问题通常是试图对某些代码部分禁用它,然后再次启用。您可能希望这样做:

  • 加载软删除的实体
  • 完全绕过软删除筛选器从数据库中删除实体
  • 那么如何禁用它呢?

    1。如何加载软删除实体 根据文档,禁用实体管理器的过滤器:

    $em->getFilters()->disable('softdeleteable');
    $object = $em->find('AppBundle:Object', 1); // soft-deleted entity will be loaded
    
    要再次启用软删除,请执行以下操作:

    $em->getFilters()->enable('softdeleteable');
    
    注意:
    $em->clear()

    2.如何从数据库中完全删除实体 即使文档中没有提到,但如果需要删除实体并绕过软删除过滤器,第一个解决方案也不起作用。需要从实体管理器的事件侦听器中删除筛选器:

    // initiate an array for the removed listeners
    $originalEventListeners = [];
    
    // cycle through all registered event listeners
    foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
        foreach ($listeners as $listener) {
            if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
    
                // store the event listener, that gets removed
                $originalEventListeners[$eventName] = $listener;
    
                // remove the SoftDeletableSubscriber event listener
                $em->getEventManager()->removeEventListener($eventName, $listener);
            }
        }
    }
    
    // remove the entity
    $em->remove($object);
    $em->flush($object); // or $em->flush();
    
    // re-add the removed listener back to the event-manager
    foreach ($originalEventListeners as $eventName => $listener) {
        $em->getEventManager()->addEventListener($eventName, $listener);
    }
    
    参考资料:


    您可以使用服务禁用并重新启用软删除筛选器行为:

    <?php
    
    namespace App\Util;
    
    use Doctrine\ORM\EntityManagerInterface;
    use Gedmo\SoftDeleteable\SoftDeleteableListener;
    
    class SoftDeleteFilter
    {
        /**
         * @var string
         */
        const EVENT_NAME = 'onFlush';
    
        /**
         * @var object
         */
        private $originalEventListener;
    
        /**
         * @param EntityManagerInterface $em
         */
        public function removeSoftDeleteFilter(EntityManagerInterface $em)
        {
            foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
                foreach ($listeners as $listener) {
                    if ($listener instanceof SoftDeleteableListener) {
                        if ($eventName === self::EVENT_NAME) {
                            $this->originalEventListener = $listener;
                            $em->getEventManager()->removeEventListener($eventName, $listener);
                        }
                    }
                }
            }
        }
    
        /**
         * @param EntityManagerInterface $em
         */
        public function undoRemoveSoftDeleteFilter(EntityManagerInterface $em)
        {
            if (empty($this->originalEventListener)) {
                throw new \Exception('can not undo remove, soft delete listener was not removed');
            }
            // re-add the removed listener back to the event-manager
            $em->getEventManager()->addEventListener(self::EVENT_NAME, $this->originalEventListener);
        }
    }
    
    正如在by posted中所述:一个简单有效的解决方案是:

    // Remove an entity entirely from the DB (skip soft delete)
    $this->entityManager->remove($entity);
    $this->entityManager->flush();
    // Just run it a second time :-)
    $this->entityManager->remove($entity);
    $this->entityManager->flush();
    

    只是再次发布它,让它更具可视性,因为它的工作方式就像一个魔咒…

    只是一个小小的提醒

    当您想要使用Gedmo Softdeletable硬删除实体时,必须在相应的注释中设置
    hardDelete=true
    ,请参见:

    @Gedmo\softdeletable(fieldName=“deletedAt”,timeAware=false,hardDelete=true)

    编辑:
    hardDelete=true
    默认为true

    这样,您就不必禁用侦听器/过滤器。如果您有
    hardDelete=false
    ,则上述建议的双重删除将不起作用

    资料来源:


    过滤器只是一个条令查询,因此它与冲洗过程没有真正的联系。硬删除的一个简单得多的方法是运行
    $em->remove($object)$em->flush($object)两次。第一次刷新将
    deletedAt
    设置为现在。第二个将识别先前已设置的
    deletedAt
    ,并将忽略您在此处看到的实际delete-ass。@Qoopmao我用最新的标记(2.4.13)尝试了此操作,但无效。也许现在只有在branch大师的帮助下,你的方法才能很好地发挥作用。我想你应该把它作为一个答案,因为我第一次忽略了它。奥雷利库斯的回答很有启发性,但根本没有必要。我用v2.5.5尝试过它。如果它不起作用,请尝试“软删除”而不是“软删除”。所以应该是:
    $em->getFilters()->disable('soft-deletable')但是默认情况下,
    硬删除
    是正确的。您是对的,重要信息。谢谢你提醒我。
    // Remove an entity entirely from the DB (skip soft delete)
    $this->entityManager->remove($entity);
    $this->entityManager->flush();
    // Just run it a second time :-)
    $this->entityManager->remove($entity);
    $this->entityManager->flush();