HasOneOf
extends AbstractRelationship
in package
Relationship class for "has one of" relationships
Tags
Table of Contents
Constants
- COMPOSITE_KEY_DELIMITER = "\x1f"
- Delimiter used to join multiple column values into one composite lookup key
Properties
- $children : array<string|int, mixed>
- Relationship children (list of dotted child paths to eager-load under this relationship)
- $foreignKey : string|array<string|int, mixed>|null
- Foreign key
- $foreignTable : string|null
- Foreign table class
- $options : array<string|int, mixed>|null
- Relationship options
- $parent : Record
- Parent record
Methods
- __construct() : mixed
- Constructor
- buildCompositeKey() : string
- Build a single composite lookup key from an ordered list of column values
- getChild() : Record
- Get child
- getChildRelationships() : array<string|int, mixed>
- Get child relationships
- getEagerRelationships() : array<string|int, mixed>
- Get eager relationships
- getEmptyRelationshipValue() : mixed
- Get the value to use when no eager-loaded result exists for a given leaf record
- getForeignKey() : string|array<string|int, mixed>|null
- Get foreign key
- getForeignTable() : string|null
- Get foreign table class
- getOptions() : array<string|int, mixed>|null
- Get options
- getParent() : Record|null
- Get parent record
- setChildRelationships() : static
- Set children child relationships
- tupleFor() : array<string|int, mixed>|null
- Build an ordered tuple of values for the given columns from a record (either a Record instance or a plain array row). Returns null if any one of the columns is missing or null, i.e. the record has no usable composite key and should be skipped.
- applyEagerIdFilter() : void
- Apply the eager-load id filter to a SELECT's WHERE clause and collect its bound values.
- assertKeyCardinality() : void
- Validate that an array foreign-key column count matches the target table's own primary-key column count. A plain string $foreignKey is always treated as cardinality 1.
- assertTupleCardinality() : void
- Validate that the tuples in an eager-load id list have the same number of components as the array foreign key they will be bound to. A plain string $foreignKey (cardinality 1) and an empty $ids list are always valid.
- bindPlaceholder() : string
- Bind a single value as a query parameter and return the placeholder token that must be rendered in its place.
- bindPlaceholders() : array<string|int, mixed>
- Bind a flat list of values for a single column and return their placeholder tokens
- hydrateChildRelationships() : void
- Hydrate nested child relationships onto a flat list of leaf records, resolving each named child relationship once (accumulated by name) and distributing every one of them onto every leaf record — so multiple differently-named children under this relationship don't overwrite each other.
Constants
COMPOSITE_KEY_DELIMITER
Delimiter used to join multiple column values into one composite lookup key
public
string
COMPOSITE_KEY_DELIMITER
= "\x1f"
Properties
$children
Relationship children (list of dotted child paths to eager-load under this relationship)
protected
array<string|int, mixed>
$children
= []
$foreignKey
Foreign key
protected
string|array<string|int, mixed>|null
$foreignKey
= null
$foreignTable
Foreign table class
protected
string|null
$foreignTable
= null
$options
Relationship options
protected
array<string|int, mixed>|null
$options
= null
$parent
Parent record
protected
Record
$parent
= null
Methods
__construct()
Constructor
public
__construct(Record $parent, string $foreignTable, string|array<string|int, mixed> $foreignKey[, array<string|int, mixed>|null $options = null ]) : mixed
Instantiate the relationship object
Parameters
- $parent : Record
- $foreignTable : string
- $foreignKey : string|array<string|int, mixed>
- $options : array<string|int, mixed>|null = null
buildCompositeKey()
Build a single composite lookup key from an ordered list of column values
public
static buildCompositeKey(array<string|int, mixed> $values) : string
Parameters
- $values : array<string|int, mixed>
Return values
stringgetChild()
Get child
public
getChild() : Record
Return values
RecordgetChildRelationships()
Get child relationships
public
getChildRelationships() : array<string|int, mixed>
Return values
array<string|int, mixed>getEagerRelationships()
Get eager relationships
public
getEagerRelationships(array<string|int, mixed> $ids) : array<string|int, mixed>
Parameters
- $ids : array<string|int, mixed>
Tags
Return values
array<string|int, mixed>getEmptyRelationshipValue()
Get the value to use when no eager-loaded result exists for a given leaf record
public
getEmptyRelationshipValue() : mixed
getForeignKey()
Get foreign key
public
getForeignKey() : string|array<string|int, mixed>|null
Return values
string|array<string|int, mixed>|nullgetForeignTable()
Get foreign table class
public
getForeignTable() : string|null
Return values
string|nullgetOptions()
Get options
public
getOptions() : array<string|int, mixed>|null
Return values
array<string|int, mixed>|nullgetParent()
Get parent record
public
getParent() : Record|null
Return values
Record|nullsetChildRelationships()
Set children child relationships
public
setChildRelationships(array<string|int, mixed> $children) : static
Parameters
- $children : array<string|int, mixed>
Return values
statictupleFor()
Build an ordered tuple of values for the given columns from a record (either a Record instance or a plain array row). Returns null if any one of the columns is missing or null, i.e. the record has no usable composite key and should be skipped.
public
static tupleFor(mixed $record, array<string|int, mixed> $columns) : array<string|int, mixed>|null
Parameters
- $record : mixed
- $columns : array<string|int, mixed>
Return values
array<string|int, mixed>|nullapplyEagerIdFilter()
Apply the eager-load id filter to a SELECT's WHERE clause and collect its bound values.
protected
applyEagerIdFilter(Sql $sql, string|array<string|int, mixed> $key, array<string|int, mixed> $ids, array<string|int, mixed> &$params) : void
A single-column key renders as one "column IN (...)" predicate. A composite key renders as one AND-nested group of per-tuple OR-nested equality groups, so that whatever gets appended to the WHERE clause afterward is ANDed against the whole "matches any of these id tuples" block rather than becoming a sibling OR at the top level. It renders identically when there is no sibling predicate.
Parameters
- $sql : Sql
- $key : string|array<string|int, mixed>
- $ids : array<string|int, mixed>
- $params : array<string|int, mixed>
assertKeyCardinality()
Validate that an array foreign-key column count matches the target table's own primary-key column count. A plain string $foreignKey is always treated as cardinality 1.
protected
assertKeyCardinality(string|array<string|int, mixed> $foreignKey, array<string|int, mixed> $targetPrimaryKeys) : void
Parameters
- $foreignKey : string|array<string|int, mixed>
- $targetPrimaryKeys : array<string|int, mixed>
Tags
assertTupleCardinality()
Validate that the tuples in an eager-load id list have the same number of components as the array foreign key they will be bound to. A plain string $foreignKey (cardinality 1) and an empty $ids list are always valid.
protected
assertTupleCardinality(array<string|int, mixed> $ids, string|array<string|int, mixed> $foreignKey) : void
Parameters
- $ids : array<string|int, mixed>
- $foreignKey : string|array<string|int, mixed>
Tags
bindPlaceholder()
Bind a single value as a query parameter and return the placeholder token that must be rendered in its place.
protected
static bindPlaceholder(Sql $sql, string $column, mixed $value, array<string|int, mixed> &$params) : string
A bare placeholder character is NOT a usable placeholder on every dialect: only MySQL/SQL Server take a bare '?'. PostgreSQL needs a positional '$N' and SQLite/PDO need a named ':name', so the token has to be generated here rather than repeating whatever Sql::getPlaceholder() returns. The Sql object's own parameter counter is used to number (PostgreSQL) and to uniquely name (SQLite/PDO) every parameter in the statement, so callers can bind several groups of parameters into one query without colliding.
The generated names deliberately start with the counter, i.e. with a digit, which is exactly what keeps them from ever colliding with the column-derived names that Sql\Parser\Expression::parseShorthand() emits for the same statement.
Parameters
- $sql : Sql
- $column : string
- $value : mixed
- $params : array<string|int, mixed>
Return values
stringbindPlaceholders()
Bind a flat list of values for a single column and return their placeholder tokens
protected
static bindPlaceholders(Sql $sql, string $column, array<string|int, mixed> $values, array<string|int, mixed> &$params) : array<string|int, mixed>
Parameters
- $sql : Sql
- $column : string
- $values : array<string|int, mixed>
- $params : array<string|int, mixed>
Return values
array<string|int, mixed>hydrateChildRelationships()
Hydrate nested child relationships onto a flat list of leaf records, resolving each named child relationship once (accumulated by name) and distributing every one of them onto every leaf record — so multiple differently-named children under this relationship don't overwrite each other.
protected
hydrateChildRelationships(array<string|int, mixed> $leafRecords, string|array<string|int, mixed> $primaryKeyColumn) : void
The column used to query and match a given child relationship is decided per relationship name, not once for all of them: "to-one by foreign key" children (HasOneOf and BelongsTo) are keyed by the leaf record's own foreign key column — the column holding the value that identifies which foreign row to fetch — while every other kind is keyed by the leaf record's primary key.
Parameters
- $leafRecords : array<string|int, mixed>
- $primaryKeyColumn : string|array<string|int, mixed>