symfony 符号2/理论:使用Gedmo的条令扩展时阅读“删除”数据

zfciruhq  于 2023-03-09  发布在  其他
关注(0)|答案(4)|浏览(119)

我正在构建一个Symfony2项目,使用gedmo/doctrine-extensionsGitHub)来实现软删除,我的问题是是否有一种方法可以"禁用"或"覆盖"软删除,甚至检测是否有东西被软删除。
情况是这样的:
我有一个引用了"user"实体的"note"实体。一个特定的note引用了一个已经被软删除的用户。即使用户已经被删除,它也会为TWIG的"is defined"逻辑返回true,甚至可以返回被删除用户的id。但是,如果我查询任何其他信息(包括标记它是否已被删除的"deletedAt"参数),我会得到500 "Entity was not found"错误。
由于数据实际上仍然存在,并且由于注解本身没有被删除,所以我仍然想知道是谁写的注解,即使用户已经被删除。
这可能吗?如果不可能,我如何正确地检测一些东西是否已经被软删除?就像我说的,$note->getUser()仍然检索一个对象,并对任何null/" is defined "比较返回true。

yhived7q

yhived7q1#

您可以通过以下方式实现此目的:

$filter = $em->getFilters()->enable('soft-deleteable');
$filter->disableForEntity('Entity\User');
$filter->enableForEntity('Entity\Note');
aor9mmx1

aor9mmx12#

您需要将关系加载设置为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链接时,它看起来是这样的:

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="answers", fetch="EAGER")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $user;

在这种情况下,User实体可以有多个answers。当从answer透视图加载一个User时,将执行以下操作:

foreach($answers as $answer) {
    $user = $answer->getUser();

    if (!$user) {
        continue;
    }
}
0vvn1miw

0vvn1miw3#

您可以暂时禁用软删除,以便在结果中返回已删除的项目。See the documentation,您特别感兴趣的部分如下:
这将禁用SoftDeleteable过滤器,因此被“软删除”的实体将出现在结果中$em-〉getFilters()-〉disable('soft-deleteable');
因此,首先在Entity Manager $em上运行上面的代码,然后使用它收集$note

ne5o7dgx

ne5o7dgx4#

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

$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')]
);

这是通用的helper函数,只需将其作为Utility类放在某处即可

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\EntityManagerInterface;

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

相关问题