我正在使用 Doctrine 过滤器将结果集限制为登录用户的记录(即
where user_id = <their id>
)。我想知道这是否只能通过以编程方式向 Doctrine 过滤器添加参数来完成,或者我可以在 config\packages\doctrine.yaml (或 config\packages\doctrine.php)文件中动态执行此操作。
过滤器参数在控制器中以编程方式设置,如下所示:
config/packages/doctrine.yaml:
...
filters:
user_filter:
class: App\Doctrine\UserFilter
enabled: true
src\Doctrine\UserFilter.php:
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias): string
{
if ($targetEntity->getReflectionClass()->name == 'App\Entity\Task') {
$mypar = $this->getParameter('user_id');
return sprintf('%s.user_id = %s', $targetTableAlias, $mypar );
}
return '';
}
src/TaskController.php:
class TaskController extends AbstractController
{
#[Route('/', name: 'app_task_index', methods: ['GET'])]
public function index(TaskRepository $taskRepository, EntityManagerInterface $entityManager): Response
{
// Add the user_id filter to the Doctrine filter
// First get the filter, then set the required parameter on it
$userFilter = $entityManager->getFilters()->getFilter('user_filter');
$userFilter->setParameter('user_id', $this->getUser()->getId());
return $this->render('task/index.html.twig', [
'tasks' => $taskRepository->findAll(),
]);
}
像这样设置 Doctrine 过滤器参数是可行的,但它需要传入 EntityManagerInterface,以便我们可以访问实体管理器。
我希望能够使用 Symfony 6.2 Doctrine 过滤器配置来设置参数,它允许我们在配置文件中传递参数:
config/packages/doctrine.yaml
...
filters:
user_filter:
class: App\Doctrine\UserFilter
enabled: true
parameters: $user->getUser()->getId() << this doesn't work
我尝试将学说配置转换为 PHP,认为它可能允许解释代码:
config/packages/doctrine.php:
'filters' => [
'user_filter' => [
'class' => UserFilter::class,
'enabled' => true,
'parameters' => [
'user_id' => $this->getUser()->getId(), << this doesn't work
],
不在对象上下文中使用 $this 会产生错误。
这样的配置是否可以获取登录的用户id,还是太晚了(上面的配置只是静态信息)?我编码参数的方式是最合适的方式吗?
感谢您的指导。
您可以考虑利用事件侦听器,例如
namespace App\Doctrine\EventListener;
use App\Entity\User;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
class UserCreateListener
{
public function loadClassMetadata(LoadClassMetadataEventArgs $args): void
{
// if this listener may apply to user entity type only,
$targetEntity = $args->getClassMetadata();
if ($targetEntity->getReflectionClass()->name !== User::class) {
return;
}
// enables filter (service) 'user_filter' and set parameters
$entityManager = $args->getEntityManager();
$conn = $entityManager->getConnection();
$sql = 'SELECT id FROM <database>';
$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery()->fetchAssociative();
$filter = $entityManager->getFilters()->enable('user_filter');
$filter->setParameter('user_id', $result['id']);
}
}
在 services.yaml 中注册服务可能是这样的:
App\Doctrine\EventListener\UserCreateListener:
tags:
- name: doctrine.event_listener
# this is the only required option for the lifecycle listener tag
event: 'loadClassMetadata'
# listeners can define their priority in case multiple subscribers or listeners are associated
# to the same event (default priority = 0; higher numbers = listener is run earlier)
priority: 512
# you can also restrict listeners to a specific Doctrine connection
connection: 'default'
欲了解更多信息,请查看:
https://symfony.com/doc/current/doctrine/events.html#doctrine-lifecycle-listeners