Symfony 2 从实体管理器获取实体的原始数据

Posted

技术标签:

【中文标题】Symfony 2 从实体管理器获取实体的原始数据【英文标题】:Symfony 2 Get original data of entity from entity manager 【发布时间】:2013-12-13 15:28:11 【问题描述】:

我正在为我的应用程序使用 Sonata 管理包,一切正常,在我的应用程序中,我有用户和管理员,管理员可以在我尝试更新用户时添加/编辑/删除用户密码数据有问题从用户表中覆盖。我已经覆盖了管理控制器的preUpdate 方法,我得到了$object,它有一个用户实体管理器的实例,所以如果用户离开以更新密码并保存数据,密码就会丢失。

public function preUpdate($object)

    $Password = $object->getUserPassword();
    if (!empty($Password))  /* i check here if user has enter password then update it goes well*/
        $salt = md5(time());
        $encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory');
        $User = new User();
        $encoder = $encoderservice->getEncoder($User);
        $encoded_pass = $encoder->encodePassword($Password, $salt);
        $object->setUserSalt($salt)->setUserPassword($encoded_pass);
     else  /* here i try to set the old password if user not enters the new password but fails */
        $object->setUserPassword($object->getUserPassword());
    

当我尝试设置$object->setUserPassword($object->getUserPassword()); 时,它会变为 null 并将密码更新为 null 它没有获得编辑数据我试图再次获取存储库(如下)以获取密码但运气不一样

$DM = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager()->getRepository("...")->find(id here);

有没有办法在实体管理器中访问当前实体的原始数据

【问题讨论】:

【参考方案1】:

您可以通过获取学说的工作单元来访问原始数据。As from docs

您可以通过调用直接访问工作单元 EntityManager#getUnitOfWork()。这将返回 UnitOfWork EntityManager 当前正在使用的实例。包含 实体原始数据

从 Unit of Work 获取密码并在您的 setter 方法中使用

public function preUpdate($object)


    $DM = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager();
    $uow = $DM->getUnitOfWork();
    $OriginalEntityData = $uow->getOriginalEntityData( $object );
    $Password = $object->getUserPassword();
    if (!empty($Password))  /* i check here if user has enter password then update it goes well*/
        $salt = md5(time());
        $encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory');
        $User = new User();
        $encoder = $encoderservice->getEncoder($User);
        $encoded_pass = $encoder->encodePassword($Password, $salt);
        $object->setUserSalt($salt)->setUserPassword($encoded_pass);
     else  /* here i try to set the old password if user not enters the new password but fails */
        $object->setUserPassword($OriginalEntityData['Password']);/* your property name for password field */
    

希望一切顺利

Direct access to a Unit of Work

【讨论】:

链接失效【参考方案2】:
$this->getConfigurationPool()
     ->getContainer()
     ->get('Doctrine')
     ->getRepository("...")
     ->find(id here);

所以省略getManager() 部分;

【讨论】:

【参考方案3】:

在实体管理中重置实体,例如onFlush事件

  /**
     * @param OnFlushEventArgs $args
     *
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function onFlush(OnFlushEventArgs  $args)
    
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityUpdates() as $keyEntity => $entity) 
            if ($entity instanceof Bill) 
                $em->refresh($entity);
                $this->createPdfs($entity);

            
        
    

【讨论】:

以上是关于Symfony 2 从实体管理器获取实体的原始数据的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 doctrine来自特定实体的更新架构

Symfony2 - Doctrine - 在实体管理器刷新调用中捕获错误

Symfony2:如何使用非默认实体管理器对用户进行身份验证?

在Symfony3中创建实体管理器?

Symfony:必须管理传递给选择字段的“App\Entity\Classement”类型的实体。也许您忘记将其保留在实体管理器中?

Symfony 2.0 在实体内部获取服务