gedmo/doctrine-extensions
Doctrine Behavioral Extensions adds powerful behaviors to Doctrine ORM and MongoDB ODM, including Sluggable, Timestampable, Blameable, Loggable, and Translatable, easily attached via Doctrine's event system.
Architecture fit. Gedmo is not a Laravel package; it is a Doctrine ORM/ODM extension library that hooks into Doctrine's event system (prePersist, onFlush, postFlush, loadClassMetadata) to implement behavioral patterns declaratively via attributes. Laravel's default persistence layer is Eloquent, so there is an architectural mismatch out of the box: this package is only usable if the application (or a bounded context within it) is already running Doctrine via a bridge such as laravel-doctrine/orm. That bridge is community-maintained and trails Laravel/Doctrine major releases, which is the single largest adoption risk.
Where it fits well: teams already on Doctrine, or greenfield services where domain modeling depth justifies Doctrine over Eloquent. The behavior set (Sluggable, Timestampable, Blameable, SoftDeleteable, Tree, Translatable, Loggable, Sortable, Uploadable) is a mature, well-scoped answer to common data-modeling chores that Eloquent solves with ad-hoc traits or third-party packages of varying quality.
Integration feasibility. Technically straightforward if Doctrine is present: register the relevant listeners as subscribers in a service provider, attach the entity manager, and annotate entities with #[Gedmo\...] attributes. No Laravel service provider ships in the package — the README points to a Laravel doc page, but the wiring is our code. Rough effort for a spike: 3–5 engineer-days for a Doctrine-enabled skeleton plus one behavior (Timestampable + Sluggable) validated end-to-end against our DB and test harness.
Release review (v3.22.2). Patch release; no new features, no API changes, no deprecations, no migration required. Four fixes, two of which materially touch risks already on our register:
doctrine/persistence >= 4.0 and doctrine/event-manager >= 2.1. This is forward-compatibility work, and it is the first concrete signal in the package that persistence 4.0 is being actively targeted. It modestly reduces our version-matrix risk for SoftDeleteable specifically, but it also confirms persistence 4.0 is close enough to require a budgeted upgrade rather than an opportunistic one. It tells us nothing about whether the other eight extensions are ready for persistence 4.0 — assume they lag until proven otherwise, and pin.TreeObjectHydrator compatible with ORM 3 when the parent property is declared before children in the entity (#3041). Reinforces the point that ORM 3 readiness is landing incrementally, extension by extension; our compatibility gate must be per-extension, not per-package.Net effect on the assessment: no change to the architectural verdict, no change to the recommended approach. The compatibility picture is marginally better and the Tree write-path risk is marginally lower, but the dominant risks (stack mismatch, silent failures, concurrency semantics, bridge maintenance) are untouched. Treat this as evidence of an actively maintained project, not as a reason to accelerate.
Technical risk. Moderate-to-high, and concentrated in three places:
Secondary risks: DBAL/ORM/persistence version matrix (^3.2 DBAL for all extensions; DBAL 4 excludes Loggable; ORM ^2.14/^3.0; persistence and event-manager support now varying by extension), and the deprecation of annotation mapping with removal in 4.0 — any codebase still on annotations has a scheduled migration.
Key questions to answer before committing.
laravel-doctrine bridge if it lags the next Laravel major?doctrine/persistence 4.0 support, or only SoftDeleteable? This determines whether our pins are coherent or a mix of generations.Stack fit. Assume PHP 8.1+, Laravel 10/11, MySQL or PostgreSQL, and Gedmo pinned at >=3.22.2 (baseline for the Tree and SoftDeleteable fixes). The viable paths are: (a) full Doctrine context — highest value, highest cost; (b) Doctrine confined to a new module/service inside an otherwise Eloquent app, communicating through repositories/DTOs, not shared models; (c) no adoption — reimplement Timestampable, SoftDeletes, and slugging with Eloquent-native traits, and skip the rest. Path (c) is genuinely defensible for a typical Laravel team and should be presented as a real option, not a straw man.
Migration path. Do not attempt an in-place Eloquent→Doctrine migration of a live domain. Instead: introduce Doctrine in one bounded context (content/CMS-style modules are ideal — Translatable, Tree, and Sluggable map directly to their needs), prove it for a release cycle, then decide on expansion. If we are already on Doctrine (inherited codebase, or a Symfony-adjacent service), adoption is additive: enable behaviors on existing entities incrementally, one attribute at a time, with schema migrations generated and reviewed.
Compatibility gates to clear first.
laravel-doctrine/orm supports our exact Laravel minor version; if not, plan to fork or vendor it.Blameable (it needs a user resolver wired to Auth::user()).Sequencing (recommended 2-sprint shape).
Maintenance. The project is healthy on paper: 4.1k stars, MIT, active CI/QA/coding-standard badges, changelog and releases, and a 3.0 line that explicitly modernized for current PHP/Doctrine. v3.22.2 supports that read — it is a maintenance release with forward-compat fixes for persistence 4.0, event-manager 2.1, and ORM 3, which is exactly the kind of work a healthy library does between majors. It is a well-run community library with a small maintainer base — typical of the Doctrine ecosystem. Realistic maintenance burden for us is low per behavior but non-zero: version-matrix upgrades (DBAL 4, ORM 3, persistence 4.0, the eventual 4.0 that drops annotations) will require scheduled work rather than being absorbed silently. The per-extension nature of readiness means we should track compatibility at the extension level, not by package version alone. If we fork the Laravel bridge, add ~1–2 engineer-days per Laravel major for compatibility patching.
Support. No commercial SLA; GitHub issues and community channels only. Acceptable for internal tooling; a gap for anything customer-facing with an on-call rotation unless we designate an internal owner with Doctrine fluency.
Scaling characteristics. The behaviors execute in PHP during flush(), so cost scales with write volume and flush batch size, not reads:
Failure modes to instrument and document.
NOT NULL and an assertion test.>=3.22.2 and add a multi-root-single-flush test so we do not regress onto the fixed bug.Ramp-up. For a team fluent in Eloquent but not Doctrine, budget 1–2 weeks per engineer to reach productive velocity on entity mapping, the UnitOfWork, DQL, and the event lifecycle — the behaviors themselves are the easy part. The Laravel-specific documentation is thin (one framework page), so internal onboarding docs and a working reference module are prerequisites, not nice-to-haves. Budget an internal Doctrine champion; without one, the first production incident involving a tree or flush ordering will be expensive.
How can I help you explore Laravel packages today?