如何在symfony中禁用doctrine的软删除(软删除)过滤器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在symfony中禁用doctrine的软删除(软删除)过滤器相关的知识,希望对你有一定的参考价值。

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

  1. 加载软删除的实体
  2. 完全绕过软删除过滤器从数据库中删除实体

那么如何禁用它呢?

答案

1. How to load soft-deleted entity

根据文档,禁用实体管理器的过滤器:

$em->getFilters()->disable('softdeleteable');
$object = $em->find('AppBundle:Object', 1); // soft-deleted entity will be loaded

要再次启用软删除:

$em->getFilters()->enable('softdeleteable');

注意:如果实体已加载了禁用的软删除过滤器,则此行之前可能需要$em->clear();

2. How to remove entity from database entirely

即使文档中没有提到,如果您需要删除实体并绕过软删除过滤器,第一个解决方案也不起作用。需要从实体管理器的事件侦听器中删除过滤器:

// 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 GedmoSoftDeleteableSoftDeleteableListener) {

            // 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 AppUtil;

use DoctrineORMEntityManagerInterface;
use GedmoSoftDeleteableSoftDeleteableListener;

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);
    }
}

用法:

$this->softDeleteFilter->removeSoftDeleteFilter($this->entityManager);
$this->entityManager->remove($entity);
$this->entityManager->flush();
$this->softDeleteFilter->undoRemoveSoftDeleteFilter($this->entityManager);
另一答案

正如在former comment发布的qooplmao中所说:一个简单而有效的解决方案是:

// 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();

只是再次发布它,让它更具可见性,因为它像一个魅力......

以上是关于如何在symfony中禁用doctrine的软删除(软删除)过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Symfony 中添加 Doctrine 过滤器?

Symfony Doctrine 关系 - 删除反面的实体

Symfony2 / Doctrine2:不要在模式上删除全文索引:更新

Symfony 和 Doctrine 使迁移无效

Doctrine symfony使用OneToMany删除实体 - ManyToOne关系

Symfony 2 - Doctrine 2 - Native Sql - 删除查询