Whenever a value is saved to a Component Repository and whenever a value is retrieved via the getValue()
method of the Component View Model, the value is automatically validated. Validators are added to the component entry in etc/loki_components.xml
and are fully extensible.
To add a validator to an component - either a new component or an existing component - create a file etc/loki_components.xml
, find or add an entry for the component in question and then add a new <validator/>
tag to it.
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
<component name="loki-components.example">
<validator name="number" />
</component>
</components>
Let's say that the component value is a string foobar
, then the string FOOBAR
will not validate correctly and will not be saved to the repository. Let's say that the string foobar
has been saved before, then the value will be retrieved via the ComponentViewModel::getValue()
method and will be fully used. However, validation messages will be sent (by default, local messages).
If the component value is an array, each entry in the array is validated as well.
Because validation could be expensive (by using remote APIs), when a value is saved to the repository and retrieved again by the ViewModel in the same AJAX request, validation only will occur once.
Validators are identified in the etc/loki_components.xml
file by their name. This name is declared together with a corresponding validator class via the constructor of the class Loki\Components\Validator\ValidatorRegistry
.
The following validators exist by default:
required
number
positive_number
length
email
date
past_date
Some validators (like length
) allow configuration via the XML layout (minlength
, maxlength
).
Other modules, like LokiCheckout_Core
, can add additional validators as well: password_complexity
, email_available
, dob
, gender
, postcode
, iban
, etcetera. And you can add your own custom validators.
To add a new validator, an di.xml
entry is needed:
<?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="Loki\Components\Validator\ValidatorRegistry">
<arguments>
<argument name="validators" xsi:type="array">
<item name="badWords" xsi:type="object">YireoTraining\ExampleComponent\Validator\BadWords</item>
</argument>
</arguments>
</type>
</config>
Next, the PHP class YireoTraining\ExampleComponent\Validator\BadWords
needs to be implementing the Loki\Components\Validator\ValidatorInterface
interface. This could a bit like the following:
<?php declare(strict_types=1);
namespace YireoTraining\ExampleComponent\Validator;
use Loki\Components\Validator\ValidatorInterface;
class BadWords implements ValidatorInterface
{
public function validate(mixed $value, ?ComponentInterface $component = null): bool|array
{
if (false === is_string($value) || empty($value)) {
return true;
}
if (false === str_contains($value, 'fart')) {
return true;
}
return [__('Go wash your mouth')];
}
}
And now the validator can be applied:
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Loki_Components:etc/loki_components.xsd">
<component name="loki-components.example">
<validator name="badWords" />
</component>
</components>
Client-side validation is not included with the Loki Components package. The Loki Field Components package does offer a client-side validation, which is then heavily extended by the Loki Checkout.
See Client-side validation of Field Components