Validator Component

Form validation that is designed to simplify and work seamlessly with Jörn's jQuery Validation Plugin.

use BootPress\Validator\Component as Validator;

Packagist License MIT HHVM Tested PHP 7 Supported Build Status Code Climate Test Coverage


Form validation that is designed to simplify and work seamlessly with Jörn's jQuery Validation Plugin. All of the validation routines are designed to match (as closely as possible) those provided by Jörn, so that the browser and server validation routines are in sync with one another.

public array $rules ;

@var

Custom validation rules you would like to apply remotely.

@example
$validator->rules['name'] = function ($value) {
    return ($value == 'Charlie') ? true : false;
}
$validator->set('name', 'required|remote[name]');

public array $errors ;

@var

Error messages associated with each validation rule. After checking if $validator->certified(), this will be an empty array if it passes, or contain all the errors if it doesn't. You can customize and add as you see fit.

@example
$validator->errors['name'] = 'Sorry Charlie, try again.';
if ($vars = $validator->certified()) {
    if ($vars['password'] != 'sekrit') {
        $validator->errors['password'] = 'Enter a sekrit password.';
    }
}

public array $menu ;

@var

A field's array of acceptable values which, if specified here, do not need to be included 'inList'.

@example
$validator->menu['name'] = array('Charlie');
$validator->set('name', 'required|inList');

public __construct ( [ array $values ] )

Pass an array of $values to be validated.

@example
$validator = new Validator($_POST);

public set ( string $field [, string|array $rules ] )

This allows you to set individually (or all at once) the validation rules and filters for each form field. The value of every $field you set here is automatically trim()ed and returned when $this->certified().

@param $field

The name of your form field. If this is an array($field => $rules, $field, ...) then we loop through each one and call this method ourselves over and over.

Your $field names can be an array by adding brackets to the end eg. 'name[]'. They can also be multi-dimensional arrays such as 'name[first]', or 'name[players][]', or 'name[parent][child]', etc. The important thing to remember is that you must always use the exact name given here when referencing them in other methods.

@param $rules

A pipe delimited set (or an array) of rules to validate and filter the $field with. You can also specify custom messages by making this an array($rule => $message, ...). Parameters are comma-delimited, and placed within '[]' two brackets. The available options are:

  • 'remote[rule]' - Set $validator->rules['rule'] = function($value){ ... } to determine the validity of a submitted $value. The function should return a boolean true or false.
  • 'default' - A default value if the field is empty, or not even set.
  • 'required' - This field must have a value, and cannot be empty.
  • 'equalTo[field]' - Must match the same value as contained in the other form [field].
  • 'notEqualTo[field]' - Must NOT match the same value as contained in the other form [field].
  • Numbers:
    • 'number' - Must be a valid decimal number, positive or negative, integer or float, commas okay. Defaults to 0.
    • 'integer' - Must be a postive or negative integer number, no commas. Defaults to 0.
    • 'digits' - Must be a positive integer number, no commas. Defaults to 0.
    • 'min[number]' - Must be greater than or equal to [number].
    • 'max[number]' - Must be less than or equal to [number].
    • 'range[min, max]' - Must be greater than or equal to [min], and less than or equal to [max].
  • Strings:
    • 'alphaNumeric' - Alpha (a-z), numeric (0-9), and underscore (_) characters only.
    • 'minLength[integer]' - String length must be greater than or equal to [integer].
    • 'maxLength[integer]' - String length must be less than or equal to [integer].
    • 'rangeLength[minLength, maxLength]' - String length must be greater than or equal to [minLength], and less than or equal to [maxLength].
    • 'minWords[integer]' - Number of words must be greater than or equal to [integer].
    • 'maxWords[integer]' - Number of words must be less than or equal to [integer].
    • 'rangeWords[minWords, maxWords]' - Number of words must be greater than or equal to [minWords], and less than or equal to [maxWords].
    • 'pattern[regex]' - Must match the supplied ECMA Javascript compatible [regex].
    • 'date' - Must be a valid looking date. No particular format is enforced.
    • 'email' - Must be a valid looking email.
    • 'url' - Must be a valid looking url.
    • 'ipv4' - Must be a valid looking ipv4 address.
    • 'ipv6' - Must be a valid looking ipv6 address.
    • 'inList[1,2,3]' - Must be one of a comma-separated list of acceptable values.
    • 'noWhiteSpace' - Must contain no white space.
  • Filters:
    • 'singleSpace' - Removes any doubled-up whitespace so that you only have single spaces between words.
    • 'trueFalse' - Returns a 1 (true) or 0 (false) integer.
    • 'yesNo' - Returns a 'Y' or 'N' value.
@example
$validator->set('name', 'required');

$validator->set('email', 'required|email');

$validator->set(array(
    'password' => 'required|alphaNumeric|minLength[5]|noWhiteSpace',
    'confim' => array('required', 'matches[password]'),
));

$validator->set('field', array('required' => 'Do this or else.'));

public mixed certified ( void )

Goes through every field the $validator->set(), determines if the form has been sent, and picks out any errors.

@return

An array of validated, filtered, and trim()ed form values for every $validator->set('field') IF the form was submitted (ie. at least one field has it's $_GET or $_POST counterpart), AND there were no errors. false if not.

@example
if ($vars = $validator->certified()) {
    // process $vars
}
Document Your Code

Installation

Add the following to your composer.json file.

{
    "require": {
        "bootpress/validator": "^1.0"
    }
}

Example Usage

<?php

use BootPress\Validator\Component as Validator;

$validator = new Validator($_POST);

The first thing you need to do is give us an array of values to validate against. In this case you have given us the $_POST vars. Now you can set the rules and filters for each field.

// Create a custom rule
$validator->rules['name'] = function ($value) {
    return ($value == 'Charlie') ? true : false;
}

// Customize error messages
$validator->errors['name'] = 'Sorry Charlie, try again.';
$validator->errors['required'] = 'Why I Oughta!';

// Require a name
$validator->set('name', 'required|remote[name]');

// Require an email, and make sure it looks like one as well
$validator->set('email', 'required|email');

// Set multiple fields at once
$validator->set(array(
    'password' => 'required|alphaNumeric|minLength[5]|noWhiteSpace', // Using a pipe separated string
    'confirm' => array('required', 'matches[password]'), // Using an array of rules and filters
));

// Set and create a custom required message for this one field
$validator->set('field', array('required' => 'Do this or else.')

To see if the $_POST array you gave us meets all of your requirements:

if ($vars = $validator->certified()) {
    // Add another validation layer
    if ($vars['password'] != 'sekrit') {
        $validator->errors['password'] = 'Enter a sekrit password.';
    } else {
        // Process $vars
    }
} else {
    // The form was either not submitted, or there were errors
}

The $vars returned are all trim()ed and filtered, ready for you to process as you see fit. From here, the best thing to do is use our BootPress Form Component, but if you have any better ideas then the following will come in useful:

public mixed __get ( string $name )

Get the values of the following protected properties:

  • 'data' - (array) Everything the $validator->set() for each field.
  • 'values' - (array) The user submitted values for each field.
  • 'submitted' - (bool|null) true or false if we know whether the form has been submitted or not, and null if we don't know.
  • 'certified' - (mixed) Either false, or an array of all the validated and filtered values.

public bool required ( string $field )

Whether or not a form $field has been required.

public mixed value ( string|array $field )

Get the submitted $field(s) value(s) that should be used when displaying the form. These are the same as the $vars = $validator->certified(). The array feature comes in handy when saving the values to a database.

@return

Either a string, or an array of values depending on the type of $field. If !$validator->submitted, then the value(s) will be null.

public null|string error ( string $field )

Get the error message (if any) that should be used when displaying the form.

public array rules ( string $field )

Validate all of the rules set up for a $field.

@example
foreach ($validator->rules($field) as $validate => $param) {
    $attributes["data-rule-{$validate}"] = htmlspecialchars($param);
}

public array messages ( string $field )

Iterate over a $field's rules and associated error messages.

@example
foreach ($validator->messages($field) as $rule => $message) {
    $attributes["data-msg-{$rule}"] = htmlspecialchars($message);
}

public jquery ( string $form [, array $options ] )

Includes Jörn's jQuery Validation code that this component was meant to sync perfectly with.

@param $form

The jQuery identifier of your form.

@param $options

The rules and custom messages should be added to each inputs 'data-...' attributes using $this->rules() and $this->messages(). Any other fine-tuning can be done here. The $options values must already be json encoded ie. quotes around strings ("string"), brackets for arrays ([]), quoted bools ('false'), etc. The reason for this is because we cannot json_encode functions properly ('function(){}').

@example
$validator->jquery('#form', array('debug'=>'true'));
@see

public string id ( string $field )

Get the unique id assigned to a $field.

Document Your Code

All of the above is just assuming you are using this component to validate submitted form data, but it is equally well suited to validate anything on the side as well. The static methods we provide (and use ourselves) are:

public static bool number ( string $value )

Determine if the $value is a valid decimal number. Can be positive or negative, integer or float, and commas to separate thousandths are okay.

@example
Validator::number(1.345); // true - this is a number
Validator::number('string'); // false

public static bool integer ( string $value )

Determine if the $value is a positive or negative integer number, no commas.

@example
Validator::integer(1000); // true
Validator::integer(1.345); // false - must be a whole number

public static bool digits ( string $value )

Determine if the $value is a positive integer number, no commas.

@example
Validator::digits(1000); // true
Validator::digits(1.345); // false - no periods allowed

public static bool min ( float $value , float $param )

Determine if the $value is greater than or equal to $param.

@example
Validator::min(5, 3); // true - 5 is greater than 3
Validator::min(3, 5); // false - 3 is less than 5

public static bool max ( float $value , float $param )

Determine if the $value is less than or equal to $param.

@example
Validator::max(5, 3); // false - 5 is greater than 3
Validator::max(3, 5); // true - 3 is less than 5

public static bool range ( float $value , float[] $param )

Determine if the $value is greater than or equal to $param[0], and less than or equal to $param[1].

@example
Validator::range(5, array(2, 7)); // true
Validator::range(5, array(6, 7)); // false

public static bool alphaNumeric ( string $value )

Determine if the $value has alpha (a-z), numeric (0-9), and underscore (_) characters only.

@example
Validator::alphaNumeric('abc123'); // true
Validator::alphaNumeric('abc-xyz'); // false

public static bool minLength ( string $value , int $param )

Determine if the $value's length is greater than or equal to $param.

@example
Validator::minLength('string', 2); // true
Validator::minLength('string', 7); // false

public static bool maxLength ( string $value , int $param )

Determine if the $value's length is less than or equal to $param.

@example
Validator::maxLength('string', 7); // true
Validator::maxLength('string', 2); // false

public static bool rangeLength ( string $value , int[] $param )

Determine if the $value's length is greater than or equal to $param[0], and less than or equal to $param[1].

@example
Validator::rangeLength('string', array(2, 6)); // true
Validator::rangeLength('string', array(7, 15)); // false
Validator::rangeLength(array(1, 2), array(2, 4)); // true - there are between 2 and 4 elements in array(1, 2)
Validator::rangeLength(array(1, 2), array(3, 5)); // false - 2 elements is outside the range of 3 and 5

public static bool minWords ( string $value , int $param )

Determine if the number of $value's words are greater than or equal to $param.

@example
Validator::minWords('one two three', 1); // true
Validator::minWords('one two three', 5); // false

public static bool maxWords ( string $value , int $param )

Determine if the number of $value's words are less than or equal to $param.

@example
Validator::maxWords('one two three', 5); // true
Validator::maxWords('one two three', 1); // false

public static bool rangeWords ( string $value , int[] $param )

Determine if the number of $value's words are greater than or equal to $param[0], and less than or equal to $param[1].

@example
Validator::rangeWords('one two three', array(1, 3)); // true
Validator::rangeWords('one two three', array(0, 2)); // false

public static bool pattern ( string $value , string $param )

Determine if the $value matches the supplied regex ($param).

@example
// Allows phone numbers with optional country code, optional special characters and whitespace
$phone_number = '/^([+]?\d{1,2}[-\s]?|)\d{3}[-\s]?\d{3}[-\s]?\d{4}$/';
Validator::pattern('907-555-0145', $phone_number); // true
Validator::pattern('555-0145', $phone_number); // false

public static bool date ( string $value )

Determine if the $value is a parseable date.

@example
Validator::date('2015-12-31'); // true
Validator::date('infinite'); // false

public static bool email ( string $value )

Determine if the $value is a valid looking email.

@example
Validator::email('email@example.com'); // true
Validator::email('email@example..com'); // false

public static bool url ( string $value )

Determine if the $value is a valid looking url.

@example
Validator::url('http://example.com'); // true
Validator::url('example.com'); // false

public static bool ipv4 ( string $value )

Determine if the $value is a valid looking ipv4 address.

@example
Validator::ipv4('175.16.254.1'); // true
Validator::ipv4('2001:0db8:0000:0000:0000:ff00:0042:8329'); // false

public static bool ipv6 ( string $value )

Determine if the $value is a valid looking ipv6 address.

@example
Validator::ipv6('2001:0db8:0000:0000:0000:ff00:0042:8329'); // true
Validator::ipv6('175.16.254.1'); // false

public static bool inList ( string $value , array $param )

Determine if the $value exists in the $param array.

@example
Validator::inList('2', array(1, 2, 3)); // true
Validator::inList(7, array(1, 2, 3)); // false

public static bool noWhiteSpace ( string $value )

Determine if the $value contains any white space.

@example
Validator::noWhiteSpace('whitespace'); // true
Validator::noWhitespace('white space'); // false

public static string singleSpace ( string $value )

Removes any doubled-up whitespace from the $value.

@example
Validator::singleSpace('single     space'); // 'single space'
Validator::singleSpace('single space'); // 'single space'

public static int trueFalse ( mixed $value )

Returns a 1 (true) or 0 (false) integer depending on the $value.

@example
Validator::trueFalse(101)); // 1
Validator::trueFalse('true')); // 1
Validator::trueFalse('n')); // 0
Validator::trueFalse(0)); // 0

public static string yesNo ( mixed $value )

Returns a 'Y' or 'N' string depending on the $value.

@example
Validator::yesNo(101)); // 'Y'
Validator::yesNo('true')); // 'Y'
Validator::yesNo('n')); // 'N'
Validator::yesNo(0)); // 'N'
Document Your Code

The value you want to validate always comes first, and any parameters come second - lest you be confused.