/** * Sets the keywords for the XML document. This gets added under the root. * Expects a keywords entry in the block * @param \System\Cache\PageCache\Block The block with the keywords entry * @return \SimpleXMLElement The XML tree */ public function outputKeywordsXML(\System\Cache\PageCache\Block $block) { $xml = \System\XML\XML::createXMLRoot(); $xml->keywords = \System\Security\Sanitize::sanitizeString((string) $block->keywords, false, false, true, true, false, false); return $xml; }
/** * Converts the given XML tree and the given XSL file to a (HTML) file, with respect to the given XSL parameters. * The given XMLTree parameter may be of the SimpleXMLElement or the DOMDocument type, however, the latter is the fastest. * The generated output may be considered to be formatted properly. * @param mixed The XML Tree as a SimpleXMLElement or a DOMDocument * @param mixed The fullpath to the XSL file, or an instanced \SimpleXMLElement XSL tree * @param \System\Collection\Map The map with the parameters, or null for no parameters or default */ public final function render() { $args = func_get_args(); if (count($args) != 3) { throw new \InvalidArgumentException('Invalid amount of arguments given.'); } list($xmlTree, $xslFile, $parameters) = $args; $processor = new \XSLTProcessor(); //register the php functions if (count(self::$registeredPHPFunctions) > 0) { $processor->registerPHPFunctions(self::$registeredPHPFunctions); } //load the xsl file intro a dom $xsl = new \DOMDocument(); if ($xslFile instanceof \SimpleXMLElement) { $xsl->loadXML($xslFile->asXML()); } else { if (!file_exists($xslFile)) { throw new \System\Error\Exception\FileNotFoundException('XSL File: ' . $xslFile . ' cannot be found'); } $xsl->load($xslFile); } //attach the xsl dom to the processor $processor->importStylesheet($xsl); //when we run as a local debug system, we output the profiling information if (defined('DEBUG')) { $processor->setProfiling(PATH_LOGS . 'XSLTRenderProfiling.txt'); } $dom = new \DOMDocument(); switch (true) { case $xmlTree instanceof \SimpleXMLElement: //we need to convert to a domdocument $dom = \System\XML\XML::convertSimpleXMLElementToDOMDocument($xmlTree); break; case $xmlTree instanceof \DOMDocument: //no conversion needed break; default: throw new \InvalidArgumentException('Given XML tree is of non supported tree type: ' . get_class($xmlTree)); } $this->preprocessParameters($parameters); //we do not need any namespaces $processor->setParameter('', $parameters->getArrayCopy()); $output = $processor->transformToXML($dom); if (!$output) { throw new \Exception('Could not transform the given XML and XSL to a valid HTML page'); } if (MINIFY_ENABLE) { $output = \System\Web\Minify\HTML\Minify::minify($output); } $this->addToBuffer($output); }
/** * Loads the XML file from disk and parses it to an XML structure. This structure is then returned. * This function is used internally to parse the given DynamicBaseObj XML descriptors and should not * be called directly, as it serves no further purpose. * @param string The XML file to load * @return \SimpleXMLElement The XML tree */ public static final function parseXml($xmlFile) { try { if (!($xml = \simplexml_load_file($xmlFile))) { throw new \Exception('XML file does not exist, or could not be loaded: ' . $xmlFile); } else { /* check for xml inheritance. we currently support adding of parent fields, conditions and virtuals only we apply this recursively, to allow inheritance trees */ if (isset($xml['extends'])) { $fileName = (string) $xml['extends']; $currentFilePath = new \System\IO\File($xmlFile); $parentFile = $currentFilePath->getPath() . $fileName; $parentXml = self::parseXml($parentFile); //we only add some field types in the parent xml to our current loaded xml foreach ($parentXml->children() as $item) { switch ($item->getName()) { case 'fields': foreach ($item->children() as $field) { $result = $xml->xpath('fields/' . $field->getName()); if (is_array($result) && count($result) == 0) { if (!isset($xml->fields)) { $xml->addChild('fields'); } \System\XML\XML::appendToXML($xml->fields, $field); } } break; case 'virtuals': foreach ($item->children() as $virtual) { $result = $xml->xpath('virtuals/' . $virtual->getName()); if (is_array($result) && count($result) == 0) { if (!isset($xml->virtuals)) { $xml->addChild('virtuals'); } \System\XML\XML::appendToXML($xml->virtuals, $virtual); } } break; case 'conditions': foreach ($item->children() as $condition) { //conditions follow a different structure and work on the name attribute $result = $xml->xpath('conditions/condition[@name="' . $condition['name'] . '"]'); if (is_array($result) && count($result) == 0) { if (!isset($xml->conditions)) { $xml->addChild('conditions'); } \System\XML\XML::appendToXML($xml->conditions, $condition); } } break; default: //we ignore other items } } } return $xml; } } catch (Exception $e) { throw new \System\Error\Exception\ObjectLoaderSourceException($e->getMessage()); } }
/** * Combines the XML structures from the given Blocks. The XML will be merged with the current existing xml, * possibly overriding already defined nodes. Because of the homogenous output of the different types of blocks, * the XML can be merged without any conversion. * @return \SimpleXMLElement The final output */ private final function generateXML() { foreach ($this->blocks as $block) { $xml = null; switch (true) { //because MemcacheBlock is a subclass of Block, we must query this first case $block instanceof \System\Cache\PageCache\MemcacheBlock: $xml = $xml = $block->callMemcacheBlock(); break; //because StaticBlock is a subclass of Block, we must query this first //because StaticBlock is a subclass of Block, we must query this first case $block instanceof \System\Cache\PageCache\StaticBlock: //we check if there is a configuration directive to disable staticblocks and use them as regular blocks if (PAGECACHE_STATICBLOCK_ENABLE) { $xml = $block->callStaticBlock(); } else { $xml = $block->callBlock(); } break; case $block instanceof \System\Cache\PageCache\Block: $xml = $block->callBlock(); break; default: throw new \Exception('Invalid BlockType detected. Corrupt input given.'); } //check if the xml is valid for processing if ($xml instanceof \SimpleXMLElement) { $this->xml = \System\XML\XML::mergeXML($this->xml, $xml); } else { throw new \Exception('The given returnvalue is not a XML document tree!'); } } return $this->xml; }