function _parseFunction($name, $args) { switch ($name) { case 'if': $res = 'if (' . $this->_parseFinal($args, $this->_allowedInExpr) . '): '; array_push($this->_blockStack, 'if'); break; case 'else': if (end($this->_blockStack) != 'if') { throw new Exception(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack))); } $res = 'else: '; break; case 'elseif': if (end($this->_blockStack) != 'if') { throw new Exception(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack))); } $res = 'elseif(' . $this->_parseFinal($args, $this->_allowedInExpr) . '):'; break; case 'foreach': $res = 'foreach (' . $this->_parseFinal($args, array_merge(array(T_AS, T_DOUBLE_ARROW, T_STRING, T_OBJECT_OPERATOR, T_LIST, $this->_allowedAssign, '[', ']')), array(';', '!')) . '): '; array_push($this->_blockStack, 'foreach'); break; case 'while': $res = 'while(' . $this->_parseFinal($args, $this->_allowedInExpr) . '):'; array_push($this->_blockStack, 'while'); break; case '/foreach': case '/if': case '/while': $short = substr($name, 1); if (end($this->_blockStack) != $short) { throw new Exception(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack))); } array_pop($this->_blockStack); $res = 'end' . $short . '; '; break; case 'assign': $res = $this->_parseFinal($args, $this->_allowedAssign) . '; '; break; case 'literal': if (count($this->_literals)) { $res = '?>' . array_shift($this->_literals) . '<?php '; } else { throw new Exception(__('End tag of a block missing: literal')); } break; case '/literal': throw new Exception(__('Start tag of a block missing: literal')); break; case 'block': $res = '?>' . $this->_extendBlocks[$args] . '<?php '; break; case 'superblock': $res = '?>~~{~~superblock~~}~~<?php '; break; case 'trans': $argfct = $this->_parseFinal($args, $this->_allowedAssign); $res = 'echo(__(' . $argfct . '));'; break; case 'blocktrans': array_push($this->_blockStack, 'blocktrans'); $res = ''; $this->_transStack = array(); if ($args) { $this->_transPlural = true; $_args = $this->_parseFinal($args, $this->_allowedAssign, array(';', '[', ']'), true); $res .= '$_btc=' . trim(array_shift($_args)) . '; '; } $res .= 'ob_start(); '; break; case '/blocktrans': $short = substr($name, 1); if (end($this->_blockStack) != $short) { throw new Exception(sprintf(__('End tag of a block missing: %s'), end($this->_blockStack))); } $res = ''; if ($this->_transPlural) { $res .= '$_btp=ob_get_contents(); ob_end_clean(); echo('; $res .= '\\photon\\translation\\Translation::sprintf(_n($_bts, $_btp, $_btc), array('; $_tmp = array(); foreach ($this->_transStack as $key => $_trans) { $_tmp[] = '\'' . addslashes($key) . '\' => \\photon\\template\\Renderer::sreturn(' . $_trans . ')'; } $res .= implode(', ', $_tmp); unset($_trans, $_tmp); $res .= ')));'; $this->_transStack = array(); } else { $res .= '$_bts=ob_get_contents(); ob_end_clean(); '; if (count($this->_transStack) == 0) { $res .= 'echo(__($_bts)); '; } else { $res .= 'echo(\\photon\\translation\\Translation::sprintf(__($_bts), array('; $_tmp = array(); foreach ($this->_transStack as $key => $_trans) { $_tmp[] = '\'' . addslashes($key) . '\' => \\photon\\template\\Renderer::sreturn(' . $_trans . ')'; } $res .= implode(', ', $_tmp); unset($_trans, $_tmp); $res .= '))); '; $this->_transStack = array(); } } $this->_transPlural = false; array_pop($this->_blockStack); break; case 'plural': $res = '$_bts=ob_get_contents(); ob_end_clean(); ob_start(); '; break; case 'include': // FUTURE: Will need some security check, when online editing. $argfct = preg_replace('!^[\'"](.*)[\'"]$!', '$1', $args); $_comp = new Compiler($argfct, $this->templateFolders); $res = $_comp->compile(); $this->updateModifierStack($_comp); break; default: $_end = false; $oname = $name; if (substr($name, 0, 1) == '/') { $_end = true; $name = substr($name, 1); } // FUTURE: Here we could allow custom blocks. // Here we start the template tag calls at the template tag // {tag ...} is not a block, so it must be a function. if (!isset($this->_allowedTags[$name])) { throw new Exception(sprintf(__('The function tag "%s" is not allowed.'), $name)); } $argfct = $this->_parseFinal($args, $this->_allowedAssign); // $argfct is a string that can be copy/pasted in the PHP code // but we need the array of args. $res = ''; if (isset($this->_extraTags[$name])) { if (false == $_end) { if (method_exists($this->_extraTags[$name], 'start')) { $res .= '$_etag = new ' . $this->_allowedTags[$name] . '($t); $_etag->start(' . $argfct . '); '; } if (method_exists($this->_extraTags[$name], 'genStart')) { $res .= $this->_extraTags[$name]->genStart(); } } else { if (method_exists($this->_extraTags[$name], 'genEnd')) { $res .= $this->_extraTags[$name]->genEnd(); } if (method_exists($this->_extraTags[$name], 'end')) { $res .= '$_etag = new ' . $this->_allowedTags[$name] . '($t); $_etag->end(' . $argfct . '); '; } } } if ($res == '') { throw new Exception(sprintf(__('The function tag "{%s ...}" is not supported.'), $oname)); } } return $res; }
public function run() { $this->loadConfig(); $folders = Conf::f('template_folders', array()); $tmp_folder = sys_get_temp_dir() . '/' . uniqid('photon', true); @mkdir($tmp_folder); @touch($this->potfile); // Compile all template to generate PHP Code $already_compiled = array(); foreach ($folders as $folder) { foreach (\photon\path\Dir::listFiles($folder) as $tpl) { if (!in_array($tpl, $already_compiled)) { // Compile the template $compiler = new compiler\Compiler($tpl, $folders); $content = $compiler->compile(); // save it $output = $tmp_folder . '/' . $tpl; $directory = dirname($output); if (is_dir($directory) === false) { mkdir($directory, 0777, true); } file_put_contents($output, $content); $already_compiled[] = $tpl; } } } $return_var = 0; // Run xgettext on PHP project source $cmd = 'cd ' . $this->cwd . ' && find . -type f -iname "*.php" | sed -e \'s/^\\.\\///\' | xargs xgettext -o ' . $this->potfile . ' -p ' . $this->cwd . ' --from-code=UTF-8 -j --keyword --keyword=__ --keyword=_n:1,2 -L PHP'; passthru($cmd, $return_var); // Run xgettext on PHP project compiled template source $cmd = 'cd ' . $tmp_folder . ' && find . -type f | sed -e \'s/^\\.\\///\' | xargs xgettext -o ' . $this->potfile . ' -p ' . $this->cwd . ' --from-code=UTF-8 -j --keyword --keyword=__ --keyword=_n:1,2 -L PHP'; passthru($cmd, $return_var); \photon\path\Dir::remove($tmp_folder); }
public function testVarBadChar2() { $compiler = new compiler\Compiler('dummy', array(__DIR__), array('load' => false)); $compiler->templateContent = '{$;}'; $this->setExpectedException('\\photon\\template\\compiler\\Exception'); print $compiler->compile(); }