如何在 symfony 中禁用 doctrine 的软删除(Soft-deleteable)过滤器
How to disable soft delete (Soft-deleteable) filter for doctrine in symfony
安装和使用 Doctrine 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);
}
参考文献:
- https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/softdeleteable.md
- Disable Soft Deleteable filter for hard delete record doesn't work
您可以使用服务来禁用和启用软删除过滤器行为:
<?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);
}
}
用法:
$this->softDeleteFilter->removeSoftDeleteFilter($this->entityManager);
$this->entityManager->remove($entity);
$this->entityManager->flush();
$this->softDeleteFilter->undoRemoveSoftDeleteFilter($this->entityManager);
如 by 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();
刚刚再次发布它以增加它的可见度,因为它像一个魅力...
一个小小的提醒。
当您想使用 Gedmo Softdeletable 硬删除实体时,您必须在相应的注释中包含 hardDelete=true
,请参阅:
@Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=true)
编辑:hardDelete=true
默认为真
有了这个,您不必禁用 listener/filter。如果您有 hardDelete=false
,上面建议的双重删除将不起作用。
来源:
安装和使用 Doctrine 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);
}
参考文献:
- https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/softdeleteable.md
- Disable Soft Deleteable filter for hard delete record doesn't work
您可以使用服务来禁用和启用软删除过滤器行为:
<?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);
}
}
用法:
$this->softDeleteFilter->removeSoftDeleteFilter($this->entityManager);
$this->entityManager->remove($entity);
$this->entityManager->flush();
$this->softDeleteFilter->undoRemoveSoftDeleteFilter($this->entityManager);
如
// 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\SoftDeleteable(fieldName="deletedAt", timeAware=false, hardDelete=true)
编辑:hardDelete=true
默认为真
有了这个,您不必禁用 listener/filter。如果您有 hardDelete=false
,上面建议的双重删除将不起作用。
来源: