PHPackages                             api-skeletons/doctrine-orm-querybuilder-filter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. api-skeletons/doctrine-orm-querybuilder-filter

ActiveLibrary

api-skeletons/doctrine-orm-querybuilder-filter
==============================================

Filter a QueryBuilder with filter\[fieldName|operator\]=value

2.0.1(2y ago)11.2k2MITPHPPHP ~7.4||^8.0

Since Oct 21Pushed 2y ago1 watchersCompare

[ Source](https://github.com/API-Skeletons/doctrine-orm-querybuilder-filter)[ Packagist](https://packagist.org/packages/api-skeletons/doctrine-orm-querybuilder-filter)[ RSS](/packages/api-skeletons-doctrine-orm-querybuilder-filter/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (7)Versions (2)Used By (0)

Doctrine ORM QueryBuilder Filter
================================

[](#doctrine-orm-querybuilder-filter)

[![Build Status](https://github.com/API-Skeletons/doctrine-orm-querybuilder-filter/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/API-Skeletons/doctrine-orm-querybuilder-filter/actions/workflows/continuous-integration.yml?query=branch%3Amain)[![Code Coverage](https://camo.githubusercontent.com/cc4041f5f32b506df17d47ba2d3cb0cdaccf6f35c7bf58945c5ce16598bed97b/68747470733a2f2f636f6465636f762e696f2f67682f4150492d536b656c65746f6e732f646f637472696e652d6f726d2d71756572796275696c6465722d66696c7465722f6272616e63682f6d61696e2f6772617068732f62616467652e737667)](https://codecov.io/gh/API-Skeletons/doctrine-orm-querybuilder-filter/branch/main)[![PHP Version](https://camo.githubusercontent.com/0149ac1d0ca006acb3678c3848257b218156c1d51d5fda3ff521bcc1d2422d24/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d372e34253743253743382e302532622d626c7565)](https://img.shields.io/badge/PHP-7.4%7C%7C8.0%2b-blue)[![Total Downloads](https://camo.githubusercontent.com/b677d1bf8dd47d0f1e904282944b55056a4691e66f8451f222d269ff0be50e30/68747470733a2f2f706f7365722e707567782e6f72672f6170692d736b656c65746f6e732f646f637472696e652d6f726d2d71756572796275696c6465722d66696c7465722f646f776e6c6f616473)](//packagist.org/packages/api-skeletons/doctrine-orm-querybuilder-filter)[![License](https://camo.githubusercontent.com/e8006e1d291fb11d72ef328e2d163c8140b7d943e4c9393783027790049b22d5/68747470733a2f2f706f7365722e707567782e6f72672f6170692d736b656c65746f6e732f646f637472696e652d6f726d2d71756572796275696c6465722d66696c7465722f6c6963656e7365)](//packagist.org/packages/api-skeletons/doctrine-orm-querybuilder-filter)

Apply filters to a QueryBuilder based on request parameters. Supports deep queries using joins. This repository is intened to apply query parameters to filter entity data.

Installation
------------

[](#installation)

Run the following to install this library using [Composer](https://getcomposer.org/):

```
composer require api-skeletons/doctrine-orm-querybuilder-filter
```

Quick Start
-----------

[](#quick-start)

```
use ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator;

$applicator = new Applicator($entityManager, Entity\User::class);
$queryBuilder = $applicator($_REQUEST['filter']);
```

Filters
-------

[](#filters)

The pattern for creating a filter is `filter[fieldName|operator]=value`This pattern is an easy way to define complex queries utilizing all the filtering capabilities of the QueryBuilder.

The following URL will provide a LIKE filter for a user's `name`:

```
http://localhost/api/user?filter[name|like]=John
```

These operators are supported:

- eq - equals. If no operator is specified then this is the default
- neq - does not equal
- gt - greater than
- gte - greater than or equals
- lt - less than
- lte - less than or equals
- between - between two values comma delmited e.g. `filter[id|between]=1,5`
- like - a fuzzy search which wraps the value in wildcards
- startswith - a `like` operator with a wildcard on the right
- endswith - a `like` operator with a wildcard on the left
- in - a list of values to match comma delmited e.g. `filter[id|in]=1,2,3]`
- notin - the opposite of an `in` operator
- isnull - any value is acceptable; the field will be checked for null
- isnotnull - the opposite of an `isNull` operator
- sort - sort the result on the field either `asc` or `desc`

You may use as many filters as you wish. Filters operate on the field names of the entity and on the association names. This allows you to filter on an assocaition. For instance, to filter a list of users by company where the id of the company is known and the Doctrine metadata is correct you may filter like this:

```
http://localhost/api/user?filter[company]=10
```

So even though there is not a field named company there is an association and that is filterable though this tool.

### Filtering on single entities

[](#filtering-on-single-entities)

The configuration of the Applicator allows you to enable assocaition filtering, but this is disabled by default. So, assuming the default setting, this is a complex filter on a single entity:

```
http://localhost/api/user?filter[company|neq]=15&filter[name]=John
```

### Filtering on the hierarcy of entities

[](#filtering-on-the-hierarcy-of-entities)

The configuration of the Applicator allows you to enable assocation filtering. This means you can filter the current entity based on fields with an association with the current entity and you may do so as deep as you wish.

In this example we'll pull user data based on their company by name:

```
http://localhost/api/user?filter[company][name|eq]=AAA
```

In this example we'll pull user data based on their company by company type by company type name:

```
http://localhost/api/user?filter[company][companyType][name|neq]=Consultant
```

Before you get too concerned about this ability remember you can modify the QueryBuilder after it has had filters applied to it so if you need to apply security settings that is supported.

### A note on sorting

[](#a-note-on-sorting)

While sorting isn't by strict definition a filter, it falls into the same context when requesting data. You can sort by multiple fields and you can sort across associations (if enabled). Sorting is prioritized left to right.

Use
---

[](#use)

This is the minimum required to use this library:

```
use ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator;

$applicator = (new Applicator($entityManager, Entity\User::class));
$queryBuilder = $applicator($_REQUEST['filter']);
```

This is an example of configuring the applicator with all possible options

```
use ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator;

$applicator = (new Applicator($entityManager, Entity\User::class))
    ->enableRelationships()
    ->removeOperator('like')
    ->setEntityAlias('user')
    ->setFieldAliases(['firstName' => 'name'])
    ->setFilterableFields(['id', 'name'])
    ;
$queryBuilder = $applicator($_REQUEST['filter']);

$entityAliasMap = $applicator->getEntityAliasMap();
```

After a QueryBuilder is returned with the filters applied to it you may modify it as desired before using it to fetch your result.

Real world Laravel example
--------------------------

[](#real-world-laravel-example)

In this example, data from the `Entity\Style` entity is returned using [HAL](https://github.com/API-Skeletons/laravel-hal) in a paginated response in a controller action.

```
use ApiSkeletons\Doctrine\QueryBuilder\Filter\Applicator;
use Doctrine\ORM\Tools\Pagination\Paginator;
use HAL;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

public function fetchAll(Request $request)
{
    $filter = $request->query()['filter'] ?? [];
    if (! is_array($filter)) {
        $filter = [];
    ]

    $page = (int) $request->query()['page'] ?? 1;
    if ($page < 1) {
        $page = 1;
    }

    $applicator = (new Applicator(app('em'), Entity\Style::class))
        ->enableRelationships(true);
    $queryBuilder = $applicator($filter);

    $paginator = new Paginator($queryBuilder);
    $paginator->getQuery()
        ->setFirstResult(25 * ($page - 1)) // Page is 0 indexed in query
        ->setMaxResults(25)
        ;

    $data = (new LengthAwarePaginator(iterator_to_array($paginator->getIterator()), $paginator->count(), 25))
        ->appends($request->query())
        ->withPath(route('api.style::fetchAll'))
        ;

    return HAL::paginate('style', $data)->toArray();
}
```

Configuration
-------------

[](#configuration)

Using the Applicator is strait-forward and many options for configuring it are available. Begin by creating the Applicator then run configuration functions:

```
$applicator = new Applicator($entityManager, Entity\Style::class);
```

### enableAssociations()

[](#enableassociations)

This configuration method turns on deep filtering by using the Doctrine metadata to traverse the ORM through existing joins to the target entity. This is only possible in a Doctrine installation with complete metadata and proper associations between entities defined in the metadata.

### removeOperator(string|array)

[](#removeoperatorstringarray)

If you want to disable any operator you may remove it. A good example is the `like` operator which could result in expensive queries.

### setEntityAlias(string)

[](#setentityaliasstring)

The default alias used when creating filters for the target entity in the QueryBuilder is `entity`. You may want to change this so you know the alias after the QueryBuilder is returned and you can add additional parameters to it.

### setFieldAliases(array)

[](#setfieldaliasesarray)

If you want the filter to alias a field instead of using the ORM field name (such as using naming strategies in hydrators) you may pass an array of `[alias => field]` values so mapping can be adjusted.

### setFilterableFields(array)

[](#setfilterablefieldsarray)

By default all fields on the target entity can be filtered. If you want to limit which fields your users can create filters for then pass those field names in this array.

### getEntityAliasMap()

[](#getentityaliasmap)

This method is for post-processing of the target entity. When users use deep filtering using `enableAssociations()` aliases are created for every entity joined to the original entity query. This method returns an array of `[alias => entityClass]` for all entities joined in the QueryBuilder.

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 76.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

935d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/49dd7d9dba889ac674b0da447d9c1e69d1128dc3ccbaef98ba83d6ee519fc2d6?d=identicon)[tom\_anderson](/maintainers/tom_anderson)

---

Top Contributors

[![TomHAnderson](https://avatars.githubusercontent.com/u/493920?v=4)](https://github.com/TomHAnderson "TomHAnderson (81 commits)")[![kaiqueCavalcanti](https://avatars.githubusercontent.com/u/34461821?v=4)](https://github.com/kaiqueCavalcanti "kaiqueCavalcanti (16 commits)")[![kiqcavalcanti](https://avatars.githubusercontent.com/u/53445199?v=4)](https://github.com/kiqcavalcanti "kiqcavalcanti (9 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/api-skeletons-doctrine-orm-querybuilder-filter/health.svg)

```
[![Health](https://phpackages.com/badges/api-skeletons-doctrine-orm-querybuilder-filter/health.svg)](https://phpackages.com/packages/api-skeletons-doctrine-orm-querybuilder-filter)
```

###  Alternatives

[sonata-project/entity-audit-bundle

Audit for Doctrine Entities

644989.8k1](/packages/sonata-project-entity-audit-bundle)[neos/flow

Flow Application Framework

862.0M451](/packages/neos-flow)[api-platform/doctrine-orm

Doctrine ORM bridge

243.1M39](/packages/api-platform-doctrine-orm)[neos/flow-development-collection

Flow packages in a joined repository for pull requests.

144179.3k3](/packages/neos-flow-development-collection)[pixelfederation/doctrine-resettable-em-bundle

Symfony bundle for decorating default entity managers using a resettable decorator.

20113.5k](/packages/pixelfederation-doctrine-resettable-em-bundle)[leapt/core-bundle

Symfony LeaptCoreBundle

2529.1k4](/packages/leapt-core-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
