/** * @param string $name * @param AbstractNode[] $body * @param ExpressionNode[] $defaults * @return string * @throws CompilerException */ private function compileRender($name, $body, $defaults = array()) { $ret = "public function " . $this->getRenderName($name) . "(array \$____) {\n"; $ret .= "\$____ = \$____;\n"; // FIXME: why? if ($this->context->getAppPath() && $this->context->getOutputFileName()) { $appPath = realpath($this->context->getAppPath()); $templateFileName = $this->context->getParserContext()->getFileName(); if (strncmp($templateFileName, $appPath, strlen($appPath)) !== 0) { throw new CompilerException($this->context, "Template '{$templateFileName}' is outside of app path '{$appPath}'."); } $outputFileName = $this->context->getOutputFileName(); if (strncmp($outputFileName, $appPath, strlen($appPath)) !== 0) { throw new CompilerException($this->context, "Output file name '{$outputFileName}' is outside of app path '{$appPath}'."); } $templateFileName = explode("/", substr($templateFileName, strlen($appPath) + 1)); $outputFileName = explode("/", substr($outputFileName, strlen($appPath) + 1)); array_pop($templateFileName); array_pop($outputFileName); while (current($templateFileName) === current($outputFileName)) { array_shift($templateFileName); array_shift($outputFileName); } $relative = var_export(str_repeat("/..", count($outputFileName)) . "/" . implode("/", $templateFileName), true); $dirName = "__DIR__ . {$relative}"; } else { $dirName = var_export(dirname($this->context->getParserContext()->getFileName()), true); } $ret .= "\$smarty = (object) array('current_dir' => {$dirName}, 'get' => \$_GET, 'post' => \$_POST, 'cookie' => \$_COOKIE, 'now' => time(), 'capture' => (object) array(), 'foreach' => (object) array(), 'section' => (object) array());"; // prepare variable names $finder = new VariableNamesWalker(); $variableNames = array_keys($finder->walk($this->context->getTemplate())); foreach ($variableNames as $variableName) { if ($variableName === "smarty") { continue; } $ret .= "if(isset(\$____['{$variableName}'])){"; $ret .= "\${$variableName}=\$____['{$variableName}'];"; $ret .= "}else{"; if (isset($defaults[$variableName])) { $statementAndExpression = $this->walkExpression($defaults[$variableName]); $ret .= $statementAndExpression->getStatement(); $ret .= "\${$variableName}={$statementAndExpression->getExpression()};"; } else { $ret .= "\${$variableName}=null;"; } $ret .= "}\n"; } // main $ret .= $this->context->getBeforeCode(); $ret .= "\n"; $ret .= implode("", $this->walkEach($body)); $ret .= "\n"; $ret .= $this->context->getAfterCode(); $ret .= "\n\n"; $ret .= "}\n"; return $ret; }