happyr/doctrine-specification
Happyr Doctrine Specification brings the Specification pattern to Doctrine: compose small, reusable, testable specification classes into query expressions instead of bloated repositories with long QueryBuilder calls and duplicated logic.
Spec classes combined with andX/orX/notX, instead of adding another findActiveUserWithPictureAndCompany() method. This directly reduces the per-feature cost of new filtered views, admin screens, and API list endpoints.match()) and in memory (isSatisfiedBy(), filterCollection()). That supports previews, dry-run eligibility checks, exports, validation, and "does this entity qualify?" UIs without duplicating logic in two languages (DQL and PHP).Adopt when:
laravel-doctrine — note this is not an Eloquent library).find* methods, many optional parameters, duplicated andWhere blocks.Look elsewhere when:
where closures instead.Bitwise, moved/removed classes) given your current usage.For executives (one paragraph): This is a small, MIT-licensed library that changes how our engineering team writes database queries. Today, query logic accumulates inside repository classes as long, duplicated methods that are hard to test and easy to get subtly wrong — especially around permission and tenant filtering. This package replaces that with small, named, reusable query components that compose together, so a new filtered screen or API endpoint reuses existing pieces instead of copying them. It is actively maintained (supporting both Doctrine ORM 2 and 3, with releases through 2026), carries no license cost, and its main cost is a short learning curve. Expected payoff is faster delivery of filtered views and a materially lower chance of a permission filter being missed on a new endpoint.
For engineering leads (bullets):
Spec::andX(...), orX, notX compose into a tree, which plain QueryBuilder mutation cannot express or reuse.repository->match($spec) for DB queries, isSatisfiedBy($entity) for single-entity checks, filterCollection($items) for in-memory filtering — no duplicated rule logic.DISTINCT and Count), SelectNew, GroupBy, OrderBy, Limit/Offset, and iteration with real keys.Bitwise, relocated Having), so budget for a version audit if we have legacy usage.Recommendation: Approve a scoped pilot on one bounded area — e.g., a search/filter endpoint with permission scoping — with success measured by duplication removed and test coverage of query logic gained. Decision to standardize follows the pilot.
How can I help you explore Laravel packages today?