rendered paste body<?php
if(!APP) exit;
require_once('tag.php');
class TemplateParser
{
public function parse($template_buffer)
{
$tags = preg_split("~<(/?)([a-z0-9_]+)\:([a-z0-9_]+)((?: [^>]*)?)>~i", $template_buffer, -1, PREG_SPLIT_DELIM_CAPTURE);
$tree = array();
$tree[] = new RootTag();
$i = -1;
while(isset($tags[++$i])) {
$Tag = $tags[$i];
$ParentTag = end($tree);
$key = $i % 5;
if($key == 0) {
$ParentTag->append($Tag);
}
if(isset($tags[$i + 4])) {
$tag_info = array(
'closing' => $tags[$i + 1] == '/',
'ns' => trim($tags[$i + 2]),
'name' => trim($tags[$i + 3]),
'attributes' => trim($tags[$i + 4]),
'non_closing' => false
);
if(!empty($tag_info['attributes']) && $tag_info['attributes']{strlen($tag_info['attributes']) - 1} == '/') {
$tag_info['non_closing'] = true;
$tag_info['attibutes'] = trim(substr($tag_info['attibutes'], 0, -1));
}
if($tag_info['closing']) {
$Tag = array_pop($tree);
$ParentTag = end($tree);
if($tag_info['name'] == $Tag->name) {
$ParentTag->append($Tag->parse());
} else {
$ParentTag->append("<!-- Improper closing tag for [{$tag_info['ns']}:{$tag_info['name']} -->");
}
} else {
$tag_info['file'] = LIB_DIR . DS . 'template' . DS . 'tags' . DS . $tag_info['ns'] . DS . "{$tag_info['name']}.php";
$tag_info['class'] = strtoupper($tag_info['name']) . 'Tag';
if(!file_exists($tag_info['file'])) {
$tag_info['file'] = PLUGIN_DIR . $tag_info['ns'] . DS . 'template' . DS . 'tags' . DS . "{$tag_info['name']}.php";
$tag_info['class'] = strtoupper($tag_info['ns']) . strtoupper($tag_info['name']) . 'Tag';
}
if(file_exists($tag_info['file'])) {
include_once($tag_info['file']);
}
$Tag = (class_exists($tag_info['class'], false)) ? new $tag_info['class']($tag_info['name']) : new UnknownTag($tag_info['name']);
if($tag_info['attributes']) {
preg_match_all('~(?P<key>[a-z]+)="(?P<value>[^"]*)"~i', $tag_info['attributes'], $attributes);
$Tag->attributes = $this->parseTagAttributes($attributes);
}
if($tag_info['non_closing']) {
$ParentTag->append($Tag->parse());
} else {
$tree[] = $Tag;
}
}
}
$i += 4;
}
while($Tag = array_pop($tree)) {
if($Tag instanceof TemplateTag) {
$template_buffer = $Tag->template_buffer;
}
}
return preg_replace_callback('~{(\$|\@|\/)([^}]*)}~', array($this, 'parseVariables'), $template_buffer);
}
public function parseVariables($matches)
{
$variable_type = $matches[1];
$variable_block = trim($matches[2]);
switch($variable_type) {
case '$':
if(!empty($variable_block)) {
$callbacks = explode('|', $variable_block);
$variable_key = array_shift($callbacks);
$template_buffer = "\$Template['{$variable_key}']";
foreach($callbacks as $callback) {
$args = explode(':', $callback);
$function = array_shift($args);
if(function_exists($function)) {
$args = !empty($args) ? ', ' . implode(', ', $args) : null;
$template_buffer = "{$function}({$template_buffer}{$args})";
}
}
$template_buffer = "<?= {$template_buffer} ?>";
}
break;
case '@':
// Gettext support goes here.
$template_buffer = $variable_block;
break;
case '/':
// Relative url support goes here.
$template_buffer = $variable_block;
break;
}
return $template_buffer;
}
private function parseTagAttributes(array $parts = array())
{
$attributes = array();
foreach($parts['key'] as $i => $attrib) {
$attributes[strtolower($attrib)] = $parts['value'][$i];
}
return $attributes;
}
}
?>