Doctrine orm 如何禁用symfony中条令的软删除(软删除)筛选器
为条令2安装和使用SoftDeleteable行为扩展非常简单。问题通常是试图对某些代码部分禁用它,然后再次启用。您可能希望这样做: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
$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();