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

Product Decisions This Supports

  • Feature scoping for computed/aggregate fields. This package makes “derived” attributes — orderCount, totalRevenue, lastOrderDate, CSAT-style rollups — first-class entity properties populated by an embedded SQL/DQL subquery. It directly enables features that previously needed either a per-row query (N+1), a hand-written DTO projection, or a nightly ETL/reporting table: customer health badges, admin list sorting by lifetime value, segmentation thresholds, “inactive customer” ordering, revenue tiers in a single result set.
  • Build vs buy for read-model plumbing. The real alternative is internal work: a custom SqlWalker/hydrator, a projection DTO layer, or a materialized view plus refresh job. This package is a ~1–2 day spike versus an estimated 1–2 weeks of internal implementation for the same behaviour. The decision is therefore borrow-and-own, not buy-and-trust: plan to vendor or fork it into an internal namespace rather than depend on upstream support.
  • Roadmap sequencing for reporting-adjacent features. Because formula fields work in WHERE, ORDER BY, GROUP BY, HAVING, CASE WHEN and standard aggregates, it unblocks roadmap items that are currently gated on “we need a reporting store first”: filterable metrics, ranked leaderboards, threshold-based categorization. It does not replace a warehouse — it defers the need for one for small/medium datasets.
  • Architecture decision: entity-computed vs. separate read model. The package embeds the subquery on every SELECT of that entity, with no opt-in/opt-out. That is a genuine product trade-off: cheap for detail pages and admin screens, potentially expensive for high-traffic list endpoints where the metric isn’t displayed. This should be an explicit decision recorded against the affected endpoints, not an incidental one.
  • Stack fit decision. Important caveat for scoping: despite being a PHP package, this targets Doctrine ORM 3, i.e. Symfony-style stacks, not Laravel/Eloquent. For a Laravel product it informs nothing on the roadmap beyond “this pattern exists”; for a Doctrine/Symfony service it is directly actionable.
  • Platform/version commitment. Requires PHP >= 8.2 and Doctrine ORM 3. Adopting it is a soft commitment to those floors and to the DBAL middleware pipeline being part of your bootstrap.

When to Consider This Package

Consider it when all of the following hold:

  • You are on Doctrine ORM 3 / PHP 8.2+, ideally Symfony (where cryonighter/formula-doctrine-bundle wires the stack via DI and removes the manual bootstrap).
  • You have a small, stable set of aggregate fields (roughly 1–5 per entity) that are naturally scoped to the root entity and cheap as a correlated subquery.
  • Your data volumes and query rates let an always-on correlated subquery be acceptable, or the entity is only loaded on detail/admin screens.
  • You are willing to treat it as internal code: pin an exact version, review the walker, add integration tests asserting the emitted SQL, and accept maintenance ownership.
  • The alternative (projection DTOs, materialized views, maintained counter columns) is materially more expensive for this iteration.

Look elsewhere when:

  • You are on Laravel/Eloquent. Not applicable; there is no Eloquent integration here.
  • You need write-time denormalized counters (trigger- or event-maintained) rather than read-time computation — different mechanism, different guarantees.
  • Hot paths: endpoints that serialize many rows and don’t display the metric will still pay for the subquery. Prefer DTO projections there.
  • Heavy analytics: multi-join, cross-entity windows, large scans, or anything you would normally push to a warehouse or materialized view.
  • Dynamic/parameterized formulas: the expression is static per entity property; per-user or per-request filtering must be composed in the query, not the attribute.
  • Third-party risk is unacceptable. Maturity signals are thin: 0 stars, 0 dependents, no production adoption evidence, README + CHANGELOG only, single maintainer. There is no security posture, no release cadence, no community support path. If your org requires vetted OSS provenance, this fails that gate regardless of technical merit.
  • You need portability guarantees across PostgreSQL/MySQL/SQLite. The docs are PostgreSQL-flavoured and require you to hand-write native SQL with a {this} placeholder and a parentheses convention (native SQL must be wrapped, DQL must not) — a real footgun that will be misused without review.

How to Pitch It (Stakeholders)

To executives (one paragraph): We can ship “customer health” style metrics — order counts, lifetime value, last activity, revenue tiering — without standing up a reporting database or writing a bespoke aggregation layer. Instead of one database round-trip per row, the metric is computed inside the main query, which is cheaper and simpler. The catch is that the library is an early-stage, single-maintainer open-source project with no known adopters, so the recommendation is a short, time-boxed pilot on one entity, with a deliberate plan to fork the code internally if it proves out. Cost to evaluate is days, not weeks; the main risk is maintenance ownership, not licensing (MIT).

To engineering leads: Declarative #[Formula] attribute on Doctrine 3 entities, registered through a DBAL FormulaMiddleware plus loadClassMetadata/postGenerateSchema listeners. Formula fields become non-insertable, non-updatable mapped fields, so the standard ObjectHydrator populates them and they never appear in INSERT/UPDATE; the schema listener strips them from generated DDL. The subquery is embedded once per query regardless of how many clauses reference it, and it works transparently with DQL, QueryBuilder, find/findBy/findAll, eager associations and lazy proxies — no changes to calling code. Ask engineering to verify: emitted SQL on our target driver, behaviour under pagination and with setMaxResults, cost on our largest list endpoint, and whether the always-on subquery is acceptable there. Treat the attribute as an infrastructure detail behind repository methods, not something the domain layer references directly.

Recommendation: Approve a 1–2 day spike on a single non-critical entity in a Doctrine-based service. Success criteria: correct values across find, QueryBuilder, and aggregate/GROUP BY queries; no measurable regression on the target endpoint’s p95; no INSERT/UPDATE leakage. If it passes, vendor the package (pinned commit, internal namespace, integration tests around generated SQL) rather than consuming it upstream. If the stack is Laravel/Eloquent, close the evaluation — the pattern is worth borrowing, the package is not applicable.

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