Creating a custom validator type
Creating a custom validator is very easy. In principle, you have two options: extending / modifying / overriding one of the existing validators, or creating a completely custom validator from scratch – a brand new validator type. Let's see how to do it.
Extending / Modifying an Existing Validator
The principle is simple: using inheritance, you modify the original class and bind it to the given type using the factory system. Here is an example:
namespace JetApplication;
use Jet\Validator_Date;
class MyDateValidator extends Validator_Date {
public const ERROR_CODE_FORBIDDEN_DAY = 'forbidden_day';
public function validate_value( mixed $value ): bool
{
if(!parent::validate_value( $value )) {
return false;
}
if($value=='1980-08-13') {
$this->setError(static::ERROR_CODE_FORBIDDEN_DAY);
return false;
}
return true;
}
public function getErrorCodeScope() : array
{
$codes = parent::getErrorCodeScope();
$codes[] = static::ERROR_CODE_FORBIDDEN_DAY;
return $codes;
}
}
And then all you need to do is replace the old validator with the new one. This means adding this line of code to the initialization script application/Init/Factory.php:
use Jet\Factory_Validator;
Factory_Validator::setValidatorClassName( MyDateValidator::getType(), MyDateValidator::class );
Creating a Completely Custom Validator
Creating a custom validator uses the exact same principle, with the difference that your class will inherit directly from the Validator class and must implement more methods. At the same time, we will use this example to demonstrate how to define attributes for the validator definition.
use Jet\Validator;
use Jet\Entity_Validator_Definition_ValidatorOption;
class MySuperbValidator extends Validator {
protected static string $type = 'my_superb_validator';
public const ERROR_CODE_EXAMPLE = 'example_error_code';
protected array $error_messages = [
self::ERROR_CODE_EMPTY => 'Missing value',
self::ERROR_CODE_EXAMPLE => 'Example error message',
];
#[Entity_Validator_Definition_ValidatorOption(
type: Entity_Validator_Definition_ValidatorOption::TYPE_INT,
label: 'Minimal value',
getter: 'getMinimalValue',
setter: 'setMinimalValue',
)]
protected ?int $minimal_value = null;
public function getMinimalValue(): ?int
{
return $this->minimal_value;
}
public function setMinimalValue( ?int $minimal_value ): void
{
$this->minimal_value = $minimal_value;
}
public function validate_value( mixed $value ): bool
{
if(
$this->minimal_value!==null &&
$value < $this->minimal_value
) {
$this->setError(static::ERROR_CODE_EXAMPLE, ['minimal_value'=>$this->minimal_value]);
return false;
}
return true;
}
public function getErrorCodeScope(): array
{
$codes = [
static::ERROR_CODE_EXAMPLE
];
if($this->is_required) {
$codes[] = static::ERROR_CODE_EMPTY;
}
return $codes;
}
}
Please note the usage of Entity_Validator_Definition_ValidatorOption. This is how attributes are defined for validators. The Entity_Validator_Definition_ValidatorOption class takes care of complete validator attribute management; you just need to define the attribute like this.
Now all that remains is to register the new validator. This again means adding this line of code to the initialization script application/Init/Factory.php:
use Jet\Factory_Validator;
Factory_Validator::registerNewValidatorType( MySuperbValidator::getType(), MySuperbValidator::class );