Reputation: 515
How to use a dynamic query on a custom field type ? What I mean by that:
I want to create a custom Entity Type form field which lists all the my supplier
entities ... but, I want that custom form field to have an additional option byStatus
. That option should then be used ( if set ) to set the query_builder
option in order to retrieve only the suppliers where the status is equal to the byStatus
option.
So here is my SupplierType:
class SupplierType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'class' => 'AppBundle:Supplier',
'byStatus' => 1,
'query_builder' => function (EntityRepository $er) {
$q = $er->createQueryBuilder('s')
->orderBy('s.name', 'ASC')
->andWhere('s.status = :status')
->setParameter('status', ????);
return $q;
}
));
}
public function getParent()
{
return EntityType::class;
}
}
So how can I replace the ????
by the byStatus
option value.
And of course it should be possible to change the byStatus
option when using the field type.
Like so:
$formMapper->add('supplier', SupplierType::class, [
'byStatus' => -1,
]);
Upvotes: 1
Views: 1846
Reputation: 515
Ok, I found it. Actually very easy:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'class' => 'AppBundle:Supplier',
'byStatus' => 1,
));
$resolver->setDefault('query_builder', function (Options $options) {
return function (EntityRepository $er) use ($options) {
return $er->createQueryBuilder('s')
->orderBy('s.name', 'ASC')
->andWhere('s.status = :status')
->setParameter('status', $options['byStatus']);
};
});
}
Upvotes: 2
Reputation: 17166
If you want to pass in the option from another field I recommend using the setNormalizers
as it allows you to pass in the options, i.e. other values, like this:
public function configureOptions(OptionsResolver $resolver)
{
// ... your setup without the query builder...
$resolver->setNormalizers([
'query_builder' => function (Options $options, $value) {
return function (EntityRepository $er) use ($options) {
return $er->createQueryBuilder('s')
->orderBy('s.name', 'ASC')
->andWhere('s.status = :status')
->setParameter('status', $options['byStatus'] ?? 1);
};
},
]);
}
See the docs for the OptionsResolver: https://symfony.com/doc/current/components/options_resolver.html#option-normalization
edit: I added the ?? 1
which will only work with PHP7+, but it provides some safety when the option was not set. Search for null coalesce operator in the php docs if you don't know what it is.
Upvotes: 1