feature #10513 [Bridge][Propel1][Form] Model choice accept custom unique column (cedriclombardot)

This PR was merged into the 2.5-dev branch.

Discussion
----------

[Bridge][Propel1][Form] Model choice accept custom unique column

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| License       | MIT

This PR permit to do :

```` php
<?php
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('my_field', 'model', array(
                        'class' => 'MyClassWithSlug',
                        'index_property' => 'slug'
    ));
}
````

With this option you can hide internal ids to expose an unique column eg slug and render

```` html
<select name="my_field">
      <option value="{THE_SLUG}">{THE_VALUE}</option>
</select>
````

Commits
-------

81e94d0 Model choice accept custom unique column
This commit is contained in:
Fabien Potencier 2014-03-26 15:17:29 +01:00
commit 9dc14a5c2b
6 changed files with 60 additions and 12 deletions

View File

@ -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 @@ class ModelChoiceList extends ObjectChoiceList
$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 @@ class ModelChoiceList extends ObjectChoiceList
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());
}

View File

@ -79,7 +79,8 @@ class ModelType extends AbstractType
$options['query'],
$options['group_by'],
$options['preferred_choices'],
$propertyAccessor
$propertyAccessor,
$options['index_property']
);
};
@ -94,6 +95,7 @@ class ModelType extends AbstractType
'choice_list' => $choiceList,
'group_by' => null,
'by_reference' => false,
'index_property' => null,
));
}

View File

@ -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()

View File

@ -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 @@ class Item implements \Persistent
return $this->price;
}
public function getSlug()
{
return $this->slug;
}
public function getPrimaryKey()
{
return $this->getId();

View File

@ -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,
);

View File

@ -259,4 +259,26 @@ class ModelChoiceListTest extends Propel1TestCase
{
$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());
}
}