//
// If structures like these are required ten they can usually be achieved by wrapping the raw
// text nodes in a .
use function MRBS\escape_html;
use function MRBS\is_assoc;
class Element
{
private $tag;
private $self_closing;
private $attributes = array();
private $text = null;
private $raw = false;
private $text_at_start = false;
private $elements = [];
private $next = null;
private $prev = null;
public function __construct(string $tag, bool $self_closing=false)
{
$this->tag = $tag;
$this->self_closing = $self_closing;
}
// If $raw is true then the text will not be put through escape_html(). Only to
// be used for trusted text.
public function setText(string $text, bool $text_at_start=false, bool $raw=false) : Element
{
if ($this->self_closing)
{
throw new \Exception("A self closing element cannot contain text.");
}
$this->text = $text;
$this->text_at_start = $text_at_start;
$this->raw = $raw;
return $this;
}
public function getAttribute(string $name)
{
return (isset($this->attributes[$name])) ? $this->attributes[$name] : null;
}
// A value of true allows for the setting of boolean attributes such as
// 'required' and 'disabled'
public function setAttribute(string $name, $value=true) : Element
{
$this->attributes[$name] = $value;
return $this;
}
public function setAttributes(array $attributes) : Element
{
foreach ($attributes as $name => $value)
{
$this->setAttribute($name, $value);
}
return $this;
}
public function removeAttribute(string $name) : Element
{
unset($this->attributes[$name]);
return $this;
}
public function getElement(string $key) : Element
{
return $this->elements[$key];
}
public function setElement(string $key, Element $element) : Element
{
$this->elements[$key] = $element;
return $this;
}
public function getElements() : array
{
return $this->elements;
}
public function setElements(array $elements) : Element
{
$this->elements = $elements;
return $this;
}
public function addElement(?Element $element=null, ?string $key=null) : Element
{
if (isset($element))
{
if (isset($key))
{
$this->elements[$key] = $element;
}
else
{
$this->elements[] = $element;
}
}
return $this;
}
public function addElements(array $elements) : Element
{
foreach ($elements as $element)
{
$this->addElement($element);
}
return $this;
}
public function removeElement(string $key) : Element
{
unset($this->elements[$key]);
return $this;
}
public function next(?Element $element=null) : ?Element
{
if (isset($element))
{
$this->next = $element;
return $this;
}
elseif (isset($this->next))
{
return $this->next;
}
else
{
return null;
}
}
public function prev(?Element $element=null): ?Element
{
if (isset($element))
{
$this->prev = $element;
return $this;
}
elseif (isset($this->prev))
{
return $this->prev;
}
else
{
return null;
}
}
public function addClass(string $class) : Element
{
$classes = $this->getAttribute('class');
$classes = (isset($classes)) ? explode(' ', $classes) : array();
if (!in_array($class, $classes))
{
$classes[] = $class;
$this->setAttribute('class', implode(' ', $classes));
}
return $this;
}
// Add a set of select options to an element, eg to a