Can Yildirim's Blog

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() ); } } // ... }

Can Yildirim

Written by Can Yildirim who lives in London. Full Stack Software Engineer. Follow me on Twitter Linkedin

© 2023,