/** * Given the set of matches, nest them according to their types * * @param \ArrayIterator $result Iterator of match results * @param \SalesforceEng\Breakout\Token $latest Token instance * @return array Set of nested token instances (arrays) */ public function nest(&$result, $latest = null) { $container = []; if (!$result instanceof \ArrayIterator) { $result = new \ArrayIterator($result); } while ($result->valid()) { $current = new Token($result->current()); $result->next(); if ($current->getType() == 'block') { // see if we're closing it out $content = trim($current->getContent()); if ($content !== 'endif' && $content !== 'endfor' && $content !== 'else' && $content !== 'endraw') { $group = [$current]; $found = $this->nest($result, $current); $current = array_merge($group, $found); } else { if ($latest !== null) { $latestType = explode(' ', trim($latest->getContent()))[0]; if ($latestType == 'if' && trim($current->getContent()) == 'endif') { $container[] = $current; return $container; } elseif ($latestType == 'for' && trim($current->getContent()) == 'endfor') { $container[] = $current; return $container; } elseif ($latestType == 'raw' && trim($current->getContent()) == 'endraw') { $container[] = $current; return $container; } } } } $container[] = $current; } return $container; }
/** * Handle the replacement and escaping for a variable value * * @param array $data Data to use for the variable * @param \SalesforceEng\Breakout\Token $token Token instance * @param \SalesforceEng\Breakout\Document $document Document instance * @return SalesforceEng\Breakout\Document updated instance */ public function handleVariable(array $data, $token, Document $document) { $key = trim($token->getContent()); if (strpos($key, '|') !== false) { list($key, $context) = explode('|', $key); } else { $context = 'html'; } $resolved = $this->resolveValue($data, $key); $content = $resolved !== null ? $resolved : ''; if (!array_key_exists($context, $this->contextCache)) { // Escape the content according to the context $contextNs = '\\SalesforceEng\\Breakout\\Context\\' . ucwords(strtolower($context)); if (!class_exists($contextNs)) { throw new \InvalidArgumentException('Context "' . $context . '" does not exist!'); } $instance = new $contextNs(); $this->contextCache[$context] = $instance; } else { $instance = $this->contextCache[$context]; } $content = $this->normalizeUtf8($content); $content = $this->unicodeEscape($content); $document->replace($token, $instance->escape($content)); return $document; }
/** * Replace the token with the provided content * Updates the document (self) in place, no return value * * @param \SalesforceEng\Breakout\Token $token Token instance * @param string $content Content used for replacement */ public function replace($token, $content) { // get the length of the tag to replace $tagLength = strlen($token->getFull()); $contentLength = strlen($content); $currentOffset = $this->getOffset(); // Get the portions before and after the tag $start = substr($this->document, 0, $token->getStart() + $currentOffset); $end = substr($this->document, $token->getEnd() + $currentOffset); // ...and merge $updatedDocument = $start . $content . $end; $this->setOffset(strlen($updatedDocument) - strlen($this->document) + $currentOffset); $this->document = $updatedDocument; }