Skip to content

Deactivation

phil/doctrine-behaviours
TypeKindRole
Contract\DeactivatableinterfaceisActive(), deactivatedAt(), deactivate(), reactivate(), stampDeactivated()
DeactivatableEntitytraitThe columns active, boolean, and deactivated_at, datetime_immutable, nullable
DeactivationListenerlistener: prePersist, onFlushKeeps the date in step with the state, in UTC
DeactivatedFilterSQL filter phil_deactivatedactive = true on every Deactivatable entity

A deactivated record is switched off, not removed: its row stays whole, its relations stay, and it comes back with one call. Soft delete says a record is gone and a second removal deletes it; deactivation says nothing of the kind, and the two can be combined on one entity.

$member->deactivate();
$manager->flush();                                 // active = false, deactivated_at = now

$manager->getFilters()->disable(DeactivatedFilter::NAME);
$member = $members->find($id);
$member->reactivate();
$manager->flush();                                 // active = true, deactivated_at = null
Flushdeactivated_at
an entity switched offset to now, unless it was given a date
an entity switched back onforgotten
an entity persisted already offset to now, unless it was given a date

An import that keeps an original date calls stampDeactivated() itself, and the listener leaves it alone.

The filter hides deactivated rows from every query, lazily loaded collections included, while it is enabled. An administration screen disables it for its queries. A to-one relation to a deactivated row meets what a relation to a soft-deleted row meets: see Soft delete.

The filter compares the column with the database's own spelling of true: 1 on MySQL and SQLite, true on PostgreSQL.