Skip to content
Permalink
Browse files

Fix behavior method alias management.

When behaviors explicitly defined their finders/methods aliasing and
disabling methods no longer worked. This was due to the underlying
config() method always merging and the values - not the keys - being the
key feature of the data. This new code now uses the values to determine
what the correct config data should be. This results in additional calls
to config when methods are customized, but the code behaves as most
people would expect now.

Refs #4414
  • Loading branch information...
markstory committed Aug 28, 2014
1 parent 0fa5a84 commit 0cb4ee606cc8b065d8aab021783e01d9edacffa5
@@ -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
*
@@ -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()
*
@@ -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());
}
/**
@@ -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() {
}

0 comments on commit 0cb4ee6

Please sign in to comment.
You can’t perform that action at this time.