From f009e96a6965f68fc848ff7855c7a6aa08197c55 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 27 Mar 2012 23:36:16 -0430 Subject: [PATCH 1/6] Adding test for lazy loading helpers using the collection --- .../Test/Case/View/HelperCollectionTest.php | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Test/Case/View/HelperCollectionTest.php b/lib/Cake/Test/Case/View/HelperCollectionTest.php index 742d5d3e3..5d9021341 100644 --- a/lib/Cake/Test/Case/View/HelperCollectionTest.php +++ b/lib/Cake/Test/Case/View/HelperCollectionTest.php @@ -67,6 +67,25 @@ class HelperCollectionTest extends CakeTestCase { $this->assertTrue($this->Helpers->enabled('Html')); } +/** + * test lazy loading of helpers + * + * @return void + */ + public function testLazyLoad() { + $result = $this->Helpers->Html; + $this->assertInstanceOf('HtmlHelper', $result); + + $result = $this->Helpers->Form; + $this->assertInstanceOf('FormHelper', $result); + + App::build(array('Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS))); + $this->View->plugin = 'TestPlugin'; + CakePlugin::load(array('TestPlugin')); + $result = $this->Helpers->OtherHelper; + $this->assertInstanceOf('OtherHelperHelper', $result); + } + /** * Tests loading as an alias * @@ -149,8 +168,8 @@ class HelperCollectionTest extends CakeTestCase { $this->assertEquals(array('Form', 'Html'), $result, 'loaded helpers is wrong'); $this->Helpers->unload('Html'); - $this->assertFalse(isset($this->Helpers->Html)); - $this->assertTrue(isset($this->Helpers->Form)); + $this->assertNotContains('Html', $this->Helpers->attached()); + $this->assertContains('Form', $this->Helpers->attached()); $result = $this->Helpers->attached(); $this->assertEquals(array('Form'), $result, 'loaded helpers is wrong'); From c270e7ffda72c7ec3e3474abf413236d30c4cd05 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 27 Mar 2012 23:43:41 -0430 Subject: [PATCH 2/6] Adding test for lazy loading helpers in views --- lib/Cake/Test/Case/View/ViewTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/Cake/Test/Case/View/ViewTest.php b/lib/Cake/Test/Case/View/ViewTest.php index 9609d1cb5..8c318b36b 100644 --- a/lib/Cake/Test/Case/View/ViewTest.php +++ b/lib/Cake/Test/Case/View/ViewTest.php @@ -797,6 +797,20 @@ class ViewTest extends CakeTestCase { $this->assertInstanceOf('FormHelper', $View->Form, 'Object type is wrong.'); } + +/** + * test lazy loading helpers + * + * @return void + */ + public function testLazyLoadHelpers() { + $View = new View($this->PostsController); + + $View->helpers = array(); + $this->assertInstanceOf('HtmlHelper', $View->Html, 'Object type is wrong.'); + $this->assertInstanceOf('FormHelper', $View->Form, 'Object type is wrong.'); + } + /** * test the correct triggering of helper callbacks * From f688d5777e421e710246176285432ca003bae910 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 27 Mar 2012 23:44:23 -0430 Subject: [PATCH 3/6] Implementing helper lazy loading --- lib/Cake/View/HelperCollection.php | 51 ++++++++++++++++++++++++++++++ lib/Cake/View/View.php | 10 +++--- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/lib/Cake/View/HelperCollection.php b/lib/Cake/View/HelperCollection.php index e726f3d3a..e5b465346 100644 --- a/lib/Cake/View/HelperCollection.php +++ b/lib/Cake/View/HelperCollection.php @@ -43,6 +43,57 @@ class HelperCollection extends ObjectCollection implements CakeEventListener { $this->_View = $view; } +/** + * Tries to lazy load a helper based on its name, if it cannot be found + * in the application folder, then it tries looking under the current plugin + * if any + * + * @param string $helper The helper name to be loaded + * @return boolean wheter the helper could be loaded or not + **/ + public function __isset($helper) { + if (parent::__isset($helper)) { + return true; + } + if (!$this->_loadSandbox($helper)) { + return $this->_View->plugin && $this->_loadSandbox($this->_View->plugin . '.' . $helper); + } + return true; + } + +/** + * Provide public read access to the loaded objects + * + * @param string $name Name of property to read + * @return mixed + */ + public function __get($name) { + if ($result = parent::__get($name)) { + return $result; + } + if ($this->__isset($name)) { + return $this->_loaded[$name]; + } + return null; + } + +/** + * Auxiliary function used for lazy loading helpers + * catches any MissingHelperException and converts it into + * a boolean return + * + * @param string $helper The helper name to be loaded + * @return boolean wheter the helper could be loaded or not + **/ + protected function _loadSandbox($helper) { + try { + $this->load($helper); + } catch (MissingHelperException $e) { + return false; + } + return true; + } + /** * Loads/constructs a helper. Will return the instance in the registry if it already exists. * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you diff --git a/lib/Cake/View/View.php b/lib/Cake/View/View.php index 9e0269ae8..93e756746 100644 --- a/lib/Cake/View/View.php +++ b/lib/Cake/View/View.php @@ -785,9 +785,6 @@ class View extends Object { * @return mixed */ public function __get($name) { - if (isset($this->Helpers->{$name})) { - return $this->Helpers->{$name}; - } switch ($name) { case 'base': case 'here': @@ -800,9 +797,12 @@ class View extends Object { return $this->request; case 'output': return $this->Blocks->get('content'); - default: - return $this->{$name}; } + if (isset($this->Helpers->{$name})) { + $this->{$name} = $this->Helpers->{$name}; + return $this->Helpers->{$name}; + } + return $this->{$name}; } /** From f349c9e34cd16642a00377095bc30bd8888e48a1 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 27 Mar 2012 23:45:01 -0430 Subject: [PATCH 4/6] Removing hardcoded helpers from Controller and PagesController class since they are now lazy loaded --- app/Controller/PagesController.php | 6 ------ lib/Cake/Controller/Controller.php | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/app/Controller/PagesController.php b/app/Controller/PagesController.php index 83fd907bc..4759719ae 100644 --- a/app/Controller/PagesController.php +++ b/app/Controller/PagesController.php @@ -38,12 +38,6 @@ class PagesController extends AppController { */ public $name = 'Pages'; -/** - * Default helper - * - * @var array - */ - public $helpers = array('Html', 'Session'); /** * This controller does not use a model diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php index bef8bfcc9..24df664ea 100644 --- a/lib/Cake/Controller/Controller.php +++ b/lib/Cake/Controller/Controller.php @@ -95,7 +95,7 @@ class Controller extends Object implements CakeEventListener { * @var mixed A single name as a string or a list of names as an array. * @link http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses */ - public $helpers = array('Session', 'Html', 'Form'); + public $helpers = array(); /** * An instance of a CakeRequest object that contains information about the current request. From 5a41024cf36dde3592c4a53dbcf0364ec93c3025 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 27 Mar 2012 23:53:22 -0430 Subject: [PATCH 5/6] Removing hardcoded helper from PagesController in skel --- .../Console/Templates/skel/Controller/PagesController.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/Cake/Console/Templates/skel/Controller/PagesController.php b/lib/Cake/Console/Templates/skel/Controller/PagesController.php index b291eb08e..73649547f 100644 --- a/lib/Cake/Console/Templates/skel/Controller/PagesController.php +++ b/lib/Cake/Console/Templates/skel/Controller/PagesController.php @@ -29,13 +29,6 @@ */ class PagesController extends AppController { -/** - * Default helper - * - * @var array - */ - public $helpers = array('Html'); - /** * This controller does not use a model * From 18b843467fbf2b24b7a842ed9a3210db0cfa88ca Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Wed, 28 Mar 2012 22:12:46 -0430 Subject: [PATCH 6/6] Making lazy loader throw an exception for missing helpers --- .../Test/Case/View/HelperCollectionTest.php | 10 ++++++ lib/Cake/View/HelperCollection.php | 32 ++++++++----------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/Cake/Test/Case/View/HelperCollectionTest.php b/lib/Cake/Test/Case/View/HelperCollectionTest.php index 5d9021341..a7f222d50 100644 --- a/lib/Cake/Test/Case/View/HelperCollectionTest.php +++ b/lib/Cake/Test/Case/View/HelperCollectionTest.php @@ -86,6 +86,16 @@ class HelperCollectionTest extends CakeTestCase { $this->assertInstanceOf('OtherHelperHelper', $result); } +/** + * test lazy loading of helpers + * + * @expectedException MissingHelperException + * @return void + */ + public function testLazyLoadException() { + $result = $this->Helpers->NotAHelper; + } + /** * Tests loading as an alias * diff --git a/lib/Cake/View/HelperCollection.php b/lib/Cake/View/HelperCollection.php index e5b465346..7fda46762 100644 --- a/lib/Cake/View/HelperCollection.php +++ b/lib/Cake/View/HelperCollection.php @@ -55,9 +55,20 @@ class HelperCollection extends ObjectCollection implements CakeEventListener { if (parent::__isset($helper)) { return true; } - if (!$this->_loadSandbox($helper)) { - return $this->_View->plugin && $this->_loadSandbox($this->_View->plugin . '.' . $helper); + + try { + $this->load($helper); + } catch (MissingHelperException $exception) { + if ($this->_View->plugin) { + $this->load($this->_View->plugin . '.' . $helper); + return true; + } } + + if (!empty($exception)) { + throw $exception; + } + return true; } @@ -77,23 +88,6 @@ class HelperCollection extends ObjectCollection implements CakeEventListener { return null; } -/** - * Auxiliary function used for lazy loading helpers - * catches any MissingHelperException and converts it into - * a boolean return - * - * @param string $helper The helper name to be loaded - * @return boolean wheter the helper could be loaded or not - **/ - protected function _loadSandbox($helper) { - try { - $this->load($helper); - } catch (MissingHelperException $e) { - return false; - } - return true; - } - /** * Loads/constructs a helper. Will return the instance in the registry if it already exists. * By setting `$enable` to false you can disable callbacks for a helper. Alternatively you