/** * Sets the value for the property specified * * @param string $name * @param string $value * @throws \InvalidArgumentException * @throws \Exception */ public function __set($name, $value) { if (!is_string($value)) { throw new \InvalidArgumentException('The value argument must be of type string'); } if ($name === 'innerHTML') { while ($this->hasChildNodes()) { $this->removeChild($this->firstChild); } $tmpDoc = new \IvoPetkov\HTML5DOMDocument(); $tmpDoc->loadHTML('<body>' . $value . '</body>'); foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) { $node = $this->ownerDocument->importNode($node, true); $this->appendChild($node); } return; } elseif ($name === 'outerHTML') { $tmpDoc = new \IvoPetkov\HTML5DOMDocument(); $tmpDoc->loadHTML('<body>' . $value . '</body>'); foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) { $node = $this->ownerDocument->importNode($node, true); $this->parentNode->insertBefore($node, $this); } $this->parentNode->removeChild($this); return; } throw new \Exception('Undefined property: HTML5DOMElement::$' . $name); }
/** * Converts components code (if any) into HTML code * * @param string|\IvoPetkov\HTMLServerComponent $content The content to be processed * @param array $options Compiler options * @throws \InvalidArgumentException * @return string The result HTML code */ public function process($content, $options = []) { if (!is_string($content) && !$content instanceof \IvoPetkov\HTMLServerComponent) { throw new \InvalidArgumentException(''); } if (!is_array($options)) { throw new \InvalidArgumentException(''); } if (is_string($content) && strpos($content, '<component') === false) { return $content; } if (isset($options['_internal_process_components']) && $options['_internal_process_components'] === false) { return $content; } $getComponentFileContent = function ($file, $component, $variables) { if (is_file($file)) { $__componentFile = $file; unset($file); if (!empty($variables)) { extract($variables, EXTR_SKIP); } unset($variables); ob_start(); include $__componentFile; $content = ob_get_clean(); return $content; } else { throw new \Exception('Component file cannot be found (' . $file . ')'); } }; $getComponentResultHTML = function ($component) use(&$getComponentFileContent, $options) { if (isset($component->attributes['src'])) { // todo check alias of alias $srcAttributeValue = $component->attributes['src']; if (isset($this->aliases[$srcAttributeValue])) { $sourceParts = explode(':', $this->aliases[$srcAttributeValue], 2); } else { $sourceParts = explode(':', $srcAttributeValue, 2); } if (sizeof($sourceParts) === 2) { $scheme = $sourceParts[0]; if (isset($options['recursive']) && $options['recursive'] === false) { $componentOptions = array_merge($options, ['_internal_process_components' => false]); } if ($scheme === 'data') { if (substr($sourceParts[1], 0, 7) === 'base64,') { return $this->process(base64_decode(substr($sourceParts[1], 7)), isset($componentOptions) ? $componentOptions : $options); } throw new \Exception('Components data URI scheme only supports base64 (data:base64,ABCD...)!'); } elseif ($scheme === 'file') { return $this->process($getComponentFileContent(urldecode($sourceParts[1]), $component, isset($options['variables']) && is_array($options['variables']) ? $options['variables'] : []), isset($componentOptions) ? $componentOptions : $options); } throw new \Exception('Components URI scheme not valid! It must be \'file:\', \'data:\' or an alias.'); } throw new \Exception('Components URI scheme or alias not found at ' . (string) $component . '!'); } throw new \Exception('Component src attribute is missing at ' . (string) $component . '!'); }; $domDocument = new \IvoPetkov\HTML5DOMDocument(); if ($content instanceof \IvoPetkov\HTMLServerComponent) { $domDocument->loadHTML($getComponentResultHTML($content)); } else { $domDocument->loadHTML($content); $componentElements = $domDocument->getElementsByTagName('component'); $componentElementsCount = $componentElements->length; if ($componentElementsCount > 0) { for ($i = 0; $i < $componentElementsCount; $i++) { $componentElement = $componentElements->item(0); $component = $this->constructComponent($componentElement->getAttributes(), $componentElement->innerHTML); $componentResultHTML = $getComponentResultHTML($component); $isInBodyTag = false; $parentNode = $componentElement->parentNode; while ($parentNode !== null && isset($parentNode->tagName)) { if ($parentNode->tagName === 'body') { $isInBodyTag = true; break; } $parentNode = $parentNode->parentNode; } if ($isInBodyTag) { $insertTargetName = 'html-server-components-compiler-target-' . uniqid(); $componentElement->parentNode->insertBefore($domDocument->createInsertTarget($insertTargetName), $componentElement); $domDocument->insertHTML($componentResultHTML, $insertTargetName); } else { $domDocument->insertHTML($componentResultHTML); } $componentElement->parentNode->removeChild($componentElement); } } } return $domDocument->saveHTML(); }