1. Go to this page and download the library: Download dakujem/oliva library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
dakujem / oliva example snippets
use Dakujem\Oliva\TreeNodeContract;
$tree = (new TreeBuilder(
node: fn(mixed $data) => new Node($data), // A node factory.
))->build(
input: $anyDataCollection, // An iterable collection to build a tree from.
);
fn(mixed $data) => new \Dakujem\Oliva\Node($data);
fn(mixed $anyItem) => new MyNode(MyTransformer::transform($anyItem)),
use Dakujem\Oliva\MovableNodeContract;
use Any\Item;
use Dakujem\Oliva\MaterializedPath\Path;
use Dakujem\Oliva\MaterializedPath\TreeBuilder;
use Dakujem\Oliva\Node;
// The input data may be a result of an SQL query or any other iterable collection.
$collection = [
new Item(id: 0, path: ''), // the root
new Item(id: 1, path: '000'),
new Item(id: 2, path: '001'),
new Item(id: 3, path: '003'),
new Item(id: 4, path: '000000'),
new Item(id: 5, path: '002000'),
new Item(id: 6, path: '002'),
new Item(id: 7, path: '000001'),
];
$builder = new TreeBuilder(
node: fn(Item $item) => new Node($item), // How to create a node.
vector: Path::fixed( // How to extract path vector.
levelWidth: 3,
accessor: fn(Item $item) => $item->path,
),
);
$root = $builder->build(
input: $collection,
);
use Any\Item;
use Dakujem\Oliva\MaterializedPath\Path;
use Dakujem\Oliva\MaterializedPath\TreeBuilder;
use Dakujem\Oliva\Node;
$collection = [
new Item(id: 0, path: null), // the root
new Item(id: 1, path: '.0'),
new Item(id: 2, path: '.1'),
new Item(id: 3, path: '.3'),
new Item(id: 4, path: '.0.0'),
new Item(id: 5, path: '.2.0'),
new Item(id: 6, path: '.2'),
new Item(id: 7, path: '.0.1'),
];
$builder = new TreeBuilder(
node: fn(Item $item) => new Node($item), // How to create a node.
vector: Path::delimited( // How to extract path vector.
delimiter: '.',
accessor: fn(Item $item) => $item->path,
),
);
$root = $builder->build(
input: $collection,
);
use Any\Item;
use Dakujem\Oliva\Recursive\TreeBuilder;
use Dakujem\Oliva\Node;
$collection = [
new Item(id: 0, parent: null),
new Item(id: 1, parent: 0),
new Item(id: 2, parent: 0),
new Item(id: 3, parent: 0),
new Item(id: 4, parent: 1),
new Item(id: 5, parent: 6),
new Item(id: 6, parent: 0),
new Item(id: 7, parent: 1),
];
$builder = new TreeBuilder(
node: fn(Item $item) => new Node($item), // How to create a node.
selfRef: fn(Item $item) => $item->id, // How to get ID of self.
parentRef: fn(Item $item) => $item->parent, // How to get parent ID.
root: null, // The root node's parent value.
);
$root = $builder->build(
input: $collection,
);
use Any\Item;
use Dakujem\Oliva\Simple\TreeWrapper;
use Dakujem\Oliva\Node;
// $json = (new External\ApiConnector())->call('getJsonData');
// $rawData = json_decode($json);
// $rawData = yaml_parse_file('/config.yaml');
$rawData = [
'children' => [
[
'attributes' => [ ... ],
'children' => [
[
'attributes' => [ ... ],
'children' => [],
]
],
],
[
'attributes' => [ ... ],
'children' => [ ... ],
],
],
];
$builder = new TreeWrapper(
node: function(array $item) { // How to create a node.
unset($item['children']); // Note the unset call optimization.
return new Node($item);
},
children: fn(array $item):array => $item['children'] ?? [], // How to extract children.
);
$root = $builder->wrap($rawData);
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Simple\NodeBuilder;
// Tell the builder how to create a node.
// The `$item` parameter of the node factory
// will contain the first argument to each `NodeBuilder::node` call.
$proxy = new NodeBuilder(
node: fn(mixed $item) => new Node($item),
);
$root =
$proxy->node('root', [
$proxy->node('first child', [
$proxy->node('leaf of the first child node'),
$proxy->node('another leaf of the first child node'),
]),
$proxy->node('second child'),
]);
use Dakujem\Oliva\Node;
$root = new Node('root');
$root->addChild($child1 = new Node('first child'));
$root->addChild($child2 = new Node('second child'));
$child1->setParent($root);
$child2->setParent($root);
$leaf1 = new Node('leaf of the first child node');
$child1->addChild($leaf1);
$leaf1->setParent($child1);
$leaf2 = new Node('another leaf of the first child node');
$child1->addChild($leaf2);
$leaf2->setParent($child1);
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Tree;
$root = new Node('root');
Tree::link(node: $child1 = new Node('first child'), parent: $root);
Tree::link(node: $child2 = new Node('second child'), parent: $root);
Tree::link(node: new Node('leaf of the first child node'), parent: $child1);
Tree::link(node: new Node('another leaf of the first child node'), parent: $child1);
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Tree;
Tree::linkChildren(node: $root = new Node('root'), children: [
Tree::linkChildren(node: new Node('first child'), children: [
new Node('leaf of the first child node'),
new Node('another leaf of the first child node'),
]),
new Node('second child'),
]);
use Dakujem\Oliva\Iterator\Filter;
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Seed;
use Dakujem\Oliva\Tree;
// Create a find-by-id function (see Iterators section below):
$findById = fn(int $id, Node $tree) => Seed::firstOf(
new Filter($tree, fn(Node $node) => $node->data()?->id === $id)
);
// Move node with ID 7 into node ID 14:
$node = $findById(7, $root);
$parent = $findById(14, $root);
Tree::link($node, $parent);
use Dakujem\Oliva\Iterator\Traversal;
use Dakujem\Oliva\Iterator\PreOrderTraversal;
use Dakujem\Oliva\Iterator\PostOrderTraversal;
use Dakujem\Oliva\Iterator\LevelOrderTraversal;
foreach(Traversal::levelOrder($root) as $node) { /* ... */ }
foreach(new LevelOrderTraversal($root) as $node) { /* ... */ }
use Dakujem\Oliva\Node;
$root = new Node( ... );
foreach ($root as $node) {
// do something useful with the node
}
use Dakujem\Oliva\Iterator\Filter;
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Seed;
// Filter the input before building a tree.
$filteredCollection = new Filter($sourceCollection, fn(Item $item): bool => $item->id > 5);
$root = (new TreeBuilder( ... ))->build(
$filteredCollection,
);
// Iterate over leafs only.
$filter = new Filter($root, fn(Node $node): bool => $node->isLeaf());
foreach($filter as $node){
// ...
}
// Find the first node that matches a criterion (data with ID = 42).
$node = Seed::firstOf(new Filter(
input: $root,
accept: fn(Node $node): bool => $node->data()?->id === 42),
);
use Dakujem\Oliva\Iterator\Filter;
use Dakujem\Oliva\Node;
use Dakujem\Oliva\Seed;
// Create a find-by-id function.
$findById = fn(int $id, Node $tree): ?Node => Seed::firstOf(
new Filter($tree, fn(Node $node) => $node->data()?->id === $id)
);
// Search for any node by ID.
$node_42 = $findById(42, $root);
class TreeFinder
{
public function __construct(
public Node $tree,
) {
}
public function byId(int $id){ ... }
public function byName(string $name){ ... }
}
use Dakujem\Oliva\Node;
$root = new Node( ... );
foreach ($root as $key => $node) {
// The keys will increment 0, 1, 2, 3, ... and so on.
}
use Dakujem\Oliva\Iterator\PreOrderTraversal;
use Dakujem\Oliva\Node;
$iterator = new PreOrderTraversal(
node: $root,
key: fn(Node $node): int => $node->data()->id,
);
fn(
Dakujem\Oliva\TreeNodeContract $node,
array $vector, // array<int, string|int>
int $seq,
int $counter
): string|int
use Dakujem\Oliva\MaterializedPath;
use Dakujem\Oliva\Seed;
$source = Sql::getMeTheCommentsFor($article);
// When prepending `null`, care must be taken that both the extractor and the factory are able to cope with `null` values.
// Note the use of `?` nullable type hint indicator and null-safe `?->` operator.
$factory = fn(?Item $item) => new Node($item);
$pathExtractor = fn(?Item $item) => $item?->path;
$builder = new MaterializedPath\TreeBuilder( ... );
$root = $builder->build(
input: Seed::nullFirst($source), // `null` is prepended to the data
);
foreach(Seed::omitNull($root) as $node) { // The node with `null` data is omitted from the iteration
display($node);
}
use Dakujem\Oliva\MaterializedPath;
use Dakujem\Oliva\Seed;
$source = Sql::getMeTheCommentsFor($article);
// We need not take care of null values anymore.
$factory = fn(Item $item) => new Node($item);
$pathExtractor = fn(Item $item) => $item->path;
$builder = new MaterializedPath\TreeBuilder( ... );
$root = $builder->build(
input: Seed::merged([new Item(id: 0, path: '')], $source),
);
foreach(Seed::omitRoot($root) as $node) { // The root node is omitted from the iteration
display($node);
}
use Any\Item;
use Dakujem\Oliva\Recursive\TreeBuilder;
use Dakujem\Oliva\Node;
$collection = [
new Item(id: 100, parent: 99), // Note that no data with ID 99 is present
new Item(id: 101, parent: 100),
new Item(id: 102, parent: 100),
new Item(id: 103, parent: 100),
new Item(id: 104, parent: 101),
new Item(id: 105, parent: 106),
new Item(id: 106, parent: 100),
new Item(id: 107, parent: 101),
];
$builder = new TreeBuilder(
node: fn(Item $item) => new Node($item),
self: fn(Item $item) => $item->id,
parent: fn(Item $item) => $item->parent,
root: 99, // Here we indicate what the parent of the root is
);
$root = $builder->build(
input: $collection,
);
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.