有没有一种方法可以使用DTO将过滤器添加到自定义端点?

时间:2019-10-18 13:48:18

标签: filter dto api-platform.com

我有一个自定义端点(它执行一些自定义聚合),该端点的返回是DTO的集合。我想为我的api使用者添加一些过滤器摘要。这可能吗 ?你该怎么做?

总结:

  • 我有一个DTO(ApiResource,但未链接到学说或数据库)。
  • 我有一个自定义的GET端点,该端点返回DTO的集合(是否经过过滤)。
  • 我想向该端点添加过滤器提示。

我应该以某种方式修改hydra:search吗?

我试图在DTO上添加ApiFilters(就像我对实体所做的那样),但是ApiFilters链接到学说,因此它给了我以下错误:Call to a member function getClassMetadata() on null上的vendor/api-platform/core/src/Bridge/Doctrine/Common/PropertyHelperTrait.php

1 个答案:

答案 0 :(得分:0)

我遇到了相同的问题,为解决此问题,我创建了一个没有$this->isPropertyMapped部分的自定义过滤器。

我将ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\FilterExtension注入了我的收藏提供者,并应用了 $this->filterExtension->applyToCollection($qb, $queryNameGenerator, $resourceClass, $operationName, $context);以更改查询。

然后我只需要在dto对象中配置自定义过滤器

@ApiFilter(SearchFilter::class, properties={"columnName": "exact"})

<?php

declare(strict_types=1);

namespace App\ThirdParty\ApiPlatform\Filter;

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

final class SearchFilter extends AbstractContextAwareFilter
{

    protected function filterProperty(
        string $property,
        $value,
        QueryBuilder $queryBuilder,
        QueryNameGeneratorInterface $queryNameGenerator,
        string $resourceClass,
        string $operationName = null
    ): void {
        if (
            !$this->isPropertyEnabled($property, $resourceClass)
        ) {
            return;
        }

        $parameterName = $queryNameGenerator->generateParameterName($property);

        $rootAlias = $queryBuilder->getRootAliases()[0];

        $queryBuilder
            ->andWhere(sprintf('%s.%s = :%s', $rootAlias, $property, $parameterName))
            ->setParameter($parameterName, $value);
    }

    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' => 'description',
                    'name' => $property,
                    'type' => 'type',
                ],
            ];
        }

        return $description;
    }
}

相关问题