merged branch bschussek/issue5205 (PR #5277)

Commits
-------

3ad3876 [Form] Fixed support for preferred choices in "entity" type

Discussion
----------

[Form] Fixed support for preferred choices in "entity" type

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: #5205
Todo: -
This commit is contained in:
Fabien Potencier 2012-08-16 20:00:28 +02:00
commit 1656bf3dcf
4 changed files with 65 additions and 5 deletions

View File

@ -76,6 +76,13 @@ class EntityChoiceList extends ObjectChoiceList
*/
private $loaded = false;
/**
* The preferred entities.
*
* @var array
*/
private $preferredEntities = array();
/**
* Creates a new entity choice list.
*
@ -88,13 +95,14 @@ class EntityChoiceList extends ObjectChoiceList
* to group the choices. Only allowed if
* the choices are given as flat array.
*/
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, $groupPath = null)
public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null)
{
$this->em = $manager;
$this->entityLoader = $entityLoader;
$this->classMetadata = $manager->getClassMetadata($class);
$this->class = $this->classMetadata->getName();
$this->loaded = is_array($entities) || $entities instanceof \Traversable;
$this->preferredEntities = $preferredEntities;
$identifier = $this->classMetadata->getIdentifierFieldNames();
@ -113,7 +121,7 @@ class EntityChoiceList extends ObjectChoiceList
$entities = array();
}
parent::__construct($entities, $labelPath, array(), $groupPath);
parent::__construct($entities, $labelPath, $preferredEntities, $groupPath);
}
/**
@ -359,8 +367,7 @@ class EntityChoiceList extends ObjectChoiceList
try {
// The second parameter $labels is ignored by ObjectChoiceList
// The third parameter $preferredChoices is currently not supported
parent::initialize($entities, array(), array());
parent::initialize($entities, array(), $this->preferredEntities);
} catch (StringCastException $e) {
throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e);
}

View File

@ -81,6 +81,14 @@ abstract class DoctrineType extends AbstractType
});
}
$preferredChoiceHashes = $options['preferred_choices'];
if (is_array($preferredChoiceHashes)) {
array_walk_recursive($preferredChoiceHashes, function ($value) {
return spl_object_hash($value);
});
}
// Support for custom loaders (with query builders)
$loaderHash = is_object($options['loader'])
? spl_object_hash($options['loader'])
@ -97,6 +105,7 @@ abstract class DoctrineType extends AbstractType
$propertyHash,
$loaderHash,
$choiceHashes,
$preferredChoiceHashes,
$groupByHash
)));
@ -107,6 +116,7 @@ abstract class DoctrineType extends AbstractType
$options['property'],
$options['loader'],
$options['choices'],
$options['preferred_choices'],
$options['group_by']
);
}

View File

@ -181,7 +181,8 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
array(
'group1' => array($entity1),
'group2' => array($entity2),
)
),
array()
);
$this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices());
@ -214,6 +215,7 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
$item3,
$item4,
),
array(),
'groupName'
);
@ -242,6 +244,7 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
$item1,
$item2,
),
array(),
'child.that.does.not.exist'
);
@ -267,6 +270,7 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
null,
null,
null,
array(),
null
);

View File

@ -536,6 +536,45 @@ class EntityTypeTest extends TypeTestCase
), $field->createView()->vars['choices']);
}
public function testPreferredChoices()
{
$entity1 = new SingleIdentEntity(1, 'Foo');
$entity2 = new SingleIdentEntity(2, 'Bar');
$entity3 = new SingleIdentEntity(3, 'Baz');
$this->persist(array($entity1, $entity2, $entity3));
$field = $this->factory->createNamed('name', 'entity', null, array(
'em' => 'default',
'class' => self::SINGLE_IDENT_CLASS,
'preferred_choices' => array($entity3, $entity2),
'property' => 'name',
));
$this->assertEquals(array(3 => new ChoiceView($entity3, '3', 'Baz'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['preferred_choices']);
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo')), $field->createView()->vars['choices']);
}
public function testOverrideChoicesWithPreferredChoices()
{
$entity1 = new SingleIdentEntity(1, 'Foo');
$entity2 = new SingleIdentEntity(2, 'Bar');
$entity3 = new SingleIdentEntity(3, 'Baz');
$this->persist(array($entity1, $entity2, $entity3));
$field = $this->factory->createNamed('name', 'entity', null, array(
'em' => 'default',
'class' => self::SINGLE_IDENT_CLASS,
'choices' => array($entity2, $entity3),
'preferred_choices' => array($entity3),
'property' => 'name',
));
$this->assertEquals(array(3 => new ChoiceView($entity3, '3', 'Baz')), $field->createView()->vars['preferred_choices']);
$this->assertEquals(array(2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
}
public function testDisallowChoicesThatAreNotIncluded_choicesSingleIdentifier()
{
$entity1 = new SingleIdentEntity(1, 'Foo');