/** * Processes the opt:if node. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function processNode(Opt_Xml_Node $node) { $params = array('test' => array(0 => self::REQUIRED, self::EXPRESSION)); switch ($node->getName()) { case 'if': $this->_extractAttributes($node, $params); $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, ' if(' . $params['test'] . '){ '); $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, ' } '); $node->sort(array('*' => 0, 'opt:elseif' => 1, 'opt:else' => 2)); $this->_process($node); break; case 'else-if': if ($node->getParent()->getName() == 'if') { $this->_extractAttributes($node, $params); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, ' } elseif(' . $params['test'] . '){ '); $this->_process($node); } else { throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'opt:if'); } break; case 'else': if ($node->getParent()->getName() == 'if') { $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, '}else{ '); $this->_process($node); } else { throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'opt:if'); } break; } }
/** * Processes the opt:component, opt:on-event and opt:display nodes. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function processNode(Opt_Xml_Node $node) { switch ($node->getName()) { case 'component': $node->set('component', true); // Undefined component processing $params = array('from' => array(self::REQUIRED, self::EXPRESSION, null), 'datasource' => array(self::OPTIONAL, self::EXPRESSION, null), 'template' => array(self::OPTIONAL, self::ID, 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_Component_Interface){ ' . $params['from'] . '->setView($this); '; if (!is_null($params['datasource'])) { $mainCode .= $params['from'] . '->setDatasource(' . $params['datasource'] . '); '; } $mainCode .= $this->_commonProcessing($node, $params['from'], $params, $vars); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, $mainCode); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } '); break; case 'onEvent': if ($this->_stack->count() == 0) { throw new Opt_ComponentNotActive_Exception($node->getXmlName()); } $tagParams = array('name' => array(self::REQUIRED, self::EXPRESSION)); $this->_extractAttributes($node, $tagParams); $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, ' if(' . $this->_stack->top() . '->processEvent(' . $tagParams['name'] . ')){ '); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } '); $this->_process($node); break; case 'display': if ($this->_stack->count() == 0) { throw new Opt_ComponentNotActive_Exception($node->getXmlName()); } $node->set('hidden', false); $node->removeChildren(); // The opt:display attributes must be packed into array and sent // to Opt_Component_Interface::display() $subCode = ''; if ($node->hasAttributes()) { $params = array('__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)); $vars = $this->_extractAttributes($node, $params); $subCode = 'array('; foreach ($vars as $name => $value) { $subCode .= '\'' . $name . '\' => ' . $value . ','; } $subCode .= ')'; } $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $this->_stack->top() . '->display(' . $subCode . '); '); break; } }
/** * Processes the opt:foreach node. * @internal * @param Opt_Xml_Node $node The recognized node. */ public function processNode(Opt_Xml_Node $node) { switch ($node->getName()) { case 'foreach': $params = array('array' => array(0 => self::REQUIRED, self::EXPRESSION), 'value' => array(0 => self::REQUIRED, self::ID), 'index' => array(0 => self::OPTIONAL, self::ID, null), 'separator' => array(0 => self::OPTIONAL, self::EXPRESSION, null)); $this->_extractAttributes($node, $params); $this->_nesting++; $node->sort(array('*' => 0, 'opt:foreachelse' => 1)); $list = $node->getElementsByTagNameNS('opt', 'foreachelse', false); $codeBegin = ' foreach(' . $params['array'] . ' as ' . (!is_null($params['index']) ? '$__fe' . $this->_nesting . '_idx => ' : '') . '$__fe' . $this->_nesting . '_val){ '; switch (sizeof($list)) { case 0: break; case 1: $codeBegin = 'if(sizeof(' . $params['array'] . ') > 0){ ' . $codeBegin; break; default: throw new Opt_InstructionTooManyItems_Exception('opt:foreachelse', $node->getXmlName()); } $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, $codeBegin); $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } '); $this->_compiler->setConversion('##var_' . $params['value'], '$__fe' . $this->_nesting . '_val'); if (!is_null($params['index'])) { $this->_compiler->setConversion('##var_' . $params['index'], '$__fe' . $this->_nesting . '_idx'); } $this->processSeparator('$__foreach_' . $this->_nesting, $params['separator'], $node); $node->set('postprocess', true); $this->_process($node); $node->set('params', $params); break; case 'foreachelse': if ($node->getParent()->getName() != 'foreach') { throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'opt:foreach'); } $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, '} } else { '); $this->_process($node); break; } }
/** * This method is called automatically for each XML element that the * processor has registered during the postprocessing, if the instruction * requested this by setting the "postprocess" variable to "true" in the * node. It can handle many instructions tags, and * the default implementation redirects the processing to the private * user-created methods _postprocessTagName for "opt:tagName". * * @param Opt_Xml_Node $node The node to be postprocessed. */ public function postprocessNode(Opt_Xml_Node $node) { $name = '_postprocess' . ucfirst($node->getName()); $this->{$name}($node); }