aegisora/any-of-rule

Any Of Rule provides a simple, rule-based logical OR validation implementation for the Aegisora ecosystem.

Maintainers

Package info

github.com/Aegisora/any-of-rule

pkg:composer/aegisora/any-of-rule

Transparency log

Statistics

Installs: 18

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-08-14 14:48 UTC

This package is auto-updated.

Last update: 2026-08-14 14:50:44 UTC


README

Latest Version Total Downloads Code Coverage Badge Software License PHPStan Badge

Any Of Rule provides a simple, rule-based logical OR validation implementation for the Aegisora ecosystem.

It is built on top of aegisora/rule-contract and follows its strict validation architecture, ensuring consistent and predictable behavior across applications.

This rule is useful whenever a value is acceptable if it satisfies at least one of several alternative rules โ€” for example, accepting either an email or a phone number, matching one of several allowed formats, or passing any one of a set of business constraints.

๐Ÿ“‘ Table of Contents

โœจ Features

  • ๐Ÿ”น Lightweight and dependency-free except aegisora/rule-contract
  • ๐Ÿ”น Validates that a value satisfies at least one of several rules (logical OR)
  • ๐Ÿ”น Short-circuits on the first rule that passes
  • ๐Ÿ”น Accepts a RuleContextCollection of (rule, context) pairs
  • ๐Ÿ”น Rejects a non-collection or an empty collection as an invalid context
  • ๐Ÿ”น Fully compatible with Aegisora validation pipeline
  • ๐Ÿ”น Strict Context โ†’ Result validation flow
  • ๐Ÿ”น No raw booleans โ€” only structured results
  • ๐Ÿ”น Safe execution via base Rule abstraction
  • ๐Ÿ”น Simple factory API (create)
  • ๐Ÿ”น Ready to use out of the box

๐Ÿ“ฆ Installation

composer require aegisora/any-of-rule

๐Ÿš€ Core Concept

This package implements a single validation rule:

  • accepts a RuleContextCollection via Context
  • runs each inner rule against its own context
  • passes as soon as any inner rule reports a valid result
  • returns a standardized Result

Under the hood it wraps the common boilerplate:

foreach ($ruleContextCollection as $ruleContext) {
    if ($ruleContext->getRule()->validate($ruleContext->getContext())->isValid()) {
        // at least one rule passed
    }
}

into a reusable rule that reports its outcome through a Result object instead of a raw boolean.

๐Ÿ—๏ธ Basic Usage

use Aegisora\RuleContract\Models\Context;
use Aegisora\RuleContract\Models\RuleContext;
use Aegisora\RuleContract\Models\RuleContextCollection;
use Aegisora\Rules\AnyOfRule;

$result = AnyOfRule::create()->validate(
    Context::create(
        RuleContextCollection::create(
            RuleContext::create($emailRule, Context::create($value)),
            RuleContext::create($phoneRule, Context::create($value))
        )
    )
);

if ($result->isValid()) {
    // value satisfied at least one rule
} else {
    // value satisfied none of the rules
}

โœ… Valid vs Invalid

The rule passes when at least one inner rule is valid and fails only when every inner rule is invalid.

Valid

$rule = AnyOfRule::create();

// passes โ€” the first rule is valid
$rule->validate(
    Context::create(
        RuleContextCollection::create(
            RuleContext::create($validRule, Context::create($value))
        )
    )
);

// passes โ€” at least one rule in the collection is valid
$rule->validate(
    Context::create(
        RuleContextCollection::create(
            RuleContext::create($invalidRule, Context::create($value)),
            RuleContext::create($validRule, Context::create($value))
        )
    )
);

Invalid

$rule = AnyOfRule::create();

// fails โ€” every rule in the collection is invalid
$rule->validate(
    Context::create(
        RuleContextCollection::create(
            RuleContext::create($invalidRule, Context::create($value)),
            RuleContext::create($invalidRule, Context::create($value))
        )
    )
);

๐Ÿงช Validation Result

If at least one inner rule is valid, the rule returns a valid result.

$result->isValid(); // true

If every inner rule is invalid, the rule returns an invalid result.

$result->isValid(); // false
$result->getFailedRuleCode(); // any_of_rule

If the context value is not a RuleContextCollection, or the collection is empty, the rule throws:

Aegisora\RuleContract\Exceptions\InvalidRuleContextException

๐Ÿ”— Guardian Usage

This rule can be used together with aegisora/guardian to build fluent validation pipelines.

use Aegisora\Guardian\Guardian;
use Aegisora\RuleContract\Models\Context;
use Aegisora\RuleContract\Models\RuleContext;
use Aegisora\RuleContract\Models\RuleContextCollection;
use Aegisora\Rules\AnyOfRule;
use App\Exceptions\InvalidValueException;

$guardian = new Guardian();

$guardian
    ->that(
        RuleContextCollection::create(
            RuleContext::create($emailRule, Context::create($value)),
            RuleContext::create($phoneRule, Context::create($value))
        )
    )
    ->must(AnyOfRule::create(), new InvalidValueException())
    ->validate();

If none of the rules pass, Guardian throws the provided domain exception.

๐Ÿงญ Real-World Examples

Any Of Rule is useful whenever a value has several acceptable alternatives.

Examples

Contact:

accept the value if it is a valid email OR a valid phone number
Identifiers:

accept either a UUID OR a numeric id
Formats:

allow a date in one of several supported formats
Access:

grant access if any one of several permission rules is satisfied

๐Ÿงฉ Factory Methods

AnyOfRule::create();

  • no arguments โ€” creates a new rule instance

AnyOfRule::create()->validate($context);

  • $context โ€” Context wrapping the RuleContextCollection to validate

๐Ÿ›๏ธ Architecture

This package relies on aegisora/rule-contract.

Flow:

  1. validate() is called
  2. Context is passed in
  3. The RuleContextCollection is extracted from context (non-collections and empty collections raise InvalidRuleContextException)
  4. Each RuleContext is validated against its own Context
  5. The rule passes on the first valid result and fails if none are valid
  6. Result is returned โ€” valid on success, invalid with the any_of_rule code on failure

All logic is safely handled by Rule contract.

โš–๏ธ License

This package is open-source and licensed under the MIT License. See the LICENSE for details.

๐ŸŒฑ Contributing

Contributions are welcome and greatly appreciated! See the CONTRIBUTING for details.

๐ŸŒŸ Support

If you find this project useful, please consider giving it a star on GitHub!

It helps the project grow and motivates further development.