9

我正在使用DoctrineExtensionsStofDoctrineExtensionsBundle来获得可软删除的行为。

它在我的应用程序的前端工作得非常好。

在后端,我需要“硬”删除实体的选项。

我在我的管理控制器中禁用了过滤器(我使用 SonataAdmin):

$filters = $this->getModelManager()->getEntityManager($this->getClass())->getFilters();

if (array_key_exists('softdeleteable', $filters->getEnabledFilters())) {
    $filters->disable('softdeleteable');
}

这有效(软删除的实体出现在列表中),但是当我尝试删除它时,实体确实再次被软删除。如何强制“硬”删除?

4

4 回答 4

11

您不需要禁用过滤器 - 它仅用于过滤选择的记录。您必须改为禁用侦听器:

// $em is your EntityManager
foreach ($em->getEventManager()->getListeners() as $eventName => $listeners) {
    foreach ($listeners as $listener) {
        if ($listener instanceof \Gedmo\SoftDeleteable\SoftDeleteableListener) {
            $em->getEventManager()->removeEventListener($eventName, $listener);
        }
    }
}

然后打电话

$em->remove($entity);
$em->flush();
于 2013-01-25T16:27:00.460 回答
7

启用 softdeleteable 后,无需创建侦听器或任何要硬删除的东西。

原始的 softdeleteable 事件有这一行:

$reflProp = $meta->getReflectionProperty($config['fieldName']);
$oldValue = $reflProp->getValue($object);
if ($oldValue instanceof \Datetime) {
    continue; // want to hard delete
}

这一切意味着如果你:

$entity->setDeletedAt(new \Datetime());
$em->flush();

接着:

$em->remove($entity);
$em->flush();

届时,它将被硬删除。

如果您在 ->remove($entity) 之后调用 ->flush() 时在 deletedAt 字段中已经有一个有效日期,则您的实体将被硬删除

于 2017-01-12T13:38:28.263 回答
2

不是最优雅的方式:你总是可以用 SQL 进行真正的删除,它会绕过 softdeletable

$em->createQuery("DELETE MyEntity e WHERE e = :et")->setParameter('et',$entity)->execute();
于 2016-03-17T13:38:28.673 回答
0

虽然这个问题有点老,但它可能对某人有用:

创建自己的事件侦听器可能是更好的解决方案:

class SoftDeleteableListener extends BaseSoftDeleteableListener
{

/**
 * @inheritdoc
 */
public function onFlush(EventArgs $args)
{
    $ea = $this->getEventAdapter($args);
    $om = $ea->getObjectManager();
    //return from event listener if you disabled filter: $em->getFilters()->disable('softdeleteable');
    if (!$om->getFilters()->isEnabled('softdeleteable')) {
        return;
    }

    parent::onFlush($args);
}

}

并添加您的配置:

gedmo.listener.softdeleteable:
    class: AppBundle\EventListener\SoftDeleteableListener
    tags:
        - { name: doctrine.event_subscriber, connection: default }
    calls:
        - [ setAnnotationReader, [ @annotation_reader ] ]

来源:https ://github.com/Atlantic18/DoctrineExtensions/issues/1175

于 2016-02-01T16:32:44.293 回答