【问题标题】:Doctrine - Get old value in onFlush event listenerDoctrine - 在 onFlush 事件监听器中获取旧值
【发布时间】:2014-06-29 13:53:20
【问题描述】:

我正在尝试实现一项功能,让用户指定他的相互状态并选择另一个用户,就像 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);
                }
            }
        }
    }
}

【问题讨论】:

    标签: symfony doctrine-orm event-listener


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢一百万!它与$uow->getEntityChangeSet($entity) 合作。它返回一个包含所有更改字段的关联数组。也无需致电computeChangeSet()。再次感谢。
    猜你喜欢
    • 2012-02-08
    • 1970-01-01
    • 2016-10-16
    • 2017-03-27
    • 2016-10-23
    • 2013-07-01
    • 2017-11-10
    • 2013-10-11
    • 1970-01-01
    相关资源
    最近更新 更多