The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Validator::Custom::Guide - Validator::Custom Guide

GUIDE

1. Basic

1. Create a new Validator::Custom object

  use Validator::Custom;
  my $vc = Validator::Custom->new;

2. Prepare data for validation

  my $data = {age => 19, name => 'Ken Suzuki'};

Data must be hash reference.

3. Prepare a rule for validation

  my $rule = [
    age => {message => 'age must be integer'} => [
      'not_blank',
      'int'
    ],
    name => {message => 'name must be string. the length 1 to 5'} => [
      'not_blank',
      {length => [1, 5]}
    ],
    price => [
      'not_blank',
      'int'
    ]
  ];

Rule has specific structure. which consists of several parts, such as parameter name, option, constraint function, constraint argument

  my $rule = [
    PARAMETER_NAME => \%OPTION => [
      CONSTRAINT_NAME1
      {CONSTRAINT_NAME2 => CONSTAINT_ARGUMENT}
    ],
    ...
  ]

You can use many constraint function, such as int, not_blank, length by default. See "CONSTRAINTS" in Validator::Custom to know all constraint functions.

Rule details is explanined in "3. Rule syntax" section.

4. Validate data

  my $result = $vc->validate($data, $rule);

use validate() to validate the data applying the rule. validate() return Validator::Custom::Result object.

5. Manipulate the validation result

  unless ($result->is_ok) {
    if ($result->has_missing) {
      my $missing_params = $result->missing_params;
    }
    
    if ($result->has_invalid) {
      my $messages = $result->messages_to_hash;
    }
  }

If you check the data is completely valid, use is_ok(). is_ok() return true value if invalid parameter values is not found and all parameter names specified in the rule is found in the data.

If at least one of parameter names specified in the rule is not found in the data, has_missing() return true value.

You can get missing parameter names using missing_params(). In this example, return value is the following one.

  ['price']

If at least one of parameter value is invalid, has_invalid() return true value.

You can get the pairs of invalid parameter name and message using messages_to_hash(). In this example, return value is the following one.

  {
    name => 'name must be string. the length 1 to 5'
  }

Validator::Custom::Result details is explained in "2. Validation result".

2. Validation result

validate() return Validator::Custom::Result object. You can manipulate the result by variouse methods.

is_ok(), has_missing(), has_invalid(), missing_params(), messages_to_hash() is already explained in "1. Basic"

The following ones is offten used methods.

data()

  my $data = $result->data;

Get the data in the end state. Validator::Custom has filtering ability. The parameter values in data passed to validate() is maybe converted to other data by filter. You can get filtered data using data().

messages()

  my $messages = $result->messages;

Get messages corresponding to the parameter names which value is invalid. Messages keep the order of parameter names of the rule.

message()

  my $message = $result->message('name');

Get a message corresponding to the parameter name which value is invalid.

All Validator::Custom::Result's APIs is explained in the POD of Validator::Custom::Result

3. Rule syntax

Basic

Rule has specified structure.

Rule must be array reference.

  my $rule = [
  
  ];

This is for keeping the order of parameter names.

Rule has pairs of parameter name and constraint functions.

  my $rule = [
    age =>  [            # paramter name1
      'not_blank',       #   constraint function1
      'int'              #   constraint function2
    ],                                                   
                                                         
    name => [              # parameter name2       
      'not_blank',         #   constraint function1
      {'length' => [1, 5]} #   constraint function2
    ]
  ];

Constraint function can receive arguments using hash reference.

  my $rule = [
    name => [
        {'length' => [1, 5]}
    ]
  ];

You can set message for each constraint function

  my $rule = [
    name => [
        ['not_blank', 'name must be not blank'],
        [{length => [1, 5]}, 'name must be 1 to 5 length']
    ]
  ];

Option

You can set options for each paramter name.

  my $rule = [
           # Option
    age => {message => 'age must be integer'} => [
        'not_blank',
    ]
  ];

Option is located after the paramter name, and option must be hash reference.

The following options is available.

1. message
 {message => "This is invalid"}

Message corresponding to the parameter name which value is invalid.

2. default
  {default => 5}

Default value. This value is automatically set to result data if the paramter value is invalid or the paramter name specified in rule is missing in the data.

3. copy
  {copy => 0}

If this value is 0, The parameter value is not copied to result data.

Default to 1. Parameter value is copied to the data.

4. require

If this value is 0 and parameter value is not found, the parameter is not added to missing paramter list.

Default to 1.

Multiple parameters validation

Multiple parameters validation is available.

  my $data = {password1 => 'xxx', password2 => 'xxx'};
  my $rule = [
    {password_check => [qw/password1 password2/]} => [
        'duplication'
    ]
  ];

In this example, We check if 'password1' and 'password2' is same. The following value is passed to constraint function duplication.

  ['xxx', 'xxx']

You must specify new key, such as password_check. This is used by Validator::Result object.

You can also use the reference of regular expression if you need.

  my $data = {person1 => 'Taro', person2 => 'Rika', person3 => 'Ken'};
  my $rule = [
    {merged_person => qr/^person;/} => [
      'merge', # TaroRikaKen
    ]
  ];

All matched value is passed to constraint function as array reference. In this example, the following value is passed.

  ['Taro', 'Rika', 'Ken']

Negative constraint function

You can negative a constraint function

  my $rule = [
    age => [
      '!int'
    ]
  ];

"!" is added to the head of the constraint name if you negative a constrint function. '!int' means not 'int'.

In this example,

"OR" of constraint functions

You can create "OR" of constraint functions

  my $rule = [
    email => [
      'blank || email'
    ]
  ];

Use "||" to create "OR" of constraint functions. 'blank || email' means 'blank' or 'email'.

You can combine "||" and "!".

  my $rule = [
    email => [
      'blank || !int'
    ]
  ];

Array validation

You can check if all the elements of array is valid.

  my $data = {
    nums => [1, 2, 3]
  };
  
  my $rule = [
    'nums' => [
      '@int'
    ]
  ];

"@" is added to the head of constraint function name to validate all the elements of array.

4. Constraint functions

Register constraint function

Validator::Custom has various constraint functions. You can see constraint functions registered by default "CONSTRAINTS" in Validator::Custom.

and you can register your constraint function if you need.

  $vc->register_constraint(
    telephone => sub {
      my $value = shift;
      
      my $is_valid;
      if ($value =~ /^[\d-]+$/) {
        $is_valid = 1;
      }
      return $is_valid;
    }
  );

Constraint function for telephone number is registered.

Constraint function receive a scalar value as first argument and return boolean value which check if the value is valid.

Constraint function receive argument of constraint function as second argument and Validator::Custom object as third argument.

  $vc->register_constraint(
    telephone => sub {
      my ($value, $arg, $vc) = @_;
      
      return $is_valid;
    }
  );

If you know the implementations of constraint functions, see the soruce of Validator::Custom::Constraint.

If you want to return custom message, you can use hash reference as return value. This feature is yet EXPERIMENTAL.

  $vc->register_constraint(
    telephone => sub {
      my ($value, $arg, $vc) = @_;
      
      # Process
      my $is_valid = ...;
      
      if ($is_valid) {
        return 1;
      }
      else {
        return {result => 0, message => 'Custom error message'};
      }
    }
  );

Register filter function

register_constraint() is also used to register filter function.

Filter function is same as constraint function except for return value;

  $vc->register_constraint(
    to_upper_case => sub {
      my $value = shift;
      
      $value = uc $value;
                  
      return [1, $value];
    }
  );

Return value of filter function must be array reference. First element is boolean value which chekc if the value is valid. Second element is filtered value.

In this example, First element of array reference is set to 1 because this function is intended to filter only.

You can also use hash reference representation(This is yet EXPERIMENTAL).

  # This is same as above
  $vc->register_constraint(
    to_upper_case => sub {
      my $value = shift;
      
      $value = uc $value;
                  
      return {result => 1, output => $value};
    }
  );
  

5. Extending

It is easy to define your class extending Validator::Custom. Register constraint function using register_constraint in the constructor.

  package Validator::Custom::Your;
  use base 'Validator::Custom';
  
  sub new {
    my $self = shift->SUPER::new(@_);
    $self->register_constraint(
      telephone => sub { ... }
    );
    return $self;
  }
  
  1;
  

Validator::Custom::HTMLForm is good extending examples.

EXAMPLES

See Validator::Custom Wiki. There are many examples.