Composing Rule Sets

The library offers multiple methods for composing rule sets, giving you control over how you build your validation logic.

Logical Operators

  • AndX: Use this instruction when you want all of a set of rules to pass for a given value.
  • OrX: Use this instruction when you want at least one of a set of rules to pass for a given value.

Example:

use Norvica\Validation\Instruction\AndX;
use Norvica\Validation\Instruction\OrX;
use Norvica\Validation\Rule\Email;
use Norvica\Validation\Rule\Uuid;

// Value must be either a valid email OR a valid UUID
$validator->validate('[email protected]', new OrX(new Email(), new Uuid())); // will pass
$validator->validate('e2575f66-47ea-4152-ba1e-0ed63dec1e4f', new OrX(new Email(), new Uuid())); // will pass

// Value must be BOTH a valid email AND should not exist in your system (your imaginary custom rule)
$validator->validate('[email protected]', new AndX(new Email(), new Unique(table: 'users', column: 'username')));

Optional Values

Use the OptionalX instruction to mark a rule as optional. This prevents validation errors if the corresponding property is not present in your data or if its value is null.

use Norvica\Validation\Instruction\OptionalX;
use Norvica\Validation\Rule\Url;

$data = [];  // or `['website' => null]`

// without `OptionalX`: would throw an exception if 'website' is missing or `null`
$validator->validate(value: $data, rules: ['website' => new Url()]);

// with `OptionalX`: validation of 'website' is skipped if missing or `null`
$validator->validate(value: $data, rules: ['website' => new OptionalX(new Url())]);

Dynamic Rules

For more complex scenarios, create rule sets dynamically based on data. This allows fine-grained control over which rules are applied.

class YourRulesRegistry
{
    public static function profileRules(array $data): array
    {
        $rules = [];
        if (!empty($data['website'])) {
            $rules['website'] = new Url();
        }

        return $rules;
    }
}

$data = [];  // or `['website' => null]`

// compose rules based on provided data
$rules = YourRulesRegistry::profileRules($data);

// validate
$validator->validate(value: $data, rules: $rules);