Fr3nch13/CakePHP Utilities

TreeBehavior extends Behavior
in package

Makes the table to which this is attached to behave like a nested set and provides methods for managing and retrieving information out of the derived hierarchical structure.

Tables attaching this behavior are required to have a column referencing the parent row, and two other numeric columns (lft and rght) where the implicit order will be cached.

For more information on what is a nested set and a how it works refer to https://www.sitepoint.com/hierarchical-data-database-2/

Table of Contents

Properties

$_config  : array<string, mixed>
Runtime config
$_configInitialized  : bool
Whether the config property has already been configured with defaults
$_defaultConfig  : array<string, mixed>
Default config
$_primaryKey  : string
Cached copy of the first column in a table's primary key.
$_reflectionCache  : array<string, array<string|int, mixed>>
Reflection method cache for behaviors.
$_table  : Table
Table instance.

Methods

__construct()  : mixed
Constructor
afterSave()  : void
After save listener.
beforeDelete()  : void
Also deletes the nodes in the subtree of the entity to be delete
beforeSave()  : void
Before save listener.
childCount()  : int
Get the number of children nodes.
configShallow()  : $this
Merge provided config with existing config. Unlike `config()` which does a recursive merge for nested keys, this method does a simple merge.
findChildren()  : Query
Get the children nodes of the current model
findPath()  : Query
Custom finder method which can be used to return the list of nodes from the root to a specific node in the tree. This custom finder requires that the key 'for' is passed in the options containing the id of the node to get its path for.
findTreeList()  : Query
Gets a representation of the elements in the tree as a flat list where the keys are the primary key for the table and the values are the display field for the table.
formatTreeList()  : Query
Formats query as a flat list where the keys are the primary key for the table and the values are the display field for the table. Values are prefixed to visually indicate relative depth in the tree.
getConfig()  : mixed
Returns the config.
getConfigOrFail()  : mixed
Returns the config for this specific key.
getLevel()  : int|false
Returns the depth level of a node in the tree.
getTable()  : Table
Get the table instance this behavior is bound to.
implementedEvents()  : array<string, mixed>
Gets the Model callbacks this behavior is interested in.
implementedFinders()  : array<string|int, mixed>
implementedFinders
implementedMethods()  : array<string|int, mixed>
implementedMethods
initialize()  : void
Constructor hook method.
moveDown()  : EntityInterface|false
Reorders the node without changing the parent.
moveUp()  : EntityInterface|false
Reorders the node without changing its parent.
recover()  : void
Recovers the lft and right column values out of the hierarchy defined by the parent column.
removeFromTree()  : EntityInterface|false
Removes the current node from the tree, by positioning it as a new root and re-parents all children up one level.
setConfig()  : $this
Sets the config.
table()  : Table
Get the table instance this behavior is bound to.
verifyConfig()  : void
verifyConfig
_configDelete()  : void
Deletes a single config key.
_configRead()  : mixed
Reads a config key.
_configWrite()  : void
Writes a config key.
_ensureFields()  : void
Ensures that the provided entity contains non-empty values for the left and right fields
_getMax()  : int
Returns the maximum index value in the table.
_getNode()  : EntityInterface
Returns a single node from the tree from its primary key
_getPrimaryKey()  : string
Returns a single string value representing the primary key of the attached table
_moveDown()  : EntityInterface
Helper function used with the actual code for moveDown
_moveUp()  : EntityInterface
Helper function used with the actual code for moveUp
_recoverTree()  : int
Recursive method used to recover a single level of the tree
_reflectionCache()  : array<string|int, mixed>
Gets the methods implemented by this behavior
_removeFromTree()  : EntityInterface|false
Helper function containing the actual code for removeFromTree
_resolveMethodAliases()  : array<string|int, mixed>
Removes aliased methods that would otherwise be duplicated by userland configuration.
_scope()  : Query
Alters the passed query so that it only returns scoped records as defined in the tree configuration.
_setAsRoot()  : void
Updates the left and right column for the passed entity so it can be set as a new root in the tree. It also modifies the ordering in the rest of the tree so the structure remains valid
_setChildrenLevel()  : void
Set level for descendants.
_setParent()  : void
Sets the correct left and right values for the passed entity so it can be updated to a new parent. It also makes the hole in the tree so the node move can be done without corrupting the structure.
_sync()  : void
Auxiliary function used to automatically alter the value of both the left and right columns by a certain amount that match the passed conditions
_unmarkInternalTree()  : void
Helper method used to invert the sign of the left and right columns that are less than 0. They were set to negative values before so their absolute value wouldn't change while performing other tree transformations.

Properties

$_configInitialized

Whether the config property has already been configured with defaults

protected bool $_configInitialized = false

$_defaultConfig

Default config

protected array<string, mixed> $_defaultConfig = ['implementedFinders' => ['path' => 'findPath', 'children' => 'findChildren', 'treeList' => 'findTreeList'], 'implementedMethods' => ['childCount' => 'childCount', 'moveUp' => 'moveUp', 'moveDown' => 'moveDown', 'recover' => 'recover', 'removeFromTree' => 'removeFromTree', 'getLevel' => 'getLevel', 'formatTreeList' => 'formatTreeList'], 'parent' => 'parent_id', 'left' => 'lft', 'right' => 'rght', 'scope' => null, 'level' => null, 'recoverOrder' => null, 'cascadeCallbacks' => false]

These are merged with user-provided configuration when the behavior is used.

$_primaryKey

Cached copy of the first column in a table's primary key.

protected string $_primaryKey

$_reflectionCache

Reflection method cache for behaviors.

protected static array<string, array<string|int, mixed>> $_reflectionCache = []

Stores the reflected method + finder methods per class. This prevents reflecting the same class multiple times in a single process.

Methods

__construct()

Constructor

public __construct(Table $table[, array<string, mixed> $config = [] ]) : mixed

Merges config with the default and store in the config property

Parameters
$table : Table

The table this behavior is attached to.

$config : array<string, mixed> = []

The config for this behavior.

beforeSave()

Before save listener.

public beforeSave(EventInterface $event, EntityInterface $entity) : void

Transparently manages setting the lft and rght fields if the parent field is included in the parameters to be saved.

Parameters
$event : EventInterface

The beforeSave event that was fired

$entity : EntityInterface

the entity that is going to be saved

Tags
throws
RuntimeException

if the parent to set for the node is invalid

childCount()

Get the number of children nodes.

public childCount(EntityInterface $node[, bool $direct = false ]) : int
Parameters
$node : EntityInterface

The entity to count children for

$direct : bool = false

whether to count all nodes in the subtree or just direct children

Return values
int

Number of children nodes.

configShallow()

Merge provided config with existing config. Unlike `config()` which does a recursive merge for nested keys, this method does a simple merge.

public configShallow(array<string, mixed>|string $key[, mixed|null $value = null ]) : $this

Setting a specific value:

$this->configShallow('key', $value);

Setting a nested value:

$this->configShallow('some.nested.key', $value);

Updating multiple config settings at the same time:

$this->configShallow(['one' => 'value', 'another' => 'value']);
Parameters
$key : array<string, mixed>|string

The key to set, or a complete array of configs.

$value : mixed|null = null

The value to set.

Return values
$this

findChildren()

Get the children nodes of the current model

public findChildren(Query $query, array<string, mixed> $options) : Query

Available options are:

  • for: The id of the record to read.
  • direct: Boolean, whether to return only the direct (true), or all (false) children, defaults to false (all children).

If the direct option is set to true, only the direct children are returned (based upon the parent_id field)

Parameters
$query : Query

Query.

$options : array<string, mixed>

Array of options as described above

Tags
throws
InvalidArgumentException

When the 'for' key is not passed in $options

Return values
Query

findPath()

Custom finder method which can be used to return the list of nodes from the root to a specific node in the tree. This custom finder requires that the key 'for' is passed in the options containing the id of the node to get its path for.

public findPath(Query $query, array<string, mixed> $options) : Query
Parameters
$query : Query

The constructed query to modify

$options : array<string, mixed>

the list of options for the query

Tags
throws
InvalidArgumentException

If the 'for' key is missing in options

Return values
Query

findTreeList()

Gets a representation of the elements in the tree as a flat list where the keys are the primary key for the table and the values are the display field for the table.

public findTreeList(Query $query, array<string, mixed> $options) : Query

Values are prefixed to visually indicate relative depth in the tree.

Options

  • keyPath: A dot separated path to fetch the field to use for the array key, or a closure to return the key out of the provided row.
  • valuePath: A dot separated path to fetch the field to use for the array value, or a closure to return the value out of the provided row.
  • spacer: A string to be used as prefix for denoting the depth in the tree for each item
Parameters
$query : Query

Query.

$options : array<string, mixed>

Array of options as described above.

Return values
Query

formatTreeList()

Formats query as a flat list where the keys are the primary key for the table and the values are the display field for the table. Values are prefixed to visually indicate relative depth in the tree.

public formatTreeList(Query $query[, array<string, mixed> $options = [] ]) : Query

Options

  • keyPath: A dot separated path to the field that will be the result array key, or a closure to return the key from the provided row.
  • valuePath: A dot separated path to the field that is the array's value, or a closure to return the value from the provided row.
  • spacer: A string to be used as prefix for denoting the depth in the tree for each item.
Parameters
$query : Query

The query object to format.

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

Array of options as described above.

Return values
Query

Augmented query.

getConfig()

Returns the config.

public getConfig([string|null $key = null ][, mixed $default = null ]) : mixed

Usage

Reading the whole config:

$this->getConfig();

Reading a specific value:

$this->getConfig('key');

Reading a nested value:

$this->getConfig('some.nested.key');

Reading with default value:

$this->getConfig('some-key', 'default-value');
Parameters
$key : string|null = null

The key to get or null for the whole config.

$default : mixed = null

The return value when the key does not exist.

Return values
mixed

Configuration data at the named key or null if the key does not exist.

getConfigOrFail()

Returns the config for this specific key.

public getConfigOrFail(string $key) : mixed

The config value for this key must exist, it can never be null.

Parameters
$key : string

The key to get.

Tags
throws
InvalidArgumentException
Return values
mixed

Configuration data at the named key

getLevel()

Returns the depth level of a node in the tree.

public getLevel(EntityInterface|string|int $entity) : int|false
Parameters
$entity : EntityInterface|string|int

The entity or primary key get the level of.

Return values
int|false

Integer of the level or false if the node does not exist.

getTable()

Get the table instance this behavior is bound to.

public getTable() : Table

Use table() instead.

Return values
Table

The bound table instance.

implementedEvents()

Gets the Model callbacks this behavior is interested in.

public implementedEvents() : array<string, mixed>

By defining one of the callback methods a behavior is assumed to be interested in the related event.

Override this method if you need to add non-conventional event listeners. Or if you want your behavior to listen to non-standard events.

Return values
array<string, mixed>

implementedFinders()

implementedFinders

public implementedFinders() : array<string|int, mixed>

Provides an alias->methodname map of which finders a behavior implements. Example:

 [
   'this' => 'findThis',
   'alias' => 'findMethodName'
 ]

With the above example, a call to $table->find('this') will call $behavior->findThis() and a call to $table->find('alias') will call $behavior->findMethodName()

It is recommended, though not required, to define implementedFinders in the config property of child classes such that it is not necessary to use reflections to derive the available method list. See core behaviors for examples

Tags
throws
ReflectionException
Return values
array<string|int, mixed>

implementedMethods()

implementedMethods

public implementedMethods() : array<string|int, mixed>

Provides an alias->methodname map of which methods a behavior implements. Example:

 [
   'method' => 'method',
   'aliasedMethod' => 'somethingElse'
 ]

With the above example, a call to $table->method() will call $behavior->method() and a call to $table->aliasedMethod() will call $behavior->somethingElse()

It is recommended, though not required, to define implementedFinders in the config property of child classes such that it is not necessary to use reflections to derive the available method list. See core behaviors for examples

Tags
throws
ReflectionException
Return values
array<string|int, mixed>

initialize()

Constructor hook method.

public initialize(array<string|int, mixed> $config) : void
Parameters
$config : array<string|int, mixed>

The configuration settings provided to this behavior.

Tags
inheritDoc

moveDown()

Reorders the node without changing the parent.

public moveDown(EntityInterface $node[, int|true $number = 1 ]) : EntityInterface|false

If the node is the last child, or is a top level node with no subsequent node this method will return the same node without any changes

Parameters
$node : EntityInterface

The node to move

$number : int|true = 1

How many places to move the node or true to move to last position

Tags
throws
RecordNotFoundException

When node was not found

Return values
EntityInterface|false

the entity after being moved or false if $number is < 1

moveUp()

Reorders the node without changing its parent.

public moveUp(EntityInterface $node[, int|true $number = 1 ]) : EntityInterface|false

If the node is the first child, or is a top level node with no previous node this method will return the same node without any changes

Parameters
$node : EntityInterface

The node to move

$number : int|true = 1

How many places to move the node, or true to move to first position

Tags
throws
RecordNotFoundException

When node was not found

Return values
EntityInterface|false

$node The node after being moved or false if $number is < 1

recover()

Recovers the lft and right column values out of the hierarchy defined by the parent column.

public recover() : void

removeFromTree()

Removes the current node from the tree, by positioning it as a new root and re-parents all children up one level.

public removeFromTree(EntityInterface $node) : EntityInterface|false

Note that the node will not be deleted just moved away from its current position without moving its children with it.

Parameters
$node : EntityInterface

The node to remove from the tree

Return values
EntityInterface|false

the node after being removed from the tree or false on error

setConfig()

Sets the config.

public setConfig(array<string, mixed>|string $key[, mixed|null $value = null ][, bool $merge = true ]) : $this

Usage

Setting a specific value:

$this->setConfig('key', $value);

Setting a nested value:

$this->setConfig('some.nested.key', $value);

Updating multiple config settings at the same time:

$this->setConfig(['one' => 'value', 'another' => 'value']);
Parameters
$key : array<string, mixed>|string

The key to set, or a complete array of configs.

$value : mixed|null = null

The value to set.

$merge : bool = true

Whether to recursively merge or overwrite existing config, defaults to true.

Tags
throws
CakeException

When trying to set a key that is invalid.

Return values
$this

table()

Get the table instance this behavior is bound to.

public table() : Table
Return values
Table

The bound table instance.

verifyConfig()

verifyConfig

public verifyConfig() : void

Checks that implemented keys contain values pointing at callable.

Tags
throws
CakeException

if config are invalid

_configDelete()

Deletes a single config key.

protected _configDelete(string $key) : void
Parameters
$key : string

Key to delete.

Tags
throws
CakeException

if attempting to clobber existing config

_configRead()

Reads a config key.

protected _configRead(string|null $key) : mixed
Parameters
$key : string|null

Key to read.

_configWrite()

Writes a config key.

protected _configWrite(array<string, mixed>|string $key, mixed $value[, string|bool $merge = false ]) : void
Parameters
$key : array<string, mixed>|string

Key to write to.

$value : mixed

Value to write.

$merge : string|bool = false

True to merge recursively, 'shallow' for simple merge, false to overwrite, defaults to false.

Tags
throws
CakeException

if attempting to clobber existing config

_ensureFields()

Ensures that the provided entity contains non-empty values for the left and right fields

protected _ensureFields(EntityInterface $entity) : void
Parameters
$entity : EntityInterface

The entity to ensure fields for

_getMax()

Returns the maximum index value in the table.

protected _getMax() : int
Return values
int

_getPrimaryKey()

Returns a single string value representing the primary key of the attached table

protected _getPrimaryKey() : string
Return values
string

_recoverTree()

Recursive method used to recover a single level of the tree

protected _recoverTree([int $lftRght = 1 ][, mixed $parentId = null ][, int $level = 0 ]) : int
Parameters
$lftRght : int = 1

The starting lft/rght value

$parentId : mixed = null

the parent id of the level to be recovered

$level : int = 0

Node level

Return values
int

The next lftRght value

_reflectionCache()

Gets the methods implemented by this behavior

protected _reflectionCache() : array<string|int, mixed>

Uses the implementedEvents() method to exclude callback methods. Methods starting with _ will be ignored, as will methods declared on Cake\ORM\Behavior

Tags
throws
ReflectionException
Return values
array<string|int, mixed>

_resolveMethodAliases()

Removes aliased methods that would otherwise be duplicated by userland configuration.

protected _resolveMethodAliases(string $key, array<string, mixed> $defaults, array<string, mixed> $config) : array<string|int, mixed>
Parameters
$key : string

The key to filter.

$defaults : array<string, mixed>

The default method mappings.

$config : array<string, mixed>

The customized method mappings.

Return values
array<string|int, mixed>

A de-duped list of config data.

_scope()

Alters the passed query so that it only returns scoped records as defined in the tree configuration.

protected _scope(Query $query) : Query
Parameters
$query : Query

the Query to modify

Return values
Query

_setAsRoot()

Updates the left and right column for the passed entity so it can be set as a new root in the tree. It also modifies the ordering in the rest of the tree so the structure remains valid

protected _setAsRoot(EntityInterface $entity) : void
Parameters
$entity : EntityInterface

The entity to set as a new root

_setParent()

Sets the correct left and right values for the passed entity so it can be updated to a new parent. It also makes the hole in the tree so the node move can be done without corrupting the structure.

protected _setParent(EntityInterface $entity, mixed $parent) : void
Parameters
$entity : EntityInterface

The entity to re-parent

$parent : mixed

the id of the parent to set

Tags
throws
RuntimeException

if the parent to set to the entity is not valid

_sync()

Auxiliary function used to automatically alter the value of both the left and right columns by a certain amount that match the passed conditions

protected _sync(int $shift, string $dir, string $conditions[, bool $mark = false ]) : void
Parameters
$shift : int

the value to use for operating the left and right columns

$dir : string

The operator to use for shifting the value (+/-)

$conditions : string

a SQL snipped to be used for comparing left or right against it.

$mark : bool = false

whether to mark the updated values so that they can not be modified by future calls to this function.

_unmarkInternalTree()

Helper method used to invert the sign of the left and right columns that are less than 0. They were set to negative values before so their absolute value wouldn't change while performing other tree transformations.

protected _unmarkInternalTree() : void

        
On this page

Search results