Download the PHP package vaened/php-delta-orchestrator without Composer
On this page you can find all versions of the php package vaened/php-delta-orchestrator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download vaened/php-delta-orchestrator
More information about vaened/php-delta-orchestrator
Files in vaened/php-delta-orchestrator
Package php-delta-orchestrator
Short Description Framework-agnostic partial update orchestration engine based on real deltas
License MIT
Informations about the package php-delta-orchestrator
PHP Delta Orchestrator
php-delta-orchestrator is a library for orchestrating partial updates by comparing incoming input against the current state, producing a
Action instances only when appropriate.
Installation
Delta Orchestrator requires PHP 8.2 or higher and can be installed via Composer:
Problem it solves
Traditional approach
When handling partial updates, code tends to quickly degrade into scattered conditional logic:
- checking whether a field is present in the input,
- comparing it with the current value,
- deciding whether to execute business logic,
- avoiding unnecessary operations when nothing has changed.
This usually leads to nested conditionals, duplicated comparison logic, and implicit rules spread across the application layer.
The core issue is that this approach mixes in the same place:
- input handling,
- change detection,
- action execution.
This library’s approach
An explicit flow is introduced where each responsibility is clearly separated:
PatchValuemodels input presence and normalization,Fieldevaluates changes against the current state,Deltarepresents an effective transition,Actiondefines when and how to execute logic.
Conceptual model
The library organizes the flow of a partial update into explicit steps:
Usage
The following section shows how to apply the flow defined in the conceptual model.
1) Model patchable input
You can represent partial input in two ways.
Option A: Typed command
Option B: From array using PatchInput
PatchValue represents:
- presence (
isPresent()) - incoming value (
value()), potentially normalized
Concrete patch values also expose lightweight named constructors when you want to instantiate them directly:
2) Define fields
You connect the patch with the current state using Field::from(). Each patch represents a PatchValue, not the final
value, so the incoming value may differ in type from the current state.
You can optionally define a comparator:
You can also transform the incoming patch value before comparison and action execution:
Each Field exposes:
isPresent()→ whether the field was provided in the patchisChanged()→ whether the field has a real delta against the current valuevalue()→ incoming valuecurrent()→ current valueeffective()→ incoming value when present, otherwise current valuechanged()→ incoming value when a real change exists, otherwisenulldelta()→ returns the transition (previous → next) if a change exists, ornullotherwise
3) Declare actions
You define what should happen when a combination of fields applies through an Action.
You can also define a custom failure to be rethrown later:
Behaviors
Behaviors define the execution contract through Optional:
required()→ the field must provide a usable valueoptional()→ the field may be absent
By default, a plain Field behaves as required().
Use required() when you want to make that intent explicit, and optional() when absence should be allowed.
Activation rule (when)
when determines whether the action participates in the current patch.
By default, an action applies if at least one field is present.
You can define custom rules:
For the common presence-based cases, you can pass the provided named constructors directly:
If the decision was already resolved elsewhere, you can pass the resulting boolean directly:
If you want to treat when(...) like an inline boolean guard, you can wrap it as a rule:
4) Execute orchestrator
The Orchestrator performs:
- Evaluates
when(presence-based activation) - Validates the contract (
behaviors) - Checks for an effective delta
- Executes
apply()if applicable
execute() returns an ExecutionResult, so you can react to the run outcome:
When a required behavior is not satisfied, execute() throws ActionBehaviorNotSatisfied.
If the action
defined a custom or(...) strategy, you can inspect the failure first and then relaunch it with rethrow().
It includes totals and execution state (total, executed, skipped) plus helper checks and description-based lookups.
Note on current vs patch values
The library does not automatically build a projected state.
If you need the effective value for a field (patch value when present, otherwise current value), use effective():
This keeps action code cleaner while preserving explicit field-level behavior.
Rules
Rules allow you to declaratively define activation conditions (when) through helpers in
src/Rules/functions.php.
present()
Checks whether a field is present in the patch.
all() and any()
Allow composing conditions:
You can also nest rules:
Activation (when)
Advanced details on how to define custom activation rules.
when determines whether the action participates in the current patch.
Field
Comparators
Each Field compares the incoming value against the current value using a comparator.
Default
If none is defined, StrictComparator is used.
- compares strictly by type and value,
- compares dates by exact temporal value,
- throws
ComparisonTypeMismatchif types are not compatible.
NumericComparator
For numeric values and numeric strings.
NumericComparator compares values by numeric meaning instead of raw string or float identity.
Numeric strings are treated as exact input, while native PHP floats are normalized with a significant-digits tolerance before comparison.
This keeps values such as 0.1 + 0.2 and 0.3 equivalent, while still allowing fully explicit numeric strings to remain exact.
DateTimeComparator
For date comparisons with explicit semantics.
LooseComparator
For cases where intentional loose comparison (==) is desired.
ArrayComparator
For recursive array comparisons, with support for injecting an item comparator.
You can also provide a custom comparator for leaf values:
Patch (input)
PatchValue and normalization
Concrete PatchValue implementations can accept flexible inputs and return normalized values.
This keeps normalization at the input boundary, preventing raw values from leaking into the domain.
Playground
The repository includes an executable usage scenario located at playground/playground.php.
Unlike the snippets in the README, this example brings multiple cases together in a single flow:
- multiple
Actioninstances over the same patch, - combination of
required()andoptional(), - use of
whento control activation by presence, - cases with and without effective
delta, - use of current values as fallback,
- a contract failure case (
requiredwithnull).
The scenario is not intended to be minimal. It deliberately groups more logic than usual to expose different behaviors in a single execution.
Run
Additional documentation
You can find more details in the source code as well as in the tests located in tests/.
The tests cover different usage scenarios and can serve as additional reference for understanding the library’s behavior.