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

NAME

Validator::Custom - HTML form Validation, easy and flexibly

SYNOPSYS

  use Validator::Custom;
  my $vc = Validator::Custom->new;
  
  # Data
  my $data = {age => 19, name => 'Ken Suzuki'};
  
  # Rule
  my $rule = [
    age => [
      ['not_blank' => 'age is empty.'],
      ['int' => 'age must be integer']
    ],
    name => [
      ['not_blank' => 'name is emtpy'],
      [{length => [1, 5]} => 'name is too long']
    ]
  ];
  
  # Validation
  my $result = $vc->validate($data, $rule);
  if ($result->is_ok) {
    # Safety data
    my $safe_data = $vresult->data;
  }
  else {
    # Error messgaes
    my $errors = $vresult->messages;
  }

DESCRIPTION

Validator::Custom validate HTML form data easy and flexibly. The features are the following ones.

  • Many constraint functions are available by default, such as not_blank, int, defined, in_array, length.

  • Several filter functions are available by default, such as trim, datetime_to_timepiece, date_to_timepiece.

  • You can register your constraint function.

  • You can set error messages for invalid parameter value. The order of messages is keeped.

  • Support OR condtion constraint and negativate constraint,

GUIDE

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

ATTRIBUTES

constraints

  my $constraints = $vc->constraints;
  $vc             = $vc->constraints(\%constraints);

Constraint functions.

data_filter

  my $filter = $vc->data_filter;
  $vc        = $vc->data_filter(\&data_filter);

Filter for input data. If data is not hash reference, you can convert the data to hash reference.

  $vc->data_filter(sub {
    my $data = shift;
    
    my $hash = {};
    
    # Convert data to hash reference
    
    return $hash;
  });

error_stock

  my $error_stock = $vc->error_stcok;
  $vc             = $vc->error_stock(1);

If error_stock is set to 0, validate() return soon after invalid value is found.

Default to 1.

normalized_rule EXPERIMENTAL

  my normalized_rule = $vc->normalized_rule($rule);

Validator::Custom rule is a little complex. You maybe make misstakes offten. If you want to know that how Validator::Custom parse rule, call normalized_rule method after calling validate method.

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

  use Data::Dumper;
  print Dumper $vc->normalized_rule;

If you see ERROR key, rule syntx is wrong.

rule

  my $rule = $vc->rule;
  $vc      = $vc->rule(\@rule);

Validation rule. If second argument of validate() is not specified. this rule is used.

syntax

  my $syntax = $vc->syntax;
  $vc        = $vc->syntax($syntax);

Syntax of rule.

METHODS

Validator::Custom inherits all methods from Object::Simple and implements the following new ones.

new

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

Create a new Validator::Custom object.

js_fill_form_button

  my $button = $self->js_fill_form_button(
    mail => '[abc]{3}@[abc]{2}.com,
    title => '[pqr]{5}'
  );

Create javascript button source code to fill form. You can specify string or pattern like regular expression.

If you click this button, each text box is filled with the specified pattern string, and checkbox, radio button, and list box is automatically selected.

Note that this methods require JSON module.

validate

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

Validate the data. Return value is Validator::Custom::Result object. If second argument is not specified, rule attribute is used.

register_constraint

  $vc->register_constraint(%constraint);
  $vc->register_constraint(\%constraint);

Register constraint function.

  $vc->register_constraint(
    int => sub {
      my $value    = shift;
      my $is_valid = $value =~ /^\-?[\d]+$/;
      return $is_valid;
    },
    ascii => sub {
      my $value    = shift;
      my $is_valid = $value =~ /^[\x21-\x7E]+$/;
      return $is_valid;
    }
  );

You can register filter function.

  $vc->register_constraint(
    trim => sub {
      my $value = shift;
      $value =~ s/^\s+//;
      $value =~ s/\s+$//;
      
      return [1, $value];
    }
  );

Filter function return array reference, first element is the value if the value is valid or not, second element is the converted value by filter function.

RULE SYNTAX

Validation rule has the following syntax.

  # Rule syntax
  my $rule = [                          # 1 Rule is array ref
    key => [                            # 2 Constraints is array ref
      'constraint',                     # 3 Constraint is string
      {'constraint' => 'args'}          #     or hash ref (arguments)
      ['constraint', 'err'],            #     or arrya ref (message)
    ],
    key => [                           
      [{constraint => 'args'}, 'err']   # 4 With argument and message
    ],
    {key => ['key1', 'key2']} => [      # 5.1 Multi-parameters validation
      'constraint'
    ],
    {key => qr/^key/} => [              # 5.2 Multi-parameters validation
      'constraint'                            using regular expression
    ],
    key => [
      '@constraint'                     # 6 Multi-values validation
    ],
    key => {message => 'err', ... } => [# 7 With option
      'constraint'
    ],
    key => [
      '!constraint'                     # 8 Negativate constraint
    ],
    key => [
      'constraint1 || constraint2'      # 9 "OR" condition constraint
    ],
  ];

Rule can have option, following options is available.

1. message
  {message => "Input right value"}

Message for invalid value.

2. default
  {default => 5}

Default value, set to data of Validator::Custom::Result when invalid value or missing value is found

3. copy
  {copy => 0}

If copy is 0, the value is not copied to data of Validator::Custom::Result.

Default to 1.

4. require
  {require => 0}

If require is 0, The value is not appended to missing parameter list even if the value is not found

Default to 1.

CONSTRAINTS

ascii

  my $data => {name => 'Ken'};
  my $rule = [
    name => [
      'ascii'
    ]
  ];

Ascii graphic characters(hex 21-7e).

between

  my $data = {age => 19};
  my $rule = [
    age => [
      {between => [1, 20]} # (1, 2, .. 19, 20)
    ]
  ];

Between A and B.

blank

  my $data = {name => ''};
  my $rule = [
    name => [
      'blank'
    ]
  ];

Blank.

decimal

  my $data = {num1 => '123', num2 => '1.45'};
  my $rule => [
    num1 => [
      {'decimal' => 3}
    ],
    num2 => [
      {'decimal' => [1, 2]}
    ]
  ];

Decimal. You can specify maximus digits number at before and after '.'.

defined

  my $data => {name => 'Ken'};
  my $rule = [
    name => [
      'defined'
    ]
  ];

Defined.

duplication

  my $data = {mail1 => 'a@somehost.com', mail2 => 'a@somehost.com'};
  my $rule => [
    {mail => ['mail1', 'mail2']} => [
      'duplication'
    ]
  ];

Check if the two data are same or not.

Note that if one value is not defined or both values are not defined, result of validation is false.

equal_to

  my $data = {price => 1000};
  my $rule = [
    price => [
      {'equal_to' => 1000}
    ]
  ];

Numeric equal comparison.

greater_than

  my $data = {price => 1000};
  my $rule = [
    price => [
      {'greater_than' => 900}
    ]
  ];

Numeric "greater than" comparison

http_url

  my $data = {url => 'http://somehost.com'};
  my $rule => [
    url => [
      'http_url'
    ]
  ];

HTTP(or HTTPS) URL.

int

  my $data = {age => 19};
  my $rule = [
    age => [
      'int'
    ]
  ];

Integer.

in_array

  my $data = {food => 'sushi'};
  my $rule = [
    food => [
      {'in_array' => [qw/sushi bread apple/]}
    ]
  ];

Check if the values is in array.

length

  my $data = {value1 => 'aaa', value2 => 'bbbbb'};
  my $rule => [
    value1 => [
      # length is equal to 3
      {'length' => 3} # 'aaa'
    ],
    value2 => [
      # length is greater than or equal to 2 and lower than or equeal to 5
      {'length' => [2, 5]} # 'bb' to 'bbbbb'
    ]
    value3 => [
      # length is greater than or equal to 2 and lower than or equeal to 5
      {'length' => {min => 2, max => 5}} # 'bb' to 'bbbbb'
    ]
    value4 => [
      # greater than or equal to 2
      {'length' => {min => 2}}
    ]
    value5 => [
      # lower than or equal to 5
      {'length' => {max => 5}}
    ]
  ];

Length of the value.

Not that if value is internal string, length is character length. if value is byte string, length is byte length.

less_than

  my $data = {num => 20};
  my $rule = [
    num => [
      {'less_than' => 25}
    ]
  ];

Numeric "less than" comparison.

not_blank

  my $data = {name => 'Ken'};
  my $rule = [
    name => [
      'not_blank' # Except for ''
    ]
  ];

Not blank.

not_defined

  my $data = {name => 'Ken'};
  my $rule = [
    name => [
      'not_defined'
    ]
  ];

Not defined.

not_space

  my $data = {name => 'Ken'};
  my $rule = [
    name => [
      'not_space' # Except for '', ' ', '   '
    ]
  ];

Not contain only space characters. Not that space is only [ \t\n\r\f] which don't contain unicode space character.

space

  my $data = {name => '   '};
  my $rule = [
    name => [
      'space' # '', ' ', '   '
    ]
  ];

White space or empty stirng. Not that space is only [ \t\n\r\f] which don't contain unicode space character.

uint

  my $data = {age => 19};
  my $rule = [
    age => [
      'uint'
    ]
  ];

Unsigned integer(contain zero).

regex

  my $data = {num => '123'};
  my $rule => [
    num => [
      {'regex' => qr/\d{0,3}/}
    ]
  ];

Match a regular expression.

selected_at_least

  my $data = {hobby => ['music', 'movie' ]};
  my $rule => [
    hobby => [
      {selected_at_least => 1}
    ]
  ];

Selected at least specified count item. In other word, the array contains at least specified count element.

FILTERS

date_to_timepiece

  my $data = {date => '2010/11/12'};
  my $rule = [
    date => [
      'date_to_timepiece'
    ]
  ];

The value which looks like date is converted to Time::Piece object. If the value contains 8 digits, the value is assumed date.

  2010/11/12 # ok
  2010-11-12 # ok
  20101112   # ok
  2010       # NG
  2010111106 # NG

And year and month and mday combination is ok.

  my $data = {year => 2011, month => 3, mday => 9};
  my $rule = [
    {date => ['year', 'month', 'mday']} => [
      'date_to_timepiece'
    ]
  ];

Note that Time::Piece is required.

datetime_to_timepiece

  my $data = {datetime => '2010/11/12 12:14:45'};
  my $rule = [
    datetime => [
      'datetime_to_timepiece'
    ]
  ];

The value which looks like date and time is converted to Time::Piece object. If the value contains 14 digits, the value is assumed date and time.

  2010/11/12 12:14:45 # ok
  2010-11-12 12:14:45 # ok
  20101112 121445     # ok
  2010                # NG
  2010111106 12       # NG

And year and month and mday combination is ok.

  my $data = {year => 2011, month => 3, mday => 9
              hour => 10, min => 30, sec => 30};
  my $rule = [
    {datetime => ['year', 'month', 'mday', 'hour', 'min', 'sec']} => [
      'datetime_to_timepiece'
    ]
  ];

Note that Time::Piece is required.

merge

  my $data = {name1 => 'Ken', name2 => 'Rika', name3 => 'Taro'};
  my $rule = [
    {merged_name => ['name1', 'name2', 'name3']} => [
      'merge' # KenRikaTaro
    ]
  ];

Merge the values. Note that if one value is not defined, merged value become undefined.

shift

  my $data = {names => ['Ken', 'Taro']};
  my $rule => [
    names => [
      'shift' # 'Ken'
    ]
  ];

Shift the head element of array.

to_array

  my $data = {languages => 'Japanese'};
  my $rule = [
    languages => [
      'to_array' # ['Japanese']
    ],
  ];
  

Convert non array reference data to array reference. This is useful to check checkbox values or select multiple values.

trim

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim' # 'Ken'
    ]
  ];

Trim leading and trailing white space. Not that trim only [ \t\n\r\f] which don't contain unicode space character.

trim_collapse

  my $data = {name => '  Ken   Takagi  '};
  my $rule = [
    name => [
      'trim_collapse' # 'Ken Takagi'
    ]
  ];

Trim leading and trailing white space, and collapse all whitespace characters into a single space. Not that trim only [ \t\n\r\f] which don't contain unicode space character.

trim_lead

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim_lead' # 'Ken  '
    ]
  ];

Trim leading white space. Not that trim only [ \t\n\r\f] which don't contain unicode space character.

trim_trail

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim_trail' # '  Ken'
    ]
  ];

Trim trailing white space. Not that trim only [ \t\n\r\f] which don't contain unicode space character.

trim_uni

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim_uni' # 'Ken'
    ]
  ];

Trim leading and trailing white space, which contain unicode space character.

trim_uni_collapse

  my $data = {name => '  Ken   Takagi  '};
  my $rule = [
    name => [
      'trim_uni_collapse' # 'Ken Takagi'
    ]
  ];

Trim leading and trailing white space, which contain unicode space character.

trim_uni_lead

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim_uni_lead' # 'Ken  '
    ]
  ];

Trim leading white space, which contain unicode space character.

trim_uni_trail

  my $data = {name => '  Ken  '};
  my $rule = [
    name => [
      'trim_uni_trail' # '  Ken'
    ]
  ];

Trim trailing white space, which contain unicode space character.

DEPRECATED FUNCTIONALITIES

Validator::Custom

  # Atrribute methods
  shared_rule # Removed at 2017/1/1
  
  # Methods
  __PACKAGE__->constraints(...); # Call constraints method as class method
                                 # Removed at 2017/1/1
L<Validator::Custom::Result>

  # Attribute methods
  error_infos # Removed at 2017/1/1 

  # Methods
  add_error_info # Removed at 2017/1/1
  error # Removed at 2017/1/1
  errors # Removed at 2017/1/1
  errors_to_hash # Removed at 2017/1/1
  invalid_keys # Removed at 2017/1/1
  remove_error_info# Removed at 2017/1/1

BACKWORD COMPATIBLE POLICY

If a functionality is DEPRECATED, you can know it by DEPRECATED warnings. DEPRECATED functionality is removed after five years, but if at least one person use the functionality and tell me that thing I extend one year each time you tell me it.

EXPERIMENTAL functionality will be changed without warnings.

AUTHOR

Yuki Kimoto, <kimoto.yuki at gmail.com>

http://github.com/yuki-kimoto/Validator-Custom

COPYRIGHT & LICENCE

Copyright 2009-2013 Yuki Kimoto, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.