Index

tArrayProperties

MMO\core\classes · 1 symbol · generated 5 Oct 2026

trait

tArrayProperties

tArrayProperties.php:35

Trait implementing iArrayProperties: turns a class's PHP properties (and/or methods) annotated with the #[ArrayProperty] attribute into a declarative, schema-backed "array" of named values, with array-access ($obj['key']), coercion, JSON-Schema generation, storage export, and change tracking built in.

trait MMO\core\classes\tArrayProperties
Namespace
MMO\core\classes
See
iMutationObserver contract) -- setArrayPropertyOffset calls it directly. It is not provided by the trait itself, since concrete change-tracking (e.g. Entity) is left to the consuming class.
Each #[ArrayProperty] can target a class itself (a "virtual" property backed entirely by a getter/setter method, e.g. `#[ArrayProperty(name: 'uid', getter: 'uid')]` on the class) or a single property (`#[ArrayProperty]` right above `protected string $name;`, in which case name/getter/setter default from the property itself). NOTE: a class using this trait is expected to also implement `markChanged(string ...$keys): bool` (the
class Person implements iArrayProperties { use tArrayProperties; #[ArrayProperty] protected string $name = ''; #[ArrayProperty] protected int $age = 0; } $p = new Person(); $p->loadArray(['name' => 'Marc', 'age' => 42]); $p['name']; // 'Marc' $p->toArray(); // ['name' => 'Marc', 'age' => 42]

Index

ArrayProperties static
SearchProperties static
ArrayProperties() staticBuild (once per class, then cached in the static $ArrayProperties array) the list of every #[ArrayProperty] declared on this class, its parent classes, and the traits they use -- by reflection…
ArrayProperty($name) static
getArrayProperty($key, $isRef, $store)Read a single array property's current value, through its getter (a direct property, a path alias, or a method).
HiddenPath($path) staticThe hidden property (ArrayProperty::isHidden) a json-path goes through, known from the declared types alone: of this class, or of a class a property on the way may hold -- every class of its t…
isArrayPropertySet($key, $store)
isEmpty()
isHiddenPath($path)
ListClassReferences($onlyStorable) staticGet a list of all the classes and their properties that are using references to this class.
loadArray($data, $coerceOptions, $fromStore)Set every entry of $data as an array property, through setArrayProperty (so each value is coerced by its property's schema).
mutate($type, $path, $value, $oldValue)\MMO\core\interfaces\iMutationObserver::mutate -- reacts to a mutation that happened deep inside one of this object's array properties (e.g.
offsetExists($key)\ArrayAccess::offsetExists -- tells whether $key is a *declared* #[ArrayProperty], not whether it currently holds a non-default value (use isArrayPropertySet for that).
offsetGet($key)\ArrayAccess::offsetGet
offsetSet($key, $value)\ArrayAccess::offsetSet
offsetUnset($key)\ArrayAccess::offsetUnset -- equivalent to setting the property to null (its coerced value depends on the property's schema: e.g.
Schema() staticThe JSON-Schema describing every #[ArrayProperty] of this class (built once and cached by ArrayProperties).
SearchProperty($name) static
setArrayProperty($key, $value, $coerceOptions, $fromStore)Set array property
setArrayPropertyOffset($key, $offset, $value, $coerceOptions)Set/push a value into an array property
store()Export all array properties with store set to true.
toArray($fields, $flatten, $recursive)Export fields to an array.

Properties2

ArrayProperties

static
#[MMO\core\attributes\Serialize(false)] static array $ArrayProperties = []
Type
array

SearchProperties

static
static array $SearchProperties = []
Type
array

Methods20

ArrayProperties()

statictArrayProperties.php:85

Build (once per class, then cached in the static $ArrayProperties array) the list of every #[ArrayProperty] declared on this class, its parent classes, and the traits they use -- by reflection over class- and property-level attributes. Also builds this class's Schema as a side effect. Called automatically by every other method in this trait: rarely called directly.

static function ArrayProperties(): array
returnsarray\MMO\core\attributes\ArrayProperty} name => ArrayProperty, in schema-sort order
throws
Person::ArrayProperties(); // ['name' => ArrayProperty(name: 'name', ...), 'age' => ArrayProperty(...)]

ArrayProperty($name)

statictArrayProperties.php:243
static function ArrayProperty(string $name): MMO\core\attributes\ArrayProperty
$namestring
returnsArrayPropertythe property's metadata (schema, getter, setter, ...)
throwsif $name is not a declared #[ArrayProperty]
Person::ArrayProperty('name')->schema['type']; // ['string']

getArrayProperty($key, $isRef, $store)

tArrayProperties.php:426

Read a single array property's current value, through its getter (a direct property, a path alias, or a method).

function getArrayProperty(string $key, &$isRef = null, bool $store = false): mixed
$keystringthe array property's name
$isRef = null
$store = falseboolif true, use the property's store getter instead of its normal getter
returnsmixeda reference to the value (a typed property that was never assigned returns null rather than throwing PHP's usual "must not be accessed before initialization" error)
$person->getArrayProperty('name'); // 'Marc'

HiddenPath($path)

statictArrayProperties.php:261

The hidden property (ArrayProperty::isHidden) a json-path goes through, known from the declared types alone: of this class, or of a class a property on the way may hold -- every class of its type (owner/passhash when owner is an iClient, and User is one). A query tells the values it filters or sorts on through what it returns: an API query cannot use it (Route::extractQuery). What a property of no class holds (a plain array, mixed) is not looked into.

static function HiddenPath(array|string $path): ?string
$patharray | string
returnsnull | stringthe path to the hidden property (owner/passhash), or null if $path goes through none
User::HiddenPath('passhash'); // 'passhash'File::HiddenPath('owner/passhash'); // 'owner/passhash': its owner may be a UserUser::HiddenPath('roles/0/label'); // null

isArrayPropertySet($key, $store)

tArrayProperties.php:491
function isArrayPropertySet(string $key, bool $store = false): bool
See
iArrayProperties value is considered set if it is itself non-isEmpty)
$keystringthe array property's name
$store = falseboolif true, read through the store getter instead of the normal getter
returnsbooltrue if the property's current value differs from its schema default (a nested
(new Person())->isArrayPropertySet('name') === false // default value ('') is still in place

isEmpty()

tArrayProperties.php:477
function isEmpty(): bool
returnsbooltrue if every storable property still holds its schema default value (i.e. nothing meaningful has been set on this instance yet)
(new Person())->isEmpty() === true(new Person())->loadArray(['name' => 'Marc'])->isEmpty() === false

isHiddenPath($path)

tArrayProperties.php:352
function isHiddenPath(string $path): bool
$pathstringa property's name, or a json-path through the values of this object (owner/passhash)
returnsbooltrue if $path goes through a hidden property (ArrayProperty::isHidden), of this object or of one met on the way: what it holds is never exported (toArray)
$user->isHiddenPath('passhash'); // true: `@hidden`$file->isHiddenPath('owner/passhash'); // true when its owner is a User$file->isHiddenPath('owner/username'); // false

ListClassReferences($onlyStorable)

statictArrayProperties.php:61

Get a list of all the classes and their properties that are using references to this class.

static function ListClassReferences(bool $onlyStorable = false): array
$onlyStorable = falseboolif true, will only list properties that are storable. This is useful for getting all the entities that might make a reference in the repository to this class
returnsarray(classname => [name => ArrayProperty])
// if PersonWithFriend has: #[ArrayProperty] protected ?Person $friend; Person::ListClassReferences(); // [PersonWithFriend::class => ['friend' => ArrayProperty(...)]]

loadArray($data, $coerceOptions, $fromStore)

tArrayProperties.php:391

Set every entry of $data as an array property, through setArrayProperty (so each value is coerced by its property's schema). Unknown keys are dropped with a logged \MMO\error() rather than throwing.

function loadArray(array $data, array $coerceOptions = [], bool $fromStore = false): static
$dataarraykey => value, as produced by toArray / store
$coerceOptions = []arrayoptions forwarded to the schema coercer
$fromStore = falseboolif true, readonly properties can still be set (needed to reload a stored/persisted record, whose readonly properties were legitimately set once at store time)
returnsstatic$this, for chaining
$person = (new Person())->loadArray(['name' => 'Marc', 'age' => 42]);

mutate($type, $path, $value, $oldValue)

tArrayProperties.php:619

\MMO\core\interfaces\iMutationObserver::mutate -- reacts to a mutation that happened deep inside one of this object's array properties (e.g. an item of a nested array/object was changed through its own reference) by re-running that top-level property's setter, so any custom coercion/validation logic still applies.

function mutate(string $type, array $path, mixed $value, mixed $oldValue): bool
$typestringthe kind of mutation ('+', '-', '=', ...)
$patharraythe property path that changed, e.g. ['tags', 0]
$valuemixedthe new value
$oldValuemixedthe previous value
returnsbooltrue (this trait never rejects a mutation)

offsetExists($key)

tArrayProperties.php:665

\ArrayAccess::offsetExists -- tells whether $key is a *declared* #[ArrayProperty], not whether it currently holds a non-default value (use isArrayPropertySet for that).

function offsetExists(mixed $key): bool
$keymixed
returnsbool
isset($person['name']) === trueisset($person['does-not-exist']) === false

offsetUnset($key)

tArrayProperties.php:636

\ArrayAccess::offsetUnset -- equivalent to setting the property to null (its coerced value depends on the property's schema: e.g. a non-nullable string ends up as '', not literally null -- see setArrayProperty)

function offsetUnset(mixed $key): void
$keymixed
returnsvoid
unset($person['name']); // $person['name'] becomes '' (the schema's coerced form of null)

Schema()

statictArrayProperties.php:45

The JSON-Schema describing every #[ArrayProperty] of this class (built once and cached by ArrayProperties).

static function Schema(): MMO\core\schemas\Schema
returnsSchema
Person::Schema(); // a Schema instance with 'name' (string) and 'age' (integer) properties

SearchProperty($name)

statictArrayProperties.php:291
static function SearchProperty(string $name): MMO\core\attributes\SearchProperty
$namestring
returnsSearchProperty
throwsif $name is not a declared #[SearchProperty] (every class always has at least 'label', added automatically by ArrayProperties)
Person::SearchProperty('label')->name === 'label'

setArrayProperty($key, $value, $coerceOptions, $fromStore)

tArrayProperties.php:510

Set array property

function setArrayProperty( string $key, mixed $value, array $coerceOptions = [], bool $fromStore = false ): bool
$keystringthe array property's name
$valuemixedthe value to set
$coerceOptions = []arrayoptions to pass to the schema's coercer
$fromStore = falseboolif true, won't throw an exception for readonly properties if it is an actual storable property
returnsbooltrue if the value actually changed (a set to an equal value returns false and does nothing)
throwswhen a readonly properties is set.
$person->setArrayProperty('age', 43); // true: value changed$person->setArrayProperty('age', 43); // false the second time: already 43, no-op

setArrayPropertyOffset($key, $offset, $value, $coerceOptions)

tArrayProperties.php:571

Set/push a value into an array property

function setArrayPropertyOffset( string $key, string|int|null $offset, mixed $value, array $coerceOptions = [] ): bool
$keystringthe array property's name
$offsetstring | int | nullthe offset at wich to set the value
$valuemixedif null (and $offset is not null), unset the offset instead of setting it
$coerceOptions = []arraythe coerce options
returnsbooltrue if the value has changed
$person->setArrayPropertyOffset('tags', null, 'x'); // pushes 'x' onto the end of the list$person->setArrayPropertyOffset('tags', 0, 'z'); // sets index 0 to 'z'$person->setArrayPropertyOffset('tags', 0, null); // unsets index 0

store()

tArrayProperties.php:373

Export all array properties with store set to true.

function store(): arrayUsed to store the entity in a database
returnsarray
throws
$person->store(); // ['name' => 'Marc', 'age' => 42] -- every property here is storable by default

toArray($fields, $flatten, $recursive)

tArrayProperties.php:317

Export fields to an array.

function toArray(?array $fields = null, bool $flatten = false, bool $recursive = false): arrayPath in fields are allowed, so field 'a/b/c' will look for value at $this['a']['b']['c'] A hidden property ([`ArrayProperty::isHidden`](https://mcp.mmoframework.fr/documentation/mmo.core/php/attributes/ArrayProperty.md#arrayproperty-ishidden)) is never exported: not even named in $fields, nor further along a path (`owner/passhash`).
$fields = nullnull | arrayif null, export all non-hidden array properties.
$flatten = falseboolif true and a field is a path, the structure is not created to set the value
$recursive = falseboolif true, any nested iArrayProperties value is itself recursively converted with toArray(null, true, true); if false (the default), a nested value is left as-is (e.g. still an object, not a plain array)
returnsarray
throws
$person->toArray(); // ['name' => 'Marc', 'age' => 42]$personWithFriend->toArray(); // ['name' => 'Marc', 'friend' => Person{...}, 'tags' => [...]] -- $friend stays an object$personWithFriend->toArray(null, false, true); // same, but 'friend' => ['name' => ..., 'age' => ...] (recursively expanded)$personWithFriend->toArray(['friend/name']); // ['friend' => ['name' => 'Alice']] -- path fields rebuild the nesting$personWithFriend->toArray(['friend/name'], true); // ['friend/name' => 'Alice'] -- $flatten=true keeps the path as a single key$user->toArray(['username', 'passhash']); // ['username' => 'marc'] -- passhash is `@hidden`