feature #13990 [Form] Add flexibility for EntityType (raziel057)

This PR was submitted for the 2.7 branch but it was merged into the 2.8 branch instead (closes #13990).

Discussion
----------

[Form] Add flexibility for EntityType

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Sometimes it can be usefull to return null rather than a QueryBuilder from the closure attached to the ``query_builder`` attribute of an EntityType.

For example, if I have the following method in a "DelegateRepository", which can return a QueryBuilder or null:

```php
public function getQbForOfficers()
{
    $permanentMeeting = $this->getEntityManager()->getRepository('MyBundle:PermanentMeeting')->findOneBy(array());

    if ($permanentMeeting === null || $permanentMeeting->getMeeting() === null) {
        return null;
    }

    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->select('p')
        ->from('MyBundle:Delegate', 'p')
        ->andWhere('p.meeting = :meetingId')
        ->setParameter('meetingId', $permanentMeeting->getMeeting()->getId());

    return $qb;
}
```

To be able to present a list without entries when creating an entity field like this:

```php
$event->getForm()->add('officers', 'entity', array(
	'class' => 'MyBundle:Delegate',
	'property' => 'fullName',
	'query_builder' => function(EntityRepository $er) use ($meeting, $delegationId) {
	    return $er->getQbForOfficers();
	}
)));
```

Rather than using the "choices" attributes (more verbose and which requires the injection of the entityManager):

```php
$qb = $this->entityManager->getRepository('PTCNoventoBundle:Delegate')->getQbForOfficers();

$officers = ($qb !== null) ? $qb->getQuery()->getResult() : array();

$event->getForm()->add('officers', 'entity', array(
	'class' => 'PTCNoventoBundle:Delegate',
	'property' => 'fullName',
	'choices' => $officers,
));
```

Commits
-------

e0a1294 [Form] Add flexibility for EntityType
This commit is contained in:
Fabien Potencier 2015-08-01 14:00:55 +02:00
commit 317d30b6ef
2 changed files with 23 additions and 2 deletions

View File

@ -30,7 +30,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
*
* This property should only be accessed through queryBuilder.
*
* @var QueryBuilder
* @var QueryBuilder|null
*/
private $queryBuilder;
@ -68,7 +68,7 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
$queryBuilder = $queryBuilder($manager->getRepository($class));
if (!$queryBuilder instanceof QueryBuilder) {
if (null !== $queryBuilder && !$queryBuilder instanceof QueryBuilder) {
throw new UnexpectedTypeException($queryBuilder, 'Doctrine\ORM\QueryBuilder');
}
}
@ -81,6 +81,10 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
*/
public function getEntities()
{
if (null === $this->queryBuilder) {
return array();
}
return $this->queryBuilder->getQuery()->execute();
}
@ -89,6 +93,10 @@ class ORMQueryBuilderLoader implements EntityLoaderInterface
*/
public function getEntitiesByIds($identifier, array $values)
{
if (null === $this->queryBuilder) {
return array();
}
$qb = clone ($this->queryBuilder);
$alias = current($qb->getRootAliases());
$parameter = 'ORMQueryBuilderLoader_getEntitiesByIds_'.$identifier;

View File

@ -212,6 +212,19 @@ class EntityTypeTest extends TypeTestCase
$field->submit('2');
}
public function testConfigureQueryBuilderWithClosureReturningNull()
{
$field = $this->factory->createNamed('name', 'entity', null, array(
'em' => 'default',
'class' => self::SINGLE_IDENT_CLASS,
'query_builder' => function () {
return null;
},
));
$this->assertEquals(array(), $field->createView()->vars['choices']);
}
public function testSetDataSingleNull()
{