Source of file EntityChoiceList.php
Size: 12,474 Bytes - Last Modified: 2013-07-17T08:22:21+02:00
/home/theseer/Downloads/Symfony/vendor/symfony/symfony/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityChoiceList.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 | <?php /* * This file is part of the Symfony package. * * (c) Fabien Potencier <fabien@symfony.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Bridge\Doctrine\Form\ChoiceList; use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\Exception\StringCastException; use Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList; use Doctrine\Common\Persistence\ObjectManager; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; /** * A choice list presenting a list of Doctrine entities as choices * * @author Bernhard Schussek <bschussek@gmail.com> */ class EntityChoiceList extends ObjectChoiceList { /** * @var ObjectManager */ private $em; /** * @var string */ private $class; /** * @var \Doctrine\Common\Persistence\Mapping\ClassMetadata */ private $classMetadata; /** * Contains the query builder that builds the query for fetching the * entities * * This property should only be accessed through queryBuilder. * * @var EntityLoaderInterface */ private $entityLoader; /** * The identifier field, if the identifier is not composite * * @var array */ private $idField = null; /** * Whether to use the identifier for index generation * * @var Boolean */ private $idAsIndex = false; /** * Whether to use the identifier for value generation * * @var Boolean */ private $idAsValue = false; /** * Whether the entities have already been loaded. * * @var Boolean */ private $loaded = false; /** * The preferred entities. * * @var array */ private $preferredEntities = array(); /** * Creates a new entity choice list. * * @param ObjectManager $manager An EntityManager instance * @param string $class The class name * @param string $labelPath The property path used for the label * @param EntityLoaderInterface $entityLoader An optional query builder * @param array $entities An array of choices * @param array $preferredEntities An array of preferred choices * @param string $groupPath A property path pointing to the property used * to group the choices. Only allowed if * the choices are given as flat array. * @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths. */ public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = 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(); if (1 === count($identifier)) { $this->idField = $identifier[0]; $this->idAsValue = true; if (in_array($this->classMetadata->getTypeOfField($this->idField), array('integer', 'smallint', 'bigint'))) { $this->idAsIndex = true; } } if (!$this->loaded) { // Make sure the constraints of the parent constructor are // fulfilled $entities = array(); } parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, null, $propertyAccessor); } /** * Returns the list of entities * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getChoices() { if (!$this->loaded) { $this->load(); } return parent::getChoices(); } /** * Returns the values for the entities * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getValues() { if (!$this->loaded) { $this->load(); } return parent::getValues(); } /** * Returns the choice views of the preferred choices as nested array with * the choice groups as top-level keys. * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getPreferredViews() { if (!$this->loaded) { $this->load(); } return parent::getPreferredViews(); } /** * Returns the choice views of the choices that are not preferred as nested * array with the choice groups as top-level keys. * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getRemainingViews() { if (!$this->loaded) { $this->load(); } return parent::getRemainingViews(); } /** * Returns the entities corresponding to the given values. * * @param array $values * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getChoicesForValues(array $values) { if (!$this->loaded) { // Optimize performance in case we have an entity loader and // a single-field identifier if ($this->idAsValue && $this->entityLoader) { if (empty($values)) { return array(); } return $this->entityLoader->getEntitiesByIds($this->idField, $values); } $this->load(); } return parent::getChoicesForValues($values); } /** * Returns the values corresponding to the given entities. * * @param array $entities * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getValuesForChoices(array $entities) { if (!$this->loaded) { // Optimize performance for single-field identifiers. We already // know that the IDs are used as values // Attention: This optimization does not check choices for existence if ($this->idAsValue) { $values = array(); foreach ($entities as $entity) { if ($entity instanceof $this->class) { // Make sure to convert to the right format $values[] = $this->fixValue(current($this->getIdentifierValues($entity))); } } return $values; } $this->load(); } return parent::getValuesForChoices($entities); } /** * Returns the indices corresponding to the given entities. * * @param array $entities * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getIndicesForChoices(array $entities) { if (!$this->loaded) { // Optimize performance for single-field identifiers. We already // know that the IDs are used as indices // Attention: This optimization does not check choices for existence if ($this->idAsIndex) { $indices = array(); foreach ($entities as $entity) { if ($entity instanceof $this->class) { // Make sure to convert to the right format $indices[] = $this->fixIndex(current($this->getIdentifierValues($entity))); } } return $indices; } $this->load(); } return parent::getIndicesForChoices($entities); } /** * Returns the entities corresponding to the given values. * * @param array $values * * @return array * * @see Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface */ public function getIndicesForValues(array $values) { if (!$this->loaded) { // Optimize performance for single-field identifiers. // Attention: This optimization does not check values for existence if ($this->idAsIndex && $this->idAsValue) { return $this->fixIndices($values); } $this->load(); } return parent::getIndicesForValues($values); } /** * Creates a new unique index for this entity. * * If the entity has a single-field identifier, this identifier is used. * * Otherwise a new integer is generated. * * @param mixed $entity The choice to create an index for * * @return integer|string A unique index containing only ASCII letters, * digits and underscores. */ protected function createIndex($entity) { if ($this->idAsIndex) { return $this->fixIndex(current($this->getIdentifierValues($entity))); } return parent::createIndex($entity); } /** * Creates a new unique value for this entity. * * If the entity has a single-field identifier, this identifier is used. * * Otherwise a new integer is generated. * * @param mixed $entity The choice to create a value for * * @return integer|string A unique value without character limitations. */ protected function createValue($entity) { if ($this->idAsValue) { return (string) current($this->getIdentifierValues($entity)); } return parent::createValue($entity); } /** * {@inheritdoc} */ protected function fixIndex($index) { $index = parent::fixIndex($index); // If the ID is a single-field integer identifier, it is used as // index. Replace any leading minus by underscore to make it a valid // form name. if ($this->idAsIndex && $index < 0) { $index = strtr($index, '-', '_'); } return $index; } /** * Loads the list with entities. */ private function load() { if ($this->entityLoader) { $entities = $this->entityLoader->getEntities(); } else { $entities = $this->em->getRepository($this->class)->findAll(); } try { // The second parameter $labels is ignored by ObjectChoiceList parent::initialize($entities, array(), $this->preferredEntities); } catch (StringCastException $e) { throw new StringCastException(str_replace('argument $labelPath', 'option "property"', $e->getMessage()), null, $e); } $this->loaded = true; } /** * Returns the values of the identifier fields of an entity. * * Doctrine must know about this entity, that is, the entity must already * be persisted or added to the identity map before. Otherwise an * exception is thrown. * * @param object $entity The entity for which to get the identifier * * @return array The identifier values * * @throws RuntimeException If the entity does not exist in Doctrine's identity map */ private function getIdentifierValues($entity) { if (!$this->em->contains($entity)) { throw new RuntimeException( 'Entities passed to the choice field must be managed. Maybe ' . 'persist them in the entity manager?' ); } $this->em->initializeObject($entity); return $this->classMetadata->getIdentifierValues($entity); } } |