diff --git a/src/ORM/BehaviorRegistry.php b/src/ORM/BehaviorRegistry.php index e7730ead200..db02e72472c 100644 --- a/src/ORM/BehaviorRegistry.php +++ b/src/ORM/BehaviorRegistry.php @@ -137,7 +137,7 @@ protected function _getMethods(Behavior $instance, $class, $alias) { $methods = array_change_key_case($instance->implementedMethods()); foreach ($finders as $finder => $methodName) { - if (isset($this->_finderMap[$finder])) { + if (isset($this->_finderMap[$finder]) && $this->loaded($this->_finderMap[$finder][0])) { $duplicate = $this->_finderMap[$finder]; $error = sprintf( '%s contains duplicate finder "%s" which is already provided by "%s"', @@ -151,7 +151,7 @@ protected function _getMethods(Behavior $instance, $class, $alias) { } foreach ($methods as $method => $methodName) { - if (isset($this->_methodMap[$method])) { + if (isset($this->_methodMap[$method]) && $this->loaded($this->_methodMap[$method][0])) { $duplicate = $this->_methodMap[$method]; $error = sprintf( '%s contains duplicate method "%s" which is already provided by "%s"', @@ -205,7 +205,7 @@ public function hasFinder($method) { */ public function call($method, array $args = []) { $method = strtolower($method); - if ($this->hasMethod($method)) { + if ($this->hasMethod($method) && $this->loaded($this->_methodMap[$method][0])) { list($behavior, $callMethod) = $this->_methodMap[$method]; return call_user_func_array([$this->_loaded[$behavior], $callMethod], $args); } @@ -224,7 +224,7 @@ public function call($method, array $args = []) { public function callFinder($type, array $args = []) { $type = strtolower($type); - if ($this->hasFinder($type)) { + if ($this->hasFinder($type) && $this->loaded($this->_finderMap[$type][0])) { list($behavior, $callMethod) = $this->_finderMap[$type]; return call_user_func_array([$this->_loaded[$behavior], $callMethod], $args); } diff --git a/tests/TestCase/ORM/BehaviorRegistryTest.php b/tests/TestCase/ORM/BehaviorRegistryTest.php index be6c7f257eb..e5b5d361feb 100644 --- a/tests/TestCase/ORM/BehaviorRegistryTest.php +++ b/tests/TestCase/ORM/BehaviorRegistryTest.php @@ -243,4 +243,46 @@ public function testCallFinderError() { $this->Behaviors->callFinder('nope'); } +/** + * Test errors on unloaded behavior methods. + * + * @expectedException \Cake\Error\Exception + * @expectedExceptionMessage Cannot call "slugify" it does not belong to any attached behavior. + */ + public function testUnloadBehaviorThenCall() { + $this->Behaviors->load('Sluggable'); + $this->Behaviors->unload('Sluggable'); + + $this->Behaviors->call('slugify'); + } + +/** + * Test errors on unloaded behavior finders. + * + * @expectedException \Cake\Error\Exception + * @expectedExceptionMessage Cannot call finder "noslug" it does not belong to any attached behavior. + */ + public function testUnloadBehaviorThenCallFinder() { + $this->Behaviors->load('Sluggable'); + $this->Behaviors->unload('Sluggable'); + + $this->Behaviors->callFinder('noSlug'); + } + +/** + * Test that unloading then reloading a behavior does not throw any errors. + * + * @return void + */ + public function testUnloadBehaviorThenReload() { + $this->Behaviors->load('Sluggable'); + $this->Behaviors->unload('Sluggable'); + + $this->assertEmpty($this->Behaviors->loaded()); + + $this->Behaviors->load('Sluggable'); + + $this->assertEquals(['Sluggable'], $this->Behaviors->loaded()); + } + }