andanteproject/软删除包

一个用于处理 Doctrine 实体软删除的 Symfony 包

安装量: 15 114

依赖者: 0

建议者: 0

安全性: 0

星标: 8

关注者: 3

分支: 2

开放问题: 0

类型:symfony-bundle

1.2.0 2021-12-13 14:16 UTC

This package is auto-updated.

Last update: 2024-09-11 19:31:25 UTC


README

Andante Project Logo

软删除包

Symfony 包 - AndanteProject

Latest Version Github actions Framework Php7 PhpStan

一个简单的 Symfony 包,用于处理 doctrine 实体的软删除。因此,你的实体“不会真的从数据库中删除”。🙌

需求

Symfony 4.x-5.x 和 PHP 7.4。

安装

通过 Composer

$ composer require andanteproject/soft-deletable-bundle

特性

  • 无需配置即可立即使用,但可完全自定义;
  • deleteAt 属性是 ?\DateTimeImmutable
  • 您可以禁用过滤器运行时,即使是针对某些实体;
  • 无需注解;
  • 如魔法般使用 ✨。

基本用法

安装后,确保您已将包注册到您的 symfony 包列表中(如果使用 Symfony Flex,则此操作应自动完成。否则,请自行注册。)

return [
    /// bundles...
    Andante\SoftDeletableBundle\AndanteSoftDeletableBundle::class => ['all' => true],
    /// bundles...
];

如果使用 Symfony Flex,则应已自动完成。否则,请自行注册。

假设我们有一个 App\Entity\Article doctrine 实体,我们希望启用其软删除功能。您需要做的就是实现 Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableInterface 并使用 Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableTrait 特性。

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableInterface;
use Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableTrait;

/**
 * @ORM\Entity()
 */
class Article implements SoftDeletableInterface // <-- implement this
{
    use SoftDeletableTrait; // <-- add this

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    /**
     * @ORM\Column(type="string")
     */
    private string $title;
    
    public function __construct(string $title)
    {
        $this->title = $title;
    }
    
    // ...
    // Some others beautiful properties and methods ...
    // ...
}

请确保根据您的 doctrine 工作流程更新您的数据库模式(如果你是坏蛋,使用 bin/console doctrine:schema:update --force;如果你选择成为更好的开发者,使用 迁移!)

您应该会看到一个名为 deleted_at(或基于您的 doctrine 命名策略 的类似名称)的新列。

恭喜!您已完成!🎉

从现在起,当您删除实体时,它不会从数据库中硬删除。例如,让我们保存一个新的 Article

$article = new Article('Free 🍕 for everyone!');
$entityManager->persist($article);
$entityManager->flush();

因此,它将出现在我们的数据库中。

但是,如果您使用 Doctrine 删除它,行仍然会存在,但 deleted_at 将填充删除日期。

$entityManager->remove($article);
$entityManager->flush();    

实体将不再在您的应用程序查询中可用。(我能否恢复它们?

$articleArrayWithNoFreePizza = $entityManager->getRepsitory(Article::class)->findAll();
//Every entity with a deleted_at date is going to be ignored from your queries

哎呀,你在对我可怜的实体做什么?! 🤭

在使用此包时,没有实体被虐待。🙌

我们建议您使用 Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableTrait 特性来简化您的生活。它并不在幕后做任何特殊的事情:它为您实体添加了一个映射到我们的 deleted_at doctrine 类型\DateTimeImmutable deletedAt 属性以及一个获取器/设置器来处理它。

但是,出于任何原因,您可以自由地进行操作(如果您不想这样做,则必须强制实现 SoftDeletableInterface)。

不使用特性使用

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Andante\SoftDeletableBundle\SoftDeletable\SoftDeletableInterface;

/**
 * @ORM\Entity()
 */
class Article implements SoftDeletableInterface // <-- implement this
{
    // No trait needed
    
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    /**
     * @ORM\Column(type="string")
     */
    private string $title;
    
    // DO NOT use ORM annotations to map this property. See bundle configuration section for more info 
    private ?\DateTimeImmutable $deletedAt = null; 
    
    public function __construct(string $title)
    {
        $this->title = $title;
    }
    
    public function getDeletedAt() : ?\DateTimeImmutable
    {
        return $this->deletedAt;
    }

    public function setDeletedAt(\DateTimeImmutable $deletedAt = null) : void
    {
        $this->deletedAt = $deletedAt;
    }
}

这允许您,例如,为您的属性使用不同的名称(例如,使用 deleted 而不是 deletedAt)。但您需要在此处明确指出(在 包配置 中)。

禁用软删除过滤器

您可以通过对实体管理器进行以下操作来完全在运行时禁用过滤器。

use Andante\SoftDeletableBundle\Doctrine\Filter\SoftDeletableFilter;
/** @var $entityManager \Doctrine\ORM\EntityManagerInterface */
$entityManager->getFilters()->disable(SoftDeletableFilter::NAME);
// From now on, entities with a "deletedAt" date are again available.
// If you want to enable the filter back:
$entityManager->getFilters()->enable(SoftDeletableFilter::NAME);

如果您愿意,也可以通过以下方式仅禁用一个或多个实体的过滤器

/** @var $softDeletableFilter Andante\SoftDeletableBundle\Doctrine\Filter\SoftDeletableFilter */
$softDeletableFilter = $entityManager->getFilters()->getFilter(SoftDeletableFilter::NAME);
$softDeletableFilter->disableForEntity(Article::class);
// From now on, filter is still on but disabled just for Articles
$softDeletableFilter->enableForEntity(Article::class);

配置(完全可选)

这个包的构建旨在节省您的时间,尽可能遵循最佳实践。

这意味着您甚至可以忽略在您的应用程序中拥有一个andante_soft_deletable.yaml配置文件。

然而,无论出于什么原因(遗留代码?),使用包配置来根据您的需求更改大多数行为。

andante_soft_deletable:
  deleted_date_aware: true # default: true
                           # Set the filter to also check deleted date value.
                           # If set true, Future date will still be avaiable 
  default:
    property_name: deletedAt # default: deletedAt
                             # The property to be used by default as deletedAt date 
                             # inside entities implementing SoftDeletableInterface
    
    column_name: deleted_at # default: null
                           # Column name to be used on database. 
                           # If set to NULL will use your default doctrine naming strategy
    table_index: false # default: true
                       # Adds automatically a table index to deleted date column
    
    always_update_deleted_at: true # default: false
                                   # if set to true, when you delete an entity which has already
                                   # a deleted date, the date will be updated to last deletion.
  entity: # You can use per-entity configuration to override default config
    Andante\SoftDeletableBundle\Tests\Fixtures\Entity\Organization:
      property_name: deletedAt
      table_index: true
    Andante\SoftDeletableBundle\Tests\Fixtures\Entity\Address:
      property_name: deleted
      column_name: delete_date
      table_index: false
      always_update_deleted_at: false

请注意

  • 此包不处理直接的DQL查询;
  • deleted_date_aware的默认设置为false。过滤器将排除任何带有NOT NULL删除日期的行。如果您只想排除带有过去日期的deletedAt日期的行,同时检索具有未来日期的行,则需要将deleted_date_aware设置为true

AndanteProject团队用爱💖构建。