如何通过 Api-Platform 中的链接 属性 过滤结果?
How to filter results by a linked property in Api-Platform?
我有一个 User
实体和一个 Organisation
实体,Booking
和 User
之间存在关系 ManyToOne
:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="bookings")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
User
实体有一个名为 属性 的国家/地区。我想将预订设置为仅显示与登录用户具有相同国家/地区的用户所做的记录。这是我试过的
collectionOperations={
* "get"={
* "access_control"="object.getUser().getOrganisation() == user.organisation"
* "normalization_context"={
* "groups"={"read"}
* }
* },
当然不行
我知道我可以过滤查询字符串中传递的参数,但我需要在 API 端而不是客户端过滤这些结果。
在 Security page of the docs 上说:
Filtering collections according to the role or permissions of the current user must be done directly at the data provider level. For instance, when using the built-in adapters for Doctrine ORM, MongoDB and ElasticSearch, removing entries from a collection should be done using extensions.
查看 extensions,您需要执行以下操作:
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 }
我有一个 User
实体和一个 Organisation
实体,Booking
和 User
之间存在关系 ManyToOne
:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="bookings")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
User
实体有一个名为 属性 的国家/地区。我想将预订设置为仅显示与登录用户具有相同国家/地区的用户所做的记录。这是我试过的
collectionOperations={
* "get"={
* "access_control"="object.getUser().getOrganisation() == user.organisation"
* "normalization_context"={
* "groups"={"read"}
* }
* },
当然不行
我知道我可以过滤查询字符串中传递的参数,但我需要在 API 端而不是客户端过滤这些结果。
在 Security page of the docs 上说:
Filtering collections according to the role or permissions of the current user must be done directly at the data provider level. For instance, when using the built-in adapters for Doctrine ORM, MongoDB and ElasticSearch, removing entries from a collection should be done using extensions.
查看 extensions,您需要执行以下操作:
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 }