hydrate
Table of Contents
Namespaces
Functions
- findPhysicalQuantityByType() : PhysicalQuantity|null
- Walk a packaging chain and hand back the level whose `additionalType` matches, as a {@see PhysicalQuantity} — so the level found keeps what it weighs and what it occupies.
- hydrateAggregateOffer() : AggregateOffer|null
- Hydrate an array definition with the AggregateOffer class.
- hydrateApplicableResource() : ApplicableResource|null
- Hydrate an array definition with the ApplicableResource class, down to the resource it points at.
- hydrateCustomer() : mixed
- Hydrate an array definition with the Customer class.
- hydrateCustomerEmployee() : mixed
- Hydrate an array definition with the CustomerEmployee class.
- hydrateCustomerSite() : mixed
- Hydrate an array definition with the CustomerSite class.
- hydrateDeliveryRouteAssignment() : mixed
- Hydrate an array definition with the DeliveryRouteAssignment class.
- hydrateFeeSpecification() : FeeSpecification|null
- Hydrate an array definition with the FeeSpecification class, down to the rate it derives from.
- hydrateParcelDelivery() : mixed
- Hydrate an array definition with the ParcelDelivery class — where the goods go, how they travel, on which round and for when.
- hydratePhysicalQuantity() : PhysicalQuantity|null
- Hydrate an array definition with the PhysicalQuantity class, down the whole chain.
- hydrateStockLevel() : StockLevel|null
- Hydrate an array definition with the StockLevel class.
- hydrateWarehouse() : mixed
- Hydrate an array definition with the Warehouse class.
- termClassOf() : DefinedTerm>
- Answer the class one term property is hydrated into.
Functions
findPhysicalQuantityByType()
Walk a packaging chain and hand back the level whose `additionalType` matches, as a {@see PhysicalQuantity} — so the level found keeps what it weighs and what it occupies.
findPhysicalQuantityByType(string $type[, array<string|int, mixed>|QuantitativeValue|null $tree = null ]) : PhysicalQuantity|null
🔑 The level found is typed, and so is the chain below it. A consumer that
walks on from the level it asked for reads ->weight at every depth, never
['weight'] one step down : the walk hands back the same shape
Reflection::hydrate() builds, not a typed head sitting
over raw rows.
The chain is read one level at a time, valueReference after
valueReference, until the type is met or the chain stops.
🔑 The tree is a parameter, not a property. The walk belongs to whoever holds a chain, and a chain is not always reachable from the product that defined it : it is built at import time, copied onto the offers, and it is that copy which is stored — so a product read back from a base has none, while the offer beside it does. Left private on the product, the walk had to be written a second time by anyone holding the offer's tree, and a walk written by hand rebuilds the levels as plain QuantitativeValue : that class declares neither weight nor volume, and a class discards the keys it does not declare. Both would leave without an error and without a trace. Exposing the walk is what makes that loss impossible rather than repairable.
⚠️ Schema.org lets valueReference hold things that are not quantities at
all — a bare code, an enumeration. Anything that is neither an array nor a
QuantitativeValue ends the walk instead of being read as a level.
Example:
$parcel = findPhysicalQuantityByType( UnitOfSaleType::PARCEL , $offer->eligibleQuantity ) ;
$parcel?->weight ; // 245.1456
Parameters
- $type : string
-
One of the UnitOfSaleType constants.
- $tree : array<string|int, mixed>|QuantitativeValue|null = null
-
The chain to walk — a typed level, or the raw rows a base read leaves.
Tags
Return values
PhysicalQuantity|null —The matching level, or null when the chain holds none.
hydrateAggregateOffer()
Hydrate an array definition with the AggregateOffer class.
hydrateAggregateOffer([array<string|int, mixed>|null $init = null ]) : AggregateOffer|null
Use it in the 'products' definition in the DI container.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : array<string|int, mixed>|null = null
Tags
Return values
AggregateOffer|nullhydrateApplicableResource()
Hydrate an array definition with the ApplicableResource class, down to the resource it points at.
hydrateApplicableResource([mixed $init = null ]) : ApplicableResource|null
A link is read for two things at once — the flag, to know whether it applies,
and the resource, to know what applies — so typing the head alone would leave
a consumer reading ->appliedByDefault on the link and ['id'] on the
resource beside it.
⚠️ Only the constructor path needs this. Reflection::hydrate() types the
entries on its own, Product::$hasApplicableResource
declaring the attribute for it. The two doors have to agree, which is what
this function is for.
🔑 item is typed as a Product, because that is what an applicable
resource is today : a record of the catalogue like any other. The day the
payload's own @type has to decide — a Service beside a Product — this
becomes a hydrateProductOrService() on the model of
hydrateOrganizationOrPerson(). Guessing
from a declared union instead is exactly the mistake that pattern exists to
prevent.
Use it in the 'products' definition in the DI container.
Parameters
- $init : mixed = null
-
The definition to hydrate.
Tags
Return values
ApplicableResource|null —The link, or null when there is nothing to build.
hydrateCustomer()
Hydrate an array definition with the Customer class.
hydrateCustomer([mixed $init = null ]) : mixed
Handles both a single customer array and an array of customers, and hydrates the
nested contactPoint and address references so the resolved customer carries typed
values rather than raw arrays.
Each nested reference is hydrated only when the raw value is an array — when there is
something to hydrate. The helper's answer is then written as is, null included : an
array that resolves to nothing (an empty list, a list of unhydratable entries) becomes
null, never a leftover raw array, so the customer answers the same thing as the
nested helper called on its own. Anything that is not an array — an unresolved string
reference, an already typed instance — is left untouched.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
-
Single customer data or array of customer data.
Tags
hydrateCustomerEmployee()
Hydrate an array definition with the CustomerEmployee class.
hydrateCustomerEmployee([mixed $init = null ]) : mixed
Handles both single employee array and array of employees.
Each nested reference is hydrated only when the raw value is an array — when there is
something to hydrate. The helper's answer is then written as is, null included : an
array that resolves to nothing (an empty list, a list of unhydratable entries) becomes
null, never a leftover raw array, so the employee answers the same thing as the
nested helper called on its own. Anything that is not an array — an unresolved string
reference, an already typed instance — is left untouched.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
-
Single employee data or array of employee data
Tags
hydrateCustomerSite()
Hydrate an array definition with the CustomerSite class.
hydrateCustomerSite([mixed $init = null ]) : mixed
Handles both single CustomerSite array and array of CustomerSite things.
Each nested reference is hydrated only when the raw value is an array — when there is
something to hydrate. The helper's answer is then written as is, null included : an
array that resolves to nothing (an empty list, a list of unhydratable entries) becomes
null, never a leftover raw array, so the site answers the same thing as the nested
helper called on its own. Anything that is not an array — an unresolved string
reference, an already typed instance — is left untouched.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
-
Single CustomerSite data or array of CustomerSite data
Tags
hydrateDeliveryRouteAssignment()
Hydrate an array definition with the DeliveryRouteAssignment class.
hydrateDeliveryRouteAssignment([mixed $init = null ]) : mixed
Handles both a single assignment array and a list of them — the list being the usual shape, since a same address is commonly served by more than one route.
The nested route is resolved into a DeliveryRouteTerm when it holds
the joined reference row. A bare code is left untouched : nothing has been
joined yet, and inventing a term out of a string would claim a label nobody
read.
route is hydrated only when the raw value is an array — when there is something
to hydrate. The helper's answer is then written as is, null included : an array
that resolves to nothing becomes null, never a leftover raw array.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
-
Single DeliveryRouteAssignment data or array of DeliveryRouteAssignment data.
Tags
hydrateFeeSpecification()
Hydrate an array definition with the FeeSpecification class, down to the rate it derives from.
hydrateFeeSpecification([mixed $init = null ]) : FeeSpecification|null
A fee is read in two places at once — price to compute an amount, rate to
explain it — and the two carry different units on purpose. Typing the head
alone would leave a consumer reading ->price on the fee and
['price'] on the rate beside it, on a pair whose whole point is that both
are read together.
The issuing body is typed too, through hydrateOrganizationOrPerson(),
which reads the payload's @type rather than guessing from the declared
union.
⚠️ Only the constructor path needs this. Reflection::hydrate() types both on
its own, FeeSpecification::$rate declaring the attribute for it.
Use it in the 'products' definition in the DI container.
Parameters
- $init : mixed = null
Tags
Return values
FeeSpecification|nullhydrateParcelDelivery()
Hydrate an array definition with the ParcelDelivery class — where the goods go, how they travel, on which round and for when.
hydrateParcelDelivery([mixed $init = null ][, DefinedTerm> $deliveryMethodClass = DeliveryMethodTerm::class ][, DefinedTerm> $deliveryRouteClass = DeliveryRouteTerm::class ]) : mixed
Handles both a single delivery array and an array of them.
The delivery is built through the ParcelDelivery constructor, and its
references are resolved one by one afterwards. Reflection::hydrate()
would bring nothing here : the class declares no #[HydrateAs] on
deliveryAddress, hasDeliveryMethod or hasDeliveryRoute, so reflection
would leave the three of them raw while adding its own strictness — it drops
whatever the class does not declare, and a delivery read back from a store
commonly carries more than Schema.org names.
The two travel terms are parameters rather than hard-wired classes, and
that is the reason this helper lives under xyz\oihana while
ParcelDelivery is plain org\schema : a thesaurus term belongs to the
business layer, and an attribute on the Schema.org class would make the lower
layer depend on the upper one. The defaults name the business terms; any
DefinedTerm subclass may replace them, which is what the property's own
declared type asks for.
provider — the carrier — carries the Organization|Person union that
reflection cannot resolve from the property type alone, so it goes through
hydrateOrganizationOrPerson(), which reads the payload's @type.
Each resolution happens only when the value is still an array — when there is
something to hydrate — and its answer is then written as is, null included :
an array that resolves to nothing becomes null, never a leftover raw array.
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
-
Single delivery data or array of delivery data.
- $deliveryMethodClass : DefinedTerm> = DeliveryMethodTerm::class
-
The class the delivery method is hydrated into.
- $deliveryRouteClass : DefinedTerm> = DeliveryRouteTerm::class
-
The class the delivery route is hydrated into.
Tags
hydratePhysicalQuantity()
Hydrate an array definition with the PhysicalQuantity class, down the whole chain.
hydratePhysicalQuantity([mixed $init = null ]) : PhysicalQuantity|null
A packaging chain is read one level at a time — the unit, then what one
package holds of it, then what one pallet holds of packages — and each level
carries its own weight and volume. Typing the head alone would leave a
consumer reading ->weight at the first level and ['weight'] below it, on
a structure whose entire point is the ratio between two levels. So every
valueReference is walked and typed too.
⚠️ Only the constructor path needs this. Reflection::hydrate() types the
chain on its own, PhysicalQuantity::$valueReference declaring the
attribute for it.
Use it in the 'products' definition in the DI container.
Parameters
- $init : mixed = null
Tags
Return values
PhysicalQuantity|nullhydrateStockLevel()
Hydrate an array definition with the StockLevel class.
hydrateStockLevel([mixed $init = null ]) : StockLevel|null
Use it in the 'products' definition in the DI container.
Parameters
- $init : mixed = null
Tags
Return values
StockLevel|nullhydrateWarehouse()
Hydrate an array definition with the Warehouse class.
hydrateWarehouse([mixed $init = null ]) : mixed
🔑 A bare reference survives inside a list, exactly as it does on its own : a list of unresolved handles comes back as it stands, and only an entry that was an array and resolved to nothing is dropped. The keys stay gap-free — a filtered list left with holes serializes as a JSON object, and a consumer walking the value gets something it cannot walk.
Parameters
- $init : mixed = null
Tags
termClassOf()
Answer the class one term property is hydrated into.
termClassOf(DefinedTerm>|array<string, DefinedTerm>|array<string, DefinedTerm>>> $termClass, string $property) : DefinedTerm>
A hydrator that resolves several vocabularies takes one $termClass parameter rather
than one per property, and reads it through this helper. The parameter accepts two forms,
and the short one is the common case :
- a class name — every term of the entity is hydrated into it ;
- a map —
[ Prop::DEFAULT => …, '<property>' => … ], where each key names a property and Prop::DEFAULT covers everything left unnamed.
The two forms are the same statement at two levels of detail, so a caller only writes a map the day one family stops answering what the others answer. Anything a map does not name — no key for the property, no Prop::DEFAULT — falls back to ThesaurusTerm, the class the house families serve.
🔑 A nested branch is not a class, and is never answered as one. A map may carry a sub-map
under a property that holds a whole entity rather than a term — report, for instance,
whose own terms belong to their own families. Such an entry is not a class name, so it is
never returned here : the hydrator that owns that property reads the branch itself and
hands it down. This helper answers classes, and only classes.
⚠️ A map is keyed by property, not by family. Two entities of one hierarchy may declare
the same property name over two different families — a meeting's tags and its report's
tags are not the same vocabulary. One flat map cannot tell them apart, which is exactly
what the nested branch is for : the inner entity inherits the outer map until the caller
gives it one of its own.
Parameters
- $termClass : DefinedTerm>|array<string, DefinedTerm>|array<string, DefinedTerm>>>
-
A class name, or a map of property name to class name.
- $property : string
-
The property whose class is asked for.