From 81e94d084bbbae942d626c0f4e9809f0745adc35 Mon Sep 17 00:00:00 2001 From: Cedric LOMBARDOT Date: Sat, 22 Mar 2014 11:45:01 +0000 Subject: [PATCH] Model choice accept custom unique column Use now ->add('my_field', 'model', array('class' => 'MyClassWithSlug', 'index_property' => 'slug')); To make choice list keys as slug --- .../Form/ChoiceList/ModelChoiceList.php | 30 ++++++++++++++----- .../Bridge/Propel1/Form/Type/ModelType.php | 4 ++- .../Bridge/Propel1/Tests/Fixtures/Column.php | 5 ++-- .../Bridge/Propel1/Tests/Fixtures/Item.php | 10 ++++++- .../Propel1/Tests/Fixtures/ItemQuery.php | 1 + .../Form/ChoiceList/ModelChoiceListTest.php | 22 ++++++++++++++ 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php index eaeeba960bfc..3c6e6690e3c9 100644 --- a/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php +++ b/src/Symfony/Bridge/Propel1/Form/ChoiceList/ModelChoiceList.php @@ -71,17 +71,18 @@ class ModelChoiceList extends ObjectChoiceList * * @see \Symfony\Bridge\Propel1\Form\Type\ModelType How to use the preferred choices. * - * @param string $class The FQCN of the model class to be loaded. - * @param string $labelPath A property path pointing to the property used for the choice labels. - * @param array $choices An optional array to use, rather than fetching the models. - * @param ModelCriteria $queryObject The query to use retrieving model data from database. - * @param string $groupPath A property path pointing to the property used to group the choices. - * @param array|ModelCriteria $preferred The preferred items of this choice. + * @param string $class The FQCN of the model class to be loaded. + * @param string $labelPath A property path pointing to the property used for the choice labels. + * @param array $choices An optional array to use, rather than fetching the models. + * @param ModelCriteria $queryObject The query to use retrieving model data from database. + * @param string $groupPath A property path pointing to the property used to group the choices. + * @param array|ModelCriteria $preferred The preferred items of this choice. * Either an array if $choices is given, * or a ModelCriteria to be merged with the $queryObject. + * @param string $useAsIdentifier a custome unique column (eg slug) to use instead of primary key * @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths. */ - public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array(), PropertyAccessorInterface $propertyAccessor = null) + public function __construct($class, $labelPath = null, $choices = null, $queryObject = null, $groupPath = null, $preferred = array(), PropertyAccessorInterface $propertyAccessor = null, $useAsIdentifier = null) { $this->class = $class; @@ -96,7 +97,12 @@ public function __construct($class, $labelPath = null, $choices = null, $queryOb $query = new $queryClass(); $this->query = $queryObject ?: $query; - $this->identifier = $this->query->getTableMap()->getPrimaryKeys(); + if ($useAsIdentifier) { + $this->identifier = array( $this->query->getTableMap()->getColumn($useAsIdentifier) ); + } else { + $this->identifier = $this->query->getTableMap()->getPrimaryKeys(); + } + $this->loaded = is_array($choices) || $choices instanceof \Traversable; if ($preferred instanceof ModelCriteria) { @@ -437,6 +443,14 @@ private function getIdentifierValues($model) return array(); } + if (1 === count($this->identifier) && current($this->identifier) instanceof \ColumnMap) { + $phpName = current($this->identifier)->getPhpName(); + + if (method_exists($model, 'get'.$phpName)) { + return array($model->{'get'.$phpName}()); + } + } + if ($model instanceof Persistent) { return array($model->getPrimaryKey()); } diff --git a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php index 02090d3638a2..7e4b2ec3a91f 100644 --- a/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php +++ b/src/Symfony/Bridge/Propel1/Form/Type/ModelType.php @@ -79,7 +79,8 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) $options['query'], $options['group_by'], $options['preferred_choices'], - $propertyAccessor + $propertyAccessor, + $options['index_property'] ); }; @@ -94,6 +95,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) 'choice_list' => $choiceList, 'group_by' => null, 'by_reference' => false, + 'index_property' => null, )); } diff --git a/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php b/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php index 6b03977e2032..24a0ae0e15f3 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php +++ b/src/Symfony/Bridge/Propel1/Tests/Fixtures/Column.php @@ -11,16 +11,17 @@ namespace Symfony\Bridge\Propel1\Tests\Fixtures; -class Column +class Column extends \ColumnMap { private $name; - private $type; + protected $type; public function __construct($name, $type) { $this->name = $name; $this->type = $type; + $this->phpName = ucfirst($name); } public function getType() diff --git a/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php b/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php index 70705b6c86da..fdc4024ad972 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php +++ b/src/Symfony/Bridge/Propel1/Tests/Fixtures/Item.php @@ -23,12 +23,15 @@ class Item implements \Persistent private $price; - public function __construct($id = null, $value = null, $groupName = null, $price = null) + private $slug; + + public function __construct($id = null, $value = null, $groupName = null, $price = null, $slug = null) { $this->id = $id; $this->value = $value; $this->groupName = $groupName; $this->price = $price; + $this->slug = $slug; } public function getId() @@ -56,6 +59,11 @@ public function getPrice() return $this->price; } + public function getSlug() + { + return $this->slug; + } + public function getPrimaryKey() { return $this->getId(); diff --git a/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php b/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php index 3e1aecc58d26..cb2532f64768 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php +++ b/src/Symfony/Bridge/Propel1/Tests/Fixtures/ItemQuery.php @@ -18,6 +18,7 @@ class ItemQuery 'value' => \PropelColumnTypes::VARCHAR, 'price' => \PropelColumnTypes::FLOAT, 'is_active' => \PropelColumnTypes::BOOLEAN, + 'slug' => \PropelColumnTypes::VARCHAR, 'enabled' => \PropelColumnTypes::BOOLEAN_EMU, 'updated_at' => \PropelColumnTypes::TIMESTAMP, ); diff --git a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php index ef77b5edbbd7..fa67bb5e7bff 100644 --- a/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php +++ b/src/Symfony/Bridge/Propel1/Tests/Form/ChoiceList/ModelChoiceListTest.php @@ -259,4 +259,26 @@ public function testInvalidClass() { $choiceList = new ModelChoiceList('Foo\Bar\DoesNotExistClass'); } + + public function testCustomIdentifier() + { + $item1 = new Item(1, 'Foo', null, null, 'slug'); + $item2 = new Item(2, 'Bar', null, null, 'slug2'); + + $choiceList = new ModelChoiceList( + self::ITEM_CLASS, + 'value', + array( + $item1, + $item2, + ), + null, + null, + array(), + null, + 'slug' + ); + + $this->assertSame(array('slug' => $item1, 'slug2' => $item2), $choiceList->getChoices()); + } }