ADOBE COMMERCE

Customer Address Validation in Adobe Commerce

Oleg Blinnikov

customer_address_validation_in_adobe_commerce_cloud Customer Address validation in Adobe Commerce Cloud

Address validation is an essential step in customer management processing. Adobe Commerce provides a set of validation rules by default. But each company has its own processing rules, which can depend on many factors. These may include the location of the customer/company, ERP constraints, shipping provider rules, or other factors. So let's take a look at how we can add new rules to the standard Adobe Commerce workflow.

We can easily extend Magento with custom validators. Without the need to override core functions, create plugins, observers, etc.

The most important extension point is this class:

Magento\Customer\Model\Address\CompositeValidator

This class collects all validators defined in di.xml. The validate(AbstractAddress $address) method then validates address instances against these validators. If a validation fails, the method returns an array of errors.

To add a custom validator, we need to perform few steps in the custom module:

Step 1: Create module registration.php

<?php
declare(strict_types=1);

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Comwrap_AddressValidation', __DIR__);

Step 2: Create 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="Comwrap_AddressValidation">
        <sequence>
            <module name="Magento_Customer"/>
        </sequence>
    </module>
</config>

Step 3: Create composer.json

{
  "name": "comwrap/address-validation",
  "version": "1.0.0",
  "description": "Module implements bunch of requirements on address validation",
  "type": "magento2-module",
  "require": {
      "magento/framework": "*",
      "magento/module-customer": "*"
  },
  "license": [
    "Proprietary"
  ],
  "autoload": {
    "files": [
      "registration.php"
    ],
    "psr-4": {
      "Comwrap\\AddressValidation\\": ""
    }
  }
}

Step 4: Create 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">
    <type name="Magento\Customer\Model\Address\CompositeValidator">
        <arguments>
            <argument name="validators" xsi:type="array">
                <item name="encoding" xsi:type="object">Comwrap\AddressValidation\Model\Address\Validator\Encoding</item>
            </argument>
        </arguments>
    </type>
</config>

Step 5: Adding custom validator class

Create the Comwrap\AddressValidation\Model\Address\Validator\Encoding.php. The class must implement interface \Magento\Customer\Model\Address\ValidatorInterface and implement method validate.

Here is an example for encoding validation:

<?php
declare(strict_types=1);

namespace Comwrap\AddressValidation\Model\Address\Validator;

use Magento\Customer\Model\Address\AbstractAddress;
use Magento\Customer\Model\Address\ValidatorInterface;

class Encoding implements ValidatorInterface
{
    /**
     * Error Message
     */
    public const ERROR_MESSAGE = 'Sorry, please use "/standard/" Western European characters only. Field: %fieldName';

    /**
     * @inheritdoc
     */
    public function validate(AbstractAddress $address): array
    {
        $errors = [];
        foreach ($address->getData() as $key => $value) {
            if ($value && is_string($value) && !$this->isValid($value)) {
                $errors[] = __(self::ERROR_MESSAGE, ['fieldName' => $key]);
            }
        }

        return $errors;
    }

    /**
     *
     * Basically, this validator tries to convert a string to ISO-8859-15 using iconv()
     * If iconv() fails, we assume that the string includes characters that do not fit our encoding
     *
     * @param string $value
     * @return bool
     */
    public function isValid(string $value): bool
    {
        // convert the string, if iconv fails the string was not proper
        $convertedString = @iconv('UTF-8', 'ISO-8859-15', $value);

        return (bool)$convertedString;
    }
}

Now install the new module like:

php bin/magento module:enable Comwrap_AddressValidation
php bin/magento setup:upgrade
php bin/magento cache:flush

As you can see, in this manner you can add any custom validation rule. Including simple validations or some more complex validations against APIs.

Photo by Erol Ahmed on Unsplash