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; private $loaded = false;
/**
* The preferred entities.
*
* @var array
*/
private $preferredEntities = array();
/** /**
* Creates a new entity choice list. * Creates a new entity choice list.
* *
@ -88,13 +95,14 @@ class EntityChoiceList extends ObjectChoiceList
* to group the choices. Only allowed if * to group the choices. Only allowed if
* the choices are given as flat array. * 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->em = $manager;
$this->entityLoader = $entityLoader; $this->entityLoader = $entityLoader;
$this->classMetadata = $manager->getClassMetadata($class); $this->classMetadata = $manager->getClassMetadata($class);
$this->class = $this->classMetadata->getName(); $this->class = $this->classMetadata->getName();
$this->loaded = is_array($entities) || $entities instanceof \Traversable; $this->loaded = is_array($entities) || $entities instanceof \Traversable;
$this->preferredEntities = $preferredEntities;
$identifier = $this->classMetadata->getIdentifierFieldNames(); $identifier = $this->classMetadata->getIdentifierFieldNames();
@ -113,7 +121,7 @@ class EntityChoiceList extends ObjectChoiceList
$entities = array(); $entities = array();
} }
parent::__construct($entities, $labelPath, array(), $groupPath); parent::__construct($entities, $labelPath, $preferredEntities, $groupPath);
} }
/** /**
@ -359,8 +367,7 @@ class EntityChoiceList extends ObjectChoiceList
try { try {
// The second parameter $labels is ignored by ObjectChoiceList // The second parameter $labels is ignored by ObjectChoiceList
// The third parameter $preferredChoices is currently not supported parent::initialize($entities, array(), $this->preferredEntities);
parent::initialize($entities, array(), array());
} catch (StringCastException $e) { } catch (StringCastException $e) {
throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $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) // Support for custom loaders (with query builders)
$loaderHash = is_object($options['loader']) $loaderHash = is_object($options['loader'])
? spl_object_hash($options['loader']) ? spl_object_hash($options['loader'])
@ -97,6 +105,7 @@ abstract class DoctrineType extends AbstractType
$propertyHash, $propertyHash,
$loaderHash, $loaderHash,
$choiceHashes, $choiceHashes,
$preferredChoiceHashes,
$groupByHash $groupByHash
))); )));
@ -107,6 +116,7 @@ abstract class DoctrineType extends AbstractType
$options['property'], $options['property'],
$options['loader'], $options['loader'],
$options['choices'], $options['choices'],
$options['preferred_choices'],
$options['group_by'] $options['group_by']
); );
} }

View File

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

View File

@ -536,6 +536,45 @@ class EntityTypeTest extends TypeTestCase
), $field->createView()->vars['choices']); ), $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() public function testDisallowChoicesThatAreNotIncluded_choicesSingleIdentifier()
{ {
$entity1 = new SingleIdentEntity(1, 'Foo'); $entity1 = new SingleIdentEntity(1, 'Foo');