evence/soft-deleteable-extension-bundle
Symfony bundle that extends Gedmo's SoftDeleteable listener, adding onSoftDelete annotations to entity associations. Supports CASCADE, SET NULL, and SUCCESSOR behaviors so references are handled cleanly when a parent is soft-deleted, avoiding Doctrine errors.
First-order finding: this is not a Laravel package. Before any roadmap discussion, a TPM needs to close the stack question, because it determines whether this item consumes engineering capacity at all. The package is a Symfony bundle (Evence\Bundle\SoftDeleteableExtensionBundle) extending Gedmo's Doctrine SoftDeleteable listener for the Doctrine ORM. There is no service provider, no Eloquent hook, no Laravel package manifest. The "Laravel/PHP package" framing in the intake is a categorisation error, and the correct TPM action is portfolio triage, not backlog grooming.
| Target stack | Fit | TPM disposition |
|---|---|---|
| Symfony + Doctrine ORM + Gedmo SoftDeleteable | Strong — closes a gap open since 2012 (Atlantic18/DoctrineExtensions#505) | Evaluate for adoption |
Laravel on laravel-doctrine/orm with Gedmo already load-bearing |
Conditional — feasible, but you inherit two nested third-party Doctrine layers | Only if Doctrine is already strategic |
| Laravel/Eloquent (the default assumption) | Poor — not applicable; Eloquent soft deletes already cover cascade/null/successor via model events | Reject from evaluation list |
What it buys the product. Gedmo soft-delete sets deletedAt instead of removing the row, which bypasses database ON DELETE semantics entirely. Associations then point at records that are logically gone, producing Doctrine EntityNotFoundException and proxy-hydration errors that surface as production incidents and inconsistent reporting. This bundle restores declarative referential actions at the ORM layer:
CASCADE → "deleting a shop archives its listings."SET NULL → "unlinking is not deleting" (child record preserved).SUCCESSOR → "reassign to the replacement record" (merges, plan migrations, ownership transfers).That third mode is the differentiator. It has no clean built-in equivalent, and it is the mode that retires hand-written one-off migration scripts — a recurring, unbudgeted engineering cost that a TPM can point to directly.
Integration feasibility. Low effort if the stack matches: Composer require, bundle registration, annotate the owning side of an association. No schema migration, no backfill, no new infrastructure. The real cost is verification, not implementation — the package's compatibility envelope (PHP version, Doctrine ORM 3, DBAL 4, Gedmo 3.x, attribute vs. annotation mapping) is not evidenced in the README.
Technical risk. Three concentrated areas, each with a TPM-visible consequence:
UnitOfWork behaviour across upgrades. Every Gedmo bump becomes a potential regression in our delete semantics — and delete paths are rarely well covered by tests.SUCCESSOR chains, bulk DQL deletes, and interaction with SoftDeleteableFilter are all places where "behaves like SQL ON DELETE" is an aspiration rather than a contract.Key questions to put to engineering before committing scope.
CASCADE and SUCCESSOR?preSoftDelete only, or also bulk DQL DELETE and programmatic remove()?ManyToOne only, or OneToOne / ManyToMany too?Stack fit is the gate, not a variable. Pursue only where Doctrine + Gedmo are already load-bearing. If a Laravel team is considering introducing Doctrine solely to gain this behaviour, reject: the correct Laravel answer is deleting/deleted model events or a service that enforces cascade semantics explicitly. Framing this correctly saves a TPM from sponsoring an architecture change disguised as a library adoption.
Migration path. Incremental, additive, and reversible — the strongest selling point for stakeholder conversations:
composer require → bundle registration → annotate one relation → characterise behaviour with tests → widen.Compatibility — fork-first. Given 0 dependents and a narrow maintainer base, the recommended posture is to vendor the source into the monorepo or hold a private fork under our own CI matrix. This converts an availability risk into a known, low-cost maintenance line and preserves the right to patch Doctrine/Gedmo compatibility ourselves. MIT permits this cleanly (attribute and preserve the notice — confirm with legal, but there should be no blocker).
Sequencing.
Sequencing rationale for stakeholders: steps 1–2 are timeboxed to under three engineer-days, which keeps the option value high and the downside bounded.
Maintenance. The dominant ongoing cost is not the package, it is the Gedmo compatibility surface. Budget a recurring, low-frequency task: on every Doctrine/Gedmo upgrade, re-run the delete-path test suite against the vendored copy. If we vendor, this becomes a normal internal dependency review; if we depend on Packagist, it becomes an unowned risk with no upstream SLA. Recommend vendoring, assigned to the owning team, reviewed at each major ORM bump.
Support. There is no vendor support, no SLA, and a single-maintainer profile. The TPM must name an internal owner before adoption — "the platform team will handle it" is not an owner. Escalation path is: patch our fork. That requires at least one engineer comfortable in Doctrine event listeners and UnitOfWork, which is a hiring/training consideration, not just a scheduling one.
Scaling. Watch three things as data volume grows: deep CASCADE trees (soft-deleting a high-fan-out parent can touch many rows in one request — a latency and lock-duration concern), SUCCESSOR chains during large account/plan migrations (verify idempotency and re-run safety), and bulk operations. Soft delete does not shrink tables; retention and purge jobs remain a separate, unaddressed obligation. Do not let "we do soft deletes" become a substitute for a retention policy.
Failure modes to monitor and test for.
onSoftDelete annotation reintroduces orphaned references with no compile-time warning. Mitigate with a convention check in CI or a code-review checklist item.CASCADE loops or SUCCESSOR cycles hanging or corrupting the delete path.ON DELETE mental model engineers assume, especially for bulk DQL.Ramp-up. Small API surface (three modes, one annotation) — a developer is productive in well under a day. The real ramp-up is conceptual: understanding Doctrine association ownership, Gedmo listener timing, and why soft delete breaks ON DELETE in the first place. Budget onboarding material as a short internal note covering the three modes, the cycle/transaction caveats, and the "annotate every owning association" rule. Support and QA also need the mental model — otherwise "the record still exists but is invisible" generates tickets that look like bugs.
Bottom line for the roadmap. Adopt where Symfony + Doctrine + Gedmo already hold; reject outright on Eloquent. Bound the exposure with a timeboxed spike, a fork-first posture, and a named internal owner. The value is not the 57-star library — it is the explicit, reviewable per-relationship retention policy that adopting it forces the team to write down.
How can I help you explore Laravel packages today?