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中更改了别名。给你。非常感谢你的帮助。