cryonighter/formula-doctrine
Hibernate-style #[Formula] computed fields for Doctrine ORM 3 entities. Adds read-only, SQL-computed properties populated via subqueries, aggregations, and joins, without N+1 queries. Works standalone or with a Symfony bundle.
Architecture fit. cryonighter/formula-doctrine is a Doctrine ORM 3 extension, not a Laravel/Eloquent package. Its integration surface is a DBAL middleware (FormulaMiddleware), an ORM output SQL walker (FormulaSqlWalker), two event listeners (loadClassMetadata, postGenerateSchema), and a metadata registry. This is a textbook "seam" design for Doctrine, but it has no native Laravel footprint — no service provider, no config file, no facade. If the target application is Eloquent-based (the default Laravel ORM), the package is out of scope. It only makes sense if the team has already committed to Doctrine via a bridge such as laravel-doctrine or runs Doctrine inside a non-Laravel PHP service consumed by the Laravel app.
Integration feasibility. Manual bootstrap is documented and straightforward if you understand Doctrine wiring, but a TPM would have to commission:
FormulaMiddleware on the DBAL Configuration.FormulaSqlWalker as the default output walker and the registry as a query hint (the package's FormulaDoctrineConfigurator is Symfony-specific).loadClassMetadata and postGenerateSchema.That is a modest but non-trivial piece of glue work, plus a test suite to prove it works across the codebase's queries.
Technical risk.
ClassMetadata (registering fields as non-insertable/non-updatable), overriding the SQL output walker, and hooking postGenerateSchema. These are internal-heavy seams that historically break across Doctrine major/minor releases. ORM 3 is a young major (Doctrine 3 is recent), so compatibility churn is likely.SELECT. That removes N+1 but shifts cost into per-row subquery execution; on large tables with weak indexes this can be slower than batched alternatives. GROUP BY / aggregate composition amplifies complexity.Paginator-style queries is a real failure mode.Key questions to resolve before commitment.
Paginator, toIterable(), batch processing, second-level cache, and read/write split connections?COUNT queries, GROUP BY/HAVING, and array/DTO hydrators?Stack fit. Treat this as Doctrine-only. A TPM should gate adoption on the following decision tree:
laravel-doctrine or similar): Viable candidate for reporting/read-model entities, not core write entities.formula-doctrine-bundle; standalone users follow the README bootstrap.Migration path.
EXPLAIN plans and p95/p99 latencies.Compatibility.
cryonighter/formula-doctrine to a specific version; pin Doctrine ORM to 3.x and DBAL to 4.x to match tested versions. Do not float.doctrine/migrations) and any schema-diff tooling, since PostGenerateSchemaListener removes formula columns from generated schemas.Sequencing. Prototype (1 sprint) → internal benchmarking & test harness (1 sprint) → pilot in production behind feature flag (1–2 sprints) → evaluate against alternatives → decide on wider adoption. Budget for the fork/vendor decision as a distinct milestone, not an afterthought.
Maintenance. The primary operational concern is bus factor 1. There is no evidence of a maintainer team, no dependent packages to co-maintain, and the package sits on ORM internals that will break on Doctrine upgrades. A TPM should plan for:
Support. Community support is effectively nil. Documentation is a README with examples; there is no support SLA, no changelog depth, no issue-history signal. The team must expect self-support — internal wiki, runbooks, and a contact-of-record engineer. This is acceptable for a bounded read-model feature; unacceptable for a platform-wide dependency.
Scaling.
LIMIT/OFFSET mitigate but do not eliminate the cost; COUNT(*) wrapping and total-row queries need explicit testing.orders.customer_id) must be indexed. Without this, the feature will degrade badly on large tables.Failure modes.
PostGenerateSchemaListener fails to remove formula fields or removes real columns; migrations generate ghost columns. Mitigation: diff generated schema against a golden schema in CI.alias: values colliding with real column aliases in complex queries. Mitigation: naming convention, code review checklist.EXPLAIN in PRs touching formula entities.Ramp-up. Moderate; not because the package is complex but because debugging requires understanding of the Doctrine SQL walker and query AST. A competent Doctrine engineer is productive in a few days; a team new to Doctrine (or Eloquent-only) faces a multi-week ramp — which on its own often discredits adoption for a Laravel-only shop. Recommended initial team: one senior PHP engineer with Doctrine internals experience, one engineer owning tests/CI, and product ownership by a TPM tracking the pilot metrics and the fork/abandon decision.
How can I help you explore Laravel packages today?