Skip to content

Commit

Permalink
[Form] Added the entity_id type (symfony#1946)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregwar committed Aug 12, 2011
1 parent a1810d6 commit 05a064a
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
@@ -0,0 +1,97 @@
<?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\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;
}
}

59 changes: 59 additions & 0 deletions src/Symfony/Bridge/Doctrine/Form/Type/EntityIdType.php
@@ -0,0 +1,59 @@
<?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\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';
}
}
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml
Expand Up @@ -58,6 +58,11 @@
<argument type="service" id="doctrine" />
</service>

<service id="form.type.entity_id" class="Symfony\Bridge\Doctrine\Form\Type\EntityIdType">
<tag name="form.type" alias="entity_id" />
<argument type="service" id="doctrine" />
</service>

<service id="doctrine.orm.configuration" class="%doctrine.orm.configuration.class%" abstract="true" public="false" />

<service id="doctrine.orm.entity_manager.abstract" class="%doctrine.orm.entity_manager.class%" factory-class="%doctrine.orm.entity_manager.class%" factory-method="create" abstract="true" />
Expand Down

1 comment on commit 05a064a

@zazzou
Copy link

@zazzou zazzou commented on 05a064a Mar 16, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi,
i have this error:
FatalErrorException: Compile Error: Declaration of Symfony\Bridge\Doctrine\Form\Type\EntityIdType::buildForm() must be compatible with Symfony\Component\Form\FormTypeInterface::buildForm(Symfony\Component\Form\FormBuilderInterface $builder, array $options) in C:\wamp\www\Symfony\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\Form\Type\EntityIdType.php line 59

Please sign in to comment.