2014-05-12 8 views
5

Sto tentando di implementare una funzionalità che consente all'utente di specificare il suo stato reciproco e selezionare un altro utente, proprio come quello di Facebook.Doctrine - Ottieni un vecchio valore nell'ascoltatore di eventi suFlush

mio schema del database è simile:

UserInfo entità:

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 entità:

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

Ora ecco il listener di eventi, Controlla lo stato dell'utente e cambia l'altro utente, Funziona come previsto. Ma ha solo un difetto, se l'utente è sposato con (A) e poi lo ha cambiato in sposato con (B), L'utente (A) continua a ottenere il Married e non viene reimpostato.

Tutto ciò che voglio fare è prima di collegare la relazione dell'utente a (B), voglio recuperare (A) e resettarlo. Come si può fare all'interno dell'evento 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); 
       } 
      } 
     } 
    } 
} 

risposta

13

dottrina UoW ha un metodo PropertyChanged (...) che tiene traccia delle modifiche alle proprietà di entità. Queste modifiche sono memorizzate in entityChangeSets-Property di UoW.

Penso che dovrebbe essere possibile chiamare $uow->getEntityChangeSet($entity) che restituisce un array in cui le chiavi sono le proprietà di $ entity ei valori sono [$oldValue, $newValue].

Non sono sicuro di dover chiamare lo computeChangeSet() per il vecchio utente della relazione, ma spero che riesci a capirlo e lasciare un commento?

+1

Grazie mille! Ha funzionato con '$ uow-> getEntityChangeSet ($ entity)'. Ha restituito un array associativo con tutti i campi modificati. E senza la necessità di chiamare 'computeChangeSet()'. Grazie ancora. –

+1

Ottimo! Grazie per l'aggiornamento! – SecretUsername

Problemi correlati