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

Formula Doctrine Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

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:

  • A Laravel service provider registering FormulaMiddleware on the DBAL Configuration.
  • Registration of FormulaSqlWalker as the default output walker and the registry as a query hint (the package's FormulaDoctrineConfigurator is Symfony-specific).
  • Listener registration for loadClassMetadata and postGenerateSchema.
  • Confirmation that the existing Laravel–Doctrine bridge does not conflict with custom DBAL middleware or output walkers.

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.

  • Ecosystem risk (high): 0 stars, 0 dependents, single maintainer, only README + CHANGELOG, no test coverage signals. No evidence of production use.
  • Version-fragility (high): Relies on mutating 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.
  • Performance risk (medium–high): Formula fields are correlated SQL subqueries embedded into every 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.
  • Correctness risk (medium): Debugging is harder because SQL is rewritten invisibly. Formula fields silently omitted or duplicated in partial hydration, DTO hydration, pagination counts, or Paginator-style queries is a real failure mode.
  • Security (low): Formula expressions are developer-authored attributes, not user input; no injection vector beyond what a developer could already write.
  • Maturity (low): Pre-1.0 ecosystem signals, no dependents, no external validation.

Key questions to resolve before commitment.

  1. Is the application actually using Doctrine ORM 3, or Eloquent? If Eloquent, is a Doctrine migration justified by the value of this feature alone? (Almost certainly not.)
  2. Which Doctrine ORM / DBAL / PHP versions are pinned, and does the maintainer commit to tracking Doctrine releases?
  3. How does the walker behave with the Doctrine Paginator, toIterable(), batch processing, second-level cache, and read/write split connections?
  4. How are formula fields treated in COUNT queries, GROUP BY/HAVING, and array/DTO hydrators?
  5. What is the fallback if the package is abandoned — is the team prepared to fork and vendor it?
  6. What is the measured query-plan impact of correlated subqueries on the target tables (EXPLAIN before/after)?

Integration Approach

Stack fit. Treat this as Doctrine-only. A TPM should gate adoption on the following decision tree:

  • Eloquent-first Laravel app: Reject for now. Equivalent value can be obtained via accessors + explicit repository queries, or a materialized read model. Do not adopt Doctrine just to use this package.
  • Laravel app already running Doctrine (via laravel-doctrine or similar): Viable candidate for reporting/read-model entities, not core write entities.
  • Standalone PHP service (Symfony or plain) behind a Laravel API: Best fit. Symfony users can use the companion formula-doctrine-bundle; standalone users follow the README bootstrap.

Migration path.

  1. Isolate a pilot module — a reporting or analytics read model with 1–3 entities and 1–2 formula fields (e.g., order count, lifetime value). Keep it out of the primary write schema.
  2. Bootstrap the middleware, walker, and listeners via a dedicated service provider; wrap in config flags so it can be disabled without code removal.
  3. Prove correctness with a Doctrine-specific test suite: query results, generated SQL snapshots, schema tool output, fixture loading, and hydration of nullable and typed properties.
  4. Benchmark pilot endpoints against the current implementation with realistic data volumes; capture EXPLAIN plans and p95/p99 latencies.
  5. Expand to additional read models only after the pilot demonstrates performance parity or improvement and no walker regressions.
  6. Never apply formula fields to entities whose INSERT/UPDATE path is business-critical until the non-insertable/non-updatable behavior is proven under load.

Compatibility.

  • Pin 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.
  • Ensure existing DBAL middleware (logging, profiling, read/write splitting) coexists — the package must be added to a middleware chain, and ordering matters.
  • Verify against the Doctrine migration tooling (doctrine/migrations) and any schema-diff tooling, since PostGenerateSchemaListener removes formula columns from generated schemas.
  • Consider a "vendor fork" arrangement (private fork with internal tests) if the pilot proves value — this de-risks abandonment and lets the team control upgrade cadence.

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.

Operational Impact

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:

  • Internal ownership with at least one engineer who understands the SQL walker and metadata mutation.
  • A documented upgrade runbook: pin Doctrine, upgrade the package and Doctrine together, run the SQL-snapshot test suite.
  • A pre-approved fork fallback if upstream goes dormant (likely, given 0 stars and 0 activity signals).

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.

  • Query cost: Correlated subqueries per row scale with result-set size. Pagination and LIMIT/OFFSET mitigate but do not eliminate the cost; COUNT(*) wrapping and total-row queries need explicit testing.
  • Index coverage: All correlation columns (e.g., orders.customer_id) must be indexed. Without this, the feature will degrade badly on large tables.
  • Aggregations: GROUP BY / HAVING over formula fields compound cost; restrict to low-cardinality reporting paths.
  • Caching: Formula fields are computed at query time; they do not benefit from entity second-level caching unless query-level caching is used. Any cache invalidation strategy must be at the query layer, not the entity layer.
  • Read replicas: Safe if the DBAL middleware is applied to the replica-bound connection; verify read/write splitting does not strip or reorder the middleware.

Failure modes.

  • Silent walker regressions: A Doctrine upgrade alters SQL generation, formula SQL is misplaced, and queries return correct-looking but stale/empty fields. Mitigation: SQL snapshot tests plus assertions on representative entities.
  • Schema drift: PostGenerateSchemaListener fails to remove formula fields or removes real columns; migrations generate ghost columns. Mitigation: diff generated schema against a golden schema in CI.
  • Hydration gaps: Formula fields not populated under partial hydration, DTO hydration, or custom hydrators. Mitigation: contract tests across all hydration modes in use.
  • Alias collisions: Custom alias: values colliding with real column aliases in complex queries. Mitigation: naming convention, code review checklist.
  • Performance cliffs: A new query path wraps a formula field in an aggregate that triggers repeated subquery evaluation. Mitigation: query review checklist + EXPLAIN in PRs touching formula entities.
  • Abandonment: Upstream stops tracking Doctrine. Mitigation: vendor fork with internal tests.

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.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums