SoftDeletable
«М'яке» видалення: remove() не видаляє рядок, а ставить час видалення в deletedAt.
Сутність
use Doctrine\ORM\Mapping as ORM;
use Ufo\DoctrineBehaviors\Contract\Entity\SoftDeletableInterface;
use Ufo\DoctrineBehaviors\Model\SoftDeletable\SoftDeletableTrait;
#[ORM\Entity]
class Category implements SoftDeletableInterface
{
use SoftDeletableTrait;
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
private ?int $id = null;
}
Бандл мапить deletedAt (datetime, nullable).
Як це працює
У onFlush кожна сутність із SoftDeletableInterface, запланована до видалення, отримує delete() (поточний час у deletedAt) і зберігається знову — замість DELETE виконується UPDATE.
Фільтра запитів немає: find(), репозиторії й DQL повертають і «видалені» сутності. Відсіюйте їх самі — умовою deletedAt IS NULL або перевіркою isDeleted().
Каскадне видалення пов'язаних сутностей Doctrine виконує як завжди: «м'яко» видаляються лише ті, що теж реалізують SoftDeletableInterface.
Використання
$entityManager->remove($category);
$entityManager->flush();
$category = $categoryRepository->find($id); // сутність на місці
$category->isDeleted(); // true
Відновлення
$category->restore(); // deletedAt = null
$category->isDeleted(); // false
$entityManager->flush();
Видалення в заданий час
$category->setDeletedAt(new \DateTime('+1 day'));
$category->isDeleted(); // false — до настання дати
$category->willBeDeleted(); // true
$entityManager->flush();
| Метод | Що повертає |
|---|---|
isDeleted() |
true, якщо deletedAt задано і вже настав |
willBeDeleted(?DateTimeInterface $at = null) |
true, якщо deletedAt задано (і, якщо передано $at, не пізніше за нього) |
getDeletedAt() |
?DateTimeInterface |