andanteproject / 软删除包
一个用于处理 Doctrine 实体软删除的 Symfony 包
Requires
- php: ^7.4 || ^8.0
- doctrine/common: ^2.13 || ^3.0
- doctrine/event-manager: ^1.0
- symfony/framework-bundle: ^4.4 | ^5.0 | ^6.0
Requires (Dev)
- ext-json: *
- doctrine/doctrine-bundle: ^2.2
- doctrine/orm: ^2.6.3
- friendsofphp/php-cs-fixer: ^3.4
- phpspec/prophecy: ^1.15
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.2
- phpstan/phpstan-phpunit: ^1.0
- phpstan/phpstan-symfony: ^1.0
- phpunit/phpunit: ^9.5
- roave/security-advisories: dev-master
- symfony/yaml: ^4.0 | ^5.0 | ^6.0
This package is auto-updated.
Last update: 2024-09-11 19:31:25 UTC
README
软删除包
Symfony 包 - AndanteProject
一个简单的 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团队用爱💖构建。