SoftDeletable

← SoftDeletable

Ashterix

docs: Doctrine section with Doctrine Behaviors and Doctrine Helper (uk + en)

uk/docs/doctrine/doctrine-behaviors/soft_deletable.md новий файл +65 −0

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