diff --git a/sandbox/fenom.php b/sandbox/fenom.php index 6b8ccf6..e4709c9 100644 --- a/sandbox/fenom.php +++ b/sandbox/fenom.php @@ -5,73 +5,12 @@ require_once __DIR__.'/../tests/tools.php'; \Fenom::registerAutoload(); -$vars = [ - [ - "id" => 1, - "name" => "Блаблабла", - "hidden_url" => "/" - ], - [ - "id" => 2, - "name" => "Каталог", - "hidden_url" => "/catalog" - ], - [ - "id" => 3, - "name" => "Сыромолочная группа", - "hidden_url" => "/catalog/cat_1.html" - ], - [ - "id" => 4, - "name" => "Сыры", - "hidden_url" => "/catalog/cat_2.html" - ], -]; - $fenom = Fenom::factory(__DIR__.'/templates', __DIR__.'/compiled'); -$fenom->setOptions(Fenom::AUTO_RELOAD | Fenom::FORCE_VERIFY); +$fenom->setOptions(Fenom::AUTO_RELOAD | Fenom::FORCE_VERIFY | Fenom::FORCE_INCLUDE); //var_dump($fenom->compile("nested.tpl", [])->getTemplateCode()); //exit; -var_dump($fenom->fetch('bug249/bread.tpl', ["arr" => $vars])); +var_dump($fenom->compile('bug241/recursive.tpl', false)->getBody()); //var_dump($fenom->compile('bug249/bread.tpl', false)->getBody()); //var_dump($fenom->compile("bug158/main.tpl", [])->getTemplateCode()); //var_dump($fenom->display("bug158/main.tpl", [])); // $fenom->getTemplate("problem.tpl"); - -/* - * - * Array -( - [0] => Array - ( - [id] => 1 - [name] => Блаблабла - [hidden_url] => / - ) - [1] => Array - ( - [id] => 2 - [name] => Каталог - [hidden_url] => /catalog/ - ) - [2] => Array - ( - [orig_id] => 1 - [hidden_url] => /catalog/cat_1.html - [name] => Сыромолочная группа - ) - [3] => Array - ( - [orig_id] => 2 - [hidden_url] => /catalog/cat_2.html - [name] => Сыры - ) - [4] => Array - ( - [orig_id] => 6 - [hidden_url] => /catalog/cat_6.html - [name] => Сыр плавленый - ) -) - - */ \ No newline at end of file diff --git a/sandbox/templates/bug241/recursive.tpl b/sandbox/templates/bug241/recursive.tpl new file mode 100644 index 0000000..7b72475 --- /dev/null +++ b/sandbox/templates/bug241/recursive.tpl @@ -0,0 +1,3 @@ +{if $n < 10} + {include 'bug241/recursive.tpl' n=$n - 1} +{/if} \ No newline at end of file diff --git a/src/Fenom.php b/src/Fenom.php index c117068..d779731 100644 --- a/src/Fenom.php +++ b/src/Fenom.php @@ -944,9 +944,9 @@ class Fenom * * @return Fenom\Template */ - public function getRawTemplate() + public function getRawTemplate(Template $parent = null) { - return new Template($this, $this->_options); + return new Template($this, $this->_options, $parent); } /** diff --git a/src/Fenom/Compiler.php b/src/Fenom/Compiler.php index f72e52b..2a8dec3 100644 --- a/src/Fenom/Compiler.php +++ b/src/Fenom/Compiler.php @@ -38,13 +38,24 @@ class Compiler $p = $tpl->parseParams($tokens); if ($name) { if ($tpl->getStorage()->getOptions() & \Fenom::FORCE_INCLUDE) { - $inc = $tpl->getStorage()->compile($name, false); - $tpl->addDepend($inc); - $var = $tpl->tmpVar(); - if ($p) { - return $var . ' = $var; $var = ' . self::toArray($p) . ' + $var; ?>' . $inc->getBody() . '' . $inc->getBody() . 'parent) { + if($_t->parent->getName() == $name) { // recursion detected + $recursion = true; + } + $_t = $_t->parent; + } + if(!$recursion) { + $inc = $tpl->getStorage()->getRawTemplate($tpl); + $inc->load($name, true); + $tpl->addDepend($inc); + $var = $tpl->tmpVar(); + if ($p) { + return $var . ' = $var; $var = ' . self::toArray($p) . ' + $var; ?>' . $inc->getBody() . '' . $inc->getBody() . 'getStorage()->templateExists($name)) { throw new \LogicException("Template $name not found"); diff --git a/src/Fenom/Template.php b/src/Fenom/Template.php index 9a5b449..b6912c7 100644 --- a/src/Fenom/Template.php +++ b/src/Fenom/Template.php @@ -81,6 +81,12 @@ class Template extends Render public $extend_body = false; + /** + * Parent template + * @var Template + */ + public $parent; + /** * Template PHP code * @var string @@ -121,10 +127,11 @@ class Template extends Render /** * @param Fenom $fenom Template storage * @param int $options - * @return \Fenom\Template + * @param Template $parent */ - public function __construct(Fenom $fenom, $options) + public function __construct(Fenom $fenom, $options, Template $parent = null) { + $this->parent = $parent; $this->_fenom = $fenom; $this->_options = $options; $this->_filters = $this->_fenom->getFilters(); diff --git a/tests/TestCase.php b/tests/TestCase.php index c919bda..2299b4d 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -116,6 +116,12 @@ class TestCase extends \PHPUnit_Framework_TestCase return filemtime(FENOM_RESOURCES . '/template/' . $name); } + public function tpls(array $list) { + foreach($list as $name => $tpl) { + $this->tpl($name, $tpl); + } + } + /** * Compile and execute template * diff --git a/tests/cases/Fenom/TemplateTest.php b/tests/cases/Fenom/TemplateTest.php index 061b9b8..a83f4b2 100644 --- a/tests/cases/Fenom/TemplateTest.php +++ b/tests/cases/Fenom/TemplateTest.php @@ -268,48 +268,6 @@ class TemplateTest extends TestCase ); } - public static function providerInclude() - { - $a = array( - "name" => "welcome", - "tpl" => "welcome.tpl", - "fragment" => "come", - "pr_fragment" => "Come", - "pr_name" => "Welcome", - "username" => "Master", - "email" => "dev@null.net" - ); - $result = 'Include Welcome, Master (dev@null.net) template'; - $result2 = 'Include Welcome, Flame (dev@null.net) template'; - $result3 = 'Include Welcome, Master (flame@dev.null) template'; - $result4 = 'Include Welcome, Flame (flame@dev.null) template'; - return array( - array('Include {include "welcome.tpl"} template', $a, $result), - array('Include {include "welcome.tpl"} template', $a, $result, Fenom::FORCE_INCLUDE), - array('Include {include $tpl} template', $a, $result), - array('Include {include "$tpl"} template', $a, $result), - array('Include {include "{$tpl}"} template', $a, $result), - array('Include {include "$name.tpl"} template', $a, $result), - array('Include {include "{$name}.tpl"} template', $a, $result), - array('Include {include "{$pr_name|lower}.tpl"} template', $a, $result), - array('Include {include "wel{$fragment}.tpl"} template', $a, $result), - array('Include {include "wel{$pr_fragment|lower}.tpl"} template', $a, $result), - array('Include {include "welcome.tpl" username="Flame"} template', $a, $result2), - array('Include {include "welcome.tpl" username="Flame"} template', $a, $result2, Fenom::FORCE_INCLUDE), - array('Include {include "welcome.tpl" email="flame@dev.null"} template', $a, $result3), - array( - 'Include {include "welcome.tpl" email="flame@dev.null"} template', - $a, - $result3, - Fenom::FORCE_INCLUDE - ), - array( - 'Include {include "welcome.tpl" username="Flame" email="flame@dev.null"} template', - $a, - $result4 - ), - ); - } public static function providerIncludeInvalid() { @@ -1195,12 +1153,66 @@ class TemplateTest extends TestCase $this->execError($code, $exception, $message, $options); } + + public static function providerInclude() + { + $a = array( + "name" => "welcome", + "tpl" => "welcome.tpl", + "fragment" => "come", + "pr_fragment" => "Come", + "pr_name" => "Welcome", + "username" => "Master", + "email" => "dev@null.net" + ); + + $result = 'Include Welcome, Master (dev@null.net) template'; + $result2 = 'Include Welcome, Flame (dev@null.net) template'; + $result3 = 'Include Welcome, Master (flame@dev.null) template'; + $result4 = 'Include Welcome, Flame (flame@dev.null) template'; + + $recursive_result = 'Include Hello, Master (dev@null.net) template'; + $recursive_result2 = 'Include Hello, Flame (dev@null.net) template'; + return array( + array('Include {include "welcome.tpl"} template', $a, $result), + array('Include {include "welcome.tpl"} template', $a, $result, Fenom::FORCE_INCLUDE), + array('Include {include "recursive.tpl"} template', $a, $recursive_result, Fenom::FORCE_INCLUDE), + array('Include {include $tpl} template', $a, $result), + array('Include {include "$tpl"} template', $a, $result), + array('Include {include "{$tpl}"} template', $a, $result), + array('Include {include "$name.tpl"} template', $a, $result), + array('Include {include "{$name}.tpl"} template', $a, $result), + array('Include {include "{$pr_name|lower}.tpl"} template', $a, $result), + array('Include {include "wel{$fragment}.tpl"} template', $a, $result), + array('Include {include "wel{$pr_fragment|lower}.tpl"} template', $a, $result), + array('Include {include "welcome.tpl" username="Flame"} template', $a, $result2), + array('Include {include "welcome.tpl" username="Flame"} template', $a, $result2, Fenom::FORCE_INCLUDE), + array('Include {include "recursive.tpl" username="Flame"} template', $a, $recursive_result2, Fenom::FORCE_INCLUDE), + array('Include {include "welcome.tpl" email="flame@dev.null"} template', $a, $result3), + array( + 'Include {include "welcome.tpl" email="flame@dev.null"} template', + $a, + $result3, + Fenom::FORCE_INCLUDE + ), + array( + 'Include {include "welcome.tpl" username="Flame" email="flame@dev.null"} template', + $a, + $result4, + ), + ); + } + /** - * @group include + * @group dev * @dataProvider providerInclude */ public function testInclude($code, $vars, $result, $options = 0) { + $this->tpls(array( + 'welcome.tpl' => 'Welcome, {$username} ({$email})', + 'recursive.tpl' => 'Hello, {$username} ({$email}){if false}{include "recursive.tpl"}{/if}' + )); $this->exec($code, $vars, $result, $options); }