Warm tip: This article is reproduced from serverfault.com, please click

symfony-如何在我的自定义数据提供程序上注入api-plaform的分页过滤器

(symfony - How to inject api-plaform's pagination filter on my custom dataprovider)

发布于 2019-07-13 10:33:31

我正在使用symfony4开发一个应用程序,其中使用的是api平台。我已经为特定实体(例如Car)创建了一个自定义数据提供程序。CarCollectionDataProvider返回所有蓝色汽车。

<?php

namespace App\DataProvider;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Car;
use Doctrine\Common\Persistence\ManagerRegistry;
use Generator;

final class CarCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
    private $managerRegistry;
    private $paginationExtenstion;

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

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

    public function getCollection(string $resourceClass, string $operationName = null): Generator
    {
        $queryBuilder = $this->managerRegistry
            ->getManagerForClass($resourceClass)
            ->getRepository($resourceClass)->createQueryBuilder('car')
            ->where('car.color = :color')
            ->setParameter('color', 'blue');

        $this->paginationExtenstion->applyToCollection($queryBuilder, new QueryNameGenerator(), $resourceClass, $operationName, []);

        yield $this->paginationExtenstion->getResult($queryBuilder, $resourceClass, $operationName, []);
    }
}

如何在自定义数据提供程序(CarCollectionDataProvider)上注入api平台的分页扩展名?

Questioner
walidtlili
Viewed
0
MetaClass 2020-12-02 21:50:56

如果你只想向所有资源的所有收集操作查询中添加-> where('car.color =:color')这样的标准,则自定义扩展会更合适,并且可以使用默认的分页(和过滤器) ):

// api/src/Doctrine/CarCollectionExtension.php

namespace App\Doctrine;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use App\Entity\Car;
use Doctrine\ORM\QueryBuilder;

final class CarCollectionExtension implements QueryCollectionExtensionInterface
{
    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
    {
        if ($resourceClass != Car::class) return;

         $rootAlias = $queryBuilder->getRootAliases()[0];
         $queryBuilder->andWhere($rootAlias. '.color = :color');
         $queryBuilder->setParameter('color', 'blue');
    }
}

你可以通过在if语句中添加类似以下内容的方法来使此扩展特定于某个操作:

|| $operationName == 'get_blue'

来自docs)如果你未使用自动配置,则必须注册自定义扩展名:

# api/config/services.yaml
services:

    # ...

    'App\Doctrine\CarCollectionExtension':
        tags:
            - { name: api_platform.doctrine.orm.query_extension.collection }

如果你还想为项目操作添加条件,请参阅扩展上的文档