File Coverage

blib/lib/HTML/FormFu/Role/CreateChildren.pm
Criterion Covered Total %
statement 210 256 82.0
branch 69 108 63.8
condition 6 6 100.0
subroutine 21 23 91.3
pod 0 8 0.0
total 306 401 76.3


line stmt bran cond sub pod time code
1             package HTML::FormFu::Role::CreateChildren;
2              
3 400     400   172513 use strict;
  400         616  
  400         14837  
4             our $VERSION = '2.05'; # VERSION
5              
6 400     400   1497 use Moose::Role;
  400         460  
  400         2182  
7              
8 400     400   1301529 use HTML::FormFu::Util qw( _merge_hashes require_class );
  400         595  
  400         19470  
9 400     400   1576 use Carp qw( croak );
  400         508  
  400         13355  
10 400     400   1534 use Clone ();
  400         559  
  400         8795  
11 400     400   1393 use List::Util 1.45 qw( uniq );
  400         8545  
  400         19313  
12 400     400   1634 use Scalar::Util qw( weaken );
  400         536  
  400         732847  
13              
14             sub element {
15 1242     1242 0 6779 my ( $self, $arg ) = @_;
16 1242         1628 my @return;
17              
18 1242 100       3792 if ( ref $arg eq 'ARRAY' ) {
19 231         478 push @return, map { $self->_single_element($_) } @$arg;
  457         1729  
20             }
21             else {
22 1011         3476 push @return, $self->_single_element($arg);
23             }
24              
25 1241 100       7563 return @return == 1 ? $return[0] : @return;
26             }
27              
28             sub deflator {
29 2     2 0 12 my ( $self, $arg ) = @_;
30 2         2 my @return;
31              
32 2 50       7 if ( ref $arg eq 'ARRAY' ) {
33 0         0 push @return, map { $self->_single_deflator($_) } @$arg;
  0         0  
34             }
35             else {
36 2         8 push @return, $self->_single_deflator($arg);
37             }
38              
39 2 50       11 return @return == 1 ? $return[0] : @return;
40             }
41              
42             sub filter {
43 17     17 0 32 my ( $self, $arg ) = @_;
44 17         22 my @return;
45              
46 17 100       52 if ( ref $arg eq 'ARRAY' ) {
47 3         6 push @return, map { $self->_single_filter($_) } @$arg;
  3         8  
48             }
49             else {
50 14         56 push @return, $self->_single_filter($arg);
51             }
52              
53 17 100       104 return @return == 1 ? $return[0] : @return;
54             }
55              
56             sub constraint {
57 65     65 0 474 my ( $self, $arg ) = @_;
58 65         106 my @return;
59              
60 65 100       218 if ( ref $arg eq 'ARRAY' ) {
61 14         36 push @return, map { $self->_single_constraint($_) } @$arg;
  15         79  
62             }
63             else {
64 51         213 push @return, $self->_single_constraint($arg);
65             }
66              
67 65 100       438 return @return == 1 ? $return[0] : @return;
68             }
69              
70             sub inflator {
71 5     5 0 19 my ( $self, $arg ) = @_;
72 5         10 my @return;
73              
74 5 50       33 if ( ref $arg eq 'ARRAY' ) {
75 0         0 push @return, map { $self->_single_inflator($_) } @$arg;
  0         0  
76             }
77             else {
78 5         26 push @return, $self->_single_inflator($arg);
79             }
80              
81 5 100       41 return @return == 1 ? $return[0] : @return;
82             }
83              
84             sub validator {
85 2     2 0 4 my ( $self, $arg ) = @_;
86 2         3 my @return;
87              
88 2 50       10 if ( ref $arg eq 'ARRAY' ) {
89 0         0 push @return, map { $self->_single_validator($_) } @$arg;
  0         0  
90             }
91             else {
92 2         9 push @return, $self->_single_validator($arg);
93             }
94              
95 2 100       19 return @return == 1 ? $return[0] : @return;
96             }
97              
98             sub transformer {
99 0     0 0 0 my ( $self, $arg ) = @_;
100 0         0 my @return;
101              
102 0 0       0 if ( ref $arg eq 'ARRAY' ) {
103 0         0 push @return, map { $self->_single_transformer($_) } @$arg;
  0         0  
104             }
105             else {
106 0         0 push @return, $self->_single_transformer($arg);
107             }
108              
109 0 0       0 return @return == 1 ? $return[0] : @return;
110             }
111              
112             sub plugin {
113 1     1 0 2 my ( $self, $arg ) = @_;
114 1         1 my @return;
115              
116 1 50       4 if ( ref $arg eq 'ARRAY' ) {
117 1         2 push @return, map { $self->_single_plugin($_) } @$arg;
  1         4  
118             }
119             else {
120 0         0 push @return, $self->_single_plugin($arg);
121             }
122              
123 1 50       5 return @return == 1 ? $return[0] : @return;
124             }
125              
126             sub _require_element {
127 1468     1468   2053 my ( $self, $arg ) = @_;
128              
129 1468 100       4048 $arg->{type} = 'Text' if !exists $arg->{type};
130              
131 1468         2864 my $type = delete $arg->{type};
132 1468         2115 my $class = $type;
133              
134 1468 100       4871 if ( not $class =~ s/^\+// ) {
135 1467         5653 $class = "HTML::FormFu::Element::$class";
136             }
137              
138 1468         3188 $type =~ s/^\+//;
139              
140 1468         5443 require_class($class);
141              
142 1468         45738 my $element = $class->new( {
143             type => $type,
144             parent => $self,
145             } );
146              
147 1468         7990 my $default_args = $self->default_args;
148              
149 1468 100       3703 if ( %$default_args ) {
150 254 100       1553 if ( $element->can('default_args') ) {
151 73         1105 $element->default_args( Clone::clone( $default_args ) );
152             }
153              
154 254         2773 $default_args = $element->_match_default_args( Clone::clone( $default_args->{elements} ) );
155              
156 254 100       804 if ( %$default_args ) {
157 11         31 $arg = _merge_hashes( $arg, $default_args );
158             }
159             }
160              
161 1468         4321 $element->populate($arg);
162              
163 1467         7449 $element->setup;
164              
165 1467         2967 return $element;
166             }
167              
168             sub _single_element {
169 1468     1468   2126 my ( $self, $arg ) = @_;
170              
171 1468 100       4602 if ( !ref $arg ) {
    50          
172 674         1783 $arg = { type => $arg };
173             }
174             elsif ( ref $arg eq 'HASH' ) {
175 794         3219 $arg = {%$arg}; # shallow clone
176             }
177             else {
178 0         0 croak 'invalid args';
179             }
180              
181 1468         4701 my $new = $self->_require_element($arg);
182              
183 1467 100 100     12079 if ( $self->can('auto_fieldset')
      100        
184             && $self->auto_fieldset
185             && $new->type ne 'Fieldset' )
186             {
187             my ($target)
188 200         294 = reverse @{ $self->get_elements( { type => 'Fieldset' } ) };
  200         1352  
189              
190 200         349 push @{ $target->_elements }, $new;
  200         5484  
191              
192 200         394 $new->{parent} = $target;
193 200         638 weaken $new->{parent};
194             }
195             else {
196 1267         1376 push @{ $self->_elements }, $new;
  1267         31102  
197             }
198              
199 1467         4098 return $new;
200             }
201              
202             sub _single_deflator {
203 2     2   4 my ( $self, $arg ) = @_;
204              
205 2 50       5 if ( !ref $arg ) {
    0          
206 2         6 $arg = { type => $arg };
207             }
208             elsif ( ref $arg eq 'HASH' ) {
209 0         0 $arg = {%$arg}; # shallow clone
210             }
211             else {
212 0         0 croak 'invalid args';
213             }
214              
215 0 0       0 my @names = map { ref $_ ? @$_ : $_ }
216 2         7 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  4         8  
217              
218 2 50       8 if ( !@names ) {
219             @names = uniq
220 4         16 grep {defined}
221 2         3 map { $_->nested_name } @{ $self->get_fields };
  4         12  
  2         11  
222             }
223              
224 2 50       8 croak "no field names to add deflator to" if !@names;
225              
226 2         7 my $type = delete $arg->{type};
227              
228 2         5 my @return;
229              
230 2         3 for my $x (@names) {
231 4         5 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  4         20  
232 4         23 my $new = $field->_require_deflator( $type, $arg );
233 4         6 push @{ $field->_deflators }, $new;
  4         108  
234 4         14 push @return, $new;
235             }
236             }
237              
238 2         7 return @return;
239             }
240              
241             sub _single_filter {
242 17     17   39 my ( $self, $arg ) = @_;
243              
244 17 100       56 if ( !ref $arg ) {
    50          
245 15         34 $arg = { type => $arg };
246             }
247             elsif ( ref $arg eq 'HASH' ) {
248 2         6 $arg = {%$arg}; # shallow clone
249             }
250             else {
251 0         0 croak 'invalid args';
252             }
253              
254 2 50       8 my @names = map { ref $_ ? @$_ : $_ }
255 17         44 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  34         57  
256              
257 17 100       62 if ( !@names ) {
258             @names = uniq
259 37         119 grep {defined}
260 15         25 map { $_->nested_name } @{ $self->get_fields };
  37         90  
  15         60  
261             }
262              
263 17 50       61 croak "no field names to add filter to" if !@names;
264              
265 17         39 my $type = delete $arg->{type};
266              
267 17         23 my @return;
268              
269 17         35 for my $x (@names) {
270 41         39 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  41         181  
271 41         194 my $new = $field->_require_filter( $type, $arg );
272 41         41 push @{ $field->_filters }, $new;
  41         1110  
273 41         117 push @return, $new;
274             }
275             }
276              
277 17         56 return @return;
278             }
279              
280             sub _single_constraint {
281 66     66   116 my ( $self, $arg ) = @_;
282              
283 66 100       230 if ( !ref $arg ) {
    50          
284 42         112 $arg = { type => $arg };
285             }
286             elsif ( ref $arg eq 'HASH' ) {
287 24         83 $arg = {%$arg}; # shallow clone
288             }
289             else {
290 0         0 croak 'invalid args';
291             }
292              
293 20 100       69 my @names = map { ref $_ ? @$_ : $_ }
294 66         213 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  132         274  
295              
296 66 100       220 if ( !@names ) {
297             @names = uniq
298 93         381 grep {defined}
299 46         76 map { $_->nested_name } @{ $self->get_fields };
  95         315  
  46         262  
300             }
301              
302 66 50       250 croak "no field names to add constraint to" if !@names;
303              
304 66         132 my $type = delete $arg->{type};
305              
306 66         93 my @return;
307              
308 66         133 for my $x (@names) {
309 118         151 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  118         589  
310 119         603 my $new = $field->_require_constraint( $type, $arg );
311 119         149 push @{ $field->_constraints }, $new;
  119         3359  
312 119         417 push @return, $new;
313             }
314             }
315              
316 66         254 return @return;
317             }
318              
319             sub _single_inflator {
320 5     5   10 my ( $self, $arg ) = @_;
321              
322 5 100       14 if ( !ref $arg ) {
    50          
323 4         12 $arg = { type => $arg };
324             }
325             elsif ( ref $arg eq 'HASH' ) {
326 1         4 $arg = {%$arg}; # shallow clone
327             }
328             else {
329 0         0 croak 'invalid args';
330             }
331              
332 1 50       4 my @names = map { ref $_ ? @$_ : $_ }
333 5         16 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  10         29  
334              
335 5 100       19 if ( !@names ) {
336             @names = uniq
337 6         37 grep {defined}
338 4         6 map { $_->nested_name } @{ $self->get_fields };
  6         23  
  4         30  
339             }
340              
341 5 50       18 croak "no field names to add inflator to" if !@names;
342              
343 5         12 my $type = delete $arg->{type};
344              
345 5         7 my @return;
346              
347 5         10 for my $x (@names) {
348 7         18 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  7         42  
349 7         51 my $new = $field->_require_inflator( $type, $arg );
350 7         9 push @{ $field->_inflators }, $new;
  7         194  
351 7         40 push @return, $new;
352             }
353             }
354              
355 5         17 return @return;
356             }
357              
358             sub _single_validator {
359 2     2   4 my ( $self, $arg ) = @_;
360              
361 2 100       8 if ( !ref $arg ) {
    50          
362 1         2 $arg = { type => $arg };
363             }
364             elsif ( ref $arg eq 'HASH' ) {
365 1         4 $arg = {%$arg}; # shallow clone
366             }
367             else {
368 0         0 croak 'invalid args';
369             }
370              
371 1 50       4 my @names = map { ref $_ ? @$_ : $_ }
372 2         7 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  4         7  
373              
374 2 100       14 if ( !@names ) {
375             @names = uniq
376 2         7 grep {defined}
377 1         2 map { $_->nested_name } @{ $self->get_fields };
  2         6  
  1         5  
378             }
379              
380 2 50       6 croak "no field names to add validator to" if !@names;
381              
382 2         4 my $type = delete $arg->{type};
383              
384 2         4 my @return;
385              
386 2         3 for my $x (@names) {
387 3         3 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  3         23  
388 3         16 my $new = $field->_require_validator( $type, $arg );
389 3         5 push @{ $field->_validators }, $new;
  3         89  
390 3         10 push @return, $new;
391             }
392             }
393              
394 2         8 return @return;
395             }
396              
397             sub _single_transformer {
398 0     0     my ( $self, $arg ) = @_;
399              
400 0 0         if ( !ref $arg ) {
    0          
401 0           $arg = { type => $arg };
402             }
403             elsif ( ref $arg eq 'HASH' ) {
404 0           $arg = {%$arg}; # shallow clone
405             }
406             else {
407 0           croak 'invalid args';
408             }
409              
410 0 0         my @names = map { ref $_ ? @$_ : $_ }
411 0           grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  0            
412              
413 0 0         if ( !@names ) {
414             @names = uniq
415 0           grep {defined}
416 0           map { $_->nested_name } @{ $self->get_fields };
  0            
  0            
417             }
418              
419 0 0         croak "no field names to add transformer to" if !@names;
420              
421 0           my $type = delete $arg->{type};
422              
423 0           my @return;
424              
425 0           for my $x (@names) {
426 0           for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  0            
427 0           my $new = $field->_require_transformer( $type, $arg );
428 0           push @{ $field->_transformers }, $new;
  0            
429 0           push @return, $new;
430             }
431             }
432              
433 0           return @return;
434             }
435              
436             1;