diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php index 5f5874abeafc..17491acad724 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php @@ -115,20 +115,12 @@ public function __construct(EntityManager $em, $class, $property = null, $queryB /** * Initializes the choices and returns them * - * The choices are generated from the entities. If the entities have a - * composite identifier, the choices are indexed using ascending integers. - * Otherwise the identifiers are used as indices. - * * If the entities were passed in the "choices" option, this method * does not have any significant overhead. Otherwise, if a query builder * was passed in the "query_builder" option, this builder is now used * to construct a query which is executed. In the last case, all entities * for the underlying class are fetched from the repository. * - * If the option "property" was passed, the property path in that option - * is used as option values. Otherwise this method tries to convert - * objects to strings using __toString(). - * * @return array An array of choices */ protected function load() @@ -146,7 +138,32 @@ protected function load() $this->choices = array(); $this->entities = array(); + $this->loadEntities($entities); + + return $this->choices; + } + + /** + * Convert entities into choices with support for groups + * + * The choices are generated from the entities. If the entities have a + * composite identifier, the choices are indexed using ascending integers. + * Otherwise the identifiers are used as indices. + * + * If the option "property" was passed, the property path in that option + * is used as option values. Otherwise this method tries to convert + * objects to strings using __toString(). + * + */ + private function loadEntities($entities, $group = null) + { foreach ($entities as $key => $entity) { + if (is_array($entity)) { + // Entities are in named groups + $this->loadEntities($entity, $key); + continue; + } + if ($this->propertyPath) { // If the property option was given, use it $value = $this->propertyPath->getValue($entity); @@ -158,15 +175,22 @@ protected function load() if (count($this->identifier) > 1) { // When the identifier consists of multiple field, use // naturally ordered keys to refer to the choices - $this->choices[$key] = $value; - $this->entities[$key] = $entity; + $id = $key; } else { // When the identifier is a single field, index choices by // entity ID for performance reasons $id = current($this->getIdentifierValues($entity)); + } + + if (null === $group) { + // Flat list of choices $this->choices[$id] = $value; - $this->entities[$id] = $entity; + } else { + // Nested choices + $this->choices[$group][$id] = $value; } + + $this->entities[$id] = $entity; } }