Oihana PHP

AlterTrait uses trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short, trait:short

Provides a set of methods to alter properties of arrays or objects based on a configurable set of rules (called "alters").

Supports chaining multiple alterations on a single property:

Example usage:

class MyProcessor
{
    use AlterDocumentTrait;

    public function __construct()
    {
        $this->alters =
        [
            'price' => Alter::FLOAT,
            'tags'  => [ Alter::ARRAY , Alter::CLEAN ],
            'meta'  => [ Alter::JSON_PARSE ],
            'link'  => [ Alter::URL , '/product/' ],
            'score' => [ Alter::CALL , fn( $value ) => $value * 10 ],
            'total' => [ ALTER::MAP , fn( &$document ) => $document['price'] + ( $document['price'] * ( $document['vat'] ?? 0 ) ) ] ,
            'geo'   => [ Alter::NORMALIZE , [ Alter::HYDRATE , GeoCoordinates::class ] ],
            'name'  => [ Alter::TRIM , Alter::UPPERCASE , Alter::NORMALIZE ],
        ];
    }
}

Supported alteration types (see enum Alter):

  • Alter::ARRAY → Split string into array and apply sub-alters.
  • Alter::CLEAN → Remove empty/null elements from an array.
  • Alter::CALL → Call a function on the value.
  • Alter::FLOAT → Convert to float (or array of floats).
  • Alter::GET → Fetch a document using a model.
  • Alter::HYDRATE → Hydrate a value with a specific class.
  • Alter::INT → Convert to integer (or array of integers).
  • Alter::JSON_PARSE → Parse JSON string.
  • Alter::JSON_STRINGIFY → Convert value to JSON string.
  • Alter::MAP → Map a property of a document (or all the document structure) - Can transform or update the document.
  • Alter::NORMALIZE → Normalize a document property using configurable flags.
  • Alter::NOT → Invert boolean values.
  • Alter::URL → Generate a URL from a property.
  • Alter::VALUE → Override with a fixed value.

This is the low-level engine shared by AlterDocumentTrait and AlterBindVarsTrait. It aggregates every per-type Alter*PropertyTrait and exposes alterProperty() as the single entry point that dispatches a property to the right alteration (single or chained). You rarely mix this trait directly — use one of the higher-level traits instead.

Tags
author

Marc Alcaraz (ekameleon)

since
1.0.0

Table of Contents

Properties

$alterKey  : string
The default property key used when an alteration needs to read a value from the document.

Methods

alterArrayCleanProperty()  : array<string|int, mixed>|float
Removes empty-string and null elements from an array value.
alterArrayElements()  : array<string|int, mixed>
Applies a chain of element-level alterations to every item of an array.
alterArrayProperty()  : array<string|int, mixed>
Transforms a value into an array and applies an optional chain of element alterations.
alterCallableProperty()  : mixed
Alters a value by invoking a user-defined callable.
alterFloatProperty()  : float|array<string|int, mixed>
Casts a value (or every element of an array) to float.
alterGetDocument()  : mixed
Replaces an identifier value by the document it references, loaded through a Documents model.
alterHydrateProperty()  : mixed
Hydrate a property value into a specific class instance using reflection.
alterIntProperty()  : int|array<string|int, mixed>
Casts a value (or all elements of an array) to integer.
alterJsonParseProperty()  : mixed
Decodes a JSON-encoded string into its native PHP value.
alterJsonStringifyProperty()  : string|null|false
Encodes a value into its JSON string representation.
alterListifyProperty()  : string|null
Transforms a string or array into a normalized list string.
alterMapProperty()  : mixed
Alters a property of a document through a context-aware "map" callback.
alterNormalizeProperty()  : mixed
Normalize a document property using configurable flags.
alterNotProperty()  : bool|array<string|int, mixed>
Invert a boolean value or an array of booleans.
alterUrlProperty()  : string
Generates a complete URL by combining path segments and document properties.
alterValue()  : mixed
Replaces a value with a fixed replacement when they differ, otherwise keeps the original.
initializeAlterKey()  : static
Initializes the {@see $alterKey} property from an initialization array.
alterProperty()  : array<string|int, mixed>|object
Alters a specific property of the given document using one or more transformation rules.
applyChainedAlterations()  : array<string|int, mixed>|object
Applies chained alterations to a property.
applySingleAlteration()  : array<string|int, mixed>|object
Applies a single alteration (original behavior).
executeAlteration()  : mixed
Executes a specific alteration.
firstIsAlter()  : bool
Checks if a value is an Alter enum or an array starting with an Alter enum.
isChainedDefinition()  : bool
Detects if the definition represents chained alterations.

Properties

$alterKey

The default property key used when an alteration needs to read a value from the document.

public string $alterKey = \org\schema\constants\Schema::ID

Consumed for instance by AlterUrlPropertyTrait to pick which property provides the final URL segment when none is given explicitly. Defaults to Schema::ID.

Tags
see
AlterUrlPropertyTrait

Methods

alterArrayCleanProperty()

Removes empty-string and null elements from an array value.

public alterArrayCleanProperty(mixed $value[, bool &$modified = false ]) : array<string|int, mixed>|float

Only arrays are processed; any other value is returned unchanged. When an array is given, the $modified flag is set to true even if no element was actually removed (the filtering pass is always considered an alteration).

Parameters
$value : mixed

The value to clean. When it is an array, empty-string and unset elements are removed; otherwise it is returned as-is.

$modified : bool = false

Reference flag set to true when an array was processed.

Return values
array<string|int, mixed>|float

The cleaned array (keys preserved), or the original value when it was not an array.

Example:

use oihana\models\traits\alters\AlterArrayCleanPropertyTrait;

class Product
{
    use AlterArrayCleanPropertyTrait;
}

$product  = new Product();
$modified = false;

$tags = $product->alterArrayCleanProperty( [ 'php' , '' , 'models' , null ] , $modified );
// $tags     === [ 0 => 'php' , 2 => 'models' ]  (keys preserved)
// $modified === true

$scalar = $product->alterArrayCleanProperty( 'unchanged' , $modified );
// $scalar === 'unchanged'

alterArrayElements()

Applies a chain of element-level alterations to every item of an array.

public alterArrayElements(array<string|int, mixed> $array[, array<string|int, mixed> $options = [] ][, Container|null $container = null ]) : array<string|int, mixed>

Each entry of $options is either a bare Alter::* type or an array shaped as [ type , ...params ] where the extra parameters are forwarded to the corresponding element alter. The supported types are CALL, CLEAN, FLOAT, GET, HYDRATE, NORMALIZE, NOT, INT and JSON_PARSE; any unknown type leaves the array untouched. The alterations are applied sequentially, each operating on the result of the previous one. If either the array or the option list is empty, the array is returned unchanged.

Parameters
$array : array<string|int, mixed>

The array whose elements must be altered.

$options : array<string|int, mixed> = []

An ordered list of alter definitions, each a bare Alter::* type or an array [ type , ...params ].

$container : Container|null = null

An optional DI container, forwarded to alters that resolve services (notably Alter::GET).

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

Example:

use oihana\models\enums\Alter;

// Trim/empty-clean then JSON-decode each element
$result = $this->alterArrayElements
(
    [ '{"a":1}' , '' , '{"b":2}' ] ,
    [ Alter::CLEAN , Alter::JSON_PARSE ]
);
// $result === [ (object) [ 'a' => 1 ] , (object) [ 'b' => 2 ] ]
Return values
array<string|int, mixed>

The array after all element-level alterations have been applied.

alterArrayProperty()

Transforms a value into an array and applies an optional chain of element alterations.

public alterArrayProperty(mixed $value[, array<string|int, mixed> $options = [] ][, Container|null $container = null ][, bool &$modified = false ]) : array<string|int, mixed>

A non-empty string is split on the semicolon (;) separator. The resulting array (or the value itself when it is already an array) is then passed to alterArrayElements() so that each chained alter definition in $options is applied to every element. Any value that is neither a string nor an array becomes an empty array.

Parameters
$value : mixed

The value to convert. A semicolon-separated string is exploded; an array is used as-is; anything else yields [].

$options : array<string|int, mixed> = []

An ordered list of element-level alter definitions to apply to each item (e.g. [ Alter::CLEAN , Alter::INT ]). Each entry is either an Alter::* type or an array [ type , ...params ].

$container : Container|null = null

An optional DI container, forwarded to element alters that need service resolution (e.g. Alter::GET).

$modified : bool = false

Reference flag; always set to true because the value is coerced to an array.

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

Example:

use oihana\models\enums\Alter;
use oihana\models\traits\alters\AlterArrayPropertyTrait;

class Product
{
    use AlterArrayPropertyTrait;
}

$product  = new Product();
$modified = false;

// Split a string and cast each element to int
$ids = $product->alterArrayProperty( '10;20;30' , [ Alter::INT ] , null , $modified );
// $ids      === [ 10 , 20 , 30 ]
// $modified === true

// Already an array, cleaned of empty entries
$tags = $product->alterArrayProperty( [ 'php' , '' , 'models' ] , [ Alter::CLEAN ] , null , $modified );
// $tags === [ 0 => 'php' , 2 => 'models' ]
Return values
array<string|int, mixed>

The resulting array after splitting and element-level alterations.

alterCallableProperty()

Alters a value by invoking a user-defined callable.

public alterCallableProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : mixed

This method allows transforming a property value using any callable (closure, function name, static method, service callback, etc.). It is typically used when an alteration rule is defined as:

[
    Alter::CALLABLE,
    $callable,
    ...$additionalParams
]

The first element of $definition must be a callable or a string resolvable to a callable via resolveCallable().

The callable will be invoked with the following signature:

function (mixed $value, mixed ...$additionalParams): mixed

Any additional elements from $definition will be forwarded as extra arguments. If the callable returns a different value, $modified will be set to true.

Parameters
$value : mixed

The current value of the property to be altered.

$definition : array<string|int, mixed> = []

The alteration definition:

  • index 0: the callable (closure, function name, or resolvable string)
  • index 1+: optional parameters passed to the callable
$modified : bool = false

Output flag set to true if the callable altered the value.

Tags
throws
InvalidArgumentException

If the callable is a string but cannot be resolved.

example
$definition = [
    fn($value, $factor) => $value * $factor,
    2
];

$value = 10;
$value = $this->alterCallableProperty($value, $definition, $modified);

// $value    = 20
// $modified = true
Return values
mixed

The altered value returned by the callable, or the original value if no callable was provided or callable resolution failed.

alterFloatProperty()

Casts a value (or every element of an array) to float.

public alterFloatProperty(mixed $value[, bool &$modified = false ]) : float|array<string|int, mixed>

This method ensures that the resulting value is always of type float (or an array of floats). It also sets $modified to true when any transformation occurs.

Rules:

  • If $value is already a float → returned as is, not marked modified.
  • If $value is an array → each element converted via floatval().
  • Otherwise → $value is cast to float.
Parameters
$value : mixed

The value to convert. Can be scalar or array.

$modified : bool = false

Output flag set to true if a cast was performed.

Tags
example
$value = '12.5';
$new   = $this->alterFloatProperty($value, $modified);

// $new      = 12.5
// $modified = true

Array usage

$value = ['1.2', '3.4', 5];
$new   = $this->alterFloatProperty($value, $modified);

// $new      = [1.2, 3.4, 5.0]
// $modified = true
Return values
float|array<string|int, mixed>

The float-cast value or an array of float-cast values.

alterGetDocument()

Replaces an identifier value by the document it references, loaded through a Documents model.

public alterGetDocument(mixed $value[, array<string|int, mixed> $definition = [] ][, Container|null $container = null ][, bool &$modified = false ]) : mixed

The model class name is taken from $definition[0] and resolved via getDocumentsModel() (optionally using the DI container). The model's get() method is then called with the lookup key $definition[1] and the current $value. A null value short-circuits and is returned untouched, and any failure raised while fetching the document is swallowed and turned into a null result.

Parameters
$value : mixed

The identifier to resolve. A null value is returned as-is.

$definition : array<string|int, mixed> = []

The lookup definition: [ 0 => model class/identifier , 1 => lookup key field ]. Both default to null.

$container : Container|null = null

Optional DI container used by getDocumentsModel() to resolve the model instance from a service definition.

$modified : bool = false

Reference flag set to true once a document has been fetched.

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

example
class MyMapper
{
    use AlterGetDocumentPropertyTrait;
}

$mapper   = new MyMapper();
$modified = false;

// Replace a user id by the full user document loaded from the 'UserModel' service
$user = $mapper->alterGetDocument( 42 , [ 'UserModel' , 'id' ] , $container , $modified );
// $user === <document whose id === 42> (or null if not found)
// $modified === true

// A null identifier is returned untouched
$none = $mapper->alterGetDocument( null , [ 'UserModel' , 'id' ] , $container , $modified );
// $none === null
Return values
mixed

The loaded document, null when the lookup failed, or the original $value when it was null or no model could be resolved.

alterHydrateProperty()

Hydrate a property value into a specific class instance using reflection.

public alterHydrateProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : mixed

This method transforms a raw value (typically an array) into an object of the specified class. If the input value is an array, it can be normalized and then hydrated using either the Thing constructor or the ReflectionTrait::hydrate() method depending on the class type.

Behavior

  • If $value is not an array, it is returned as-is.
  • If $value is an empty array, the method returns null (by default).
  • If $schema refers to a class extending Thing, the object is created directly via its constructor.
  • Otherwise, hydration is performed via ReflectionTrait::hydrate().
  • The $modified flag is set to true if the resulting value differs from the input.

Usage Example

Property::GEO => [ Alter::HYDRATE, GeoCoordinates::class ],

Custom Normalization

You can specify a custom normalization flag as a third element in the definition:

[ Alter::HYDRATE, GeoCoordinates::class, true , CleanFlag::ALL ]

By default, the value is normalized using: normalize() with flags CleanFlag::DEFAULT | CleanFlag::RETURN_NULL.

Parameters
$value : mixed

The original value to hydrate. Can be a scalar, array, or object.

$definition : array<string|int, mixed> = []

The alter definition, expected as:

[
    0 => string|null $schema,   // Fully qualified class name to hydrate into
    1 => bool        $normalize // Whether to normalize the value before hydration (default true)
    2 => int         $flags     // Optional CleanFlag bitmask
]
$modified : bool = false

Reference flag set to true if the resulting value differs from the original.

Tags
throws
ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

example
use oihana\models\traits\alters\AlterHydratePropertyTrait;
use org\schema\GeoCoordinates;

class Place
{
    use AlterHydratePropertyTrait;
}

$place    = new Place();
$modified = false;

$geo = $place->alterHydrateProperty
(
    [ 'latitude' => 48.85 , 'longitude' => 2.35 ] ,
    [ GeoCoordinates::class ] ,
    $modified
);
// $geo instanceof GeoCoordinates === true
// $modified === true

// A scalar is returned untouched
$raw = $place->alterHydrateProperty( 'not-an-array' , [ GeoCoordinates::class ] , $modified );
// $raw === 'not-an-array'
Return values
mixed

The hydrated value, possibly an instance of $schema, or null if empty.

alterIntProperty()

Casts a value (or all elements of an array) to integer.

public alterIntProperty(mixed $value[, bool &$modified = false ]) : int|array<string|int, mixed>

This alteration is typically used within property transformation pipelines to ensure that the resulting value is strictly of type int.

Behavior:

  • If $value is an array, each element is individually cast using intval().
  • If $value is already an integer, it is returned unchanged and $modified remains false.
  • If $value is not an integer, it is cast to integer and $modified becomes true.

The $modified flag will be set to true whenever at least one casting occurs (i.e., when the original value or any array element was not already an integer).

Example:

use oihana\models\traits\alters\AlterIntPropertyTrait;

class Product {
    use AlterIntPropertyTrait;
}

$product  = new Product();
$modified = false;

// Casting a single value
$id = $product->alterIntProperty("42", $modified);
// $id === 42
// $modified === true

// Casting an array of values
$values = $product->alterIntProperty(["10", "20", "30"], $modified);
// $values === [10, 20, 30]
// $modified === true

// Already an int
$count = $product->alterIntProperty(5, $modified);
// $count === 5
// $modified === false
Parameters
$value : mixed

The input value, scalar or array.

$modified : bool = false

Reference flag indicating if any cast occurred.

Return values
int|array<string|int, mixed>

The cast integer or array of integers.

alterJsonParseProperty()

Decodes a JSON-encoded string into its native PHP value.

public alterJsonParseProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : mixed

The value is decoded only when it is a string that passes json_validate(); otherwise it is returned as-is. The optional $definition entries are passed straight to json_decode() after the value (associative, depth, flags).

Parameters
$value : mixed

The value to decode. Decoded only when it is a valid JSON string; any other value is returned unchanged.

$definition : array<string|int, mixed> = []

Extra arguments forwarded to json_decode(): [ associative , depth , flags ]. Defaults to standard json_decode() behavior (objects for JSON objects).

$modified : bool = false

Reference flag set to true when the value was decoded.

Tags
example
use oihana\models\traits\alters\AlterJSONParsePropertyTrait;

class Record
{
    use AlterJSONParsePropertyTrait;
}

$record   = new Record();
$modified = false;

// Decode to an associative array
$meta = $record->alterJsonParseProperty( '{"a":1,"b":2}' , [ true ] , $modified );
// $meta     === [ 'a' => 1 , 'b' => 2 ]
// $modified === true

// Non-JSON input is left untouched
$plain = $record->alterJsonParseProperty( 'hello' , [] , $modified );
// $plain === 'hello'
Return values
mixed

The decoded value (object, array, scalar or null), or the original value when it was not a valid JSON string.

alterJsonStringifyProperty()

Encodes a value into its JSON string representation.

public alterJsonStringifyProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : string|null|false

The value is always passed to json_encode(); the optional $definition entries are forwarded as the following arguments (flags, depth). A false result from json_encode() is normalized to null.

Parameters
$value : mixed

The value to encode (array, object, scalar, etc.).

$definition : array<string|int, mixed> = []

Extra arguments forwarded to json_encode(): [ flags , depth ] (e.g. JSON_PRETTY_PRINT). Empty by default.

$modified : bool = false

Reference flag; always set to true.

Tags
example
use oihana\models\traits\alters\AlterJSONStringifyPropertyTrait;

class Record
{
    use AlterJSONStringifyPropertyTrait;
}

$record   = new Record();
$modified = false;

$json = $record->alterJsonStringifyProperty( [ 'a' => 1 , 'b' => 2 ] , [] , $modified );
// $json     === '{"a":1,"b":2}'
// $modified === true

// With pretty-print flag
$pretty = $record->alterJsonStringifyProperty( [ 'a' => 1 ] , [ JSON_PRETTY_PRINT ] , $modified );
// $pretty === "{\n    \"a\": 1\n}"
Return values
string|null|false

The JSON string, or null when encoding fails.

alterListifyProperty()

Transforms a string or array into a normalized list string.

public alterListifyProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : string|null

The transformation can be customized via the $definition array:

  • $definition[0] (string): Input separator for strings (default: ;)
  • $definition[1] (string): Output separator for joining (default: PHP_EOL)
  • $definition[2] (string|null): Default value if result is empty (default: null)
Parameters
$value : mixed

The value to transform: a separator-delimited string, an array of items, or null.

$definition : array<string|int, mixed> = []

Optional parameters [ separator , replace , default ]: the input separator (default ;), the output separator used to join items (default PHP_EOL), and the fallback value returned when the result is empty (default null).

$modified : bool = false

Reference flag set to true when the resulting value differs from the original.

Tags
example
// Use default separators
$this->alterListifyProperty('a;b;c');
// Result: "a\nb\nc"

// Custom separators
$this->alterListifyProperty('a,b,c', [',', ' - ']);
// Result: "a - b - c"

// With fallback default
$this->alterListifyProperty('', [';', PHP_EOL, 'empty']);
// Result: "empty"
Return values
string|null

The normalized list string, or the configured default when empty.

alterMapProperty()

Alters a property of a document through a context-aware "map" callback.

public alterMapProperty(array<string|int, mixed>|object &$document, Container|null $container, string $key, mixed $value[, array<string|int, mixed> $params = [] ][, bool &$modified = false ]) : mixed

The first element of $params is treated as the callback (a callable or a string resolvable via resolveCallable()); the remaining elements are forwarded to it as its $params argument. The callback receives the full document, the container, the key and the current value, and returns the new value. If $params is empty or the callback cannot be resolved to a callable, the original value is returned untouched.

Parameters
$document : array<string|int, mixed>|object

The document (array or object) holding the property; passed by reference so the callback may read or adjust siblings.

$container : Container|null

Optional DI container, forwarded to the callback for resolving services when the computed value needs them.

$key : string

The key or property name being altered.

$value : mixed

The current value of the property.

$params : array<string|int, mixed> = []

Parameters whose first element is the callback (callable or resolvable string); any remaining elements are forwarded to it.

$modified : bool = false

Output flag set to true when the callback is applied.

Tags
throws
InvalidArgumentException

If the callback is given as a string that cannot be resolved.

example
$document = [ 'price' => 10 , 'vat' => '0.2' ];
$modified = false;

// The callback reads a sibling property ('vat') to compute the new value
$callback = fn( array|object $document , $container , string $key , mixed $value , array $params )
    => $value + ( $value * ( $document['vat'] ?? 0 ) ) ;

$newValue = $this->alterMapProperty
(
     $document ,
     null ,
     'price' ,
     $document['price'] ,
     [ $callback ] ,   // the callback is the first element of $params
     $modified
);
// $newValue === 12
// $modified === true
Return values
mixed

The value returned by the callback, or the original value when no callback applies.

alterNormalizeProperty()

Normalize a document property using configurable flags.

public alterNormalizeProperty(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : mixed

The normalization can be customized via the $definition array:

  • If empty or no flags provided, uses CleanFlag::DEFAULT | CleanFlag::RETURN_NULL
  • If a flags value is provided at index 0, uses that instead
Parameters
$value : mixed

The value to normalize (array, string, scalar or object).

$definition : array<string|int, mixed> = []

Optional flags array [ CleanFlag bitmask , ...other params ]. When omitted, CleanFlag::DEFAULT | CleanFlag::RETURN_NULL is used.

$modified : bool = false

Reference flag set to true when the normalized value differs from the original.

Tags
example
// Use default flags
$this->alterNormalizeProperty( $value );
// Uses: CleanFlag::DEFAULT | CleanFlag::RETURN_NULL

// Use custom flags
$this->alterNormalizeProperty($value, [ CleanFlag::NULLS | CleanFlag::EMPTY ] );

// Only remove nulls
$this->alterNormalizeProperty($value, [CleanFlag::NULLS]);
Return values
mixed

The normalized value, or null when it was entirely cleaned away.

alterNotProperty()

Invert a boolean value or an array of booleans.

public alterNotProperty(mixed $value[, bool &$modified = false ]) : bool|array<string|int, mixed>
Parameters
$value : mixed

The value to invert: a boolean, an array of booleans, or any other value (which is coerced to boolean before inversion).

$modified : bool = false

Reference flag; always set to true since the inversion is unconditional.

Tags
example
$processor = new class {
    use \oihana\models\traits\alters\AlterNotPropertyTrait;
};

// Single boolean
$modified = false;
$result = $processor->alterNotProperty(true, $modified);
// $result === false
// $modified === true

// Array of booleans
$array = [true, false, true];
$result = $processor->alterNotProperty($array, $modified);
// $result === [false, true, false]
// $modified === true
Return values
bool|array<string|int, mixed>

The inverted boolean, or an array of inverted booleans when an array was given.

alterUrlProperty()

Generates a complete URL by combining path segments and document properties.

public alterUrlProperty(array<string|int, mixed>|object $document[, array<string|int, mixed> $options = [] ][, Container|null $container = null ][, bool &$modified = false ][, string|null $propertyName = null ][, string $containerKey = 'baseUrl' ]) : string

The method builds a URL in the following order:

  1. Resolves the base URL from the container (if containerKey is provided and not false)
  2. Joins the base URL with the provided path segment
  3. Appends the property value from the document
  4. Optionally adds a trailing slash

Parameters via $options array:

  • [0] (string) — Path segment to append after base URL (e.g., '/products', '/api/v1/users')
  • [1] (string) — Document property name containing the final segment (default: 'id')
  • [2] (string|bool) — Container service key for base URL resolution or false to skip (default: 'baseUrl')
  • [3] (bool) — Add trailing slash to the result (default: false)
Parameters
$document : array<string|int, mixed>|object

The document (array or object) to read property values from.

$options : array<string|int, mixed> = []

Configuration array [ path , propertyName , containerKey , trailingSlash ]; missing entries fall back to the method arguments and defaults described above.

$container : Container|null = null

DI container used to resolve the base URL from a service definition; ignored when null or when the key is false.

$modified : bool = false

Reference flag; always set to true since a URL is always built.

$propertyName : string|null = null

Default property name to read when none is given in $options[1] (otherwise falls back to $alterKey then Schema::ID).

$containerKey : string = 'baseUrl'

Default container service key for the base URL when none is given in $options[2] (default 'baseUrl').

Tags
throws
DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

Complete Example:

class DocumentMapper
{
    use AlterUrlPropertyTrait ;

    public function mapPlace( $document , $container )
    {
        $modified = false;
        return $this->alterUrlProperty
        (
            $document ,
            [ '/places' , 'id' , 'baseUrl' , true ] ,
            $container ,
            $modified ,
            'id' ,
            'baseUrl'
        );
    }
}

// With container containing: 'baseUrl' => 'https://api.example.com'
// And document: ['id' => 123]
// Result: 'https://api.example.com/places/123/'
Return values
string

The generated URL.

alterValue()

Replaces a value with a fixed replacement when they differ, otherwise keeps the original.

public alterValue(mixed $value[, array<string|int, mixed> $definition = [] ][, bool &$modified = false ]) : mixed

The replacement is read from $definition[0]. When it is strictly equal (!==) to the current value, nothing changes and $modified is left untouched; otherwise the new value is returned and $modified is set to true.

Parameters
$value : mixed

The original value.

$definition : array<string|int, mixed> = []

The alter definition; $definition[0] holds the replacement value (defaults to null when absent).

$modified : bool = false

Reference flag set to true when the value was actually replaced.

Tags
example
use oihana\models\traits\alters\AlterValueTrait;

class Example
{
    use AlterValueTrait;
}

$example  = new Example();
$modified = false;

$status = $example->alterValue( 'draft' , [ 'published' ] , $modified );
// $status   === 'published'
// $modified === true

// Same value: no change
$same = $example->alterValue( 'published' , [ 'published' ] , $modified );
// $same === 'published'
Return values
mixed

The replacement value when it differs from the original, otherwise the original.

initializeAlterKey()

Initializes the {@see $alterKey} property from an initialization array.

public initializeAlterKey([array<string|int, mixed> $init = [] ]) : static

Reads ModelParam::ALTER_KEY from $init; when absent, the key falls back to Schema::ID. Returns the current instance for fluent chaining.

Parameters
$init : array<string|int, mixed> = []

Initialization options; the ModelParam::ALTER_KEY entry, when present, overrides the default alter key.

Tags
example
use oihana\models\enums\ModelParam;

$this->initializeAlterKey( [ ModelParam::ALTER_KEY => 'slug' ] );
// $this->alterKey === 'slug'

$this->initializeAlterKey();
// $this->alterKey === Schema::ID  (default)
Return values
static

The current instance, for method chaining.

alterProperty()

Alters a specific property of the given document using one or more transformation rules.

protected alterProperty(string $key, array<string|int, mixed>|object $document, string|array<string|int, mixed> $definition[, Container|null $container = null ]) : array<string|int, mixed>|object

The transformation is defined by the $definition argument, which can be:

  • A string representing a single Alter:: constant (e.g. Alter::FLOAT)
  • An array with a single alteration and parameters: [ Alter::URL , '/product/' ]
  • An array with chained alterations (NEW): [ Alter::NORMALIZE , [ Alter::HYDRATE , Class::class ] ]
  • An array with multiple simple alterations (NEW): [ Alter::TRIM , Alter::UPPERCASE , Alter::NORMALIZE ]

If the alteration modifies the value, the altered value is set back into the document. Otherwise, the original document is returned unmodified.

Supported alter types:

  • Alter::ARRAY — Explodes a string into an array (using ;) and applies sub-alters
  • Alter::CALL — Calls a user-defined callable on the value
  • Alter::CLEAN — Removes empty ("") or null elements from arrays
  • Alter::FLOAT — Casts the value to float
  • Alter::GET — Resolves a document by ID using a model
  • Alter::HYDRATE — Hydrate a value with a specific class.
  • Alter::INT — Casts the value to integer
  • Alter::JSON_PARSE — Parses a JSON string into a PHP value
  • Alter::JSON_STRINGIFY — Encodes a value into a JSON string
  • Alter::MAP — Normalize a document property using configurable flags
  • Alter::NORMALIZE — Normalize a document property using configurable flags
  • Alter::NOT — Invert boolean values
  • Alter::URL — Generates a URL based on document properties
  • Alter::VALUE — Replaces the value with a fixed constant
Parameters
$key : string

The name of the property to alter (e.g. 'price', 'tags')

$document : array<string|int, mixed>|object

The document (array or object) passed by reference

$definition : string|array<string|int, mixed>

The alteration definition: either a string (Alter::) or an array ([ Alter::X , ...args ])

$container : Container|null = null

An optional DI container reference.

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

example
$this->alters =
[
    'price'    => Alter::FLOAT,                         // Casts 'price' to float
    'tags'     => [ Alter::ARRAY , Alter::CLEAN ],      // Splits and cleans 'tags'
    'meta'     => [ Alter::JSON_PARSE ],                // Parses 'meta' JSON string
    'url'      => [ Alter::URL , '/product/' ],         // Generates a product URL
    'discount' => [ Alter::CALL , fn($v) => $v * 0.9 ], // Applies a callable
    'rating'   => [ Alter::VALUE , 5 ],                 // Fixed value replacement
    'geo'      => [ Alter::NORMALIZE , [ Alter::HYDRATE , GeoCoordinates::class ] ],
    'name'     => [ Alter::TRIM , Alter::UPPERCASE , Alter::NORMALIZE ],
];

$document =
[
    'price'    => '29.90',
    'tags'     => 'a;;b;',
    'meta'     => '{"active":true}',
    'url'      => '123',
    'discount' => 100,
    'rating'   => 0,
    'geo'      => ['latitude' => null, 'longitude' => 2.5],
    'name'     => '  john doe  ',
];

$result = $this->alterProperty('price', $document, Alter::FLOAT);
// Returns the document with 'price' casted to float (29.9)
Return values
array<string|int, mixed>|object

The altered document (same reference type as input)

applyChainedAlterations()

Applies chained alterations to a property.

protected applyChainedAlterations(string $key, array<string|int, mixed>|object $document, array<string|int, mixed> $definitions[, Container|null $container = null ]) : array<string|int, mixed>|object

Each alteration in the chain is applied sequentially, with the output of one becoming the input of the next.

Parameters
$key : string

The property key

$document : array<string|int, mixed>|object

The document containing the property

$definitions : array<string|int, mixed>

The array of alteration definitions

$container : Container|null = null

An optional DI container reference.

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

Return values
array<string|int, mixed>|object

$document The document with the altered property

applySingleAlteration()

Applies a single alteration (original behavior).

protected applySingleAlteration(string $key, array<string|int, mixed>|object $document, array<string|int, mixed> $definitions[, Container|null $container = null ]) : array<string|int, mixed>|object
Parameters
$key : string

The property key

$document : array<string|int, mixed>|object

The document containing the property

$definitions : array<string|int, mixed>

The alteration definition with parameters

$container : Container|null = null

An optional DI container reference.

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

Return values
array<string|int, mixed>|object

The document with the altered property

executeAlteration()

Executes a specific alteration.

protected executeAlteration(string|Alter $alter, string $key, mixed $value, array<string|int, mixed> $params, array<string|int, mixed>|object &$document[, Container|null $container = null ][, bool &$modified = false ]) : mixed
Parameters
$alter : string|Alter

The alteration type

$key : string

The property key (for context)

$value : mixed

The value to alter

$params : array<string|int, mixed>

The alteration parameters

$document : array<string|int, mixed>|object

The full document (for context)

$container : Container|null = null

An optional DI container reference.

$modified : bool = false

Output parameter indicating if the value was modified

Tags
throws
ContainerExceptionInterface

If an error occurs while retrieving an entry from the dependency-injection container.

DependencyException

If the dependency cannot be resolved by the container.

NotFoundException

If no entry is found for the given identifier in the container.

NotFoundExceptionInterface

If no entry is found for the requested identifier in the container.

ReflectionException

If a class or property cannot be reflected (e.g. during hydration).

Return values
mixed

The altered value

firstIsAlter()

Checks if a value is an Alter enum or an array starting with an Alter enum.

protected firstIsAlter(mixed $first) : bool
Parameters
$first : mixed

The value to check

Return values
bool

True if it's an Alter or array with Alter as first element

isChainedDefinition()

Detects if the definition represents chained alterations.

protected isChainedDefinition(array<string|int, mixed> $definitions) : bool

Chaining is detected when:

  • The first element is an Alter enum
  • AND the second element is either:
    • Another Alter enum (simple chaining)
    • An array whose first element is an Alter enum (chaining with params)
Parameters
$definitions : array<string|int, mixed>

The alteration definitions

Return values
bool

True if chaining is detected, false otherwise

On this page

Search results