Browse Source

Ensuring list of behavior methods are refreshed between calls of
validates() in the model, fixes #3071

Jose Lorenzo Rodriguez 13 years ago
parent
commit
f6278488af
2 changed files with 51 additions and 4 deletions
  1. 22 4
      lib/Cake/Model/ModelValidator.php
  2. 29 0
      lib/Cake/Test/Case/Model/ModelValidationTest.php

+ 22 - 4
lib/Cake/Model/ModelValidator.php

@@ -64,6 +64,20 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
 	protected $_methods = array();
 
 /**
+ * Holds the available custom callback methods from the model
+ *
+ * @var array
+ */
+	protected $_modelMethods = array();
+
+/**
+ * Holds the list of behavior names that were attached when this object was created
+ *
+ * @var array
+ */
+	protected $_behaviors = array();
+
+/**
  * Constructor
  *
  * @param Model $Model A reference to the Model the Validator is attached to
@@ -280,15 +294,19 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
  * @return array List of callables to be used as validation methods
  */
 	public function getMethods() {
-		if (!empty($this->_methods)) {
+		$behaviors = $this->_model->Behaviors->enabled();
+		if (!empty($this->_methods) && $behaviors === $this->_behaviors) {
 			return $this->_methods;
 		}
+		$this->_behaviors = $behaviors;
 
-		$methods = array();
-		foreach (get_class_methods($this->_model) as $method) {
-			$methods[strtolower($method)] = array($this->_model, $method);
+		if (empty($this->_modelMethods)) {
+			foreach (get_class_methods($this->_model) as $method) {
+				$this->_modelMethods[strtolower($method)] = array($this->_model, $method);
+			}
 		}
 
+		$methods = $this->_modelMethods;
 		foreach (array_keys($this->_model->Behaviors->methods()) as $method) {
 			$methods += array(strtolower($method) => array($this->_model, $method));
 		}

+ 29 - 0
lib/Cake/Test/Case/Model/ModelValidationTest.php

@@ -1701,6 +1701,35 @@ class ModelValidationTest extends BaseModelTest {
 	}
 
 /**
+ *  Tests that methods are refreshed when the list of behaviors change
+ *
+ * @return void
+ */
+	public function testGetMethodsRefresh() {
+		$this->loadFixtures('Article', 'Comment');
+		$TestModel = new Article();
+		$Validator = $TestModel->validator();
+
+		$result = $Validator->getMethods();
+
+		$expected = array_map('strtolower', get_class_methods('Article'));
+		$this->assertEquals($expected, array_keys($result));
+
+		$TestModel->Behaviors->attach('Containable');
+		$newList = array(
+			'contain',
+			'resetbindings',
+			'containments',
+			'fielddependencies',
+			'containmentsmap'
+		);
+		$this->assertEquals(array_merge($expected, $newList), array_keys($Validator->getMethods()));
+
+		$TestModel->Behaviors->detach('Containable');
+		$this->assertEquals($expected, array_keys($Validator->getMethods()));
+	}
+
+/**
  * testSetValidationDomain method
  *
  * @return void