Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Extensions Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

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:

  1. SoftDeleteable — listener resolution now goes through the ObjectManager, adding support for 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.
  2. Tree — multiple root nodes inserted in a single flush with the nested-set strategy now work when roots are not persisted first (#2582). This was a real correctness bug on a write path we had flagged as risky; if our spike or reference module inserts seed/fixture trees in one flush (very common in tests and importers), we would have hit it. Pin to >= 3.22.2 before writing any nested-set code.
  3. Tree — 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.
  4. Loggable — PHPDoc template bounds for Symfony TypeInfo (#3044). Static-analysis/DI-container noise, no runtime or behavioral consequence for us.

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:

  1. Stack mismatch — adopting this effectively means adopting Doctrine, a much larger commitment than the package itself.
  2. Silent-failure behaviors — if a listener is not registered or an attribute is misplaced, the extension degrades quietly (null timestamps, absent slug) rather than throwing. This is a test-coverage obligation, not just a config task.
  3. Concurrency semantics — Sluggable uniqueness checks and NestedSet/Sortable tree writes are read-modify-write in PHP. Under concurrent inserts these need unique constraints and/or locking discipline we must design ourselves. The v3.22.2 multi-root fix removes one deterministic bug; it does not address contention.

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.

  • Is the target codebase already on Doctrine, or would this trigger an Eloquent→Doctrine migration? (A migration is a quarter-scale project, not a package adoption.)
  • Which of the nine extensions do we actually need? Timestampable, SoftDeleteable, and Sluggable are cheap wins; Translatable, Loggable, and Tree carry real schema and write-path consequences.
  • Does any behavior touch money, inventory, or audit data? Loggable and NestedSet are the two where incorrect behavior has compliance or correctness weight.
  • Who owns the laravel-doctrine bridge if it lags the next Laravel major?
  • What is our concurrency profile on the tables that will carry Sluggable/Tree/Sortable?
  • Have the other eight extensions declared doctrine/persistence 4.0 support, or only SoftDeleteable? This determines whether our pins are coherent or a mix of generations.

Integration Approach

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.

  • Confirm Doctrine ORM/DBAL/persistence/event-manager versions against the matrix above; pin explicitly. Note that v3.22.2 makes SoftDeleteable compatible with persistence >= 4.0 and event-manager >= 2.1, but that support is not yet evidenced across the other extensions — do not assume a mixed-generation install is safe.
  • Confirm laravel-doctrine/orm supports our exact Laravel minor version; if not, plan to fork or vendor it.
  • Confirm attribute mapping only (reject annotation-based entities; they are a 4.0 time bomb).
  • Validate that our existing Laravel middleware/auth integrates with Doctrine's Blameable (it needs a user resolver wired to Auth::user()).
  • Verify the nested-set multi-root insert behavior on our actual entity graph (fixtures, seeders, importer) after upgrading — the fix landed in this release and our reference module should assert it.

Sequencing (recommended 2-sprint shape).

  1. Sprint 1 — spike: Doctrine bridge in a sandbox branch, Timestampable + SoftDeleteable + Sluggable on two entities, integration tests including a concurrent-slug test, CI wiring.
  2. Sprint 2 — hardening: add unique constraints, document listener registration as a checklist item, write a failure-mode runbook (below), decide on Loggable/Translatable/Tree scope. Add a regression test for multi-root nested-set inserts in one flush and for ORM 3 hydrator ordering before any Tree work starts.
  3. Post-decision: only then evaluate the expensive extensions (Translatable, Loggable, Tree) against alternatives — for content i18n, a dedicated translations table or JSON columns may beat Translatable's join-heavy model.

Operational Impact

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:

  • Sluggable issues an extra lookup per unique-slug insert; bulk imports need batched or precomputed slugs.
  • NestedSet and Sortable rewrite sibling ranges — O(n) writes per insert/move. Large trees with frequent reordering will show lock contention and deadlock risk. This is the extension most likely to force a redesign at scale. The 3.22.2 multi-root fix resolves a correctness edge case in this path but not the O(n) cost.
  • Translatable adds per-locale joins or secondary queries; watch for N+1 in list endpoints.
  • Loggable and Uploadable add auxiliary tables/storage: version tables grow unboundedly (needs retention policy), and Uploadable couples entity persistence to filesystem state with no built-in orphan cleanup.
  • Bulk updates via DQL bypass listeners entirely — a known trap.

Failure modes to instrument and document.

  1. Listener not registered (config drift, new environment) → silent null timestamps/slugs; mitigate with schema NOT NULL and an assertion test.
  2. Duplicate slug under concurrency → unique index + retry-on-conflict handler.
  3. Tree corruption after a partially failed transaction or a raw DQL mutation → periodic integrity check job. Related: pin >=3.22.2 and add a multi-root-single-flush test so we do not regress onto the fixed bug.
  4. Soft-deleted rows leaking into reports through hand-written SQL that bypasses the filter.
  5. Loggable write amplification during bulk imports → exclude those paths explicitly.
  6. Uploadable orphaned files on rollback → scheduled reconciliation job.
  7. Mixed-generation dependency install (some extensions on persistence 4.0, some not) → constrain the dependency set explicitly and let CI resolve the full matrix before merge.

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.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route