2014-05-12 31 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