/** * The main compilation function - called recursivley to process * * @param DOMNode $node * @return void */ public function process(DOMNode $node) { $end = null; $processChildren = true; switch ($node->nodeType) { case XML_DOCUMENT_NODE: break; case XML_COMMENT_NODE: $body = trim($node->data); if (strpos($body, "\n") === false) { $this->write("<?php\n// {$body}\n?>"); } else { $lines = explode("\n", $body); for ($i = 0; $i < count($lines); $i++) { if ($i == 0) { $buf = '/* ' . $lines[$i] . "\n"; } else { $buf .= ' * ' . $lines[$i] . "\n"; } } $this->write("<?php\n{$buf} */\n?>"); } break; case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: $text = PHPSTLExpressionParser::expand($node->nodeValue); if ($this->whitespace == self::WHITESPACE_TRIM) { $text = trim($text); $text = preg_replace('/\\s+/s', ' ', $text); } $this->write($text); break; case XML_PI_NODE: switch ($node->target) { case 'php': $data = trim($node->data); if (!preg_match('/[:;{}]$/', $data)) { $data .= ';'; } $this->write("<?php {$data} ?>"); break; case 'whitespace': switch (trim($node->data)) { case 'preserve': $this->whitespace = self::WHITESPACE_PRESERVE; break; case 'collapse': $this->whitespace = self::WHITESPACE_COLLAPSE; break; case 'trim': $this->whitespace = self::WHITESPACE_TRIM; break; default: throw new PHPSTLCompilerException($this, "invalid <?whitespace {$node->data} ?>"); break; } break; default: throw new PHPSTLCompilerException($this, "unknown processing instruction {$node->target}"); } break; case XML_ELEMENT_NODE: $attrs = array(); foreach ($node->attributes as $name => $attr) { if (isset($attr->namespaceURI)) { $handler = $this->handleNamespace($attr->namespaceURI); $val = $handler->handle($attr); $node->removeAttributeNode($attr); if (isset($val)) { $attrs[$attr->name] = $val; } } else { $attrs[$attr->name] = $attr->value; } } if ($node === $this->dom->documentElement) { foreach ($attrs as $name => $value) { $this->meta[$name] = $value; } } elseif (isset($node->namespaceURI)) { $processChildren = false; $handler = $this->handleNamespace($node->namespaceURI); $handler->handle($node); } else { $start = "<{$node->nodeName}"; foreach ($attrs as $name => $value) { $start .= " {$name}=\"{$value}\""; } if ($node->hasChildNodes() && ($this->meta['type'] != 'text/html' || !in_array($node->nodeName, self::$HTMLSingleTags))) { $start .= '>'; $end = "</{$node->nodeName}>"; } else { $processChildren = false; $start .= ' />'; } $this->write($start); } break; } if ($processChildren && $node->hasChildNodes()) { foreach ($node->childNodes as $child) { $this->process($child); } } if (isset($end)) { $this->write($end); } }
/** * Expands variable expressions in the given value * * This is used by attribute retreival methos to expand ${...} and @{...} * expressions into real php * * @param string $value * * @param boolean $full defaults false, if true then the expansion will be * done to full <?php ... ?> directives, this usually isn't what you want * since most consumers of attribute values want a value for use in * building a <?php ... ?> block * * @return $value */ protected function expand($value, $full = false) { return PHPSTLExpressionParser::expand($value, $full, $full, !$full); }