PHPackages                             studiomado/query-bundle - 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. [Database &amp; ORM](/categories/database)
4. /
5. studiomado/query-bundle

ActiveSymfony-bundle[Database &amp; ORM](/categories/database)

studiomado/query-bundle
=======================

v2.4.23(7y ago)137.6k4[12 issues](https://github.com/studiomado/query-bundle/issues)PHP

Since Aug 8Pushed 3y ago7 watchersCompare

[ Source](https://github.com/studiomado/query-bundle)[ Packagist](https://packagist.org/packages/studiomado/query-bundle)[ RSS](/packages/studiomado-query-bundle/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (3)Dependencies (11)Versions (106)Used By (0)

QueryBundle
===========

[](#querybundle)

latest stable version [![Latest Stable Version](https://camo.githubusercontent.com/63dbea3ee82ed927da1ad8c1a9d714806c805c2fde63fbfe5d29a5236879a670/68747470733a2f2f706f7365722e707567782e6f72672f73747564696f6d61646f2f71756572792d62756e646c652f76657273696f6e)](https://packagist.org/packages/studiomado/query-bundle)

2.4 (master)2.32.2[![Build Status](https://camo.githubusercontent.com/06e9e39a76f97c9cf14a027350a1846017e0e8f0bf58d7dd01a743390f330b3a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f6275696c642e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/studiomado/query-bundle/build-status/master)[![Build Status](https://camo.githubusercontent.com/72af668c2a8dad1b5bd974dd1b368eb58de682cc5f6d77612be6f9e7663a4df5/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f6275696c642e706e673f623d322e33)](https://scrutinizer-ci.com/g/studiomado/query-bundle/build-status/2.3)[![Build Status](https://camo.githubusercontent.com/ebe537cddb6e8906ee8b3a6b828cb9685f8f758bb027dec9cac08d87f99cda8e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f6275696c642e706e673f623d322e32)](https://scrutinizer-ci.com/g/studiomado/query-bundle/build-status/2.2)[![Code Coverage](https://camo.githubusercontent.com/e3c66b23b8539ea93dd6a518b20e105d334e6f7ab101a3b308ba474fdc619ddc/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/d0ef04b19ca3bcea2c454c6c632dae12aacc3d4c44d63e30f0127e55bcbbce7a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f636f7665726167652e706e673f623d322e33)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=2.3)[![Code Coverage](https://camo.githubusercontent.com/5729f27eef83030ef3bd2408b4ae76253901831f3e9b05e1b5046f95258798b0/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f636f7665726167652e706e673f623d322e32)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=2.2)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/d5359c99c786372bfd8d77f8e6590626dda060d94d3631c605ee2d1e340ce02c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=master)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/364f8e27bf0ed110a637b5d8a5ba16466a102ec4ae3c65c07b9e87ee16a7998b/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f7175616c6974792d73636f72652e706e673f623d322e33)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=2.3)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/047c052400d7d93b96669dc21094bd8a32eb91f8028aa9f1c2dd2297c7b60acd/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f73747564696f6d61646f2f71756572792d62756e646c652f6261646765732f7175616c6974792d73636f72652e706e673f623d322e32)](https://scrutinizer-ci.com/g/studiomado/query-bundle/?branch=2.2)Run tests
---------

[](#run-tests)

- `./runtests.sh` run all unit tests
- `./agile.sh` generate testdox documentation
- `./coverage.sh` generate and open html coverage

Plain symfony project for query-bundle
======================================

[](#plain-symfony-project-for-query-bundle)

The purpose of this project is to see how studiomado/query-bundle works and can be installed in a plain symfony project.

- database configuration
- install query-bundle
- create at least one entity

Database configuration
======================

[](#database-configuration)

Remember to update parameter.yml file, parameter.yml.dist and config.yml file. In config.yml file also remember that the drive MUST be changed in pdo\_sqlite to enable doctrine to work with this database.

This is just an example: for this example we use sqlite but in production you can use mysql or postgres or any other database supported by doctrine.

```
prompt> ./bin/console doctrine:database:create
Created database /path/to/project/var/data/data.sqlite for connection named default

```

Install query-bundle
====================

[](#install-query-bundle)

```
prompt> composer require studiomado/query-bundle

```

Create at least one entity
==========================

[](#create-at-least-one-entity)

Create at least one entity ...

```
prompt> ./bin/console doctrine:generate:entity

```

In this example I created an entity Task following command steps.

```
created ./src/AppBundle/Entity/
created ./src/AppBundle/Entity/Task.php
> Generating entity class src/AppBundle/Entity/Task.php: OK!
> > Generating repository class src/AppBundle/Repository/TaskRepository.php: OK!

```

... and update the schema ...

```
	prompt> ./bin/console doctrine:schema:update
	ATTENTION: This operation should not be executed in a production environment.
						 Use the incremental update to detect changes during development and use
						 the SQL DDL provided to manually update your database in production.

	The Schema-Tool would execute "1" queries to update the database.
	Please run the operation by passing one - or both - of the following options:
			doctrine:schema:update --force to execute the command
			doctrine:schema:update --dump-sql to dump the SQL statements to the screen

```

The schema update works only with force option

```
prompt> ./bin/console doctrine:schema:update --force
Updating database schema...
Database schema updated successfully! "1" query was executed

```

Just take a look of the database content (that now is simply empty).

```
prompt> ./bin/console doctrine:query:dql "select t from AppBundle:Task t"

```

The query will return an empty array of result

```
 array (size=0)
   empty

```

Just add first task ...

```
prompt> ./bin/console doctrine:query:sql "insert into task values (null, 'complete this guide', 'todo') "

```

and take a look of the content

```
prompt> ./bin/console doctrine:query:dql "select t from AppBundle:Task t"

array (size=1)
  0 =>
    object(stdClass)[507]
      public '__CLASS__' => string 'AppBundle\Entity\Task' (length=21)
      public 'id' => int 1
      public 'description' => string 'complete this guide' (length=19)
      public 'status' => string 'todo' (length=4)

```

Complete installation
=====================

[](#complete-installation)

First of all install vendors

```
prompt> composer require jms/serializer-bundle
prompt> composer require willdurand/hateoas-bundle
prompt> composer require white-october/pagerfanta-bundle
prompt> composer require friendsofsymfony/rest-bundle

```

and then, … add vendors in your app/AppKernel

```
new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle(),
new Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle(),

```

Complete configuration and use the bundle
=========================================

[](#complete-configuration-and-use-the-bundle)

Once everything is done, you can add new endpoints using the query-bundle to query the database.

```
namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DefaultController extends Controller
{
    /** @Route("/", name="homepage") */
    public function indexAction(
        Request $request,
        \Doctrine\ORM\EntityManager $em,
        \JMS\Serializer\Serializer $serializer
    ) {
        $data = $em->getRepository('AppBundle:Task')
            ->setRequest($request)
            ->findAllPaginated();

        $content = $serializer->serialize($data, 'json');

        return new Response($content, 200);
    }
}

```

Configure your entity repository
================================

[](#configure-your-entity-repository)

Now be sure that your repository extends the right BaseRepository.

```
namespace AppBundle\Repository;

class TaskRepository extends \Mado\QueryBundle\Repositories\BaseRepository
{
    // to do …
}

```

```
namespace AppBundle\Entity;

/** @ORM\Entity(repositoryClass="AppBundle\Repository\TaskRepository") */
class Task
{
    // to do …
}

```

Customize entity serialization
==============================

[](#customize-entity-serialization)

Now if you want to customize responses add

```
use JMS\Serializer\Annotation as JMS;

```

On top of your entities and complete your JMS configurations. See JMS documentation to get all the complete documentation.

Here some examples:

- [http://127.0.0.1:8000/?filtering\[status\]=todo](http://127.0.0.1:8000/?filtering%5Bstatus%5D=todo)
- [http://127.0.0.1:8000/?filtering\[status|contains\]=od](http://127.0.0.1:8000/?filtering%5Bstatus%7Ccontains%5D=od)
- [http://127.0.0.1:8000/?filtering\[status|endswith\]=gress](http://127.0.0.1:8000/?filtering%5Bstatus%7Cendswith%5D=gress)

Find All No Paginated
=====================

[](#find-all-no-paginated)

Added a new method in **BaseRepository**
When you need results applying filter and sort without pagination

```
public function findAllNoPaginated();

```

This feature was needed to create an Excel Report, injecting results into the Excel Report

Example without pagination
--------------------------

[](#example-without-pagination)

In Controller:

```
public function getTasksExcelReportAction(Request $request)
    {
        $tasks = $this->getDoctrine()
            ->getRepository('AppBundle:Task')
            ->findAllNoPaginated();

        $reportExcel = new TasksReport($tasks);
        $reportExcel->createReport();

        $excelContent = $reportExcel->printReport();

        return new Response(
            $excelContent,
            200, [
                'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            ]
        );
    }

```

Example with pagination
-----------------------

[](#example-with-pagination)

In Controller:

```
    public function getTasksAction(Request $request)
    {
        return $this->getDoctrine()
            ->getRepository('AppBundle:Task')
            ->setRequest($request)
            ->findAllPaginated();
    }

```

Queries
=======

[](#queries)

AND Conditions
--------------

[](#and-conditions)

If you want to create an AND condition with this library you can create it from the client for example with a simple GET request like this:

```
/api/foo?filtering[name|eq]=bar&filtering[surname|eq]=bar

```

This request will produce a query like this:

```
SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2" .
FROM foo f0_" .
WHERE f0_.name = "bar" AND f0_.surname = "bar"

```

OR Conditions
-------------

[](#or-conditions)

If you want to create an OR condition with this library you can create it from the client for example with a simple GET request like this:

```
/api/foo?filtering_or[name|eq]=bar&filtering_or[surname|eq]=bar

```

This request will produce a query like this:

```
SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2" .
FROM foo f0_" .
WHERE ((f0_.name = "bar" OR f0_.surname = "bar"))

```

Instead, if you want to have more OR conditions separated you can do something like this:

```
/api/foo?filtering_or[name|eq|1]=bar&filtering_or[surname|eq|1]=bar&filtering_or[group|contains|2]=baz&filtering_or[role|contains|2]=baz

```

This request will produce a query like this:

```
SELECT f0_.id AS id_0, f0_.name AS name_1, f0_.surname AS surname_2, f0_.group AS group_3, f0_.role AS role_4" .
FROM foo f0_" .
WHERE (f0_.name = "bar" OR f0_.surname = "bar") AND (f0_.group LIKE "%baz%" OR f0_.role LIKE "%baz%")

```

This can be done by using a counter after the operator separated by `|`

Search into relations
---------------------

[](#search-into-relations)

If you want to search inside an entity where a condition is inside another entity you can do this:

```
/api/users?filtering[_embedded.group.name|contains =bar

```

This request will produce a query like this:

```
SELECT u0_.id AS id_0 u0_.username AS username_1,  u0_.group_id AS group_id_2 " .
FROM User u0_
LEFT JOIN Group g1_ ON u0_.group_id = g1_.id " .
WHERE g1_.name LIKE "%bar%"

```

To do this you need to add inside the user entity some Hateoas annotations like this:

```
 * @Hateoas\Relation(
 *     "groups",
 *     embedded = @Hateoas\Embedded(
 *         "expr(object.getGroups())",
 *          exclusion = @Hateoas\Exclusion(
 *              excludeIf = "expr(object.getGroups().isEmpty() === true)",
 *              groups={"groups"},
 *              maxDepth = 1
 *          )
 *     ),
 *     exclusion = @Hateoas\Exclusion(
 *              excludeIf = "expr(object.getGroups().isEmpty() === true)",
 *              groups={"groups"},
 *              maxDepth = 1
 *          )
 * )

```

If you add Hateoas annotations correctly, you can search deeper than only "one level". Here an example:

```
/api/users?filtering[_embedded.profile.location.country.name|contains]=italy

```

In this example you search all users that have a profile with a country location name: Italy.
Profile, location and country are entities and name is the field.

You can use \_embedded filter also into filtering\_or conditions.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance2

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 71.9% 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

Every ~19 days

Recently: every ~369 days

Total

100

Last Release

1365d ago

Major Versions

1.0.6 → v2.0.0-RC12017-09-18

2.4.x-dev → 3.0.x-dev2022-10-04

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/26791202?v=4)[Studio Mado](/maintainers/studiomado)[@studiomado](https://github.com/studiomado)

---

Top Contributors

[![sensorario](https://avatars.githubusercontent.com/u/820248?v=4)](https://github.com/sensorario "sensorario (335 commits)")[![AlessandroMinoccheri](https://avatars.githubusercontent.com/u/3356506?v=4)](https://github.com/AlessandroMinoccheri "AlessandroMinoccheri (125 commits)")[![orociscaverai](https://avatars.githubusercontent.com/u/300871?v=4)](https://github.com/orociscaverai "orociscaverai (4 commits)")[![sensomado](https://avatars.githubusercontent.com/u/30717685?v=4)](https://github.com/sensomado "sensomado (2 commits)")

---

Tags

databasedijkstradoctrinedoctrine2graphqlhateoasquery-builderrest-apisymfony

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/studiomado-query-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/studiomado-query-bundle/health.svg)](https://phpackages.com/packages/studiomado-query-bundle)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.5M378](/packages/easycorp-easyadmin-bundle)[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k246.0M11.1k](/packages/symfony-framework-bundle)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M196](/packages/sulu-sulu)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.4M526](/packages/shopware-core)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9417.2k58](/packages/open-dxp-opendxp)

PHPackages © 2026

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