# Repository Query A Repository query is an abstraction of the doctrine repository. ## Requirement Entities must implements `App\Core\Entity\EntityInterface`. ```php-inline title="src/Entity/MyEntity.php" namespace App\Entity; use App\Repository\MyEntityRepository; use Doctrine\ORM\Mapping as ORM; use App\Core\Entity\EntityInterface; #[ORM\Entity(repositoryClass: MyEntityRepository::class)] class MyEntity implements EntityInterface { // ... } ``` ## Generation The generation is performed in CLI. These information are required: * The namespace of the repository (eg: `MyEntityRepository`) Simply run `php bin/console make:repository-query`. Each entity has its own repository query which is a service. ```php-inline title="src/Repository/MyEntityRepositoryQuery" namespace App\Repository; use App\Core\Repository\RepositoryQuery; use Knp\Component\Pager\PaginatorInterface; class MyEntityRepositoryQuery extends RepositoryQuery { public function __construct(MyEntityRepository $repository, PaginatorInterface $paginator) { parent::__construct($repository, 'm', $paginator); } // Example of custom filter public function filterByFooBar(bool $foo, bool $bar): self { $this ->andWhere('.foo = :foo') ->andWhere('.bar = :bar') ->setParameter(':foo', $foo) ->setParameter(':bar', $bar); return $this; } } ``` ## Usage You are able to find entities in an easy way, without knowing the identification variable and without creating a query builder. ```php-inline title="src/Controller/FooController.php" namespace App\Controller; use App\Repository\MyEntityRepositoryQuery use Symfony\Component\HttpFoundation\Response; class FooController { public function foo(MyEntityRepositoryQuery $query): Response { $entities = $query->create()->find(); $entity = $query->create()->findOne(); // Filtered and sorted entities $entities = $query->create() ->orderBy('.id', 'DESC') ->where('.isPublished = true') ->find(); // ... } } ``` ## Custom methods ```php-inline // ... class MyEntityRepositoryQuery extends RepositoryQuery { // ... public function filterByFooBar(bool $foo, bool $bar): self { $this ->andWhere('.foo = :foo') ->andWhere('.bar = :bar') ->setParameter(':foo', $foo) ->setParameter(':bar', $bar); return $this; } } ``` ```php-inline $entities = $query->create() ->filterByFoo($foo, $bar) ->find(); ``` In the context of a CRUD, filters are applied using [the method `useFilters`](https://gitnet.fr/murph/murph-core/src/branch/master/src/core/Repository/RepositoryQuery.php#L78-L99). Integers, strings and booleans are automatically processed. Other types are passed to [the method `filterHandler`](https://gitnet.fr/murph/murph-core/src/branch/master/src/core/Repository/RepositoryQuery.php#L122-L124). You have to override it to manage them, example: ```php-inline // ... use App\Entity\Something; class MyEntityRepositoryQuery extends RepositoryQuery { // ... public function filterHandler(string $name, $value): self { if ($name === 'something' && $value instanceof Something) { $this ->join('something', 's') ->andWhere('s.id = :something') ->setParameter('something', $value->getId()) ; } } } ``` You can also force `filterHandler` te be used for specific filter field: ```php-inline // ... class MyEntityRepositoryQuery extends RepositoryQuery { public function __construct(Repository $repository, PaginatorInterface $paginator) { // ... $this->addForcedFilterHandler('foo'); } public function filterHandler(string $name, $value): self { // ... if ($name === 'foo) { // ... } } } ``` ## Pager You can paginate entities (`Knp\Component\Pager\Pagination\PaginationInterface`): ```php-inline $pager = $query->create()->paginate($page, $maxPerPage); ```