Processors reduce the raw results from a collector to one value. Use them when several modules contribute data but the caller needs a clear answer, such as the first available email, a merged list, or a boolean decision.
Processors apply only to collectors. Actions return void, and filters already return their transformed value.
Calling collect('customer.primary_email', $customer) on the same endpoint still returns one raw result per listener. It bypasses processor and renderer configuration. Without a configured processor, process() throws MissingProcessorException. clearProcessor() removes the slot and reports whether one existed. setProcessor() replaces the processor for that collector point.
Use processWith() when the caller needs a different reduction for one invocation. It accepts the same processor instance, callable, or class name as setProcessor(), collects the listeners once, and passes the results and ProcessingContext to that processor. The supplied processor is not stored, and an existing configured processor remains unchanged.
This is useful when the same collector can be viewed in more than one way. For example, an endpoint may normally use a configured processor, while an export or fallback path needs the first available value for one call:
processWith() is part of magdicom/hooksv2.0.0-beta.2. Use it when one call needs a different processor without changing the persistent processor configured for that hook point.
The released built-ins live under Magdicom\Processors and implement ResultProcessor. Each receives (array $results, ProcessingContext $context) and returns its documented value.
Numeric keys are reindexed and array keys are discarded; invalid depth or non-arrays throw
BooleanAndProcessor
Strict booleans
bool
true
Non-booleans throw UnexpectedValueException
BooleanOrProcessor
Strict booleans
bool
false
Non-booleans throw UnexpectedValueException
All built-ins receive the original hook point and invocation arguments through ProcessingContext. They do not add shortcut methods such as first(), last(), merge(), or flatten().
Use FirstProcessor when the first registered contribution wins. It returns the first raw result, or null when no collectors ran. It accepts any result type and has no configuration options.
LastProcessor is useful when later registration should provide the final fallback or override. It returns the last result, or null for an empty list. It accepts any result type and has no options.
FirstNonNullProcessor skips null results until it finds a value. It returns null when every result is null or there are no results. It accepts any result type and has no options.
Use MergeProcessor when each collector returns an array and the caller needs one combined array. It uses PHP’s array_merge() semantics: string keys later in the list overwrite earlier values, while numeric keys are reindexed. An empty result list returns []; a non-array result throws UnexpectedValueException.
Use FlattenProcessor when collectors return nested arrays and the caller needs one list of values. Its constructor accepts depth, defaulting to -1 for unlimited flattening. Depth 0 keeps nested arrays at the current level; non-negative depths limit traversal. A depth below -1 throws InvalidArgumentException. Every top-level result must be an array or processing throws UnexpectedValueException. Flattening discards array keys and reindexes the result.
Use BooleanAndProcessor when every registered rule must approve a decision. Each collector must return a real bool; values are not coerced. It returns false as soon as it sees false, true for an empty result list, and throws UnexpectedValueException for any non-boolean result.
Use BooleanOrProcessor when one approving rule is enough. Results must be real booleans. It returns true as soon as it sees true, false for an empty result list, and throws UnexpectedValueException for any non-boolean result.
setProcessor() accepts a processor instance, a callable, or a class name. A callable receives the raw result array and ProcessingContext and may return any value:
Class-name processors are resolved when process() runs and must implement ResultProcessor; otherwise InvalidProcessorException is thrown. The core NativeResolver creates a class with new $className(). Laravel replaces that resolver with a container-backed resolver, so constructor dependencies can be injected:
The same class-name configuration is shown in both tabs; Laravel’s resolver is what changes how the class is constructed. Custom processor exceptions propagate unchanged.
See renderers for string-specific collector output, and collectors for raw collection semantics.