Symfony 2 Get original data of entity from entity manager

user3023209 picture user3023209 · Nov 27, 2013 · Viewed 16.6k times · Source

I am using Sonata admin bundle for my application all works well,In my application i have users and admin,admin can add/edit/delete the users when i am trying to update a user there is a problem the password data is overrided from user table. i have overrided the preUpdate method of admin controller ,I got $object which has an instance of user entity manager so if user leaves to update password and saves data the password is lost.

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

When i try to set $object->setUserPassword($object->getUserPassword()); it gets null and updates the password as null its not getting the edit data i have tried to get the repository (below) again to get the password but no luck its getting the same

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

Is there a way i can access the original data of current entity in entity manager

Answer

M Khalid Junaid picture M Khalid Junaid · Nov 27, 2013

You can access the original data by getting doctrine's Unit of Work.As from docs

You can get direct access to the Unit of Work by calling EntityManager#getUnitOfWork(). This will return the UnitOfWork instance the EntityManager is currently using.An array containing the original data of entity

Grab the password from Unit of Work and use in your setter method

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 */
    }
}

Hope it works fine

Direct access to a Unit of Work