Фильтр свойств ApiPlatform Regex с Postgresql - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь добавить пользовательский фильтр к объекту в моем проекте ApiPlatform, который позволяет мне фильтровать по заданному c свойству с учетом шаблона регулярного выражения.

Следуя документации ApiPlatform, я придумал следующий класс (это почти копия их примера, отличается только предложение where):

<?php

namespace App\Filter;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Doctrine\ORM\QueryBuilder;

final class RegexFilter extends AbstractContextAwareFilter
{
    protected function filterProperty(
        string $property,
        $value,
        QueryBuilder $queryBuilder,
        QueryNameGeneratorInterface $queryNameGenerator,
        string $resourceClass,
        string $operationName = null
    ) {
        // otherwise filter is applied to order and page as well
        if (
            !$this->isPropertyEnabled($property, $resourceClass) ||
            !$this->isPropertyMapped($property, $resourceClass)
        ) {
            return;
        }

        $parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters
        $queryBuilder
            ->andWhere(sprintf('(o.%s ~ :%s) = true', $property, $parameterName))
            ->setParameter($parameterName, $value);
    }

    // This function is only used to hook in documentation generators (supported by Swagger and Hydra)
    public function getDescription(string $resourceClass): array
    {
        if (!$this->properties) {
            return [];
        }

        $description = [];
        foreach ($this->properties as $property => $strategy) {
            $description["regexp_$property"] = [
                'property' => $property,
                'type' => 'string',
                'required' => false,
                'swagger' => [
                    'description' => 'Filter using a regex. This will appear in the Swagger documentation!',
                    'name' => 'Custom name to use in the Swagger documentation',
                    'type' => 'Will appear below the name in the Swagger documentation',
                ],
            ];
        }

        return $description;
    }
}

Когда я запускаю свой код, это приводит к следующему DQL:

SELECT o FROM App\Entity\Vehicle o WHERE (o.licensePlate ~ :licensePlate_p1) = true ORDER BY o.id ASC

Однако я не могу заставить Лексера понять символ тильды ~:

Doctrine\ORM\Query\QueryException
[Syntax Error] line 0, col 56: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '~'

Как я могу заставить Doctrine понять тильду?

1 Ответ

0 голосов
/ 19 февраля 2020

Оказывается, я был довольно близок, ответ simPod помог мне заполнить пробелы .

  • Я скопировал его пользовательскую функцию DQL и добавил ее в свою Doctrine конфигурацию yaml
  • В моем RegexFilter мне пришлось немного изменить предложение where:

    ->andWhere(sprintf('REGEX(o.%s, :%s) = true', $property, $parameterName))
    
...