diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php index 6406bb1dd5..0b00b98181 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php @@ -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); } diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 48cbdda954..e7c6accaa4 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -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'] ); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php index 5d9c747c6e..3a2e9bba9f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/EntityChoiceListTest.php @@ -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 ); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index 073336a8b5..1dc90fb3c7 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -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');