是否可以动态设置doctrine.yaml(或doctrine.php)中的Doctrine参数?

问题描述 投票:0回答:1

我正在使用 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,还是太晚了(上面的配置只是静态信息)?我编码参数的方式是最合适的方式吗?

感谢您的指导。

doctrine-orm doctrine symfony6
1个回答
0
投票

您可以考虑利用事件侦听器,例如

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

© www.soinside.com 2019 - 2024. All rights reserved.