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);
}