po4e4ka-lib/symfony-filter

Filter for symfony orm with postgresql

dev-main 2023-06-27 10:26 UTC

This package is not auto-updated.

Last update: 2024-05-07 10:18:07 UTC


README

Библиотека фильтрации на уровне SQL (проверено только для Postgresql)

Данное расширение позволяет фильтровать запросы в базу по фильтрам.

Особенности:

  • Фильтрация по наименованиям колонок таблицы
  • Фильтрация по alias(имя после as) для колонок
  • Возможно сравнивать два поля между собой
  • Есть возможность добавлять limit и offset
  • Добавлена функция REGEXP для postgres
  • Добавлена возможность фильтрации по JSON ключам

Установка

  • Выполнить команду php composer require po4e4ka-lib/symfony-filter

Обновить файл service.yaml:

services:

    ...

    ElsaLib\SymfonyFilter\:
        resource: '../vendor/po4e4ka/symfony-filter/src/'
        public: true
        exclude:
            - '../vendor/po4e4ka/symfony-filter/src/RegexDqlPostgresFunction.php'
    ...

Обновить файл doctrine.yaml:

doctrine:
    orm:
        dql:
            string_functions:
                JSON_GET_TEXT: Scienta\DoctrineJsonFunctions\Query\AST\Functions\Postgresql\JsonGetText
                regexp: Po4e4ka\SymfonyFilter\RegexDqlPostgresFunction
        

Использование

Frontend:

Для подачи фильтра необходимо в запросе добавить queryParam, который является массивом кратный трём, где в каждой тройке:

  1. поле фильтрации
  2. оператор
  3. значение

Пример валидного запроса

https://api.test.test/api/building?limit=40&offset=0&filter[]=address&filter[]=~&filter[]=Руч&filter[]=city&filter[]==&filter[]=2

Здесь добавляется два фильтра. В базе это будет выглядеть как ... WHERE table_name.address ~ 'Руч' AND table_name.city = 2 ...

Доступные операторы: >, <, =, <=, >=, ~, <>, !=, is, is_not.

~ - выполняет функцию поиска подстроки в поле (regexp)

Backend:

Для использования фильтра необходимо инжектить класс Filtrate в свой Repository класс

use Po4e4ka\SymfonyFilter\Filtrate;

class MyRepository extends ServiceEntityRepository{
    private Filtrate $filtrate;

    public function __construct(Filtrate $filtrate)
    {
        $this->filtrate = $filtrate;
    }
...

Фильтр работает с уже готовым QueryBuilder объектом. Для использования фильтра, вам необходимо добавать его перед получением результата:

...

    public function getSomeData(int $buildingId, array $filters, ?int $limit, ?int $offset)
        {
            $qb = $this->createQueryBuilder('my_table_alias')
                ->where('my_table_alias.building = ' . $buildingId)
                ->orderBy('my_table_alias.id', 'DESC');
            $this->filtrate->filtrate($qb, $filters, $limit, $offset);
            return $qb->getQuery()->getResult();
        }

...