diff --git a/src/ORM/Behavior.php b/src/ORM/Behavior.php index 82ba05d7fb7..70d226b85f0 100644 --- a/src/ORM/Behavior.php +++ b/src/ORM/Behavior.php @@ -125,9 +125,49 @@ class Behavior implements EventListener { * @param array $config The config for this behavior. */ public function __construct(Table $table, array $config = []) { + $config = $this->_resolveMethodAliases( + 'implementedFinders', + $this->_defaultConfig, + $config + ); + $config = $this->_resolveMethodAliases( + 'implementedMethods', + $this->_defaultConfig, + $config + ); $this->config($config); } +/** + * Removes aliased methods that would otherwise be duplicated by userland configuration. + * + * @param string $key The key to filter. + * @param array $defaults The default method mappings. + * @param array $config The customized method mappings. + * @return array A de-duped list of config data. + */ + protected function _resolveMethodAliases($key, $defaults, $config) { + if (!isset($defaults[$key], $config[$key])) { + return $config; + } + if (isset($config[$key]) && $config[$key] === []) { + $this->config($key, [], false); + unset($config[$key]); + return $config; + } + + $indexed = array_flip($defaults[$key]); + $indexedCustom = array_flip($config[$key]); + foreach ($indexed as $method => $alias) { + if (!isset($indexedCustom[$method])) { + $indexedCustom[$method] = $alias; + } + } + $this->config($key, array_flip($indexedCustom), false); + unset($config[$key]); + return $config; + } + /** * verifyConfig * diff --git a/tests/TestCase/ORM/BehaviorRegistryTest.php b/tests/TestCase/ORM/BehaviorRegistryTest.php index bea640bb148..79c8d8f4eb0 100644 --- a/tests/TestCase/ORM/BehaviorRegistryTest.php +++ b/tests/TestCase/ORM/BehaviorRegistryTest.php @@ -128,6 +128,51 @@ public function testLoadDuplicateMethodError() { $this->Behaviors->load('Duplicate'); } +/** + * Test load() duplicate method aliasing + * + * @return void + */ + public function testLoadDuplicateMethodAliasing() { + $this->Behaviors->load('Tree'); + $this->Behaviors->load('Duplicate', [ + 'implementedFinders' => [ + 'renamed' => 'findChildren', + ], + 'implementedMethods' => [ + 'renamed' => 'slugify', + ] + ]); + $this->assertTrue($this->Behaviors->hasMethod('renamed')); + } + +/** + * Test load() duplicate finder error + * + * @expectedException \Cake\Error\Exception + * @expectedExceptionMessage TestApp\Model\Behavior\DuplicateBehavior contains duplicate finder "children" + * @return void + */ + public function testLoadDuplicateFinderError() { + $this->Behaviors->load('Tree'); + $this->Behaviors->load('Duplicate'); + } + +/** + * Test load() duplicate finder aliasing + * + * @return void + */ + public function testLoadDuplicateFinderAliasing() { + $this->Behaviors->load('Tree'); + $this->Behaviors->load('Duplicate', [ + 'implementedFinders' => [ + 'renamed' => 'findChildren', + ] + ]); + $this->assertTrue($this->Behaviors->hasFinder('renamed')); + } + /** * test hasMethod() * diff --git a/tests/TestCase/ORM/BehaviorTest.php b/tests/TestCase/ORM/BehaviorTest.php index 4a68ff373da..48b8aefecdc 100644 --- a/tests/TestCase/ORM/BehaviorTest.php +++ b/tests/TestCase/ORM/BehaviorTest.php @@ -34,6 +34,14 @@ public function beforeFind() { * Test Stub. */ class Test2Behavior extends Behavior { + protected $_defaultConfig = [ + 'implementedFinders' => [ + 'foo' => 'findFoo', + ], + 'implementedMethods' => [ + 'doSomething' => 'doSomething', + ] + ]; /** * Test for event bindings. @@ -239,7 +247,7 @@ public function testImplementedFinders() { $table = $this->getMock('Cake\ORM\Table'); $behavior = new Test2Behavior($table); $expected = [ - 'foo' => 'findFoo' + 'foo' => 'findFoo', ]; $this->assertEquals($expected, $behavior->implementedFinders()); } @@ -272,8 +280,7 @@ public function testImplementedFindersDisabled() { $behavior = new Test2Behavior($table, [ 'implementedFinders' => [] ]); - $expected = []; - $this->assertEquals($expected, $behavior->implementedFinders()); + $this->assertEquals([], $behavior->implementedFinders()); } /** diff --git a/tests/test_app/TestApp/Model/Behavior/DuplicateBehavior.php b/tests/test_app/TestApp/Model/Behavior/DuplicateBehavior.php index 75352a89a26..3b49efd60b8 100644 --- a/tests/test_app/TestApp/Model/Behavior/DuplicateBehavior.php +++ b/tests/test_app/TestApp/Model/Behavior/DuplicateBehavior.php @@ -20,6 +20,17 @@ * Test class for trigging duplicate method errors. */ class DuplicateBehavior extends Behavior { + protected $_defaultConfig = [ + 'implementedFinders' => [ + 'children' => 'findChildren', + ], + 'implementedMethods' => [ + 'slugify' => 'slugify', + ] + ]; + + public function findChildren() { + } public function slugify() { }