Porzucamy poprzedni projekt walidatora, ale zachowujemy konwencję, w jakiej podchodziliśmy do walidacji. Rozpoczynamy pisanie walidatora z prawdziwego zdarzenia.

Na początek ku pamięci jak będą wyglądać nasze reguły oraz same formData:

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];

Teraz interfejs klasy reguła:

interface RuleInterface
{
  public function validate(array $data, string $field, array $params): bool;

  public function getMessage(array $data, string $field, array $params): string;
}

Metoda validate przyjmuje dane (czyli całe form data), nazwę pola oraz opcjonalnie parametry (dodatkowe argumenty, dla 'match’ jest to 'password’).

My chcemy napisać prostą regułę sprawdzającą dla 'required’ czy dane pole istnieje:

class RequiredRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return !empty($data[$field]);
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "This field is required.";
  }
}

Teraz przykład użycia:

<?php 

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];



interface RuleInterface
{
  //(...)
}

class RequiredRule implements RuleInterface
{
  //(...)
}

$field = 'email';
$required_rule = new RequiredRule;
var_dump($required_rule->validate($form_data, $field, []));
//true

Teraz możemy wypróbować metodę getMessage:

<?php 

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email1' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];


//(...)

$field = 'email';
$required_rule = new RequiredRule;
$field_exists = $required_rule->validate($form_data, $field, []);
if(!$field_exists){
    echo "$field: " . $required_rule->getMessage($form_data, $field, []);
}
//email: This field is required.

Swoją drogą możemy logikę przenieść właśnie do tej funkcji, ale musimy (ze względu na przyszłą strukturę projektu) trzymać się tej konwencji podawania argumentów jako data, pole i ewentualne parametry:

/*
$form_rules =  [
    'email' => ['required', 'email'],
    'password' => ['required'],
    'confirmPassword' => ['required', 'match:password']
];
*/

$form_data = [ 
    'email1' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];


interface RuleInterface
{
  public function validate(array $data, string $field, array $params): bool;

  public function getMessage(array $data, string $field, array $params): string;
}

class RequiredRule implements RuleInterface
{
  public function validate(array $data, string $field, array $params): bool
  {
    return !empty($data[$field]);
  }

  public function getMessage(array $data, string $field, array $params): string
  {
    return "Field {$field} is missing!";
  }
}

$field = 'email';
$required_rule = new RequiredRule;
$field_exists = $required_rule->validate($form_data, $field, []);
if(!$field_exists){
    echo $required_rule->getMessage($form_data, $field, []);
}
//Field email is missing!

Zamieńmy ’email1′ na ’email’, a wiadomość o błędzie zniknie:

$form_data = [ 
    'email' => 'john.doe@gmail.com',
    'password' => md5('helloworld'),
    'confirmPassword' => md5('helloworld')
];