ruwork/doctrine-behaviors-bundle
Symfony bundle for integrating Doctrine behavioral extensions, simplifying configuration of behaviors such as timestampable, blameable, sluggable, tree, and soft-deletable entities in your projects.
Architecture fit. The package is mislabeled in the request: it is not a Laravel package. It is a Symfony bundle (ruwork/doctrine-behaviors-bundle) that wires the ruwork/doctrine-behaviors library into the Symfony DI container by registering Doctrine event subscribers for behaviors such as timestampable, blameable, soft-delete, and sluggable. It presumes Symfony's bundle/kernel architecture, service tagging, and configuration tree. A Laravel application runs on Eloquent by default; adopting this would require first adopting Doctrine ORM plus a Doctrine integration layer for Laravel, then hand-wiring the subscribers this bundle was built to register for you. The bundle's core value proposition — automatic service registration — evaporates outside Symfony.
Integration feasibility. Low for a Laravel codebase, moderate for a Symfony 3.x/4.x codebase frozen on the matching PHP generation. The underlying behaviors themselves are small, well-understood Doctrine event-listener patterns; the reusable intellectual property is perhaps a few hundred lines of listener logic. Any competent engineer can reimplement the specific behavior required (e.g., soft-delete via a query filter plus a deletedAt column) in less time than it takes to validate this dependency. That reframes the decision: we are not evaluating an integration, we are evaluating whether to harvest code from an abandoned repository.
Technical risk. High and asymmetric:
Key questions.
created_at/updated_at, route-model-binding slugs)?gedmo/doctrine-extensions + stof/doctrine-extensions-bundle been ruled out? That is the maintained, widely adopted equivalent with the dependents and release cadence this package lacks.Stack fit. Poor. For a Laravel/Eloquent application, integration cost is dominated by introducing Doctrine at all — a migration far larger than the feature being requested. For a Symfony/Doctrine application, fit is structural but version-constrained; verify the bundle's composer.json constraints against the current PHP and Symfony versions before anything else. Expect the constraints to exclude current runtimes entirely.
Recommended path (Laravel). Do not integrate. Implement the behavior natively:
SoftDeletes trait, withTrashed/onlyTrashed scopes.$table->timestamps(), already default.created_by/updated_by from the authenticated context.HasSlug trait or spatie/laravel-sluggable.
This delivers the same semantics with zero new dependencies, first-class framework support, and no upgrade debt.Recommended path (Symfony/Doctrine). Adopt gedmo/doctrine-extensions with stof/doctrine-extensions-bundle instead. It covers the same behavior set, has an active maintainer base, and ships compatibility for current Doctrine releases. Migrating behavior annotations/attributes at this layer is a per-entity, mechanical change.
Fallback path (hard requirement on this specific library). Treat it as source code, not a dependency: fork to an internal namespace, vendor it, strip the Symfony bundle layer, replace the service wiring with explicit listener registration, add test coverage for each behavior, and pin the PHP/Doctrine versions it runs against. Budget this as a small internal project with a named owner, not as a Composer install.
Sequencing. (1) Confirm runtime and ORM. (2) Confirm the precise behavior list. (3) Prototype the native/maintained alternative against one representative entity. (4) Only if the prototype fails a hard requirement, evaluate the fork. Never sequence the fork first — it front-loads risk for a feature that is usually a 50-line trait.
Maintenance. Effectively total internal ownership on day one. Archived projects receive no bug fixes, no security patches, and no compatibility updates. Every future PHP minor, Symfony major, and Doctrine major becomes our remediation work. The bus factor is one: whoever forks it.
Support. None upstream. No maintainer to escalate to, no issue tracker with resolution history, no community forum. Internal support is limited to engineers who can read Doctrine's event system — a narrower group than those who can write an Eloquent trait.
Scaling. Runtime cost is negligible either way: Doctrine listeners fire per entity per flush, and soft-delete query filters add a predicate to reads. The real scaling constraint is organizational — the maintenance cost grows with every framework upgrade cycle, while the benefit stays fixed. Over a three-year horizon this dependency's total cost of ownership is far higher than any equivalent built into the framework.
Failure modes.
DELETE, or raw queries — deleted records resurface in reports or API responses. This is a correctness and potentially compliance risk.Ramp-up. Low conceptual learning curve — these are simple, well-documented behavioral patterns, and engineers familiar with Doctrine or with Eloquent observers will grasp the intent in an hour. The cost is archaeological rather than intellectual: reading 2018-era code, understanding legacy annotation semantics, and tracing DI wiring with no documentation. For a Laravel team, add the cost of learning Doctrine's unit-of-work, event lifecycle, and metadata model — a multi-week learning curve for a feature the framework ships out of the box.
Bottom line. MIT licensing aside, this package offers no viable adoption path. The underlying need is real; this artifact is not the implementation. Recommend closing the evaluation and routing to the native framework feature (Laravel) or gedmo/doctrine-extensions (Doctrine), reserving a fork only for a documented hard requirement with a named owner and a funded exit plan.
How can I help you explore Laravel packages today?