/** * 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); }
/** * Processes the opt:dynamic node. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function processNode(Opt_Xml_Node $node) { // Add capturing the content for the caching purposes $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, '$this->_outputBuffer[] = ob_get_contents();'); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' ob_start(); '); // Inform the compiler to store this piece of compiled // template in an extra file, where it will be accessible // to the caching system. $node->set('dynamic', true); $this->_process($node); }
/** * Processes the opt:block node. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function processNode(Opt_Xml_Node $node) { $node->set('block', true); // Undefined block processing $params = array('from' => array(self::REQUIRED, self::EXPRESSION, null), '__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)); $vars = $this->_extractAttributes($node, $params); $this->_stack->push($params['from']); $mainCode = ' if(is_object(' . $params['from'] . ') && ' . $params['from'] . ' instanceof Opt_Block_Interface){ ' . $params['from'] . '->setView($this); '; $mainCode .= $this->_commonProcessing($node, $params['from'], $vars); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, $mainCode); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } '); }
/** * Finalizes the opt:show attribute. If there was no section in opt:show, * it initializes a section for a moment just to generate the condition, * but does not add it to the stack. * * @param Opt_Xml_Node $node The node. */ protected function _postprocessShow(Opt_Xml_Node $node) { if (!is_null($node->get('priv:initialized'))) { return; } $section = $this->_extractSectionAttributes($node, null); $section['show'] = $node; $section['node'] = null; $section['attribute'] = null; $this->_validateSection($section); $this->_createShowCondition($node, $section); }
/** * Finishes the processing of the opt:extend node. In this particular * case it handles the support of snippet extending, where the snippets * need to be scanned AFTER they are actually loaded. * * @internal * @param Opt_Xml_Node $node The recognized node. */ public function postprocessNode(Opt_Xml_Node $node) { if ($this->_compiler->processor('snippet')->isSnippet($node->get('branch'))) { $node->getParent()->set('snippet', $node->get('branch')); } else { $node->getParent()->set('extend', $node->get('branch')); } }
/** * A helper method for building the XML tree. It jumps out of the * current node to the parent and switches to it. * * @internal * @param Opt_Xml_Node $current The current node. * @return Opt_Xml_Node */ protected function _treeJumpOut($current) { $parent = $current->getParent(); if (!is_null($parent)) { return $parent; } return $current; }
/** * Postprocesses the opt:single instruction attribute. * * @internal * @param Opt_Xml_Node $node XML node. * @param Opt_Xml_Attribute $attr XML attribute. */ public function postprocessAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { if ($attr->getValue() == 'yes') { $node->set('single', true); $node->removeChildren(); } }
/** * Finishes the public processing of the component. * * @param Opt_Xml_Node $node The recognized node. */ public function postprocessComponent(Opt_Xml_Node $node) { if (!is_null($attribute = $node->get('_componentTemplate'))) { $this->_compiler->processor('snippet')->postprocessAttribute($node, $attribute); $node->set('_componentTemplate', NULL); } $this->_stack->pop(); }
/** * Extra dispose function. * * @internal */ protected function _dispose() { parent::_dispose(); $this->_subnodes = NULL; $this->_prototypes = NULL; $this->_i = NULL; $this->_size = 0; $this->_copy = NULL; }
/** * Finishes the processing of the opt:foreach node. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function postprocessNode(Opt_Xml_Node $node) { $params = $node->get('params'); $this->_compiler->unsetConversion('##var_' . $params['value']); $this->_compiler->unsetConversion('##var_' . $params['index']); $this->_nesting--; }
/** * Finalizes the processing of the opt:if and opt:omit-tag attributes. * @internal * @param Opt_Xml_Node $node The node with the attribute * @param Opt_Xml_Attribute $attr The recognized attribute. */ public function postprocessAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { $expr = $this->_compiler->compileExpression((string) $attr, false, Opt_Compiler_Class::ESCAPE_OFF); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, ' if(' . $expr[0] . '){ '); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } '); }
/** * Tests, if the specified node can be a child of root. * @param Opt_Xml_Node $node The node to test. */ protected function _testNode(Opt_Xml_Node $node) { if ($node->getType() == 'Opt_Xml_Expression' && $node->getType() == 'Opt_Xml_Cdata') { throw new Opt_APIInvalidNodeType_Exception('Opt_Xml_Root', $node->getType()); } }
/** * Processes the opt:capture attribute. * @internal * @param Opt_Xml_Node $node The node with the attribute * @param Opt_Xml_Attribute $attr The recognized attribute. */ public function processAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { if ($this->_compiler->isIdentifier($attr->getValue())) { $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, 'ob_start(); '); $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, 'self::$_capture[\'' . $attr->getValue() . '\'] = ob_get_clean();'); $this->_process($node); } else { throw new Opt_InvalidAttributeType_Exception('opt:capture', 'identifier'); } }
/** * Processes the opt:empty-item tag. * @internal * @param Opt_Xml_Element $node The recognized node. */ protected function _processEmptyItem(Opt_Xml_Node $node) { if (is_null($node->get('priv:section'))) { throw new Opt_InstructionInvalidLocation_Exception('opt:item', 'opt:grid'); } $section = $node->get('priv:section'); $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, ' if($_' . $section['name'] . '_remain > 0 && !' . $section['format']->get('section:valid') . ') { for($_' . $section['name'] . '_k = 0; $_' . $section['name'] . '_k < $_' . $section['name'] . '_remain; $_' . $section['name'] . '_k++) { '); $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, ' } } '); $this->_process($node); }
/** * Processes the opt:attributes-build and opt:attributes-ignore attributes. * @internal * @param Opt_Xml_Element $node The node * @param Opt_Xml_Attribute $attr The attribute to process */ public function processAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { if ($attr->getName() == 'attributes-build') { $ignoreList = $node->getAttribute('opt:attributes-ignore'); if ($ignoreList instanceof Opt_Xml_Attribute) { $ignore = $this->_compiler->compileExpression($ignoreList->getValue(), false, Opt_Compiler_Class::ESCAPE_OFF); $ignore = $ignore[0]; } else { $ignore = 'array()'; } $expression = $this->_compiler->compileExpression($attr->getValue(), false, Opt_Compiler_Class::ESCAPE_OFF); $node->addAfter(Opt_Xml_Buffer::TAG_ENDING_ATTRIBUTES, 'echo Opt_Function::buildAttributes(' . $expression[0] . ', ' . $ignore . ', \' \'); '); } }
/** * Specifies, what node types can be children of XML tags. * * @internal * @param Opt_Xml_Node $node */ protected function _testNode(Opt_Xml_Node $node) { if ($node->getType() != 'Opt_Xml_Element' && $node->getType() != 'Opt_Xml_Text' && $node->getType() != 'Opt_Xml_Comment') { throw new Opt_APIInvalidNodeType_Exception('Opt_Xml_Element', $node->getType()); } }
/** * Initializes the expression node. The argument determines the * expression that it represents. * @param String $expression The expression represented by the node. */ public function __construct($expression) { parent::__construct(); $this->_expression = $expression; }
/** * An utility method that simplifies inserting the text to the XML * tree. Depending on the last child type, it can create a new text * node or add the text to the existing one. * * @internal * @param Opt_Xml_Node $current The currently built XML node. * @param String|Opt_Xml_Node $text The text or the expression node. * @return Opt_Xml_Node The current XML node. */ protected function _treeTextAppend($current, $text) { $last = $current->getLastChild(); if (!is_object($last) || !$last instanceof Opt_Xml_Text) { if (!is_object($text)) { $node = new Opt_Xml_Text($text); } else { $node = new Opt_Xml_Text(); $node->appendChild($text); } $current->appendChild($node); } else { if (!is_object($text)) { $last->appendData($text); } else { $last->appendChild($text); } } return $current; }
/** * A postprocessing routine for attributed opt:selector * @internal * @param Opt_Xml_Node $node * @param Opt_Xml_Attribute $attr */ protected function _postprocessAttrSelector(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { $section = self::getSection($node->get('priv:section')); $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, $section['format']->get('section:endLoop')); $this->_sectionEnd($node); }
/** * A postprocessing routine for opt:use * @internal * @param Opt_Xml_Node $node * @param Opt_Xml_Attribute $attr */ public function postprocessAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { if (!is_null($attr->get('size'))) { $snippet = $attr->get('snippetObj'); unset($snippet[$attr->get('size')]); } // Restore the original escaping state $this->_compiler->set('escaping', $node->get('escaping')); array_pop($this->_current); }
/** * Closes the XML comment for the commented item. * * @internal * @param Opt_Xml_Node $item The commented item. * @param String &$output The reference to the output buffer. */ protected function _closeComments($item) { if ($item->get('commented')) { $this->_comments--; if ($this->_comments == 0) { // According to the XML grammar, the construct "--->" is not allowed. if (strlen($this->_output) > 0 && $this->_output[strlen($this->_output) - 1] == '-') { throw new Opt_XmlComment_Exception('--->'); } $this->_output .= '-->'; } } }
/** * Adds the children of the specified node to the queue of the currently * parsed element. It allows them to be processed. * * @final * @internal * @param Opt_Xml_Node $node */ protected final function _process(Opt_Xml_Node $node) { if (is_null($this->_queue)) { $this->_queue = new SplQueue(); } if ($node->hasChildren()) { foreach ($node as $child) { $this->_queue->enqueue($child); } } }
/** * Processes the opt:content attribute. * @internal * @param Opt_Xml_Node $node The node with the attribute * @param Opt_Xml_Attribute $attr The recognized attribute. */ public function processAttribute(Opt_Xml_Node $node, Opt_Xml_Attribute $attr) { $result = $this->_compiler->compileExpression($attr->getValue(), false, Opt_Compiler_Class::ESCAPE_BOTH); if ($result[2] == true) { // The expression is a single variable that can be handled in a simple way. $node->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, 'if(empty(' . $result[3] . ')){ '); $node->addAfter(Opt_Xml_Buffer::TAG_CONTENT_AFTER, '} else { echo ' . $result[0] . '; } '); } else { // In more complex expressions, we store the result to a temporary variable. $node->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, ' $_cont' . $this->_nesting . ' = ' . $result[0] . '; if(empty($_cont' . $this->_nesting . ')){ '); $node->addAfter(Opt_Xml_Buffer::TAG_CONTENT_AFTER, '} else { echo $_cont' . $this->_nesting . '; } '); } $this->_nesting++; $attr->set('postprocess', true); }
/** * Constructs a new Opt_Xml_Cdata node. * * @param String $cdata The initial text. */ public function __construct($cdata) { parent::__construct(); self::$mode != Opt_Class::QUIRKS_MODE and $this->_validate($cdata); $this->_text = $cdata; }