The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Validator::Custom - Validate user input easily

SYNOPSYS

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

    my $data = {age => 19, name => 'Ken Suzuki'};
    
    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'
        ]
    ];
    
    my $result = $vc->validate($data, $rule);

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

DESCRIPTION

Validator::Custom validate user input easily. 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, 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.

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.

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.45678', num2 => '1.45'};
    my $rule => [
        num1 => [
            'decimal'
        ],
        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 => [
        [qw/mail1 mail2/] => [
            'duplication'
        ]
    ];

Check if the two data are same or not.

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' => 3}
        ],
        value2 => [
            {'length' => [2, 5]} # 'bb' to 'bbbbb'
        ]
    ];

Length of the value.

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.

space

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

White space or empty stirng.

uint

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

Unsigned integer.

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.

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.

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.

trim_lead

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

Trim leading white space.

trim_trail

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

Trim trailing white space.

STABILITY

All methods in these documentations (except for EXPERIMENTAL marking ones) keep backword compatible in the future.

AUTHOR

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

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

COPYRIGHT & LICENCE

Copyright 2009-2011 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.