我在 Api 平台中有以下实体,我想知道是否有一种惯用的方法可以在不使用处理器或自定义操作的情况下获取登录用户(使用 jwt 令牌登录的普通用户)的所有关键问题。
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Table(name: 'critical_question')]
#[ORM\Index(name: 'fk_criticals_question_user1_idx', columns: ['user_id'])]
#[ORM\Index(name: 'fk_criticals_question_question1_idx', columns: ['question_id'])]
#[ORM\Entity]
class CriticalQuestion
{
#[ORM\Column(name: 'id', type: 'integer', nullable: false)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
private int $id;
#[ORM\Column(name: 'correct_times', type: 'integer', nullable: false)]
private int $correctTimes;
#[ORM\ManyToOne(targetEntity: Question::class)]
#[ORM\JoinColumn(name: 'question_id', referencedColumnName: 'id')]
#[ORM\JoinColumn(name: 'question_id', referencedColumnName: 'id')]
private Question $question;
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id')]
#[ORM\ManyToOne(targetEntity: User::class)]
#[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id')]
private User $user;
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* @return Question
*/
public function getQuestion(): Question
{
return $this->question;
}
/**
* @param Question $question
*/
public function setQuestion(Question $question): void
{
$this->question = $question;
}
/**
* @return int
*/
public function getCorrectTimes(): int
{
return $this->correctTimes;
}
}
我只是想知道是否有一种简单的方法可以做到这一点,因为我用它来加速构建 API 的过程,但对于我的应用程序中的大多数用例,我使用自定义存储库的自定义操作,或者在某些情况下我使用处理器。
不幸的是,文档并没有很好地解释主题,或者也许这只是我的问题。
在我的一个项目中,我们使用
QueryCollectionExtensionInterface
和 QueryItemExtensionInterface
来进行 Doctrine 级别的过滤。示例代码(未经测试,不提供任何保证):
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bundle\SecurityBundle\Security;
class FilterForCurrentUserExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
public function __construct(protected Security $security)
{
}
public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
{
$this->addWhere($queryBuilder, $resourceClass);
}
/**
* @param mixed[] $identifiers
* @param mixed[] $context
*/
public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, ?Operation $operation = null, array $context = []): void
{
$this->addWhere($queryBuilder, $resourceClass);
}
protected function addWhere(QueryBuilder $queryBuilder, string $resourceClass): void
{
$user = $this->security->getUser();
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere(sprintf('%s.user = :current_user', $rootAlias));
$queryBuilder->setParameter('current_user', $user->getId());
}
}