Symfony v6.3 中的弃用:不推荐将“App\DQL\TablePrefixSubscriber”注册为 Doctrine 订阅者

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

Symfony v6.3 中的弃用:不推荐将“App\DQL\TablePrefixSubscriber”注册为 Doctrine 订阅者

简介

我通过Doctrine官方方法StackOverflow答案在数据库中的表中使用前缀。


问题

升级到 Symfony v6.3 后得到新的弃用:

用户已弃用:自 symfony/doctrine-bridge 6.3 起:已弃用将“App\DQL\TablePrefixSubscriber”注册为 Doctrine 订阅者。相反,使用例如将其注册为侦听器#[AsDoctrineListener] 属性。


代码

相关部分

services.yaml

parameters:
    app.db_table_prefix: abc_

services:
    app.tbl_prefix_subscriber:
        class: App\DQL\TablePrefixSubscriber
        arguments: [%app.db_table_prefix%]
        tags:
            - { name: doctrine.event_subscriber }

我现在的

TablePrefixSubscriber

<?php

namespace App\DQL;

use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\Common\EventSubscriber as EventSubscriber;
use Doctrine\ORM\Mapping\ClassMetadataInfo as ClassMetadataInfo;

class TablePrefixSubscriberNew implements EventSubscriber
{
    protected string $prefix = '';

    public function __construct(string $prefix)
    {
        $this->prefix = $prefix;
    }

    public function getSubscribedEvents(): array
    {
        return array('loadClassMetadata');
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
    {
        $classMetadata = $eventArgs->getClassMetadata();

        if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
            $classMetadata->setPrimaryTable([
                'name' => $this->prefix . $classMetadata->getTableName()
            ]);
        }

        foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
            if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
                $mappedTableName = $mapping['joinTable']['name'];
                $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
            }
        }
    }
}
php symfony doctrine-orm doctrine symfony6
1个回答
0
投票

一个答案

遵循弃用通知中的建议并进行少量重构后,我找到了工作解决方案。

代码

相关部分

services.yaml

parameters:
    app.db_table_prefix: abc_

services:
    App\DQL\TablePrefixListener:
        arguments:
            $prefix: '%app.db_table_prefix%'
        public: true

当前

TablePrefixListener

<?php

namespace App\DQL;

use Doctrine\Bundle\DoctrineBundle\Attribute\AsDoctrineListener;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadataInfo as ClassMetadataInfo;

/*
 * Setup information directly from Doctrine
 * https://www.doctrine-project.org/projects/doctrine-orm/en/2.16/cookbook/sql-table-prefixes.html#telling-the-entitymanager-about-our-listener
 * https://symfony.com/doc/current/doctrine/events.html#doctrine-entity-listeners
 */
#[AsDoctrineListener(event: Events::loadClassMetadata, priority: 500, connection: 'default')]
class TablePrefixListener
{
    protected string $prefix = '';

    public function __construct(string $prefix)
    {
        $this->prefix = $prefix;
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
    {
        $classMetadata = $eventArgs->getClassMetadata();

        if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
            $classMetadata->setPrimaryTable([
                'name' => $this->prefix . $classMetadata->getTableName()
            ]);
        }

        foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
            if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
                $mappedTableName = $mapping['joinTable']['name'];
                $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.