Example #1
0
 /**
  * Processes the opt:root node.
  * @internal
  * @param Opt_Xml_Node $node The recognized node.
  */
 public function processNode(Opt_Xml_Node $node)
 {
     if ($node->getParent()->getType() != 'Opt_Xml_Root') {
         throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'ROOT');
     }
     $params = array('escaping' => array(0 => self::OPTIONAL, self::BOOL, NULL), 'include' => array(0 => self::OPTIONAL, self::STRING, NULL), 'dynamic' => array(0 => self::OPTIONAL, self::BOOL, false));
     $this->_extractAttributes($node, $params);
     // Compile-time inclusion support
     if (!is_null($params['include'])) {
         $file = $params['include'];
         if ($params['dynamic']) {
             if (is_null($file = $this->_compiler->inherits($this->_compiler->get('currentTemplate')))) {
                 $file = $params['include'];
             }
         }
         $this->_compiler->addDependantTemplate($file);
         $compiler = new Opt_Compiler_Class($this->_compiler);
         $compiler->compile($this->_tpl->_getSource($file), $file, NULL, $this->_compiler->get('mode'));
         $this->_compiler->importDependencies($compiler);
     }
     // Escaping control support
     if (!is_null($params['escaping'])) {
         $this->_compiler->set('escaping', $params['escaping']);
     }
     $this->_process($node);
 }
Example #2
0
 /**
  * Compiles the current text block between two XML tags, creating a
  * complete Opt_Xml_Text node. It looks for the expressions in the
  * curly brackets, extracts them and packs as separate nodes.
  *
  * Moreover, it replaces the entities with the corresponding characters.
  *
  * @internal
  * @param Opt_Xml_Node $current The current XML node.
  * @param String $text The text block between two tags.
  * @param Boolean $noExpressions=false If true, do not look for the expressions.
  * @return Opt_Xml_Node The current XML node.
  */
 protected function _treeTextCompile($current, $text, $noExpressions = false)
 {
     // Yes, we parse entities, but the text itself should not contain
     // any special characters.
     if (strcspn($text, '<>') != strlen($text)) {
         throw new Opt_XmlInvalidCharacter_Exception(htmlspecialchars($text));
     }
     if ($noExpressions) {
         $current = $this->_treeTextAppend($current, $this->_compiler->parseEntities($text));
     }
     preg_match_all($this->_rExpressionTag, $text, $result, PREG_SET_ORDER);
     $resultSize = sizeof($result);
     $offset = 0;
     for ($i = 0; $i < $resultSize; $i++) {
         $id = strpos($text, $result[$i][0], $offset);
         if ($id > $offset) {
             $current = $this->_treeTextAppend($current, $this->_compiler->parseEntities(substr($text, $offset, $id - $offset)));
         }
         $offset = $id + strlen($result[$i][0]);
         $current = $this->_treeTextAppend($current, new Opt_Xml_Expression($this->_compiler->parseEntities($result[$i][2])));
     }
     $i--;
     // Now the remaining content of the file
     if (strlen($text) > $offset) {
         $current = $this->_treeTextAppend($current, $this->_compiler->parseEntities(substr($text, $offset, strlen($text) - $offset)));
     }
     return $current;
 }
Example #3
0
 /**
  * @dataProvider dataProvider
  */
 public function testExpression($assign, $src, $dst, $result)
 {
     try {
         $info = $this->cpl->compileExpression($src, $assign, Opt_Compiler_Class::ESCAPE_BOTH);
         if ($result == 0) {
             $this->assertEquals($dst, $info[0]);
             return true;
         }
         $this->fail('Exception NOT returned, but should be: ' . $result);
     } catch (Opt_Exception $e) {
         if ($result !== 0) {
             if ($result != get_class($e)) {
                 $this->fail('Invalid exception returned: #' . get_class($e) . ', ' . $result . ' expected.');
             }
             return true;
         }
         $this->fail('Exception returned: #' . get_class($e) . ': ' . $e->getMessage() . ' (line: ' . $e->getLine() . ')');
     }
 }
Example #4
0
 /**
  * Tries to extract a single attribute, using the specified value type.
  *
  * @final
  * @internal
  * @param Opt_Xml_Element $item The scanned XML element.
  * @param Opt_Xml_Attribute $attr The parsed attribute
  * @param Int $type The requested value type.
  * @return Mixed The extracted attribute value
  */
 private final function _extractAttribute(Opt_Xml_Element $item, Opt_Xml_Attribute $attr, $type, $exprType = null)
 {
     $value = (string) $attr;
     switch ($type) {
         // An identifier, but with empty values allowed.
         case self::ID_EMP:
             if ($value == '') {
                 return $value;
             }
             // An identifier
         // An identifier
         case self::ID:
             if (!preg_match('/^[a-zA-Z0-9\\_\\.]+$/', $value)) {
                 throw new Opt_InvalidAttributeType_Exception($attr->getXmlName(), $item->getXmlName(), 'identifier');
             }
             return $value;
             // A number
         // A number
         case self::NUMBER:
             if (!preg_match('/^\\-?([0-9]+\\.?[0-9]*)|(0[xX][0-9a-fA-F]+)$/', $value)) {
                 throw new Opt_InvalidAttributeType_Exception($attr->getXmlName(), $item->getXmlName(), 'number');
             }
             return $value;
             // Boolean value: "yes" or "no"
         // Boolean value: "yes" or "no"
         case self::BOOL:
             if ($value != 'yes' && $value != 'no') {
                 throw new Opt_InvalidAttributeType_Exception($attr->getXmlName(), $item->getXmlName(), '"yes" or "no"');
             }
             return $value == 'yes';
             // A string packed into PHP expression. Can be switched to EXPRESSION.
         // A string packed into PHP expression. Can be switched to EXPRESSION.
         case self::STRING:
             return $value;
             break;
             // An OPT expression.
         // An OPT expression.
         case self::EXPRESSION:
         case self::ASSIGN_EXPR:
             if (strlen(trim($value)) == 0) {
                 throw new Opt_AttributeEmpty_Exception($attr->getXmlName(), $item->getXmlName());
             }
             if (preg_match('/^([a-zA-Z0-9\\_]{2,})\\:([^\\:].*)$/', $value, $found)) {
                 $result = $this->_compiler->parseExpression($found[2], $found[1]);
             } else {
                 $result = $this->_compiler->parseExpression($value, $exprType);
             }
             if ($result['type'] == Opt_Expression_Interface::ASSIGNMENT && $type != self::ASSIGN_EXPR) {
                 Opt_ExpressionOptionDisabled_Exception('Assignments', 'compiler requirements');
             }
             return $result['bare'];
     }
 }
Example #5
0
 /**
  * Uses the specified variable within the context.
  *
  * @param string $variable The variable name.
  * @param boolean $isGlobal Is the variable global or local?
  * @param string $contextFormat The format enforced by the occurence context.
  * @return array
  */
 public function useVariable($variable, $type, $isGlobal, $contextFormat = null)
 {
     if (!isset($this->_variables[$type . $variable])) {
         // In this case the variable has not been used yet. We must check
         // if the user have not selected any format for it, calculate the
         // default format and modify the context format.
         $manager = $this->_compiler->getCdfManager();
         try {
             // In case of template variables, we should not check the data formats
             // because we would run into several problems. We immediately jump to the
             // format resolution algorithm.
             if ($type == '@') {
                 throw new Exception();
             }
             // OK, look for a variable
             $this->_variables[$type . $variable] = $manager->getFormat('variable', $variable, $this);
             return array('format' => $this->_variables[$type . $variable], 'replacement' => null, 'cast' => null);
         } catch (Exception $exception) {
             if ($contextFormat === null) {
                 // This is very strange. It seems that someone has used
                 // an uninitialized variable, so we can set it to null and
                 // report it as an unused variable.
                 Opt_Support::warning('Uninitialized variable ' . $variable . ' - casting to NULL');
                 return array('format' => null, 'replacement' => 'null');
             } else {
                 $manager->addFormat('variable', $variable, $contextFormat, $this->getElementLocation('variable', $variable));
                 $this->_variables[$type . $variable] = $manager->getFormat('variable', $variable, $this);
                 return array('format' => $this->_variables[$type . $variable], 'replacement' => null, 'cast' => null);
             }
         }
     } else {
         // The variable has already been used. We must match the
         // previously selected format.
         if ($contextFormat !== null) {
             return array('format' => $this->_variables[$type . $variable], 'replacement' => null, 'cast' => $this->_variables[$type . $variable]->getName());
         } else {
             return array('format' => $this->_variables[$type . $variable], 'replacement' => null);
         }
     }
 }
Example #6
0
 /**
  * Processes some extra objective calls: cloning and creating
  * new objects.
  *
  * @param string $action The action: 'new' or 'clone'
  * @param mixed $what The action argument
  * @param int $weight The action weight
  * @return SplFixedArray
  */
 public function _objective($action, $what, $weight)
 {
     if (!$this->_tpl->allowObjects || !$this->_tpl->allowObjectCreation) {
         throw new Opt_NotSupported_Exception('object creation', 'disabled by the configuration');
     }
     switch ($action) {
         case 'clone':
             $answer = $what;
             $answer[0] = 'clone ' . $answer[0];
             $answer[1] += $weight;
             $answer[3] = 0;
             break;
         case 'new':
             if (($compiled = $this->_compiler->isClass($what[0])) === null) {
                 throw new Opt_ItemNotAllowed_Exception('Class', $what[0]);
             }
             $answer = new SplFixedArray(4);
             $answer[0] = 'new ' . $compiled;
             $answer[1] = $weight;
             $answer[3] = 0;
             // Process the constructor arguments
             if (sizeof($what[1]) > 0) {
                 $answer[0] .= '(';
                 $first = true;
                 foreach ($what[1] as $item) {
                     if (!$first) {
                         $answer[0] .= ',';
                     } else {
                         $first = false;
                     }
                     $answer[0] .= $item[0];
                     $answer[1] += $item[1];
                 }
                 $answer[0] .= ')';
             }
     }
     return $answer;
 }
Example #7
0
 /**
  * The compilation launcher. It executes the proper compilation steps
  * according to the inheritance rules etc.
  *
  * @param String $code The source code to be compiled.
  * @param String $filename The source template filename.
  * @param String $compiledFilename The output template filename.
  * @param Int $mode The compilation mode.
  */
 public function compile($code, $filename, $compiledFilename, $mode)
 {
     $manager = $this->getCdfManager();
     // Initialize the context.
     $this->_contextStack->push(new Opt_Compiler_Context($this, Opt_Compiler_Context::TEMPLATE_CTX, $filename));
     try {
         // First, we select a parser.
         if (!isset($this->_parsers[$mode])) {
             $this->_parsers[$mode] = new $mode();
             if (!$this->_parsers[$mode] instanceof Opt_Parser_Interface) {
                 throw new Opt_InvalidParser_Exception($mode);
             }
         }
         $parser = $this->_parsers[$mode];
         $parser->setCompiler($this);
         // We cannot compile two templates at the same time
         if (!is_null($this->_template)) {
             throw new Opt_CompilerLocked_Exception($filename, $this->_template);
         }
         // Detecting recursive inclusion
         if (is_null(self::$_recursionDetector)) {
             self::$_recursionDetector = array(0 => $filename);
             $weFree = true;
         } else {
             if (in_array($filename, self::$_recursionDetector)) {
                 $exception = new Opt_CompilerRecursion_Exception($filename);
                 $exception->setData(self::$_recursionDetector);
                 throw $exception;
             }
             self::$_recursionDetector[] = $filename;
             $weFree = false;
         }
         // Cleaning up the processors
         foreach ($this->_processors as $proc) {
             $proc->reset();
         }
         // Initializing the template launcher
         $this->set('template', $this->_template = $filename);
         $this->set('mode', $mode);
         $this->set('currentTemplate', $this->_template);
         array_push(self::$_templates, $filename);
         $this->_stack = new SplStack();
         $i = 0;
         $extend = $filename;
         $memory = 0;
         // The inheritance loop
         do {
             // Stage 1 - code compilation
             if ($this->_tpl->debugConsole) {
                 $initial = memory_get_usage();
                 $tree = $parser->parse($extend, $code);
                 // Migration stage - only if backwards compatibility is on
                 if ($this->_tpl->backwardCompatibility) {
                     $tree = $this->_migrate($tree);
                 }
                 // Stage 2 - PHP tree processing
                 $this->_stack = null;
                 $this->_stage2($tree);
                 $this->set('escape', NULL);
                 unset($this->_stack);
                 $memory += memory_get_usage() - $initial;
                 unset($code);
             } else {
                 $tree = $parser->parse($extend, $code);
                 unset($code);
                 // Migration stage - only if backward compatibility is on
                 if ($this->_tpl->backwardCompatibility) {
                     $this->_migrate($tree);
                 }
                 // Stage 2 - PHP tree processing
                 $this->_stack = array();
                 $this->_stage2($tree);
                 $this->set('escape', NULL);
                 unset($this->_stack);
             }
             // if the template extends something, load it and also process
             if (isset($extend) && $extend != $filename) {
                 $this->addDependantTemplate($extend);
             }
             if (!is_null($snippet = $tree->get('snippet'))) {
                 $tree->dispose();
                 unset($tree);
                 // Change the specified snippet into a root node.
                 $tree = new Opt_Xml_Root();
                 $attribute = new Opt_Xml_Attribute('opt:use', $snippet);
                 $this->processor('snippet')->processAttribute($tree, $attribute);
                 $this->processor('snippet')->postprocessAttribute($tree, $attribute);
                 $this->_stage2($tree, true);
                 break;
             }
             if (!is_null($extend = $tree->get('extend'))) {
                 $tree->dispose();
                 unset($tree);
                 $this->set('currentTemplate', $extend);
                 array_pop(self::$_templates);
                 array_push(self::$_templates, $extend);
                 $code = $this->_tpl->_getSource($extend);
             }
             $i++;
         } while (!is_null($extend));
         // There are some dependant templates. We must add a suitable PHP code
         // to the output.
         if (sizeof($this->_dependencies) > 0) {
             $this->_addDependencies($tree);
         }
         if ($this->_tpl->debugConsole) {
             Opt_Support::addCompiledTemplate($this->_template, $memory);
         }
         // Stage 3 - linking the last tree
         if (!is_null($compiledFilename)) {
             $this->_output = '';
             $this->_newQueue = null;
             $this->_dynamicBlocks = array();
             $this->_stage3($output, $tree);
             $tree->dispose();
             unset($tree);
             $this->_output = str_replace('?><' . '?php', '', $this->_output);
             // Build the directories, if needed.
             if (($pos = strrpos($compiledFilename, '/')) !== false) {
                 $path = $this->_tpl->compileDir . substr($compiledFilename, 0, $pos);
                 if (!is_dir($path)) {
                     mkdir($path, 0750, true);
                 }
             }
             // Save the file
             if (sizeof($this->_dynamicBlocks) > 0) {
                 file_put_contents($this->_tpl->compileDir . $compiledFilename . '.dyn', serialize($this->_dynamicBlocks));
             }
             file_put_contents($this->_tpl->compileDir . $compiledFilename, $this->_output);
             $this->_output = '';
             $this->_dynamicBlocks = null;
         } else {
             $tree->dispose();
         }
         array_pop(self::$_templates);
         $this->_inheritance = array();
         if ($weFree) {
             // Do the cleanup.
             $this->_dependencies = array();
             self::$_recursionDetector = NULL;
             foreach ($this->_processors as $processor) {
                 $processor->reset();
             }
         }
         $this->_template = NULL;
         $manager->clearLocals();
         // Free the context.
         while ($this->_contextStack->count() > 0) {
             $ctx = $this->_contextStack->pop();
             $ctx->dispose();
         }
         // Run the new garbage collector, if it is available.
         /*	if(version_compare(PHP_VERSION, '5.3.0', '>='))
         			{
         				gc_collect_cycles();
         			}*/
     } catch (Exception $e) {
         // Free the context
         while ($this->_contextStack->count() > 0) {
             $ctx = $this->_contextStack->pop();
             $ctx->dispose();
         }
         // Free the memory
         if (isset($tree)) {
             $tree->dispose();
         }
         // Clean the compiler state in case of exception
         $this->_template = NULL;
         $this->_dependencies = array();
         self::$_recursionDetector = NULL;
         foreach ($this->_processors as $processor) {
             $processor->reset();
         }
         $manager->clearLocals();
         // And throw it forward.
         throw $e;
     }
 }
Example #8
0
 /**
  * This function is executed by the compiler during the third compilation stage,
  * linking.
  */
 public function preLink(Opt_Compiler_Class $compiler)
 {
     $compiler->appendOutput($this->buildCode(Opt_Xml_Buffer::TAG_BEFORE));
     //	$this->_closeComments($item, $output);
 }
Example #9
0
 /**
  * Parses the input code and returns the OPT XML tree.
  *
  * @param String $filename The file name (for debug purposes)
  * @param String &$code The code to parse
  * @return Opt_Xml_Root
  */
 public function parse($filename, &$code)
 {
     $debug = array(XMLReader::NONE => 'NONE', XMLReader::ELEMENT => 'ELEMENT', XMLReader::ATTRIBUTE => 'ATTRIBUTE', XMLReader::TEXT => 'TEXT', XMLReader::CDATA => 'CDATA', XMLReader::ENTITY_REF => 'ENTITY_REF', XMLReader::ENTITY => 'ENTITY', XMLReader::PI => 'PI', XMLReader::COMMENT => 'COMMENT', XMLReader::DOC => 'DOC', XMLReader::DOC_TYPE => 'DOC_TYPE', XMLReader::DOC_FRAGMENT => 'DOC_FRAGMENT', XMLReader::NOTATION => 'NOTATION', XMLReader::WHITESPACE => 'WHITESPACE', XMLReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE', XMLReader::END_ELEMENT => 'END_ELEMENT', XMLReader::END_ENTITY => 'END_ENTITY', XMLReader::XML_DECLARATION => 'XML_DECLARATION');
     libxml_use_internal_errors(true);
     $reader = new XMLReader();
     $reader->xml($code);
     //	$reader->setParserProperty(XMLReader::LOADDTD, true);
     //	$reader->setParserProperty(XMLReader::VALIDATE, true);
     $reader->setParserProperty(XMLReader::SUBST_ENTITIES, true);
     $root = $current = new Opt_Xml_Root();
     $firstElementMatched = false;
     $depth = 0;
     // Thanks, Oh Great PHP for your excellent WARNINGS!!! >:(
     while (@$reader->read()) {
         if ($reader->depth < $depth) {
             $current = $current->getParent();
         } elseif ($reader->depth > $depth) {
             $current = $optNode;
         }
         //	Opl_Debug::write($debug[$reader->nodeType].': '.$reader->name.', '.$reader->value);
         switch ($reader->nodeType) {
             // XML elements
             case XMLReader::ELEMENT:
                 $optNode = new Opt_Xml_Element($reader->name);
                 // Parse element attributes, if you manage to get there
                 if ($reader->moveToFirstAttribute()) {
                     do {
                         // "xmlns" special namespace must be handler somehow differently.
                         if ($reader->prefix == 'xmlns') {
                             $ns = str_replace('xmlns:', '', $reader->name);
                             $root->addNamespace($ns, $reader->value);
                             // Let this attribute to appear, if it does not represent an OPT special
                             // namespace
                             if (!$this->_compiler->isNamespace($ns)) {
                                 $optAttribute = new Opt_Xml_Attribute($reader->name, $reader->value);
                                 $optNode->addAttribute($optAttribute);
                             }
                         } else {
                             $optAttribute = new Opt_Xml_Attribute($reader->name, $reader->value);
                             $optNode->addAttribute($optAttribute);
                         }
                     } while ($reader->moveToNextAttribute());
                     $reader->moveToElement();
                 }
                 // Set "rootNode" flag
                 if (!$firstElementMatched) {
                     $optNode->set('rootNode', true);
                     $firstElementMatched = true;
                 }
                 // Set "single" flag
                 if ($reader->isEmptyElement) {
                     $optNode->set('single', true);
                 }
                 $current->appendChild($optNode);
                 break;
             case XMLReader::TEXT:
                 $this->_treeTextCompile($current, $reader->value);
                 break;
             case XMLReader::COMMENT:
                 $optNode = new Opt_Xml_Comment($reader->value);
                 $current->appendChild($optNode);
                 break;
             case XMLReader::CDATA:
                 $cdata = new Opt_Xml_Cdata($reader->value);
                 $cdata->set('cdata', true);
                 if ($current instanceof Opt_Xml_Text) {
                     $current->appendChild($cdata);
                 } else {
                     $text = new Opt_Xml_Text();
                     $text->appendChild($cdata);
                     $current->appendChild($text);
                     $current = $text;
                 }
                 break;
                 /*		case XMLReader::SIGNIFICANT_WHITESPACE:
                 					$cdata = new Opt_Xml_Cdata($reader->value);
                 					$cdata->set('cdata', true);
                 
                 					if($current instanceof Opt_Xml_Text)
                 					{
                 						$current->appendChild($cdata);
                 					}
                 					else
                 					{
                 						$text = new Opt_Xml_Text();
                 						$text->appendChild($cdata);
                 						$current->appendChild($text);
                 						$current = $text;
                 					}
                 					break;
                 		 */
         }
         $depth = $reader->depth;
     }
     // Error checking
     $errors = libxml_get_errors();
     if (sizeof($errors) > 0) {
         libxml_clear_errors();
         foreach ($errors as $error) {
             echo $error->message . ' (' . $error->line . ')<br/>';
         }
     }
     return $root;
 }
Example #10
0
 /**
  * Looks for special OPT attributes in the element attribute list and
  * processes them. Returns the list of nodes that need to be postprocessed.
  *
  * @internal
  * @param Opt_Compiler_Class $compiler The compiler.
  * @param Boolean $specialNs Do we recognize special namespaces?
  */
 protected function _processXml(Opt_Compiler_Class $compiler, $specialNs = true)
 {
     if (!$this->hasAttributes()) {
         return array();
     }
     $attributes = $this->getAttributes();
     $this->_postprocess = array();
     $opt = Opl_Registry::get('opt');
     // Look for special OPT attributes
     foreach ($attributes as $attr) {
         if ($compiler->isNamespace($attr->getNamespace())) {
             $xml = $attr->getXmlName();
             if (($processor = $compiler->isOptAttribute($xml)) !== null) {
                 $processor->processAttribute($this, $attr);
                 if ($attr->get('postprocess')) {
                     $this->_postprocess[] = array($processor, $attr);
                 }
             }
             $this->removeAttribute($xml);
         } else {
             $compiler->compileAttribute($attr);
         }
     }
 }
Example #11
0
 /**
  * This function is executed by the compiler during the third compilation stage,
  * linking, after linking the child nodes.
  */
 public function postLink(Opt_Compiler_Class $compiler)
 {
     $compiler->appendOutput($this->buildCode(Opt_Xml_Buffer::TAG_AFTER));
 }
Example #12
0
 /**
  * The informator that prints the currently compiled template name
  * for the compilation errors.
  *
  * @internal
  * @param Opt_Exception $exception Exception
  */
 protected function _printTemplateInfo($exception)
 {
     echo "\t\t<p class=\"directive\">Template: <span>" . Opt_Compiler_Class::getCurrentTemplate() . "</span></p>\r\n";
 }
Example #13
0
 /**
  * This function is executed by the compiler during the third compilation stage,
  * linking.
  */
 public function preLink(Opt_Compiler_Class $compiler)
 {
     if ($this->get('cdata')) {
         $compiler->appendOutput($this->buildCode(Opt_Xml_Buffer::TAG_BEFORE) . '<![CDATA[' . $this . ']]>' . $this->buildCode(Opt_Xml_Buffer::TAG_AFTER));
         return;
     }
     $compiler->appendOutput($this->buildCode(Opt_Xml_Buffer::TAG_BEFORE));
     $tpl = Opl_Registry::get('opt');
     // We strip the white spaces at the linking level.
     if ($tpl->stripWhitespaces) {
         // The CDATA composed of white characters only is reduced to a single space.
         if (ctype_space((string) $this)) {
             // TODO: Wtf is this? Compare with OPT 2.0 code...
             /*if($wasElement)
             		{
             			$output .= ' ';
             		}*/
         } else {
             // In the opposite case reduce all the groups of the white characters
             // to single spaces in the text.
             if ($this->get('noEntitize') === true) {
                 $compiler->appendOutput(preg_replace('/\\s\\s+/', ' ', (string) $this));
             } else {
                 $compiler->appendOutput($compiler->parseSpecialChars(preg_replace('/(\\s){1,}/', ' ', (string) $this)));
             }
         }
     } else {
         $compiler->appendOutput($this->get('noEntitize') ? (string) $this : $compiler->parseSpecialChars($this));
     }
     $compiler->appendOutput($this->buildCode(Opt_Xml_Buffer::TAG_AFTER));
     //	$this->_closeComments($item, $output);
 }