/** * The common processing part of the dynamically and statically * deployed components. Returns the compiled PHP code ready to * be appended to the XML tag. The caller must generate a component * variable name that will be used in the generated code to refer * to the component object. Furthermore, he must pass the results * of _extractAttributes() method: both the $params array and the * returned values. * * @internal * @param Opt_Xml_Element $node The node with the component data. * @param string $componentVariable The PHP component variable name. * @param array $params The array of standard component attributes. * @param array $args The array of custom component attributes. * @return string */ private function _commonProcessing(Opt_Xml_Element $node, $componentVariable, array $params, array $args) { // Common part of the component processing $set2 = array(); if (!is_null($params['template'])) { // Scan for opt:set tags - they may contain some custom arguments. $set2 = $node->getElementsByTagNameNS('opt', 'set'); // Now a little trick - how to cheat the opt:insert instruction $attribute = new Opt_Xml_Attribute('opt:use', $params['template']); $this->_compiler->processor('snippet')->processAttribute($node, $attribute); } // Find all the important component elements // Remember that some opt:set tags may have been found above and are located in $set2 array. $everything = $this->_find($node); $everything[0] = array_merge($everything[0], $set2); $code = ''; // opt:set foreach ($everything[0] as $set) { $tagParams = array('name' => array(self::REQUIRED, self::EXPRESSION), 'value' => array(self::REQUIRED, self::EXPRESSION)); $this->_extractAttributes($set, $tagParams); $code .= $componentVariable . '->set(' . $tagParams['name'] . ', ' . $tagParams['value'] . '); '; } foreach ($args as $name => $value) { $code .= $componentVariable . '->set(\'' . $name . '\', ' . $value . '); '; } // com:* and opt:component-attributes foreach ($everything[1] as $wtf) { $id = null; if ($wtf->getNamespace() == 'com') { $wtf->setNamespace(NULL); $subCode = ' $out = ' . $componentVariable . '->manageAttributes(\'' . $wtf->getName() . '\', array('; } else { $id = $wtf->getAttribute('opt:component-attributes')->getValue(); $subCode = ' $out = ' . $componentVariable . '->manageAttributes(\'' . $wtf->getName() . '#' . $id . '\', array('; } foreach ($wtf->getAttributes() as $attribute) { $params = array('__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)); $vars = $this->_extractAttributes($wtf, $params); foreach ($vars as $name => $value) { $subCode .= '\'' . $name . '\' => ' . $value . ','; } } $wtf->removeAttributes(); $wtf->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $subCode . ')); '); $wtf->addAfter(Opt_Xml_Buffer::TAG_ENDING_ATTRIBUTES, ' if(is_array($out)){ foreach($out as $name=>$value){ echo \' \'.$name.\'="\'.$value.\'"\'; } } '); } $node->set('postprocess', true); if (isset($attribute)) { $node->set('_componentTemplate', $attribute); } $this->_process($node); return $code; }
/** * Processes opt:treeelse node. * @internal * @param Opt_Xml_Element $node The instruction node found by the compiler. */ protected function _processTreeelse(Opt_Xml_Element $node) { $parent = $node->getParent(); if ($parent instanceof Opt_Xml_Element && $parent->getXmlName() == 'opt:tree') { $parent->set('sectionElse', true); $section = $this->getSection($parent->get('sectionName')); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, ' } else { '); $this->_process($node); } }
/** * The internal magic shared by the selector elements. Locates the node elements * and constructs the switch() statement for them. * @internal * @param Opt_Xml_Element $node The found element * @param array $section The reference to the section data. * @param string $type The name of the selection item. * @throws Opt_InstructionTooManyItems_Exception */ private function _internalMagic($node, &$section, $type) { $section['format']->assign('item', !$type ? $section['test'] : 'item'); // Check, if there are no instruction tags in the children list. $instructions = array(); $cases = array(); $alternative = null; foreach ($node as $subnode) { if ($subnode instanceof Opt_Xml_Element && $this->_compiler->isNamespace($subnode->getNamespace())) { if ($this->_compiler->isInstruction($subnode->getXmlName()) || $subnode->getXmlName() == 'opt:separator') { if ($subnode != 'opt:selectorelse') { $instructions[] = $subnode; } else { if (!is_null($alternative)) { throw new Opt_InstructionTooManyItems_Exception('opt:selectorelse', $node->getXmlName(), 'Zero or one'); } $alternative = $subnode; } } else { $cases[] = $subnode; } } else { $node->removeChild($subnode); } } if (sizeof($instructions) > 0) { // There are instructions in opt:selector. We have to move the // cases to a fake node in order to sanitize them. $node->removeChildren(); foreach ($instructions as $instruction) { $node->appendChild($instruction); } $fake = new Opt_Xml_Element('opt:_'); foreach ($cases as $case) { $fake->appendChild($case); } $fake->set('processAll', true); $fake->set('hidden', false); $node->appendChild($fake); if (!is_null($alternative)) { $node->appendChild($alternative); } } else { $fake = $node; } $fake->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, 'switch(' . $section['format']->get('section:variable') . '){'); // If opt:selectorelse is used, the ending curly bracket is created by // _processSelectorelse(). if (is_null($alternative)) { $fake->addBefore(Opt_Xml_Buffer::TAG_CONTENT_AFTER, ' } '); } foreach ($cases as $case) { if ($case->getXmlName() == 'opt:separator') { Opl_Debug::write('Print shit'); } if ($case->getName() == 'default') { $case->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, ' default: '); } else { $case->addAfter(Opt_Xml_Buffer::TAG_CONTENT_BEFORE, ' case \'' . $case->getName() . '\': '); } $case->addBefore(Opt_Xml_Buffer::TAG_CONTENT_AFTER, ' break; '); $case->set('processAll', true); $case->set('hidden', false); } }
/** * Returns the concatenated elements of opt:value * * @internal * @param Opt_Xml_Element $node The node to scan. * @param array $params The node parameters. * @return array */ private function _getValuePairs(Opt_Xml_Element $node, array $params) { // The more sophisticated behaviour. $tags = $node->getElementsByTagNameNS('opt', 'value', false); $pairs = new SplQueue(); $else = null; if (isset($params['value'])) { $else = $params['value']; } // Pack the tags into the PHP code. foreach ($tags as $tag) { if ($tag->countChildren() > 1) { throw new Opt_InvalidValue_Exception('opt:value'); } if (!($content = $tag->getLastChild()) instanceof Opt_Xml_Text) { throw new Opt_InvalidValue_Exception('opt:value'); } // Concatenate the tag content into an expression $code = array(); foreach ($content as $items) { if ($items instanceof Opt_Xml_Cdata) { $code[] = '\'' . (string) $items . '\''; } elseif ($items instanceof Opt_Xml_Expression) { $result = $this->_compiler->compileExpression($items->getExpression(), false, Opt_Compiler_Class::ESCAPE_OFF); $code[] = $result[0]; } } $code = $this->_compiler->escape(implode('.', $code)); // Decide, what to do (final alternative or not...) if (($condition = $tag->getAttribute('test')) === null) { if ($else !== null) { throw new Opt_AttributeNotDefined_Exception('test', 'opt:value'); } $else = $code; } else { $result = $this->_compiler->compileExpression($condition, true, Opt_Compiler_Class::ESCAPE_OFF); $pairs->enqueue(array($result[0], $code)); } } return array($pairs, $else); }
/** * Processes the opt:sectionelse element. * @internal * @param Opt_Xml_Element $node The recognized element. */ protected function _processSectionelse(Opt_Xml_Element $node) { $parent = $node->getParent(); if ($parent instanceof Opt_Xml_Element && $parent->getXmlName() == 'opt:section') { $parent->set('priv:alternative', true); $section = self::getSection($parent->get('priv:section')); if (!is_array($section)) { throw new Opt_APINoDataReturned_Exception('Opt_Instruction_BaseSection::getSection', 'processing opt:sectionelse'); } $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, $section['format']->get('section:endLoop') . ' } else { '); $this->_sectionEnd($parent); $this->_process($node); } else { throw new Opt_InstructionInvalidParent_Exception($node->getXmlName(), 'opt:section'); } }
/** * 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) { $current = $tree = new Opt_Xml_Root(); $codeSize = strlen($code); $encoding = $this->_tpl->charset; // First we have to find the prolog and DTD. Then we will be able to parse tags. if ($this->_mode == 0) { // Find and parse XML prolog $endProlog = 0; $endDoctype = 0; if (substr($code, 0, 5) == '<?xml') { $endProlog = strpos($code, '?>', 5); if ($endProlog === false) { throw new Opt_XmlInvalidProlog_Exception('prolog ending is missing'); } $values = $this->_compileProlog(substr($code, 5, $endProlog - 5)); $endProlog += 2; if (!$this->_tpl->prologRequired) { // The prolog must be displayed $tree->setProlog(new Opt_Xml_Prolog($values)); } } // Skip white spaces for ($i = $endProlog; $i < $codeSize; $i++) { if ($code[$i] != ' ' && $code[$i] != ' ' && $code[$i] != "\r" && $code[$i] != "\n") { break; } } // Try to find doctype at the new position. $possibleDoctype = substr($code, $i, 9); if ($possibleDoctype == '<!doctype' || $possibleDoctype == '<!DOCTYPE') { // OK, we've found it, now determine the doctype end. $bracketCounter = 0; $doctypeStart = $i; for ($i += 9; $i < $codeSize; $i++) { if ($code[$i] == '<') { $bracketCounter++; } else { if ($code[$i] == '>') { if ($bracketCounter == 0) { $endDoctype = $i; break; } $bracketCounter--; } } } if ($endDoctype == 0) { throw new Opt_XmlInvalidDoctype_Exception('doctype ending is missing'); } if (!$this->_tpl->prologRequired) { $tree->setDtd(new Opt_Xml_Dtd(substr($code, $doctypeStart, $i - $doctypeStart + 1))); } $endDoctype++; } else { $endDoctype = $endProlog; } // OK, now skip that part. $code = substr($code, $endDoctype, $codeSize); // In the quirks mode, some results from the regular expression parser are // moved by one position, so we must add some dynamics here. $attributeCell = 5; $endingSlashCell = 6; $tagExpression = $this->_rXmlTagExpression; } else { $tagExpression = $this->_rQuirksTagExpression; $attributeCell = 6; $endingSlashCell = 7; } // Split through the general groups (cdata-content) $groups = preg_split($this->_rCDataExpression, $code, 0, PREG_SPLIT_DELIM_CAPTURE); $groupCnt = sizeof($groups); $groupState = 0; Opt_Xml_Cdata::$mode = $this->_mode; for ($k = 0; $k < $groupCnt; $k++) { // Process CDATA if ($groupState == 0 && $groups[$k] == '<![CDATA[') { $cdata = new Opt_Xml_Cdata(''); $cdata->set('cdata', true); $groupState = 1; continue; } if ($groupState == 1) { if ($groups[$k] == ']]>') { $current = $this->_treeTextAppend($current, $cdata); $groupState = 0; } else { $cdata->appendData($groups[$k]); } continue; } $subgroups = preg_split($this->_rCommentExpression, $groups[$k], 0, PREG_SPLIT_DELIM_CAPTURE); $subgroupCnt = sizeof($subgroups); $subgroupState = 0; for ($i = 0; $i < $subgroupCnt; $i++) { // Process comments if ($subgroupState == 0 && $subgroups[$i] == '<!--') { $commentNode = new Opt_Xml_Comment(); $subgroupState = 1; continue; } if ($subgroupState == 1) { if ($subgroups[$i] == '-->') { $current->appendChild($commentNode); $subgroupState = 0; } else { $commentNode->appendData($subgroups[$i]); } continue; } elseif ($subgroups[$i] == '-->') { throw new Opt_XmlInvalidCharacter_Exception('-->'); } // Find XML tags preg_match_all($tagExpression, $subgroups[$i], $result, PREG_SET_ORDER); /* * Output field description for $result array: * 0 - original content * 1 - tag content (without delimiters) * 2 - /, if enclosing tag * 3 - name * 4 - arguments (5 in quirks mode) * 5 - /, if enclosing tag without subcontent (6 in quirks mode) */ $resultSize = sizeof($result); $offset = 0; for ($j = 0; $j < $resultSize; $j++) { // Copy the remaining text to the text node $id = strpos($subgroups[$i], $result[$j][0], $offset); if ($id > $offset) { $current = $this->_treeTextCompile($current, substr($subgroups[$i], $offset, $id - $offset)); } $offset = $id + strlen($result[$j][0]); if (!isset($result[$j][$endingSlashCell])) { $result[$j][$endingSlashCell] = ''; } // Process the argument list $attributes = array(); if (!empty($result[$j][$attributeCell])) { // Just for sure... $result[$j][$attributeCell] = trim($result[$j][$attributeCell]); $oldLength = strlen($result[$j][$attributeCell]); $result[$j][$attributeCell] = rtrim($result[$j][$attributeCell], '/'); if (strlen($result[$j][$attributeCell]) != $oldLength) { $result[$j][$endingSlashCell] = '/'; } $attributes = $this->_compileAttributes($result[$j][$attributeCell]); if (!is_array($attributes)) { throw new Opt_XmlInvalidAttribute_Exception($result[$j][0]); } } // Recognize the tag type if ($result[$j][3] != '/') { // Opening tag $node = new Opt_Xml_Element($result[$j][4]); $node->set('single', $result[$j][$endingSlashCell] == '/'); foreach ($attributes as $name => $value) { $node->addAttribute($anode = new Opt_Xml_Attribute($name, $value)); } $current = $this->_treeNodeAppend($current, $node, $result[$j][$endingSlashCell] != '/'); } elseif ($result[$j][3] == '/') { if (sizeof($attributes) > 0) { throw new Opt_XmlInvalidTagStructure_Exception($result[$j][0]); } if ($current instanceof Opt_Xml_Element) { if ($current->getXmlName() != $result[$j][4]) { throw new Opt_XmlInvalidOrder_Exception($result[$j][4], $current->getXmlName()); } } else { throw new Opt_XmlInvalidOrder_Exception($result[$j][4], 'NULL'); } $current = $this->_treeJumpOut($current); } else { throw new Opt_XmlInvalidTagStructure_Exception($result[$j][0]); } } if (strlen($subgroups[$i]) > $offset) { $current = $this->_treeTextCompile($current, substr($subgroups[$i], $offset, strlen($subgroups[$i]) - $offset)); } } } // Testing if everything was closed. if ($current !== $tree) { // Error handling - determine the name of the unclosed tag. while (!$current instanceof Opt_Xml_Element) { $current = $current->getParent(); } throw new Opt_UnclosedTag_Exception($current->getXmlName()); } if ($this->_mode == 0 && $this->_tpl->singleRootNode) { // TODO: The current code does not check the contents of Opt_Text_Nodes and other root elements // that may contain invalid and valid XML syntax at the same time. // For now, this code is frozen, we'll think a bit about it in the future. Maybe nobody // will notice this :) $elementFound = false; foreach ($tree as $item) { if ($item instanceof Opt_Xml_Element) { if ($elementFound) { // Oops, there is already another root node! throw new Opt_XmlRootElement_Exception($item->getXmlName()); } $elementFound = true; } } } return $tree; }
/** * An utility method that cleans the contents of the section node, by * moving the alternative section (opt:sectionelse etc. tags) code to the end * of the children list. * * In the parameters, we must specify the name and the namespace of the * tags that will be treated as the alternative content tags. * * @param Opt_Xml_Element $node The section node * @param String $ns The namespace * @param String $name The alternative section content tag name */ protected function _sortSectionContents(Opt_Xml_Element $node, $ns, $name) { $else = $node->getElementsByTagNameNS($ns, $name, false); if (sizeof($else) == 1) { if (!$node->hasAttributes()) { throw new Opt_InstructionTooManyItems_Exception($ns . ':' . $name, $node->getXmlName(), 'Zero'); } $node->bringToEnd($else[0]); } elseif (sizeof($else) > 1) { throw new Opt_InstructionTooManyItems_Exception($ns . ':' . $name, $node->getXmlName(), 'Zero or one'); } }
/** * Postprocesses the opt:insert element. * @internal * @param Opt_Xml_Element $node The found element. */ public function _postprocessInsert(Opt_Xml_Element $node) { // Freeing the fake node, if necessary. if (!is_null($node->get('insertSize'))) { $this->_snippets[$node->get('insertSnippet')][$node->get('insertSize')]->dispose(); unset($this->_snippets[$node->get('insertSnippet')][$node->get('insertSize')]); } // Restore the original escaping state $this->_compiler->set('escaping', $node->get('escaping')); array_pop($this->_current); }
/** * 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']; } }
/** * 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; }
public function testScannableInsertBefore2() { $topNode = new Opt_Xml_Element('foo'); $subnodes = array(0 => new Opt_Xml_Element('bar'), new Opt_Xml_Element('joe'), new Opt_Xml_Element('goo')); $topNode->appendChild($subnodes[0]); $topNode->appendChild($subnodes[1]); $topNode->insertBefore($subnodes[2]); $ok = true; $i = 0; foreach ($topNode as $n) { if ($n !== $subnodes[$i]) { $ok = false; } $i++; } $this->assertTrue($ok); }
/** * @covers Opt_Xml_Buffer::copyBuffer */ public function testCopyBufferExisting() { $this->_obj->addAfter(Opt_Xml_Buffer::TAG_BEFORE, 'foo'); $obj2 = new Opt_Xml_Element('opt:foo'); $obj2->addAfter(Opt_Xml_Buffer::TAG_AFTER, 'bar'); $obj2->copyBuffer($this->_obj, Opt_Xml_Buffer::TAG_BEFORE, Opt_Xml_Buffer::TAG_AFTER); $buf1 = $obj2->getBuffer(Opt_Xml_Buffer::TAG_AFTER); $this->assertEquals(array('foo', 'bar'), $buf1); }
/** * The common processing part of the dynamically and statically * deployed components. Returns the compiled PHP code ready to * be appended to the XML tag. The caller must generate a component * variable name that will be used in the generated code to refer * to the component object. Furthermore, he must pass the returned results * of _extractAttributes() method. * * @internal * @param Opt_Xml_Element $node The node with the component data. * @param string $blockVariable The PHP block variable name. * @param array $args The array of custom block attributes. * @return string */ private function _commonProcessing(Opt_Xml_Element $node, $blockVariable, array $args) { // Common part of the component processing $argList = 'array( '; foreach ($args as $name => $value) { $argList .= '\'' . $name . '\' => ' . $value . ', '; } $argList .= ')'; if ($node->get('single')) { $node->addAfter(Opt_Xml_Buffer::TAG_SINGLE_BEFORE, $blockVariable . '->onSingle(' . $argList . '); '); } else { $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, ' if(' . $blockVariable . '->onOpen(' . $argList . ')){ '); $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, ' } ' . $blockVariable . '->onClose(); '); } $this->_process($node); }
/** * Processes the opt:gridelse tag. * @internal * @param Opt_Xml_Element $node The recognized node. */ protected function _processGridelse(Opt_Xml_Element $node) { $parent = $node->getParent(); if ($parent instanceof Opt_Xml_Element && $parent->getXmlName() == 'opt:grid') { $parent->set('priv:alternative', true); $section = $parent->get('priv:section'); $node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, ' } else { '); // $this->_deactivateSection($parent->get('sectionName')); $this->_process($node); } }