NAME

Validator::Custom - Custamizable validator

VERSION

Version 0.1001

STATE

This module is not stable. APIs will be changed for a while.

SYNOPSYS

use Validator::Custom;

# New
my $validator = Validator::Custom->new;

# Add Constraint
$validator->add_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;
    },
    not_blank => sub {
        my $value = shift;
        my $is_valid = $value ne '';
        return $is_valid;
    },
    length => sub {
        my ($value, $args) = @_;
        my ($min, $max) = @$args;
        my $length = length $value;
        my $is_valid = $length >= $min && $length <= $max;
        return $is_valid;
    }
);

# Data
my $data = { 
    age => 19, 
    names => ['abcoooo', 'def']
};

# Validation rule
$validator->rule([
    age => [
        'int'
    ],
    names => [
        ['@not_blank',          "name must exist"],
        ['@ascii',              "name must be ascii"],
        [{'@length' => [1, 5]}, "name must be 1 to 5"]
    ]
]);

# Data filter
$validator->data_filter(
    sub { 
        my $data = shift;
        
        # Do something
        
        return $data;
    }
);

# Validation
my $result = $validator->validate($data);

# Error messages
my @errors = $result->errors;

# One error message
my $error = $result->error('age');

# Error messages by hash ref
my $errors = $result->errors_to_hash;

# Invalid keys
my @invalid_keys = $result->invalid_keys;

# Producted value
my $products = $result->products;

# Is the result valid?
my $ret = $result->is_valid;

# Is one data valid
$ret = $result->is_valid('age');

# Corelative validation
my $rule = [
    {password_check => [qw/password1 password2/]} => [
        ['duplicate', 'Passwor is not same']
    ]
];

# "or" validation
$rule = [
    email => [
        'blank'
    ],
    # or
    email => [
        'not_blank',
        'email'
    ]
];
    

ATTRIBUTES

constraints

Constraint functions

$validator          = $validator->constraints($constraints);
$constraints = $validator->constraints;

Example

$validator->constraints(
    int    => sub { ... },
    string => sub { ... }
);

error_stock

Are errors stocked?

$validator   = $validator->error_stock(0);
$error_stock = $validator->error_stcok;

If you set 0, validation errors is not stocked. Validation is finished when one error is occured. This is faster than stocking all errors.

Default is 1. All errors are stocked.

data_filter

Data filtering function

$validator = $validator->data_filter($filter);
$filter    = $validator->data_filter;

Data filtering function is available. This function receive data, which is first argument of validate(). and return converted data.

$validator->data_filter(
    sub {
        my $data = shift;
        
        # Do someting
        
        return $data;
    }
)

rule

Validation rule

$validator   = $validator->rule($rule);
$rule        = $validator->rule;

Validation rule has the following syntax.

### Syntax of validation rule         
my $rule = [                          # 1. Validation rule is array ref
    key1 => [                         # 2. Constraints is array ref
        'constraint1_1',              # 3. Constraint is string
        ['constraint1_2', 'error1_2'],#      or arrya ref (error message)
        {'constraint1_3' => 'string'} #      or hash ref (arguments)
          
    ],
    key2 => [
        {'constraint2_1'              # 4. Argument is string
          => 'string'},               #
        {'constraint2_2'              #     or array ref
          => ['arg1', 'arg2']},       #
        {'constraint1_3'              #     or hash ref
          => {k1 => 'v1', k2 => 'v2'}}#
    ],
    key3 => [                           
        [{constraint3_1 => 'string'}, # 5. Combination argument
         'error3_1' ]                 #     and error message
    ],
    { key4 => ['key4_1', 'key4_2'] }  # 6. Multi key validation
        => [
            'constraint4_1'
           ],
    key5 => [
        '@constraint5_1'              # 7. array's items validation
    ]
];

'validation_rule' is deprecated. It is renamed to 'rule'

syntax

Syntax of validation rule

$validator = $validator->syntax($syntax);
$syntax    = $validator->syntax;

MEHTODS

new

Constructor

$validator = Validator::Costom->new;
$validator = Validator::Costom->new(rule => [ .. ]);

add_constraint

Add constraint function

$validator->add_constraint(%constraint);
$validator->add_constraint(\%constraint);

Example

$validator->add_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;
    }
);

validate

Validation

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

If you omit $rule, $validator->rule is used. Return value is Validator::Custom::Result object.

Validator::Custom::Result

'validate' method return Validator::Custom::Result object.

See Validator::Custom::Result.

The following is Validator::Custom::Result example

# Restlt
$result = $validator->validate($data, $rule);

# Error message
@errors = $result->errors;

# Invalid keys
@invalid_keys = $result->invalid_keys;

# Producted values
$products = $result->products;
$product  = $products->{key1};

# Is it valid?
$is_valid = $result->is_valid;

CONSTRAINT FUNCTION

You can resist your constraint function using 'add_constraint' method.

Constrant function can receive three argument.

1. validating data(which is first argument of validator())
2. arguments(which is in validation rule)
3. Validator::Cotsom object

I explain using example. You can pass argument in validation rule. and you can receive the argument in constraint function

my $data = {key => 'value'}; # 1. value
my $rule => {
    key => [
        {'name' => $args} # 2. arguments
    ],
}

$validator->add_constraint(name => sub {
    my ($value, $args, $self) = @_;
    
    # ...
    
    return $is_valid;
});

constraint function also can return producted value.

$validator->add_constraint(name => sub {
    my ($value, $args, $self) = @_;
    
    # ...
    
    return ($is_valid, $product);
});

Validator::Custom::HTML::Form is good example.

You can use constraints function already resisted,

$validator->add_constraint(name => sub {
    my ($value, $args, $self) = @_;
    
    my $is_valid = $self->constraints->{email}->($value);
    
    # And do something.
    
    return ($is_valid, $product);
});

You must not referrer outer Validator::Custom object. Circular reference and memory leak occur.

$validator->add_constraint(name => sub {
    my ($value, $args) = @_;
    
    # Must not do this!
    my $is_valid = $validator->constraints->{email}->($value);
    
    return ($is_valid, $product);
});    

CUSTOM CLASS

You can create your custom class extending Validator::Custom.

package Validator::Custom::Yours;
use base 'Validator::Custom';

__PACKAGE__->add_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;
    }
);

This class is avalilable same way as Validator::Custom

$validator = Validator::Custom::Yours->new;

Validator::Custom::Trim, Validator::Custom::HTMLForm is good example.

OR VALIDATION

This module also provide 'or' validation. You write key constaraint in a rule repeateadly. one of the constraint is valid, the key is valid.

$validator->rule( key1 => ['constraint'], key1 => ['constraint2'] );

Example

"email" is valid, if 'email' is blank or mail address, To understand "or validation" easily, it is good practice to add "# or" comment to your code.

$validator->rule([
    email => [
        'blank'
    ],
    # or
    email => [
        'not_blank',
        'email'
    ]
]);

AUTHOR

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

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

COPYRIGHT & LICENCE

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