Skip to content

Extending custom rules

Greg Bowler edited this page Mar 5, 2023 · 1 revision

The validation rules that are part of the HTML standard cover the common use cases for most web applications, but are limited in two ways:

  1. Complexity of rules is limited by default

This is due to the default rules being generic in approach. The default rules must be applicable to all web applications, so can't ever be too specific.

  1. Rules are not aware of anything other than one input's value

If the validity of an input depends on the value of another input, or an external data source, we will have to implement our own rules - for example, making it invalid to use a password that contains your username, or making it invalid to pick a username that's already used by another user.

The ValidationRules class

To define your own rules, create an instance of a class that extends ValidationRules. This class can be provided individual Rule objects, or it can extend the DefaultValidationRules to add to the rules defined in the HTML standard.

The ValidationRules object is passed into the Validator class's constructor.

Example: default rules with one additional rule - the password is invalid if it contains the username

Define the Rule:

class UsernameNotWithinPassword extends Rule {
	public function isValid(Element $element, string $value, array $inputKvp):bool {
		if($element->type !== "password") {
			return true;
		}

		return !str_contains($value, $inputKvp["username"]);
	}

	public function getHint(Element $element, string $value):string {
		return "The password must not contain the username";
	}
};

Adding the custom Rule to the ValidationRules:

$rules = new DefaultValidationRules();
$rules->addRule($usernameNotWithinPasswordRule);

Performing the input validation:

$validator = new Validator($rules);

try {
	$validator->validate($form, [
		"username" => "g105b",
		"password" => "g105b-password",
	]);
}
catch(ValidationException $exception) {
// Handle the excpetion by displaying the errors provided in $validator->getLastErrorList()
}