gregosphatos/doctrine-filters-bundle
A Symfony bundle for Doctrine that lets you register and enable SQL filters declaratively through configuration, so you can apply reusable query conditions such as soft-delete or tenant scoping without touching repository code.
Architecture fit — poor, at the framework layer only. The package is a Symfony bundle (DoctrineFiltersBundle) for the Doctrine ORM. Laravel's default persistence layer is Eloquent/ActiveRecord; Doctrine is a second-class citizen in Laravel, adopted only via the community laravel-doctrine/* packages. The bundle's core value (a Symfony Bundle class, a DI Extension, and a compiler pass that registers Doctrine SQLFilter implementations) has no meaning inside Laravel's service container, which does not understand Symfony bundle conventions. The filters themselves — the actual SQLFilter/SQLFilter subclasses that inject WHERE clauses into every query for a given entity — are portable, since they are plain Doctrine ORM constructs. So the reusable surface is likely small and the wrapping is discarded.
Integration feasibility — feasible but largely a re-implementation. Under laravel-doctrine/orm, filters are enabled by calling $em->getConfiguration()->addFilter($name, $className) and $em->getFilters()->enable($name) during boot — a handful of lines in a service provider. That is the entirety of what the bundle automates. The pragmatic path is to vendor or fork the filter classes and register them directly, treating the bundle as reference source rather than a dependency.
Technical risk — high, driven by abandonment, not by code complexity. Zero stars, zero dependents, and a single author indicate no downstream validation and no support ecosystem. The repository is almost certainly written against an older Symfony (2.x/3.x) and Doctrine ORM 2.x constraint set; a hard symfony/framework-bundle requirement in composer.json would make it uninstallable in a modern Laravel app without --ignore-platform-reqs or a fork. Doctrine ORM 3.x also changed filter APIs and attribute/metadata handling, so version drift is a real hazard. MIT license means forking is legally clean — that is the primary mitigating factor.
Key questions before committing:
composer.json constraints for PHP, doctrine/orm, and symfony/*? Does it install cleanly on our target PHP 8.2+/Doctrine 3 stack?Stack fit. Only relevant if the target application has already committed to Doctrine ORM under Laravel via laravel-doctrine/orm. On an Eloquent codebase, the correct answer is to reject the package and use Eloquent global scopes, which provide equivalent per-model query interception with first-class Laravel support. This should be stated plainly to stakeholders rather than treated as a porting exercise.
Migration path. Three options, in increasing cost: (1) add as a Composer dependency and bridge the DI extension — not recommended, since the Symfony container integration cannot be satisfied; (2) fork the filter classes into app/Doctrine/Filters under our own namespace, drop the bundle wrapper, and register via a DoctrineServiceProvider boot method; (3) re-derive the filters from scratch against our current Doctrine version. Option 2 is the defensible default: it preserves any battle-tested SQL logic while eliminating unmaintained framework glue.
Compatibility. Assume the fork is required. Port work is bounded: filter classes are typically tens of lines, but they may reference Symfony DI annotations, parameter bags, or ContainerAwareInterface. Each of those must be stripped and replaced with constructor injection. Verify behavior against Doctrine ORM 3 metadata drivers (attributes vs. annotations) and against laravel-doctrine's entity manager lifecycle, particularly boot order — filters must be enabled before the first query, not lazily.
Sequencing. (a) Two-day spike: install in a scratch Laravel+Doctrine project, inventory the shipped filters, confirm what breaks. (b) Decision gate on fork vs. build vs. reject. (c) If forking: extract classes, add unit tests asserting generated SQL per filter and per entity, and a regression test proving the filter cannot be silently bypassed. (d) Register in a service provider with explicit enable/disable toggles. (e) Only then wire into domain code.
Maintenance. We own it outright. There is no upstream to patch, no issue tracker activity to monitor, and no realistic expectation of a security fix. Budget for this as internal code from day one: assign a named owner, keep it in a first-party namespace, and document the provenance and fork commit in the README so future maintainers know why the code exists.
Support. Effectively zero. No vendor, no community, no dependents to crowd-source answers from. Any production issue is diagnosed by us with Doctrine internals knowledge — a nontrivial skill that may sit with one or two engineers.
Scaling. Filters compile into SQL WHERE clauses and generally scale acceptably, but two costs need attention: filters that reference request-scoped state (tenant ID, user context) must be resolved per-request and cannot be baked into a long-lived configuration in queue workers or Octane-style persistent processes. This is the most likely production surprise — a tenant filter captured at boot will silently serve one tenant's data to another. Second, filters interact poorly with second-level cache and with query result caching; scope those deliberately.
Failure modes. The dangerous class of failure is silent non-application: a filter fails to enable, is disabled by a code path, or is bypassed by native SQL or a raw DQL query, and cross-tenant or soft-deleted rows leak into responses. This is a confidentiality failure, not a bug. Secondary modes: duplicate filtering when a global scope and a Doctrine filter overlap; exceptions during filter construction taking down the whole entity manager; and confusing behavior in UnitOfWork when filtered-out entities are still managed in memory. Mitigation is a startup assertion that expected filters are enabled plus an integration test per entity that proves the WHERE clause is present.
Ramp-up. The codebase is small, so comprehension cost is low — a day for a Doctrine-familiar engineer. The real ramp-up cost is organizational: the team must accept ownership of unmaintained third-party logic in a security-sensitive path (data isolation). Given zero stars, zero dependents, and a framework mismatch with Laravel, my recommendation is to mine this repository for the filter logic and reimplement it first-party, rather than adopt it as a dependency.
How can I help you explore Laravel packages today?