Class TreeBehavior

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/

Cake\ORM\Behavior implements Cake\Event\EventListenerInterface uses Cake\Core\InstanceConfigTrait
Extended by Cake\ORM\Behavior\TreeBehavior

Properties summary

  • $_defaultConfig protected
    array
    Default config
  • $_primaryKey protected
    string
    Cached copy of the first column in a table's primary key.

Inherited Properties

Method Summary

  • _ensureFields() protected

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

  • _getMax() protected
    Returns the maximum index value in the table.
  • _getNode() protected
    Returns a single node from the tree from its primary key
  • _getPrimaryKey() protected
    Returns a single string value representing the primary key of the attached table
  • _moveDown() protected
    Helper function used with the actual code for moveDown
  • _moveUp() protected
    Helper function used with the actual code for moveUp
  • _recoverTree() protected
    Recursive method used to recover a single level of the tree
  • _removeFromTree() protected
    Helper function containing the actual code for removeFromTree
  • _scope() protected

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

  • _setAsRoot() protected

    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

  • Set level for descendants.
  • _setParent() protected

    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() protected

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

  • 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.

  • afterSave() public
    After save listener.
  • Also deletes the nodes in the subtree of the entity to be delete
  • beforeSave() public

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

  • childCount() public
    Get the number of children nodes.
  • Get the children nodes of the current model
  • findPath() public

    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.

  • 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. Values are prefixed to visually indicate relative depth in the tree.

  • 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.

  • getLevel() public
    Returns the depth level of a node in the tree.
  • initialize() public
    Constructor hook method.
  • moveDown() public
    Reorders the node without changing the parent.
  • moveUp() public
    Reorders the node without changing its parent.
  • recover() public

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

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

Method Detail

_ensureFields()source protected

_ensureFields( Cake\Datasource\EntityInterface $entity )

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

Parameters

Cake\Datasource\EntityInterface $entity
The entity to ensure fields for

_getMax()source protected

_getMax( )

Returns the maximum index value in the table.

Returns

integer

_getNode()source protected

_getNode( mixed $id )

Returns a single node from the tree from its primary key

Parameters

mixed $id
Record id.

Returns

Cake\Datasource\EntityInterface

Throws

Cake\Datasource\Exception\RecordNotFoundException
When node was not found

_getPrimaryKey()source protected

_getPrimaryKey( )

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

Returns

string

_moveDown()source protected

_moveDown( Cake\Datasource\EntityInterface $node , integer|boolean $number )

Helper function used with the actual code for moveDown

Parameters

Cake\Datasource\EntityInterface $node
The node to move
integer|boolean $number
How many places to move the node, or true to move to last position

Returns

Cake\Datasource\EntityInterface|boolean
$node The node after being moved or false on failure

Throws

Cake\Datasource\Exception\RecordNotFoundException
When node was not found

_moveUp()source protected

_moveUp( Cake\Datasource\EntityInterface $node , integer|boolean $number )

Helper function used with the actual code for moveUp

Parameters

Cake\Datasource\EntityInterface $node
The node to move
integer|boolean $number
How many places to move the node, or true to move to first position

Returns

Cake\Datasource\EntityInterface|boolean
$node The node after being moved or false on failure

Throws

Cake\Datasource\Exception\RecordNotFoundException
When node was not found

_recoverTree()source protected

_recoverTree( integer $counter 0 , mixed $parentId null , integer $level -1 )

Recursive method used to recover a single level of the tree

Parameters

integer $counter optional 0
The Last left column value that was assigned
mixed $parentId optional null
the parent id of the level to be recovered
integer $level optional -1
Node level

Returns

integer
The next value to use for the left column

_removeFromTree()source protected

_removeFromTree( Cake\Datasource\EntityInterface $node )

Helper function containing the actual code for removeFromTree

Parameters

Cake\Datasource\EntityInterface $node
The node to remove from the tree

Returns

Cake\Datasource\EntityInterface|false

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


_scope()source protected

_scope( Cake\ORM\Query $query )

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

Parameters

Cake\ORM\Query $query
the Query to modify

Returns

Cake\ORM\Query

_setAsRoot()source protected

_setAsRoot( Cake\Datasource\EntityInterface $entity )

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

Parameters

Cake\Datasource\EntityInterface $entity
The entity to set as a new root

_setChildrenLevel()source protected

_setChildrenLevel( Cake\Datasource\EntityInterface $entity )

Set level for descendants.

Parameters

Cake\Datasource\EntityInterface $entity
The entity whose descendants need to be updated.

_setParent()source protected

_setParent( Cake\Datasource\EntityInterface $entity , mixed $parent )

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.

Parameters

Cake\Datasource\EntityInterface $entity
The entity to re-parent
mixed $parent
the id of the parent to set

Throws

RuntimeException
if the parent to set to the entity is not valid

_sync()source protected

_sync( integer $shift , string $dir , string $conditions , boolean $mark false )

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

Parameters

integer $shift
the value to use for operating the left and right columns
string $dir
The operator to use for shifting the value (+/-)
string $conditions

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

boolean $mark optional false

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

_unmarkInternalTree()source protected

_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.

afterSave()source public

afterSave( Cake\Event\Event $event , Cake\Datasource\EntityInterface $entity )

After save listener.

Manages updating level of descendants of currently saved entity.

Parameters

Cake\Event\Event $event
The afterSave event that was fired
Cake\Datasource\EntityInterface $entity
the entity that is going to be saved

beforeDelete()source public

beforeDelete( Cake\Event\Event $event , Cake\Datasource\EntityInterface $entity )

Also deletes the nodes in the subtree of the entity to be delete

Parameters

Cake\Event\Event $event
The beforeDelete event that was fired
Cake\Datasource\EntityInterface $entity
The entity that is going to be saved

beforeSave()source public

beforeSave( Cake\Event\Event $event , Cake\Datasource\EntityInterface $entity )

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

Parameters

Cake\Event\Event $event
The beforeSave event that was fired
Cake\Datasource\EntityInterface $entity
the entity that is going to be saved

Throws

RuntimeException
if the parent to set for the node is invalid

childCount()source public

childCount( Cake\Datasource\EntityInterface $node , boolean $direct false )

Get the number of children nodes.

Parameters

Cake\Datasource\EntityInterface $node
The entity to count children for
boolean $direct optional false

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

Returns

integer
Number of children nodes.

findChildren()source public

findChildren( Cake\ORM\Query $query , array $options )

Get the children nodes of the current model

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

Cake\ORM\Query $query
Query.
array $options
Array of options as described above

Returns

Cake\ORM\Query

Throws

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

findPath()source public

findPath( Cake\ORM\Query $query , array $options )

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.

Parameters

Cake\ORM\Query $query
The constructed query to modify
array $options
the list of options for the query

Returns

Cake\ORM\Query

Throws

InvalidArgumentException
If the 'for' key is missing in options

findTreeList()source public

findTreeList( Cake\ORM\Query $query , array $options )

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. 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

Cake\ORM\Query $query
Query.
array $options
Array of options as described above.

Returns

Cake\ORM\Query

formatTreeList()source public

formatTreeList( Cake\ORM\Query $query , array $options [] )

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.

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

Cake\ORM\Query $query
The query object to format.
array $options optional []
Array of options as described above.

Returns

Cake\ORM\Query
Augmented query.

getLevel()source public

getLevel( integer|string|Cake\Datasource\EntityInterface $entity )

Returns the depth level of a node in the tree.

Parameters

integer|string|Cake\Datasource\EntityInterface $entity
The entity or primary key get the level of.

Returns

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

initialize()source public

initialize( array $config )

Constructor hook method.

Parameters

array $config
The configuration settings provided to this behavior.

Overrides

Cake\ORM\Behavior::initialize()

moveDown()source public

moveDown( Cake\Datasource\EntityInterface $node , integer|boolean $number 1 )

Reorders the node without changing the parent.

If the node is the last child, or is a top level node with no subsequent node this method will return false

Parameters

Cake\Datasource\EntityInterface $node
The node to move
integer|boolean $number optional 1
How many places to move the node or true to move to last position

Returns

Cake\Datasource\EntityInterface|boolean
the entity after being moved or false on failure

Throws

Cake\Datasource\Exception\RecordNotFoundException
When node was not found

moveUp()source public

moveUp( Cake\Datasource\EntityInterface $node , integer|boolean $number 1 )

Reorders the node without changing its parent.

If the node is the first child, or is a top level node with no previous node this method will return false

Parameters

Cake\Datasource\EntityInterface $node
The node to move
integer|boolean $number optional 1
How many places to move the node, or true to move to first position

Returns

Cake\Datasource\EntityInterface|boolean
$node The node after being moved or false on failure

Throws

Cake\Datasource\Exception\RecordNotFoundException
When node was not found

recover()source public

recover( )

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

removeFromTree()source public

removeFromTree( Cake\Datasource\EntityInterface $node )

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

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

Parameters

Cake\Datasource\EntityInterface $node
The node to remove from the tree

Returns

Cake\Datasource\EntityInterface|false

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


Methods inherited from Cake\ORM\Behavior

__construct()source public

__construct( Cake\ORM\Table $table , array $config [] )

Constructor

Merges config with the default and store in the config property

Parameters

Cake\ORM\Table $table
The table this behavior is attached to.
array $config optional []
The config for this behavior.

_reflectionCache()source protected

_reflectionCache( )

Gets the methods implemented by this behavior

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

Returns

array

_resolveMethodAliases()source protected

_resolveMethodAliases( string $key , array $defaults , array $config )

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

Parameters

string $key
The key to filter.
array $defaults
The default method mappings.
array $config
The customized method mappings.

Returns

array
A de-duped list of config data.

getTable()source public

getTable( )

Get the table instance this behavior is bound to.

Returns

Cake\ORM\Table
The bound table instance.

implementedEvents()source public

implementedEvents( )

Gets the Model callbacks this behavior is interested in.

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.

Returns

array

Implementation of

Cake\Event\EventListenerInterface::implementedEvents()

implementedFinders()source public

implementedFinders( )

implementedFinders

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

Returns

array

implementedMethods()source public

implementedMethods( )

implementedMethods

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

Returns

array

verifyConfig()source public

verifyConfig( )

verifyConfig

Checks that implemented keys contain values pointing at callable.

Throws

Cake\Core\Exception\Exception
if config are invalid

Methods used from Cake\Core\InstanceConfigTrait

_configDelete()source protected

_configDelete( string $key )

Deletes a single config key.

Parameters

string $key
Key to delete.

Throws

Cake\Core\Exception\Exception
if attempting to clobber existing config

_configRead()source protected

_configRead( string|null $key )

Reads a config key.

Parameters

string|null $key
Key to read.

Returns

mixed

_configWrite()source protected

_configWrite( string|array $key , mixed $value , boolean|string $merge false )

Writes a config key.

Parameters

string|array $key
Key to write to.
mixed $value
Value to write.
boolean|string $merge optional false

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

Throws

Cake\Core\Exception\Exception
if attempting to clobber existing config

config()source public

config( string|array|null $key null , mixed|null $value null , boolean $merge true )

Gets/Sets the config.

Usage

Reading the whole config:

$this->config();

Reading a specific value:

$this->config('key');

Reading a nested value:

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

Setting a specific value:

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

Setting a nested value:

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

Updating multiple config settings at the same time:

$this->config(['one' => 'value', 'another' => 'value']);

Deprecated

3.4.0 use setConfig()/getConfig() instead.

Parameters

string|array|null $key optional null
The key to get/set, or a complete array of configs.
mixed|null $value optional null
The value to set.
boolean $merge optional true
Whether to recursively merge or overwrite existing config, defaults to true.

Returns

mixed
Config value being read, or the object itself on write operations.

Throws

Cake\Core\Exception\Exception
When trying to set a key that is invalid.

configShallow()source public

configShallow( string|array $key , mixed|null $value null )

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

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

string|array $key
The key to set, or a complete array of configs.
mixed|null $value optional null
The value to set.

Returns


$this

getConfig()source public

getConfig( string|null $key null , mixed $default null )

Returns the config.

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

string|null $key optional null
The key to get or null for the whole config.
mixed $default optional null
The return value when the key does not exist.

Returns

mixed
Config value being read.

setConfig()source public

setConfig( string|array $key , mixed|null $value null , boolean $merge true )

Sets the config.

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

string|array $key
The key to set, or a complete array of configs.
mixed|null $value optional null
The value to set.
boolean $merge optional true
Whether to recursively merge or overwrite existing config, defaults to true.

Returns


$this

Throws

Cake\Core\Exception\Exception
When trying to set a key that is invalid.

Properties detail

$_defaultConfigsource

protected array

Default config

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

[
    '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,
]

$_primaryKeysource

protected string

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

© 2005–2017 The Cake Software Foundation, Inc.
Licensed under the MIT License.
CakePHP is a registered trademark of Cake Software Foundation, Inc.
We are not endorsed by or affiliated with CakePHP.
https://api.cakephp.org/3.4/class-Cake.ORM.Behavior.TreeBehavior.html