diff --git a/src/Neuron/Core/Template.php b/src/Neuron/Core/Template.php index 8ea5aee..bf1890f 100755 --- a/src/Neuron/Core/Template.php +++ b/src/Neuron/Core/Template.php @@ -311,7 +311,14 @@ public function parse ($template = null, $text = null) } } - include $ctlbtmpltfiles[0]; + try { + include $ctlbtmpltfiles[0]; + } catch (\Throwable $ctlbtmplterror) { + // Close our buffer before rethrowing, or it stays open and + // swallows everything the caller outputs afterwards. + ob_end_clean (); + throw $ctlbtmplterror; + } $val = ob_get_contents(); @@ -384,10 +391,15 @@ private function combine ($template, $parameters = []) ${$k} = $v; } - if ($ctlbtmpltfiles = $this->getFilenames($template, true)) { - foreach ($ctlbtmpltfiles as $ctlbtmpltfile) { - include $ctlbtmpltfile; + try { + if ($ctlbtmpltfiles = $this->getFilenames($template, true)) { + foreach ($ctlbtmpltfiles as $ctlbtmpltfile) { + include $ctlbtmpltfile; + } } + } catch (\Throwable $ctlbtmplterror) { + ob_end_clean(); + throw $ctlbtmplterror; } $val = ob_get_contents(); @@ -418,10 +430,15 @@ private function template ($template, $parameters = []) ${$k} = $v; } - if ($ctlbtmpltfiles = $this->getFilenames($template)) { - foreach ($ctlbtmpltfiles as $ctlbtmpltfile) { - include $ctlbtmpltfile; + try { + if ($ctlbtmpltfiles = $this->getFilenames($template)) { + foreach ($ctlbtmpltfiles as $ctlbtmpltfile) { + include $ctlbtmpltfile; + } } + } catch (\Throwable $ctlbtmplterror) { + ob_end_clean(); + throw $ctlbtmplterror; } $val = ob_get_contents(); diff --git a/tests/TemplateOutputBufferTest.php b/tests/TemplateOutputBufferTest.php new file mode 100644 index 0000000..a0c1cca --- /dev/null +++ b/tests/TemplateOutputBufferTest.php @@ -0,0 +1,56 @@ + [ 'buffer/throws.phpt' ], + 'template() inside a template' => [ 'buffer/viaTemplate.phpt' ], + 'combine() inside a template' => [ 'buffer/viaCombine.phpt' ], + ]; + } + + /** + * @dataProvider throwingTemplates + */ + public function testThrowingTemplateClosesItsBuffers ($name) + { + $level = ob_get_level (); + + try { + (new Template ($name))->parse (); + $this->fail ('Expected the template exception to propagate'); + } catch (\RuntimeException $e) { + $this->assertSame ('template failed', $e->getMessage ()); + } + + $this->assertSame ($level, ob_get_level ()); + } + + public function testRenderingStillReturnsTheOutput () + { + $level = ob_get_level (); + + $template = new Template ('buffer/fine.phpt'); + $template->set ('name', 'world'); + + $this->assertSame ('hello world', trim ($template->parse ())); + $this->assertSame ($level, ob_get_level ()); + } +} diff --git a/tests/templates/buffer/fine.phpt b/tests/templates/buffer/fine.phpt new file mode 100644 index 0000000..eb49be2 --- /dev/null +++ b/tests/templates/buffer/fine.phpt @@ -0,0 +1 @@ +hello diff --git a/tests/templates/buffer/throws.phpt b/tests/templates/buffer/throws.phpt new file mode 100644 index 0000000..4dd3968 --- /dev/null +++ b/tests/templates/buffer/throws.phpt @@ -0,0 +1 @@ +partial output diff --git a/tests/templates/buffer/viaCombine.phpt b/tests/templates/buffer/viaCombine.phpt new file mode 100644 index 0000000..d6f94e0 --- /dev/null +++ b/tests/templates/buffer/viaCombine.phpt @@ -0,0 +1 @@ +outercombine('buffer/throws.phpt'); ?> diff --git a/tests/templates/buffer/viaTemplate.phpt b/tests/templates/buffer/viaTemplate.phpt new file mode 100644 index 0000000..b4b914d --- /dev/null +++ b/tests/templates/buffer/viaTemplate.phpt @@ -0,0 +1 @@ +outertemplate('buffer/throws.phpt'); ?>