Skip to content

Commit

Permalink
QueryBuilder in CarCollectionDataProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
Aymeric Ratinaud committed Jul 3, 2021
1 parent 26560aa commit 4d8d22a
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 1 deletion.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Inspired from https://github.com/api-platform/demo

There is tree examples in this repo
There is four examples in this repo

## First Example use raw data from a csv file

Expand Down Expand Up @@ -52,6 +52,22 @@ The param `order` can be `title` or `id` and ordered by `asc|desc`. The paginati
data provider using repository (by group from normalization_context on Movie entity)
`api/movies/custom-action-using-dataprovider?page=2&order[title]=desc&isPublished=false`

## Fourth example use QueryBuilder in CarCollectionDataProvider

This example show how use queryBuilder in CarCollectionDataProvider and filter by color. The pagination is available

### Usage

`/api/cars?color=color_name`

#### Color name available

- red
- orange
- green
- yellow
- black

## Install

composer install
Expand Down
4 changes: 4 additions & 0 deletions fixtures/car.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
App\Entity\Car:
movie_{1..1000}:
name: <word(10, 700)>
color: '<randomElement( ["red", "orange", "green", "yellow", "black"] )>'
52 changes: 52 additions & 0 deletions src/DataProvider/CarCollectionDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace App\DataProvider;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Car;
use Doctrine\Persistence\ManagerRegistry;

final class CarCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;
private $paginationExtension;

public function __construct(ManagerRegistry $managerRegistry, PaginationExtension $paginationExtension)
{
$this->managerRegistry = $managerRegistry;
$this->paginationExtension = $paginationExtension;
}

public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Car::class === $resourceClass;
}

public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
{
$queryBuilder = $this->managerRegistry
->getManagerForClass($resourceClass)
->getRepository($resourceClass)->createQueryBuilder('c');

if (isset($context['filters']['color'])) {
$queryBuilder
->where('c.color = :color')
->setParameter('color', $context['filters']['color'])
;
}

$this->paginationExtension->applyToCollection($queryBuilder, new QueryNameGenerator(), $resourceClass, $operationName, $context);

if ($this->paginationExtension instanceof QueryResultCollectionExtensionInterface &&
$this->paginationExtension->supportsResult($resourceClass, $operationName, $context)) {
return $this->paginationExtension->getResult($queryBuilder, $resourceClass, $operationName, $context);
}

return $queryBuilder->getQuery()->getResult();

}
}
60 changes: 60 additions & 0 deletions src/Entity/Car.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\CarRepository;
use Doctrine\ORM\Mapping as ORM;

/**
* @ApiResource()
* @ORM\Entity(repositoryClass=CarRepository::class)
*/
class Car
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

/**
* @ORM\Column(type="string", length=255)
*/
private $name;

/**
* @ORM\Column(type="string", length=255)
*/
private $color;

public function getId(): ?int
{
return $this->id;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(string $name): self
{
$this->name = $name;

return $this;
}

public function getColor(): ?string
{
return $this->color;
}

public function setColor(string $color): self
{
$this->color = $color;

return $this;
}
}
50 changes: 50 additions & 0 deletions src/Repository/CarRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Repository;

use App\Entity\Car;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @method Car|null find($id, $lockMode = null, $lockVersion = null)
* @method Car|null findOneBy(array $criteria, array $orderBy = null)
* @method Car[] findAll()
* @method Car[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CarRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Car::class);
}

// /**
// * @return Car[] Returns an array of Car objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->orderBy('c.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/

/*
public function findOneBySomeField($value): ?Car
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

0 comments on commit 4d8d22a

Please # to comment.