<?php
declare(strict_types=1);
namespace voku\helper;
abstract class AbstractSimpleXmlDom
{
/**
* @var array
*/
protected static $functionAliases = [
'children' => 'childNodes',
'first_child' => 'firstChild',
'last_child' => 'lastChild',
'next_sibling' => 'nextSibling',
'prev_sibling' => 'previousSibling',
'parent' => 'parentNode',
];
/**
* @var \DOMElement|\DOMNode|null
*/
protected $node;
/**
* @param string $name
* @param array $arguments
*
* @throws \BadMethodCallException
*
* @return SimpleXmlDomInterface|string|null
*/
public function __call($name, $arguments)
{
$name = \strtolower($name);
if (isset(self::$functionAliases[$name])) {
return \call_user_func_array([$this, self::$functionAliases[$name]], $arguments);
}
throw new \BadMethodCallException('Method does not exist');
}
/**
* @param string $name
*
* @return array|string|null
*/
public function __get($name)
{
$nameOrig = $name;
$name = \strtolower($name);
switch ($name) {
case 'xml':
return $this->xml();
case 'plaintext':
return $this->text();
case 'tag':
return $this->node->nodeName ?? '';
case 'attr':
return $this->getAllAttributes();
default:
if ($this->node && \property_exists($this->node, $nameOrig)) {
return $this->node->{$nameOrig};
}
return $this->getAttribute($name);
}
}
/**
* @param string $selector
* @param int|null $idx
*
* @return SimpleXmlDomInterface|SimpleXmlDomInterface[]|SimpleXmlDomNodeInterface<SimpleXmlDomInterface>
*/
public function __invoke($selector, $idx = null)
{
return $this->find($selector, $idx);
}
/**
* @param string $name
*
* @return bool
*/
public function __isset($name)
{
$nameOrig = $name;
$name = \strtolower($name);
switch ($name) {
case 'outertext':
case 'outerhtml':
case 'innertext':
case 'innerhtml':
case 'innerhtmlkeep':
case 'plaintext':
case 'text':
case 'tag':
return true;
default:
if ($this->node && \property_exists($this->node, $nameOrig)) {
return isset($this->node->{$nameOrig});
}
return $this->hasAttribute($name);
}
}
/**
* @param string $name
* @param mixed $value
*
* @return SimpleXmlDomInterface|null
*/
public function __set($name, $value)
{
$nameOrig = $name;
$name = \strtolower($name);
switch ($name) {
case 'outerhtml':
case 'outertext':
return $this->replaceNodeWithString($value);
case 'innertext':
case 'innerhtml':
return $this->replaceChildWithString($value);
case 'innerhtmlkeep':
return $this->replaceChildWithString($value, false);
case 'plaintext':
return $this->replaceTextWithString($value);
default:
if ($this->node && \property_exists($this->node, $nameOrig)) {
return $this->node->{$nameOrig} = $value;
}
return $this->setAttribute($name, $value);
}
}
/**
* @return string
*/
public function __toString()
{
return $this->xml();
}
/**
* @param string $name
*
* @return void
*/
public function __unset($name)
{
/** @noinspection UnusedFunctionResultInspection */
$this->removeAttribute($name);
}
/**
* @param string $selector
* @param int|null $idx
*
* @return SimpleXmlDomInterface|SimpleXmlDomInterface[]|SimpleXmlDomNodeInterface<SimpleXmlDomInterface>
*/
abstract public function find(string $selector, $idx = null);
/**
* @return string[]|null
*/
abstract public function getAllAttributes();
/**
* @param string $name
*
* @return string
*/
abstract public function getAttribute(string $name): string;
/**
* @param string $name
*
* @return bool
*/
abstract public function hasAttribute(string $name): bool;
abstract public function innerXml(bool $multiDecodeNewHtmlEntity = false): string;
abstract public function removeAttribute(string $name): SimpleXmlDomInterface;
abstract protected function replaceChildWithString(string $string, bool $putBrokenReplacedBack = true): SimpleXmlDomInterface;
abstract protected function replaceNodeWithString(string $string): SimpleXmlDomInterface;
/**
* @param string $string
*
* @return SimpleXmlDomInterface
*/
abstract protected function replaceTextWithString($string): SimpleXmlDomInterface;
/**
* @param string $name
* @param string|null $value
* @param bool $strictEmptyValueCheck
*
* @return SimpleXmlDomInterface
*/
abstract public function setAttribute(string $name, $value = null, bool $strictEmptyValueCheck = false): SimpleXmlDomInterface;
abstract public function text(): string;
abstract public function xml(bool $multiDecodeNewHtmlEntity = false): string;
}