DataCreator
class DataCreator
Creates data objects by filling, validating, and constructing them over one ConstructionState.
Fill normalizes and prepares the input and records each decision that depends on the raw input: selected union types, wire-key mappings, morph classes, automatic lazy and paginator sources, and deferred named factories. Validation and construction read those records instead of deciding again from normalized values. When a validation hook replaces a value, reconciliation prepares it again.
Beneath a property with an explicit cast, validated input is still normalized and prepared, but named factories and object construction wait until the cast declines the value.
Properties
| protected CreationContext> | $defaultContexts | ||
| protected CreationExtensions | $emptyExtensions | The empty extensions each operation clones; it is never used directly. |
Methods
Create a data creator.
Create a fresh construction factory for a data class.
Create a data object through one fixed construction operation.
Validate a payload without casting or construction.
Get validation rules for a payload without running the Validator.
Resolve one deferred automatic lazy property.
Collect data objects through one root operation.
Create typed items through one internal collection operation.
Collect a deferred source without enumerating it.
Create a deferred item collection with one shared operation memo.
Create one nested node without restarting root validation or authorization.
Collect an eager source through one Fill and validation graph.
Create every eager item through one Fill and validation graph.
Batch relations explicitly selected by data properties.
Fill every eager root collection item into one construction state.
Cast and instantiate every eager root collection item.
Run the fixed operation through its selected exit point.
Normalize and fill one data node into the root construction state.
Fill one post-factory value through the general construction path.
Create one fixed array node without entering the general Fill path.
Fill one node introduced or changed by a validation payload hook.
Write the raw input of constructor parameters that have no public data property.
Write one resolved data node and recursively fill its declared children.
Write one resolved property and recursively fill its declared children.
Apply one root payload-hook stage and reconcile changed selections.
Reconcile changed eager root collection items.
Reconcile one changed assembled data node without replaying prepare hooks.
Match the named factory again for a node beneath a cast whose input a validation hook replaced.
Reconcile one changed property selection.
Reconcile one changed typed data iterable.
Cast and instantiate the node at the current construction path.
Build one automatic lazy property around the ordinary cast path.
Cast one supplied property value.
Cast every item in one declared data iterable.
Cast every item in one declared non-data iterable.
Cast one declared iterable item.
Build the declared property values a user cast receives for the current node.
Determine if casting a property can reach a user cast that receives the declared values.
Determine if casts own the construction of a data object or collection property.
Resolve every declared property against the normalized sources.
Resolve one property from the last source that supplies it, with mapped-key precedence inside each source.
Resolve the raw source aligned with one automatic lazy property.
Match one property against one normalized source.
Get the effective input key for one property.
Pass each normalized source through the class's prepareForPipeline() method.
Build the prepare-data hook input from the values property resolution selects.
Merge the array sources, with later sources taking precedence.
Merge the keys of every normalized source for unknown-field detection.
Project a non-enumerable normalized source into declared wire keys.
Recursively fill only values absent from the earlier source.
Find the first compatible named object factory.
Create the object with a matching named factory, or list the payloads for ordinary creation.
Find the first compatible named collection factory.
Invoke one matched named factory without method-binding interception.
Invoke one matched named object factory, which must return the requested object.
Resolve the concrete class selected by an abstract property's discriminator.
Materialize a property default only when morph selection requires it.
Determine if an automatic lazy property needs deferred Fill replay.
Determine if a property uses model relation automatic lazy loading.
Select and record the declared type that receives a union value.
Retain source metadata for one declared paginator property.
Convert an eager iterable to its keyed values.
Details
at line 82
__construct(Container $container, DataClassRepository $dataClasses, DataConfig $config, DataCollectableFactory $dataCollectables, DataInstantiator $instantiator, DataValidator $validator)
Create a data creator.
at line 103
CreationContextFactory
factory(string $class, CreationContext|null $creationContext = null)
Create a fresh construction factory for a data class.
A given creation context supplies its options, but not its hooks, which belong to its own operation.
at line 136
BaseData
create(string $class, CreationContext $context, mixed ...$payloads)
Create a data object through one fixed construction operation.
at line 154
array
validate(string $class, CreationContext $context, array $payloads)
Validate a payload without casting or construction.
at line 172
array
getValidationRules(string $class, CreationContext $context, array $payloads)
Get validation rules for a payload without running the Validator.
at line 188
mixed
resolveAutoLazyProperty(string $propertyName, mixed $value, ConstructionState $state, AutoLazyReplayMode|null $replay, array|null $castInputs = null)
| internal |
Resolve one deferred automatic lazy property.
at line 232
array|DataCollection|PaginatedDataCollection|CursorPaginatedDataCollection|Enumerable|AbstractPaginator|Paginator|AbstractCursorPaginator|CursorPaginator|LazyCollection|Collection
collect(string $class, CreationContext $context, mixed $items, string|null $into = null)
Collect data objects through one root operation.
at line 278
Enumerable
collectItems(string $class, CreationContext $context, mixed $items)
| internal |
Create typed items through one internal collection operation.
at line 321
protected array|DataCollection|PaginatedDataCollection|CursorPaginatedDataCollection|Enumerable|AbstractPaginator|Paginator|AbstractCursorPaginator|CursorPaginator|LazyCollection|Collection
collectLazy(string $class, CreationContext $context, LazyCollection $source, string|null $into)
Collect a deferred source without enumerating it.
at line 349
protected LazyCollection
deferCollectionItems(string $class, CreationContext $context, LazyCollection $source)
Create a deferred item collection with one shared operation memo.
at line 378
protected BaseData
createUnvalidatedNode(string $class, CreationContext $context, array $payloads, CreationExtensions $extensions)
Create one nested node without restarting root validation or authorization.
at line 439
protected array|DataCollection|PaginatedDataCollection|CursorPaginatedDataCollection|Enumerable|AbstractPaginator|Paginator|AbstractCursorPaginator|CursorPaginator|LazyCollection|Collection
collectEager(string $class, CreationContext $context, mixed $source, array $values, string|null $into, bool $shouldValidate)
Collect an eager source through one Fill and validation graph.
at line 475
protected array
createEagerCollectionItems(string $class, CreationContext $context, mixed $source, array $values, bool $shouldValidate)
Create every eager item through one Fill and validation graph.
at line 541
protected void
loadMissingRelations(string $class, Collection $models)
Batch relations explicitly selected by data properties.
at line 571
protected void
fillCollectionItems(string $class, array $values, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate)
Fill every eager root collection item into one construction state.
at line 613
protected array
castCollectionItems(string $class, ConstructionState $state, CreationExtensions $extensions)
Cast and instantiate every eager root collection item.
at line 646
protected BaseData|array
execute(string $class, CreationContext $context, array $payloads)
Run the fixed operation through its selected exit point.
at line 738
protected BaseData|null
fillNode(string $class, array $payloads, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Normalize and fill one data node into the root construction state.
Factory matching consumes caller keys. Every later source-indexed operation receives a list.
at line 806
protected bool
fillGeneralNode(DataClass $dataClass, array $payloads, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Fill one post-factory value through the general construction path.
at line 918
protected BaseData|null
tryCreateDirectArrayNode(DataClass $dataClass, array $payloads, CreationContext $context, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Create one fixed array node without entering the general Fill path.
The complete node is checked before conversion so a later miss cannot repeat a nested factory, hook, or constructor when the caller enters general Fill.
at line 1051
protected BaseData|null
fillHookNode(string $class, mixed $payload, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Fill one node introduced or changed by a validation payload hook.
at line 1118
protected void
fillConstructorInputs(DataClass $dataClass, array $sources, ConstructionState $state)
Write the raw input of constructor parameters that have no public data property.
at line 1139
protected void
fillResolvedProperties(DataClass $dataClass, array $resolvedProperties, array $sources, array $payloads, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules, bool $fromValidationHook)
Write one resolved data node and recursively fill its declared children.
at line 1258
protected void
fillResolvedProperty(DataProperty $property, array $inputPath, mixed $value, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules, bool $fromValidationHook)
Write one resolved property and recursively fill its declared children.
at line 1441
protected void
applyPayloadHooks(string $class, array $hooks, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules, bool $reconcile = true, bool $collection = false)
Apply one root payload-hook stage and reconcile changed selections.
at line 1496
protected void
reconcileCollection(string $class, array $previousPayload, array $payload, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Reconcile changed eager root collection items.
at line 1578
protected void
reconcileNode(string $declaredClass, array $previousPayload, array $payload, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Reconcile one changed assembled data node without replaying prepare hooks.
at line 1686
protected void
rematchDeferredFactory(DataClass $dataClass, array $payload, ConstructionState $state)
Match the named factory again for a node beneath a cast whose input a validation hook replaced.
A recorded match holds the earlier input, so it no longer describes the node.
at line 1703
protected void
reconcileProperty(DataProperty $property, mixed $previousValue, mixed $value, string|int $wireKey, array $payload, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Reconcile one changed property selection.
at line 1898
protected void
reconcileDataIterable(DataProperty $property, NamedType $type, mixed $previousValue, mixed $value, array $inputPath, ConstructionState $state, CreationExtensions $extensions, bool $shouldValidate, bool $compilesRules)
Reconcile one changed typed data iterable.
at line 2013
protected BaseData
castAndInstantiateNode(ConstructionState $state, CreationExtensions $extensions)
Cast and instantiate the node at the current construction path.
at line 2198
protected mixed
buildAutoLazy(DataProperty $property, mixed $value, ConstructionState $state, CreationExtensions $extensions, array $properties = [], array|null $castInputs = null)
Build one automatic lazy property around the ordinary cast path.
at line 2251
protected mixed
castProperty(DataProperty $property, mixed $value, ConstructionState $state, CreationExtensions $extensions, array $properties = [], array|null $castInputs = null)
Cast one supplied property value.
at line 2440
protected mixed
castDataIterable(DataProperty $property, NamedType $type, mixed $value, ConstructionState $state, CreationExtensions $extensions)
Cast every item in one declared data iterable.
at line 2517
protected mixed
castTypedIterable(DataProperty $property, NamedType $type, mixed $value, ConstructionState $state, CreationExtensions $extensions, array $casts, array $properties, array|null $castInputs)
Cast every item in one declared non-data iterable.
at line 2591
protected mixed
castIterableItem(DataProperty $property, Type $type, mixed $value, ConstructionState $state, CreationExtensions $extensions, array $casts, array $castInputs)
Cast one declared iterable item.
at line 2679
protected array
castInputs(ConstructionState $state, array $properties)
Build the declared property values a user cast receives for the current node.
Values already cast for this node are used as they are, other supplied input stays raw, and absent properties resolve as construction would resolve them. Contextual constructor values are excluded.
at line 2718
protected bool
requiresCastInputs(DataProperty $property, CreationContext $context, CreationExtensions $extensions)
Determine if casting a property can reach a user cast that receives the declared values.
at line 2747
protected bool
hasCastableType(Type $type)
Determine if a type accepts a Castable class.
at line 2764
protected bool
isCastOwned(DataProperty $property, CreationContext $context, CreationExtensions $extensions)
Determine if casts own the construction of a data object or collection property.
Casts receive such a value before any of its objects are built. Under validation it is prepared and validated first, while its named factories and constructors wait until the casts decline it.
at line 2777
protected array
resolveProperties(DataClass $dataClass, array $sources, CreationContext $context, bool $compilesRules)
Resolve every declared property against the normalized sources.
at line 2798
protected array
resolveProperty(array $sources, DataProperty $property, CreationContext $context, bool $compilesRules)
Resolve one property from the last source that supplies it, with mapped-key precedence inside each source.
at line 2833
protected mixed
resolveAutoLazySource(DataProperty $property, array $sources, array $payloads, CreationContext $context, bool $compilesRules)
Resolve the raw source aligned with one automatic lazy property.
at line 2871
protected array|null
matchPropertySource(array|Normalized $source, DataProperty $property, string|int $mappedKey, bool $compilesRules)
Match one property against one normalized source.
Validated input must use the mapped name, as its rules do. Otherwise, as upstream, the PHP property name is read when the mapped name is missing.
at line 2897
protected string|int
propertyInputKey(DataProperty $property, CreationContext $context)
Get the effective input key for one property.
at line 2914
protected array
prepareSourcesForPipeline(DataClass $dataClass, array $sources, CreationContext $context, bool $compilesRules)
Pass each normalized source through the class's prepareForPipeline() method.
A model source is first projected to its declared properties, as upstream does.
at line 2942
protected array
prepareDataInput(DataClass $dataClass, array $sources, array $resolvedProperties, CreationContext $context, bool $compilesRules)
Build the prepare-data hook input from the values property resolution selects.
Later array sources supply undeclared keys. Each declared property's selected value is written under the spelling resolution reads first, so a hook that returns its input changes nothing.
at line 2987
protected array
mergeArraySources(array $sources)
Merge the array sources, with later sources taking precedence.
at line 3006
protected array
mergeSources(DataClass $dataClass, array $sources, CreationContext $context, bool $compilesRules)
Merge the keys of every normalized source for unknown-field detection.
at line 3029
protected array
projectNormalizedSource(DataClass $dataClass, Normalized $source, CreationContext $context, bool $compilesRules)
Project a non-enumerable normalized source into declared wire keys.
at line 3061
protected array
mergeMissingValues(array $target, array $source)
Recursively fill only values absent from the earlier source.
at line 3084
protected array|null
matchNamedFactory(DataClass $dataClass, CreationContext $context, array $payloads)
Find the first compatible named object factory.
at line 3118
protected BaseData|array
resolveFactoryPayloads(DataClass $dataClass, CreationContext $context, array $payloads)
Create the object with a matching named factory, or list the payloads for ordinary creation.
Caller keys remain meaningful through factory matching and are discarded afterwards.
at line 3135
protected array|null
matchNamedCollectionFactory(DataClass $dataClass, CreationContext $context, mixed $items, string|null $into)
Find the first compatible named collection factory.
at line 3166
protected mixed
invokeNamedFactory(DataClass $dataClass, DataMethod $method, DataMethodMatch $match)
Invoke one matched named factory without method-binding interception.
at line 3182
protected BaseData
invokeNamedObjectFactory(DataClass $dataClass, DataMethod $method, DataMethodMatch $match)
Invoke one matched named object factory, which must return the requested object.
at line 3205
protected string
resolveMorphClass(DataClass $dataClass, array $resolvedProperties, bool $compilesRules)
Resolve the concrete class selected by an abstract property's discriminator.
When rules compile, a missing discriminator or a null morph() result keeps the abstract class, so validation reports the discriminator instead of creation failing.
at line 3271
protected mixed
propertyDefaultValue(DataClass $dataClass, DataProperty $property)
Materialize a property default only when morph selection requires it.
at line 3293
protected bool
requiresAutoLazyReplay(DataProperty $property, CreationContext $context, CreationExtensions $extensions)
Determine if an automatic lazy property needs deferred Fill replay.
at line 3322
protected bool
isAutoWhenLoaded(DataProperty $property)
Determine if a property uses model relation automatic lazy loading.
at line 3334
protected NamedType|null
selectType(DataProperty $property, mixed $value, ConstructionState $state)
Select and record the declared type that receives a union value.
The one container type accepting the value receives it. Otherwise a value no declared type accepts selects the data object type, and any other value is kept.
at line 3352
protected void
retainPaginatorSource(DataProperty $property, NamedType $type, mixed $value, array $inputPath, ConstructionState $state)
Retain source metadata for one declared paginator property.
at line 3377
protected array|null
iterableValues(mixed $value)
Convert an eager iterable to its keyed values.