Php 如何在Api平台中按链接属性筛选结果?

Php 如何在Api平台中按链接属性筛选结果?,php,symfony,doctrine-orm,symfony4,api-platform.com,Php,Symfony,Doctrine Orm,Symfony4,Api Platform.com,我有一个用户实体和一个组织实体,在预订和用户之间有一个关系manytone: /** * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="bookings") * @ORM\JoinColumn(nullable=false) */ private $user; 用户实体有一个名为country的属性。我想将预订设置为仅显示与登录用户所在国家/地区相同的用户所做的记录。这就是我试过的 collectionOperati

我有一个
用户
实体和一个
组织
实体,在
预订
用户
之间有一个关系
manytone

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="bookings")
 * @ORM\JoinColumn(nullable=false)
 */
private $user;
用户
实体有一个名为country的属性。我想将预订设置为仅显示与登录用户所在国家/地区相同的用户所做的记录。这就是我试过的

collectionOperations={
*          "get"={
*              "access_control"="object.getUser().getOrganisation() == user.organisation"
*              "normalization_context"={
*                  "groups"={"read"}
*              }
*          },
当然,这是行不通的

我知道我可以过滤查询字符串中传递的参数,但我需要在API端而不是客户端对这些结果进行过滤。

屏幕上显示:

必须直接在数据提供程序级别根据当前用户的角色或权限筛选集合。例如,当使用ORM、MongoDB和ElasticSearch的内置适配器时,从集合中删除条目应该使用扩展来完成

现在,您需要执行以下操作:

final class BookingOwnerExtension implements QueryCollectionExtensionInterface
{
    private $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
    {
        if (Booking::class !== $resourceClass || $this->security->isGranted('ROLE_ADMIN') || null === $user = $this->security->getUser()) {
            return;
        }

        $organization = $user->getOrganization()

        $rootAlias = $queryBuilder->getRootAliases()[0];
        $queryBuilder
            ->leftJoin(sprintf('%s.user', $rootAlias), 'u')
            ->andWhere('user.organization = :organization')
            ->setParameter('organization', $organization);
    }
}
(确切的查询将取决于您打算做什么,因为我不熟悉您的应用程序,我只能为您指出正确的方向。但这只是使用查询生成器向查询添加适当的条件)

这很可能就足够了,但如果您不使用自动配置,则必须使用适当的标记注册自定义扩展:

# api/config/services.yaml
services:
    # ...

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

谢谢@yivi,现在我明白了这个过程。如果我按“%s.user=:user”进行筛选,它会工作,它只返回该用户插入的记录。如果我尝试按“%s.user.organization=:organization”进行筛选,则会得到一个错误“Class App\\Entity\\Booking没有名为user.organization的字段或关联”。知道为什么吗?是的,这主要是一个条令/查询生成器问题,有点超出了这个问题的范围。我上面的代码几乎是伪代码,因为我不知道数据库模式是如何工作的(这里的问题不是“如何编写条令查询”)。但基本上,您可能需要在预订和用户之间添加一个左连接,并在该级别中应用where。我将添加一些通用代码,但最终的设计必须由您自己完成。这只是告诉你如何在Api平台上完成这个过滤,这里真正的问题是,它能按预期工作。刚在用户的andWhere中更改了别名。给你。非常感谢你的帮助。