Download the PHP package mathiasonea/laravel-rulebook without Composer

On this page you can find all versions of the php package mathiasonea/laravel-rulebook. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-rulebook

Laravel Rulebook

Keep historical business decisions reproducible—even after the rules change.

Pricing, eligibility, and entitlement rules often change on a specific date. When that logic lives in growing if statements, it becomes difficult to answer:

Give each policy version a name and validity period. When resolution succeeds, Laravel Rulebook returns one explicit winner for that point in time:

The same decision also explains what happened to every other rule:

Rule Status Role
Global default applicable Shadowed fallback
Austrian price applicable Shadowed fallback
Austrian EV 2025 outside_validity Skipped
Austrian EV 2026 applicable Winner
Austrian EV 2027 outside_validity Skipped

Change tomorrow's policy without rewriting yesterday's decision.

Latest Version on Packagist Total Downloads Tests PHP Version

Before and after

Without an explicit model, effective-date logic tends to grow inside one branching path:

With Rulebook, each policy version remains a named rule. The decision date is explicit, and the result says which rule won and why:

Every resolution also retains the complete evaluation: applicable fallbacks, rejected rules, and rules skipped because they were outside their validity window.

Installation

Laravel discovers the package provider automatically. There is no configuration to publish, migration to run, facade, or global registry.

For a complete working application, run the Austrian EV pricing example. It compares three yearly policies and prints the winner, fallbacks, skipped validity windows, and reasons from one Artisan command.

Use it when

Requirements

Not a fit when

Rulebook is deliberately code-defined and resolves exactly one winning rule. It is not a fit when you need:

Resources

Versioned pricing in practice

Suppose an Austrian electric-vehicle price changes every calendar year. The base price, incentive, and battery fee can all change, while a general Austrian price and a global default must remain available as fallbacks.

Model each policy version as its own rule. The rulebook then becomes a readable history of every policy that can govern the decision:

The PHPStan annotation establishes the subject, context, and outcome types for every rule in the rulebook. Rule order does not decide the winner; every applicable rule participates in explicit priority resolution.

Share stable policy, isolate yearly changes

Common eligibility can live in an abstract application-owned rule. The calculation delegates the values that are expected to change to the concrete yearly policy:

Each year supplies its own validity window and parameters:

This keeps a historical policy intact after a new year begins. If the formula itself changes in 2027—not just its parameters—the 2027 class can override the calculation without adding if ($year === ...) branches to older rules.

The rule class strings are resolved through Laravel's container, so the shared rule or concrete yearly rules can use constructor injection without package-specific registration. Exceptions from a rule or one of its dependencies bubble unchanged; an operational failure is never converted into “does not apply.”

Resolve and inspect a dated decision

Resolve historical or future decisions with a DateTimeInterface:

At that instant, the 2025 and 2027 rules are outside their validity windows and are not invoked. The 2026 rule wins with priority 100; the general Austrian and default prices can still be inspected as applicable but shadowed fallbacks.

Rule What happens on 2026-06-15 Role in the decision
DefaultVehiclePrice Applies Shadowed fallback
AustrianVehiclePrice Applies Shadowed fallback
AustrianElectricVehiclePrice2025 Outside its validity window; not invoked Inapplicable
AustrianElectricVehiclePrice2026 Applies Winner
AustrianElectricVehiclePrice2027 Outside its validity window; not invoked Inapplicable

The same rulebook can reproduce decisions under earlier or later policy versions without changing application code:

The returned decision exposes the winner and the complete evaluation:

A lower-priority match is still applicable. It is described as shadowed because the sole higher-priority rule governs the decision.

Evaluate without requiring a winner

Use evaluateNow() or evaluateAt() when diagnostics must remain available even if no rule applies or the top priority is ambiguous.

resolveNow() and resolveAt() are convenience methods for evaluating and then resolving.

Resolution throws:

NoMatchingRule and AmbiguousRuleMatch both retain the exact Evaluation on their public $evaluation property and through evaluation(). Registration order never breaks an equal-priority tie.

Rule authoring contract

Rulebook evaluates every rule inside its validity period, including lower-priority fallbacks, so that the returned evaluation explains the complete decision. Treat evaluate() as a deterministic, side-effect-free operation:

The default rule key is its class name. That is convenient while developing, but a class rename changes the key. Override key() with a stable domain identifier when decisions or their explanations are stored outside the current request:

Rulebook returns the complete evaluation but deliberately does not persist it. Applications that require a durable audit record can store a portable snapshot alongside their own business record.

Structured statuses and reason codes

Every RuleEvaluation has one structured status:

wasEvaluated() remains available when only the distinction between a domain rejection and a skipped rule matters. Rule keys, priorities, and validity periods are captured once before domain evaluation, so later inspection cannot change the winner.

Results may also include an optional machine-readable reason code alongside the mandatory human explanation:

Use reason codes for stable filtering, metrics, or localization; keep the reason useful to a human reading the decision.

Portable decision snapshots

Snapshots remove live subject, context, and rule objects while retaining the decision time, frozen rule metadata, validity windows, statuses, reasons, and reason codes. A decision snapshot always has one winner; an evaluation snapshot can instead record a conflict or no match. Both implement JsonSerializable and expose toArray():

Scalar, array, backed-enum, or JsonSerializable outcomes can use $decision->snapshot() directly. Supply normalizeOutcome when another outcome object needs an application-specific portable representation. Snapshot creation eagerly copies the normalized value and throws UnportableSnapshotValue for unsupported objects, resources, invalid UTF-8, non-finite numbers, cycles, or excessive nesting.

An evaluation can be snapshotted before resolution, including when no rule applies or several rules conflict:

Snapshots are transport records, not persistence. The application remains responsible for choosing where to store them and which subject or business-record identifier belongs beside them.

Every top-level snapshot contains schema_version: 1. The serialized field names, meanings, and status values are public API and follow the package's semantic-versioning policy.

Validity periods

Periods are half-open: [from, until).

An out-of-window rule is not invoked. Its RuleEvaluation is inapplicable, has a generated validity reason, and returns false from wasEvaluated().

Optional context

Use null as the context type when a decision only needs its subject:

RuleInput::subject() and RuleInput::context() provide typed access. A mismatch throws UnexpectedSubject or UnexpectedContext with the expected and actual types.

Nullable outcomes

null can be a valid typed outcome:

Applicability is stored separately from the outcome, so this is not confused with RuleResult::doesNotApply(...).

Time and testing

“Now” resolutions use Carbon's clock, including CarbonImmutable::setTestNow() in tests. Explicit DateTimeInterface values passed to resolveAt() and evaluateAt() are copied without changing their instant.

Roadmap

Already maintaining effective-date business logic? Model one real decision with Rulebook, then open an issue or start a discussion and tell us where the API feels heavy or breaks down. Focused pull requests are welcome; please discuss larger changes first.

Core invariants

Blank reasons, blank provided reason codes, blank rule keys, and invalid or empty validity periods are rejected. Skipped out-of-window rules remain distinguishable from evaluated domain rejections, and rule metadata is captured once per evaluation. Portable snapshots reject values that cannot be represented safely in their versioned JSON schema.

Development

The test suite includes vehicle-pricing and subscription-billing rulebooks, boundary and timezone cases, conflict and missing-match inspection, container injection, nullable outcomes, Carbon test time, exception propagation, architecture constraints, and PHPStan outcome inference.

License

Laravel Rulebook is open-source software licensed under the MIT license.


All versions of laravel-rulebook with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
illuminate/contracts Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package mathiasonea/laravel-rulebook contains the following files

Loading the files please wait ...