From 19975a2cf6e3bf07e390263efd5fa6cce7dbd620 Mon Sep 17 00:00:00 2001 From: nate Date: Wed, 15 Oct 2008 13:07:46 +0000 Subject: [PATCH] Fixing issue where startup() / shutdown() etc. were being called on components not directly attached to the controller. Only initialize() should be called on sub-components. git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7745 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/controller/component.php | 71 +++++++++++-------- .../cases/libs/controller/component.test.php | 50 ++++++++++--- 2 files changed, 84 insertions(+), 37 deletions(-) diff --git a/cake/libs/controller/component.php b/cake/libs/controller/component.php index 2b3caf404..a3ecac926 100644 --- a/cake/libs/controller/component.php +++ b/cake/libs/controller/component.php @@ -41,9 +41,17 @@ class Component extends Object { * All loaded components * * @var object - * @access private + * @access protected */ - var $__loaded = array(); + var $_loaded = array(); +/** + * List of components attached directly to the controller, which callbacks + * should be executed on. + * + * @var object + * @access protected + */ + var $_primary = array(); /** * Settings for loaded components. * @@ -59,16 +67,19 @@ class Component extends Object { * @access public */ function init(&$controller) { - if ($controller->components !== false && is_array($controller->components)) { - $this->__controllerVars = array( - 'plugin' => $controller->plugin, 'name' => $controller->name, 'base' => $controller->base - ); - - if (!in_array('Session', $controller->components)) { - array_unshift($controller->components, 'Session'); - } - $this->_loadComponents($controller); + if (!is_array($controller->components)) { + return; } + $this->__controllerVars = array( + 'plugin' => $controller->plugin, 'name' => $controller->name, + 'base' => $controller->base + ); + + if (!in_array('Session', $controller->components)) { + array_unshift($controller->components, 'Session'); + } + $this->_primary = array_keys(Set::normalize($controller->components)); + $this->_loadComponents($controller); } /** * Called before the Controller::beforeFilter() @@ -78,8 +89,9 @@ class Component extends Object { * @access public */ function initialize(&$controller) { - foreach (array_keys($this->__loaded) as $name) { - $component =& $this->__loaded[$name]; + foreach (array_keys($this->_loaded) as $name) { + $component =& $this->_loaded[$name]; + if (method_exists($component,'initialize') && $component->enabled === true) { $settings = array(); if (isset($this->__settings[$name])) { @@ -97,24 +109,25 @@ class Component extends Object { * @access public */ function startup(&$controller) { - foreach (array_keys($this->__loaded) as $name) { - $component =& $this->__loaded[$name]; - if (method_exists($component,'startup') && $component->enabled === true) { + foreach ($this->_primary as $name) { + $component =& $this->_loaded[$name]; + if ($component->enabled === true && method_exists($component, 'startup')) { $component->startup($controller); } } } /** - * Called after the Controller::beforeRender(), after the view class is loaded, and before the Controller::render() + * Called after the Controller::beforeRender(), after the view class is loaded, and before the + * Controller::render() * * @param object $controller Controller with components to beforeRender * @return void * @access public */ function beforeRender(&$controller) { - foreach (array_keys($this->__loaded) as $name) { - $component =& $this->__loaded[$name]; - if (method_exists($component,'beforeRender') && $component->enabled === true) { + foreach ($this->_primary as $name) { + $component =& $this->_loaded[$name]; + if ($component->enabled === true && method_exists($component,'beforeRender')) { $component->beforeRender($controller); } } @@ -128,9 +141,11 @@ class Component extends Object { */ function beforeRedirect(&$controller, $url, $status = null, $exit = true) { $response = array(); - foreach (array_keys($this->__loaded) as $name) { - $component =& $this->__loaded[$name]; - if (method_exists($component,'beforeRedirect') && $component->enabled === true) { + + foreach ($this->_primary as $name) { + $component =& $this->_loaded[$name]; + + if ($component->enabled === true && method_exists($component, 'beforeRedirect')) { $resp = $component->beforeRedirect($controller, $url, $status, $exit); if ($resp === false) { return false; @@ -148,8 +163,8 @@ class Component extends Object { * @access public */ function shutdown(&$controller) { - foreach (array_keys($this->__loaded) as $name) { - $component =& $this->__loaded[$name]; + foreach ($this->_primary as $name) { + $component =& $this->_loaded[$name]; if (method_exists($component,'shutdown') && $component->enabled === true) { $component->shutdown($controller); } @@ -208,8 +223,8 @@ class Component extends Object { } } - if (isset($this->__loaded[$component])) { - $object->{$component} =& $this->__loaded[$component]; + if (isset($this->_loaded[$component])) { + $object->{$component} =& $this->_loaded[$component]; if (!empty($config) && isset($this->__settings[$component])) { $this->__settings[$component] = array_merge($this->__settings[$component], $config); @@ -223,7 +238,7 @@ class Component extends Object { $object->{$component} =& new $componentCn(); } $object->{$component}->enabled = true; - $this->__loaded[$component] =& $object->{$component}; + $this->_loaded[$component] =& $object->{$component}; if (!empty($config)) { $this->__settings[$component] = $config; } diff --git a/cake/tests/cases/libs/controller/component.test.php b/cake/tests/cases/libs/controller/component.test.php index 9808c838d..f995da6e4 100644 --- a/cake/tests/cases/libs/controller/component.test.php +++ b/cake/tests/cases/libs/controller/component.test.php @@ -186,6 +186,10 @@ class OrangeComponent extends Object { $this->Banana->testField = 'OrangeField'; $this->settings = $settings; } + + function startup(&$controller) { + $controller->foo = 'pass'; + } } /** * BananaComponent class @@ -201,6 +205,10 @@ class BananaComponent extends Object { * @access public */ var $testField = 'BananaField'; + + function startup(&$controller) { + $controller->bar = 'fail'; + } } /** * MutuallyReferencingOneComponent class @@ -234,7 +242,9 @@ class ComponentTest extends CakeTestCase { * @return void */ function setUp() { - Configure::write('pluginPaths', array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS)); + Configure::write('pluginPaths', array( + TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS + )); } /** * testLoadComponents method @@ -260,7 +270,10 @@ class ComponentTest extends CakeTestCase { $this->assertTrue(is_a($Controller->RequestHandler, 'RequestHandlerComponent')); $this->assertTrue(is_a($Controller->TestPluginComponent, 'TestPluginComponentComponent')); - $this->assertTrue(is_a($Controller->TestPluginComponent->TestPluginOtherComponent, 'TestPluginOtherComponentComponent')); + $this->assertTrue(is_a( + $Controller->TestPluginComponent->TestPluginOtherComponent, + 'TestPluginOtherComponentComponent' + )); $this->assertFalse(isset($Controller->TestPluginOtherComponent)); $Controller =& new ComponentTestController(); @@ -299,7 +312,8 @@ class ComponentTest extends CakeTestCase { $this->assertTrue(is_a($Controller->Apple->Orange->Banana, 'BananaComponent')); } /** - * test component::startup and running all built components startup() + * Tests Component::startup() and only running callbacks for components directly attached to + * the controller. * * @return void */ @@ -313,6 +327,10 @@ class ComponentTest extends CakeTestCase { $this->assertTrue(is_a($Controller->Apple, 'AppleComponent')); $this->assertEqual($Controller->Apple->testName, 'ComponentTest'); + + $expected = !(defined('APP_CONTROLLER_EXISTS') && APP_CONTROLLER_EXISTS); + $this->assertEqual(isset($Controller->foo), $expected); + $this->assertFalse(isset($Controller->bar)); } /** * test a component being used more than once. @@ -353,17 +371,21 @@ class ComponentTest extends CakeTestCase { //Settings are merged from app controller and current controller. $Controller =& new ComponentTestController(); - $Controller->components = array('ParamTest' => array('test' => 'value'), 'Orange' => array('ripeness' => 'perfect')); + $Controller->components = array( + 'ParamTest' => array('test' => 'value'), + 'Orange' => array('ripeness' => 'perfect') + ); $Controller->constructClasses(); $Controller->Component->initialize($Controller); - $this->assertEqual($Controller->Orange->settings, array('colour' => 'blood orange', 'ripeness' => 'perfect')); + $expected = array('colour' => 'blood orange', 'ripeness' => 'perfect'); + $this->assertEqual($Controller->Orange->settings, $expected); $this->assertEqual($Controller->ParamTest->test, 'value'); } /** * Test mutually referencing components. * - * + * @return void */ function testMutuallyReferencingComponents() { $Controller =& new ComponentTestController(); @@ -371,9 +393,19 @@ class ComponentTest extends CakeTestCase { $Controller->constructClasses(); $Controller->Component->initialize($Controller); - $this->assertTrue(is_a($Controller->MutuallyReferencingOne, 'MutuallyReferencingOneComponent')); - $this->assertTrue(is_a($Controller->MutuallyReferencingOne->MutuallyReferencingTwo, 'MutuallyReferencingTwoComponent')); - $this->assertTrue(is_a($Controller->MutuallyReferencingOne->MutuallyReferencingTwo->MutuallyReferencingOne, 'MutuallyReferencingOneComponent')); + $this->assertTrue(is_a( + $Controller->MutuallyReferencingOne, + 'MutuallyReferencingOneComponent' + )); + $this->assertTrue(is_a( + $Controller->MutuallyReferencingOne->MutuallyReferencingTwo, + 'MutuallyReferencingTwoComponent' + )); + $this->assertTrue(is_a( + $Controller->MutuallyReferencingOne->MutuallyReferencingTwo->MutuallyReferencingOne, + 'MutuallyReferencingOneComponent' + )); } } + ?> \ No newline at end of file