Doctrine - 在onFlush事件监听器中获取旧值

时间:2014-05-12 09:07:16

标签: symfony doctrine-orm event-listener

我试图实现一项功能,让用户指定他的共同状态并选择另一个用户,就像在Facebook中那样。

我的数据库架构如下:

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

1 个答案:

答案 0 :(得分:14)

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

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

我不确定您是否必须为旧关系用户致电computeChangeSet(),但我希望您能解决这个问题并发表评论?