From 05a064a93ba0029357d734ba147fca22e11f8921 Mon Sep 17 00:00:00 2001 From: Gregwar Date: Fri, 12 Aug 2011 19:03:13 +0200 Subject: [PATCH] [Form] Added the entity_id type (#1946) --- .../OneEntityToIdTransformer.php | 97 +++++++++++++++++++ .../Doctrine/Form/Type/EntityIdType.php | 59 +++++++++++ .../DoctrineBundle/Resources/config/orm.xml | 5 + 3 files changed, 161 insertions(+) create mode 100755 src/Symfony/Bridge/Doctrine/Form/DataTransformer/OneEntityToIdTransformer.php create mode 100644 src/Symfony/Bridge/Doctrine/Form/Type/EntityIdType.php diff --git a/src/Symfony/Bridge/Doctrine/Form/DataTransformer/OneEntityToIdTransformer.php b/src/Symfony/Bridge/Doctrine/Form/DataTransformer/OneEntityToIdTransformer.php new file mode 100755 index 000000000000..125cf3a7d72d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Form/DataTransformer/OneEntityToIdTransformer.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Form\DataTransformer; + +use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\DataTransformerInterface; +use Symfony\Component\Form\FormError; +use Symfony\Component\Form\Exception\TransformationFailedException; +use Symfony\Component\Form\Exception\UnexpectedTypeException; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\NoResultException; + +class OneEntityToIdTransformer implements DataTransformerInterface +{ + private $em; + private $class; + private $queryBuilder; + + public function __construct(EntityManager $em, $class, $queryBuilder) + { + if (!(null === $queryBuilder || $queryBuilder instanceof \Closure)) { + throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder or \Closure'); + } + + if (null == $class) + throw new UnexpectedTypeException($class, 'string'); + + $this->em = $em; + $this->class = $class; + $this->queryBuilder = $queryBuilder; + } + + /** + * Fetch the id of the entity to populate the form + */ + public function transform($data) + { + if (null === $data) + return null; + + $meta = $this->em->getClassMetadata($this->class); + + if (!$meta->getReflectionClass()->isInstance($data)) + throw new TransformationFailedException('Invalid data, must be an instance of '.$this->class); + + $identifierField = $meta->getSingleIdentifierFieldName(); + $id = $meta->getReflectionProperty($identifierField)->getValue($data); + + return $id; + } + + /** + * Try to fetch the entity from its id in the database + */ + public function reverseTransform($data) + { + if (!$data) { + return null; + } + + $em = $this->em; + $class = $this->class; + $repository = $em->getRepository($class); + + if ($qb = $this->queryBuilder) { + // If a closure was passed, call id with the repository and the id + if ($qb instanceof \Closure) { + $qb = $qb($repository, $data); + } + + try { + $result = $qb->getQuery()->getSingleResult(); + } catch (NoResultException $e) { + $result = null; + } + } else { + // Defaults to find() + $result = $repository->find($data); + } + + if (!$result) + throw new TransformationFailedException('Can not find entity'); + + return $result; + } +} + diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/EntityIdType.php b/src/Symfony/Bridge/Doctrine/Form/Type/EntityIdType.php new file mode 100644 index 000000000000..9ab750fb3181 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Form/Type/EntityIdType.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Form\Type; + +use Symfony\Component\Form\FormBuilder; +use Symfony\Bridge\Doctrine\RegistryInterface; +use Symfony\Bridge\Doctrine\Form\DataTransformer\OneEntityToIdTransformer; +use Symfony\Component\Form\AbstractType; + +class EntityIdType extends AbstractType +{ + protected $em; + + public function __construct(RegistryInterface $registry) + { + $this->em = $registry->getEntityManager(); + } + + public function buildForm(FormBuilder $builder, array $options) + { + $em = $options['em'] ?: $this->em; + + $builder->prependClientTransformer(new OneEntityToIdTransformer($em, $options['class'], $options['query_builder'])); + } + + public function getDefaultOptions(array $options) + { + $defaultOptions = array( + 'required' => true, + 'em' => null, + 'class' => null, + 'query_builder' => null, + 'hidden' => true + ); + + $options = array_replace($defaultOptions, $options); + + return $defaultOptions; + } + + public function getParent(array $options) + { + return $options['hidden'] ? 'hidden' : 'field'; + } + + public function getName() + { + return 'entity_id'; + } +} diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml index 85e1e7153a81..9f0a108e9ea3 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -58,6 +58,11 @@ + + + + +