/** * Create a hierarchy of roles. * @param array $inHierarchy The hierarchy of roles. * @throws \Exception */ public function __construct($inHierarchyOrTopRole) { if (is_array($inHierarchyOrTopRole)) { $this->__tree = Tree::fromArray($inHierarchyOrTopRole, null, 'role', 'access'); $this->__currentRole = $this->__tree->getRoot(); $this->__index = $this->__tree->index(function ($x) { return $x; }, true); $this->__init = true; } elseif (is_string($inHierarchyOrTopRole)) { $this->__tree = new Tree($inHierarchyOrTopRole); $this->__currentRole = $this->__index[$inHierarchyOrTopRole] = $this->__tree->getRoot(); } else { throw new \Exception("Invalid value for hierarchy' specification. Valid values are strings or arrays."); } }
public function testIsParentOf() { /** * @var Node $root * @var Node $A * @var Node $AA * @var Node $B * @var Node $C * @var Node $D * @var Node $E * @var Node $J */ $root = $this->__treeByData->getRoot(); $found = $this->__treeByData->search('A'); $this->assertEquals(count($found), 2); $A = $found[0]; $AA = $found[1]; $found = $this->__treeByData->search('B'); $this->assertEquals(count($found), 1); $B = $found[0]; $found = $this->__treeByData->search('C'); $this->assertEquals(count($found), 1); $C = $found[0]; $found = $this->__treeByData->search('D'); $this->assertEquals(count($found), 1); $D = $found[0]; $found = $this->__treeByData->search('E'); $this->assertEquals(count($found), 1); $E = $found[0]; $found = $this->__treeByData->search('J'); $this->assertEquals(count($found), 1); $J = $found[0]; $this->assertTrue($A->isParentOf($B)); $this->assertTrue($A->isParentOf($C)); $this->assertTrue($A->isParentOf($D)); $this->assertTrue($D->isParentOf($E)); $this->assertTrue($D->isParentOf($J)); $this->assertFalse($A->isParentOf($root)); $this->assertFalse($B->isParentOf($A)); $this->assertFalse($C->isParentOf($A)); $this->assertFalse($D->isParentOf($A)); $this->assertFalse($B->isParentOf($B)); $this->assertFalse($J->isParentOf($D)); // ... It's OK }
$this->__creationDate = new DateTime(); $this->__creationDate->add(new DateInterval('P' . self::$__inter . 'D')); self::$__inter += 1; } public function serialise($inOptFormat = 'Y-m-d H:i:s') { return $this->__creationDate->format($inOptFormat); } } $array = array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array()), array('data' => new MyDate(), 'children' => array()), array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array()), array('data' => new MyDate(), 'children' => array()))), array('data' => new MyDate(), 'children' => array()))), array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array(array('data' => new MyDate(), 'children' => array()), array('data' => new MyDate(), 'children' => array()))))))))))))); /** * @var array This array will be manipulated by the traversal function. * The traversal function if free to use this array as it sees fit. */ $result = []; /** * @var callable The traversal function. * @param array $inCurrent Current node. * @param bool $isLead This boolean tells the function whether the current node is a leaf or not. * @param (array|null $inParent Associative array that represents the parent's node. * This value may be null is the current node is the getRoot node. * @param array $inOutResult Permanent variable used by the function to organize and store values. */ $traversalFunction = function (array $inCurrent, $isLead, $inParent, &$inOutResult) { /** @var MyDate $data */ $data = $inCurrent['data']; $inOutResult[] = $data->serialise(); // Call the data' serializer. }; Tree::arrayTraverse($array, $traversalFunction, $result); echo print_r($result, true);
<?php /** * This example shows how to search for a node's data within the entire tree. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; use dbeurive\Tree\Node; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); /** * @var callable Function used to compare two nodes' values. * @param mixed $value1 First value. * @param mixed $value2 Second value. * @return bool If $value1 is equal to $value2, then the function returns the value "true". * Otherwise the function returns the value "false". */ $optionalCompareFunction = function ($value1, $value2) { return $value1 == $value2; }; /** * @var array List of nodes. */ $found = $tree->search("A", 0, $optionalCompareFunction); /** * @var int $_index * @var Node $_node */ foreach ($found as $_index => $_node) { $label = $_node->isLeaf() ? "this is a leaf" : "this is not a leaf"; echo spl_object_hash($_node) . " " . $_node->getData() . " ({$label})\n";
<?php /** * This example shows how to select nodes based on their data's values. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); /** * This function is used to select nodes based on their values. * @param string $inData Nodes' data. * @return bool If the data must be kept, then the function returns the value true. Otherwise, it returns tha value true. */ $dataSelector = function ($inData) { return 1 === preg_match('/^E+$/', $inData); }; // We should select the nodes which data is: "E", "EE" and "EEE". $selection = $tree->select($dataSelector); /** @var \dbeurive\Tree\Node $_node */ foreach ($selection as $_node) { print $_node->getData() . " -> Object(" . spl_object_hash($_node) . ")\n"; }
public function __construct() { $this->__creationDate = new DateTime(); $this->__creationDate->add(new DateInterval('P' . self::$__inter . 'D')); if (self::$__inter > 3) { self::$__inter = 0; } else { self::$__inter += 1; } } public function serialise($inOptFormat = 'Y-m-d H:i:s') { return $this->__creationDate->format($inOptFormat); } } $tree = new Tree(new MyDate()); // Root = date. $tree->getRoot()->addChild(new MyDate())->end()->addChild(new MyDate())->end()->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->end()->addChild(new MyDate())->end()->end()->addChild(new MyDate())->end()->end()->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->end()->addChild(new MyDate())->end()->end()->end()->end()->end()->end(); /** * @var callable This function generates an index from a given data. * @param MyDate $inData Data to serialize. * @return string The function returns the generated index. */ $indexBuilder = function (MyDate $inData) { return $inData->serialise(); // Call the data' serializer. }; // Please note the use of the second parameter (which value is false). // This tells the function that indexes should point to array of nodes. $index = $tree->index($indexBuilder, false); /** @var array $_value */
<?php /** * this example shows how to create a tree using the tree builder. It creates an instance of class \dbeurive\Tree\Tree. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); // Generate the DOT representation, so we can verify that the tree is OK. $dot = $tree->toDot(); $fd = fopen(__DIR__ . DIRECTORY_SEPARATOR . "treeBuilder.dot", "w"); fwrite($fd, $dot); fclose($fd); print "To create a graphical representation of the tree, install GRAPHVIZ and run the following command:\n"; print "dot -Tgif -Ograph treeBuilder.dot\n";
<?php /** * This example shows how to convert a tree defined as an object of class \dbeurive\Tree\Tree into the "array representation" (an array of imbricated arrays). */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); $array = $tree->toArray(); print print_r($array, true) . "\n";
class MyDate { private $__creationDate = null; private static $__inter = 0; public function __construct() { $this->__creationDate = new DateTime(); $this->__creationDate->add(new DateInterval('P' . self::$__inter . 'D')); self::$__inter += 1; } public function serialise($inOptFormat = 'Y-m-d H:i:s') { return $this->__creationDate->format($inOptFormat); } } $tree = new Tree(new MyDate()); // Root = date. $tree->getRoot()->addChild(new MyDate())->end()->addChild(new MyDate())->end()->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->end()->addChild(new MyDate())->end()->end()->addChild(new MyDate())->end()->end()->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->addChild(new MyDate())->end()->addChild(new MyDate())->end()->end()->end()->end()->end()->end(); /** * @var array This array will be manipulated by the traversal function. * The traversal function if free to use this array as it sees fit. */ $result = []; /** * @var callable The traversal function. * @param Node $inNode The current node. * @param array $inOutResult Reference to the array used by the traversal function. * The traversal function if free to use this array as it sees fit. */ $traversalFunction = function (Node $inNode, array &$inOutResult) { /** @var MyDate $data */
<?php /** * This example illustrates the procedure to create a tree (an object of class \dbeurive\Tree\Tree from an array of imbricated arrays. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; $array = array('data' => 'getRoot', 'children' => array(array('data' => 'A', 'children' => array()), array('data' => 'B', 'children' => array()), array('data' => 'C', 'children' => array(array('data' => 'D', 'children' => array(array('data' => 'E', 'children' => array(array('data' => 'EE', 'children' => array()), array('data' => 'EEE', 'children' => array()))), array('data' => 'F', 'children' => array()))), array('data' => 'A', 'children' => array(array('data' => 'H', 'children' => array(array('data' => 'I', 'children' => array(array('data' => 'J', 'children' => array(array('data' => 'K', 'children' => array()), array('data' => 'L', 'children' => array()))))))))))))); $tree = Tree::fromArray($array); // Generate the DOT representation, so we can verify that the tree is OK. $dot = $tree->toDot(); $fd = fopen(__DIR__ . DIRECTORY_SEPARATOR . "array2tree.dot", "w"); fwrite($fd, $dot); fclose($fd); print "To create a graphical representation of the tree, install GRAPHVIZ and run the following command:\n"; print "dot -Tgif -Ograph array2tree.dot\n";
<?php /** * This example shows how search for nodes with given values. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); /** * This function is used to compare two nodes' values. * @param string $inData1 First value to compare. * @param string $inData2 Second value to compare. * @return bool If the values are identical, then the function returns the value true. Otherwise, it returns the value true. */ $dataComparator = function ($inData1, $inData2) { return $inData1 === $inData2; }; // We should select 2 nodes. $result = $tree->search("A", 0, $dataComparator); /** @var \dbeurive\Tree\Node $_node */ foreach ($result as $_node) { print $_node->getData() . " -> Object(" . spl_object_hash($_node) . ")\n"; }
$root = new Node("root"); $A = new Node("A"); $AA = new Node("A"); $B = new Node("B"); $C = new Node("C"); $D = new Node("D"); $E = new Node("E"); $EE = new Node("EE"); $EEE = new Node("EEE"); $F = new Node("F"); $H = new Node("H"); $I = new Node("I"); $J = new Node("J"); $K = new Node("K"); $L = new Node("L"); $tree = new Tree($root); $tree->getRoot()->addChild($A)->end()->addChild($B)->end()->addChild($C)->addChild($D)->addChild($E)->addChild($EE)->end()->addChild($EEE)->end()->end()->addChild($F)->end()->end()->addChild($AA)->addChild($H)->addChild($I)->addChild($J)->addChild($K)->end()->addChild($L)->end()->end()->end()->end()->end()->end(); // --------------------------------------------------------------------------------------------------------------------- // Testing ancestry // --------------------------------------------------------------------------------------------------------------------- print "Is <" . $root->getData() . "> an ascendant of <" . $L->getData() . "> ? " . ($root->isAscendantOf($L) ? 'yes' : 'no') . "\n"; print "Is <" . $root->getData() . "> an ascendant of <" . $F->getData() . "> ? " . ($root->isAscendantOf($F) ? 'yes' : 'no') . "\n"; print "Is <" . $L->getData() . "> an ascendant of <" . $K->getData() . "> ? " . ($L->isAscendantOf($K) ? 'yes' : 'no') . "\n"; // --------------------------------------------------------------------------------------------------------------------- // Testing descendance // --------------------------------------------------------------------------------------------------------------------- print "Is <" . $root->getData() . "> a descendant of <" . $L->getData() . "> ? " . ($root->isDescendantOf($L) ? 'yes' : 'no') . "\n"; print "Is <" . $root->getData() . "> a descendant of <" . $F->getData() . "> ? " . ($root->isDescendantOf($F) ? 'yes' : 'no') . "\n"; print "Is <" . $L->getData() . "> a descendant of <" . $K->getData() . "> ? " . ($L->isDescendantOf($K) ? 'yes' : 'no') . "\n"; // --------------------------------------------------------------------------------------------------------------------- // Is a node the parent of another node ?
<?php /** * this example shows how to traverse a tree that is an object of class \dbeurive\Tree\Tree. */ include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; use dbeurive\Tree\Tree; use dbeurive\Tree\Node; $tree = new Tree("getRoot"); $tree->getRoot()->addChild("A")->end()->addChild("B")->end()->addChild("C")->addChild("D")->addChild("E")->addChild("EE")->end()->addChild("EEE")->end()->end()->addChild("F")->end()->end()->addChild("A")->addChild('H')->addChild("I")->addChild("J")->addChild("K")->end()->addChild("L")->end()->end()->end()->end()->end()->end(); /** * @var array This array will be manipulated by the traversal function. * The traversal function if free to use this array as it sees fit. */ $result = []; /** * @var callable The traversal function. * @param Node $inNode The current node. * @param array $inOutResult Reference to the array used by the traversal function. * The traversal function if free to use this array as it sees fit. */ $traversalFunction = function (Node $inNode, array &$inOutResult) { $inOutResult[] = $inNode->getData(); }; $tree->traverse($traversalFunction, $result); echo print_r($result, true);