class DataValidationCompiler

Constants

protected PRESENCE_RULES

protected INFERRED_RULE_TYPES

The attribute type of each inferred rule, which a declared attribute of that type replaces.

Methods

__construct(DataClassRepository $dataClasses, Container $container, RuleDenormalizer $ruleDenormalizer, RuleNormalizer $ruleNormalizer, DataConfig $config)

Create a data validation compiler.

compile(ConstructionState $state)

Compile validation for one filled data graph.

compileCollection(ConstructionState $state, string $dataClass)

Compile validation for one filled root data collection.

array
preservedPaths(ValidationAccumulator $accumulator)

Get the paths restored after validation.

void
compileNode(string $class, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass, bool $observed = true)

Compile one data node into the root rule graph.

void
compileDataIterable(DataProperty $property, string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile nested rules for one data iterable.

void
compileDataIterableValues(string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile one data iterable from its current structure path.

compileUniformDynamicIterable(string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile dynamic items at one wildcard path when their complete output matches.

array
propertyRules(DataProperty $property, ValidationPath $nodePath, ValidationContext|null $context, ValidationPath $propertyPath, bool $hasValue, mixed $value, ConstructionState $state, string|Enum|null $typeRule, bool $receivesDataCollection, bool $inferredRequired, Closure $resolveField)

Build the rules for one property: inferred presence and type rules, then declared attributes.

array
declaredRuleAttributes(DataProperty $property)

Get the fresh validation attributes declared on a property.

array
inferRules(DataProperty $property, string|object|null $typeRule, bool $hasPresenceRule, bool $receivesDataCollection, bool $hasValue)

Infer fixed presence and type rules for one property.

applyRuleInferrers(DataProperty $property, array $attributes, array $inferredRules, ValidationContext $context, ConstructionState $state)

Run the configured rule inferrers over one property's inferred and attribute rules.

array
resolveRuleInferrers()

Resolve the configured rule inferrers for one compilation.

void
applyClassRules(DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationContext|null $context, ValidationPath $structuralPath, ValidationAccumulator $accumulator, bool $observed, Closure $resolveField)

Apply class-owned rule replacements in PHP property-name space.

array
collapseTranslatedRulePaths(array $paths, ValidationAccumulator $accumulator)

Collapse concrete translations onto an existing authoritative wildcard rule.

void
applyClassMessagesAndAttributes(DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $observed)

Apply class-owned messages and attribute labels in PHP property-name space.

array
callArrayLifecycleMethod(DataClass $dataClass, string $method, array $parameters = [])

Invoke one array-returning validation lifecycle method.

string
resolveFieldReference(FieldReference $reference, ValidationPath $path, DataClass $dataClass, DataClass|null $rootDataClass, bool $mapPropertyNames)

Resolve a field reference's property names to input names.

array
translateRulePaths(string $key, DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, bool $observed, bool $allowsRuleSuffix = false)

Translate a class rule key to its observed wire paths.

array
translateRuleSegments(array $segments, int $offset, DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, bool $observed, bool $allowsRuleSuffix = false)

Recursively translate class-rule segments through Data metadata.

array
finishedValuePaths(ValidationPath $path, ValidationPath $structuralPath, array $segments, int $offset, bool $allowsRuleSuffix)

Translate the rest of a key that reaches a finished value.

appendUnmappedSegments(ValidationPath $path, array $segments, int $offset)

Append rule segments that no longer describe Data properties.

void
appendStructuralMarkers(ValidationAccumulator $accumulator, array $payload)

Append wildcard identity markers after every rule replacement is complete.

bool
hasDistinctRule(array $rules)

Determine if a rule list contains a distinct rule.

array
mergeRules(array $rules, array $additionalRules)

Merge rule lists without duplicating identical string rules.

bool
hasPresenceRule(array $rules)

Determine if a rule list explicitly controls field presence.

string|null
ruleKeyword(mixed $rule)

Get the keyword of a string or structured validation rule.

bool
usesDynamicRules(string $dataClass, ConstructionState $state)

Determine if item rules can differ across one collection.

string|Enum|null
primitiveRule(DataProperty $property)

Get one unambiguous type validation rule.

string|Enum|null
typeRuleFor(NamedType $type)

Get the type rule for one declared named type.

string|Enum|null
inferredTypeRule(DataProperty $property, bool $hasValue, mixed $value, NamedType|null $dataType)

Get the inferred type rule for one property value.

string|int
wireKey(DataProperty $property, ConstructionState $state, bool $observed)

Get the wire key selected during Fill or its canonical fallback.

NamedType|null
receivingDataType(DataProperty $property, ConstructionState $state, bool $hasValue, mixed $value)

Get the data object or data collection type that receives a property's value on the current node.

void
recordAuxiliaryPath(DataProperty $property, ValidationPath $path, ValidationAccumulator $accumulator)

Record an exact field or opaque subtree excluded from rule compilation.

bool
canContainDescendants(DataProperty $property)

Determine if a skipped property can contain nested input.

bool
hasUnstructuredDescendants(DataProperty $property)

Determine if a validated property has no recursive schema.

bool
isUnstructuredObject(NamedType $type)

Determine if a named object type has no Data-owned child schema.

Details

at line 82
__construct(DataClassRepository $dataClasses, Container $container, RuleDenormalizer $ruleDenormalizer, RuleNormalizer $ruleNormalizer, DataConfig $config)

Create a data validation compiler.

Parameters

DataClassRepository $dataClasses
Container $container
RuleDenormalizer $ruleDenormalizer
RuleNormalizer $ruleNormalizer
DataConfig $config

at line 94
CompiledValidation compile(ConstructionState $state)

Compile validation for one filled data graph.

Parameters

ConstructionState $state

Return Value

CompiledValidation

at line 132
CompiledValidation compileCollection(ConstructionState $state, string $dataClass)

Compile validation for one filled root data collection.

Parameters

ConstructionState $state
string $dataClass

Return Value

CompiledValidation

at line 175
protected array preservedPaths(ValidationAccumulator $accumulator)

Get the paths restored after validation.

A constructor input is restored only when no compiled rule applies to it or to anything beneath it; otherwise the validated result owns it.

Parameters

ValidationAccumulator $accumulator

Return Value

array

at line 219
protected void compileNode(string $class, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass, bool $observed = true)

Compile one data node into the root rule graph.

Parameters

string $class
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
ValidationAccumulator $accumulator
array $lifecycleDeclarations
bool $compileUnknownFields
DataClass|null $rootDataClass
bool $observed

Return Value

void

at line 463
protected void compileDataIterable(DataProperty $property, string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile nested rules for one data iterable.

Parameters

DataProperty $property
string $dataClass
array $values
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
ValidationAccumulator $accumulator
array $lifecycleDeclarations
bool $compileUnknownFields
DataClass|null $rootDataClass

Return Value

void

at line 502
protected void compileDataIterableValues(string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile one data iterable from its current structure path.

Parameters

string $dataClass
array $values
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
ValidationAccumulator $accumulator
array $lifecycleDeclarations
bool $compileUnknownFields
DataClass|null $rootDataClass

Return Value

void

at line 635
protected ValidationAccumulator|null compileUniformDynamicIterable(string $dataClass, array $values, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, array $lifecycleDeclarations, bool $compileUnknownFields, DataClass|null $rootDataClass)

Compile dynamic items at one wildcard path when their complete output matches.

Parameters

string $dataClass
array $values
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
array $lifecycleDeclarations
bool $compileUnknownFields
DataClass|null $rootDataClass

Return Value

ValidationAccumulator|null

at line 688
protected array propertyRules(DataProperty $property, ValidationPath $nodePath, ValidationContext|null $context, ValidationPath $propertyPath, bool $hasValue, mixed $value, ConstructionState $state, string|Enum|null $typeRule, bool $receivesDataCollection, bool $inferredRequired, Closure $resolveField)

Build the rules for one property: inferred presence and type rules, then declared attributes.

Parameters

DataProperty $property
ValidationPath $nodePath
ValidationContext|null $context

the node's context, present when class rules or configured inferrers use it

ValidationPath $propertyPath
bool $hasValue
mixed $value
ConstructionState $state
string|Enum|null $typeRule
bool $receivesDataCollection
bool $inferredRequired
Closure $resolveField

Return Value

array

at line 815
protected array declaredRuleAttributes(DataProperty $property)

Get the fresh validation attributes declared on a property.

A Rule attribute's rules become typed attributes where possible, so they replace inferred rules of their type.

Parameters

DataProperty $property

Return Value

array

at line 838
protected array inferRules(DataProperty $property, string|object|null $typeRule, bool $hasPresenceRule, bool $receivesDataCollection, bool $hasValue)

Infer fixed presence and type rules for one property.

Parameters

DataProperty $property
string|object|null $typeRule

a rule name, or a rule object used as given

bool $hasPresenceRule
bool $receivesDataCollection
bool $hasValue

Return Value

array

at line 885
protected PropertyRules applyRuleInferrers(DataProperty $property, array $attributes, array $inferredRules, ValidationContext $context, ConstructionState $state)

Run the configured rule inferrers over one property's inferred and attribute rules.

Declared attributes follow the inferred rules and replace inferred rules of the same type.

Parameters

DataProperty $property
array $attributes
array $inferredRules
ValidationContext $context
ConstructionState $state

Return Value

PropertyRules

at line 917
protected array resolveRuleInferrers()

Resolve the configured rule inferrers for one compilation.

They are resolved per compilation, so scoped inferrers follow the current coroutine.

Return Value

array

at line 934
protected void applyClassRules(DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationContext|null $context, ValidationPath $structuralPath, ValidationAccumulator $accumulator, bool $observed, Closure $resolveField)

Apply class-owned rule replacements in PHP property-name space.

Parameters

DataClass $dataClass
ConstructionState $state
ValidationPath $path
ValidationContext|null $context
ValidationPath $structuralPath
ValidationAccumulator $accumulator
bool $observed
Closure $resolveField

Return Value

void

at line 1025
protected array collapseTranslatedRulePaths(array $paths, ValidationAccumulator $accumulator)

Collapse concrete translations onto an existing authoritative wildcard rule.

Parameters

array $paths
ValidationAccumulator $accumulator

Return Value

array

at line 1053
protected void applyClassMessagesAndAttributes(DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, ValidationAccumulator $accumulator, array $lifecycleDeclarations, bool $observed)

Apply class-owned messages and attribute labels in PHP property-name space.

Parameters

DataClass $dataClass
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
ValidationAccumulator $accumulator
array $lifecycleDeclarations
bool $observed

Return Value

void

at line 1137
protected array callArrayLifecycleMethod(DataClass $dataClass, string $method, array $parameters = [])

Invoke one array-returning validation lifecycle method.

Parameters

DataClass $dataClass
string $method
array $parameters

Return Value

array

at line 1164
protected string resolveFieldReference(FieldReference $reference, ValidationPath $path, DataClass $dataClass, DataClass|null $rootDataClass, bool $mapPropertyNames)

Resolve a field reference's property names to input names.

Unlike rule keys, references are not filtered, since a condition may read input that has no rules.

Parameters

FieldReference $reference
ValidationPath $path
DataClass $dataClass
DataClass|null $rootDataClass
bool $mapPropertyNames

Return Value

string

at line 1223
protected array translateRulePaths(string $key, DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, bool $observed, bool $allowsRuleSuffix = false)

Translate a class rule key to its observed wire paths.

Parameters

string $key
DataClass $dataClass
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
bool $observed
bool $allowsRuleSuffix

whether the key may end with a rule, as a string message key may

Return Value

array

at line 1250
protected array translateRuleSegments(array $segments, int $offset, DataClass $dataClass, ConstructionState $state, ValidationPath $path, ValidationPath $structuralPath, bool $observed, bool $allowsRuleSuffix = false)

Recursively translate class-rule segments through Data metadata.

Parameters

array $segments
int $offset
DataClass $dataClass
ConstructionState $state
ValidationPath $path
ValidationPath $structuralPath
bool $observed
bool $allowsRuleSuffix

Return Value

array

at line 1469
protected array finishedValuePaths(ValidationPath $path, ValidationPath $structuralPath, array $segments, int $offset, bool $allowsRuleSuffix)

Translate the rest of a key that reaches a finished value.

A finished value is not validated internally, so only a key ending at the value applies, or a message key ending with one rule for it.

Parameters

ValidationPath $path
ValidationPath $structuralPath
array $segments
int $offset
bool $allowsRuleSuffix

Return Value

array

at line 1493
protected ValidationPath appendUnmappedSegments(ValidationPath $path, array $segments, int $offset)

Append rule segments that no longer describe Data properties.

Parameters

ValidationPath $path
array $segments
int $offset

Return Value

ValidationPath

at line 1510
protected void appendStructuralMarkers(ValidationAccumulator $accumulator, array $payload)

Append wildcard identity markers after every rule replacement is complete.

Parameters

ValidationAccumulator $accumulator
array $payload

Return Value

void

at line 1588
protected bool hasDistinctRule(array $rules)

Determine if a rule list contains a distinct rule.

Parameters

array $rules

Return Value

bool

at line 1610
protected array mergeRules(array $rules, array $additionalRules)

Merge rule lists without duplicating identical string rules.

Parameters

array $rules
array $additionalRules

Return Value

array

at line 1628
protected bool hasPresenceRule(array $rules)

Determine if a rule list explicitly controls field presence.

Parameters

array $rules

Return Value

bool

at line 1646
protected string|null ruleKeyword(mixed $rule)

Get the keyword of a string or structured validation rule.

Parameters

mixed $rule

Return Value

string|null

at line 1660
protected bool usesDynamicRules(string $dataClass, ConstructionState $state)

Determine if item rules can differ across one collection.

Parameters

string $dataClass
ConstructionState $state

Return Value

bool

at line 1675
protected string|Enum|null primitiveRule(DataProperty $property)

Get one unambiguous type validation rule.

Parameters

DataProperty $property

Return Value

string|Enum|null

at line 1695
protected string|Enum|null typeRuleFor(NamedType $type)

Get the type rule for one declared named type.

Parameters

NamedType $type

Return Value

string|Enum|null

at line 1717
protected string|Enum|null inferredTypeRule(DataProperty $property, bool $hasValue, mixed $value, NamedType|null $dataType)

Get the inferred type rule for one property value.

A union value uses the rule of the declared type that holds it, so numeric size rules keep their numeric meaning. Other values use the declaration's rule.

Parameters

DataProperty $property
bool $hasValue
mixed $value
NamedType|null $dataType

Return Value

string|Enum|null

at line 1744
protected string|int wireKey(DataProperty $property, ConstructionState $state, bool $observed)

Get the wire key selected during Fill or its canonical fallback.

Parameters

DataProperty $property
ConstructionState $state
bool $observed

Return Value

string|int

at line 1764
protected NamedType|null receivingDataType(DataProperty $property, ConstructionState $state, bool $hasValue, mixed $value)

Get the data object or data collection type that receives a property's value on the current node.

A union value uses the type Fill selected from the raw value, because Fill replaced a data value with its normalized input. Without a value, the declaration's one data type applies.

Parameters

DataProperty $property
ConstructionState $state
bool $hasValue
mixed $value

Return Value

NamedType|null

at line 1782
protected void recordAuxiliaryPath(DataProperty $property, ValidationPath $path, ValidationAccumulator $accumulator)

Record an exact field or opaque subtree excluded from rule compilation.

Parameters

DataProperty $property
ValidationPath $path
ValidationAccumulator $accumulator

Return Value

void

at line 1797
protected bool canContainDescendants(DataProperty $property)

Determine if a skipped property can contain nested input.

Parameters

DataProperty $property

Return Value

bool

at line 1818
protected bool hasUnstructuredDescendants(DataProperty $property)

Determine if a validated property has no recursive schema.

Parameters

DataProperty $property

Return Value

bool

at line 1836
protected bool isUnstructuredObject(NamedType $type)

Determine if a named object type has no Data-owned child schema.

Parameters

NamedType $type

Return Value

bool