Browse Source

Fixing behavior prioritizing

ADmad 13 years ago
parent
commit
b32e855a3d

+ 8 - 3
lib/Cake/Model/BehaviorCollection.php

@@ -108,7 +108,8 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
 			$behavior = $config['className'];
 		}
 		$configDisabled = isset($config['enabled']) && $config['enabled'] === false;
-		unset($config['enabled'], $config['className']);
+		$priority = isset($config['priority']) ? $config['priority'] : $this->defaultPriority;
+		unset($config['enabled'], $config['className'], $config['priority']);
 
 		list($plugin, $name) = pluginSplit($behavior, true);
 		if (!isset($alias)) {
@@ -145,6 +146,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
 		if (empty($config)) {
 			$config = array();
 		}
+		$this->_loaded[$alias]->settings['priority'] = $priority;
 		$this->_loaded[$alias]->setup(ClassRegistry::getObject($this->modelName), $config);
 
 		foreach ($this->_loaded[$alias]->mapMethods as $method => $methodAlias) {
@@ -169,11 +171,14 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
 			}
 		}
 
-		if (!in_array($alias, $this->_enabled) && !$configDisabled) {
+		if ($configDisabled) {
+			$this->disable($alias);
+		} elseif (!$this->enabled($alias)) {
 			$this->enable($alias);
 		} else {
-			$this->disable($alias);
+			$this->setPriority($alias, $priority);
 		}
+
 		return true;
 	}
 

+ 110 - 3
lib/Cake/Test/Case/Model/BehaviorCollectionTest.php

@@ -419,6 +419,39 @@ class TestAliasBehavior extends TestBehavior {
 }
 
 /**
+ * FirstBehavior
+ */
+class FirstBehavior extends ModelBehavior {
+
+	public function beforeFind(Model $model, $query = array()) {
+		$model->called[] = get_class($this);
+		return $query;
+	}
+
+}
+
+/**
+ * SecondBehavior
+ */
+class SecondBehavior extends FirstBehavior {
+}
+
+/**
+ * ThirdBehavior
+ */
+class ThirdBehavior extends FirstBehavior {
+}
+
+/**
+ * Orangutan Model
+ */
+class Orangutan extends Monkey {
+
+	public $called = array();
+
+}
+
+/**
  * BehaviorCollection class
  *
  * @package       Cake.Test.Case.Model
@@ -432,7 +465,8 @@ class BehaviorCollectionTest extends CakeTestCase {
  */
 	public $fixtures = array(
 		'core.apple', 'core.sample', 'core.article', 'core.user', 'core.comment',
-		'core.attachment', 'core.tag', 'core.articles_tag', 'core.translate'
+		'core.attachment', 'core.tag', 'core.articles_tag', 'core.translate',
+		'core.device'
 	);
 
 /**
@@ -489,14 +523,14 @@ class BehaviorCollectionTest extends CakeTestCase {
 		$this->assertEquals('testbehavior', strtolower(get_class($Apple->Behaviors->Test)));
 		$expected = array('beforeFind' => 'on', 'afterFind' => 'off', 'key' => 'value');
 		$this->assertEquals($expected, $Apple->Behaviors->Test->settings['Apple']);
-		$this->assertEquals(array('Apple'), array_keys($Apple->Behaviors->Test->settings));
+		$this->assertEquals(array('priority', 'Apple'), array_keys($Apple->Behaviors->Test->settings));
 
 		$this->assertSame($Apple->Sample->Behaviors->loaded(), array());
 		$Apple->Sample->Behaviors->attach('Test', array('key2' => 'value2'));
 		$this->assertSame($Apple->Sample->Behaviors->loaded(), array('Test'));
 		$this->assertEquals(array('beforeFind' => 'on', 'afterFind' => 'off', 'key2' => 'value2'), $Apple->Sample->Behaviors->Test->settings['Sample']);
 
-		$this->assertEquals(array('Apple', 'Sample'), array_keys($Apple->Behaviors->Test->settings));
+		$this->assertEquals(array('priority', 'Apple', 'Sample'), array_keys($Apple->Behaviors->Test->settings));
 		$this->assertSame(
 			$Apple->Sample->Behaviors->Test->settings,
 			$Apple->Behaviors->Test->settings
@@ -1149,4 +1183,77 @@ class BehaviorCollectionTest extends CakeTestCase {
 		$this->assertEquals($expected, $result);
 	}
 
+/**
+ * Test that behavior priority
+ */
+	public function testBehaviorOrderCallbacks() {
+		$model = ClassRegistry::init('Orangutan');
+		$model->Behaviors->init('Orangutan', array(
+			'Second' => array('priority' => 9),
+			'Third',
+			'First' => array('priority' => 8),
+		));
+
+		$this->assertEmpty($model->called);
+
+		$model->find('first');
+		$expected = array(
+			'FirstBehavior',
+			'SecondBehavior',
+			'ThirdBehavior',
+		);
+		$this->assertEquals($expected, $model->called);
+
+		$model->called = array();
+		$model->Behaviors->load('Third', array('priority' => 1));
+
+		$model->find('first');
+		$expected = array(
+			'ThirdBehavior',
+			'FirstBehavior',
+			'SecondBehavior'
+		);
+		$this->assertEquals($expected, $model->called);
+
+		$model->called = array();
+		$model->Behaviors->load('First');
+
+		$model->find('first');
+		$expected = array(
+			'ThirdBehavior',
+			'SecondBehavior',
+			'FirstBehavior'
+		);
+		$this->assertEquals($expected, $model->called);
+
+		$model->called = array();
+		$model->Behaviors->unload('Third');
+
+		$model->find('first');
+		$expected = array(
+			'SecondBehavior',
+			'FirstBehavior'
+		);
+		$this->assertEquals($expected, $model->called);
+
+		$model->called = array();
+		$model->Behaviors->disable('Second');
+
+		$model->find('first');
+		$expected = array(
+			'FirstBehavior'
+		);
+		$this->assertEquals($expected, $model->called);
+
+		$model->called = array();
+		$model->Behaviors->enable('Second');
+
+		$model->find('first');
+		$expected = array(
+			'SecondBehavior',
+			'FirstBehavior'
+		);
+		$this->assertEquals($expected, $model->called);
+	}
+
 }