public function addFunction($name, $callback) { $this->compilerContext->addFunction($name, $callback); }
/** * @return string * @throws CompilerException */ public function compile() { $namespace = null; $className = trim($this->context->getFullyQualifiedClassName(), "\\"); $pos = strrpos($className, "\\"); if ($pos !== false) { $namespace = substr($className, 0, $pos); $className = substr($className, $pos + 1); } // prelude $ret = ""; $ret .= "<?php\n"; if ($namespace) { $ret .= "namespace {$namespace};\n"; $ret .= "\n"; } foreach ($this->context->getUses() as $alias => $fqn) { $ret .= "use {$fqn} as {$alias};\n"; } $ret .= "\n"; $ret .= "class {$className} implements \\Skrz\\Templating\\Engine\\TemplateInterface {\n"; $ret .= "\n"; $ret .= "public function __invoke(array \$____) {\n"; $ret .= "\t\$this->render(\$____);\n"; $ret .= "}\n"; $ret .= "\n"; $ret .= "public function fetch(array \$____) {\n"; $ret .= "\tob_start();\n"; $ret .= "\t\$this->render(\$____);\n"; $ret .= "\treturn ob_get_clean();\n"; $ret .= "}\n"; $ret .= "\n"; $ret .= "public function fetchFunction(\$functionName, array \$____) {\n"; $ret .= "\tob_start();\n"; $ret .= "\t\$this->{'render' . \$functionName}(\$____);\n"; $ret .= "\treturn ob_get_clean();\n"; $ret .= "}\n"; $ret .= "\n"; $ret .= "public function renderFunction(\$functionName, array \$____) {\n"; $ret .= "\t\$this->{'render' . \$functionName}(\$____);\n"; $ret .= "}\n"; $ret .= "\n"; // find function declarations $functionDeclarationFinder = new FunctionDeclarationsWalker(); $functionDeclarationFinder->walk($this->context->getTemplate()); // function declarations have to be registered first and compiled into render functions, // otherwise recursive calls would not be possible $ret .= "private \$functions = array("; foreach ($functionDeclarationFinder->getDeclarations() as $declaration) { $ret .= var_export($declaration->getName(), true) . "=>true,"; $this->context->addFunction($declaration->getName(), function (Compiler $compiler, FunctionNode $node) use($declaration) { $statement = ""; $args = "array("; foreach ($node->getArguments() as $name => $expression) { $statementAndExpression = $compiler->walkExpression($expression); $statement .= $statementAndExpression->getStatement(); $args .= var_export($name, true) . '=>' . $statementAndExpression->getExpression() . ","; } $args .= ")"; return new FunctionCompilerResult($statement . "\$this->" . $this->getRenderName($declaration->getName()) . "(" . $args . " + \$____);"); }); } $ret .= ");\n\n"; $ret .= "public function hasFunction(\$functionName) {\n"; $ret .= "\treturn isset(\$this->functions[\$functionName]);\n"; $ret .= "}\n\n"; foreach ($functionDeclarationFinder->getDeclarations() as $declaration) { $ret .= $this->compileRender($declaration->getName(), $declaration->getBody(), $declaration->getDefaultArguments()); } // compile main render $ret .= $this->compileRender("", array($this->context->getTemplate())); // end $ret .= "\n"; $ret .= "}\n"; return $ret; }