* @author Sébastien Lucas */ namespace SebLucas\EPubMeta\Dom; use DOMElement; /** * EPUB-specific subclass of DOMElement * * Source: https://github.com/splitbrain/php-epub-meta * @author Andreas Gohr © 2012 * @author Simon Schrape © 2015–2018 * @author Sébastien Lucas * * @property string $nodeValueUnescaped */ class Element extends DOMElement { /** @var array */ public static $namespaces = [ 'n' => 'urn:oasis:names:tc:opendocument:xmlns:container', 'opf' => 'http://www.idpf.org/2007/opf', 'dc' => 'http://purl.org/dc/elements/1.1/', 'ncx' => 'http://www.daisy.org/z3986/2005/ncx/', ]; /** * Summary of __construct * @param string $name * @param string $value * @param string $namespaceUri */ public function __construct($name, $value = '', $namespaceUri = '') { [$prefix, $name] = $this->splitQualifiedName($name); $value = htmlspecialchars($value); if (!$namespaceUri && $prefix) { //$namespaceUri = XmlNamespace::getUri($prefix); $namespaceUri = static::$namespaces[$prefix]; } parent::__construct($name, $value, $namespaceUri); } /** * Summary of __get * @param string $name * @return string|null */ public function __get($name) { switch ($name) { case 'nodeValueUnescaped': return htmlspecialchars_decode($this->nodeValue); } return null; } /** * Summary of __set * @param string $name * @param mixed $value * @return void */ public function __set($name, $value) { switch ($name) { case 'nodeValueUnescaped': $this->nodeValue = htmlspecialchars($value); } } /** * Create and append a new child * * Works with our epub namespaces and omits default namespaces * @param string $name * @param string $value * @return Element|bool */ public function newChild($name, $value = '') { [$localName, $namespaceUri] = $this->getNameContext($name); // this doesn't call the constructor: $node = $this->ownerDocument->createElement($name,$value); $node = new Element($namespaceUri ? $name : $localName, $value, $namespaceUri); /** @var Element $node */ $node = $this->appendChild($node); return $node; } /** * Simple EPUB namespace aware attribute getter * @param string $name * @return string */ public function getAttrib($name) { [$localName, $namespaceUri] = $this->getNameContext($name); // return value if none was given if ($namespaceUri) { return $this->getAttributeNS($namespaceUri, $localName); } else { return $this->getAttribute($localName); } } /** * Simple EPUB namespace aware attribute setter * @param string $name * @param mixed $value * @return void */ public function setAttrib($name, $value) { [$localName, $namespaceUri] = $this->getNameContext($name); if ($namespaceUri) { $this->setAttributeNS($namespaceUri, $localName, $value); } else { $this->setAttribute($localName, $value); } } /** * Simple EPUB namespace aware attribute remover * @param string $name * @return void */ public function removeAttrib($name) { [$localName, $namespaceUri] = $this->getNameContext($name); if ($namespaceUri) { $this->removeAttributeNS($namespaceUri, $localName); } else { $this->removeAttribute($localName); } } /** * Remove this node from the DOM * @return void */ public function delete() { $this->parentNode->removeChild($this); } /** * Split given name in namespace prefix and local part * * @param string $name * @return array (prefix, name) */ protected function splitQualifiedName($name) { $list = explode(':', $name, 2); if (count($list) < 2) { array_unshift($list, ''); } return $list; } /** * @param string $name * @return array */ protected function getNameContext($name) { [$prefix, $localName] = $this->splitQualifiedName($name); $namespaceUri = ''; if ($prefix) { //$namespaceUri = XmlNamespace::getUri($prefix); $namespaceUri = static::$namespaces[$prefix]; if ( !$this->namespaceURI && $this->isDefaultNamespace($namespaceUri) || $this->namespaceURI == $namespaceUri ) { $namespaceUri = ''; } } return [$localName, $namespaceUri]; } }