Build a Symfony form dedicated to filtering an entity, then let the bundle turn it into Doctrine ORM query builder conditions.
📖 Full documentation: spiriitlabs.github.io/form-filter-bundle
The idea is:
- Create a form type extending
Symfony\Component\Form\AbstractType, as usual. - Add fields using the provided filter types (e.g.
TextFilterType::classinstead ofTextType::class). - Call
FilterBuilderUpdaterto build the query from the form instance, then execute it.
Any type works, but filtering on a type other than a XxxFilterType::class requires a
custom listener to apply the filter.
- Plain Symfony forms: no new DSL, your filters are regular form types with validation, theming and CSRF.
- Ready-to-use filter types: text, number, date and date range, boolean, choice, entity, enum and more.
- Composable conditions: AND/OR trees, embedded filters, collections and automatic joins.
- Fully customisable: override any field with a closure or a dedicated listener through
apply_filter. - Debuggable: the Symfony profiler shows which form field produced which DQL condition.
composer require spiriitlabs/form-filter-bundle| Requirement | Version |
|---|---|
| PHP | 8.1+ |
| Symfony | 5.4, 6.4, 7.4, 8.0 |
| Doctrine ORM | 3.0+ |
<?php
namespace Project\Form\Filter;
use Spiriit\Bundle\FormFilterBundle\Filter\Form\Type as Filters;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class RankFilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('name', Filters\TextFilterType::class);
$builder->add('rank', Filters\NumberFilterType::class);
}
}class DefaultController extends AbstractController
{
public function __invoke(
Request $request,
FormFactoryInterface $formFactory,
EntityManagerInterface $em,
FilterBuilderUpdater $filterBuilderUpdater,
): Response {
$form = $formFactory->create(RankFilterType::class);
$form->handleRequest($request);
$filterBuilder = $em->getRepository(MyEntity::class)->createQueryBuilder('e');
$filterBuilderUpdater->addFilterConditions($form, $filterBuilder);
// now look at the DQL =)
dump($filterBuilder->getDql());
return $this->render('testFilter.html.twig', ['form' => $form]);
}
}- Interactive demo: follow a filter from form to DQL
- Installation
- Basics
- Configuration
- Provided filter types
- Filter state persistence
- Debugging & profiler
- Pagination with Pagerfanta
- Live filtering with Turbo and Stimulus
Found a bug or missing a feature? Open an issue. Questions are welcome there too.
- Spiriit dev@spiriit.com
- All contributors
This bundle is under the MIT license. For the whole copyright, see the LICENSE file distributed with this source code.