2

I'm using Magento CE 2.1, deploy:mode:set was set to developer.

I have added attribute city_id for entity CUSTOMER_ADDRESS. Address was created in register form. But it wasn't able to save data for the custom attributes.

When debugging, I see that the address was saved by:

  • In: vendor/magento/module-customer/Model/ResourceModel/AddressRepository.php
    /**
     * Save customer address.
     *
     * @param \Magento\Customer\Api\Data\AddressInterface $address
     * @return \Magento\Customer\Api\Data\AddressInterface
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function save(\Magento\Customer\Api\Data\AddressInterface $address)
    {
        $addressModel = null;
        $customerModel = $this->customerRegistry->retrieve($address->getCustomerId());
        if ($address->getId()) {
            $addressModel = $this->addressRegistry->retrieve($address->getId());
        }

        if ($addressModel === null) {
            $addressModel = $this->addressFactory->create();
            $addressModel->updateData($address);
            $addressModel->setCustomer($customerModel);
        } else {
            $addressModel->updateData($address);
        }
        ...
    }

Address model will call updateData to populate $address data into Address Model.

     /**
     * Update Model with the data from Data Interface
     *
     * @param AddressInterface $address
     * @return $this
     * Use Api/RepositoryInterface for the operations in the Data Interfaces. Don't rely on Address Model
     */
    public function updateData(AddressInterface $address)
    {
        // Set all attributes
        $attributes = $this->dataProcessor
            ->buildOutputDataArray($address, '\Magento\Customer\Api\Data\AddressInterface');

        foreach ($attributes as $attributeCode => $attributeData) {
            if (AddressInterface::REGION === $attributeCode) {
                $this->setRegion($address->getRegion()->getRegion());
                $this->setRegionCode($address->getRegion()->getRegionCode());
                $this->setRegionId($address->getRegion()->getRegionId());
            } else {
                $this->setDataUsingMethod($attributeCode, $attributeData);
            }
        }
        ...
    }

I have rewritten class Magento\Customer\Api\Data\AddressInterface in di.xml to my custom class to add method setCityId() and getCity(). But it doesn't impact to the current process, the system only gets attribute from the interface Magento\Customer\Api\Data\AddressInterface. My rewrite doesn't impact to this process.

I have another solution. We need to rewrite updateData function and manually set my custom value, but I would like to clarify in this point.

$attributes = $this->dataProcessor
            ->buildOutputDataArray($address, '\Magento\Customer\Api\Data\AddressInterface');

I see the method buildOutputDataArray will be Reflection class \Magento\Customer\Api\Data\AddressInterface, but why it doesn't take my rewritten class (My class in di.xml is Voo\Customer\Model\Data\Address reference to Magento\Customer\Api\Data\AddressInterface).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.