可以动态更改教义实体映射


Possible to dynamically change Doctrine Entity mappings?

我有一个加载PSR的包,它围绕它提供的"用户"实体定义了一系列关系。

在使用此包的许多用例中,您可能希望保持所有实体不变,但替换您自己的 User 实体。

作为具体示例,该包为我提供了此实体(在此处使用注释以保持清晰):

namespace CirclicalUser'Entity;
use Doctrine'ORM'Mapping as ORM;
/**
 * An example entity that represents an action rule.
 *
 * @ORM'Entity
 * @ORM'Table(name="acl_actions_users")
 *
 */
class UserActionRule
{
    /**
     * @var int
     * @ORM'Id
     * @ORM'ManyToOne(targetEntity="CirclicalUser'Entity'ActionRule", inversedBy="user_exceptions")
     * @ORM'JoinColumn(name="action_rule_id", referencedColumnName="id")
     */
    protected $action_rule;
    /**
     * @ORM'Id
     * @ORM'ManyToOne(targetEntity="CirclicalUser'Entity'User")
     * @ORM'JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;
}

鉴于上述情况,我有什么方法可以取代UserActionRule::$user中的用户关系,该关系针对CirclicalUser''Entity''User,与我自己的用户:Acme''Entity''User(假设它本身就是一个Doctrine实体)

例如,假装 PHP:

function onBoostrap( $e ){
    DoctrineMagic::getMapping(UserActionRule::class)->get('user')->getManyToOne()->setTargetEntity(Acme'Entity'User::class);
}

谢谢!

我设法通过监听loadClassMetadata事件来解决这个问题。

namespace CirclicalUser'Listener;
use Doctrine'ORM'Event'LoadClassMetadataEventArgs;
use Doctrine'Common'EventSubscriber;
class UserEntityListener implements EventSubscriber
{
    const DEFAULT_ENTITY = 'CirclicalUser'Entity'User';
    private $userEntity;
    public function __construct($userEntity)
    {
        $this->userEntity = $userEntity;
    }
    public function getSubscribedEvents()
    {
        return ['loadClassMetadata'];
    }
    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        /** @var 'Doctrine'ORM'Mapping'ClassMetadata $classMetadata */
        $classMetadata = $eventArgs->getClassMetadata();
        if ($this->userEntity == self::DEFAULT_ENTITY) {
            return;
        }
        switch ($classMetadata->getName()) {
            case 'CirclicalUser'Entity'UserActionRule':
                $classMetadata->associationMappings['user']['targetEntity'] = $this->userEntity;
                break;
        }
    }
}

此侦听器成功地替换了用户定义的实体类的映射。

添加侦听器(Zend Framework)是微不足道的:

'doctrine' => [
    'eventmanager' => [
        'orm_default' => [
            'subscribers' => [
                UserEntityListener::class,
            ],
        ],
    ],

另外,在服务管理器配置中:

'service_manager' => [
    'invokables' => [
        UserAuthenticationLogMapper::class => UserAuthenticationLogMapper::class,
    ],
    'factories' => [
        UserEntityListener::class => UserEntityListenerFactory::class,
    ],
],