File Coverage

blib/lib/Form/DemonCore.pm
Criterion Covered Total %
statement 3 5 60.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Form::DemonCore;
2             BEGIN {
3 2     2   123714 $Form::DemonCore::AUTHORITY = 'cpan:GETTY';
4             }
5             BEGIN {
6 2     2   41 $Form::DemonCore::VERSION = '0.101';
7             }
8             # ABSTRACT: The demon core of form managements
9              
10 2     2   4887 use Moose;
  0            
  0            
11             use Form::DemonCore::Field;
12              
13             has name => (
14             isa => 'Str',
15             is => 'ro',
16             required => 1,
17             );
18              
19             has param_name => (
20             isa => 'Str',
21             is => 'ro',
22             lazy_build => 1,
23             );
24              
25             sub _build_param_name { shift->name }
26              
27             has fields => (
28             traits => ['Array'],
29             is => 'ro',
30             isa => 'ArrayRef[Form::DemonCore::Field]',
31             default => sub {[]},
32             handles => {
33             all_fields => 'elements',
34             add_field => 'push',
35             map_fields => 'map',
36             filter_fields => 'grep',
37             get_field => 'get',
38             count_fields => 'count',
39             has_fields => 'count',
40             has_no_fields => 'is_empty',
41             sorted_fields => 'sort',
42             },
43             );
44              
45             has validators => (
46             traits => ['Array'],
47             is => 'ro',
48             isa => 'ArrayRef[CodeRef]',
49             default => sub {[]},
50             handles => {
51             all_validators => 'elements',
52             add_validator => 'push',
53             count_validators => 'count',
54             has_validators => 'count',
55             has_no_validators => 'is_empty',
56             },
57             );
58              
59             has default_field_class => (
60             isa => 'Str',
61             is => 'ro',
62             lazy_build => 1,
63             );
64              
65             sub _build_default_field_class { 'Form::DemonCore::Field' }
66              
67             has field_namespace => (
68             isa => 'Str',
69             is => 'rw',
70             );
71              
72             sub factory {
73             my ( $class, $config ) = @_;
74             my %input_values = %{delete $config->{input_values}} if defined $config->{input_values};
75             my @field_defs = @{delete $config->{fields}} if defined $config->{fields};
76             my %defaults = %{delete $config->{defaults}} if defined $config->{defaults};
77             my @fields;
78             die "no fields defined" unless @field_defs;
79             my $form = $class->new(
80             %{$config},
81             );
82             for (@field_defs) {
83             push @fields, $form->field_factory(delete $_->{name}, delete $_->{type}, $_);
84             }
85             for (@fields) {
86             $form->add_field($_);
87             }
88             $form->insert_defaults(\%defaults) if (%defaults);
89             $form->insert_inputs(\%input_values) if (%input_values);
90             return $form;
91             }
92              
93             sub result {
94             my ( $self ) = @_;
95             return $self->get_values if ( $self->is_submitted && $self->is_valid );
96             return;
97             }
98              
99             sub get_values {
100             my ( $self ) = @_;
101             my %values;
102             for ($self->all_fields) {
103             $values{$_->name} = $_->value if $_->has_value;
104             }
105             return \%values;
106             }
107              
108             sub field_factory {
109             my ( $self, $name, $type, $attributes ) = @_;
110             my $class;
111             if (!defined $type) {
112             $class = $self->default_field_class;
113             } elsif ($self->field_namespace) {
114             $class = $self->field_namespace.'::'.$type;
115             }
116             die __PACKAGE__." can't handle type ".$type if !$class;
117             my $file = $class;
118             $file =~ s/::/\//g;
119             $file .= '.pm';
120             require $file;
121             return $class->new(
122             form => $self,
123             name => $name,
124             %{$attributes},
125             );
126             }
127              
128             has param_split_char => (
129             isa => 'Str',
130             is => 'ro',
131             default => sub { '_' },
132             );
133              
134             has param_split_char_regex => (
135             isa => 'Str',
136             is => 'ro',
137             default => sub { '_' },
138             );
139              
140             sub insert_defaults {
141             my ( $self, $defaults ) = @_;
142             for ($self->all_fields) {
143             if (defined $defaults->{$_->name}) {
144             $_->default_value($defaults->{$_->name});
145             }
146             }
147             }
148              
149             sub insert_inputs {
150             my ( $self, $params ) = @_;
151             $self->is_submitted(1) if ($params->{$self->name});
152             my $param_split_char_regex = $self->param_split_char_regex;
153             for ($self->all_fields) {
154             if ($_->can('input_from_params')) {
155             $_->input_from_params($params);
156             } else {
157             my $param_name = $_->param_name;
158             if (defined $params->{$param_name}) {
159             $_->input_value($params->{$param_name});
160             } else {
161             my %values;
162             for (keys %{$params}) {
163             if ($_ =~ m/^${param_name}${param_split_char_regex}(.+)/) {
164             $values{$1} = $params->{$_} if defined $params->{$_};
165             }
166             }
167             $_->input_value(\%values) if %values;
168             }
169             }
170             }
171             }
172              
173             has _is_valid => (
174             isa => 'Bool',
175             is => 'rw',
176             predicate => 'is_validated',
177             clearer => 'devalidate',
178             );
179             sub is_valid { my $self = shift; $self->validate; return $self->_is_valid }
180              
181             has is_submitted => (
182             isa => 'Bool',
183             is => 'rw',
184             clearer => 'unsubmit',
185             default => sub { 0 },
186             );
187              
188             has session => (
189             isa => 'HashRef',
190             is => 'rw',
191             predicate => 'has_session',
192             );
193              
194             sub clear_form {
195             my ( $self ) = @_;
196             for ($self->all_fields) {
197             $_->clear_session;
198             $_->clear_input_value;
199             $_->populate;
200             }
201             }
202              
203             sub validate {
204             my ( $self ) = @_;
205             return if $self->is_validated;
206             for ($self->all_validators) {
207             $self->add_error($_) for ($_->($self,$self->get_values));
208             }
209             my $valid_fields = 1;
210             for ($self->all_fields) {
211             $valid_fields = 0 if !$_->is_valid;
212             }
213             $self->_is_valid(!$self->has_errors && $valid_fields ? 1 : 0);
214             }
215              
216             has x => (
217             traits => ['Hash'],
218             is => 'ro',
219             isa => 'HashRef',
220             default => sub {{}},
221             );
222              
223             has errors => (
224             traits => ['Array'],
225             is => 'ro',
226             isa => 'ArrayRef',
227             default => sub {[]},
228             handles => {
229             all_errors => 'elements',
230             add_error => 'push',
231             count_errors => 'count',
232             has_errors => 'count',
233             has_no_errors => 'is_empty',
234             },
235             );
236              
237             1;
238              
239              
240             __END__
241             =pod
242              
243             =head1 NAME
244              
245             Form::DemonCore - The demon core of form managements
246              
247             =head1 VERSION
248              
249             version 0.101
250              
251             =head1 SYNOPSIS
252              
253             use Form::DemonCore;
254              
255             my $form = Form::DemonCore->factory({
256             name => 'testform',
257             fields => [
258             {
259             name => 'testfield',
260             notempty => 1,
261             },
262             ],
263             input_values => {
264             testform => 1,
265             testform_testfield => "test",
266             },
267             session => $session,
268             });
269              
270             if (my $result = $form->result) {
271             $form->clear_form; # to reset all values to default
272             ...
273             }
274              
275             =head1 SUPPORT
276              
277             IRC
278              
279             Join #demoncore on irc.perl.org.
280              
281             Repository
282              
283             http://github.com/Getty/p5-form-demoncore
284             Pull request and additional contributors are welcome
285              
286             Issue Tracker
287              
288             http://github.com/Getty/p5-form-demoncore/issues
289              
290             =head1 AUTHOR
291              
292             Torsten Raudssus <torsten@raudss.us> L<http://raudss.us/>
293              
294             =head1 COPYRIGHT AND LICENSE
295              
296             This software is copyright (c) 2011 by Raudssus Social Software.
297              
298             This is free software; you can redistribute it and/or modify it under
299             the same terms as the Perl 5 programming language system itself.
300              
301             =cut
302