2014-05-12 30 views
5

我试图实现一个功能,让用户指定他的相互状态并选择另一个用户,就像Facebook中的那个一样。学说 - 在onFlush事件监听器中获取旧值

我的数据库模式是这样的:

UserInfo实体:

class UserInfo 
{ 

    /** 
    * @ORM\OneToOne(targetEntity="User", inversedBy="user_info") 
    */ 
    protected $user; 

    /** 
    * @ORM\Column(type="text", nullable=true) 
    * @Assert\NotBlank 
    */ 
    protected $status; //Value taken from a dropdown list 

    /** 
    * @ORM\OneToOne(targetEntity="User", inversedBy="relationship_with_table") 
    */ 
    protected $relationship_user; 
} 

User实体:

class User 
{ 

    /** 
    * @ORM\OneToOne(targetEntity="UserInfo", mappedBy ="user", cascade={"persist","remove"}) 
    */ 
    protected $user_info; 

    /** 
    * @ORM\OneToOne(targetEntity="UserInfo", mappedBy="relationship_user") 
    */ 
    protected $relationship_with_table; 
} 

UserInfoType

class UserInfoType extends AbstractType 
{ 

    public function buildForm(FormBuilderInterface $builder, array $option) 
    { 
     $builder 
      ->add("birthday", "birthday") 
      ->add("gender", "choice", array("choices" => array("0" => "Male", "1" => "Female"))) 
      ->add("status", "choice", array("choices" => array(
        "Single" => "Single", 
        "In relationship" => "In relationship", 
        "Engaged" => "Engaged", 
        "Married" => "Married" 
       ))) 
      ->add("relationship_user", "thrace_select2_entity", array(
        "class" => 'Zgh\FEBundle\Entity\User', 
        'label' => 'User', 
        'empty_value' => 'Select user', 
        "configs" => array(
         "width" => '100%', 
        ), 
       )) 
      ->add("city", "text") 
      ->add("work", "text") 
      ->add("facebook", "url") 
      ->add("twitter", "url") 
     ; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
       "data_class" => 'Zgh\FEBundle\Entity\UserInfo', 
       "cascade_validation" => true, 
      )); 
    } 

    public function getName() 
    { 
     return "user_info"; 
    } 
} 

现在,这里是事件监听器,它检查用户状态并更改其他用户,它按预期工作。但只有一个缺陷,如果用户与(A)结婚,然后将其改为与(B)结婚,则用户(A)仍然获得结婚并且不会被重置。

所有我想要做的是将用户关系附加到(B)之前,我想检索(A)并重置它。如何在onFlush事件内完成此操作。

class DoctrinePreUpdateHandler implements EventSubscriber 
{ 
    public function getSubscribedEvents() 
    { 
     return array(
      "onFlush", 
     ); 
    } 

    public function onFlush(OnFlushEventArgs $args) 
    { 
     $em = $args->getEntityManager(); 
     $uow = $em->getUnitOfWork(); 

     $updates = $uow->getScheduledEntityUpdates(); 

     foreach ($updates as $entity) { 

      if($entity instanceof UserInfo){ 

       $target_user_info = null; 

       if($entity->getStatus() == "Single"){ 
        if($entity->getRelationshipUser() != null){ 
         $target_user_info = $entity->getRelationshipUser()->getUserInfo(); 
         $target_user_info->setStatus("Single"); 
         $target_user_info->setRelationshipUser(null); 
        } 
        $entity->setRelationshipUser(null); 
       } else { 
        $target_user_info = $entity->getRelationshipUser()->getUserInfo(); 
        $target_user_info->setStatus($entity->getStatus()); 
        $target_user_info->setRelationshipUser($entity->getUser()); 
       } 

       if($target_user_info != null){ 
        $em->persist($target_user_info); 
        $uow->computeChangeSet($em->getClassMetadata(get_class($target_user_info)), $target_user_info); 
       } 
      } 
     } 
    } 
} 

回答

13

Doctrine UoW有一个方法propertyChanged(...)来跟踪对实体属性的更改。 这些更改存储在UoW的entityChangeSets-Property中。

我认为应该可以调用$uow->getEntityChangeSet($entity),它返回一个数组,其中键是$ entity的属性,值是[$oldValue, $newValue]

我不确定您是否需要为旧关系用户致电computeChangeSet(),但我希望您能弄清楚并留下评论?

+1

非常感谢!它使用'$ uow-> getEntityChangeSet($ entity)'。它返回一个包含所有更改字段的关联数组。而且不需要调用'computeChangeSet()'。再次感谢。 –

+1

太棒了!谢谢你的更新! – SecretUsername