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 404     404   224062 use strict;
  404         1028  
  404         21470  
2              
3             package HTML::FormFu::Role::CreateChildren;
4             # ABSTRACT: CreateChildren role
5             $HTML::FormFu::Role::CreateChildren::VERSION = '2.07';
6 404     404   2480 use Moose::Role;
  404         892  
  404         2750  
7              
8 404     404   2087810 use HTML::FormFu::Util qw( _merge_hashes require_class );
  404         1065  
  404         25442  
9 404     404   2747 use Carp qw( croak );
  404         932  
  404         18413  
10 404     404   2697 use Clone ();
  404         969  
  404         12839  
11 404     404   2446 use List::Util 1.45 qw( uniq );
  404         10056  
  404         25837  
12 404     404   2994 use Scalar::Util qw( weaken );
  404         978  
  404         1076986  
13              
14             sub element {
15 1244     1244 0 9856 my ( $self, $arg ) = @_;
16 1244         6920 my @return;
17              
18 1244 100       5342 if ( ref $arg eq 'ARRAY' ) {
19 237         989 push @return, map { $self->_single_element($_) } @$arg;
  463         2459  
20             }
21             else {
22 1007         4937 push @return, $self->_single_element($arg);
23             }
24              
25 1243 100       10001 return @return == 1 ? $return[0] : @return;
26             }
27              
28             sub deflator {
29 2     2 0 16 my ( $self, $arg ) = @_;
30 2         6 my @return;
31              
32 2 50       20 if ( ref $arg eq 'ARRAY' ) {
33 0         0 push @return, map { $self->_single_deflator($_) } @$arg;
  0         0  
34             }
35             else {
36 2         14 push @return, $self->_single_deflator($arg);
37             }
38              
39 2 50       14 return @return == 1 ? $return[0] : @return;
40             }
41              
42             sub filter {
43 17     17 0 56 my ( $self, $arg ) = @_;
44 17         33 my @return;
45              
46 17 100       76 if ( ref $arg eq 'ARRAY' ) {
47 3         7 push @return, map { $self->_single_filter($_) } @$arg;
  3         12  
48             }
49             else {
50 14         104 push @return, $self->_single_filter($arg);
51             }
52              
53 17 100       133 return @return == 1 ? $return[0] : @return;
54             }
55              
56             sub constraint {
57 58     58 0 233 my ( $self, $arg ) = @_;
58 58         183 my @return;
59              
60 58 100       420 if ( ref $arg eq 'ARRAY' ) {
61 14         55 push @return, map { $self->_single_constraint($_) } @$arg;
  15         102  
62             }
63             else {
64 44         316 push @return, $self->_single_constraint($arg);
65             }
66              
67 58 100       489 return @return == 1 ? $return[0] : @return;
68             }
69              
70             sub inflator {
71 5     5 0 30 my ( $self, $arg ) = @_;
72 5         13 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         59 push @return, $self->_single_inflator($arg);
79             }
80              
81 5 100       57 return @return == 1 ? $return[0] : @return;
82             }
83              
84             sub validator {
85 2     2 0 9 my ( $self, $arg ) = @_;
86 2         4 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         12 push @return, $self->_single_validator($arg);
93             }
94              
95 2 100       12 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 4 my ( $self, $arg ) = @_;
114 1         3 my @return;
115              
116 1 50       5 if ( ref $arg eq 'ARRAY' ) {
117 1         5 push @return, map { $self->_single_plugin($_) } @$arg;
  1         7  
118             }
119             else {
120 0         0 push @return, $self->_single_plugin($arg);
121             }
122              
123 1 50       7 return @return == 1 ? $return[0] : @return;
124             }
125              
126             sub _require_element {
127 1470     1470   4193 my ( $self, $arg ) = @_;
128              
129 1470 100       5934 $arg->{type} = 'Text' if !exists $arg->{type};
130              
131 1470         4034 my $type = delete $arg->{type};
132 1470         3485 my $class = $type;
133              
134 1470 100       5718 if ( not $class =~ s/^\+// ) {
135 1469         4652 $class = "HTML::FormFu::Element::$class";
136             }
137              
138 1470         4219 $type =~ s/^\+//;
139              
140 1470         8320 require_class($class);
141              
142 1470         55925 my $element = $class->new(
143             { type => $type,
144             parent => $self,
145             } );
146              
147 1470         10507 my $default_args = $self->default_args;
148              
149 1470 100       5813 if (%$default_args) {
150 267 100       2050 if ( $element->can('default_args') ) {
151 77         1071 $element->default_args( Clone::clone($default_args) );
152             }
153              
154             $default_args = $element->_match_default_args(
155 267         3485 Clone::clone( $default_args->{elements} ) );
156              
157 267 100       1161 if (%$default_args) {
158 20         63 $arg = _merge_hashes( $arg, $default_args );
159             }
160             }
161              
162 1470         6847 $element->populate($arg);
163              
164 1469         9428 $element->setup;
165              
166 1469         4456 return $element;
167             }
168              
169             sub _single_element {
170 1470     1470   7395 my ( $self, $arg ) = @_;
171              
172 1470 100       6781 if ( !ref $arg ) {
    50          
173 679         2480 $arg = { type => $arg };
174             }
175             elsif ( ref $arg eq 'HASH' ) {
176 791         4397 $arg = {%$arg}; # shallow clone
177             }
178             else {
179 0         0 croak 'invalid args';
180             }
181              
182 1470         7045 my $new = $self->_require_element($arg);
183              
184 1469 100 100     16291 if ( $self->can('auto_fieldset')
      100        
185             && $self->auto_fieldset
186             && $new->type ne 'Fieldset' )
187             {
188             my ($target)
189 200         484 = reverse @{ $self->get_elements( { type => 'Fieldset' } ) };
  200         1458  
190              
191 200         588 push @{ $target->_elements }, $new;
  200         6682  
192              
193 200         688 $new->{parent} = $target;
194 200         970 weaken $new->{parent};
195             }
196             else {
197 1269         2893 push @{ $self->_elements }, $new;
  1269         38513  
198             }
199              
200 1469         6164 return $new;
201             }
202              
203             sub _single_deflator {
204 2     2   9 my ( $self, $arg ) = @_;
205              
206 2 50       8 if ( !ref $arg ) {
    0          
207 2         8 $arg = { type => $arg };
208             }
209             elsif ( ref $arg eq 'HASH' ) {
210 0         0 $arg = {%$arg}; # shallow clone
211             }
212             else {
213 0         0 croak 'invalid args';
214             }
215              
216 0 0       0 my @names = map { ref $_ ? @$_ : $_ }
217 2         11 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  4         15  
218              
219 2 50       7 if ( !@names ) {
220             @names = uniq
221 4         35 grep {defined}
222 2         6 map { $_->nested_name } @{ $self->get_fields };
  4         19  
  2         16  
223             }
224              
225 2 50       24 croak "no field names to add deflator to" if !@names;
226              
227 2         17 my $type = delete $arg->{type};
228              
229 2         6 my @return;
230              
231 2         8 for my $x (@names) {
232 4         10 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  4         40  
233 4         31 my $new = $field->_require_deflator( $type, $arg );
234 4         9 push @{ $field->_deflators }, $new;
  4         138  
235 4         19 push @return, $new;
236             }
237             }
238              
239 2         9 return @return;
240             }
241              
242             sub _single_filter {
243 17     17   58 my ( $self, $arg ) = @_;
244              
245 17 100       70 if ( !ref $arg ) {
    50          
246 15         54 $arg = { type => $arg };
247             }
248             elsif ( ref $arg eq 'HASH' ) {
249 2         11 $arg = {%$arg}; # shallow clone
250             }
251             else {
252 0         0 croak 'invalid args';
253             }
254              
255 2 50       32 my @names = map { ref $_ ? @$_ : $_ }
256 17         84 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  34         101  
257              
258 17 100       71 if ( !@names ) {
259             @names = uniq
260 37         188 grep {defined}
261 15         48 map { $_->nested_name } @{ $self->get_fields };
  37         127  
  15         82  
262             }
263              
264 17 50       82 croak "no field names to add filter to" if !@names;
265              
266 17         51 my $type = delete $arg->{type};
267              
268 17         48 my @return;
269              
270 17         48 for my $x (@names) {
271 41         108 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  41         264  
272 41         264 my $new = $field->_require_filter( $type, $arg );
273 41         79 push @{ $field->_filters }, $new;
  41         1336  
274 41         177 push @return, $new;
275             }
276             }
277              
278 17         79 return @return;
279             }
280              
281             sub _single_constraint {
282 59     59   205 my ( $self, $arg ) = @_;
283              
284 59 100       296 if ( !ref $arg ) {
    50          
285 44         250 $arg = { type => $arg };
286             }
287             elsif ( ref $arg eq 'HASH' ) {
288 15         95 $arg = {%$arg}; # shallow clone
289             }
290             else {
291 0         0 croak 'invalid args';
292             }
293              
294 11 100       85 my @names = map { ref $_ ? @$_ : $_ }
295 59         495 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  118         694  
296              
297 59 100       294 if ( !@names ) {
298             @names = uniq
299 96         535 grep {defined}
300 48         151 map { $_->nested_name } @{ $self->get_fields };
  98         510  
  48         356  
301             }
302              
303 59 50       364 croak "no field names to add constraint to" if !@names;
304              
305 59         218 my $type = delete $arg->{type};
306              
307 59         198 my @return;
308              
309 59         187 for my $x (@names) {
310 112         258 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  112         910  
311 113         643 my $new = $field->_require_constraint( $type, $arg );
312 113         254 push @{ $field->_constraints }, $new;
  113         4038  
313 113         577 push @return, $new;
314             }
315             }
316              
317 59         319 return @return;
318             }
319              
320             sub _single_inflator {
321 5     5   24 my ( $self, $arg ) = @_;
322              
323 5 100       26 if ( !ref $arg ) {
    50          
324 4         18 $arg = { type => $arg };
325             }
326             elsif ( ref $arg eq 'HASH' ) {
327 1         6 $arg = {%$arg}; # shallow clone
328             }
329             else {
330 0         0 croak 'invalid args';
331             }
332              
333 1 50       7 my @names = map { ref $_ ? @$_ : $_ }
334 5         31 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  10         34  
335              
336 5 100       20 if ( !@names ) {
337             @names = uniq
338 6         46 grep {defined}
339 4         13 map { $_->nested_name } @{ $self->get_fields };
  6         32  
  4         29  
340             }
341              
342 5 50       30 croak "no field names to add inflator to" if !@names;
343              
344 5         19 my $type = delete $arg->{type};
345              
346 5         13 my @return;
347              
348 5         16 for my $x (@names) {
349 7         17 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  7         77  
350 7         75 my $new = $field->_require_inflator( $type, $arg );
351 7         19 push @{ $field->_inflators }, $new;
  7         324  
352 7         42 push @return, $new;
353             }
354             }
355              
356 5         27 return @return;
357             }
358              
359             sub _single_validator {
360 2     2   7 my ( $self, $arg ) = @_;
361              
362 2 100       10 if ( !ref $arg ) {
    50          
363 1         5 $arg = { type => $arg };
364             }
365             elsif ( ref $arg eq 'HASH' ) {
366 1         6 $arg = {%$arg}; # shallow clone
367             }
368             else {
369 0         0 croak 'invalid args';
370             }
371              
372 1 50       21 my @names = map { ref $_ ? @$_ : $_ }
373 2         9 grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  4         12  
374              
375 2 100       11 if ( !@names ) {
376             @names = uniq
377 2         11 grep {defined}
378 1         2 map { $_->nested_name } @{ $self->get_fields };
  2         10  
  1         5  
379             }
380              
381 2 50       18 croak "no field names to add validator to" if !@names;
382              
383 2         9 my $type = delete $arg->{type};
384              
385 2         4 my @return;
386              
387 2         7 for my $x (@names) {
388 3         8 for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  3         31  
389 3         18 my $new = $field->_require_validator( $type, $arg );
390 3         6 push @{ $field->_validators }, $new;
  3         110  
391 3         15 push @return, $new;
392             }
393             }
394              
395 2         10 return @return;
396             }
397              
398             sub _single_transformer {
399 0     0     my ( $self, $arg ) = @_;
400              
401 0 0         if ( !ref $arg ) {
    0          
402 0           $arg = { type => $arg };
403             }
404             elsif ( ref $arg eq 'HASH' ) {
405 0           $arg = {%$arg}; # shallow clone
406             }
407             else {
408 0           croak 'invalid args';
409             }
410              
411 0 0         my @names = map { ref $_ ? @$_ : $_ }
412 0           grep {defined} ( delete $arg->{name}, delete $arg->{names} );
  0            
413              
414 0 0         if ( !@names ) {
415             @names = uniq
416 0           grep {defined}
417 0           map { $_->nested_name } @{ $self->get_fields };
  0            
  0            
418             }
419              
420 0 0         croak "no field names to add transformer to" if !@names;
421              
422 0           my $type = delete $arg->{type};
423              
424 0           my @return;
425              
426 0           for my $x (@names) {
427 0           for my $field ( @{ $self->get_fields( { nested_name => $x } ) } ) {
  0            
428 0           my $new = $field->_require_transformer( $type, $arg );
429 0           push @{ $field->_transformers }, $new;
  0            
430 0           push @return, $new;
431             }
432             }
433              
434 0           return @return;
435             }
436              
437             1;
438              
439             __END__
440              
441             =pod
442              
443             =encoding UTF-8
444              
445             =head1 NAME
446              
447             HTML::FormFu::Role::CreateChildren - CreateChildren role
448              
449             =head1 VERSION
450              
451             version 2.07
452              
453             =head1 AUTHOR
454              
455             Carl Franks <cpan@fireartist.com>
456              
457             =head1 COPYRIGHT AND LICENSE
458              
459             This software is copyright (c) 2018 by Carl Franks.
460              
461             This is free software; you can redistribute it and/or modify it under
462             the same terms as the Perl 5 programming language system itself.
463              
464             =cut