Skip to content

Latest commit

 

History

History
149 lines (117 loc) · 3.67 KB

simple-example.md

File metadata and controls

149 lines (117 loc) · 3.67 KB

Get started:

composer require atlance/http-doctrine-orm-filter

Register as service:

# config/services.yaml
services:
# > Cache -------------------------------------------------------------------
    memcached:
        class: \Memcached
        arguments: ['memcached']
        calls: [[ addServer, ['memcached', 11211]]]
# < Cache -------------------------------------------------------------------

# > Http Doctrine Filter ----------------------------------------------------
    filter.cache_adapter:
        class: Symfony\Component\Cache\Adapter\MemcachedAdapter
        arguments: ['@memcached', 'orm_filter_namespace']

    filter.cache:
        class: Doctrine\Common\Cache\Psr6\DoctrineProvider
        factory: ['Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap']
        arguments: ['@filter.cache_adapter']

    Atlance\HttpDoctrineOrmFilter\Filter:
        arguments: ['@validator', '@filter.cache']
# < Http Doctrine Filter ----------------------------------------------------

Entity validation annotations:

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Table(name="any")
 * @ORM\Entity(repositoryClass="App\Repository\AnyRepository")
 */
class Any
{
    /**
     * @var int
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     *
     * @Assert\Type(type="integer", groups={"any"})
     */
    private $id;
}

DI Service(autowiring) and prepare the join aliases before filtering:

<?php

namespace App\Fetcher;

use App\Entity\AnyEntity;
use App\Entity\FooEntity;
use App\Entity\BarEntity;
use App\Entity\BazEntity;
use Atlance\HttpDoctrineOrmFilter\Dto\Configuration;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\Expr\Join;
use Knp\Component\Pager\Pagination\PaginationInterface;

final class AnyFetcher
{
    public function __construct(
        private EntityManagerInterface $em,
        private Filter $filter,
        private PaginatorInterface $paginator
    ) {
    }

    public function list(array $conditions, int $page, int $size): PaginationInterface
    {
        $qb = $this->em->createQueryBuilder();
        $qb->select(['any'])
            ->from(AnyEntity::class, 'any')
            ->leftJoin(FooEntity::class, 'foo', Join::WITH)
            ->leftJoin(BarEntity::class, 'bar', Join::WITH)
            ->leftJoin(BazEntity::class, 'baz', Join::WITH)
        ;

        $this->filter->apply($qb, new Configuration($conditions));

        return $this->paginator->paginate($qb, $page, $size);
    }
}

Use case:

<?php

declare(strict_types=1);

namespace App\Controller;

use App\Fetcher\AnyFetcher;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

#[Route(path: '/list', name: self::class)]
class ListController extends AbstractController
{
    public function __invoke(Request $request, AnyFetcher $fetcher): Response
        {
            return $this->render('any-template.html.twig', [
                'items' => $fetcher->list(
                    $request->query->all(),
                    $request->query->getInt('page', 1),
                    $request->query->getInt('limit', 20)
                ),
            ]);
        }
}

request: http://localhost/any?filter[eq][any_id]=1|2&order[any_id]=asc

where:
filter - Filter::select argument.
[eq] - qb query alias.
[any - join/from table dql alias.
id] - table column name.
order - Filter::order argument

this http request equivalent sql: WHERE any.id = 1 OR any.id = 2 ORDER BY any.id ASC

other here