Validation - legacy

The following documentation is for Editor's PHP libraries prior to v1.7 which introduced a more functional approach to the validation, providing better integration with IDE auto-completion and matching the PHP and .NET libraries for Editor. If you are developing a new project, please refer to the current validation documentation, but also be aware that care has been taken to ensure that the 1.7 libraries remain compatible with the older style of validation setup.

If you decide to update your 1.6 or earlier validators to 1.7, normally this is simply a case of removing the quotes around the validation function string, adding parenthesis, and if any parameters were passed in, they should become arguments for the new validation function - e.g.

->validator( 'Validator::minNum', 10 );

would become:

->validator( Validator::minNum( 10 ) );

The remainder of this document relates to the legacy validation style only.

Validation function

The validation function given is either a function defined as a member of the Editor Validate class, or an anonymous function which you can provide to perform custom validation. As an example of each:

// Use the `notEmpty` validation method
Field::inst( 'first_name' )->validator( 'Validate::notEmpty' )

// Use a custom validation method through a closure
Field::inst( 'last_name' )->validator( function ( $val, $data, $field ) {
    return strlen( $val ) > 50 ?
        'Name length must be 50 characters or less' :
        true;
} );

The validator methods have the following signature:

  • Parameter 1: $val - The value to check for this field - this is the wire data - i.e. the raw data submitted by the client, before any formatting has been applied by the setFormatter() method (if it is used).
  • Parameter 2: $data - The whole data set that was submitted (useful for multiple field validation)
  • Parameter 3: $field - The field instance.
  • Return: true if valid. A string containing an error message that the end user will see if not valid (succinctly explaining why the validation has failed).

Options

The second parameter that the validator() method takes is optional, and can be used to customise the validation options for the field, and also how the validator handles empty or not present data. The validation options can always be given as an associative array, or a single parameter - the exact definition and meaning of which depends upon each field.

Each validation type shares common validation options which can be controlled using this option, when given as an associate array. These are:

  • empty - Indicate if the field is allowed to be empty (i.e. zero length). Default: true.
    • true - The field is allowed to be zero length
    • false - The field cannot be zero length
  • message - Error message to show for the field if it is found to not be valid. Default: 'Input not valid'.
  • optional - Indicate if the field must be in the submitted data or not. Default: true
    • true - The field is not required in the data set
    • false - The field is required
  • required - This is a short-cut for setting both empty and optional to false. If set the other two parameters cannot be used to override. Default false.

Each validation type can also specify its additional optional - the dateFormat validation method provides the format option for example, which is used to specify the valid input date format.

Furthermore, the second parameter need not be given or can be given as a value specified by the validation method. In either case the default validation options described above will be applied.

To illustrate by means of example, consider the dateFormat validation option:

// Validate a date with a specific format
Field::inst( 'start_date' )
    ->validator( 'Validate::dateFormat', Format::DATE_ISO_8601 )

// Identical validation, using an associative array
Field::inst( 'start_date' )
    ->validator( 'Validate::dateFormat', array(
        "format"  => Format::DATE_ISO_8601
    ) )

These two validations are identical. In the first case the default validation options are used, and the format given as the second parameter used to validate the input data. In the second case the format is given as the format parameter in an associative array. The advantage of doing it this way is that you can provide values for the other field validation options.

Multiple validators

It can often be useful to use multiple validators together, for example to confirm that an input string is less than a certain number of characters and also that it is unique in the database. Multiple validators can be added to a field simply by calling the Field->validator() method multiple times. Rather than overwriting the previous validator it will in fact add them together. They are run in the sequence they were added, and all validators must pass for the data to be accepted as valid.

As an example consider the following code which will check the min and max length of the data, and also that it is unique:

Field::inst( 'stock_name' )
    ->validator( 'Validate::minLen', 10 )
    ->validator( 'Validate::maxLen', 12 )
    ->validator( 'Validate::unique' );

Ready to use field validators

The Validate class in the Editor PHP libraries has a number of methods which can be used to perform validation very quickly and easily. These are:

Basic

  • none - No validation is performed
  • required - The field must be submitted and the data must not be zero length. Note that Editor has the option of not submitting all fields (for example when inline editing), so the NotEmpty() validator is recommended over this one.
    • Default error message: 'This field is required'
  • notEmpty - The field need not be submitted, but if it is, it cannot contain zero length data
    • Default error message: 'This field is required'
  • boolean - Check that boolean data was submitted (including 1, true on, yes, 0, false, off and no)
    • Default error message: 'Please enter true or false'

Numbers

  • numeric - Check that any input is numeric.
    • Default error message: 'This input must be given as a number
    • Option: decimal - The character used as the decimal marker in the number (default: .)
  • minNum - Check for a numeric input and that it is greater than a given value.
    • Default error message: 'Number is too small, must be {min} or larger'
    • Option: min - The minimum value
    • Option: decimal - The character used as the decimal marker in the number (default: .)
  • maxNum - Check for a numeric input and that it is less than a given value.
    • Default error message: 'Number is too large, must be {max} or smaller'
    • Option: max - The maximum value
    • Option: decimal - The character used as the decimal marker in the number (default: .)
  • minMaxNum - Check for a numeric input and that it is both greater and smaller than the given numbers.
    • Default error message: As per minNum and maxNum
    • Option: min - The minimum value
    • Option: max - The maximum value
    • Option: decimal - The character used as the decimal marker in the number (default: .).

Strings

  • email - Validate an input as an e-mail address.
    • Default error message: 'Please enter a valid e-mail address'
  • ip - Validate as an IP address.
    • Default error message: 'Please enter a valid IP address'
  • minLen - Validate a string has a minimum length.
    • Default error message: 'The input is too short. {min} characters required ({calculated} more required)'
    • Option: min - The minimum string length
  • maxLen - Validate a string does not exceed a maximum length.
    • Default error message: 'The input is {calculated} characters too long'
    • Option: max - The maximum string length
  • minMaxLen -
    • Default error message: As per minLen and maxLen
    • Option: min - The minimum string length
    • Option: max - The maximum string length
  • noTags - Don't allow HTML tags
    • Default error message: 'This field may not contain HTML'
  • url - Validate as an URL address.
    • Default error message: 'Please enter a valid URL'
  • values - Allow only values which have been specified in an array of options. This could be useful if you wish to have free-form input or even a select list, and want to confirm that the value submitted is within a given data set (see also the dbValues method if valid values are stored in a database).
    • Default error message: 'This value is not valid'
    • Option: valid - An array of values which are valid. Please note that the values are case sensitive.
  • xss - Check to see if the field may contains data that could carry an XSS attack. This is done by running the Field's XSS formatter and checked to see if the result is different from the input.
    • Default error message: 'This field contains potentially unsafe data'

Date / time

  • dateFormat - Check that a valid date input is given
    • Default error message: 'Date is not in the expected format'
    • Option: format - The data format to check, using the PHP date() format options.

Database

  • dbValues - Allow only a value that is present in a database column. This is specifically designed for use with joined tables (i.e. ensure that the reference row is present before using it), but it could potentially also be used in other situations where referential integrity is required (Requires Editor 1.5.4 or newer).
    • Default error message: 'This value is not valid'
    • Option: db - The Database object to use. If not given, the Editor instance database connection is automatically used.
    • Option: table - The table to check for unique values. If not given, the table configured the Field->options() method will be used, or an error given if there are no options configured.
    • Option: field - The column name to use when checking for a unique value. If not given the column defined by the Field->options() method will be used, or an error given if there are no options configured.
    • Option: valid - An array of values which are valid in extension to those which are in the defined database column. This can be useful if you wish to allow a null or empty string value to be submitted to break a join. Please note that the values are case sensitive.
  • unique - Ensure that the data submitted is unique in the table's column
    • Default error message: 'This field must have a unique value'
    • Option: db - The Database object to use. If not given, the Editor instance database connection is automatically used.
    • Option: table - The table to check for unique values. If not given, the table configured for the Editor instance is automatically used.
    • Option: field - The column name to use when checking for a unique value. If not given the column for the configured field is automatically used.

Note that if a field has a single option, the value for that option can be given as the second parameter for the Field validator() method.

Field validation examples

// Simple non-empty field
Field::inst( 'first_name' )->validator( 'Validate::notEmpty' )
// Number range check with custom error message
Field::inst( 'range' )->validator( 'Validate::minMaxNum', array(
    'min' => 10,
    'max' => 100,
    'message' => 'Please enter a number between 10 and 100'
) );
// E-mail address, which is required (i.e. it must be in the data set and non-zero length)
Field::inst( 'email' )->validator( 'Validate::email', array(
    'required' => true
) );
// Date format check
Field::inst( 'start_date' )
    ->validator( 'Validate::dateFormat', array(
        "format"  => "Y-m-d",
        "message" => "Please enter a date in the format yyyy-mm-dd"
    ) );
// Complete Editor example with validation methods applied
Editor::inst( $db, 'datatables-demo' )
    ->fields(
        Field::inst( 'first_name' )->validator( 'Validate::notEmpty' ),
        Field::inst( 'last_name' )->validator( 'Validate::notEmpty' ),
        Field::inst( 'position' ),
        Field::inst( 'email' ),
        Field::inst( 'office' ),
        Field::inst( 'extn' )->validator( 'Validate::numeric' ),
        Field::inst( 'age' )->validator( 'Validate::numeric' ),
        Field::inst( 'salary' )->validator( 'Validate::numeric' ),
        Field::inst( 'start_date' )
            ->validator( 'Validate::dateFormat', array(
                "format"  => Format::DATE_ISO_8601,
                "message" => "Please enter a date in the format yyyy-mm-dd"
            ) )
            ->getFormatter( 'Format::date_sql_to_format', Format::DATE_ISO_8601 )
            ->setFormatter( 'Format::date_format_to_sql', Format::DATE_ISO_8601 )
    )
    ->process( $_POST )
    ->json();
// A join with `dbValues` which will accept an empty value, which is stored as
// null on the database
Editor::inst( $db, 'users' )
    ->field( 
        Field::inst( 'users.first_name' ),
        Field::inst( 'users.last_name' ),
        Field::inst( 'users.phone' ),
        Field::inst( 'users.site' )
            ->options( 'sites', 'id', 'name' )
            ->validator( 'Validate::dbValues', array( 'valid' => array('') ) )
            ->setFormatter( 'Format::nullEmpty' ),
        Field::inst( 'sites.name' )
    )
    ->leftJoin( 'sites', 'sites.id', '=', 'users.site' )
    ->process($_POST)
    ->json();

Global validators

You may also find it useful to be able to define a global validator that will execute whenever a request is made to the server and the Editor->process() method is executed. This method can be used to provide security access restrictions, validate input data as a whole or even to check that a user is logged in before processing the request.

Function

The function that is given to the Editor->validator() method has the following signature:

  1. $editor - The Editor instance that the function is being executed for.
  2. $action - The action being performed - this will be one of:
    • Editor::ACTION_READ - Read / get data
    • Editor::ACTION_CREATE - Create a new record
    • Editor::ACTION_EDIT - Edit existing data
    • Editor::ACTION_DELETE - Delete existing row(s)
    • Editor::ACTION_UPLOAD - Upload a file.
  3. $data - The data submitted by the client.

The return value from the function should be a string if the validation fails, where the string returned is the error message to show the end user. If the validation passes, return an empty string, null or simply have no return statement.

Note that this function is executed only once when the Editor->process() method is called, rather than once per submitted row.

Examples

// Allow read only access based on a session variable
Editor::inst( $db, 'table' )
    ->fields( ... )
    ->validator( function ( $editor, $action, $data ) {
        if ( $action !== Editor::ACTION_READ && $_SESSION['read_only'] ) {
            return 'Cannot modify data';
        }
    } )
    ->process( $_POST )
    ->json();
// Create and edit with dependent validation
Editor::inst( $db, 'table' )
    ->fields( ... )
    ->validator( function ( $editor, $action, $data ) {
        if ( $action === Editor::ACTION_CREATE || $action === Editor::ACTION_EDIT ) {
            foreach ( $data['data'] as $pkey => $values ) {
                if ( $values['country'] === 'US' && $values['location'] === 'London UK' ) {
                    return 'London UK is not in the US';
                }
            }
        }
    } )
    ->process( $_POST )
    ->json();

PHP API documentation

The PHP API developer documentation for the Editor PHP classes is available for detailed and technical discussion about the methods and classes discussed above.