_namespaces[$namespace->getNamespaceName()] = $namespace; $namespace->setCompiler($this); return $this; } /** * Compiles a template * * @param string $file template file * @return string the XML output */ public function compile($file) { $data = file_get_contents($file); $data = $this->_prepareDocument($data); $document = new DOMDocument(); $document->loadXML($data); $this->_parseDom($document); return $this->_revertDocument($document->saveXML()); } /** * Create a placeholder for non-XML data such as PHP code * * @param string $block The non-XML data to store * @return string the placeholder */ public function placeholder($block) { $this->_placeholderData[] = $block; $phc = count($this->_placeholderData) - 1; return '#Cute_Placeholder_'.$phc.'#'; } /** * Parse a DOMDocument and calls element/attribute handlers * * @param DOMDocument $document */ private function _parseDom(DOMDocument $document) { foreach($this->_namespaces as $name => $ns) { $nodes = $document->getElementsByTagNameNS($name,'*'); if(count($nodes) > 0) $ns->setDocument($document); foreach($nodes as $node) $ns->parseElement($node); } } /** * Generate opening element with xmlns references * * @return string */ private function _generateRootOpen() { $openDoc = '_namespaces as $name => $ns) { $openDoc .= ' xmlns:'.$name.'="'.$name.'"'; } $openDoc .= '>'; return $openDoc; } /** * Prepare a template for the PHP DOM works * * Adds a root element for the document and replaces * all PHP blocks with placeholders. * * @param string $data template data * @return string prepared template data */ private function _prepareDocument($data) { return $this->_generateRootOpen() . preg_replace('/(<\?(.*)\?>)/e','$this->placeholder(\'$1\')', $data) . ''; } /** * Reverts a prepared xml data string back * * Replaces all placeholders with their codeblocks * and removes the root element * * @param string $data * @return string */ private function _revertDocument($data) { foreach($this->_placeholderData as $i => $phd) { $data = str_replace('#Cute_Placeholder_'.$i.'#', $phd, $data); } $open = $this->_generateRootOpen(); //?xml version="1.0" ? = 22 chars $len = strlen($open) + 22; // = 14 chars $data = substr($data,$len,-14); return $data; } }