Browse Source

Fix incorrect field detection for habtm fields.

Fields on habtm models would always be treated as multiselects.
Even when there were additional fields specified.

Fixes #2153
mark_story 14 years ago
parent
commit
c2c63d373c

+ 19 - 0
lib/Cake/Test/Case/View/HelperTest.php

@@ -349,6 +349,25 @@ class HelperTest extends CakeTestCase {
 	}
 
 /**
+ * Test that habtm associations can have property fields created.
+ *
+ * @return void
+ */
+	public function testSetEntityHabtmPropertyFieldNames() {
+		$this->Helper->fieldset = array(
+			'HelperTestComment' => array(
+				'fields' => array('Tag' => array('type' => 'multiple'))
+			)
+		);
+		$this->Helper->setEntity('HelperTestComment', true);
+
+		$this->Helper->setEntity('Tag.name');
+		$this->assertEquals('Tag', $this->Helper->model());
+		$this->assertEquals('name', $this->Helper->field());
+		$this->assertEquals(array('Tag', 'name'), $this->Helper->entity());
+	}
+
+/**
  * test that 'view' doesn't break things.
  *
  * @return void

+ 9 - 9
lib/Cake/View/Helper.php

@@ -453,21 +453,21 @@ class Helper extends Object {
 
 		$this->_association = null;
 
-		// habtm models are special
-		if (
+		$isHabtm = (
 			isset($this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type']) &&
-			$this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type'] === 'multiple'
-		) {
+			$this->fieldset[$this->_modelScope]['fields'][$parts[0]]['type'] === 'multiple' &&
+			$count == 1
+		);
+
+		// habtm models are special
+		if ($count == 1 && $isHabtm) {
 			$this->_association = $parts[0];
 			$entity = $parts[0] . '.' . $parts[0];
 		} else {
 			// check for associated model.
 			$reversed = array_reverse($parts);
-			foreach ($reversed as $part) {
-				if (
-					!isset($this->fieldset[$this->_modelScope]['fields'][$part]) &&
-					preg_match('/^[A-Z]/', $part)
-				) {
+			foreach ($reversed as $i => $part) {
+				if ($i > 0 && preg_match('/^[A-Z]/', $part)) {
 					$this->_association = $part;
 					break;
 				}

+ 3 - 20
lib/Cake/View/Helper/FormHelper.php

@@ -196,11 +196,11 @@ class FormHelper extends AppHelper {
 			if ($key === 'fields') {
 				if (!isset($this->fieldset[$model]['fields'])) {
 					$fields = $this->fieldset[$model]['fields'] = $object->schema();
-				}
-				if (empty($field)) {
 					foreach ($object->hasAndBelongsToMany as $alias => $assocData) {
 						$this->fieldset[$object->alias]['fields'][$alias] = array('type' => 'multiple');
 					}
+				}
+				if (empty($field)) {
 					return $this->fieldset[$model]['fields'];
 				} elseif (isset($this->fieldset[$model]['fields'][$field])) {
 					return $this->fieldset[$model]['fields'][$field];
@@ -445,6 +445,7 @@ class FormHelper extends AppHelper {
 
 		if ($model !== false) {
 			$this->setEntity($model, true);
+			$this->_introspectModel($model, 'fields');
 		}
 		return $this->Html->useTag('form', $action, $htmlAttributes) . $append;
 	}
@@ -2235,24 +2236,6 @@ class FormHelper extends AppHelper {
 	}
 
 /**
- * Add support for special HABTM syntax.
- *
- * Sets this helper's model and field properties to the dot-separated value-pair in $entity.
- *
- * @param mixed $entity A field name, like "ModelName.fieldName" or "ModelName.ID.fieldName"
- * @param boolean $setScope Sets the view scope to the model specified in $tagValue
- * @return void
- */
-	public function setEntity($entity, $setScope = false) {
-		parent::setEntity($entity, $setScope);
-		$parts = explode('.', $entity);
-		$field = $this->_introspectModel($this->_modelScope, 'fields', $parts[0]);
-		if (!empty($field) && $field['type'] === 'multiple') {
-			$this->_entityPath = $parts[0] . '.' . $parts[0];
-		}
-	}
-
-/**
  * Gets the input field name for the current tag
  *
  * @param array $options