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



我有一个User实体和一个Organisation实体,BookingUser之间有一个关系ManyToOne

/**
* @ORMManyToOne(targetEntity="AppEntityUser", inversedBy="bookings")
* @ORMJoinColumn(nullable=false)
*/
private $user;

User实体具有一个名为国家/地区的属性。我想将预订设置为仅显示与登录用户相同国家/地区的用户所做的记录。这就是我尝试过的

collectionOperations={
*          "get"={
*              "access_control"="object.getUser().getOrganisation() == user.organisation"
*              "normalization_context"={
*                  "groups"={"read"}
*              }
*          },

当然是行不通的。

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

在文档的"安全"页面上说:

根据当前用户的角色或权限筛选集合必须直接在数据提供程序级别完成。例如,当使用Doctrine 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:
# ...
'AppDoctrineBookingOwnerExtension':
tags:
- { name: api_platform.doctrine.orm.query_extension.collection }

最新更新