2014-05-12 21 views
5

Kullanıcının karşılıklı durumunu belirleyebildiği ve Facebook'ta olduğu gibi başka bir kullanıcı seçmesine izin veren bir özellik uygulamaya çalışıyorum.Doctrine - OnFlush olay dinleyicisindeki eski değeri al

Benim veritabanı şeması gibidir:

UserInfo varlık:

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 varlık:

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"; 
    } 
} 

Şimdi olay dinleyicisi, Kullanıcı durumunu kontrol eder ve diğer kullanıcıyı değiştirir, Beklendiği gibi çalışır. Ancak sadece bir kusur vardır, Eğer kullanıcı (A) ile evliyse ve daha sonra (B) ile evlenseydi, Kullanıcı (A) hala Evli alır ve sıfırlanamaz.

Tüm yapmak istediğim, kullanıcı ilişkisini (B) ile ilişkilendirmeden önce, (A) 'ya almak ve sıfırlamak istiyorum. Bu, onFlush etkinliğinde nasıl yapılabilir.

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); 
       } 
      } 
     } 
    } 
} 

cevap

13

Doctrine UoW, varlık özelliklerinde yapılan değişiklikleri izleyen bir propertyChanged (...) yöntemine sahiptir. Bu değişiklikler UoW ​​öğesinin entityChangeSets-Property'de depolanır.

Anahtarların $ entity'nin özellikleri ve değerlerinin [$oldValue, $newValue] olduğu bir dizi döndüren $uow->getEntityChangeSet($entity) numaralı telefonu arayabilmem gerektiğini düşünüyorum.

Eski ilişki kullanıcısı için computeChangeSet() numaralı telefonu aramanız gerekip gerekmediğinden emin değilim, ancak umarım bunu anlayabilir ve yorum yazabilirsiniz?

+1

Milyonlara teşekkürler! $ Uow-> getEntityChangeSet ($ entity) ile çalıştı. Değiştirilen tüm alanları içeren bir ilişkisel dizi döndürdü. Ve de computeChangeSet() 'i çağırmak gerek kalmadan. Tekrar teşekkürler. –

+1

Harika! Güncelleme için teşekkürler! – SecretUsername