File Coverage

blib/lib/Class/Workflow/Transition/Validate/Simple.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Class::Workflow::Transition::Validate::Simple;
4 1     1   2186 use Moose::Role;
  0            
  0            
5              
6             with qw/
7             Class::Workflow::Transition
8             Class::Workflow::Transition::Validate
9             /;
10              
11             has error_state => (
12             does => "Class::Workflow::State",
13             is => "rw",
14             );
15              
16             has no_die => (
17             isa => "Bool",
18             is => "rw",
19             default => 0,
20             );
21              
22             has validators => (
23             isa => "ArrayRef",
24             is => "rw",
25             auto_deref => 1,
26             default => sub { [] },
27             );
28              
29             has ignore_validator_rv => (
30             isa => "Bool",
31             is => "rw",
32             default => 0,
33             );
34              
35             sub add_validators {
36             my ( $self, @validators ) = @_;
37             push @{ $self->validators }, @validators;
38             }
39              
40             sub clear_validators {
41             my $self = shift;
42             $self->validators([]);
43             }
44              
45             sub validate {
46             my ( $self, $instance, @args ) = @_;
47              
48             my $ignore_rv = $self->ignore_validator_rv;
49              
50             my @errors;
51             foreach my $validator ( $self->validators ) {
52             local $@;
53             my $ok = eval { $self->$validator( $instance, @args ) };
54              
55             if ( $@ ) {
56             push @errors, $@;
57             } elsif ( !$ignore_rv and !$ok ) {
58             push @errors, "general error";
59             }
60             }
61              
62             s/ at .* line \d+\.\n//s for @errors;
63              
64             die join(", ", @errors) . "\n" if @errors;
65             # FIXME add @errors to an exception object that stringifies
66              
67             return 1;
68             }
69              
70             sub validation_error {
71             my ( $self, $error, $instance, @args ) = @_;
72             chomp $error unless ref $error;
73              
74             if ( my $state = $self->error_state ) {
75             return $self->derive_and_accept_instance(
76             $instance => {
77             state => $state,
78             error => $error
79             },
80             @args
81             );
82             } else {
83             if ( $self->no_die ) {
84             return $self->derive_and_accept_instance(
85             $instance => {
86             state => $instance->state,
87             error => $error,
88             },
89             @args
90             );
91             } else {
92             die $error;
93             }
94             }
95             }
96              
97             __PACKAGE__;
98              
99             __END__
100              
101             =pod
102              
103             =head1 NAME
104              
105             Class::Workflow::Transition::Validate::Simple - Easier validation code.
106              
107             =head1 SYNOPSIS
108              
109             package MyTransition;
110             use Moose;
111              
112             with qw/Class::Workflow::Transition::Validate::Simple/;
113              
114             # ...
115              
116             $t->clear_validators;
117             $t->add_validators( sub { ... } );
118              
119             =head1 DESCRIPTION
120              
121             =head1 FIELDS
122              
123             =over 4
124              
125             =item ignore_validator_rv
126              
127             This is useful if your validators only throw exceptions.
128              
129             Defaults to false
130              
131             =item error_state
132              
133             This contains a state that will be moved to if a validation error occurs.
134              
135             In conjunction with L<Class::Workflow::State::AutoApply> this can work like a
136             catch block.
137              
138             The instance will have the C<error> attribute set.
139              
140             =item no_die
141              
142             If this is set, C<validation_error> will not die even if C<error_state> is
143             not set.
144              
145             The instance will have the C<error> attribute set, and will be reaccepted into
146             it's current state, with the error.
147              
148             =back
149              
150             =head1 METHODS
151              
152             =over 4
153              
154             =item validators
155              
156             This is an optional list of sub refs which will be called to validate input
157             before applying C<body>.
158              
159             They should raise an exception or return a false value if the input is bad.
160              
161             They may put validation result information inside the
162             L<Class::Workflow::Context> or equivalent, if one is used.
163              
164             A more comprehensive solution is to override the C<validate> method yourself
165             and provide rich exception objects with validation error descriptors inside
166             them.
167              
168             The validators are invoked as methods on the transition.
169              
170             IF C<ignore_validator_rv> is true then only exceptions are considered input
171             validations.
172              
173             =item add_validators @code_refs
174              
175             =item clear_validators
176              
177             Modify the list of validators.
178              
179             =back
180              
181             =head1 ROLES
182              
183             This role consumes the following roles:
184              
185             =over 4
186              
187             =item *
188              
189             L<Class::Workflow::Transition::Validate>
190              
191             =back
192              
193             =cut
194              
195