0

I am using <preference> to override CustomerRepository, but Magento\Customer\Model\ResourceModel\CustomerRepository contains private functions and it throws me error

Fatal error: Call to private method Magento\Customer\Model\ResourceModel\CustomerRepository::populateCustomerModelWithSecureData() from context 'Custom\Mod\Model\ResourceModel\CustomerRepository' in /var/www/html/WC/M2/store/app/code/Custom/Mod/Model/ResourceModel/CustomerRepository.php on line 60

I want to completely override the save() function, and add many more functions. The private functions doesn't allow me to do so. It shouldn't require me to define the private functions again due to strict versional maintenance. Any solution for this?

The custom di.xml has this

<preference for="Magento\Customer\Model\ResourceModel\CustomerRepository"
                type="Custom\Mod\Model\ResourceModel\CustomerRepository" />

The customized CustomerRepository is

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Custom\Mod\Model\ResourceModel;

/**
 * Customer repository.
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class CustomerRepository extends \Magento\Customer\Model\ResourceModel\CustomerRepository
{


    /**
     * {@inheritdoc}
     */
    public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null) {
        $prevCustomerData = null;
        $prevCustomerDataArr = null;

        if ($customer->getId()) {
            $prevCustomerData = $this->getById($customer->getId());
            $prevCustomerDataArr = $prevCustomerData->__toArray();
        }

        /** @var $customer \Magento\Customer\Model\Data\Customer */
        $customerArr = $customer->__toArray();
        $customer = $this->imageProcessor->save(
                $customer, \Magento\Customer\Api\CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, $prevCustomerData
        );

        $origAddresses = $customer->getAddresses();

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

        $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
        $this->populateCustomerModelWithSecureData($customer, $passwordHash, $customerModel);

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


        $this->setDefaultBilling($customerArr, $prevCustomerDataArr, $customerModel);

        $this->setDefaultShipping($customerArr, $prevCustomerDataArr, $customerModel);

        $bo=0;
        if(isset($customerArr['custom_attributes']['back_office']['value'])){
            if($customerArr['custom_attributes']['back_office']['value']==1)
                $bo=1;
        }
        if($customerArr['custom_attributes']['customer_type']['value']=='abal'||$bo==1){

               if($customerArr['custom_attributes']['customer_type']['value']=='abal'){
                   $customerModel->setGroupId(4);
               }

                    $customerModel->save();

                    $this->customerRegistry->push($customerModel);

                    $customerId = $customerModel->getId();
                    $this->updateAddresses($customer, $customerId);
                    if($bo=1){
                    $this->updateft($customer);
                    }
                    if(isset($customerArr['id'])&&$customerArr['custom_attributes']['customer_type']['value']=='abal'){
                        $this->insertcustdetails($customer,$customerId);
                    }
                    $savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
                    $this->eventManager->dispatch(
                            'customer_save_after_data_object', ['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $customer]
                    );

                    return $savedCustomer;

        }
        else{

        $resp = NULL;
        if (!isset($customerArr['id'])) {

                $customerArr = $customer->__toArray();

                $resp = $this->curlCall($customerArr);
                if ($resp == "registration_successfull") {
                    $customerModel->save();
                    $this->customerRegistry->push($customerModel);
                    $customerId = $customerModel->getId();

                    $this->updateAddresses($customer, $customerId);

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

                    try{
                        $number = 5/0;
                    } catch (\Exception $e) {
                        $this->messageManager->addException($e, __('We can\'t save the customer.'));
                    }


                }

        }
        else{

            $customerModel->save();
                    $this->customerRegistry->push($customerModel);
                    $customerId = $customerModel->getId();
                    $this->updateft($customer);
                    $this->updateaddress($customer);
                    $this->updateAddresses($customer, $customerId);

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

        }
        }
    }
}
4
  • If you want to edit in save() function just use only save() in your file
    – Narayan S
    Commented Mar 28, 2018 at 9:36
  • I have added the code, since private functions cannot be extended, it throws me error.
    – Midlaj
    Commented Mar 28, 2018 at 9:45
  • Remove Private functions your module file, just try using save() function. Or post the code here.
    – Narayan S
    Commented Mar 28, 2018 at 9:47
  • I do not have private functions in my module, but i require calling them. Is there any way except defining the private functions again?
    – Midlaj
    Commented Mar 28, 2018 at 9:51

2 Answers 2

1

=> In di.xml of your custom module

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Customer\Model\ResourceModel\CustomerRepository" 
    type="Custom\Mod\Model\ResourceModel\CustomerRepository" />
</config>

=> In CustomerRepository.php File You have missed below function

/**
     * Set secure data to customer model
     *
     * @param \Magento\Customer\Model\Customer $customerModel
     * @param string|null $passwordHash
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @return void
     */
    private function populateCustomerWithSecureData($customerModel, $passwordHash = null)
    {
        if ($customerModel->getId()) {
            $customerSecure = $this->customerRegistry->retrieveSecureData($customerModel->getId());

            $customerModel->setRpToken($passwordHash ? null : $customerSecure->getRpToken());
            $customerModel->setRpTokenCreatedAt($passwordHash ? null : $customerSecure->getRpTokenCreatedAt());
            $customerModel->setPasswordHash($passwordHash ?: $customerSecure->getPasswordHash());

            $customerModel->setFailuresNum($customerSecure->getFailuresNum());
            $customerModel->setFirstFailure($customerSecure->getFirstFailure());
            $customerModel->setLockExpires($customerSecure->getLockExpires());
        } elseif ($passwordHash) {
            $customerModel->setPasswordHash($passwordHash);
        }

        if ($passwordHash && $customerModel->getId()) {
            $this->customerRegistry->remove($customerModel->getId());
        }
    }
7
  • I did this, my problem is after doing this step, i have mentioned it in the question.
    – Midlaj
    Commented Mar 28, 2018 at 9:30
  • Can you Post the code in the question @Midlaj Commented Mar 28, 2018 at 9:36
  • i have added the code
    – Midlaj
    Commented Mar 28, 2018 at 9:46
  • Please find the above code That You have missed @Midlaj Commented Mar 28, 2018 at 9:55
  • Yes, i understand i do not have that code since a private function cannot be extended. But is there any way to override without defining the private functions again, this is because future version changes shouldn't require anyone else to redefine the private functions again.
    – Midlaj
    Commented Mar 28, 2018 at 9:58
0

Try to do this in order to extend feature this might help you :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Customer\Api\CustomerRepositoryInterface" type="Vendor\ModuleName\Model\ResourceModel\CustomClassName" />
</config>

Make sure your model code look like this :

<?php
namespace Vendor\ModuleName\Model\ResourceModel;

use Magento\Customer\Model\ResourceModel\CustomerRepository;

Class CustomClassName extends CustomerRepository
{
   ...................
   ...................
   ...................
}
5
  • I tried this, it doesn't go to my customized CustomerRepository. It goes to core customer module's customerrepository
    – Midlaj
    Commented Mar 28, 2018 at 10:06
  • check above modification , match with your code @midlaj Commented Mar 28, 2018 at 10:44
  • i tried the same, it goes to core customer module itself, not my customclaass
    – Midlaj
    Commented Mar 28, 2018 at 11:12
  • You need to run following command : bin/magento setup:di:compile bin/magento c:f Commented Mar 28, 2018 at 11:16
  • Yeah, i have run that
    – Midlaj
    Commented Mar 28, 2018 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.