Zend certified PHP/Magento developer

Override private function _beforeSave(MagentoFrameworkDataObject $customer)

I am trying to modify the copy that displays when a user tries to change their email address to an address that already exists. The current message that displays is “A customer with the same email address already exists in an associated website.”

I’ve tried just adding this to my theme en_US.csv file, but it didn’t update.

filepath: /app/design/frontend/Vendor/themename/i18n/en_US.csv

"A customer with the same email already exists in an associated website.","Your account information has been updated."

I’ve tried adding a new en_US.csv file to a custom module, but that also didn’t work.

filepath: /app/code/Vendor/ModuleName/i18n/en_US.csv

I searched the code and found where the copy that displays is set and it is in this file /vendor/magento/module-customer/Model/ResourceModel/Customer.php. When I updated the text here, for testing purposes, it displays the copy that I want.

protected function _beforeSave(MagentoFrameworkDataObject $customer)
{
    /** @var MagentoCustomerModelCustomer $customer */
    if ($customer->getStoreId() === null) {
        $customer->setStoreId($this->storeManager->getStore()->getId());
    }
    $customer->getGroupId();

    parent::_beforeSave($customer);

    if (!$customer->getEmail()) {
        throw new ValidatorException(__('The customer email is missing. Enter and try again.'));
    }

    $connection = $this->getConnection();
    $bind = ['email' => $customer->getEmail()];

    $select = $connection->select()->from(
        $this->getEntityTable(),
        [$this->getEntityIdField()]
    )->where(
        'email = :email'
    );
    if ($customer->getSharingConfig()->isWebsiteScope()) {
        $bind['website_id'] = (int)$customer->getWebsiteId();
        $select->where('website_id = :website_id');
    }
    if ($customer->getId()) {
        $bind['entity_id'] = (int)$customer->getId();
        $select->where('entity_id != :entity_id');
    }

    $result = $connection->fetchOne($select, $bind);
    if ($result) {
        throw new AlreadyExistsException(
            __('A customer with the same email address already exists in an associated website.')
        );
    }

    // set confirmation key logic
    if (!$customer->getId() &&
        $this->accountConfirmation->isConfirmationRequired(
            $customer->getWebsiteId(),
            $customer->getId(),
            $customer->getEmail()
        )
    ) {
        $customer->setConfirmation($customer->getRandomConfirmationKey());
    }
    // remove customer confirmation key from database, if empty
    if (!$customer->getConfirmation()) {
        $customer->setConfirmation(null);
    }

    if (!$customer->getData('ignore_validation_flag')) {
        $this->_validate($customer);
    }

    return $this;
}

I thought that I could just override this by creating a custom module, but that still is not working.

Custom module code:

/app/code/Vendor/ModuleName/etc/di.xml

<?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="MagentoCustomerModelResourceModelCustomer" type="VendorModuleNameModelResourceModelCustomer" />
</config>

/app/code/Vendor/ModuleName/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_ModuleName">
        <sequence>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

/app/code/Vendor/ModuleName/Model/ResourceModel/Customer.php

namespace VendorModuleNameModelResourceModel;

use MagentoCustomerModelAccountConfirmation;
use MagentoCustomerModelCustomerNotificationStorage;
use MagentoFrameworkAppObjectManager;
use MagentoFrameworkValidatorException as ValidatorException;
use MagentoFrameworkExceptionAlreadyExistsException;

/**
 * Customer entity resource model
 *
 * @api
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @since 100.0.2
 */
class Customer extends MagentoCustomerModelResourceModelCustomer
{

/**
 * Check customer scope, email and confirmation key before saving
 *
 * @param MagentoFrameworkDataObject|MagentoCustomerApiDataCustomerInterface $customer
 *
 * @return $this
 * @throws AlreadyExistsException
 * @throws ValidatorException
 * @throws MagentoFrameworkExceptionNoSuchEntityException
 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
 * @SuppressWarnings(PHPMD.NPathComplexity)
 */
protected function _beforeSave(MagentoFrameworkDataObject $customer)
{
    /** @var MagentoCustomerModelCustomer $customer */
    if ($customer->getStoreId() === null) {
        $customer->setStoreId($this->storeManager->getStore()->getId());
    }
    $customer->getGroupId();

    parent::_beforeSave($customer);

    if (!$customer->getEmail()) {
        throw new ValidatorException(__('The customer email is missing. Enter and try again.'));
    }

    $connection = $this->getConnection();
    $bind = ['email' => $customer->getEmail()];

    $select = $connection->select()->from(
        $this->getEntityTable(),
        [$this->getEntityIdField()]
    )->where(
        'email = :email'
    );
    if ($customer->getSharingConfig()->isWebsiteScope()) {
        $bind['website_id'] = (int)$customer->getWebsiteId();
        $select->where('website_id = :website_id');
    }
    if ($customer->getId()) {
        $bind['entity_id'] = (int)$customer->getId();
        $select->where('entity_id != :entity_id');
    }

    $result = $connection->fetchOne($select, $bind);
    if ($result) {
        throw new AlreadyExistsException(
            __('Your account information has been updated.')
        );
    }

    // set confirmation key logic
    if (!$customer->getId() &&
        $this->accountConfirmation->isConfirmationRequired(
            $customer->getWebsiteId(),
            $customer->getId(),
            $customer->getEmail()
        )
    ) {
        $customer->setConfirmation($customer->getRandomConfirmationKey());
    }
    // remove customer confirmation key from database, if empty
    if (!$customer->getConfirmation()) {
        $customer->setConfirmation(null);
    }

    if (!$customer->getData('ignore_validation_flag')) {
        $this->_validate($customer);
    }

    return $this;
}

}

I’ve seen a few things say that you can’t override a protected function, so maybe that is my issue? I’m feeling kind of stuck, so any thoughts would be helpful. Thanks.