From ecbe337052e27f1c97b2c12561d9f32c92da596d Mon Sep 17 00:00:00 2001 From: AD7six Date: Wed, 25 Jan 2012 12:43:55 +0100 Subject: [PATCH] Make extending a missing element throw an exception A layout extending a missing layout throws a missing-layout exception A view extendinga missing view throws a missing-view exception Now, an element extending a missing element throws a logic exception in addition "absolute" paths can be used such that (using elements as an example) $this->extend('foo') - extends View/Elements/foo.ctp $this->extend('/foo') - extends View/foo.ctp Closes #2504 --- lib/Cake/Test/Case/View/ViewTest.php | 12 +++++- .../Elements/extended_missing_element.ctp | 2 + .../View/Posts/extend_missing_element.ctp | 1 + lib/Cake/View/View.php | 38 ++++++++++++------- 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp create mode 100644 lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index 7fe844c2e..eaef9e5f2 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -1392,7 +1392,6 @@ TEXT; $this->View->render('extend_loop'); } - /** * Test extend() in an element and a view. * @@ -1411,6 +1410,17 @@ TEXT; $this->assertEquals($expected, $content); } +/** + * Extending an element which doesn't exist should throw a missing view exception + * + * @expectedException LogicException + * @return void + */ + public function testExtendMissingElement() { + $this->View->layout = false; + $this->View->render('extend_missing_element'); + } + /** * Test that setting arbitrary properties still works. * diff --git a/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp b/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp new file mode 100644 index 000000000..dd106ce13 --- /dev/null +++ b/lib/Cake/Test/test_app/View/Elements/extended_missing_element.ctp @@ -0,0 +1,2 @@ +extend('noneexistent_parent_element'); ?> +Element content. diff --git a/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp b/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp new file mode 100644 index 000000000..7d5a6aca2 --- /dev/null +++ b/lib/Cake/Test/test_app/View/Posts/extend_missing_element.ctp @@ -0,0 +1 @@ +element('extended_missing_element'); ?> diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 4a383365b..4793f6311 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -662,24 +662,34 @@ class View extends Object { * @param string $name The view or element to 'extend' the current one with. * @return void * @throws LogicException when you extend a view with itself or make extend loops. + * @throws LogicException when you extend an element which doesn't exist */ public function extend($name) { - switch ($this->_currentType) { - case self::TYPE_VIEW: - $parent = $this->_getViewFileName($name); - break; - case self::TYPE_ELEMENT: - $parent = $this->_getElementFileName($name); - break; - case self::TYPE_LAYOUT: - $parent = $this->_getLayoutFileName($name); - break; - + if ($name[0] === '/' || $this->_currentType === self::TYPE_VIEW) { + $parent = $this->_getViewFileName($name); + } else { + switch ($this->_currentType) { + case self::TYPE_ELEMENT: + $parent = $this->_getElementFileName($name); + if (!$parent) { + list($plugin, $name) = $this->_pluginSplit($name); + $paths = $this->_paths($plugin); + $defaultPath = $paths[0] . 'Elements' . DS; + throw new LogicException(__d( + 'cake_dev', + 'You cannot extend an element which does not exist (%s).', + $defaultPath . $name . $this->ext + )); + } + break; + case self::TYPE_LAYOUT: + $parent = $this->_getLayoutFileName($name); + break; + default: + $parent = $this->_getViewFileName($name); + } } - if (!$parent) { - throw new LogicException(__d('cake_dev', 'The parent %s you specified doesn\'t exist.', $this->_currentType)); - } if ($parent == $this->_current) { throw new LogicException(__d('cake_dev', 'You cannot have views extend themselves.')); }