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

Rulerz Laravel Package

frontastic/rulerz

frontastic/rulerz is a PHP rule engine and specification library for writing business rules once as reusable predicates and applying them to arrays, query builders, and other data sources. Use its concise DSL or PHP rules for filtering, validation, and dynamic access control.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. frontastic/rulerz is a fork of K-Phoen's RulerZ implementing the Specification pattern for PHP. It gives you a runtime expression DSL (points > 30 and gender = "f"), closure-based predicates, and a Specification interface, with the same rule evaluated in-memory, compiled to SQL/DQL via Doctrine, or translated into Elasticsearch DSL via target-specific visitors. For a Laravel/PHP product this sits precisely at the domain boundary between user-defined filter input and data access — the right layer for reusable, testable, serializable business rules shared across admin UI, API query params, and persistence. Fit is strong on pattern, weak on out-of-the-box Laravel plumbing: there is no first-party Eloquent or Scout target, so the two headline integrations (Doctrine, Elasticsearch) are adjacent to, not native to, the Laravel stack.

Integration feasibility. Mechanically trivial — Composer package, MIT license, no services. The consuming surface is small: construct a RulerZ instance with a compiler, operator registry, and targets, then call satisfies(), filter(), or matching(). The real feasibility questions are economic and supply-chain:

  • Transitive dependency health. Upstream depends on hoa/ruler/hoa/compiler, effectively unmaintained with known PHP 8.x friction. The likely reason this fork exists is to patch exactly that. Verify what changed before duplicating the work.
  • Eloquent gap. matching() compiles against Doctrine QueryBuilders; Illuminate\Database\Query\Builder needs a custom Target/visitor (~200–400 LOC) or a DBAL bridge. In-memory filter() over Collections works today.
  • Elasticsearch coupling. The ES visitor targets a specific client/version and a DSL subset — treat as "demonstrate, then verify against your cluster."

Technical risk. Ranked:

Risk Severity Mitigation
Abandoned transitive dependency (hoa/*) High Swap compiler for symfony/expression-language behind the Compiler interface
Single-maintainer fork, no release cadence High Vendor internally; pin commit SHA; own CI
No PHP/Laravel compatibility matrix Medium Add PHPUnit + PHPStan matrix on adoption
Behavioral drift across targets Medium Contract tests asserting identical result sets per target
User-supplied DSL as injection/DoS surface Medium Operator allowlist; verify parameter binding; cap expression complexity
Limited per-target operator coverage Low–Medium Document supported subset; fail loudly on untranslatable specs

The dominant risk is supply chain and longevity, not code quality — the codebase is small and well-shaped, but it has zero stars, zero dependents, and zero known consumers.

Key questions.

  1. What does this fork change relative to K-Phoen/rulerz, and does it still pull hoa/*?
  2. Which PHP and Laravel versions are actually exercised in CI?
  3. Do we need query-builder pushdown now, or is in-memory collection filtering sufficient for the first use case?
  4. Are specs authored by developers (safe) or persisted/edited by end users (needs sandbox + operator allowlist)?
  5. Is the DSL a public contract that must stay stable, or an implementation detail behind our own interface?
  6. Who owns this in 12 months, and what is the exit cost to symfony/expression-language or a hand-rolled predicate tree?

Integration Approach

Stack fit. Assume Laravel 10/11/12 on PHP 8.2+. Two postures:

  • Narrow (recommended for a pilot): in-memory only — Specification objects and the DSL compiler over arrays/Collections for eligibility, segmentation, and pricing rules in the domain layer. Zero persistence coupling.
  • Broad (only if justified): add a custom Eloquent target so matching() compiles to Illuminate\Database\Query\Builder, mirroring the Doctrine target. Budget for it; do not assume it exists.

Bind the engine in a service provider as a singleton exposing a narrow interface (SpecificationEngine::filter(iterable $items, Specification $spec): iterable) so controllers and models never reference the library directly. This is the single highest-leverage decision — it caps migration cost regardless of upstream fate.

Migration path. Realistically greenfield adoption with exits pre-planned:

  1. Entry: add via a VCS repository entry pinned to a commit SHA (not a branch), and mirror into an internal namespace (internal/rulerz) so we control tags, PHP constraints, and patches. Do not depend on Packagist availability of a zero-star fork.
  2. Dependency remediation: if hoa/* is present, replace the compiler with symfony/expression-language (mature, maintained, Laravel-adjacent) behind the existing Compiler interface — confirm the fork hasn't already done this.
  3. Exit: the SpecificationEngine interface plus contract tests makes a future swap to symfony/expression-language or a hand-rolled specification tree an internal refactor, not a cross-cutting change.

Compatibility. Pin conservative constraints and widen only with evidence: PHP ^8.2, Laravel ^10.0|^11.0|^12.0, and require that the package's own constraints not force a downgrade. Treat any version bump as a reviewed change, not a composer update side effect.

Sequencing. (1) One-week timeboxed spike converting three real production rules against Collections; (2) define the internal interface and contract tests; (3) vendor and pin; (4) build the Eloquent target only if a second consumer justifies it; (5) revisit self-service authoring as a separate roadmap item — this package is the engine, not the UI.

Operational Impact

Maintenance. With this adoption profile, assume we inherit maintenance. A named owner and a vendored fork are prerequisites, not nice-to-haves. Ongoing cost is low in volume (small codebase) but non-zero in attention: PHP/Laravel upgrade compatibility checks, security advisory monitoring on a package nobody else watches, and periodic audit of the hoa/* (or replacement) surface. Budget a recurring slice of one engineer's time, not a project.

Support. No vendor, no community, no Stack Overflow corpus. Support is internal: the owning team becomes the escalation path for DSL questions, operator semantics, and target-specific behavior. Mitigate with documentation of the supported DSL subset and a deliberately loud failure mode for untranslatable specs — silent divergence between targets is the expensive failure.

Scaling. In-memory filtering scales with collection size and is unsuitable for large catalogs; pushdown to SQL or the search index is the scaling story, and that is exactly where the Eloquent gap and ES version coupling bite. There is no index-awareness or caching story out of the box — parsed-rule caching exists, but query planning does not. Benchmark against real catalog size before committing, and explicitly rule out hot-path (>1k RPS) and real-time bidding use cases.

Failure modes. Ranked by cost: (a) semantic drift — the same spec returns different results in-memory vs SQL vs ES, producing "works in preview, wrong in production" incidents; contract tests across targets are the control; (b) dependency rot — a PHP upgrade forces an emergency compiler swap; the interface boundary and a rehearsed exit contain it; (c) injection/DoS via user-supplied DSL — allowlist operators, verify parameter binding, cap complexity; (d) abandonment — the fork stops receiving patches; vendoring plus a pinned SHA makes this survivable rather than fatal.

Ramp-up. The Specification pattern is familiar to most PHP engineers, but the DSL, operator registry, and visitor/compilation model are not. Expect a genuine learning curve for anyone writing custom targets or operators, and a shallow one for anyone only composing specs. Onboarding cost is lowest when rules are plain PHP classes behind our interface and the DSL is an implementation detail — that containment is also what makes the package replaceable. For product and commercial stakeholders the gain is a shared, precise rule vocabulary and a shorter path from "change the eligibility criteria" to "it's live"; the non-gain, which must be stated plainly, is that self-service rule authoring, versioning, audit trails, and governance remain separate roadmap items requiring either a translation layer or a BRMS.

Recommendation. Fund a two-week spike, not a commitment. The defensible decision now is "encode volatile commercial rules as composable, individually tested Specification objects" — that holds regardless of whether this specific fork survives. Adopt the package only behind a thin internal interface, with a named owner, a pinned vendored copy, a written exit plan, and a due-diligence checklist covering license (MIT — fine), security advisory history, PHP/Laravel matrix, adapter coverage for our datastores, three real rules converted, and a comparison against upstream K-Phoen/rulerz.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource