Validator

Introduction

The Validator class in JiFramework provides a robust and flexible way to validate user input and data structures against a set of defined rules. It simplifies the process of ensuring data integrity and consistency within your application by offering a range of built-in validation methods, as well as the ability to add custom validation rules and error messages.

Key Features:

  • Data Validation: Validate individual fields or entire data arrays against predefined or custom rules.
  • Customizable Error Messages: Define custom error messages for specific fields and rules.
  • Custom Validation Rules: Extend the validator with your own validation logic.
  • Nested Data Support: Validate nested data structures using dot notation.
  • Default Validation Rules: Includes common validation rules such as required, email, min, max, numeric, regex, date, in, alpha, alphaNum, confirmed, and more.

Usage Options:

// Option 1: Initialize the Validator through the App
use JIFramework\Core\App\App;

$app = new App();
$validator = $app->validator;

// Option 2: Instantiate the Validator directly
use JIFramework\Core\Utilities\Validator;

$validator = new Validator();

Explanation:

  • Option 1: Initializes the App class and retrieves the Validator instance through it, using the framework's main entry point.
  • Option 2: Directly creates an instance of the Validator class

validateField()

Method: validateField($value, $rules): bool

Description: Validates a single value against a set of rules.

Parameters:

  • $value (mixed): The value to validate.
  • $rules (string|array): The validation rules, either as a string with rules separated by | or as an array.

Returns: true if validation passes, false otherwise.

Usage:

$isValid = $validator->validateField('[email protected]', 'required|email');
/*
Sample $isValid:

true
*/

if ($isValid) {
    echo "The email is valid.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Validates the provided value against the specified rules.
  • Errors can be retrieved using the errors() method if validation fails.

validateArray()

Method: validateArray(array $data, array $rules): bool

Description: Validates an array of data against a set of rules.

Parameters:

  • $data (array): The data to validate, typically $_POST or similar.
  • $rules (array): An associative array where keys are field names and values are validation rules.

Returns: true if validation passes, false otherwise.

Usage:

$data = [
    'username' => 'john_doe',
    'email'    => '[email protected]',
    'password' => 'secret',
    'password_confirmation' => 'secret',
];

$rules = [
    'username' => 'required|alphaNum|min:5',
    'email'    => 'required|email',
    'password' => 'required|min:6|confirmed',
];

$isValid = $validator->validateArray($data, $rules);
/*
Sample $isValid:

true
*/

if ($isValid) {
    echo "All inputs are valid.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Validates each field in $data against its corresponding rule in $rules.
  • Supports nested fields using dot notation (e.g., address.street).

addRule()

Method: addRule(string $ruleName, callable $callback): self

Description: Adds a custom validation rule to the validator.

Parameters:

  • $ruleName (string): The name of the custom rule.
  • $callback (callable): A function that implements the validation logic.

Returns: The Validator instance (self) to allow method chaining.

Usage:

$validator->addRule('even', function ($field, $value, $params, $data) {
    return $value % 2 === 0;
});

$data = ['number' => 4];
$rules = ['number' => 'required|even'];

$isValid = $validator->validateArray($data, $rules);
/*
Sample $isValid:

true
*/

if ($isValid) {
    echo "The number is even.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • The custom rule even checks if a number is even.
  • Custom rules can access the field name, value, parameters, and entire data array.

addMessages()

Method: addMessages(array $messages): self

Description: Adds custom error messages to the validator.

Parameters:

  • $messages (array): An associative array of custom error messages.

Returns: The Validator instance (self) to allow method chaining.

Usage:

$customMessages = [
    'username.required' => 'Please enter your username.',
    'email.email'       => 'Please provide a valid email address.',
    'password.min'      => 'Password must be at least :param0 characters long.',
];

$validator->addMessages($customMessages);

$isValid = $validator->validateArray($data, $rules);

if (!$isValid) {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Custom messages can be specific to a field and rule (e.g., username.required) or generic for a rule (e.g., required).
  • Placeholders like :param0 can be used to include parameters in messages

errors()

Method: errors(): array

Description: Retrieves the validation errors after a failed validation attempt.

Parameters: None

Returns: An associative array of errors, where keys are field names and values are arrays of error messages.

Usage:

if (!$isValid) {
    $errors = $validator->errors();
    /*
    Sample $errors:

    [
        'username' => ['Please enter your username.'],
        'email' => ['Please provide a valid email address.'],
    ]
    */

    foreach ($errors as $field => $messages) {
        foreach ($messages as $message) {
            echo $message . "\n";
        }
    }
}

Explanation:

  • Use errors() to access detailed error messages for each field.
  • Errors can be displayed to the user or logged for debugging.

Validation Rules

The Validator class comes with a set of built-in validation methods. Below are the available rules and their descriptions:

Required Rules:

required: The field must not be empty.

'username' => 'required'

String Rules:

min: The field must have a minimum length of value.

'password' => 'min:6'

max: The field must have a maximum length of value.

'username' => 'max:20'

alpha: The field may only contain alphabetic characters.

'first_name' => 'alpha'

alphaNum: The field may only contain alphanumeric characters.

'username' => 'alphaNum'
Numeric Rules

numeric: The field must be a number.

'age' => 'numeric'
Email and Date Rules

email: The field must be a valid email address.

'email' => 'required|email'

date: The field must be a valid date.

'birthdate' => 'date'
Confirmation Rules

confirmed: The field must match the value of field_confirmation.

'password' => 'required|confirmed'
Pattern Rules

regex: The field must match the given regular expression pattern.

'username' => 'regex:/^[A-Za-z0-9_]+$/'
Inclusion Rules

in,value2,...: The field must be one of the given values.

'status' => 'in:active,inactive,pending'
Custom Rules

You can add your own validation rules using the addRule() method.

Usage Examples

Example 1: Validating User Registration Data

$data = [
    'username'              => 'john_doe',
    'email'                 => '[email protected]',
    'password'              => 'secret123',
    'password_confirmation' => 'secret123',
];

$rules = [
    'username' => 'required|alphaNum|min:5|max:15',
    'email'    => 'required|email',
    'password' => 'required|min:8|confirmed',
];

$isValid = $validator->validateArray($data, $rules);

if ($isValid) {
    echo "Registration data is valid.";
} else {
    $errors = $validator->errors();
    foreach ($errors as $field => $messages) {
        foreach ($messages as $message) {
            echo $message . "\n";
        }
    }
}

/*
Sample Output (if validation fails):

The password field must be at least 8 characters.
The email field must be a valid email address.
*/

Explanation:

  • Validates user input data for registration.
  • Checks that the password is confirmed and meets length requirements.
  • Outputs error messages if validation fails.

Example 2: Adding a Custom Validation Rule

// Add a custom rule to check if a value is a palindrome
$validator->addRule('palindrome', function ($field, $value, $params, $data) {
    return $value === strrev($value);
});

$data = ['word' => 'radar'];
$rules = ['word' => 'required|palindrome'];

$isValid = $validator->validateArray($data, $rules);

if ($isValid) {
    echo "The word is a palindrome.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Adds a custom rule palindrome to validate palindromic strings.
  • Validates the data against the new rule.
  • Demonstrates the flexibility of adding custom validation logic.

Example 3: Using Custom Error Messages

$customMessages = [
    'username.required' => 'We need to know your username!',
    'email.email'       => 'That doesn\'t look like a valid email.',
    'password.confirmed'=> 'Your passwords do not match.',
];

$validator->addMessages($customMessages);

$data = [
    'username' => '',
    'email'    => 'invalid-email',
    'password' => 'secret',
    'password_confirmation' => 'not_secret',
];

$rules = [
    'username' => 'required',
    'email'    => 'email',
    'password' => 'confirmed',
];

$isValid = $validator->validateArray($data, $rules);

if (!$isValid) {
    $errors = $validator->errors();
    foreach ($errors as $field => $messages) {
        foreach ($messages as $message) {
            echo $message . "\n";
        }
    }
}

/*
Sample Output:

We need to know your username!
That doesn't look like a valid email.
Your passwords do not match.
*/

Explanation:

  • Demonstrates how to customize error messages for specific fields and rules.
  • Enhances user experience by providing friendly and meaningful feedback.

Example 4: Validating Nested Data with Dot Notation

$data = [
    'user' => [
        'name' => 'Alice',
        'email' => '[email protected]',
        'address' => [
            'street' => '123 Main St',
            'city'   => 'Wonderland',
            'zip'    => '12345',
        ],
    ],
];

$rules = [
    'user.name'            => 'required|alpha',
    'user.email'           => 'required|email',
    'user.address.street'  => 'required',
    'user.address.city'    => 'required',
    'user.address.zip'     => 'required|numeric',
];

$isValid = $validator->validateArray($data, $rules);

if ($isValid) {
    echo "User data is valid.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Validates nested data structures using dot notation for field names.
  • Ensures that all required fields in nested arrays are present and valid.

Example 5: Validating File Upload Data

Assuming you have file upload data in $_FILES, which typically requires special handling, but you can validate related data like file names and types.

use JIFramework\Core\Utilities\Validator;

$validator = new Validator();

$data = [
    'file_name' => $_FILES['uploaded_file']['name'] ?? '',
    'file_size' => $_FILES['uploaded_file']['size'] ?? 0,
];

$rules = [
    'file_name' => 'required',
    'file_size' => 'required|numeric|max:1048576', // Max 1MB
];

$isValid = $validator->validateArray($data, $rules);

if ($isValid) {
    echo "File data is valid.";
} else {
    $errors = $validator->errors();
    print_r($errors);
}

Explanation:

  • Validates file name and size before processing the upload.
  • Prevents files that exceed the maximum allowed size.