VOOZH about

URL: https://deepwiki.com/hypervel/validation/4.5-rule-interfaces-and-contracts

⇱ Rule Interfaces and Contracts | hypervel/validation | DeepWiki


Loading...
Menu

Rule Interfaces and Contracts

This page documents the interface contracts that define how validation rules interact with the validation system. These interfaces establish behavioral contracts that rules must fulfill, enabling the Validator to properly execute and contextualize rule logic.

For information about creating rule instances, see Rule Facade and Factory. For concrete rule implementations, see Built-in Rule Objects. For practical guidance on using closures and invokables, see Custom Validation Rules.

Purpose and Scope

The validation system defines several interfaces that establish contracts for rule behavior. These interfaces enable:

  1. Rule execution - Defining how validation logic is invoked
  2. Context injection - Providing rules with access to validation data and validator state
  3. Behavioral classification - Marking rules with special execution characteristics
  4. Dynamic compilation - Allowing rules to transform based on runtime context

The interface system allows rules to declare their capabilities and requirements, which the Validator uses to properly orchestrate validation execution.

Interface Hierarchy

The validation system organizes interfaces into four categories: core execution interfaces, context-aware interfaces, behavioral markers, and advanced transformation interfaces.

Diagram: Rule Interface Taxonomy


Sources: src/InvokableValidationRule.php8-14 src/ClosureValidationRule.php9-11

Core Execution Interfaces

Rule Interface

The Rule interface is the base contract that all rule objects must implement. It defines the fundamental execution contract.

Contract Definition:

MethodSignaturePurpose
passes()passes(string $attribute, mixed $value): boolExecute validation logic and return success status
message()message(): string|arrayReturn validation error message(s) when validation fails

The passes() method receives the attribute name and its value, returning true if validation succeeds or false if it fails. When validation fails, the message() method is called to retrieve error messages. The method can return either a single string or an array of strings for multiple error messages.

Implementation Example:

The ClosureValidationRule adapter implements this interface at src/ClosureValidationRule.php13 providing passes() at src/ClosureValidationRule.php45-56 and message() at src/ClosureValidationRule.php61-64

Sources: src/ClosureValidationRule.php9 src/InvokableValidationRule.php11

InvokableRule and ValidationRule

These interfaces represent two patterns for custom validation logic:

InvokableRule defines a callable contract with the signature:

__invoke(string $attribute, mixed $value, Closure $fail): void

ValidationRule defines an explicit method contract with the signature:

validate(string $attribute, mixed $value, Closure $fail): void

Both interfaces receive a $fail closure that rules invoke to signal validation failure. This closure accepts an attribute name and optional message, enabling flexible error reporting.

Key Difference:

InterfaceMethodUse Case
InvokableRule__invoke()Invokable classes (magic method)
ValidationRulevalidate()Explicit validation method

The InvokableValidationRule adapter detects which interface is implemented and calls the appropriate method at src/InvokableValidationRule.php77-79

Implicit Property:

Both interfaces support an optional $implicit property. When set to true, the rule becomes an ImplicitRule, validated even when the attribute is absent. The InvokableValidationRule::make() method checks this property at src/InvokableValidationRule.php55 to dynamically implement ImplicitRule.

Sources: src/InvokableValidationRule.php10 src/InvokableValidationRule.php12 src/InvokableValidationRule.php55-56 src/InvokableValidationRule.php77-79

Context-Aware Interfaces

Context-aware interfaces allow rules to access broader validation state beyond just the attribute being validated.

DataAwareRule Interface

The DataAwareRule interface enables rules to access the complete dataset under validation.

Contract:

MethodSignaturePurpose
setData()setData(array $data): staticInject the full validation dataset

Rules implementing this interface receive the entire data array being validated, enabling cross-field validation logic. For example, a rule validating a "password confirmation" field needs access to the original "password" field.

Execution Flow:

When the Validator encounters a rule implementing DataAwareRule, it calls setData() before invoking validation. The InvokableValidationRule adapter performs this check at src/InvokableValidationRule.php69-71

Sources: src/InvokableValidationRule.php8 src/InvokableValidationRule.php69-71

ValidatorAwareRule Interface

The ValidatorAwareRule interface provides rules with access to the complete Validator instance.

Contract:

MethodSignaturePurpose
setValidator()setValidator(Validator $validator): staticInject the validator instance

This interface grants rules access to:

  • The complete validation dataset
  • Other validation rules
  • Custom messages and attributes
  • Translator instance
  • Validation state

Rules requiring deep integration with validation state (such as conditional rules or rules that need to trigger additional validations) implement this interface.

Implementation Examples:

Both adapter classes implement ValidatorAwareRule:

The adapters inject the validator into wrapped rules if they also implement ValidatorAwareRule, as seen at src/InvokableValidationRule.php73-75

Diagram: Context Injection Flow


Sources: src/InvokableValidationRule.php69-75 src/ClosureValidationRule.php69-74

Behavioral Marker Interfaces

ImplicitRule Interface

The ImplicitRule interface is a marker interface with no methods. It classifies rules that should execute even when the attribute being validated is absent or null.

Purpose:

By default, the Validator skips validation when an attribute is missing from the dataset. Rules marked as implicit override this behavior, executing regardless of attribute presence. This is essential for rules like required, sometimes, or nullable that specifically validate the presence or absence of data.

Dynamic Implementation:

The InvokableValidationRule::make() method dynamically implements ImplicitRule based on the wrapped rule's $implicit property at src/InvokableValidationRule.php55-56:


This pattern allows invokable rules to declare implicit behavior through a simple property rather than explicit interface implementation.

Sources: src/InvokableValidationRule.php9 src/InvokableValidationRule.php55-56

Advanced Transformation Interfaces

CompilableRules Interface

The CompilableRules interface enables dynamic rule transformation based on runtime context.

Contract:

MethodSignaturePurpose
compile()compile(string $attribute, mixed $value, mixed $data, mixed $context): stdClassTransform rule into executable format

The compile() method receives:

  • $attribute: The attribute being validated
  • $value: The attribute's value
  • $data: The full validation dataset
  • $context: Additional contextual information

The method returns a stdClass object containing the compiled rule structure, which the Validator uses for execution.

Use Cases:

This interface supports:

  • Conditional rules that change behavior based on other field values
  • Dynamic parameter resolution where rule parameters depend on runtime data
  • Wildcard expansion where rules apply to multiple fields based on patterns

Sources: src/Contracts/CompilableRules.php1-15

ValidatesWhenResolved Interface

The ValidatesWhenResolved interface integrates validation with the dependency injection container lifecycle.

Contract:

MethodSignaturePurpose
validateResolved()validateResolved(): voidTrigger validation when container resolves the class

Classes implementing this interface automatically trigger validation when instantiated by the DI container. This enables form request-style validation where the container resolves a request object and validates it before passing it to controllers.

Integration Pattern:

The container's resolution process detects this interface and calls validateResolved() after construction but before returning the instance to the requester. This ensures invalid data never reaches application logic.

Sources: src/Contracts/ValidatesWhenResolved.php1-13

Adapter Implementation Patterns

The validation system uses two adapter classes to wrap custom validation logic into the Rule interface contract.

ClosureValidationRule Adapter

The ClosureValidationRule wraps closure-based validation logic, implementing both Rule and ValidatorAwareRule.

Diagram: ClosureValidationRule Structure


Execution Pattern:

The passes() method at src/ClosureValidationRule.php45-56 executes the closure with a fail callback:

  1. Reset $failed flag to false
  2. Invoke the closure with parameters: $attribute, $value, $fail callback, and $validator
  3. The fail callback sets $failed = true and accumulates messages
  4. Return the inverse of $failed

The closure receives four parameters:

  • $attribute: Attribute name
  • $value: Attribute value
  • $fail: Closure to invoke on failure
  • $validator: The validator instance (for context access)

Sources: src/ClosureValidationRule.php1-75 src/ClosureValidationRule.php45-56

InvokableValidationRule Adapter

The InvokableValidationRule wraps invokable classes, providing more sophisticated context injection.

Diagram: InvokableValidationRule Processing Flow


Sources: src/InvokableValidationRule.php1-125 src/InvokableValidationRule.php53-60 src/InvokableValidationRule.php65-88

Key Differences from ClosureValidationRule:

FeatureClosureValidationRuleInvokableValidationRule
Wrapped TypeClosureInvokableRule or ValidationRule
DataAwareRule SupportNoYes (checks and injects)
Dynamic ImplicitRuleNoYes (via anonymous class)
Method DetectionN/A (always closure)Yes (checks interface type)
Validator Injection to WrappedYes (as parameter)Yes (via setValidator if supported)

Sources: src/InvokableValidationRule.php69-75 src/InvokableValidationRule.php77-79

Interface Detection and Usage Pattern

The Validator orchestrates interface detection to properly contextualize rule execution.

Diagram: Interface Detection Flow in Validator


Sources: src/InvokableValidationRule.php65-88 src/ClosureValidationRule.php45-56

Interface Composition Strategies

Rules commonly implement multiple interfaces to declare comprehensive capabilities.

Common Interface Combinations:

CombinationPurposeExample Use Case
Rule onlyBasic validationSimple format checks
Rule + ImplicitRuleValidate absent attributesRequired rules
Rule + DataAwareRuleCross-field validationConfirmation matching
Rule + ValidatorAwareRuleAccess validator stateConditional rules
Rule + DataAwareRule + ValidatorAwareRuleFull context accessComplex business rules
CompilableRulesDynamic transformationWildcard rules

Implementation Example Pattern:

class MyRule implements Rule, DataAwareRule, ValidatorAwareRule
{
 protected array $data;
 protected Validator $validator;
 
 public function setData(array $data): static { ... }
 public function setValidator(Validator $validator): static { ... }
 public function passes(string $attribute, mixed $value): bool { ... }
 public function message(): string { ... }
}

The Validator checks for each interface using instanceof and invokes the corresponding methods before calling passes(), ensuring the rule has all required context.

Sources: src/InvokableValidationRule.php8-14 src/ClosureValidationRule.php9-11

Summary: Interface Contract Matrix

The following matrix summarizes all interface contracts and their roles:

InterfaceTypeRequired MethodsPurposeChecked By
RuleExecutionpasses(), message()Base validation contractValidator
InvokableRuleExecution__invoke()Callable validationInvokableValidationRule adapter
ValidationRuleExecutionvalidate()Explicit method validationInvokableValidationRule adapter
DataAwareRuleContextsetData()Inject full datasetValidator/adapters
ValidatorAwareRuleContextsetValidator()Inject validator instanceValidator/adapters
ImplicitRuleBehavioralNone (marker)Validate absent attributesValidator
CompilableRulesTransformcompile()Dynamic rule transformationValidator
ValidatesWhenResolvedIntegrationvalidateResolved()Container lifecycle hookDI Container

These interfaces form a cohesive contract system that enables flexible, context-aware validation while maintaining clear separation of concerns between rule logic, execution orchestration, and validation state management.

Sources: src/ClosureValidationRule.php1-75 src/InvokableValidationRule.php1-125 src/Contracts/CompilableRules.php1-15 src/Contracts/ValidatesWhenResolved.php1-13