Magento 2 Validation XML usage
September 11, 2021
Magento 2 uses etc/validation.xml
file to define validation rule for a particular group. Though the usage of this file is not widespread, it could be nice to see validation in a single place. In that way they could be more managable.
Let’s take Magento_Customer
module’s validation.xml
as an example.
<?xml version="1.0" encoding="UTF-8"?>
<validation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Validator/etc/validation.xsd">
<entity name="customer_address">
<rules>
<rule name="check_eav">
<entity_constraints>
<constraint alias="eav_data_validator" class="Magento\Eav\Model\Validator\Attribute\Data" />
</entity_constraints>
</rule>
</rules>
<groups>
<group name="save">
<uses>
<use rule="check_eav"/>
</uses>
</group>
</groups>
</entity>
</validation>
Before jumping onto how to call these verification we need tp define our validatior constraint class Magento\Eav\Model\Validator\Attribute\Data
.
<?php
namespace Magento\Eav\Model\Validator\Attribute;
class Data extends \Magento\Framework\Validator\AbstractValidator
{
public function isValid($entity)
{
/** @var $attributes Attribute[] */
$attributes = $this->_getAttributes($entity);
$data = [];
if ($this->_data) {
$data = $this->_data;
} elseif ($entity instanceof \Magento\Framework\DataObject) {
$data = $entity->getData();
}
foreach ($attributes as $attribute) {
$attributeCode = $attribute->getAttributeCode();
if (!$attribute->getDataModel() && !$attribute->getFrontendInput()) {
continue;
}
$dataModel = $this->_attrDataFactory->create($attribute, $entity);
$dataModel->setExtractedData($data);
if (!isset($data[$attributeCode])) {
$data[$attributeCode] = '';
}
$result = $dataModel->validateValue($data[$attributeCode]);
if (true !== $result) {
$this->_addErrorMessages($attributeCode, (array)$result);
}
}
return count($this->_messa ges) == 0;
}
As you the sample code above \Magento\Framework\Validator\AbstractValidator
class is extended and isValid
attribute overriden. You can do number of validations here as per your business requirement. _addErrorMessages
adds messages into a protected variable `messages’ where it’s finally checked to justify whether validation is passed.
You may think that these fields are automatically being injected related entity but unfortunately they’re not. It’s kind of cool as you have more control on when to use it.
Well… How does it work If it’s not being automatically injected ? Here it’s the usage.
<?php
namespace Magento\Customer\Model\ResourceModel;
class Address extends \Magento\Eav\Model\Entity\VersionControl\AbstractEntity
{
// ...
protected function _validate($address)
{
//...
// Validation rule is being called by "entity" name and group name that's defined on etc/validation.xml;
$validator = $this->_validatorFactory->createValidator('customer_address', 'save');
if (!$validator->isValid($address)) {
throw new \Magento\Framework\Validator\Exception(
null,
null,
$validator->getMessages()
);
}
}
// ...
}