2016-07-11 30 views
1

我有一个PSR加载包,它定义了它提供的一个“用户”实体周围的一系列关系。可能动态更改Doctrine Entity映射?

在许多使用此软件包的用例中,您可能希望保持所有实体完好无损,但替换您自己的用户实体。

至于具体的例子,包使我这个实体(使用注释这里让事情变得清晰):

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中的用户关系:: $用户中,靶向CirclicalUser \实体\用户,用我自己的用户:的Acme \实体\用户(假设它是一个主义实体在自己的权利)

例如,假装PHP:

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

谢谢!

+1

你试过EventSubscriber到'loadClassMetadata'事件? [SoftDeletableSubscriber](https://github.com/KnpLabs/DoctrineBehaviors/blob/14a4d19e808c955da1b0962b3cf0bdc9f69c61f0/src/ORM/SoftDeletable/SoftDeletableSubscriber.php#L89-L107) –

+1

只是要指出, d使用loadClassMetadata解决它!我会在下面发布我的解决方案。 – Saeven

+1

太棒了!请接受您的回答,以便将问题标记为已解决。 –

回答

1

我设法通过监听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框架)是微不足道的:

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

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

'service_manager' => [ 

    'invokables' => [ 
     UserAuthenticationLogMapper::class => UserAuthenticationLogMapper::class, 
    ], 

    'factories' => [ 
     UserEntityListener::class => UserEntityListenerFactory::class, 
    ], 

],