function generate_op_custom_tag($details, &$body)
{
static $tags;
if (!$tags) {
$tags = Haanga_Extension::getInstance('Tag');
}
foreach ($details['list'] as $id => $arg) {
if (Haanga_AST::is_var($arg)) {
$details['list'][$id] = $this->generate_variable_name($arg['var']);
}
}
$tag_name = $details['name'];
$tagFunction = $tags->getFunctionAlias($tag_name);
if (!$tagFunction && !$tags->hasGenerator($tag_name)) {
$function = $this->get_custom_tag($tag_name, isset($details['as']));
} else {
$function = $tagFunction;
}
if (isset($details['body'])) {
/*
if the custom tag has 'body'
then it behave the same way as a filter
*/
$this->ob_start($body);
$this->generate_op_code($details['body'], $body);
$target = hvar('buffer' . $this->ob_start);
if ($tags->hasGenerator($tag_name)) {
$args = array_merge(array($target), $details['list']);
$exec = $tags->generator($tag_name, $this, $args);
if (!$exec instanceof Haanga_AST) {
throw new Exception("Invalid output of custom filter {$tag_name}");
}
if ($exec->stack_size() >= 2 || $exec->doesPrint) {
/*
The generator returned more than one statement,
so we assume the output is already handled
by one of those stmts.
*/
$body->append_ast($exec);
$this->ob_start--;
return;
}
} else {
$exec = hexec($function, $target);
}
$this->ob_start--;
$this->do_print($body, $exec);
return;
}
$var = isset($details['as']) ? $details['as'] : NULL;
$args = array_merge(array($function), $details['list']);
if ($tags->hasGenerator($tag_name)) {
$exec = $tags->generator($tag_name, $this, $details['list'], $var);
if ($exec instanceof Haanga_AST) {
if ($exec->stack_size() >= 2 || $exec->doesPrint || $var !== NULL) {
/*
The generator returned more than one statement,
so we assume the output is already handled
by one of those stmts.
*/
$body->append_ast($exec);
return;
}
} else {
throw new Exception("Invalid output of the custom tag {$tag_name}");
}
} else {
$fnc = array_shift($args);
$exec = hexec($fnc);
foreach ($args as $arg) {
$exec->param($arg);
}
}
if ($var) {
$body->decl($var, $exec);
} else {
$this->do_print($body, $exec);
}
}