Browse Source

Adding magic creation of select multiple fields for HABTM associations

Jose Lorenzo Rodriguez 12 years ago
parent
commit
435d181bd0

+ 14 - 0
src/View/Form/EntityContext.php

@@ -199,12 +199,26 @@ class EntityContext implements ContextInterface {
 		}
 		$parts = explode('.', $field);
 		$entity = $this->_getEntity($parts);
+
+		if (end($parts) === '_ids' && !empty($entity)) {
+			return $this->_extractMultiple($entity, $parts);
+		}
+
 		if ($entity instanceof Entity) {
 			return $entity->get(array_pop($parts));
 		}
 		return null;
 	}
 
+	protected function _extractMultiple($values, $path) {
+		if (!(is_array($values) || $values instanceof \Traversable)) {
+			return null;
+		}
+		$table = $this->_getTable($path);
+		$primary = (array)$table->primaryKey();
+		return (new Collection($values))->extract($primary[0])->toArray();
+	}
+
 /**
  * Fetch the leaf entity for the given path.
  *

+ 11 - 7
src/View/Helper/FormHelper.php

@@ -663,11 +663,13 @@ class FormHelper extends Helper {
  */
 	public function label($fieldName, $text = null, $options = array()) {
 		if ($text === null) {
-			if (strpos($fieldName, '.') !== false) {
-				$fieldElements = explode('.', $fieldName);
+			$text = $fieldName;
+			if (substr($text, -5) === '._ids') {
+				$text = substr($text, 0, -5);
+			}
+			if (strpos($text, '.') !== false) {
+				$fieldElements = explode('.', $text);
 				$text = array_pop($fieldElements);
-			} else {
-				$text = $fieldName;
 			}
 			if (substr($text, -3) === '_id') {
 				$text = substr($text, 0, -3);
@@ -1019,14 +1021,16 @@ class FormHelper extends Helper {
 			}
 		}
 
-		// Missing HABTM
-		//...
-
 		$typesWithOptions = ['text', 'number', 'radio', 'select'];
 		if ($allowOverride && in_array($options['type'], $typesWithOptions)) {
 			$options = $this->_optionsOptions($fieldName, $options);
 		}
 
+		if ($allowOverride && substr($fieldName, -5) === '._ids') {
+			$options['type'] = 'select';
+			$options['multiple'] = true;
+		}
+
 		if ($options['type'] === 'select' && array_key_exists('step', $options)) {
 			unset($options['step']);
 		}

+ 33 - 43
tests/TestCase/View/Helper/FormHelperTest.php

@@ -3394,33 +3394,27 @@ class FormHelperTest extends TestCase {
  * @return void
  */
 	public function testHabtmSelectBox() {
-		$this->markTestIncomplete('Need to revisit once models work again.');
-		$this->View->viewVars['contactTags'] = array(
+		$this->loadFixtures('Article');
+		$options = array(
 			1 => 'blue',
 			2 => 'red',
 			3 => 'green'
 		);
-		$this->Form->request->data = array(
-			'Contact' => array(),
-			'ContactTag' => array(
-				array(
-					'id' => '1',
-					'name' => 'blue'
-				),
-				array(
-					'id' => 3,
-					'name' => 'green'
-				)
-			)
-		);
-		$this->Form->create('Contact');
-		$result = $this->Form->input('ContactTag', array('div' => false, 'label' => false));
+		$tags = [
+			new Entity(['id' => 1, 'name' => 'blue']),
+			new Entity(['id' => 3, 'name' => 'green'])
+		];
+		$article = new Article(['tags' => $tags]);
+		$this->Form->create($article);
+		$result = $this->Form->input('tags._ids', ['options' => $options]);
 		$expected = array(
-			'input' => array(
-				'type' => 'hidden', 'name' => 'ContactTag[ContactTag]', 'value' => '', 'id' => 'ContactTagContactTag_'
-			),
+			'div' => array('class' => 'input select'),
+			'label' => array('for' => 'tags-ids'),
+			'Tags',
+			'/label',
+			'input' => array('type' => 'hidden', 'name' => 'tags[_ids]', 'value' => ''),
 			'select' => array(
-				'name' => 'ContactTag[ContactTag][]', 'id' => 'ContactTagContactTag',
+				'name' => 'tags[_ids][]', 'id' => 'tags-ids',
 				'multiple' => 'multiple'
 			),
 			array('option' => array('value' => '1', 'selected' => 'selected')),
@@ -3432,37 +3426,32 @@ class FormHelperTest extends TestCase {
 			array('option' => array('value' => '3', 'selected' => 'selected')),
 			'green',
 			'/option',
-			'/select'
+			'/select',
+			'/div'
 		);
 		$this->assertTags($result, $expected);
 
 		// make sure only 50 is selected, and not 50f5c0cf
-		$this->View->viewVars['contactTags'] = array(
+		$options = array(
 			'1' => 'blue',
 			'50f5c0cf' => 'red',
 			'50' => 'green'
 		);
-		$this->Form->request->data = array(
-			'Contact' => array(),
-			'ContactTag' => array(
-				array(
-					'id' => 1,
-					'name' => 'blue'
-				),
-				array(
-					'id' => 50,
-					'name' => 'green'
-				)
-			)
-		);
-		$this->Form->create('Contact');
-		$result = $this->Form->input('ContactTag', array('div' => false, 'label' => false));
+		$tags = [
+			new Entity(['id' => 1, 'name' => 'blue']),
+			new Entity(['id' => 50, 'name' => 'green'])
+		];
+		$article = new Article(['tags' => $tags]);
+		$this->Form->create($article);
+		$result = $this->Form->input('tags._ids', ['options' => $options]);
 		$expected = array(
-			'input' => array(
-				'type' => 'hidden', 'name' => 'ContactTag[ContactTag]', 'value' => '', 'id' => 'ContactTagContactTag_'
-			),
+			'div' => array('class' => 'input select'),
+			'label' => array('for' => 'tags-ids'),
+			'Tags',
+			'/label',
+			'input' => array('type' => 'hidden', 'name' => 'tags[_ids]', 'value' => ''),
 			'select' => array(
-				'name' => 'ContactTag[ContactTag][]', 'id' => 'ContactTagContactTag',
+				'name' => 'tags[_ids][]', 'id' => 'tags-ids',
 				'multiple' => 'multiple'
 			),
 			array('option' => array('value' => '1', 'selected' => 'selected')),
@@ -3474,7 +3463,8 @@ class FormHelperTest extends TestCase {
 			array('option' => array('value' => '50', 'selected' => 'selected')),
 			'green',
 			'/option',
-			'/select'
+			'/select',
+			'/div'
 		);
 		$this->assertTags($result, $expected);
 	}