Oihana PHP System

hydrate

Table of Contents

Namespaces

appointments
documents

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
throws
ReflectionException
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
throws
ReflectionException
Return values
AggregateOffer|null

hydrateApplicableResource()

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
since
1.5.0
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
throws
ReflectionException

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
throws
ReflectionException

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
throws
ReflectionException

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
throws
ReflectionException

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
throws
HydrationException
ReflectionException
since
1.4.0
Return values
FeeSpecification|null

hydrateParcelDelivery()

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
throws
HydrationException
ReflectionException
example
$delivery = hydrateParcelDelivery
([
    'deliveryAddress'   => [ 'streetAddress' => '8 Rue Paul Gros' , 'postalCode' => '33270' ] ,
    'hasDeliveryMethod' => [ 'id' => 'F13' , 'name' => 'Franco de port' ] ,
    'hasDeliveryRoute'  => [ 'id' => '54'  , 'name' => 'Libourne / rive droite' ] ,
]) ;

$delivery->deliveryAddress   instanceof PostalAddress      ; // true
$delivery->hasDeliveryMethod instanceof DeliveryMethodTerm ; // true
$delivery->hasDeliveryRoute  instanceof DeliveryRouteTerm  ; // true

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
throws
ReflectionException
Return values
PhysicalQuantity|null

hydrateStockLevel()

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
throws
ReflectionException
Return values
StockLevel|null

hydrateWarehouse()

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
throws
ReflectionException

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.

Tags
example
termClassOf( ProductCategoryTerm::class , 'mood' ) ; // ProductCategoryTerm — the short form

$map =
[
    Prop::DEFAULT               => ThesaurusTerm::class ,
    VisitReport::MOOD           => MoodTerm::class ,
    Appointment::REPORT => [ VisitReport::MOOD => ReportMoodTerm::class ] , // a branch
];

termClassOf( $map , VisitReport::MOOD    ) ; // MoodTerm
termClassOf( $map , VisitReport::OUTCOME ) ; // ThesaurusTerm — through Prop::DEFAULT
termClassOf( $map , Appointment::REPORT ) ; // ThesaurusTerm — a branch is not a class
Return values
DefinedTerm>
On this page

Search results