Creating an observer other day to compare customer data when saved, I faced an issue trying to retrieve the old customer information.

I’ve used the event “customer_save_after_data_object” in Magento 2.1.4 to return both new and old customer data. However, when comparing them I noticed they were the same.

By debug the Magento Customer module I found a bug  in <MAGE_DIR>/vendor/magento/module-customer/Model/ResourceModel/CustomerRepository.php on the line 227.

['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $customer]

It actually should be

['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $prevCustomerData]

Once god knows when the Magento team will fix it, the best work around is overwriting the method save in the Customer Repository. To do so, in a custom module, let’s change the di.xml file.

In your custom module, file app/code/NAMESPACE/PACKAGE/etc/di.xml add the following line:

<preference for="Magento\Customer\Model\ResourceModel\CustomerRepository" type="NAMESPACE\PACKAGE\Model\ResourceModel\CustomerRepository" />

Now let’s create the file app/code/NAMESPACE/PACKAGE/Model/ResourceModel/CustomerRepository.php and add the following content:

<?php

namespace NAMESPACE\PACKAGE\Model\ResourceModel;

use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Api\ImageProcessorInterface;
use Magento\Framework\Api\SearchCriteriaInterface;
use Magento\Framework\Api\SortOrder;

/**
 * Customer repository.
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class CustomerRepository extends \Magento\Customer\Model\ResourceModel\CustomerRepository
{
    /**
     * {@inheritdoc}
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null)
    {
        $prevCustomerData = null;
        if ($customer->getId()) {
            $prevCustomerData = $this->getById($customer->getId());
        }
        $customer = $this->imageProcessor->save(
            $customer,
            CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
            $prevCustomerData
        );

        $origAddresses = $customer->getAddresses();
        $customer->setAddresses([]);
        $customerData = $this->extensibleDataObjectConverter->toNestedArray(
            $customer,
            [],
            '\Magento\Customer\Api\Data\CustomerInterface'
        );

        $customer->setAddresses($origAddresses);
        $customerModel = $this->customerFactory->create(['data' => $customerData]);
        $storeId = $customerModel->getStoreId();
        if ($storeId === null) {
            $customerModel->setStoreId($this->storeManager->getStore()->getId());
        }
        $customerModel->setId($customer->getId());

        // Need to use attribute set or future updates can cause data loss
        if (!$customerModel->getAttributeSetId()) {
            $customerModel->setAttributeSetId(
                \Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER
            );
        }
        // Populate model with secure data
        if ($customer->getId()) {
            $customerSecure = $this->customerRegistry->retrieveSecureData($customer->getId());
            $customerModel->setRpToken($customerSecure->getRpToken());
            $customerModel->setRpTokenCreatedAt($customerSecure->getRpTokenCreatedAt());
            $customerModel->setPasswordHash($customerSecure->getPasswordHash());
            $customerModel->setFailuresNum($customerSecure->getFailuresNum());
            $customerModel->setFirstFailure($customerSecure->getFirstFailure());
            $customerModel->setLockExpires($customerSecure->getLockExpires());
        } else {
            if ($passwordHash) {
                $customerModel->setPasswordHash($passwordHash);
            }
        }

        // If customer email was changed, reset RpToken info
        if ($prevCustomerData
            && $prevCustomerData->getEmail() !== $customerModel->getEmail()
        ) {
            $customerModel->setRpToken(null);
            $customerModel->setRpTokenCreatedAt(null);
        }
        $customerModel->save();
        $this->customerRegistry->push($customerModel);
        $customerId = $customerModel->getId();

        if ($customer->getAddresses() !== null) {
            if ($customer->getId()) {
                $existingAddresses = $this->getById($customer->getId())->getAddresses();
                $getIdFunc = function ($address) {
                    return $address->getId();
                };
                $existingAddressIds = array_map($getIdFunc, $existingAddresses);
            } else {
                $existingAddressIds = [];
            }

            $savedAddressIds = [];
            foreach ($customer->getAddresses() as $address) {
                $address->setCustomerId($customerId)
                    ->setRegion($address->getRegion());
                $this->addressRepository->save($address);
                if ($address->getId()) {
                    $savedAddressIds[] = $address->getId();
                }
            }

            $addressIdsToDelete = array_diff($existingAddressIds, $savedAddressIds);
            foreach ($addressIdsToDelete as $addressId) {
                $this->addressRepository->deleteById($addressId);
            }
        }

        $savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
        $this->eventManager->dispatch(
            'customer_save_after_data_object',
            ['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $prevCustomerData]
        );
        return $savedCustomer;
    }
}

You might have to clean the folder var/generation and/or run the command “php bin/magento setup:di:compile”.

That’s it. Now the variable ‘orig_customer_data_object’ brings the right customer data.

https://i2.wp.com/blog.mdnsolutions.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-24-at-10.49.47-AM.png?fit=768%2C391&ssl=1https://i2.wp.com/blog.mdnsolutions.com/wp-content/uploads/2016/06/Screen-Shot-2016-06-24-at-10.49.47-AM.png?resize=150%2C150&ssl=1Renato MedinaMagentoMagento 2customer,customer_save_after_data_object,Magento 2Creating an observer other day to compare customer data when saved, I faced an issue trying to retrieve the old customer information. I've used the event 'customer_save_after_data_object' in Magento 2.1.4 to return both new and old customer data. However, when comparing them I noticed they were the same. By debug the...A Magento Craftsman in Melbourne