Symfony2 / Doctrine:使用Gedmo的Doctrine扩展时读取"deleted"数据



我正在构建一个Symfony2项目,并使用gedmo/doctrine-extensions(GitHub)来实现软删除。我的问题是是否有办法"禁用"或"覆盖"软删除,甚至检测某些内容是否已软删除。

情况如下:

我有一个引用"用户"实体的"注释"实体。特定注释引用已软删除的用户。即使用户已被删除,它也会为TWIG的"已定义"逻辑返回true,甚至可以返回已删除用户的id。但是,如果我查询任何其他信息(包括标记它是否已被删除的"deletedAt"参数),我会收到 500"找不到实体"错误。

由于

数据实际上仍然存在,并且由于注释本身尚未被删除,因此即使用户已被删除,我仍然想说是谁写了注释。

这可能吗?如果没有,如何正确检测某些内容是否已被软删除?就像我说的,$note->getUser()仍然检索一个对象,并为任何空值/"已定义"比较返回 true。

你可以通过以下方式做到这一点:

$filter = $em->getFilters()->enable('soft-deleteable');
$filter->disableForEntity('EntityUser');
$filter->enableForEntity('EntityNote');
您需要

将关系加载设置为 eager ,这将防止仅使用id而没有其他对象的延迟加载。

您可以在此处找到有关预先加载及其注释的更多信息:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#by-eager-loading

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html。

至于我的代码,这就是现在定义指向User的链接时的样子:

/**
 * @ORMManyToOne(targetEntity="User", inversedBy="answers", fetch="EAGER")
 * @ORMJoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

在这种情况下,User实体可以有多个answers。从answer角度加载User时,这将起作用:

foreach($answers as $answer) {
    $user = $answer->getUser();
    if (!$user) {
        continue;
    }
}

可以暂时禁用软删除,以便在结果中返回已删除的项目。 请参阅文档,您特别感兴趣的是以下部分:

这将禁用软删除筛选器,因此 "软删除"将显示在结果中 $em->getFilters()->disable('soft-deleteable');

因此,首先在您的实体管理器$em上运行上面的代码,然后使用它来收集您的$note

我为此做了一个辅助函数,所以我唯一要写的是:

$softDeleted = GedmoSoftDeletableUtils::getSoftDeletedFor(
    MyClass:class, // the class for the soft-deleted items
    $em, // Pass an EntityManager
    // Optionally pass some extra Criteria if you want:
    [Criteria::expr()->eq('someExtraField', 'someValue')]
);

这是通用的辅助函数,只需将其作为实用程序类放在某个地方即可

use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCriteria;
use DoctrineORMEntityManagerInterface;
class GedmoSoftDeletableUtils
{    
    public static function getSoftDeletedFor(
        string $class,
        EntityManagerInterface $em,
        ?array $extraExpressions = []
    ): ArrayCollection {
        // First disable the soft-deleted filter for this entity
        $em->getFilters()->getFilter('softdeleteable')->disableForEntity($class);
        // The base criteria for getting the soft-deleted elements
        $criteria = (new Criteria())->andWhere(Criteria::expr()->neq('deletedAt', null));
        foreach ($extraExpressions as $expression) {
            $criteria->andWhere($expression);
        }
        // Trigger the LazyCriteriaCollection with toArray() before enabling the "softDeletableFilter" again
        $result = new ArrayCollection(
            $em->getRepository($class)->matching($criteria)->toArray()
        );
        // Enable the soft-deleted filter again for this entity
        $em->getFilters()->getFilter('softdeleteable')->enableForEntity($class);
        return $result;
    }
}

最新更新