protected function parseXmlElement($xmlElement, $replaceCurrent = false, $replaceCurrentValues = false) { $placeholderCount = 0; // Get all ODT text nodes $nodeList = $this->toArray($xmlElement->getElementsByTagNameNS(self::NS_TEXT, '*')); foreach ($nodeList as $node) { if (!$node || !is_object($node)) { continue; } $replaceVars = array(); $childNodeList = $this->toArray($node->childNodes); // Parse the placeholders and prepare the data for them foreach ($childNodeList as $element) { if (!$node || !is_object($node)) { continue; } // Skip nodes which dont include text (i.e. images) if ($element->nodeName != '#text') { continue; } // Skip empty nodes if (!$element->nodeValue) { continue; } // Get all placeholders in current node $placeholderList = SodaODTParser::parse($element->nodeValue); if (!$placeholderList) { continue; } $placeholderCount++; foreach ($placeholderList as $placeholder) { if (!is_array($this->replaceValueList[$placeholder['name']])) { // single static values $replaceVars[$placeholder['replaceString']] = $this->getReplaceValue($this->replaceValueList[$placeholder['name']], $placeholder, $element); } elseif ($placeholder['name'] == $replaceCurrent) { // replace placeholders of table row data lists if (isset($replaceCurrentValues[$placeholder['subname']])) { $tmpVal = $this->getReplaceValue($replaceCurrentValues[$placeholder['subname']], $placeholder, $element); if (is_a($tmpVal, 'SodaODTInstruction')) { if ($tmpVal->getInstruction() == 'hide_block') { return false; } elseif ($tmpVal->getInstruction() == 'show_block') { // nothing } } $replaceVars[$placeholder['replaceString']] = $tmpVal; } else { // just remove invalid data list placeholders $replaceVars[$placeholder['replaceString']] = ''; } } else { // handle table row data lists if (isset($this->finishedPlaceholders[$placeholder['name']])) { continue; } // Get the row element which should be repeated $removeNodeList = array(self::$nsPrefixList[self::NS_TEXT] . ':soft-page-break'); $repeatElementList = $this->getParentElementListOfType($element, $this->repeatableTags, $removeNodeList, $removeNodeList); if (!$repeatElementList) { continue; } // Create a new table row for every entry in $this->replaceValueList foreach ($this->replaceValueList[$placeholder['name']] as $listReplaceValues) { foreach ($repeatElementList as $tmpKey => $repeatElement) { $newNode = $repeatElement->cloneNode(true); $parseInfo = $this->parseXmlElement($newNode, $placeholder['name'], $listReplaceValues); if ($parseInfo === 0) { unset($repeatElementList[$tmpKey]); } elseif ($parseInfo !== false) { $repeatElementList[0]->parentNode->insertBefore($newNode, $repeatElementList[0]); } } } // Remove the row with the plain placeholder tags foreach ($repeatElementList as $repeatElement) { $repeatElement->parentNode->removeChild($repeatElement); } $this->finishedPlaceholders[$placeholder['name']] = true; } } } if ($replaceVars) { foreach ($replaceVars as $tmpKey => $tmpVal) { if (is_a($tmpVal, 'SodaODTInstruction')) { if ($tmpVal->getInstruction() == 'hide') { $instructionData = $tmpVal->getData(); $element = $instructionData['element']; $matchList = false; if ($instructionData['mode'] == 'row') { $matchList = array(array(self::NS_TABLE, 'table-row')); } elseif ($instructionData['mode'] == 'table') { $matchList = array(array(self::NS_TABLE, 'table')); } elseif ($instructionData['mode'] == 'frame') { $matchList = array(array(self::NS_DRAW, 'frame')); } elseif ($instructionData['mode'] == 'paragraph') { $matchList = array(array(self::NS_TEXT, 'p')); } if ($matchList) { $removeElement = $this->getParentElementOfType($element, $matchList); if ($removeElement) { if ($removeElement->parentNode) { $removeElement->parentNode->removeChild($removeElement); } else { return false; } } } } $replaceVars[$tmpKey] = ''; } } } // Do the actual replacement of the placeholders if ($replaceVars) { foreach ($node->childNodes as $element) { if ($element->nodeName != '#text') { continue; } $element->nodeValue = strtr($element->nodeValue, $replaceVars); } } } return $placeholderCount; }
protected function parseFunction() { $function = array('name' => false, 'args' => array()); // Parse function name preg_match('/^;\\s*([A-Za-z0-9_-]+)\\s*/', substr(self::$parseStr, self::$lastPos, self::$snippetEndPos), $match); if (!$match) { return false; } self::$lastPos += strlen($match[0]); $function['name'] = $match[1]; if (self::$parseStr[self::$lastPos] == ';') { return $function; } elseif (self::$parseStr[self::$lastPos] != '(') { return false; } // Parse function arguments do { self::$lastPos++; $arg = null; preg_match('/\\s*(?|' . '("){1}((?:[^"\\\\]|\\\\.)*)"' . '|(\'){1}((?:[^\'\\\\]|\\\\.)*)\'' . '|(”){1}((?:[^”\\\\]|\\\\.)*)”' . '|([A-Za-z0-9._-]+)' . ')\\s*/', substr(self::$parseStr, self::$lastPos), $match); if (!$match) { return false; } if (isset($match[2])) { $arg = $match[2]; $arg = str_replace("\\" . $match[1], $match[1], $arg); } else { $arg = $match[1]; } self::$lastPos += strlen($match[0]); if (self::$lastPos >= self::$snippetEndPos) { self::$snippetEndPos = strpos(self::$parseStr, '}', self::$lastPos); } $function['args'][] = $arg; } while (self::$parseStr[self::$lastPos] == ','); if (!preg_match('/\\s*\\)\\s*/', substr(self::$parseStr, self::$lastPos, self::$snippetEndPos), $match)) { return false; } self::$lastPos += strlen($match[0]); return $function; }