Skip to content

Instantly share code, notes, and snippets.

@mistic100
Last active August 20, 2019 14:51
Show Gist options
  • Save mistic100/06ef01f7f7d8a101dbd3 to your computer and use it in GitHub Desktop.
Save mistic100/06ef01f7f7d8a101dbd3 to your computer and use it in GitHub Desktop.
[PHP] Recursive builder pattern
<?php
/**
* Recursive builder pattern
*
* Usage:
* $tree = \Tree\Builder::init()
* ->setName('parent')
* ->addChild()
* ->setName('child 1')
* ->end()
* ->addChild()
* ->setName('child 2')
* ->addChild()
* ->setName('child 2.1')
* ->end()
* ->addChild()
* ->setName('child 2.2')
* ->build();
*
*/
namespace Tree;
/**
* @class Node
*/
class Node
{
public $name;
public $children;
public function __contruct()
{
$this->children = array();
}
}
/**
* @class Builder
*/
class Builder
{
private $el;
private $parent;
/**
* Private constructor
*/
private function __construct(Node $el, Builder $parent = null)
{
$this->el = $el;
$this->parent = $parent;
}
/**
* Init the tree builder
* @param $parent \Tree\Builder optional
* @return \Tree\Builder
*/
static function init(Builder $parent = null)
{
return new self(new Node(), $parent);
}
/**
* Set node name
* @param $name string
* @return \Tree\Builder
*/
function setName($name)
{
$this->el->name = $name;
return $this;
}
/**
* Add a child node
* @return \Tree\Builder child builder
*/
function addChild()
{
$builder = self::init($this);
$this->el->children[] = $builder->el;
return $builder;
}
/**
* Return to the parent builder (or itself if root)
* @return \Tree\Builder
*/
function end()
{
if ($this->parent == null)
{
return $this;
}
else
{
return $this->parent;
}
}
/**
* Return the final object
* @return \Tree\Node
*/
function build()
{
if ($this->parent == null)
{
return $this->el;
}
else
{
return $this->parent->build();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment