This commit is contained in:
bzick
2016-08-22 17:08:47 +03:00
parent 58f8c0facb
commit 3171d80d8b
4 changed files with 83 additions and 57 deletions

View File

@@ -5,9 +5,11 @@ require_once __DIR__.'/../tests/tools.php';
\Fenom::registerAutoload(); \Fenom::registerAutoload();
$fenom = Fenom::factory(__DIR__.'/templates', __DIR__.'/../tests/resources/compile'); $fenom = Fenom::factory(__DIR__.'/templates', __DIR__.'/compiled');
$fenom->setOptions(Fenom::AUTO_RELOAD); $fenom->setOptions(Fenom::AUTO_RELOAD | Fenom::FORCE_VERIFY);
var_dump($fenom->compileCode('{do $object->method()}')->getTemplateCode()); //var_dump($fenom->compile("nested.tpl", [])->getTemplateCode());
//exit;
var_dump($fenom->fetch('bug247/home.tpl', []));
//var_dump($fenom->compile("bug158/main.tpl", [])->getTemplateCode()); //var_dump($fenom->compile("bug158/main.tpl", [])->getTemplateCode());
//var_dump($fenom->display("bug158/main.tpl", [])); //var_dump($fenom->display("bug158/main.tpl", []));
// $fenom->getTemplate("problem.tpl"); // $fenom->getTemplate("problem.tpl");

View File

@@ -10,11 +10,11 @@
namespace Fenom; namespace Fenom;
use Fenom; use Fenom;
use Fenom\Error\UnexpectedTokenException;
use Fenom\Error\CompileException; use Fenom\Error\CompileException;
use Fenom\Error\InvalidUsageException; use Fenom\Error\InvalidUsageException;
use Fenom\Error\SecurityException; use Fenom\Error\SecurityException;
use Fenom\Error\TokenizeException; use Fenom\Error\TokenizeException;
use Fenom\Error\UnexpectedTokenException;
/** /**
* Template compiler * Template compiler
@@ -27,6 +27,12 @@ class Template extends Render
const VAR_NAME = '$var'; const VAR_NAME = '$var';
const TPL_NAME = '$tpl'; const TPL_NAME = '$tpl';
const COMPILE_STAGE_LOADED = 1;
const COMPILE_STAGE_PRE_FILTERED = 2;
const COMPILE_STAGE_PARSED = 3;
const COMPILE_STAGE_PROCESSED = 4;
const COMPILE_STAGE_POST_FILTERED = 5;
/** /**
* Disable array parser. * Disable array parser.
*/ */
@@ -80,6 +86,7 @@ class Template extends Render
* @var string * @var string
*/ */
private $_body; private $_body;
private $_compile_stage = 0;
/** /**
* Call stack * Call stack
@@ -166,6 +173,7 @@ class Template extends Render
} }
$this->_provider = $this->_fenom->getProvider($provider); $this->_provider = $this->_fenom->getProvider($provider);
$this->_src = $this->_provider->getSource($this->_base_name, $this->_time); $this->_src = $this->_provider->getSource($this->_base_name, $this->_time);
$this->_compile_stage = self::COMPILE_STAGE_LOADED;
if ($compile) { if ($compile) {
$this->compile(); $this->compile();
} }
@@ -200,6 +208,8 @@ class Template extends Render
foreach ($this->_fenom->getPreFilters() as $filter) { foreach ($this->_fenom->getPreFilters() as $filter) {
$this->_src = call_user_func($filter, $this, $this->_src); $this->_src = call_user_func($filter, $this, $this->_src);
} }
$this->_compile_stage = self::COMPILE_STAGE_PRE_FILTERED;
while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags while (($start = strpos($this->_src, '{', $pos)) !== false) { // search open-symbol of tags
switch (substr($this->_src, $start + 1, 1)) { // check next character switch (substr($this->_src, $start + 1, 1)) { // check next character
case "\n": case "\n":
@@ -265,6 +275,7 @@ class Template extends Render
} }
$pos = $end + 1; // move search-pointer to end of the tag $pos = $end + 1; // move search-pointer to end of the tag
} }
$this->_compile_stage = self::COMPILE_STAGE_PARSED;
gc_collect_cycles(); gc_collect_cycles();
$this->_appendText(substr($this->_src, $end ? $end + 1 : 0)); // append tail of the template $this->_appendText(substr($this->_src, $end ? $end + 1 : 0)); // append tail of the template
@@ -283,10 +294,16 @@ class Template extends Render
call_user_func_array($cb, array($this, &$this->_body)); call_user_func_array($cb, array($this, &$this->_body));
} }
} }
$this->_compile_stage = self::COMPILE_STAGE_PROCESSED;
$this->addDepend($this); // for 'verify' performance $this->addDepend($this); // for 'verify' performance
foreach ($this->_fenom->getPostFilters() as $filter) { foreach ($this->_fenom->getPostFilters() as $filter) {
$this->_body = call_user_func($filter, $this, $this->_body); $this->_body = call_user_func($filter, $this, $this->_body);
} }
$this->_compile_stage = self::COMPILE_STAGE_POST_FILTERED;
}
public function isStageDone($stage_no) {
return $this->_compile_stage >= $stage_no;
} }
/** /**
@@ -376,7 +393,8 @@ class Template extends Render
/** /**
* @param $tag_name * @param $tag_name
*/ */
public function ignore($tag_name) { public function ignore($tag_name)
{
$this->_ignore = $tag_name; $this->_ignore = $tag_name;
} }
@@ -519,7 +537,7 @@ class Template extends Render
*/ */
public function extend($tpl) public function extend($tpl)
{ {
if (!$this->_body) { if (!$this->isStageDone(self::COMPILE_STAGE_PARSED)) {
$this->compile(); $this->compile();
} }
$parent = $this->_fenom->getRawTemplate()->load($tpl, false); $parent = $this->_fenom->getRawTemplate()->load($tpl, false);
@@ -638,10 +656,12 @@ class Template extends Render
} }
} }
if ($tags = $this->_fenom->getTagOwners($action)) { // unknown template tag if ($tags = $this->_fenom->getTagOwners($action)) { // unknown template tag
throw new TokenizeException("Unexpected tag '$action' (this tag can be used with '" . implode( throw new TokenizeException(
"Unexpected tag '$action' (this tag can be used with '" . implode(
"', '", "', '",
$tags $tags
) . "')"); ) . "')"
);
} else { } else {
throw new TokenizeException("Unexpected tag '$action'"); throw new TokenizeException("Unexpected tag '$action'");
} }
@@ -907,7 +927,8 @@ class Template extends Render
* @param string $code start point (it is $var) * @param string $code start point (it is $var)
* @return string * @return string
*/ */
public function parseChain(Tokenizer $tokens, $code) { public function parseChain(Tokenizer $tokens, $code)
{
do { do {
if ($tokens->is('(')) { if ($tokens->is('(')) {
$code .= $this->parseArgs($tokens); $code .= $this->parseArgs($tokens);
@@ -1010,7 +1031,14 @@ class Template extends Render
return 'call_user_func($tpl->getStorage()->getAccessor(' . var_export($accessor, true) . return 'call_user_func($tpl->getStorage()->getAccessor(' . var_export($accessor, true) .
', "callback"), ' . var_export($accessor, true) . ', $tpl, $var)'; ', "callback"), ' . var_export($accessor, true) . ', $tpl, $var)';
} else { } else {
return call_user_func_array($parser['parser'], array($parser['accessor'], $tokens->next(), $this, &$is_var)); return call_user_func_array(
$parser['parser'], array(
$parser['accessor'],
$tokens->next(),
$this,
&$is_var
)
);
} }
} else { } else {
return call_user_func_array($parser, array($tokens->next(), $this, &$is_var)); return call_user_func_array($parser, array($tokens->next(), $this, &$is_var));

View File

@@ -10,7 +10,3 @@ require_once __DIR__ . "/TestCase.php";
require_once __DIR__ . "/tools.php"; require_once __DIR__ . "/tools.php";
ini_set('date.timezone', 'Europe/Moscow'); ini_set('date.timezone', 'Europe/Moscow');
if(PHP_VERSION_ID > 50400) {
function php_gte_54() {}
}

View File

@@ -321,7 +321,7 @@ class FenomTest extends \Fenom\TestCase
/** /**
* @requires function php_gte_54 * @requires PHP 5.4
* @group pipe * @group pipe
*/ */
public function testPipe() public function testPipe()